static char sccsid
[] = "@(#)scandir.c 4.3 (Berkeley) %G%";
* 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.
scandir(dirname
, namelist
, select
, dcomp
)
struct direct
*(*namelist
[]);
int (*select
)(), (*dcomp
)();
register struct direct
*d
, *p
, **names
;
register char *cp1
, *cp2
;
if ((dirp
= opendir(dirname
)) == NULL
)
if (fstat(dirp
->dd_fd
, &stb
) < 0)
* 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
*));
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
));
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
) {
if (fstat(dirp
->dd_fd
, &stb
) < 0)
return(-1); /* just might have grown */
arraysz
= stb
.st_size
/ 12;
names
= (struct direct
**)realloc((char *)names
,
arraysz
* sizeof(struct direct
*));
if (nitems
&& dcomp
!= NULL
)
qsort(names
, nitems
, sizeof(struct direct
*), dcomp
);
* Alphabetic order comparison routine for those who want it.
struct direct
**d1
, **d2
;
return(strcmp((*d1
)->d_name
, (*d2
)->d_name
));