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