Fixed VFS_ChDir to handle symlinks by using VFS_Open
[tpg/acess2.git] / Kernel / vfs / open.c
index 64c65db..eebaa82 100644 (file)
@@ -51,6 +51,10 @@ char *VFS_GetAbsPath(char *Path)
        // Memory File
        if(Path[0] == '$') {
                ret = malloc(strlen(Path)+1);
+               if(!ret) {
+                       Warning("VFS_GetAbsPath - malloc() returned NULL");
+                       return NULL;
+               }
                strcpy(ret, Path);
                LEAVE('p', ret);
                return ret;
@@ -59,6 +63,10 @@ char *VFS_GetAbsPath(char *Path)
        // Check if the path is already absolute
        if(Path[0] == '/') {
                ret = malloc(pathLen + 1);
+               if(!ret) {
+                       Warning("VFS_GetAbsPath - malloc() returned NULL");
+                       return NULL;
+               }
                strcpy(ret, Path);
                baseLen = 1;
        } else {
@@ -392,7 +400,7 @@ int VFS_Open(char *Path, Uint Mode)
        if( !(Mode & VFS_OPENFLAG_NOLINK) && (node->Flags & VFS_FFLAG_SYMLINK) )
        {
                if( !node->Read ) {
-                       LOG("No read method on symlink");
+                       Warning("No read method on symlink");
                        LEAVE('i', -1);
                        return -1;
                }
@@ -495,6 +503,50 @@ void VFS_Close(int FD)
        h->Node = NULL;
 }
 
+/**
+ * \fn int VFS_ChDir(char *New)
+ * \brief Change current working directory
+ */
+int VFS_ChDir(char *New)
+{
+       char    *buf;
+        int    fd;
+       tVFS_Handle     *h;
+       
+       // Create Absolute
+       buf = VFS_GetAbsPath(New);
+       if(buf == NULL) {
+               Log("VFS_ChDir: Path expansion failed");
+               return -1;
+       }
+       
+       // Check if path exists
+       fd = VFS_Open(buf, VFS_OPENFLAG_EXEC);
+       if(fd == -1) {
+               Log("VFS_ChDir: Path is invalid");
+               return -1;
+       }
+       
+       // Get node so we can check for directory
+       h = VFS_GetHandle(fd);
+       if( !(h->Node->Flags & VFS_FFLAG_DIRECTORY) ) {
+               Log("VFS_ChDir: Path is not a directory");
+               VFS_Close(fd);
+               return -1;
+       }
+       
+       // Close file
+       VFS_Close(fd);
+       
+       // Free working directory and set new one
+       free( CFGPTR(CFG_VFS_CWD) );
+       CFGPTR(CFG_VFS_CWD) = buf;
+       
+       Log("Updated CWD to '%s'", buf);
+       
+       return 1;
+}
+
 /**
  * \fn tVFS_Handle *VFS_GetHandle(int FD)
  * \brief Gets a pointer to the handle information structure

UCC git Repository :: git.ucc.asn.au