X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Kernel%2Fvfs%2Fopen.c;h=d203571327283e6d271fc5128ccc8ebf881fca97;hb=077a1c5d962b20dee54c6b31c8f37d2fe79105ad;hp=3a687037442a37943c82634e4b7ff9da85cea6c5;hpb=47e9dfd89189fc6b150bd6b20229cb047c7e0858;p=tpg%2Facess2.git diff --git a/Kernel/vfs/open.c b/Kernel/vfs/open.c index 3a687037..d2035713 100644 --- a/Kernel/vfs/open.c +++ b/Kernel/vfs/open.c @@ -3,7 +3,7 @@ * - Open, Close and ChDir */ #define DEBUG 0 -#include +#include #include "vfs.h" #include "vfs_int.h" #include "vfs_ext.h" @@ -15,7 +15,7 @@ // === IMPORTS === extern tVFS_Node gVFS_MemRoot; -extern tVFS_Mount *gRootMount; +extern tVFS_Mount *gVFS_RootMount; // === GLOBALS === tVFS_Handle *gaUserHandles = (void*)MM_PPD_VFS; @@ -172,7 +172,7 @@ char *VFS_GetAbsPath(char *Path) tVFS_Node *VFS_ParsePath(char *Path, char **TruePath) { tVFS_Mount *mnt; - tVFS_Mount *longestMount = gRootMount; // Root is first + tVFS_Mount *longestMount = gVFS_RootMount; // Root is first int cmp, retLength = 0; int ofs, nextSlash; tVFS_Node *curNode, *tmpNode; @@ -194,21 +194,21 @@ tVFS_Node *VFS_ParsePath(char *Path, char **TruePath) if(Path[0] == '/' && Path[1] == '\0') { if(TruePath) { - *TruePath = malloc( gRootMount->MountPointLen+1 ); - strcpy(*TruePath, gRootMount->MountPoint); + *TruePath = malloc( gVFS_RootMount->MountPointLen+1 ); + strcpy(*TruePath, gVFS_RootMount->MountPoint); } - LEAVE('p', gRootMount->RootNode); - return gRootMount->RootNode; + LEAVE('p', gVFS_RootMount->RootNode); + return gVFS_RootMount->RootNode; } // Check if there is anything mounted - if(!gMounts) { + if(!gVFS_Mounts) { Warning("WTF! There's nothing mounted?"); return NULL; } // Find Mountpoint - for(mnt = gMounts; + for(mnt = gVFS_Mounts; mnt; mnt = mnt->Next) { @@ -269,7 +269,7 @@ tVFS_Node *VFS_ParsePath(char *Path, char **TruePath) // Check permissions on root of filesystem if( !VFS_CheckACL(curNode, VFS_PERM_EXECUTE) ) { - curNode->Close( curNode ); + if(curNode->Close) curNode->Close( curNode ); if(TruePath) { free(*TruePath); *TruePath = NULL; @@ -280,7 +280,8 @@ tVFS_Node *VFS_ParsePath(char *Path, char **TruePath) } // Check if the node has a FindDir method - if(!curNode->FindDir) { + if( !curNode->FindDir ) + { if(curNode->Close) curNode->Close(curNode); if(TruePath) { free(*TruePath); @@ -295,8 +296,7 @@ tVFS_Node *VFS_ParsePath(char *Path, char **TruePath) // Get Child Node tmpNode = curNode->FindDir(curNode, &Path[ofs]); LOG("tmpNode = %p", tmpNode); - if(curNode->Close) - curNode->Close(curNode); + if(curNode->Close) curNode->Close(curNode); curNode = tmpNode; // Error Check @@ -319,6 +319,13 @@ tVFS_Node *VFS_ParsePath(char *Path, char **TruePath) *TruePath = NULL; } tmp = malloc( curNode->Size + 1 ); + if(!curNode->Read) { + Warning("VFS_ParsePath - Read of node %p is NULL (%s)", + curNode, Path); + if(curNode->Close) curNode->Close(curNode); + LEAVE('n'); + return NULL; + } curNode->Read( curNode, 0, curNode->Size, tmp ); tmp[ curNode->Size ] = '\0'; @@ -471,7 +478,7 @@ int VFS_Open(char *Path, Uint Mode) // Permissions Check if( !VFS_CheckACL(node, i) ) { - node->Close( node ); + if(node->Close) node->Close( node ); Log("VFS_Open: Permissions Failed"); LEAVE('i', -1); return -1; @@ -528,6 +535,107 @@ int VFS_Open(char *Path, Uint Mode) return -1; } + +/** + * \brief Open a file from an open directory + */ +int VFS_OpenChild(Uint *Errno, int FD, char *Name, Uint Mode) +{ + tVFS_Handle *h; + tVFS_Node *node; + int i; + + // Get handle + h = VFS_GetHandle(FD); + if(h == NULL) { + Log_Warning("VFS", "VFS_OpenChild - Invalid file handle 0x%x", FD); + if(Errno) *Errno = EINVAL; + LEAVE('i', -1); + return -1; + } + + // Check for directory + if( !(h->Node->Flags & VFS_FFLAG_DIRECTORY) ) { + Log_Warning("VFS", "VFS_OpenChild - Passed handle is not a directory", FD); + if(Errno) *Errno = ENOTDIR; + LEAVE('i', -1); + return -1; + } + + // Find Child + node = h->Node->FindDir(h->Node, Name); + if(!node) { + if(Errno) *Errno = ENOENT; + LEAVE('i', -1); + return -1; + } + + i = 0; + i |= (Mode & VFS_OPENFLAG_EXEC) ? VFS_PERM_EXECUTE : 0; + i |= (Mode & VFS_OPENFLAG_READ) ? VFS_PERM_READ : 0; + i |= (Mode & VFS_OPENFLAG_WRITE) ? VFS_PERM_WRITE : 0; + + // Permissions Check + if( !VFS_CheckACL(node, i) ) { + if(node->Close) node->Close( node ); + Log_Notice("VFS", "VFS_OpenChild - Permissions Failed"); + if(Errno) *Errno = EACCES; + LEAVE('i', -1); + return -1; + } + + // Check for a user open + if(Mode & VFS_OPENFLAG_USER) + { + // Allocate Buffer + if( MM_GetPhysAddr( (Uint)gaUserHandles ) == 0 ) + { + Uint addr, size; + size = CFGINT(CFG_VFS_MAXFILES) * sizeof(tVFS_Handle); + for(addr = 0; addr < size; addr += 0x1000) + MM_Allocate( (Uint)gaUserHandles + addr ); + memset( gaUserHandles, 0, size ); + } + // Get a handle + for(i=0;i