comparison win/dirent.c @ 3:67a643a734d9

Import
author ktk@81767d24-ef19-dc11-ae90-00e081727c95
date Tue, 03 Jul 2001 07:50:39 +0000
parents
children 4ec906d40ce2
comparison
equal deleted inserted replaced
2:36c5f0ce3fbe 3:67a643a734d9
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <ctype.h>
5
6 #include <windows.h>
7
8 #include "dirent.h"
9 #include <errno.h>
10
11 #define error(rc) errno = 255
12
13 struct _dirdescr {
14 HANDLE handle; /* DosFindFirst handle */
15 char fstype; /* filesystem type */
16 long count; /* valid entries in <ffbuf> */
17 long number; /* absolute number of next entry */
18 int index; /* relative number of next entry */
19 char name[MAXPATHLEN+3]; /* directory name */
20 unsigned attrmask; /* attribute mask for seekdir */
21 struct dirent entry; /* buffer for directory entry */
22 WIN32_FIND_DATA data;
23 };
24
25 /*
26 * Return first char of filesystem type, or 0 if unknown.
27 */
28 static char
29 getFSType(const char *path)
30 {
31 static char cache[1+26];
32 char drive[3];
33 ULONG unit;
34 char r;
35
36 if (isalpha(path[0]) && path[1] == ':') {
37 unit = toupper(path[0]) - '@';
38 path += 2;
39 } else {
40 return 0;
41 }
42
43 if ((path[0] == '\\' || path[0] == '/')
44 && (path[1] == '\\' || path[1] == '/'))
45 return 0;
46
47 if (cache [unit])
48 return cache [unit];
49
50 drive[0] = '@' + unit;
51 drive[1] = ':';
52 drive[2] = '\0';
53
54 r = GetDriveType(drive);
55
56 return cache [unit] = r;
57 }
58
59 char *
60 abs_path(const char *name, char *buffer, int len)
61 {
62 char buf[4];
63 if (isalpha(name[0]) && name[1] == ':' && name[2] == '\0') {
64 buf[0] = name[0];
65 buf[1] = name[1];
66 buf[2] = '.';
67 buf[3] = '\0';
68 name = buf;
69 }
70 if (GetLongPathName(name, buffer, len))
71 return NULL;
72 return buffer;
73 }
74
75 DIR *
76 openxdir(const char *path, unsigned att_mask)
77 {
78 DIR *dir;
79 char name[MAXPATHLEN+3];
80
81 dir = malloc(sizeof(DIR));
82 if (dir == NULL) {
83 errno = ENOMEM;
84 return NULL;
85 }
86
87 strncpy(name, path, MAXPATHLEN);
88 name[MAXPATHLEN] = '\0';
89 switch (name[strlen(name)-1]) {
90 default:
91 strcat(name, "\\");
92 case '\\':
93 case '/':
94 case ':':
95 ;
96 }
97 strcat(name, ".");
98 if (!abs_path(name, dir->name, MAXPATHLEN+1))
99 strcpy(dir->name, name);
100 if (dir->name[strlen(dir->name)-1] == '\\')
101 strcat(dir->name, "*");
102 else
103 strcat(dir->name, "\\*");
104
105 dir->fstype = getFSType(dir->name);
106 dir->attrmask = att_mask | A_DIR;
107
108 dir->count = 100;
109 if((dir->handle = FindFirstFile(dir->name, &dir->data))==NULL)
110 {
111 free(dir);
112 error(rc);
113 return NULL;
114 }
115
116 dir->number = 0;
117 dir->index = 0;
118
119 return (DIR *)dir;
120 }
121
122 DIR *
123 opendir(const char *pathname)
124 {
125 return openxdir(pathname, 0);
126 }
127
128 struct dirent *
129 readdir(DIR *dir)
130 {
131 static int dummy_ino = 2;
132
133 if (dir->number)
134 {
135 ULONG rc;
136 dir->count = 100;
137 if(!FindNextFile(dir->handle, &(dir->data)))
138 {
139 error(rc);
140 return NULL;
141 }
142
143 dir->index = 0;
144 }
145
146 strcpy(dir->entry.d_name, dir->data.cFileName);
147 dir->entry.d_ino = dummy_ino++;
148 dir->entry.d_reclen = strlen(dir->data.cFileName);
149 dir->entry.d_namlen = strlen(dir->data.cFileName);
150 dir->entry.d_size = dir->data.nFileSizeLow;
151 dir->entry.d_attribute = dir->data.dwFileAttributes;
152 #if 0
153 dir->entry.d_time = *(USHORT *)&dir->next->ftimeLastWrite;
154 dir->entry.d_date = *(USHORT *)&dir->next->fdateLastWrite;
155 #endif
156
157 dir->number++;
158 dir->index++;
159 return &dir->entry;
160 }
161
162 long
163 telldir(DIR *dir)
164 {
165 return dir->number;
166 }
167
168 void
169 seekdir(DIR *dir, long off)
170 {
171 if (dir->number > off) {
172 char name[MAXPATHLEN+2];
173 ULONG rc;
174
175 FindClose(dir->handle);
176
177 strcpy(name, dir->name);
178 strcat(name, "*");
179
180 if((dir->handle = FindFirstFile(name, &(dir->data)))==NULL)
181 {
182 error(rc);
183 return;
184 }
185
186 dir->number = 0;
187 dir->index = 0;
188 }
189
190 while (dir->number < off && readdir(dir))
191 ;
192 }
193
194 void
195 closedir(DIR *dir)
196 {
197 FindClose(dir->handle);
198 free(dir);
199 }
200
201 /*****************************************************************************/
202
203 #ifdef TEST
204
205 main(int argc, char **argv)
206 {
207 int i;
208 DIR *dir;
209 struct dirent *ep;
210
211 for (i = 1; i < argc; ++i) {
212 dir = opendir(argv[i]);
213 if (!dir)
214 continue;
215 while (ep = readdir(dir))
216 if (strchr("\\/:", argv[i] [strlen(argv[i]) - 1]))
217 printf("%s%s\n", argv[i], ep->d_name);
218 else
219 printf("%s/%s\n", argv[i], ep->d_name);
220 closedir(dir);
221 }
222
223 return 0;
224 }
225
226 #endif