From: Ralph Campbell Date: Tue, 14 Dec 1982 02:43:38 +0000 (-0800) Subject: date and time created 82/12/13 10:43:38 by ralph X-Git-Tag: BSD-4_1c_2-Snapshot-Development~1542 X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/commitdiff_plain/38cb3a9a096ac8a48023bcc1e91d7a3a1b06d9d6 date and time created 82/12/13 10:43:38 by ralph SCCS-vsn: lib/libc/gen/scandir.c 4.1 --- diff --git a/usr/src/lib/libc/gen/scandir.c b/usr/src/lib/libc/gen/scandir.c new file mode 100644 index 0000000000..f00b8b479d --- /dev/null +++ b/usr/src/lib/libc/gen/scandir.c @@ -0,0 +1,79 @@ +/* scandir.c 4.1 82/12/13 */ +/* + * Scan the directory dirname calling select to make a list of selected + * directory entries then sort using qsort and compare routine dcomp. + * Returns the number of entries and a pointer to a list of pointers to + * struct direct (through namelist). Returns -1 if there were any errors. + */ + +#include +#include +#include + +scandir(dirname, namelist, select, dcomp) + char *dirname; + struct direct *(*namelist[]); + int (*select)(), (*dcomp)(); +{ + register struct direct *d, *p, **names; + register int nitems; + register char *cp1, *cp2; + struct stat stb; + long arraysz; + DIR *dirp; + + if ((dirp = opendir(dirname)) == NULL) + return(-1); + if (fstat(dirp->dd_fd, &stb) < 0) + return(-1); + + /* + * estimate the array size by taking the size of the directory file + * and dividing it by a multiple of the minimum size entry. + */ + arraysz = (stb.st_size / 24); + names = (struct direct **)malloc(arraysz * sizeof(struct direct *)); + if (names == NULL) + return(-1); + + nitems = 0; + while ((d = readdir(dirp)) != NULL) { + if (select != NULL && !(*select)(d)) + continue; /* just selected names */ + /* + * Make a minimum size copy of the data + */ + p = (struct direct *)malloc(DIRSIZ(d)); + if (p == NULL) + return(-1); + p->d_ino = d->d_ino; + p->d_reclen = d->d_reclen; + p->d_namlen = d->d_namlen; + for (cp1 = p->d_name, cp2 = d->d_name; *cp1++ = *cp2++; ); + /* + * Check to make sure the array has space left and + * realloc the maximum size. + */ + if (++nitems >= arraysz) { + names = (struct direct **)realloc((char *)names, + (stb.st_size/12) * sizeof(struct direct *)); + if (names == NULL) + return(-1); + } + names[nitems-1] = p; + } + closedir(dirp); + if (nitems && dcomp != NULL) + qsort(names, nitems, sizeof(struct direct *), dcomp); + *namelist = names; + return(nitems); +} + +/* + * Alphabetic order comparison routine for those who want it. + */ +alphasort(d1, d2) + struct direct **d1, **d2; +{ + return(strcmp((*d1)->d_name, (*d2)->d_name)); +}