|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1983 Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * Redistribution and use in source and binary forms are permitted ! 6: * provided that the above copyright notice and this paragraph are ! 7: * duplicated in all such forms and that any documentation, ! 8: * advertising materials, and other materials related to such ! 9: * distribution and use acknowledge that the software was developed ! 10: * by the University of California, Berkeley. The name of the ! 11: * University may not be used to endorse or promote products derived ! 12: * from this software without specific prior written permission. ! 13: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ! 14: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ! 15: * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 16: */ ! 17: ! 18: #if defined(LIBC_SCCS) && !defined(lint) ! 19: static char sccsid[] = "@(#)scandir.c 5.3 (Berkeley) 6/18/88"; ! 20: #endif /* LIBC_SCCS and not lint */ ! 21: ! 22: /* ! 23: * Scan the directory dirname calling select to make a list of selected ! 24: * directory entries then sort using qsort and compare routine dcomp. ! 25: * Returns the number of entries and a pointer to a list of pointers to ! 26: * struct direct (through namelist). Returns -1 if there were any errors. ! 27: */ ! 28: ! 29: #include <sys/types.h> ! 30: #include <sys/stat.h> ! 31: #include <sys/dir.h> ! 32: ! 33: scandir(dirname, namelist, select, dcomp) ! 34: char *dirname; ! 35: struct direct *(*namelist[]); ! 36: int (*select)(), (*dcomp)(); ! 37: { ! 38: register struct direct *d, *p, **names; ! 39: register int nitems; ! 40: register char *cp1, *cp2; ! 41: struct stat stb; ! 42: long arraysz; ! 43: DIR *dirp; ! 44: ! 45: if ((dirp = opendir(dirname)) == NULL) ! 46: return(-1); ! 47: if (fstat(dirp->dd_fd, &stb) < 0) ! 48: return(-1); ! 49: ! 50: /* ! 51: * estimate the array size by taking the size of the directory file ! 52: * and dividing it by a multiple of the minimum size entry. ! 53: */ ! 54: arraysz = (stb.st_size / 24); ! 55: names = (struct direct **)malloc(arraysz * sizeof(struct direct *)); ! 56: if (names == NULL) ! 57: return(-1); ! 58: ! 59: nitems = 0; ! 60: while ((d = readdir(dirp)) != NULL) { ! 61: if (select != NULL && !(*select)(d)) ! 62: continue; /* just selected names */ ! 63: /* ! 64: * Make a minimum size copy of the data ! 65: */ ! 66: p = (struct direct *)malloc(DIRSIZ(d)); ! 67: if (p == NULL) ! 68: return(-1); ! 69: p->d_ino = d->d_ino; ! 70: p->d_reclen = d->d_reclen; ! 71: p->d_namlen = d->d_namlen; ! 72: for (cp1 = p->d_name, cp2 = d->d_name; *cp1++ = *cp2++; ); ! 73: /* ! 74: * Check to make sure the array has space left and ! 75: * realloc the maximum size. ! 76: */ ! 77: if (++nitems >= arraysz) { ! 78: if (fstat(dirp->dd_fd, &stb) < 0) ! 79: return(-1); /* just might have grown */ ! 80: arraysz = stb.st_size / 12; ! 81: names = (struct direct **)realloc((char *)names, ! 82: arraysz * sizeof(struct direct *)); ! 83: if (names == NULL) ! 84: return(-1); ! 85: } ! 86: names[nitems-1] = p; ! 87: } ! 88: closedir(dirp); ! 89: if (nitems && dcomp != NULL) ! 90: qsort(names, nitems, sizeof(struct direct *), dcomp); ! 91: *namelist = names; ! 92: return(nitems); ! 93: } ! 94: ! 95: /* ! 96: * Alphabetic order comparison routine for those who want it. ! 97: */ ! 98: alphasort(d1, d2) ! 99: struct direct **d1, **d2; ! 100: { ! 101: return(strcmp((*d1)->d_name, (*d2)->d_name)); ! 102: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.