1*13582Ssam #ifndef lint 2*13582Ssam static char sccsid[] = "@(#)scandir.c 4.2 (Berkeley) 07/01/83"; 3*13582Ssam #endif 4*13582Ssam 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> 14*13582Ssam #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) { 619609Sralph names = (struct direct **)realloc((char *)names, 629609Sralph (stb.st_size/12) * sizeof(struct direct *)); 639609Sralph if (names == NULL) 649609Sralph return(-1); 659609Sralph } 669609Sralph names[nitems-1] = p; 679609Sralph } 689609Sralph closedir(dirp); 699609Sralph if (nitems && dcomp != NULL) 709609Sralph qsort(names, nitems, sizeof(struct direct *), dcomp); 719609Sralph *namelist = names; 729609Sralph return(nitems); 739609Sralph } 749609Sralph 759609Sralph /* 769609Sralph * Alphabetic order comparison routine for those who want it. 779609Sralph */ 789609Sralph alphasort(d1, d2) 799609Sralph struct direct **d1, **d2; 809609Sralph { 819609Sralph return(strcmp((*d1)->d_name, (*d2)->d_name)); 829609Sralph } 83