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 */ |