1c9e2be55Smrg/* $XConsortium: miscfuncs.c,v 1.7 94/12/01 17:15:05 kaleb Exp $ */ 2c9e2be55Smrg/* $XFree86: xc/programs/xmh/miscfuncs.c,v 3.6 2001/10/28 03:34:39 tsi Exp $ */ 3c9e2be55Smrg 4c9e2be55Smrg#include "xmh.h" 5c9e2be55Smrg 6c9e2be55Smrg#include <X11/Xos.h> 7c9e2be55Smrg 8c9e2be55Smrg#ifndef X_NOT_POSIX 9c9e2be55Smrg#include <dirent.h> 10c9e2be55Smrg#else 11c9e2be55Smrg#include <sys/dir.h> 12c9e2be55Smrg#ifndef dirent 13c9e2be55Smrg#define dirent direct 14c9e2be55Smrg#endif 15c9e2be55Smrg#endif 16c9e2be55Smrg 17c9e2be55Smrg#include <stdlib.h> 18c9e2be55Smrg 19c9e2be55Smrg 20c9e2be55Smrg 21c9e2be55Smrg/* 22c9e2be55Smrg** This code is by Rich Salz (rsalz@bbn.com), and ported to SVR4 23c9e2be55Smrg** by David Elliott (dce@smsc.sony.com). No copyrights were found 24c9e2be55Smrg** in the original. Subsequently modified by Bob Scheifler. 25c9e2be55Smrg*/ 26c9e2be55Smrg 27c9e2be55Smrg/* A convenient shorthand. */ 28c9e2be55Smrgtypedef struct dirent ENTRY; 29c9e2be55Smrg 30c9e2be55Smrg/* Initial guess at directory size. */ 31c9e2be55Smrg#define INITIAL_SIZE 20 32c9e2be55Smrg 33c9e2be55Smrgstatic int StrCmp(char **a, char **b) 34c9e2be55Smrg{ 35c9e2be55Smrg return strcmp(*a, *b); 36c9e2be55Smrg} 37c9e2be55Smrg 38c9e2be55Smrgint 39c9e2be55SmrgScanDir( 4066d665a3Smrg const char *Name, 41c9e2be55Smrg char ***List, 42c9e2be55Smrg int (*Selector)(char *)) 43c9e2be55Smrg{ 44c9e2be55Smrg register char **names; 45c9e2be55Smrg register ENTRY *E; 4666d665a3Smrg register DIR *Dp = NULL; 4766d665a3Smrg register size_t i = 0; 4866d665a3Smrg register size_t size; 49c9e2be55Smrg 50c9e2be55Smrg /* Get initial list space and open directory. */ 51c9e2be55Smrg size = INITIAL_SIZE; 5266d665a3Smrg if (!(names = malloc(size * sizeof(char *))) || 53c9e2be55Smrg !(Dp = opendir(Name))) 5466d665a3Smrg goto failure; 55c9e2be55Smrg 56c9e2be55Smrg /* Read entries in the directory. */ 5766d665a3Smrg while ((E = readdir(Dp))) { 58c9e2be55Smrg if (!Selector || (*Selector)(E->d_name)) { 59c9e2be55Smrg /* User wants them all, or he wants this one. */ 60c9e2be55Smrg if (++i >= size) { 6166d665a3Smrg char **newnames = NULL; 62c9e2be55Smrg size <<= 1; 6366d665a3Smrg newnames = realloc(names, size * sizeof(char*)); 6466d665a3Smrg if (!newnames) { 6566d665a3Smrg i--; 6666d665a3Smrg goto failure; 67c9e2be55Smrg } 6866d665a3Smrg names = newnames; 69c9e2be55Smrg } 70c9e2be55Smrg 71c9e2be55Smrg /* Copy the entry. */ 7266d665a3Smrg names[i - 1] = strdup(E->d_name); 7366d665a3Smrg if (names[i - 1] == NULL) { 7466d665a3Smrg goto failure; 75c9e2be55Smrg } 76c9e2be55Smrg } 7766d665a3Smrg } 78c9e2be55Smrg 79c9e2be55Smrg /* Close things off. */ 80c9e2be55Smrg names[i] = (char *)0; 81c9e2be55Smrg *List = names; 82c9e2be55Smrg closedir(Dp); 83c9e2be55Smrg 84c9e2be55Smrg /* Sort? */ 85c9e2be55Smrg if (i) 86e2264b6dSmrg qsort((char *)names, i, sizeof(char *), 87e2264b6dSmrg (int (*)(const void *, const void *))StrCmp); 88c9e2be55Smrg 89c9e2be55Smrg return(i); 9066d665a3Smrg 9166d665a3Smrg failure: 9266d665a3Smrg for (size_t n = 0; n < i; n++) { 9366d665a3Smrg free(names[i]); 9466d665a3Smrg } 9566d665a3Smrg free(names); 9666d665a3Smrg if (Dp != NULL) 9766d665a3Smrg closedir(Dp); 9866d665a3Smrg return(-1); 99c9e2be55Smrg} 100