AcessNative - Updates for recent changes
[tpg/acess2.git] / AcessNative / acesskernel_src / nativefs.c
index 71774e2..1a07627 100644 (file)
  * nativefs.c\r
  * - Host filesystem access\r
  */\r
-#include <acess.h>\r
-#include <vfs.h>\r
+#define DEBUG  0\r
+#define off_t  _acess_off_t\r
+#define sprintf _acess_sprintf\r
+#include <acess.h>     // Acess\r
+#include <vfs.h>       // Acess\r
+#undef off_t\r
+#undef sprintf\r
+#include <dirent.h>    // Posix\r
+#include <sys/stat.h>  // Posix\r
+#include <stdio.h>     // Posix\r
+\r
+//NOTES:\r
+// tVFS_Node->ImplPtr is a pointer to the filesystem flags (tNativeFS)\r
+// tVFS_Node->Data is the path string (heap string)\r
+// tVFS_Node->ImplInt is the path length\r
+\r
+// === STRUCTURES ===\r
+typedef struct\r
+{\r
+       void    *InodeHandle;\r
+        int    bReadOnly;\r
+}      tNativeFS;\r
+\r
+// === PROTOTYPES ===\r
+ int   NativeFS_Install(char **Arguments);\r
+tVFS_Node      *NativeFS_Mount(const char *Device, const char **Arguments);\r
+void   NativeFS_Unmount(tVFS_Node *Node);\r
+tVFS_Node      *NativeFS_FindDir(tVFS_Node *Node, const char *Name, Uint Flags);\r
+ int   NativeFS_ReadDir(tVFS_Node *Node, int Position, char Dest[FILENAME_MAX]);\r
+size_t NativeFS_Read(tVFS_Node *Node, _acess_off_t Offset, size_t Length, void *Buffer, Uint Flags);\r
+size_t NativeFS_Write(tVFS_Node *Node, _acess_off_t Offset, size_t Length, const void *Buffer, Uint Flags);\r
+void   NativeFS_Close(tVFS_Node *Node);\r
 \r
 // === GLOBALS ===\r
+tVFS_NodeType  gNativeFS_FileNodeType = {\r
+       .Read = NativeFS_Read,\r
+       .Write = NativeFS_Write,\r
+       .Close = NativeFS_Close\r
+};\r
+tVFS_NodeType  gNativeFS_DirNodeType = {\r
+       .FindDir = NativeFS_FindDir,\r
+       .ReadDir = NativeFS_ReadDir,\r
+       .Close = NativeFS_Close\r
+};\r
+tVFS_Driver    gNativeFS_Driver = {\r
+       .Name = "nativefs",\r
+       .InitDevice = NativeFS_Mount,\r
+       .Unmount = NativeFS_Unmount\r
+};\r
 \r
 // === CODE ===\r
