2 * Copyright (c) 1983 Regents of the University of California.
5 * Redistribution and use in source and binary forms are permitted
6 * provided that the above copyright notice and this paragraph are
7 * duplicated in all such forms and that any documentation,
8 * advertising materials, and other materials related to such
9 * distribution and use acknowledge that the software was developed
10 * by the University of California, Berkeley. The name of the
11 * University may not be used to endorse or promote products derived
12 * from this software without specific prior written permission.
13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
19 * Copyright (c) 1983 Regents of the University of California.
20 * All rights reserved. The Berkeley software License Agreement
21 * specifies the terms and conditions for redistribution.
24 #pragma ident "%Z%%M% %I% %E% SMI"
27 * Scan the directory dirname calling select to make a list of selected
28 * directory entries then sort using qsort and compare routine dcomp.
29 * Returns the number of entries and a pointer to a list of pointers to
30 * struct direct (through namelist). Returns -1 if there were any errors.
33 #include <sys/types.h>
38 scandir(char *dirname
, struct direct
*(*namelist
[]),
39 int (*select
)(), int (*dcomp
)())
41 struct direct
*d
, *p
, **names
;
48 if ((dirp
= opendir(dirname
)) == NULL
)
50 if (fstat(dirp
->dd_fd
, &stb
) < 0)
54 * estimate the array size by taking the size of the directory file
55 * and dividing it by a multiple of the minimum size entry.
57 arraysz
= (stb
.st_size
/ 24);
58 names
= (struct direct
**)malloc(arraysz
* sizeof(struct direct
*));
63 while ((d
= readdir(dirp
)) != NULL
) {
64 if (select
!= NULL
&& !(*select
)(d
))
65 continue; /* just selected names */
67 * Make a minimum size copy of the data
69 p
= (struct direct
*)malloc(DIRSIZ(d
));
73 p
->d_reclen
= d
->d_reclen
;
74 p
->d_namlen
= d
->d_namlen
;
75 for (cp1
= p
->d_name
, cp2
= d
->d_name
; *cp1
++ = *cp2
++; );
77 * Check to make sure the array has space left and
78 * realloc the maximum size.
80 if (++nitems
>= arraysz
) {
81 if (fstat(dirp
->dd_fd
, &stb
) < 0)
82 return (-1); /* just might have grown */
83 arraysz
= stb
.st_size
/ 12;
84 names
= (struct direct
**)realloc((char *)names
,
85 arraysz
* sizeof(struct direct
*));
92 if (nitems
&& dcomp
!= NULL
)
93 qsort(names
, nitems
, sizeof(struct direct
*), dcomp
);
99 * Alphabetic order comparison routine for those who want it.
102 alphasort(struct direct
**d1
, struct direct
**d2
)
104 return (strcmp((*d1
)->d_name
, (*d2
)->d_name
));