Commit | Line | Data |
---|---|---|
79072805 | 1 | /* $RCSfile: directory.c,v $$Revision: 4.1 $$Date: 92/08/07 18:24:42 $ |
b1248f16 LW |
2 | * |
3 | * (C) Copyright 1987, 1988, 1990 Diomidis Spinellis. | |
4 | * | |
6e21c824 LW |
5 | * You may distribute under the terms of either the GNU General Public |
6 | * License or the Artistic License, as specified in the README file. | |
b1248f16 LW |
7 | * |
8 | * $Log: directory.c,v $ | |
79072805 LW |
9 | * Revision 4.1 92/08/07 18:24:42 lwall |
10 | * | |
6e21c824 LW |
11 | * Revision 4.0.1.1 91/06/07 11:22:24 lwall |
12 | * patch4: new copyright notice | |
13 | * | |
fe14fcc3 LW |
14 | * Revision 4.0 91/03/20 01:34:24 lwall |
15 | * 4.0 baseline. | |
16 | * | |
b1248f16 LW |
17 | * Revision 3.0.1.1 90/03/27 16:07:37 lwall |
18 | * patch16: MSDOS support | |
19 | * | |
20 | * Revision 1.3 90/03/16 22:39:40 dds | |
21 | * Fixed malloc problem. | |
22 | * | |
23 | * Revision 1.2 88/07/23 00:08:39 dds | |
24 | * Added inode non-zero filling. | |
25 | * | |
26 | * Revision 1.1 88/07/23 00:03:50 dds | |
27 | * Initial revision | |
28 | * | |
29 | */ | |
30 | ||
31 | /* | |
32 | * UNIX compatible directory access functions | |
33 | */ | |
34 | ||
35 | #include <sys/types.h> | |
36 | #include <sys/dir.h> | |
37 | #include <stddef.h> | |
38 | #include <stdlib.h> | |
39 | #include <string.h> | |
40 | #include <dos.h> | |
41 | #include <ctype.h> | |
42 | ||
43 | /* | |
44 | * File names are converted to lowercase if the | |
45 | * CONVERT_TO_LOWER_CASE variable is defined. | |
46 | */ | |
47 | #define CONVERT_TO_LOWER_CASE | |
48 | ||
49 | #define PATHLEN 65 | |
50 | ||
51 | #ifndef lint | |
79072805 | 52 | static char rcsid[] = "$RCSfile: directory.c,v $$Revision: 4.1 $$Date: 92/08/07 18:24:42 $"; |
b1248f16 LW |
53 | #endif |
54 | ||
55 | DIR * | |
56 | opendir(char *filename) | |
57 | { | |
58 | DIR *p; | |
59 | char *oldresult, *result; | |
60 | union REGS srv; | |
61 | struct SREGS segregs; | |
62 | register reslen = 0; | |
63 | char scannamespc[PATHLEN]; | |
64 | char *scanname = scannamespc; /* To take address we need a pointer */ | |
65 | ||
66 | /* | |
67 | * Structure used by the MS-DOS directory system calls. | |
68 | */ | |
69 | struct dir_buff { | |
70 | char reserved[21]; /* Reserved for MS-DOS */ | |
71 | unsigned char attribute; /* Attribute */ | |
72 | unsigned int time; /* Time */ | |
73 | unsigned int date; /* Date */ | |
74 | long size; /* Size of file */ | |
75 | char fn[13]; /* Filename */ | |
76 | } buffspc, *buff = &buffspc; | |
77 | ||
78 | ||
79 | if (!(p = (DIR *) malloc(sizeof(DIR)))) | |
80 | return NULL; | |
81 | ||
82 | /* Initialize result to use realloc on it */ | |
83 | if (!(result = malloc(1))) { | |
84 | free(p); | |
85 | return NULL; | |
86 | } | |
87 | ||
88 | /* Create the search pattern */ | |
89 | strcpy(scanname, filename); | |
90 | if (strchr("/\\", *(scanname + strlen(scanname) - 1)) == NULL) | |
91 | strcat(scanname, "/*.*"); | |
92 | else | |
93 | strcat(scanname, "*.*"); | |
94 | ||
95 | segread(&segregs); | |
96 | #if ( defined(M_I86LM) || defined(M_I86CM) || defined(M_I86HM) ) | |
97 | segregs.ds = FP_SEG(buff); | |
98 | srv.x.dx = FP_OFF(buff); | |
99 | #else | |
100 | srv.x.dx = (unsigned int) buff; | |
101 | #endif | |
102 | srv.h.ah = 0x1a; /* Set DTA to DS:DX */ | |
103 | intdosx(&srv, &srv, &segregs); | |
104 | ||
105 | #if ( defined(M_I86LM) || defined(M_I86CM) || defined(M_I86HM) ) | |
106 | segregs.ds = FP_SEG(scanname); | |
107 | srv.x.dx = FP_OFF(scanname); | |
108 | #else | |
109 | srv.x.dx = (unsigned int) scanname; | |
110 | #endif | |
111 | srv.x.cx = 0xff; /* Search mode */ | |
112 | ||
113 | for (srv.h.ah = 0x4e; !intdosx(&srv, &srv, &segregs); srv.h.ah = 0x4f) { | |
114 | if ((result = (char *) realloc(result, reslen + strlen(buff->fn) + 1)) == | |
115 | NULL) { | |
116 | free(p); | |
117 | free(oldresult); | |
118 | return NULL; | |
119 | } | |
120 | oldresult = result; | |
121 | #ifdef CONVERT_TO_LOWER_CASE | |
122 | strcpy(result + reslen, strlwr(buff->fn)); | |
123 | #else | |
124 | strcpy(result + reslen, buff->fn); | |
125 | #endif | |
126 | reslen += strlen(buff->fn) + 1; | |
127 | } | |
128 | ||
129 | if (!(result = realloc(result, reslen + 1))) { | |
130 | free(p); | |
131 | free(oldresult); | |
132 | return NULL; | |
133 | } else { | |
134 | p->start = result; | |
135 | p->curr = result; | |
136 | *(result + reslen) = '\0'; | |
137 | return p; | |
138 | } | |
139 | } | |
140 | ||
141 | ||
142 | struct direct * | |
143 | readdir(DIR *dirp) | |
144 | { | |
145 | char *p; | |
146 | register len; | |
147 | static dummy; | |
148 | ||
149 | p = dirp->curr; | |
150 | len = strlen(p); | |
151 | if (*p) { | |
152 | dirp->curr += len + 1; | |
153 | strcpy(dirp->dirstr.d_name, p); | |
154 | dirp->dirstr.d_namlen = len; | |
155 | /* To fool programs */ | |
156 | dirp->dirstr.d_ino = ++dummy; | |
157 | return &(dirp->dirstr); | |
158 | } else | |
159 | return NULL; | |
160 | } | |
161 | ||
162 | long | |
163 | telldir(DIR *dirp) | |
164 | { | |
165 | return (long) dirp->curr; /* ouch! pointer to long cast */ | |
166 | } | |
167 | ||
168 | void | |
169 | seekdir(DIR *dirp, long loc) | |
170 | { | |
171 | dirp->curr = (char *) loc; /* ouch! long to pointer cast */ | |
172 | } | |
173 | ||
174 | void | |
175 | rewinddir(DIR *dirp) | |
176 | { | |
177 | dirp->curr = dirp->start; | |
178 | } | |
179 | ||
180 | void | |
181 | closedir(DIR *dirp) | |
182 | { | |
183 | free(dirp->start); | |
184 | free(dirp); | |
185 | } |