1*9609Sralph /* scandir.c 4.1 82/12/13 */ 2*9609Sralph /* 3*9609Sralph * Scan the directory dirname calling select to make a list of selected 4*9609Sralph * directory entries then sort using qsort and compare routine dcomp. 5*9609Sralph * Returns the number of entries and a pointer to a list of pointers to 6*9609Sralph * struct direct (through namelist). Returns -1 if there were any errors. 7*9609Sralph */ 8*9609Sralph 9*9609Sralph #include <sys/types.h> 10*9609Sralph #include <sys/stat.h> 11*9609Sralph #include <dir.h> 12*9609Sralph 13*9609Sralph scandir(dirname, namelist, select, dcomp) 14*9609Sralph char *dirname; 15*9609Sralph struct direct *(*namelist[]); 16*9609Sralph int (*select)(), (*dcomp)(); 17*9609Sralph { 18*9609Sralph register struct direct *d, *p, **names; 19*9609Sralph register int nitems; 20*9609Sralph register char *cp1, *cp2; 21*9609Sralph struct stat stb; 22*9609Sralph long arraysz; 23*9609Sralph DIR *dirp; 24*9609Sralph 25*9609Sralph if ((dirp = opendir(dirname)) == NULL) 26*9609Sralph return(-1); 27*9609Sralph if (fstat(dirp->dd_fd, &stb) < 0) 28*9609Sralph return(-1); 29*9609Sralph 30*9609Sralph /* 31*9609Sralph * estimate the array size by taking the size of the directory file 32*9609Sralph * and dividing it by a multiple of the minimum size entry. 33*9609Sralph */ 34*9609Sralph arraysz = (stb.st_size / 24); 35*9609Sralph names = (struct direct **)malloc(arraysz * sizeof(struct direct *)); 36*9609Sralph if (names == NULL) 37*9609Sralph return(-1); 38*9609Sralph 39*9609Sralph nitems = 0; 40*9609Sralph while ((d = readdir(dirp)) != NULL) { 41*9609Sralph if (select != NULL && !(*select)(d)) 42*9609Sralph continue; /* just selected names */ 43*9609Sralph /* 44*9609Sralph * Make a minimum size copy of the data 45*9609Sralph */ 46*9609Sralph p = (struct direct *)malloc(DIRSIZ(d)); 47*9609Sralph if (p == NULL) 48*9609Sralph return(-1); 49*9609Sralph p->d_ino = d->d_ino; 50*9609Sralph p->d_reclen = d->d_reclen; 51*9609Sralph p->d_namlen = d->d_namlen; 52*9609Sralph for (cp1 = p->d_name, cp2 = d->d_name; *cp1++ = *cp2++; ); 53*9609Sralph /* 54*9609Sralph * Check to make sure the array has space left and 55*9609Sralph * realloc the maximum size. 56*9609Sralph */ 57*9609Sralph if (++nitems >= arraysz) { 58*9609Sralph names = (struct direct **)realloc((char *)names, 59*9609Sralph (stb.st_size/12) * sizeof(struct direct *)); 60*9609Sralph if (names == NULL) 61*9609Sralph return(-1); 62*9609Sralph } 63*9609Sralph names[nitems-1] = p; 64*9609Sralph } 65*9609Sralph closedir(dirp); 66*9609Sralph if (nitems && dcomp != NULL) 67*9609Sralph qsort(names, nitems, sizeof(struct direct *), dcomp); 68*9609Sralph *namelist = names; 69*9609Sralph return(nitems); 70*9609Sralph } 71*9609Sralph 72*9609Sralph /* 73*9609Sralph * Alphabetic order comparison routine for those who want it. 74*9609Sralph */ 75*9609Sralph alphasort(d1, d2) 76*9609Sralph struct direct **d1, **d2; 77*9609Sralph { 78*9609Sralph return(strcmp((*d1)->d_name, (*d2)->d_name)); 79*9609Sralph } 80