|
|
1.1 root 1: /* library:dosdir.c 1.3 */
2: #include "sccsid.h"
3: VERSION(@(#)library:dosdir.c 1.3)
4:
5: /*
6: * dir.c - contains routines which behave (hopefully) like the
7: * similar versions on 4.2 BSD.
8: *
9: */
10: #include <dos.h>
11: #include <errno.h>
12: #include <dir.h>
13: #include <malloc.h>
14: #include <errno.h>
15: #define NULL (char *)0
16:
17: #define ROOTFIX
18:
19: /*
20: * opendir - opens given directory and reads its contents into memory.
21: * Other functions use this data or the DIR structure to do their work.
22: */
23: DIR *
24: opendir(dirname)
25: char *dirname;
26: {
27: struct direct **namelist;
28: DIR *dirptr;
29:
30: dirptr = (DIR *)calloc(1, sizeof(DIR));
31: if(dirptr == (DIR *)0)
32: {
33: errno = ENOMEM;
34: return((DIR *)0);
35: }
36: dirptr->d_magic = DMAGIC;
37: dirptr->d_pos = 0;
38: #ifdef ROOTFIX
39: again:
40: #endif
41: dirptr->d_length = scandir(dirname, &(dirptr->namelist),
42: (int (*)())0, (int (*)())0);
43: if(dirptr->d_length < 0)
44: {
45: #ifdef ROOTFIX
46: static char *root = "a:";
47:
48: /* DOS quirk: there's no "." in root directory. vqh */
49: if (dirname[0]=='.' && dirname[1] == '\0') {
50: *root = (bdos(0x19,0,0) & 0xf)+ 'a'; /* current disk */
51: dirname = root;
52: goto again;
53: }
54: #endif
55: free((char *)dirptr);
56: return((DIR *)0);
57: }
58: return(dirptr);
59: }
60:
61: /*
62: * readdir - returns the next directory structure from the list and
63: * updates values in the DIR structure.
64: */
65: struct direct *
66: readdir(dirptr)
67: DIR *dirptr;
68: {
69: if(dirptr->d_magic != DMAGIC)
70: {
71: errno = ENOTDIR;
72: return((struct direct *)0);
73: }
74: if(dirptr->d_pos >= dirptr->d_length)
75: {
76: errno = ENFILE;
77: return((struct direct *)0);
78: }
79: return(dirptr->namelist[dirptr->d_pos++]);
80: }
81:
82: /*
83: * telldir - return the current position of the directory.
84: */
85: long
86: telldir(dirptr)
87: DIR *dirptr;
88: {
89: if(dirptr->d_magic != DMAGIC)
90: {
91: errno = ENOTDIR;
92: return(-1L);
93: }
94: return((long)dirptr->d_pos);
95: }
96:
97: /*
98: * seekdir - position the given DIR stream to position given.
99: */
100: seekdir(dirptr, loc)
101: DIR *dirptr;
102: long loc;
103: {
104: if(dirptr->d_magic != DMAGIC)
105: {
106: errno = ENOTDIR;
107: return(-1);
108: }
109: if(loc > (long)dirptr->d_length)
110: {
111: errno = EINVAL;
112: return(-1);
113: }
114: dirptr->d_pos = (int)loc;
115: return(0);
116: }
117:
118: /*
119: * rewinddir - rewind given DIR to beginning
120: */
121: rewinddir(dirptr)
122: DIR *dirptr;
123: {
124: if(dirptr->d_magic != DMAGIC)
125: {
126: errno = ENOTDIR;
127: return(-1);
128: }
129: dirptr->d_pos = 0;
130: return(0);
131: }
132:
133: /*
134: * closedir - close given directory. destroy given DIR struct so we
135: * know it is closed.
136: */
137: closedir(dirptr)
138: DIR *dirptr;
139: {
140: if(dirptr->d_magic != DMAGIC)
141: {
142: errno = ENOTDIR;
143: return(-1);
144: }
145: dirptr->d_magic = ~DMAGIC; /* mess it up a little */
146: freedir(dirptr->namelist);
147: free(dirptr);
148: return(0);
149: }
150:
151: /* XXXXXX scandir.c below here XXXXXXX */
152:
153: static struct direct buffer;
154:
155: scandir(dirname, namelist, select, compar)
156: char *dirname;
157: struct direct *(*namelist[]);
158: int (*select)();
159: int (*compar)();
160: {
161: register struct direct **names;
162: register int dirno;
163: union REGS sregs, oregs;
164: struct SREGS segregs;
165: char *ptr, *paths;
166:
167: names = (struct direct **)calloc(1, sizeof(struct direct *));
168: paths = calloc(128, 1);
169: if(names == (struct direct **)0 || paths == NULL)
170: {
171: errno = ENOMEM;
172: return(-1);
173: }
174: strcpy(paths, dirname);
175: ptr = &paths[strlen(paths) - 1];
176: if(*ptr == '/' || *ptr == '\\')
177: *ptr = '\0';
178: strcat(paths, "/*.*");
179:
180: segread(&segregs); /* set up segment registers */
181: ptr = (char *)&buffer;
182: sregs.h.ah = 0x1a; /* set DTA to buffer */
183: sregs.x.dx = FP_OFF(ptr); /* offset */
184: #ifdef M_I86LM
185: segregs.ds = FP_SEG(ptr); /* pointer in large model */
186: #endif /* M_I86LM */
187: intdosx(&sregs, &oregs, &segregs);
188: sregs.x.ax = 0x4e00; /* search for first */
189: sregs.x.cx = 0x1f; /* include all attributes */
190: sregs.x.dx = FP_OFF(paths); /* offset to path */
191: #ifdef M_I86LM
192: segregs.ds = FP_SEG(paths); /* segment for large model */
193: #endif /* M_I86LM */
194: intdosx(&sregs, &oregs, &segregs);
195: if(oregs.x.cflag)
196: {
197: errno = ENOTDIR;
198: return(-1);
199: }
200: sregs.x.ax = 0x4f00; /* search for next */
201: for(dirno = 0; oregs.x.cflag == 0; intdosx(&sregs, &oregs, &segregs))
202: {
203: for(ptr = buffer.d_name; *ptr; ptr++)
204: *ptr = tolower(*ptr);
205: if(select == (int (*)())0 || (*select)(&buffer))
206: {
207: names = (struct direct **)realloc((char *)names,
208: (dirno + 2)*sizeof(struct direct *));
209: if(names == (struct direct **)0)
210: {
211: errno = ENOMEM;
212: return(-1);
213: }
214: names[dirno] = (struct direct *)calloc(1,
215: sizeof(struct direct));
216: if(names[dirno] == (struct direct *)0)
217: {
218: errno = ENOMEM;
219: return(-1);
220: }
221: *names[dirno] = buffer;
222: names[++dirno] = (struct direct *)0;
223: }
224: }
225:
226: if(compar != (int (*)())0)
227: qsort((char *)names, dirno, sizeof(char *), compar);
228:
229: *namelist = names;
230: free(paths); /* free temp space */
231: return(dirno);
232: }
233:
234: freedir(dirs)
235: register struct direct **dirs;
236: {
237: register int ii;
238:
239: if(dirs == (struct direct **)0)
240: return(-1);
241: for(ii = 0; dirs[ii] != (struct direct *)0; ii++)
242: free(dirs[ii]);
243: free(dirs);
244: return(0);
245: }
246:
247: alphasort(dirptr1, dirptr2)
248: struct direct **dirptr1, **dirptr2;
249: {
250: return(strcmp((*dirptr1)->d_name, (*dirptr2)->d_name));
251: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.