rev |
line source |
yuuji@0
|
1 /* ========================================================================
|
yuuji@0
|
2 * Copyright 1988-2006 University of Washington
|
yuuji@0
|
3 *
|
yuuji@0
|
4 * Licensed under the Apache License, Version 2.0 (the "License");
|
yuuji@0
|
5 * you may not use this file except in compliance with the License.
|
yuuji@0
|
6 * You may obtain a copy of the License at
|
yuuji@0
|
7 *
|
yuuji@0
|
8 * http://www.apache.org/licenses/LICENSE-2.0
|
yuuji@0
|
9 *
|
yuuji@0
|
10 *
|
yuuji@0
|
11 * ========================================================================
|
yuuji@0
|
12 */
|
yuuji@0
|
13
|
yuuji@0
|
14 /*
|
yuuji@0
|
15 * Program: Scan directories
|
yuuji@0
|
16 *
|
yuuji@0
|
17 * Author: Mark Crispin
|
yuuji@0
|
18 * Networks and Distributed Computing
|
yuuji@0
|
19 * Computing & Communications
|
yuuji@0
|
20 * University of Washington
|
yuuji@0
|
21 * Administration Building, AG-44
|
yuuji@0
|
22 * Seattle, WA 98195
|
yuuji@0
|
23 * Internet: MRC@CAC.Washington.EDU
|
yuuji@0
|
24 *
|
yuuji@0
|
25 * Date: 1 August 1988
|
yuuji@0
|
26 * Last Edited: 15 September 2006
|
yuuji@0
|
27 */
|
yuuji@0
|
28
|
yuuji@0
|
29 /* Emulator for BSD scandir() call
|
yuuji@0
|
30 * Accepts: directory name
|
yuuji@0
|
31 * destination pointer of names array
|
yuuji@0
|
32 * selection function
|
yuuji@0
|
33 * comparison function
|
yuuji@0
|
34 * Returns: number of elements in the array or -1 if error
|
yuuji@0
|
35 */
|
yuuji@0
|
36
|
yuuji@0
|
37 int scandir (char *dirname,struct direct ***namelist,select_t select,
|
yuuji@0
|
38 compar_t compar)
|
yuuji@0
|
39 {
|
yuuji@0
|
40 struct direct *p,*d,**names;
|
yuuji@0
|
41 int nitems;
|
yuuji@0
|
42 struct stat stb;
|
yuuji@0
|
43 long nlmax;
|
yuuji@0
|
44 DIR *dirp = opendir (dirname);/* open directory and get status poop */
|
yuuji@0
|
45 if ((!dirp) || (fstat (dirp->dd_fd,&stb) < 0)) return -1;
|
yuuji@0
|
46 nlmax = stb.st_size / 24; /* guesstimate at number of files */
|
yuuji@0
|
47 names = (struct direct **) fs_get (nlmax * sizeof (struct direct *));
|
yuuji@0
|
48 nitems = 0; /* initially none found */
|
yuuji@0
|
49 while (d = readdir (dirp)) { /* read directory item */
|
yuuji@0
|
50 /* matches select criterion? */
|
yuuji@0
|
51 if (select && !(*select) (d)) continue;
|
yuuji@0
|
52 /* get size of direct record for this file */
|
yuuji@0
|
53 p = (struct direct *) fs_get (DIR_SIZE (d));
|
yuuji@0
|
54 p->d_ino = d->d_ino; /* copy the poop */
|
yuuji@0
|
55 strcpy (p->d_name,d->d_name);
|
yuuji@0
|
56 if (++nitems >= nlmax) { /* if out of space, try bigger guesstimate */
|
yuuji@0
|
57 void *s = (void *) names; /* stupid language */
|
yuuji@0
|
58 nlmax *= 2; /* double it */
|
yuuji@0
|
59 fs_resize ((void **) &s,nlmax * sizeof (struct direct *));
|
yuuji@0
|
60 names = (struct direct **) s;
|
yuuji@0
|
61 }
|
yuuji@0
|
62 names[nitems - 1] = p; /* store this file there */
|
yuuji@0
|
63 }
|
yuuji@0
|
64 closedir (dirp); /* done with directory */
|
yuuji@0
|
65 /* sort if necessary */
|
yuuji@0
|
66 if (nitems && compar) qsort (names,nitems,sizeof (struct direct *),compar);
|
yuuji@0
|
67 *namelist = names; /* return directory */
|
yuuji@0
|
68 return nitems; /* and size */
|
yuuji@0
|
69 }
|
yuuji@0
|
70
|
yuuji@0
|
71 /* Alphabetic file name comparision
|
yuuji@0
|
72 * Accepts: first candidate directory entry
|
yuuji@0
|
73 * second candidate directory entry
|
yuuji@0
|
74 * Returns: negative if d1 < d2, 0 if d1 == d2, postive if d1 > d2
|
yuuji@0
|
75 */
|
yuuji@0
|
76
|
yuuji@0
|
77 int alphasort (void *d1,void *d2)
|
yuuji@0
|
78 {
|
yuuji@0
|
79 return strcmp ((*(struct direct **) d1)->d_name,
|
yuuji@0
|
80 (*(struct direct **) d2)->d_name);
|
yuuji@0
|
81 }
|