date and time created 82/12/13 10:43:38 by ralph
authorRalph Campbell <ralph@ucbvax.Berkeley.EDU>
Tue, 14 Dec 1982 02:43:38 +0000 (18:43 -0800)
committerRalph Campbell <ralph@ucbvax.Berkeley.EDU>
Tue, 14 Dec 1982 02:43:38 +0000 (18:43 -0800)
SCCS-vsn: lib/libc/gen/scandir.c 4.1

usr/src/lib/libc/gen/scandir.c [new file with mode: 0644]

diff --git a/usr/src/lib/libc/gen/scandir.c b/usr/src/lib/libc/gen/scandir.c
new file mode 100644 (file)
index 0000000..f00b8b4
--- /dev/null
@@ -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 <sys/types.h>
+#include <sys/stat.h>
+#include <dir.h>
+
+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));
+}