Commit | Line | Data |
---|---|---|
38cb3a9a RC |
1 | /* scandir.c 4.1 82/12/13 */ |
2 | /* | |
3 | * Scan the directory dirname calling select to make a list of selected | |
4 | * directory entries then sort using qsort and compare routine dcomp. | |
5 | * Returns the number of entries and a pointer to a list of pointers to | |
6 | * struct direct (through namelist). Returns -1 if there were any errors. | |
7 | */ | |
8 | ||
9 | #include <sys/types.h> | |
10 | #include <sys/stat.h> | |
11 | #include <dir.h> | |
12 | ||
13 | scandir(dirname, namelist, select, dcomp) | |
14 | char *dirname; | |
15 | struct direct *(*namelist[]); | |
16 | int (*select)(), (*dcomp)(); | |
17 | { | |
18 | register struct direct *d, *p, **names; | |
19 | register int nitems; | |
20 | register char *cp1, *cp2; | |
21 | struct stat stb; | |
22 | long arraysz; | |
23 | DIR *dirp; | |
24 | ||
25 | if ((dirp = opendir(dirname)) == NULL) | |
26 | return(-1); | |
27 | if (fstat(dirp->dd_fd, &stb) < 0) | |
28 | return(-1); | |
29 | ||
30 | /* | |
31 | * estimate the array size by taking the size of the directory file | |
32 | * and dividing it by a multiple of the minimum size entry. | |
33 | */ | |
34 | arraysz = (stb.st_size / 24); | |
35 | names = (struct direct **)malloc(arraysz * sizeof(struct direct *)); | |
36 | if (names == NULL) | |
37 | return(-1); | |
38 | ||
39 | nitems = 0; | |
40 | while ((d = readdir(dirp)) != NULL) { | |
41 | if (select != NULL && !(*select)(d)) | |
42 | continue; /* just selected names */ | |
43 | /* | |
44 | * Make a minimum size copy of the data | |
45 | */ | |
46 | p = (struct direct *)malloc(DIRSIZ(d)); | |
47 | if (p == NULL) | |
48 | return(-1); | |
49 | p->d_ino = d->d_ino; | |
50 | p->d_reclen = d->d_reclen; | |
51 | p->d_namlen = d->d_namlen; | |
52 | for (cp1 = p->d_name, cp2 = d->d_name; *cp1++ = *cp2++; ); | |
53 | /* | |
54 | * Check to make sure the array has space left and | |
55 | * realloc the maximum size. | |
56 | */ | |
57 | if (++nitems >= arraysz) { | |
58 | names = (struct direct **)realloc((char *)names, | |
59 | (stb.st_size/12) * sizeof(struct direct *)); | |
60 | if (names == NULL) | |
61 | return(-1); | |
62 | } | |
63 | names[nitems-1] = p; | |
64 | } | |
65 | closedir(dirp); | |
66 | if (nitems && dcomp != NULL) | |
67 | qsort(names, nitems, sizeof(struct direct *), dcomp); | |
68 | *namelist = names; | |
69 | return(nitems); | |
70 | } | |
71 | ||
72 | /* | |
73 | * Alphabetic order comparison routine for those who want it. | |
74 | */ | |
75 | alphasort(d1, d2) | |
76 | struct direct **d1, **d2; | |
77 | { | |
78 | return(strcmp((*d1)->d_name, (*d2)->d_name)); | |
79 | } |