1*21357Sdist /* 2*21357Sdist * Copyright (c) 1983 Regents of the University of California. 3*21357Sdist * All rights reserved. The Berkeley software License Agreement 4*21357Sdist * specifies the terms and conditions for redistribution. 5*21357Sdist */ 6*21357Sdist 713582Ssam #ifndef lint 8*21357Sdist static char sccsid[] = "@(#)scandir.c 5.1 (Berkeley) 05/30/85"; 9*21357Sdist #endif not lint 1013582Ssam 119609Sralph /* 129609Sralph * Scan the directory dirname calling select to make a list of selected 139609Sralph * directory entries then sort using qsort and compare routine dcomp. 149609Sralph * Returns the number of entries and a pointer to a list of pointers to 159609Sralph * struct direct (through namelist). Returns -1 if there were any errors. 169609Sralph */ 179609Sralph 189609Sralph #include <sys/types.h> 199609Sralph #include <sys/stat.h> 2013582Ssam #include <sys/dir.h> 219609Sralph 229609Sralph scandir(dirname, namelist, select, dcomp) 239609Sralph char *dirname; 249609Sralph struct direct *(*namelist[]); 259609Sralph int (*select)(), (*dcomp)(); 269609Sralph { 279609Sralph register struct direct *d, *p, **names; 289609Sralph register int nitems; 299609Sralph register char *cp1, *cp2; 309609Sralph struct stat stb; 319609Sralph long arraysz; 329609Sralph DIR *dirp; 339609Sralph 349609Sralph if ((dirp = opendir(dirname)) == NULL) 359609Sralph return(-1); 369609Sralph if (fstat(dirp->dd_fd, &stb) < 0) 379609Sralph return(-1); 389609Sralph 399609Sralph /* 409609Sralph * estimate the array size by taking the size of the directory file 419609Sralph * and dividing it by a multiple of the minimum size entry. 429609Sralph */ 439609Sralph arraysz = (stb.st_size / 24); 449609Sralph names = (struct direct **)malloc(arraysz * sizeof(struct direct *)); 459609Sralph if (names == NULL) 469609Sralph return(-1); 479609Sralph 489609Sralph nitems = 0; 499609Sralph while ((d = readdir(dirp)) != NULL) { 509609Sralph if (select != NULL && !(*select)(d)) 519609Sralph continue; /* just selected names */ 529609Sralph /* 539609Sralph * Make a minimum size copy of the data 549609Sralph */ 559609Sralph p = (struct direct *)malloc(DIRSIZ(d)); 569609Sralph if (p == NULL) 579609Sralph return(-1); 589609Sralph p->d_ino = d->d_ino; 599609Sralph p->d_reclen = d->d_reclen; 609609Sralph p->d_namlen = d->d_namlen; 619609Sralph for (cp1 = p->d_name, cp2 = d->d_name; *cp1++ = *cp2++; ); 629609Sralph /* 639609Sralph * Check to make sure the array has space left and 649609Sralph * realloc the maximum size. 659609Sralph */ 669609Sralph if (++nitems >= arraysz) { 6715661Sralph if (fstat(dirp->dd_fd, &stb) < 0) 6815661Sralph return(-1); /* just might have grown */ 6915661Sralph arraysz = stb.st_size / 12; 709609Sralph names = (struct direct **)realloc((char *)names, 7115661Sralph arraysz * sizeof(struct direct *)); 729609Sralph if (names == NULL) 739609Sralph return(-1); 749609Sralph } 759609Sralph names[nitems-1] = p; 769609Sralph } 779609Sralph closedir(dirp); 789609Sralph if (nitems && dcomp != NULL) 799609Sralph qsort(names, nitems, sizeof(struct direct *), dcomp); 809609Sralph *namelist = names; 819609Sralph return(nitems); 829609Sralph } 839609Sralph 849609Sralph /* 859609Sralph * Alphabetic order comparison routine for those who want it. 869609Sralph */ 879609Sralph alphasort(d1, d2) 889609Sralph struct direct **d1, **d2; 899609Sralph { 909609Sralph return(strcmp((*d1)->d_name, (*d2)->d_name)); 919609Sralph } 92