Modules/FAT - Fixed edge cases in read
[tpg/acess2.git] / Modules / Filesystems / InitRD / main.c
1 /*
2  * Acess OS
3  * InitRD Driver Version 1
4  */
5 #include "initrd.h"
6 #include <modules.h>
7
8 #define DUMP_ON_MOUNT   1
9
10 // === IMPORTS ==
11 extern tVFS_Node        gInitRD_RootNode;
12 extern const int        giInitRD_NumFiles;
13 extern tVFS_Node * const        gInitRD_FileList[];
14
15 // === PROTOTYPES ===
16  int    InitRD_Install(char **Arguments);
17 tVFS_Node       *InitRD_InitDevice(const char *Device, const char **Arguments);
18 void    InitRD_Unmount(tVFS_Node *Node);
19 tVFS_Node       *InitRD_GetNodeFromINode(tVFS_Node *Root, Uint64 Inode);
20 Uint64  InitRD_ReadFile(tVFS_Node *Node, Uint64 Offset, Uint64 Size, void *Buffer);
21 char    *InitRD_ReadDir(tVFS_Node *Node, int ID);
22 tVFS_Node       *InitRD_FindDir(tVFS_Node *Node, const char *Name);
23 void    InitRD_DumpDir(tVFS_Node *Node, int Indent);
24
25 // === GLOBALS ===
26 MODULE_DEFINE(0, 0x0A, FS_InitRD, InitRD_Install, NULL);
27 tVFS_Driver     gInitRD_FSInfo = {
28         "initrd", 0, InitRD_InitDevice, InitRD_Unmount, InitRD_GetNodeFromINode
29         };
30
31 /**
32  * \brief Register initrd with the kernel
33  */
34 int InitRD_Install(char **Arguments)
35 {
36         Log_Notice("InitRD", "Installed");
37         VFS_AddDriver( &gInitRD_FSInfo );
38         
39         return MODULE_ERR_OK;
40 }
41
42 /**
43  * \brief Mount the InitRD
44  */
45 tVFS_Node *InitRD_InitDevice(const char *Device, const char **Arguments)
46 {
47         #if DUMP_ON_MOUNT
48         InitRD_DumpDir( &gInitRD_RootNode, 0 );
49         #endif
50         Log_Notice("InitRD", "Mounted");
51         return &gInitRD_RootNode;
52 }
53
54 /**
55  * \brief Unmount the InitRD
56  */
57 void InitRD_Unmount(tVFS_Node *Node)
58 {
59 }
60
61 /**
62  */
63 tVFS_Node *InitRD_GetNodeFromINode(tVFS_Node *Root, Uint64 Inode)
64 {
65         if( Inode >= giInitRD_NumFiles )        return NULL;
66         return gInitRD_FileList[Inode];
67 }
68
69 /**
70  * \brief Read from a file
71  */
72 Uint64 InitRD_ReadFile(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
73 {
74         if(Offset > Node->Size)
75                 return 0;
76         if(Offset + Length > Node->Size)
77                 Length = Node->Size - Offset;
78         
79         memcpy(Buffer, Node->ImplPtr+Offset, Length);
80         
81         return Length;
82 }
83
84 /**
85  * \brief Read from a directory
86  */
87 char *InitRD_ReadDir(tVFS_Node *Node, int ID)
88 {
89         tInitRD_File    *dir = Node->ImplPtr;
90         
91         if(ID >= Node->Size)
92                 return NULL;
93         
94         return strdup(dir[ID].Name);
95 }
96
97 /**
98  * \brief Find an element in a directory
99  */
100 tVFS_Node *InitRD_FindDir(tVFS_Node *Node, const char *Name)
101 {
102          int    i;
103         tInitRD_File    *dir = Node->ImplPtr;
104         
105         LOG("Name = '%s'", Name);
106         
107         for( i = 0; i < Node->Size; i++ )
108         {
109                 if(strcmp(Name, dir[i].Name) == 0)
110                         return dir[i].Node;
111         }
112         
113         return NULL;
114 }
115
116 void InitRD_DumpDir(tVFS_Node *Node, int Indent)
117 {
118          int    i;
119         char    indent[Indent+1];
120         tInitRD_File    *dir = Node->ImplPtr;
121         
122         for( i = 0; i < Indent; i++ )   indent[i] = ' ';
123         indent[i] = '\0';
124         
125         for( i = 0; i < Node->Size; i++ )
126         {
127                 Log_Debug("InitRD", "%s- %p %s", indent, dir[i].Node, dir[i].Name);
128                 if(dir[i].Node->Flags & VFS_FFLAG_DIRECTORY)
129                         InitRD_DumpDir(dir[i].Node, Indent+1);
130         }
131 }

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