1 |
adcroft |
1.1 |
/* |
2 |
|
|
dir.c for MS-DOS by Samuel Lam <skl@van-bc.UUCP>, June/87 |
3 |
|
|
*/ |
4 |
|
|
|
5 |
|
|
/* #ifdef WIN32 */ |
6 |
|
|
/* |
7 |
|
|
* @(#)dir.c 1.4 87/11/06 Public Domain. |
8 |
|
|
* |
9 |
|
|
* A public domain implementation of BSD directory routines for |
10 |
|
|
* MS-DOS. Written by Michael Rendell ({uunet,utai}michael@garfield), |
11 |
|
|
* August 1897 |
12 |
|
|
* Ported to OS/2 by Kai Uwe Rommel |
13 |
|
|
* December 1989, February 1990 |
14 |
|
|
* Ported to Windows NT 22 May 91 |
15 |
|
|
* other mods Summer '92 brianmo@microsoft.com |
16 |
|
|
* opendirx() was horribly written, very inefficient, and did not take care |
17 |
|
|
* of all cases. It is still not too clean, but it is far more efficient. |
18 |
|
|
* Changes made by Gordon Chaffee (chaffee@bugs-bunny.cs.berkeley.edu) |
19 |
|
|
*/ |
20 |
|
|
|
21 |
|
|
|
22 |
|
|
/*Includes: |
23 |
|
|
* crt |
24 |
|
|
*/ |
25 |
|
|
#include <windows.h> |
26 |
|
|
#include <stdlib.h> |
27 |
|
|
#include <string.h> |
28 |
|
|
#include <sys\types.h> |
29 |
|
|
#include <sys\stat.h> |
30 |
|
|
#define _SWISH_PORT |
31 |
|
|
#include "dirent.h" |
32 |
|
|
#include "config.h" |
33 |
|
|
|
34 |
|
|
/* |
35 |
|
|
* NT specific |
36 |
|
|
*/ |
37 |
|
|
#include <stdio.h> |
38 |
|
|
|
39 |
|
|
/* |
40 |
|
|
* random typedefs |
41 |
|
|
*/ |
42 |
|
|
#define HDIR HANDLE |
43 |
|
|
#define HFILE HANDLE |
44 |
|
|
#define PHFILE PHANDLE |
45 |
|
|
|
46 |
|
|
/* |
47 |
|
|
* local functions |
48 |
|
|
*/ |
49 |
|
|
static char *getdirent(char *); |
50 |
|
|
static void free_dircontents(struct _dircontents *); |
51 |
|
|
|
52 |
|
|
static HDIR FindHandle; |
53 |
|
|
static WIN32_FIND_DATA FileFindData; |
54 |
|
|
|
55 |
|
|
static struct dirent dp; |
56 |
|
|
|
57 |
|
|
DIR *opendirx(char *name, char *pattern) |
58 |
|
|
{ |
59 |
|
|
struct stat statb; |
60 |
|
|
DIR *dirp; |
61 |
|
|
char c; |
62 |
|
|
char *s; |
63 |
|
|
struct _dircontents *dp; |
64 |
|
|
int len; |
65 |
|
|
int unc; |
66 |
|
|
char path[ SW_MAXPATHNAME ]; |
67 |
|
|
register char *ip, *op; |
68 |
|
|
|
69 |
|
|
for (ip = name, op = path; ; op++, ip++) { |
70 |
|
|
*op = *ip; |
71 |
|
|
if (*ip == '\0') { |
72 |
|
|
break; |
73 |
|
|
} |
74 |
|
|
} |
75 |
|
|
|
76 |
|
|
len = ip - name; |
77 |
|
|
if (len > 0) { |
78 |
|
|
/* Windows NT required a trailing '/' at some point. Now it MUST NOT have one. */ |
79 |
|
|
// unc = ((path[0] == '\\' || path[0] == '/') && |
80 |
|
|
// (path[1] == '\\' || path[1] == '/')); |
81 |
|
|
unc = 0; |
82 |
|
|
c = path[len - 1]; |
83 |
|
|
if (unc) { |
84 |
|
|
if (c != '\\' && c != '/') { |
85 |
|
|
path[len] = '/'; |
86 |
|
|
len++; |
87 |
|
|
path[len] ='\0'; |
88 |
|
|
} |
89 |
|
|
} else { |
90 |
|
|
if ((c == '\\' || c == '/') && (len > 1)) { |
91 |
|
|
len--; |
92 |
|
|
path[len] = '\0'; |
93 |
|
|
|
94 |
|
|
if (path[len - 1] == ':' ) { |
95 |
|
|
path[len] = '/'; len++; |
96 |
|
|
path[len] = '.'; len++; |
97 |
|
|
path[len] = '\0'; |
98 |
|
|
} |
99 |
|
|
} else if (c == ':' ) { |
100 |
|
|
path[len] = '.'; |
101 |
|
|
len++; |
102 |
|
|
path[len] ='\0'; |
103 |
|
|
} |
104 |
|
|
} |
105 |
|
|
} else { |
106 |
|
|
unc = 0; |
107 |
|
|
path[0] = '.'; |
108 |
|
|
path[1] = '\0'; |
109 |
|
|
len = 1; |
110 |
|
|
} |
111 |
|
|
|
112 |
|
|
if (stat(path, &statb) < 0 || (statb.st_mode & S_IFMT) != S_IFDIR) { |
113 |
|
|
return NULL; |
114 |
|
|
} |
115 |
|
|
|
116 |
|
|
dirp = malloc(sizeof(DIR)); |
117 |
|
|
if (dirp == NULL) { |
118 |
|
|
return dirp; |
119 |
|
|
} |
120 |
|
|
|
121 |
|
|
c = path[len - 1]; |
122 |
|
|
if (c == '.' ) { |
123 |
|
|
if (len == 1) { |
124 |
|
|
len--; |
125 |
|
|
} else { |
126 |
|
|
c = path[len - 2]; |
127 |
|
|
if (c == '\\' || c == ':') { |
128 |
|
|
len--; |
129 |
|
|
} else { |
130 |
|
|
path[len] = '/'; |
131 |
|
|
len++; |
132 |
|
|
} |
133 |
|
|
} |
134 |
|
|
} else if (!unc && ((len != 1) || (c != '\\' && c != '/'))) { |
135 |
|
|
path[len] = '/'; |
136 |
|
|
len++; |
137 |
|
|
} |
138 |
|
|
strcpy(path + len, pattern); |
139 |
|
|
|
140 |
|
|
dirp -> dd_loc = 0; |
141 |
|
|
dirp -> dd_contents = dirp -> dd_cp = NULL; |
142 |
|
|
|
143 |
|
|
if ((s = getdirent(path)) == NULL) { |
144 |
|
|
return dirp; |
145 |
|
|
} |
146 |
|
|
|
147 |
|
|
do |
148 |
|
|
{ |
149 |
|
|
if (((dp = malloc(sizeof(struct _dircontents))) == NULL) || |
150 |
|
|
((dp -> _d_entry = malloc(strlen(s) + 1)) == NULL) ) |
151 |
|
|
{ |
152 |
|
|
if (dp) |
153 |
|
|
free(dp); |
154 |
|
|
free_dircontents(dirp -> dd_contents); |
155 |
|
|
|
156 |
|
|
return NULL; |
157 |
|
|
} |
158 |
|
|
|
159 |
|
|
if (dirp -> dd_contents) |
160 |
|
|
dirp -> dd_cp = dirp -> dd_cp -> _d_next = dp; |
161 |
|
|
else |
162 |
|
|
dirp -> dd_contents = dirp -> dd_cp = dp; |
163 |
|
|
|
164 |
|
|
strcpy(dp -> _d_entry, s); |
165 |
|
|
dp -> _d_next = NULL; |
166 |
|
|
|
167 |
|
|
} |
168 |
|
|
while ((s = getdirent(NULL)) != NULL); |
169 |
|
|
|
170 |
|
|
dirp -> dd_cp = dirp -> dd_contents; |
171 |
|
|
return dirp; |
172 |
|
|
} |
173 |
|
|
|
174 |
|
|
DIR *opendir(char *name) |
175 |
|
|
{ |
176 |
|
|
return opendirx(name, "*"); |
177 |
|
|
} |
178 |
|
|
|
179 |
|
|
void closedir(DIR * dirp) |
180 |
|
|
{ |
181 |
|
|
free_dircontents(dirp -> dd_contents); |
182 |
|
|
free(dirp); |
183 |
|
|
} |
184 |
|
|
|
185 |
|
|
struct dirent *readdir(DIR * dirp) |
186 |
|
|
{ |
187 |
|
|
/* static struct dirent dp; */ |
188 |
|
|
if (dirp -> dd_cp == NULL) |
189 |
|
|
return NULL; |
190 |
|
|
|
191 |
|
|
/*strcpy(dp.d_name,dirp->dd_cp->_d_entry); */ |
192 |
|
|
|
193 |
|
|
dp.d_name = dirp->dd_cp->_d_entry; |
194 |
|
|
|
195 |
|
|
dp.d_namlen = dp.d_reclen = |
196 |
|
|
strlen(dp.d_name); |
197 |
|
|
|
198 |
|
|
dp.d_ino = dirp->dd_loc+1; /* fake the inode */ |
199 |
|
|
|
200 |
|
|
dirp -> dd_cp = dirp -> dd_cp -> _d_next; |
201 |
|
|
dirp -> dd_loc++; |
202 |
|
|
|
203 |
|
|
|
204 |
|
|
return &dp; |
205 |
|
|
} |
206 |
|
|
|
207 |
|
|
void seekdir(DIR * dirp, long off) |
208 |
|
|
{ |
209 |
|
|
long i = off; |
210 |
|
|
struct _dircontents *dp; |
211 |
|
|
|
212 |
|
|
if (off >= 0) |
213 |
|
|
{ |
214 |
|
|
for (dp = dirp -> dd_contents; --i >= 0 && dp; dp = dp -> _d_next); |
215 |
|
|
|
216 |
|
|
dirp -> dd_loc = off - (i + 1); |
217 |
|
|
dirp -> dd_cp = dp; |
218 |
|
|
} |
219 |
|
|
} |
220 |
|
|
|
221 |
|
|
|
222 |
|
|
long telldir(DIR * dirp) |
223 |
|
|
{ |
224 |
|
|
return dirp -> dd_loc; |
225 |
|
|
} |
226 |
|
|
|
227 |
|
|
static void free_dircontents(struct _dircontents * dp) |
228 |
|
|
{ |
229 |
|
|
struct _dircontents *odp; |
230 |
|
|
|
231 |
|
|
while (dp) |
232 |
|
|
{ |
233 |
|
|
if (dp -> _d_entry) |
234 |
|
|
free(dp -> _d_entry); |
235 |
|
|
|
236 |
|
|
dp = (odp = dp) -> _d_next; |
237 |
|
|
free(odp); |
238 |
|
|
} |
239 |
|
|
} |
240 |
|
|
/* end of "free_dircontents" */ |
241 |
|
|
|
242 |
|
|
static char *getdirent(char *dir) |
243 |
|
|
{ |
244 |
|
|
int got_dirent; |
245 |
|
|
|
246 |
|
|
if (dir != NULL) |
247 |
|
|
{ /* get first entry */ |
248 |
|
|
if ((FindHandle = FindFirstFile( dir, &FileFindData )) |
249 |
|
|
== (HDIR)0xffffffff) |
250 |
|
|
{ |
251 |
|
|
return NULL; |
252 |
|
|
} |
253 |
|
|
got_dirent = 1; |
254 |
|
|
} |
255 |
|
|
else /* get next entry */ |
256 |
|
|
got_dirent = FindNextFile( FindHandle, &FileFindData ); |
257 |
|
|
|
258 |
|
|
if (got_dirent) |
259 |
|
|
return FileFindData.cFileName; |
260 |
|
|
else |
261 |
|
|
{ |
262 |
|
|
FindClose(FindHandle); |
263 |
|
|
return NULL; |
264 |
|
|
} |
265 |
|
|
} |
266 |
|
|
/* end of getdirent() */ |
267 |
|
|
|
268 |
|
|
struct passwd * _cdecl |
269 |
|
|
getpwnam(char *name) |
270 |
|
|
{ |
271 |
|
|
return NULL; |
272 |
|
|
} |
273 |
|
|
|
274 |
|
|
struct passwd * _cdecl |
275 |
|
|
getpwuid(int uid) |
276 |
|
|
{ |
277 |
|
|
return NULL; |
278 |
|
|
} |
279 |
|
|
|
280 |
|
|
int |
281 |
|
|
getuid() |
282 |
|
|
{ |
283 |
|
|
return 0; |
284 |
|
|
} |
285 |
|
|
|
286 |
|
|
void _cdecl |
287 |
|
|
endpwent(void) |
288 |
|
|
{ |
289 |
|
|
} |
290 |
|
|
|
291 |
|
|
/* #endif */ |