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