/** * \fn char *VFS_GetTruePath(const char *Path) * \brief Gets the true path (non-symlink) of a file */ char *VFS_GetTruePath(const char *Path) { tVFS_Node *node; char *ret, *tmp; tmp = VFS_GetAbsPath(Path); if(tmp == NULL) return NULL; //Log(" VFS_GetTruePath: tmp = '%s'", tmp); node = VFS_ParsePath(tmp, &ret, NULL); free(tmp); //Log(" VFS_GetTruePath: node=%p, ret='%s'", node, ret); if(!node) return NULL; if(node->Type->Close) node->Type->Close(node); return ret; }
/** * \fn int VFS_Symlink(const char *Name, const char *Link) * \brief Creates a symlink called \a Name to \a Link * \param Name Name of symbolic link * \param Link Destination of symbolic link */ int VFS_Symlink(const char *Name, const char *Link) { char *realLink; int fp; ENTER("sName sLink", Name, Link); // Get absolue path name realLink = VFS_GetAbsPath( Link ); if(!realLink) { Log_Warning("VFS", "Path '%s' is badly formed", Link); errno = EINVAL; LEAVE('i', -1); return -1; } LOG("realLink = '%s'", realLink); // Make node if( VFS_MkNod(Name, VFS_FFLAG_SYMLINK) != 0 ) { Log_Warning("VFS", "Unable to create link node '%s'", Name); free(realLink); // errno is set by VFS_MkNod LEAVE('i', -2); return -2; // Make link node } // Write link address fp = VFS_Open(Name, VFS_OPENFLAG_WRITE|VFS_OPENFLAG_NOLINK); if( fp == -1 ) { Log_Warning("VFS", "Unable to open newly created symlink '%s'", Name); free(realLink); LEAVE('i', -3); return -3; } VFS_Write(fp, strlen(realLink), realLink); VFS_Close(fp); free(realLink); LEAVE('i', 1); return 1; }
/** * \fn int VFS_MkNod(char *Path, Uint Flags) * \brief Create a new node in a directory * \param Path Path of new node * \param Flags Flags to apply to the node */ int VFS_MkNod(const char *Path, Uint Flags) { tVFS_Mount *mountpt; char *absPath, *name; int pos = 0, oldpos = 0; int next = 0; tVFS_Node *parent; tVFS_Node *ret; ENTER("sPath xFlags", Path, Flags); absPath = VFS_GetAbsPath(Path); LOG("absPath = '%s'", absPath); while( (next = strpos(&absPath[pos+1], '/')) != -1 ) { LOG("next = %i", next); pos += next+1; LOG("pos = %i", pos); oldpos = pos; } absPath[oldpos] = '\0'; // Mutilate path name = &absPath[oldpos+1]; LOG("absPath = '%s', name = '%s'", absPath, name); // Check for root if(absPath[0] == '\0') parent = VFS_ParsePath("/", NULL, &mountpt); else parent = VFS_ParsePath(absPath, NULL, &mountpt); LOG("parent = %p", parent); if(!parent) { errno = ENOENT; goto _error; } // Permissions Check if( !VFS_CheckACL(parent, VFS_PERM_EXECUTE|VFS_PERM_WRITE) ) { errno = EACCES; goto _error; } LOG("parent = %p", parent); if(!parent->Type || !parent->Type->MkNod) { Log_Warning("VFS", "VFS_MkNod - Directory has no MkNod method"); errno = ENOTDIR; goto _error; } // Create node ret = parent->Type->MkNod(parent, name, Flags); _CloseNode(ret); // Free allocated string free(absPath); // Free Parent ASSERT(mountpt->OpenHandleCount>0); mountpt->OpenHandleCount --; _CloseNode(parent); // Return whatever the driver said LEAVE('i', ret==NULL); return ret==NULL; _error: if( parent ) { _CloseNode(parent); ASSERT(mountpt->OpenHandleCount>0); mountpt->OpenHandleCount --; } free(absPath); LEAVE('i', -1); return -1; }