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

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