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