Merge branch 'master' of [email protected]:acess2
[tpg/acess2.git] / AcessNative / acesskernel_src / nativefs.c
1 /*\r
2  * Acess2 Native Kernel\r
3  * - Acess kernel emulation on another OS using SDL and UDP\r
4  *\r
5  * nativefs.c\r
6  * - Host filesystem access\r
7  */\r
8 #define DEBUG   1\r
9 #include <acess.h>      // Acess\r
10 #include <vfs.h>        // Acess\r
11 #include <dirent.h>     // Posix\r
12 #include <sys/stat.h>   // Posix\r
13 #include <stdio.h>      // Posix\r
14 \r
15 //NOTES:\r
16 // tVFS_Node->ImplPtr is a pointer to the filesystem flags (tNativeFS)\r
17 // tVFS_Node->Data is the path string (heap string)\r
18 // tVFS_Node->ImplInt is the path length\r
19 \r
20 // === STRUCTURES ===\r
21 typedef struct\r
22 {\r
23          int    InodeHandle;\r
24          int    bReadOnly;\r
25 }       tNativeFS;\r
26 \r
27 // === PROTOTYPES ===\r
28  int    NativeFS_Install(char **Arguments);\r
29 tVFS_Node       *NativeFS_Mount(const char *Device, const char **Arguments);\r
30 void    NativeFS_Unmount(tVFS_Node *Node);\r
31 tVFS_Node       *NativeFS_FindDir(tVFS_Node *Node, const char *Name);\r
32 char    *NativeFS_ReadDir(tVFS_Node *Node, int Position);\r
33 Uint64  NativeFS_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer);\r
34 \r
35 // === GLOBALS ===\r
36 tVFS_Driver     gNativeFS_Driver = {\r
37         "nativefs", 0,\r
38         NativeFS_Mount, NativeFS_Unmount,\r
39         NULL,\r
40 };\r
41 \r
42 // === CODE ===\r
43 int NativeFS_Install(char **Arguments)\r
44 {\r
45         VFS_AddDriver(&gNativeFS_Driver);\r
46         return 0;\r
47 }\r
48 \r
49 tVFS_Node *NativeFS_Mount(const char *Device, const char **Arguments)\r
50 {\r
51         tVFS_Node       *ret;\r
52         tNativeFS       *info;\r
53         DIR     *dp;\r
54         \r
55         dp = opendir(Device);\r
56         if(!dp) return NULL;\r
57         \r
58         // Check if directory exists\r
59         // Parse flags from arguments\r
60         info = malloc(sizeof(tNativeFS));\r
61         info->InodeHandle = Inode_GetHandle();\r
62         info->bReadOnly = 0;\r
63         // Create node\r
64         ret = malloc(sizeof(tVFS_Node));\r
65         memset(ret, 0, sizeof(tVFS_Node));\r
66         ret->Data = strdup(Device);\r
67         ret->ImplInt = strlen(ret->Data);\r
68         ret->ImplPtr = info;\r
69         ret->Inode = (Uint64)dp;\r
70         \r
71         ret->FindDir = NativeFS_FindDir;\r
72         ret->ReadDir = NativeFS_ReadDir;\r
73         \r
74         return ret;\r
75 }\r
76 \r
77 void NativeFS_Unmount(tVFS_Node *Node)\r
78 {\r
79         tNativeFS       *info = Node->ImplPtr;\r
80         Inode_ClearCache( info->InodeHandle );\r
81         closedir( (void *)Node->Inode );\r
82         free(Node->Data);\r
83         free(Node);\r
84         free(info);\r
85 }\r
86 \r
87 void NativeFS_Close(tVFS_Node *Node)\r
88 {\r
89         tNativeFS       *info = Node->ImplPtr;\r
90         Inode_UncacheNode( info->InodeHandle, Node->Inode );\r
91 }\r
92 \r
93 tVFS_Node *NativeFS_FindDir(tVFS_Node *Node, const char *Name)\r
94 {\r
95         char    *path = malloc(Node->ImplInt + 1 + strlen(Name) + 1);\r
96         tNativeFS       *info = Node->ImplPtr;\r
97         tVFS_Node       baseRet;\r
98         struct stat statbuf;\r
99 \r
100         ENTER("pNode sName", Node, Name);\r
101         \r
102         // Create path\r
103         strcpy(path, Node->Data);\r
104         path[Node->ImplInt] = '/';\r
105         strcpy(path + Node->ImplInt + 1, Name);\r
106         \r
107         LOG("path = '%s'", path);\r
108         \r
109         // Check if file exists\r
110         if( stat(path, &statbuf) ) {\r
111                 free(path);\r
112                 LOG("Doesn't exist");\r
113                 LEAVE('n');\r
114                 return NULL;\r
115         }\r
116         \r
117         memset(&baseRet, 0, sizeof(tVFS_Node));\r
118         \r
119         // Check file type\r
120         if( S_ISDIR(statbuf.st_mode) )\r
121         {\r
122                 LOG("Directory");\r
123                 baseRet.Inode = (Uint64) opendir(path);\r
124                 baseRet.FindDir = NativeFS_FindDir;\r
125                 baseRet.ReadDir = NativeFS_ReadDir;\r
126                 baseRet.Flags |= VFS_FFLAG_DIRECTORY;\r
127         }\r
128         else\r
129         {\r
130                 LOG("File");\r
131                 baseRet.Inode = (Uint64) fopen(path, "r+");\r
132                 baseRet.Read = NativeFS_Read;\r
133         }\r
134         \r
135         // Create new node\r
136         baseRet.ImplPtr = info;\r
137         baseRet.ImplInt = strlen(path);\r
138         baseRet.Data = path;\r
139         \r
140         LEAVE('-');\r
141         return Inode_CacheNode(info->InodeHandle, &baseRet);\r
142 }\r
143 \r
144 char *NativeFS_ReadDir(tVFS_Node *Node, int Position)\r
145 {\r
146         // Keep track of the current directory position\r
147         return NULL;\r
148 }\r
149 \r
150 Uint64 NativeFS_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)\r
151 {\r
152         ENTER("pNode XOffset XLength pBuffer", Node, Offset, Length, Buffer);\r
153         if( fseek( (void *)Node->Inode, Offset, SEEK_SET ) != 0 )\r
154         {\r
155                 LEAVE('i', 0);\r
156                 return 0;\r
157         }\r
158         LEAVE('-');\r
159         return fread( Buffer, 1, Length, (void *)Node->Inode );\r
160 }\r

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