|
|
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.