113582Ssam #ifndef lint 2*15661Sralph static char sccsid[] = "@(#)scandir.c 4.3 (Berkeley) 12/05/83"; 313582Ssam #endif 413582Ssam 59609Sralph /* 69609Sralph * Scan the directory dirname calling select to make a list of selected 79609Sralph * directory entries then sort using qsort and compare routine dcomp. 89609Sralph * Returns the number of entries and a pointer to a list of pointers to 99609Sralph * struct direct (through namelist). Returns -1 if there were any errors. 109609Sralph */ 119609Sralph 129609Sralph #include <sys/types.h> 139609Sralph #include <sys/stat.h> 1413582Ssam #include <sys/dir.h> 159609Sralph 169609Sralph scandir(dirname, namelist, select, dcomp) 179609Sralph char *dirname; 189609Sralph struct direct *(*namelist[]); 199609Sralph int (*select)(), (*dcomp)(); 209609Sralph { 219609Sralph register struct direct *d, *p, **names; 229609Sralph register int nitems; 239609Sralph register char *cp1, *cp2; 249609Sralph struct stat stb; 259609Sralph long arraysz; 269609Sralph DIR *dirp; 279609Sralph 289609Sralph if ((dirp = opendir(dirname)) == NULL) 299609Sralph return(-1); 309609Sralph if (fstat(dirp->dd_fd, &stb) < 0) 319609Sralph return(-1); 329609Sralph 339609Sralph /* 349609Sralph * estimate the array size by taking the size of the directory file 359609Sralph * and dividing it by a multiple of the minimum size entry. 369609Sralph */ 379609Sralph arraysz = (stb.st_size / 24); 389609Sralph names = (struct direct **)malloc(arraysz * sizeof(struct direct *)); 399609Sralph if (names == NULL) 409609Sralph return(-1); 419609Sralph 429609Sralph nitems = 0; 439609Sralph while ((d = readdir(dirp)) != NULL) { 449609Sralph if (select != NULL && !(*select)(d)) 459609Sralph continue; /* just selected names */ 469609Sralph /* 479609Sralph * Make a minimum size copy of the data 489609Sralph */ 499609Sralph p = (struct direct *)malloc(DIRSIZ(d)); 509609Sralph if (p == NULL) 519609Sralph return(-1); 529609Sralph p->d_ino = d->d_ino; 539609Sralph p->d_reclen = d->d_reclen; 549609Sralph p->d_namlen = d->d_namlen; 559609Sralph for (cp1 = p->d_name, cp2 = d->d_name; *cp1++ = *cp2++; ); 569609Sralph /* 579609Sralph * Check to make sure the array has space left and 589609Sralph * realloc the maximum size. 599609Sralph */ 609609Sralph if (++nitems >= arraysz) { 61*15661Sralph if (fstat(dirp->dd_fd, &stb) < 0) 62*15661Sralph return(-1); /* just might have grown */ 63*15661Sralph arraysz = stb.st_size / 12; 649609Sralph names = (struct direct **)realloc((char *)names, 65*15661Sralph arraysz * sizeof(struct direct *)); 669609Sralph if (names == NULL) 679609Sralph return(-1); 689609Sralph } 699609Sralph names[nitems-1] = p; 709609Sralph } 719609Sralph closedir(dirp); 729609Sralph if (nitems && dcomp != NULL) 739609Sralph qsort(names, nitems, sizeof(struct direct *), dcomp); 749609Sralph *namelist = names; 759609Sralph return(nitems); 769609Sralph } 779609Sralph 789609Sralph /* 799609Sralph * Alphabetic order comparison routine for those who want it. 809609Sralph */ 819609Sralph alphasort(d1, d2) 829609Sralph struct direct **d1, **d2; 839609Sralph { 849609Sralph return(strcmp((*d1)->d_name, (*d2)->d_name)); 859609Sralph } 86