Kernel/ARMv7 - Fixed not using ASIDs
[tpg/acess2.git] / Kernel / vfs / dir.c
1 /*
2  * Acess2 VFS
3  * - Directory Management Functions
4  */
5 #define DEBUG   0
6 #include <acess.h>
7 #include <vfs.h>
8 #include <vfs_int.h>
9
10 // === IMPORTS ===
11 extern tVFS_Mount       *gRootMount;
12
13 // === PROTOTYPES ===
14 #if 0
15  int    VFS_MkDir(const char *Path);
16 #endif
17  int    VFS_MkNod(const char *Path, Uint Flags);
18 // int  VFS_Symlink(const char *Name, const char *Link);
19
20 // === CODE ===
21 /**
22  * \fn int VFS_MkDir(char *Path)
23  * \brief Create a new node
24  * \param Path  Path of directory to create
25  */
26 int VFS_MkDir(const char *Path)
27 {
28         return VFS_MkNod(Path, VFS_FFLAG_DIRECTORY);
29 }
30
31 /**
32  * \fn int VFS_MkNod(char *Path, Uint Flags)
33  * \brief Create a new node in a directory
34  * \param Path  Path of new node
35  * \param Flags Flags to apply to the node
36  */
37 int VFS_MkNod(const char *Path, Uint Flags)
38 {
39         char    *absPath, *name;
40          int    pos = 0, oldpos = 0;
41          int    next = 0;
42         tVFS_Node       *parent;
43          int    ret;
44         
45         ENTER("sPath xFlags", Path, Flags);
46         
47         absPath = VFS_GetAbsPath(Path);
48         LOG("absPath = '%s'", absPath);
49         
50         while( (next = strpos(&absPath[pos+1], '/')) != -1 ) {
51                 LOG("next = %i", next);
52                 pos += next+1;
53                 LOG("pos = %i", pos);
54                 oldpos = pos;
55         }
56         absPath[oldpos] = '\0'; // Mutilate path
57         name = &absPath[oldpos+1];
58         
59         LOG("absPath = '%s', name = '%s'", absPath, name);
60         
61         // Check for root
62         if(absPath[0] == '\0')
63                 parent = VFS_ParsePath("/", NULL, NULL);
64         else
65                 parent = VFS_ParsePath(absPath, NULL, NULL);
66         
67         LOG("parent = %p", parent);
68         
69         if(!parent) {
70                 LEAVE('i', -1);
71                 return -1;      // Error Check
72         }
73         
74         // Permissions Check
75         if( !VFS_CheckACL(parent, VFS_PERM_EXECUTE|VFS_PERM_WRITE) ) {
76                 if(parent->Close)       parent->Close( parent );
77                 free(absPath);
78                 LEAVE('i', -1);
79                 return -1;
80         }
81         
82         LOG("parent = %p", parent);
83         
84         if(parent->MkNod == NULL) {
85                 Warning("VFS_MkNod - Directory has no MkNod method");
86                 LEAVE('i', -1);
87                 return -1;
88         }
89         
90         // Create node
91         ret = parent->MkNod(parent, name, Flags);
92         
93         // Free allocated string
94         free(absPath);
95         
96         // Free Parent
97         if(parent->Close)       parent->Close( parent );
98         
99         // Error Check
100         if(ret == 0) {
101                 LEAVE('i', -1);
102                 return -1;
103         }
104         
105         LEAVE('i', 0);
106         return 0;
107 }
108
109 /**
110  * \fn int VFS_Symlink(const char *Name, const char *Link)
111  * \brief Creates a symlink called \a Name to \a Link
112  * \param Name  Name of symbolic link
113  * \param Link  Destination of symbolic link
114  */
115 int VFS_Symlink(const char *Name, const char *Link)
116 {
117         char    *realLink;
118          int    fp;
119         char    *_link;
120         
121         ENTER("sName sLink", Name, Link);
122         
123         // Get absolue path name
124         _link = VFS_GetAbsPath( Link );
125         if(!_link) {
126                 Log_Warning("VFS", "Path '%s' is badly formed", Link);
127                 LEAVE('i', -1);
128                 return -1;
129         }
130
131         LOG("_link = '%s'", _link);
132         
133         #if 1
134         {
135         tVFS_Node *destNode = VFS_ParsePath( _link, &realLink, NULL );
136         #if 0
137         // Get true path and node
138         free(_link);
139         _link = NULL;
140         #else
141         realLink = _link;
142         #endif
143         
144         // Check if destination exists
145         if(!destNode) {
146                 Log_Warning("VFS", "File '%s' does not exist, symlink not created", Link);
147                 return -1;
148         }
149         
150         // Derefence the destination
151         if(destNode->Close)     destNode->Close(destNode);
152         }
153         #else
154         realLink = _link;
155         #endif  
156         LOG("realLink = '%s'", realLink);
157
158         // Make node
159         if( VFS_MkNod(Name, VFS_FFLAG_SYMLINK) != 0 ) {
160                 Log_Warning("VFS", "Unable to create link node '%s'", Name);
161                 LEAVE('i', -2);
162                 return -2;      // Make link node
163         }
164         
165         // Write link address
166         fp = VFS_Open(Name, VFS_OPENFLAG_WRITE|VFS_OPENFLAG_NOLINK);
167         VFS_Write(fp, strlen(realLink), realLink);
168         VFS_Close(fp);
169         
170         free(realLink);
171         
172         LEAVE('i', 1);
173         return 1;
174 }
175
176 /**
177  * \fn int VFS_ReadDir(int FD, char *Dest)
178  * \brief Read from a directory
179  */
180 int VFS_ReadDir(int FD, char *Dest)
181 {
182         tVFS_Handle     *h = VFS_GetHandle(FD);
183         char    *tmp;
184         
185         //ENTER("ph pDest", h, Dest);
186         
187         if(!h || h->Node->ReadDir == NULL) {
188                 //LEAVE('i', 0);
189                 return 0;
190         }
191         
192         if(h->Node->Size != -1 && h->Position >= h->Node->Size) {
193                 //LEAVE('i', 0);
194                 return 0;
195         }
196         
197         do {
198                 tmp = h->Node->ReadDir(h->Node, h->Position);
199                 if((Uint)tmp < (Uint)VFS_MAXSKIP)
200                         h->Position += (Uint)tmp;
201                 else
202                         h->Position ++;
203         } while(tmp != NULL && (Uint)tmp < (Uint)VFS_MAXSKIP);
204         
205         //LOG("tmp = '%s'", tmp);
206         
207         if(!tmp) {
208                 //LEAVE('i', 0);
209                 return 0;
210         }
211         
212         strcpy(Dest, tmp);
213         free(tmp);
214         
215         //LEAVE('i', 1);
216         return 1;
217 }

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