removed support for -r, -h, and rmail
[unix-history] / usr / src / lib / libc / gen / scandir.c
CommitLineData
bb0cfa24
DF
1/*
2 * Copyright (c) 1983 Regents of the University of California.
3 * All rights reserved. The Berkeley software License Agreement
4 * specifies the terms and conditions for redistribution.
5 */
6
2ce81398
DS
7#if defined(LIBC_SCCS) && !defined(lint)
8static char sccsid[] = "@(#)scandir.c 5.2 (Berkeley) %G%";
9#endif LIBC_SCCS and not lint
455b164d 10
38cb3a9a
RC
11/*
12 * Scan the directory dirname calling select to make a list of selected
13 * directory entries then sort using qsort and compare routine dcomp.
14 * Returns the number of entries and a pointer to a list of pointers to
15 * struct direct (through namelist). Returns -1 if there were any errors.
16 */
17
18#include <sys/types.h>
19#include <sys/stat.h>
455b164d 20#include <sys/dir.h>
38cb3a9a
RC
21
22scandir(dirname, namelist, select, dcomp)
23 char *dirname;
24 struct direct *(*namelist[]);
25 int (*select)(), (*dcomp)();
26{
27 register struct direct *d, *p, **names;
28 register int nitems;
29 register char *cp1, *cp2;
30 struct stat stb;
31 long arraysz;
32 DIR *dirp;
33
34 if ((dirp = opendir(dirname)) == NULL)
35 return(-1);
36 if (fstat(dirp->dd_fd, &stb) < 0)
37 return(-1);
38
39 /*
40 * estimate the array size by taking the size of the directory file
41 * and dividing it by a multiple of the minimum size entry.
42 */
43 arraysz = (stb.st_size / 24);
44 names = (struct direct **)malloc(arraysz * sizeof(struct direct *));
45 if (names == NULL)
46 return(-1);
47
48 nitems = 0;
49 while ((d = readdir(dirp)) != NULL) {
50 if (select != NULL && !(*select)(d))
51 continue; /* just selected names */
52 /*
53 * Make a minimum size copy of the data
54 */
55 p = (struct direct *)malloc(DIRSIZ(d));
56 if (p == NULL)
57 return(-1);
58 p->d_ino = d->d_ino;
59 p->d_reclen = d->d_reclen;
60 p->d_namlen = d->d_namlen;
61 for (cp1 = p->d_name, cp2 = d->d_name; *cp1++ = *cp2++; );
62 /*
63 * Check to make sure the array has space left and
64 * realloc the maximum size.
65 */
66 if (++nitems >= arraysz) {
71120ea4
RC
67 if (fstat(dirp->dd_fd, &stb) < 0)
68 return(-1); /* just might have grown */
69 arraysz = stb.st_size / 12;
38cb3a9a 70 names = (struct direct **)realloc((char *)names,
71120ea4 71 arraysz * sizeof(struct direct *));
38cb3a9a
RC
72 if (names == NULL)
73 return(-1);
74 }
75 names[nitems-1] = p;
76 }
77 closedir(dirp);
78 if (nitems && dcomp != NULL)
79 qsort(names, nitems, sizeof(struct direct *), dcomp);
80 *namelist = names;
81 return(nitems);
82}
83
84/*
85 * Alphabetic order comparison routine for those who want it.
86 */
87alphasort(d1, d2)
88 struct direct **d1, **d2;
89{
90 return(strcmp((*d1)->d_name, (*d2)->d_name));
91}