-tVFS_Node *Native_Mount(const char *Device, const char **Arguments)\r
+int NativeFS_Install(char **Arguments)\r
+{\r
+       VFS_AddDriver(&gNativeFS_Driver);\r
+       return 0;\r
+}\r
+\r
+tVFS_Node *NativeFS_Mount(const char *Device, const char **Arguments)\r
+{\r
+       tVFS_Node       *ret;\r
+       tNativeFS       *info;\r
+       DIR     *dp;\r
+       \r
+       dp = opendir(Device);\r
+       if(!dp) {\r
+               Log_Warning("NativeFS", "ERROR: Unable to open device root '%s'", Device);\r
+               return NULL;\r
+       }\r
+       \r
+       // Check if directory exists\r
+       // Parse flags from arguments\r
+       info = malloc(sizeof(tNativeFS));\r
+       info->InodeHandle = Inode_GetHandle(NULL);\r
+       info->bReadOnly = 0;\r
+       // Create node\r
+       ret = malloc(sizeof(tVFS_Node));\r
+       memset(ret, 0, sizeof(tVFS_Node));\r
+       ret->Data = strdup(Device);\r
+       ret->ImplInt = strlen(ret->Data);\r
+       ret->ImplPtr = info;\r
+       ret->Inode = (Uint64)(tVAddr)dp;\r
+       ret->Flags = VFS_FFLAG_DIRECTORY;\r
+\r
+       ret->Type = &gNativeFS_DirNodeType;     \r
+\r
+       return ret;\r
+}\r
+\r
+void NativeFS_Unmount(tVFS_Node *Node)\r
+{\r
+       tNativeFS       *info = Node->ImplPtr;\r
+       Inode_ClearCache( info->InodeHandle );\r
+       closedir( (void *)(tVAddr)Node->Inode );\r
+       free(Node->Data);\r
+       free(Node);\r
+       free(info);\r
+}\r
+\r
+void NativeFS_Close(tVFS_Node *Node)\r
+{\r
+       tNativeFS       *info = Node->ImplPtr;\r
+       DIR     *dp = (Node->Flags & VFS_FFLAG_DIRECTORY) ? (DIR*)(tVAddr)Node->Inode : 0;\r
+       FILE    *fp = (Node->Flags & VFS_FFLAG_DIRECTORY) ? 0 : (FILE*)(tVAddr)Node->Inode;\r
+       \r
+       if( Inode_UncacheNode( info->InodeHandle, Node->Inode ) == 1 ) {\r
+               if(dp)  closedir(dp);\r
+               if(fp)  fclose(fp);\r
+       }\r
+}\r
+\r
+tVFS_Node *NativeFS_FindDir(tVFS_Node *Node, const char *Name, Uint Flags)\r
+{\r
+       char    *path;\r
+       tNativeFS       *info = Node->ImplPtr;\r
+       tVFS_Node       baseRet;\r
+       struct stat statbuf;\r
+\r
+       ENTER("pNode sName", Node, Name);\r
+       \r
+       // Create path\r
+       path = malloc(Node->ImplInt + 1 + strlen(Name) + 1);\r
+       strcpy(path, Node->Data);\r
+       path[Node->ImplInt] = '/';\r
+       strcpy(path + Node->ImplInt + 1, Name);\r
+       \r
+       LOG("path = '%s'", path);\r
+       \r
+       // Check if file exists\r
+       if( stat(path, &statbuf) ) {\r
+               free(path);\r
+               LOG("Doesn't exist");\r
+               LEAVE('n');\r
+               return NULL;\r
+       }\r
+       \r
+       memset(&baseRet, 0, sizeof(tVFS_Node));\r
+       \r
+       // Check file type\r
+       if( S_ISDIR(statbuf.st_mode) )\r
+       {\r
+               LOG("Directory");\r
+               baseRet.Inode = (Uint64)(tVAddr) opendir(path);\r
+               baseRet.Type = &gNativeFS_DirNodeType;\r
+               baseRet.Flags |= VFS_FFLAG_DIRECTORY;\r
+               baseRet.Size = -1;\r
+       }\r
+       else\r
+       {\r
+               LOG("File");\r
+               FILE    *fp = fopen(path, "r+");\r
+               if( !fp ) {\r
+                       Log_Error("NativeFS", "fopen of '%s' failed: %s", path, strerror(errno));\r
+                       free(path);\r
+                       LEAVE('n');\r
+                       return NULL;\r
+               }\r
+               baseRet.Inode = (Uint64)(tVAddr) fp;\r
+               baseRet.Type = &gNativeFS_FileNodeType;\r
+               \r
+               fseek( fp, 0, SEEK_END );\r
+               baseRet.Size = ftell( fp );\r
+       }\r
+       \r
+       // Create new node\r
+       baseRet.ImplPtr = info;\r
+       baseRet.ImplInt = strlen(path);\r
+       baseRet.Data = path;\r
+       \r
+       LEAVE('-');\r
+       return Inode_CacheNode(info->InodeHandle, &baseRet);\r
+}\r
+\r
+int NativeFS_ReadDir(tVFS_Node *Node, int Position, char Dest[FILENAME_MAX])\r
 {\r
-       return NULL;\r
+       struct dirent   *ent;\r
+       DIR     *dp = (void*)(tVAddr)Node->Inode;\r
+\r
+       ENTER("pNode iPosition", Node, Position);\r
+\r
+       // TODO: Keep track of current position in the directory\r
+       // TODO: Lock node during this\r
+       rewinddir(dp);\r
+       do {\r
+               ent = readdir(dp);\r
+       } while(Position-- && ent);\r
+\r
+       if( !ent ) {\r
+               LEAVE('i', -ENOENT);\r
+               return -ENOENT;\r
+       }\r
+       \r
+       strncpy(Dest, ent->d_name, FILENAME_MAX);\r
+\r
+       // TODO: Unlock node    \r
+\r
+       LEAVE('i', 0);\r
+       return 0;\r
+}\r
+\r
+size_t NativeFS_Read(tVFS_Node *Node, _acess_off_t Offset, size_t Length, void *Buffer, Uint Flags)\r
+{\r
+       ENTER("pNode XOffset xLength pBuffer", Node, Offset, Length, Buffer);\r
+       if( fseek( (FILE *)(tVAddr)Node->Inode, Offset, SEEK_SET ) != 0 )\r
+       {\r
+               LEAVE('i', 0);\r
+               return 0;\r
+       }\r
+       size_t ret = fread( Buffer, 1, Length, (FILE *)(tVAddr)Node->Inode );\r
+       LEAVE('x', ret);\r
+       return ret;\r
+}\r
+\r
+size_t NativeFS_Write(tVFS_Node *Node, _acess_off_t Offset, size_t Length, const void *Buffer, Uint Flags)\r
+{\r
+       FILE    *fp = (FILE *)(tVAddr)Node->Inode;\r
+       ENTER("pNode XOffset xLength pBuffer", Node, Offset, Length, Buffer);\r
+       if( fseek( fp, Offset, SEEK_SET ) != 0 )\r
+       {\r
+               LEAVE('i', 0);\r
+               return 0;\r
+       }\r
+       size_t ret = fwrite( Buffer, 1, Length, fp );\r
+       fflush( fp );\r
+       LEAVE('i', ret);\r
+       return ret;\r
+\r
 }\r

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