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

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