Kernel - VFS API Update - ReadDir caller provided buffer
[tpg/acess2.git] / KernelLand / Kernel / vfs / open.c
index e7d6e1e..5ea67c1 100644 (file)
@@ -201,6 +201,7 @@ restart_parse:
                        *TruePath = malloc( gVFS_RootMount->MountPointLen+1 );
                        strcpy(*TruePath, gVFS_RootMount->MountPoint);
                }
+               gVFS_RootMount->OpenHandleCount ++;
                if(MountPoint)  *MountPoint = gVFS_RootMount;
                LEAVE('p', gVFS_RootMount->RootNode);
                return gVFS_RootMount->RootNode;
@@ -282,9 +283,16 @@ restart_parse:
                }
                
                // Check if the node has a FindDir method
+               if( !curNode->Type )
+               {
+                       LOG("Finddir failure on '%s' - No type", Path);
+                       Log_Error("VFS", "Node at '%s' has no type (mount %s:%s)",
+                               Path, mnt->Filesystem->Name, mnt->MountPoint);
+                       goto _error;
+               }
                if( !curNode->Type->FindDir )
                {
-                       LOG("Finddir failure on '%s'", Path);
+                       LOG("Finddir failure on '%s' - No FindDir method in %s", Path, curNode->Type->TypeName);
                        goto _error;
                }
                LOG("FindDir{=%p}(%p, '%s')", curNode->Type->FindDir, curNode, pathEle);
@@ -330,6 +338,7 @@ restart_parse:
                                path_buffer[ curNode->Size ] = '\0';
                                LOG("path_buffer = '%s'", path_buffer);
                                strcat(path_buffer, Path + ofs+nextSlash);
+                               // TODO: Pass to VFS_GetAbsPath to handle ../. in the symlink
                                
                                Path = path_buffer;
 //                             Log_Debug("VFS", "VFS_ParsePath: Symlink translated to '%s'", Path);
@@ -382,7 +391,7 @@ restart_parse:
        LOG("tmpNode = %p", tmpNode);
        // Check if file was found
        if(!tmpNode) {
-               LOG("Node '%s' not found in dir '%s'", &Path[ofs], Path);
+               LOG("Node '%s' not found in dir '%.*s'", &Path[ofs], ofs, Path);
                goto _error;
        }
        _CloseNode( curNode );
@@ -495,12 +504,44 @@ int VFS_OpenEx(const char *Path, Uint Flags, Uint Mode)
        if( !node && (Flags & VFS_OPENFLAG_CREATE) )
        {
                // TODO: Translate `Mode` into ACL and node flags
-               // Get parent, create node
-               if( VFS_MkNod(absPath, 0) ) {
+               Uint    new_flags = 0;
+               
+               // Split path at final separator
+               char *file = strrchr(absPath, '/');
+               *file = '\0';
+               file ++;
+
+               // Get parent node
+               tVFS_Mount      *pmnt;
+               tVFS_Node *pnode = VFS_ParsePath(absPath, NULL, &pmnt);
+               if(!pnode) {
+                       LOG("Unable to open parent '%s'", absPath);
+                       free(absPath);
+                       errno = ENOENT;
+                       LEAVE_RET('i', -1);
+               }
+
+               // TODO: Check ACLs on the parent
+               if( !VFS_CheckACL(pnode, VFS_PERM_EXECUTE|VFS_PERM_WRITE) ) {
+                       _CloseNode(pnode);
+                       pmnt->OpenHandleCount --;
                        free(absPath);
+                       LEAVE('i', -1);
                        return -1;
                }
-               node = VFS_ParsePath(absPath, NULL, &mnt);
+
+               // Check that there's a MkNod method
+               if( !pnode->Type || !pnode->Type->MkNod ) {
+                       Log_Warning("VFS", "VFS_Open - Directory has no MkNod method");
+                       errno = EINVAL;
+                       LEAVE_RET('i', -1);
+               }
+               
+               node = pnode->Type->MkNod(pnode, file, new_flags);
+               // Fall through on error check
+               
+               _CloseNode(pnode);
+               pmnt->OpenHandleCount --;
        }
        
        // Free generated path
@@ -646,7 +687,8 @@ void VFS_Close(int FD)
        
        _CloseNode(h->Node);
 
-       h->Mount->OpenHandleCount --;   
+       if( h->Mount )
+               h->Mount->OpenHandleCount --;   
 
        h->Node = NULL;
 }
@@ -693,7 +735,7 @@ int VFS_ChDir(const char *Dest)
                *cwdptr = buf;
        }
        
-       Log("Updated CWD to '%s'", buf);
+       Log_Debug("VFS", "Updated CWD to '%s'", buf);
        
        return 1;
 }

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