+ 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
+ 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
+tVFS_Node *NativeFS_MkNod(tVFS_Node *Node, const char *Name, Uint Flags)\r
+{\r
+ char path[Node->ImplInt+1+strlen(Name)+1];\r
+ sprintf(path, "%s/%s", Node->Data, Name);\r
+ if( Flags & VFS_FFLAG_DIRECTORY )\r
+ {\r
+ mkdir(path, 0755);\r
+ }\r
+ else\r
+ {\r
+ FILE *tmp = fopen(path, "w");\r
+ if(!tmp) return NULL;\r
+ fclose(tmp);\r
+ }\r
+ return NativeFS_FindDir(Node, Name, 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