|
|
1.1 ! root 1: /*************************************************************************** ! 2: * This program is Copyright (C) 1986, 1987, 1988 by Jonathan Payne. JOVE * ! 3: * is provided to you without charge, and with no warranty. You may give * ! 4: * away copies of JOVE, including sources, provided that this notice is * ! 5: * included in all the files. * ! 6: ***************************************************************************/ ! 7: ! 8: #include "jove.h" ! 9: #include "scandir.h" ! 10: ! 11: #ifdef F_COMPLETION ! 12: ! 13: #ifdef MSDOS ! 14: # include <dos.h> ! 15: # include <search.h> ! 16: #endif ! 17: ! 18: #ifdef UNIX ! 19: # include <sys/stat.h> ! 20: # ifdef M_XENIX ! 21: # include <sys/ndir.h> ! 22: # else ! 23: # include <sys/dir.h> ! 24: # endif /* M_XENIX */ ! 25: #endif ! 26: ! 27: #ifdef UNIX ! 28: ! 29: #ifdef mips ! 30: # undef scandir ! 31: #endif ! 32: ! 33: #ifdef BSD_DIR ! 34: # define DIRSIZE(entry) DIRSIZ((entry)) ! 35: #else ! 36: # define DIRSIZE(entry) ((entry)->d_name[DIRSIZ-1]=='\0' ? strlen((entry)->d_name) : DIRSIZ) ! 37: ! 38: typedef struct { ! 39: int d_fd; /* File descriptor for this directory */ ! 40: } DIR; ! 41: ! 42: DIR * ! 43: opendir(dir) ! 44: char *dir; ! 45: { ! 46: DIR *dp = (DIR *) malloc(sizeof *dp); ! 47: struct stat stbuf; ! 48: ! 49: if ((dp->d_fd = open(dir, 0)) == -1) ! 50: return 0; ! 51: if ((fstat(dp->d_fd, &stbuf) == -1) || !(stbuf.st_mode & S_IFDIR)) { ! 52: closedir(dp); ! 53: return 0; /* this isn't a directory! */ ! 54: } ! 55: return dp; ! 56: } ! 57: ! 58: closedir(dp) ! 59: DIR *dp; ! 60: { ! 61: (void) close(dp->d_fd); ! 62: free((char *) dp); ! 63: } ! 64: ! 65: struct direct * ! 66: readdir(dp) ! 67: DIR *dp; ! 68: { ! 69: static struct direct dir; ! 70: ! 71: do ! 72: if (read(dp->d_fd, &dir, sizeof dir) != sizeof dir) ! 73: return 0; ! 74: #if defined(elxsi) && defined(SYSV) ! 75: /* ! 76: * Elxsi has a BSD4.2 implementation which may or may not use ! 77: * `twisted inodes' ... Anyone able to check? ! 78: */ ! 79: while (*(unsigned short *)&dir.d_ino == 0); ! 80: #else ! 81: while (dir.d_ino == 0); ! 82: #endif ! 83: ! 84: return &dir; ! 85: } ! 86: ! 87: #endif /* BSD_DIR */ ! 88: ! 89: /* Scandir returns the number of entries or -1 if the directory cannoot ! 90: be opened or malloc fails. */ ! 91: ! 92: int ! 93: scandir(dir, nmptr, qualify, sorter) ! 94: char *dir; ! 95: char ***nmptr; ! 96: int (*qualify) proto((char *)); ! 97: int (*sorter) proto((UnivConstPtr, UnivConstPtr)); ! 98: { ! 99: DIR *dirp; ! 100: struct direct *entry; ! 101: char **ourarray; ! 102: unsigned int nalloc = 10, ! 103: nentries = 0; ! 104: ! 105: if ((dirp = opendir(dir)) == 0) ! 106: return -1; ! 107: if ((ourarray = (char **) malloc(nalloc * sizeof (char *))) == 0) ! 108: memfail: complain("[Malloc failed: cannot scandir]"); ! 109: while ((entry = readdir(dirp)) != 0) { ! 110: if (qualify != 0 && (*qualify)(entry->d_name) == 0) ! 111: continue; ! 112: if (nentries == nalloc) { ! 113: ourarray = (char **) realloc((char *) ourarray, (nalloc += 10) * sizeof (char *)); ! 114: if (ourarray == 0) ! 115: goto memfail; ! 116: } ! 117: ourarray[nentries] = (char *) malloc(DIRSIZE(entry) + 1); ! 118: null_ncpy(ourarray[nentries], entry->d_name, (size_t) DIRSIZE(entry)); ! 119: nentries += 1; ! 120: } ! 121: closedir(dirp); ! 122: if ((nentries + 1) != nalloc) ! 123: ourarray = (char **) realloc((char *) ourarray, ! 124: ((nentries + 1) * sizeof (char *))); ! 125: if (sorter != 0) ! 126: qsort((char *) ourarray, nentries, sizeof (char **), sorter); ! 127: *nmptr = ourarray; ! 128: ourarray[nentries] = 0; /* guaranteed 0 pointer */ ! 129: ! 130: return nentries; ! 131: } ! 132: ! 133: #endif /* UNIX */ ! 134: ! 135: #ifdef MSDOS ! 136: # define DIRSIZ 13 ! 137: # define DIRSIZE(entry) strlen((entry).name) ! 138: ! 139: /* Scandir returns the number of entries or -1 if the directory cannot ! 140: be opened or malloc fails. */ ! 141: ! 142: unsigned int fmask = _A_NORMAL|_A_RDONLY|_A_HIDDEN|_A_SUBDIR; ! 143: ! 144: int ! 145: scandir(dir, nmptr, qualify, sorter) ! 146: char *dir; ! 147: char ***nmptr; ! 148: int (*qualify) proto((char *)); ! 149: int (*sorter) proto((UnivConstPtr, UnivConstPtr)); ! 150: { ! 151: char dirname[FILESIZE]; ! 152: struct find_t entry; ! 153: char *ptr; ! 154: char **ourarray; ! 155: unsigned int nalloc = 10, ! 156: nentries = 0; ! 157: ! 158: strcpy(dirname, dir); ! 159: ptr = &dirname[strlen(dirname)-1]; ! 160: if ((dirname[1] == ':' && !dirname[2]) || (*ptr == '/') || (*ptr == '\\')) ! 161: strcat(dirname, "*.*"); ! 162: else ! 163: strcat(dirname, "/*.*"); ! 164: ! 165: if (_dos_findfirst(dirname, fmask, &entry)) ! 166: return -1; ! 167: if ((ourarray = (char **) malloc(nalloc * sizeof (char *))) == 0) ! 168: memfail: complain("[Malloc failed: cannot scandir]"); ! 169: do { ! 170: if ((fmask == 0x10) && !(entry.attrib&fmask)) ! 171: goto skip; ! 172: strlwr(entry.name); ! 173: if (qualify != (int (*)())0 && (*qualify)(entry.name) == 0) ! 174: goto skip; ! 175: if (nentries == nalloc) { ! 176: ourarray = (char **) realloc((char *) ourarray, (nalloc += 10) * sizeof (char *)); ! 177: if (ourarray == 0) ! 178: goto memfail; ! 179: } ! 180: ourarray[nentries] = (char *) malloc(DIRSIZE(entry) + 1); ! 181: null_ncpy(ourarray[nentries], entry.name, (int) DIRSIZE(entry)); ! 182: nentries++; ! 183: skip: ; ! 184: } ! 185: while (_dos_findnext(&entry) == 0); ! 186: ! 187: if ((nentries + 1) != nalloc) ! 188: ourarray = (char **) realloc((char *) ourarray, ! 189: ((nentries + 1) * sizeof (char *))); ! 190: if (sorter != (int (*)())0) ! 191: qsort((char *) ourarray, nentries, sizeof (char **), sorter); ! 192: *nmptr = ourarray; ! 193: ourarray[nentries] = 0; /* guaranteed 0 pointer */ ! 194: ! 195: return nentries; ! 196: } ! 197: ! 198: #endif /* MSDOS */ ! 199: ! 200: void ! 201: freedir(nmptr, nentries) ! 202: char ***nmptr; ! 203: int nentries; ! 204: { ! 205: char **ourarray = *nmptr; ! 206: ! 207: while (--nentries >= 0) ! 208: free(*ourarray++); ! 209: free((char *) *nmptr); ! 210: *nmptr = 0; ! 211: } ! 212: ! 213: int ! 214: alphacomp(a, b) ! 215: UnivConstPtr a, ! 216: b; ! 217: { ! 218: return strcmp(*(const char **)a, *(const char **)b); ! 219: } ! 220: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.