2 #define AROS_ALMOST_COMPATIBLE
5 #include <exec/lists.h>
6 #include <exec/types.h>
8 #include <proto/utility.h>
9 #include <proto/intuition.h>
10 #include <private/vapor/vapor.h>
12 #include "directory.h"
14 #include "functions.h"
24 char *directoryGetNodeName(struct directory
*dir
, struct directorynode
*node
)
28 if (dir
!= NULL
&& node
!= NULL
)
30 int l
= strlen(dir
->basename
) + 1 + strlen(node
->name
) + 1;
36 strcpy(name
, dir
->basename
);
37 AddPart(name
, node
->name
, l
);
44 void directoryFreeNodeName(char *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
))
73 char *directoryGetParentName(char *dir
)
79 if (dir
== NULL
|| strlen(dir
) == 0)
82 strncpy(path
, dir
, sizeof(path
));
84 lock
= Lock(path
, ACCESS_READ
);
88 /* we are in a valid path. use the "good" way */
90 BPTR parentLock
= ParentDir(lock
);
93 if (parentLock
&& NameFromLock(parentLock
, path
, sizeof(path
)))
95 newpath
= strdup(path
);
103 /* we are in some strange path. try to find parent ourself */
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
);
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
);
141 if (dn1
->dir
&& !dn2
->dir
)
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
)
174 NEWLIST(&directory
->list
);
175 strcpy(directory
->basename
, path
);
177 if (Examine(dirLock
, &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);
191 strcpy(n
->name
, fib
.fib_FileName
);
192 n
->dir
= isDir(&fib
);
195 if (n
->dir
&& (flags
& DIRECTORY_SCAN_RECURSIVE
))
197 char *fullpath
= directoryGetNodeName(directory
, n
);
201 n
->subdir
= directoryScan(fullpath
, flags
);
202 directoryFreeNodeName(fullpath
);
206 ADDTAIL(&directory
->list
, n
);
216 if (flags
& DIRECTORY_SORT
)
217 directorySort(directory
);
225 struct directorynode
*n
;
228 printf("Contents of: <%s>\n", directory
->basename
);
230 ITERATELIST(n
, &directory
->list
)
232 printf("<%s>\n", n
->name
);
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
)
256 rc
= callback(NULL
, fullpath
, 0, data
);
257 else if (flags
& DIRECTORY_SCAN_RECURSIVE
)
258 rc
= directoryTraverse(fullpath
, flags
, callback
, data
);
260 directoryFreeNodeName(fullpath
);
264 rc
= DIRECTORY_TRAVERSE_ERROR
;
268 if (rc
!= DIRECTORY_TRAVERSE_CONTINUE
)
272 directoryFree(directory
);
277 rc
= DIRECTORY_TRAVERSE_ERROR
;
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
)
294 return DIRECTORY_TRAVERSE_ERROR
;
297 if (Examine(dirLock
, &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
;
315 rc
= callback(&fib
, fullpath
, 0, data
);
324 if (rc
== DIRECTORY_TRAVERSE_ABORTDIR
|| rc
== DIRECTORY_TRAVERSE_CONTINUE
)
325 rc
= DIRECTORY_TRAVERSE_OK
;
331 void directoryFree(struct directory
*dir
)
335 struct directorynode
*dn
;
337 while((dn
= (struct directorynode
*)GetTail(&dir
->list
)))
339 directoryFree(dn
->subdir
);
348 int dirCreatePath(char *path
)
351 char constructedPath
[ 1024 ];
353 /* check if it doesn't exist */
357 char *eoPath
= PathPart(path
);
358 char t
= eoPath
[ 0 ];
360 /* temporarely cut the file from path */
364 lock
= Lock(path
, ACCESS_READ
);
369 /* restore file part */
376 /* restore file part */
381 constructedPath
[ 0 ] = 0;
386 pos
= SplitName(path
, '/', buff
, pos
, sizeof(buff
));
388 if (pos
!= -1) /* last part is filename itself */
392 AddPart(constructedPath
, buff
, sizeof(constructedPath
));
394 dLock
= CreateDir(constructedPath
);