/* * scandir.C -- A scandir implementation. */ /* * $Id: scandir.C,v 3.0.1.1 1994/01/24 13:58:45 ram Exp $ * * Copyright (c) 1991-1993, Raphael Manfredi * * You may redistribute only under the terms of the Artistic Licence, * as specified in the README file that comes with the distribution. * You may reuse parts of this distribution only within the terms of * that same Artistic Licence; a copy of which may be found at the root * of the source tree for dist 3.0. * * $Log: scandir.C,v $ * Revision 3.0.1.1 1994/01/24 13:58:45 ram * patch16: created * */ #include "config.h" #ifdef I_STRING #include #else #include #endif #ifdef I_DIRENT #include #else #ifdef I_SYS_NDIR #include #else #ifdef I_SYS_DIR #include #endif #endif #endif #include "confmagic.h" /* Remove if not metaconfig -M */ #ifndef HAS_SCANDIR extern Malloc_t malloc(); extern Malloc_t realloc(); extern DIR *opendir(); extern Direntry_t *readdir(); #define DIR_NULL ((DIR *) 0) #define ENTRY_NULL ((Direntry_t *) 0) static int alphasort _((Direntry_t **, Direntry_t **)); /* * scandir * * This routine reads the directory `dirnam' and builds an array of * pointers to directory entries using malloc(). The second parameter * is the address of a pointer to an array of structure pointers. The * third parameter is a pointer to a routine which is called with a * pointer to a directory entry and should return a non zero value * if the directory entry should be included in the arrary. If this * pointer is NULL, then all the directory entries will be included. * The last argument is a pointer to a routine which is passed to * qsort() to sort the completed array. If this pointer is NULL, the * array is not sorted. * scandir() returns the number of entries in the array and a pointer * to the array through the parameter namlist. * alphasort() is a routine which sorts the array alphabetically. */ V_FUNC(int scandir, (dirnam, namelist, sel, comp), char *dirnam /* Direcotry name */ NXT_ARG Direntry_t ***namelist /* Pointer to an array of struct ptrs */ NXT_ARG int (*sel)() /* Routine to select entries */ NXT_ARG int (*comp)() /* Routine passed to qsort */) { DIR *dirp; /* Returned by opendir() */ Direntry_t *dp; /* Read entry */ Direntry_t *dp_save; /* Place where entry is stored */ Direntry_t **tmplist; /* Where the array list is stored */ int nent = 0; /* Number of entries */ dirp = opendir(dirnam); if (dirp == DIR_NULL) return -1; /* Directory cannot be opened for reading */ for (dp = readdir(dirp); dp != ENTRY_NULL; dp = readdir(dirp)) { if (sel == ((int (*)()) 0) || (*sel)(dp)) { /* If entry has to be included */ nent++; /* One more entry */ if (nent == 1) { /* Create array for first entry */ tmplist = (Direntry_t **) malloc(sizeof(Direntry_t *)); if (tmplist == (Direntry_t **) 0) return -1; /* Cannot create array */ } else { /* Reallocate for a new entry */ tmplist = (Direntry_t **) realloc(tmplist, nent*sizeof(Direntry_t *)); if (tmplist == (Direntry_t **) 0) return -1; /* Cannot reallocate array */ } dp_save = (Direntry_t *) malloc(sizeof(Direntry_t)); if (dp_save == ENTRY_NULL) return -1; /* No space to save entry */ bcopy((char *) dp, (char *) dp_save, sizeof(Direntry_t)); *(tmplist+(nent-1)) = dp_save; } } if (comp != ((int (*)()) 0) && nent) /* Need sorting ? */ qsort(tmplist, nent, sizeof(Direntry_t *), comp); *namelist = tmplist; /* Passes the address of the arrray */ closedir(dirp); /* Close directory */ return nent; /* Number of items */ } P_FUNC(int alphasort, (d1, d2), Direntry_t **d1 NXT_ARG Direntry_t **d2) { return strcmp((*d1)->d_name, (*d2)->d_name); } #endif