Mercurial > dwindows
annotate win/dirent.c @ 215:03e68274623d
Two scrollbar fixes for GTK... one from Mark Hessling.
author | bsmith@81767d24-ef19-dc11-ae90-00e081727c95 |
---|---|
date | Tue, 04 Feb 2003 22:11:28 +0000 |
parents | 4ec906d40ce2 |
children | e320dc29bfcd |
rev | line source |
---|---|
3 | 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; | |
184
4ec906d40ce2
FindFirstFile returns INVALID_HANDLE_VALUE on error, not NULL.
bsmith@81767d24-ef19-dc11-ae90-00e081727c95
parents:
3
diff
changeset
|
109 if((dir->handle = FindFirstFile(dir->name, &dir->data))==INVALID_HANDLE_VALUE) |
3 | 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 |