make sure "S" is generated.
[AROS-Contrib.git] / vpdf / system / directory.c
blob46e13aad05d71329350bef170e4a9f73f4e10d64
2 #define AROS_ALMOST_COMPATIBLE
5 #include <exec/lists.h>
6 #include <exec/types.h>
7 #include <proto/dos.h>
8 #include <proto/utility.h>
9 #include <proto/intuition.h>
10 #include <private/vapor/vapor.h>
12 #include "directory.h"
13 #include "dlist.h"
14 #include "functions.h"
15 #include "util.h"
17 #include <stdio.h>
18 #include <stdlib.h>
21 * Helper functions
24 char *directoryGetNodeName(struct directory *dir, struct directorynode *node)
26 char *name = NULL;
28 if (dir != NULL && node != NULL)
30 int l = strlen(dir->basename) + 1 + strlen(node->name) + 1;
32 name = malloc(l);
34 if (name != NULL)
36 strcpy(name, dir->basename);
37 AddPart(name, node->name, l);
41 return name;
44 void directoryFreeNodeName(char *name)
46 free(name);
49 struct directorynode *directoryFindNode(struct directory *dir, char *name)
51 struct directorynode *n;
53 if (name[ strlen(name) - 1 ] == '/')
55 name[ strlen(name) - 1 ] = 0;
58 if (FilePart(name) != NULL && strlen(FilePart(name)) > 0)
59 name = FilePart(name);
62 ITERATELIST(n, &dir->list)
64 if (0 == stricmp(n->name, name))
65 return n;
68 return NULL;
73 char *directoryGetParentName(char *dir)
75 char path[ 1024 ];
76 char *newpath = NULL;
77 BPTR lock;
79 if (dir == NULL || strlen(dir) == 0)
80 return NULL;
82 strncpy(path, dir, sizeof(path));
84 lock = Lock(path, ACCESS_READ);
86 if (lock)
88 /* we are in a valid path. use the "good" way */
90 BPTR parentLock = ParentDir(lock);
91 UnLock(lock);
93 if (parentLock && NameFromLock(parentLock, path, sizeof(path)))
95 newpath = strdup(path);
98 if (parentLock)
99 UnLock(parentLock);
101 else
103 /* we are in some strange path. try to find parent ourself */
105 if (strlen(path))
107 char *prevPath;
109 if (path[ strlen(path) - 1 ] == '/')
111 path[ strlen(path) - 1 ] = 0;
114 prevPath = PathPart(path);
116 path[ prevPath - path ] = 0;
118 newpath = strdup(path);
123 return newpath;
127 * Sort directory tree (single level!).
130 static int dirnodecompare(struct MinNode *n1, struct MinNode *n2)
132 struct directorynode *dn1 = (struct directorynode*)n1;
133 struct directorynode *dn2 = (struct directorynode*)n2;
135 if ((dn1->dir && dn2->dir) || (!dn1->dir && !dn2->dir) )
137 return stricmp(dn1->name, dn2->name);
139 else
141 if (dn1->dir && !dn2->dir)
142 return -1;
143 else
144 return 1;
148 static void directorySort(struct directory *dir)
150 mergesortlist(&dir->list, dirnodecompare);
155 * Scan directory tree.
158 struct directory *directoryScan(const char *path, int flags)
160 BPTR dirLock = Lock(path, ACCESS_READ);
161 struct FileInfoBlock fib;
162 struct directory *directory = malloc(sizeof(struct directory) + strlen(path) + 1);
164 if (dirLock == NULL || directory == NULL)
166 free(directory);
168 if (dirLock)
169 UnLock(dirLock);
171 return NULL;
174 NEWLIST(&directory->list);
175 strcpy(directory->basename, path);
177 if (Examine(dirLock, &fib))
179 if (isDir(&fib))
181 /* fine. we can start examining the entries */
183 while(ExNext(dirLock, &fib))
185 /* build new name node */
187 struct directorynode *n = malloc(sizeof(struct directorynode) + strlen(fib.fib_FileName) + 1);
189 if (n)
191 strcpy(n->name, fib.fib_FileName);
192 n->dir = isDir(&fib);
193 n->subdir = NULL;
195 if (n->dir && (flags & DIRECTORY_SCAN_RECURSIVE))
197 char *fullpath = directoryGetNodeName(directory, n);
199 if (fullpath)
201 n->subdir = directoryScan(fullpath, flags);
202 directoryFreeNodeName(fullpath);
206 ADDTAIL(&directory->list, n);
212 UnLock(dirLock);
216 if (flags & DIRECTORY_SORT)
217 directorySort(directory);
220 * Debug dump.
223 if (0)
225 struct directorynode *n;
228 printf("Contents of: <%s>\n", directory->basename);
230 ITERATELIST(n, &directory->list)
232 printf("<%s>\n", n->name);
236 return directory;
239 DirectoryTraverseResult directoryTraverse(const char *path, int flags, DirectoryTraverseResult (*callback)(struct FileInfoBlock *fib, char *path, int level, void *data), void *data)
241 if (flags & DIRECTORY_SORT)
243 int rc = DIRECTORY_TRAVERSE_CONTINUE;
244 struct directory *directory = directoryScan(path, DIRECTORY_SORT);
246 if (directory != NULL)
248 struct directorynode *n;
250 ITERATELIST(n, &directory->list)
252 char *fullpath = directoryGetNodeName(directory, n);
253 if (fullpath != NULL)
255 if (n->dir == FALSE)
256 rc = callback(NULL, fullpath, 0, data);
257 else if (flags & DIRECTORY_SCAN_RECURSIVE)
258 rc = directoryTraverse(fullpath, flags, callback, data);
260 directoryFreeNodeName(fullpath);
262 else
264 rc = DIRECTORY_TRAVERSE_ERROR;
265 break;
268 if (rc != DIRECTORY_TRAVERSE_CONTINUE)
269 break;
272 directoryFree(directory);
275 else
277 rc = DIRECTORY_TRAVERSE_ERROR;
280 return rc;
282 else
285 BPTR dirLock = Lock(path, ACCESS_READ);
286 struct FileInfoBlock fib;
287 int bufflen = strlen(path) + 109;
288 char *fullpath = malloc(bufflen);
289 int rc = DIRECTORY_TRAVERSE_CONTINUE;
291 if (dirLock == NULL || fullpath == NULL)
293 free(fullpath);
294 return DIRECTORY_TRAVERSE_ERROR;
297 if (Examine(dirLock, &fib))
299 if (isDir(&fib))
301 /* fine. we can start examining the entries */
303 while(rc == DIRECTORY_TRAVERSE_CONTINUE && ExNext(dirLock, &fib))
305 strcpy(fullpath, path);
306 AddPart(fullpath, fib.fib_FileName, bufflen);
308 if (isDir(&fib) && (flags & DIRECTORY_SCAN_RECURSIVE))
310 rc = directoryTraverse(fullpath, flags, callback, data);
311 if (rc == DIRECTORY_TRAVERSE_OK)
312 rc = DIRECTORY_TRAVERSE_CONTINUE;
314 if (!isDir(&fib))
315 rc = callback(&fib, fullpath, 0, data);
319 UnLock(dirLock);
322 free(fullpath);
324 if (rc == DIRECTORY_TRAVERSE_ABORTDIR || rc == DIRECTORY_TRAVERSE_CONTINUE)
325 rc = DIRECTORY_TRAVERSE_OK;
327 return rc;
331 void directoryFree(struct directory *dir)
333 if (dir != NULL)
335 struct directorynode *dn;
337 while((dn = (struct directorynode*)GetTail(&dir->list)))
339 directoryFree(dn->subdir);
340 REMOVE(dn);
341 free(dn);
344 free(dir);
348 int dirCreatePath(char *path)
350 int pos = 0;
351 char constructedPath[ 1024 ];
353 /* check if it doesn't exist */
356 BPTR lock;
357 char *eoPath = PathPart(path);
358 char t = eoPath[ 0 ];
360 /* temporarely cut the file from path */
362 eoPath[ 0 ] = 0;
364 lock = Lock(path, ACCESS_READ);
365 if (lock)
367 UnLock(lock);
369 /* restore file part */
371 eoPath[ 0 ] = t;
373 return TRUE;
376 /* restore file part */
378 eoPath[ 0 ] = t;
381 constructedPath[ 0 ] = 0;
385 char buff[ 256 ];
386 pos = SplitName(path, '/', buff, pos, sizeof(buff));
388 if (pos != -1) /* last part is filename itself */
390 BPTR dLock;
392 AddPart(constructedPath, buff, sizeof(constructedPath));
394 dLock = CreateDir(constructedPath);
396 if (dLock)
398 UnLock(dLock);
400 else
405 } while(pos != -1);
407 return TRUE;