X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Kernel%2Fvfs%2Fopen.c;h=d5e940ecb819172164e2e30d502ee81f4289e8eb;hb=2e19f113bc68fd38f59d469b213d251ee50e314d;hp=ac47683f0631bf201991aae00531cdc19dd7fba2;hpb=f04f6f4d823b7df2117da9737a3f12d080b54d74;p=tpg%2Facess2.git diff --git a/Kernel/vfs/open.c b/Kernel/vfs/open.c index ac47683f..d5e940ec 100644 --- a/Kernel/vfs/open.c +++ b/Kernel/vfs/open.c @@ -535,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;iNode == NULL) return NULL; + //Log_Debug("VFS", "VFS_GetHandle: RETURN %p", h); return h; }