Mercurial > dwindows
annotate win/dirent.c @ 410:47273b6a8500
Fixes for signal removal. Some limitations still exist... like some
signals won't be removed for widgets that have multiple subparts with
signals attached, like comboboxes and the tree widget. This affects
dw_signal_disconnect_by_window() and dw_signal_disconnect_by_data().
author | bsmith@81767d24-ef19-dc11-ae90-00e081727c95 |
---|---|
date | Tue, 13 May 2003 05:32:22 +0000 |
parents | e320dc29bfcd |
children | e0ea29c3d1eb |
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 | |
260
e320dc29bfcd
Rewrote abs_path() so the code will work on NT 4.0.
bsmith@81767d24-ef19-dc11-ae90-00e081727c95
parents:
184
diff
changeset
|
59 char *abs_path(const char *name, char *buffer, int len) |
3 | 60 { |
260
e320dc29bfcd
Rewrote abs_path() so the code will work on NT 4.0.
bsmith@81767d24-ef19-dc11-ae90-00e081727c95
parents:
184
diff
changeset
|
61 char *buf; |
e320dc29bfcd
Rewrote abs_path() so the code will work on NT 4.0.
bsmith@81767d24-ef19-dc11-ae90-00e081727c95
parents:
184
diff
changeset
|
62 LPTSTR file; |
e320dc29bfcd
Rewrote abs_path() so the code will work on NT 4.0.
bsmith@81767d24-ef19-dc11-ae90-00e081727c95
parents:
184
diff
changeset
|
63 |
e320dc29bfcd
Rewrote abs_path() so the code will work on NT 4.0.
bsmith@81767d24-ef19-dc11-ae90-00e081727c95
parents:
184
diff
changeset
|
64 if(isalpha(name[0]) && name[1] == ':' && name[2] == '\0') |
e320dc29bfcd
Rewrote abs_path() so the code will work on NT 4.0.
bsmith@81767d24-ef19-dc11-ae90-00e081727c95
parents:
184
diff
changeset
|
65 { |
e320dc29bfcd
Rewrote abs_path() so the code will work on NT 4.0.
bsmith@81767d24-ef19-dc11-ae90-00e081727c95
parents:
184
diff
changeset
|
66 int drive = _getdrive(); |
e320dc29bfcd
Rewrote abs_path() so the code will work on NT 4.0.
bsmith@81767d24-ef19-dc11-ae90-00e081727c95
parents:
184
diff
changeset
|
67 char newdrive = toupper(name[0]); |
e320dc29bfcd
Rewrote abs_path() so the code will work on NT 4.0.
bsmith@81767d24-ef19-dc11-ae90-00e081727c95
parents:
184
diff
changeset
|
68 |
e320dc29bfcd
Rewrote abs_path() so the code will work on NT 4.0.
bsmith@81767d24-ef19-dc11-ae90-00e081727c95
parents:
184
diff
changeset
|
69 _chdrive((newdrive - 'A')+1); |
e320dc29bfcd
Rewrote abs_path() so the code will work on NT 4.0.
bsmith@81767d24-ef19-dc11-ae90-00e081727c95
parents:
184
diff
changeset
|
70 |
e320dc29bfcd
Rewrote abs_path() so the code will work on NT 4.0.
bsmith@81767d24-ef19-dc11-ae90-00e081727c95
parents:
184
diff
changeset
|
71 if(getcwd(buffer, len)) |
e320dc29bfcd
Rewrote abs_path() so the code will work on NT 4.0.
bsmith@81767d24-ef19-dc11-ae90-00e081727c95
parents:
184
diff
changeset
|
72 { |
e320dc29bfcd
Rewrote abs_path() so the code will work on NT 4.0.
bsmith@81767d24-ef19-dc11-ae90-00e081727c95
parents:
184
diff
changeset
|
73 _chdrive(drive); |
e320dc29bfcd
Rewrote abs_path() so the code will work on NT 4.0.
bsmith@81767d24-ef19-dc11-ae90-00e081727c95
parents:
184
diff
changeset
|
74 return buffer; |
e320dc29bfcd
Rewrote abs_path() so the code will work on NT 4.0.
bsmith@81767d24-ef19-dc11-ae90-00e081727c95
parents:
184
diff
changeset
|
75 } |
e320dc29bfcd
Rewrote abs_path() so the code will work on NT 4.0.
bsmith@81767d24-ef19-dc11-ae90-00e081727c95
parents:
184
diff
changeset
|
76 _chdrive(drive); |
e320dc29bfcd
Rewrote abs_path() so the code will work on NT 4.0.
bsmith@81767d24-ef19-dc11-ae90-00e081727c95
parents:
184
diff
changeset
|
77 return NULL; |
3 | 78 } |
260
e320dc29bfcd
Rewrote abs_path() so the code will work on NT 4.0.
bsmith@81767d24-ef19-dc11-ae90-00e081727c95
parents:
184
diff
changeset
|
79 if(GetFullPathName(name, len, buffer, &file)) |
e320dc29bfcd
Rewrote abs_path() so the code will work on NT 4.0.
bsmith@81767d24-ef19-dc11-ae90-00e081727c95
parents:
184
diff
changeset
|
80 return buffer; |
e320dc29bfcd
Rewrote abs_path() so the code will work on NT 4.0.
bsmith@81767d24-ef19-dc11-ae90-00e081727c95
parents:
184
diff
changeset
|
81 return NULL; |
3 | 82 } |
83 | |
260
e320dc29bfcd
Rewrote abs_path() so the code will work on NT 4.0.
bsmith@81767d24-ef19-dc11-ae90-00e081727c95
parents:
184
diff
changeset
|
84 DIR *openxdir(const char *path, unsigned att_mask) |
3 | 85 { |
86 DIR *dir; | |
87 char name[MAXPATHLEN+3]; | |
88 | |
89 dir = malloc(sizeof(DIR)); | |
90 if (dir == NULL) { | |
91 errno = ENOMEM; | |
92 return NULL; | |
93 } | |
94 | |
95 strncpy(name, path, MAXPATHLEN); | |
96 name[MAXPATHLEN] = '\0'; | |
97 switch (name[strlen(name)-1]) { | |
98 default: | |
99 strcat(name, "\\"); | |
100 case '\\': | |
101 case '/': | |
102 case ':': | |
103 ; | |
104 } | |
105 strcat(name, "."); | |
106 if (!abs_path(name, dir->name, MAXPATHLEN+1)) | |
107 strcpy(dir->name, name); | |
108 if (dir->name[strlen(dir->name)-1] == '\\') | |
109 strcat(dir->name, "*"); | |
110 else | |
111 strcat(dir->name, "\\*"); | |
112 | |
113 dir->fstype = getFSType(dir->name); | |
114 dir->attrmask = att_mask | A_DIR; | |
115 | |
116 dir->count = 100; | |
184
4ec906d40ce2
FindFirstFile returns INVALID_HANDLE_VALUE on error, not NULL.
bsmith@81767d24-ef19-dc11-ae90-00e081727c95
parents:
3
diff
changeset
|
117 if((dir->handle = FindFirstFile(dir->name, &dir->data))==INVALID_HANDLE_VALUE) |
3 | 118 { |
119 free(dir); | |
120 error(rc); | |
121 return NULL; | |
122 } | |
123 | |
124 dir->number = 0; | |
125 dir->index = 0; | |
126 | |
127 return (DIR *)dir; | |
128 } | |
129 | |
130 DIR * | |
131 opendir(const char *pathname) | |
132 { | |
133 return openxdir(pathname, 0); | |
134 } | |
135 | |
136 struct dirent * | |
137 readdir(DIR *dir) | |
138 { | |
139 static int dummy_ino = 2; | |
140 | |
141 if (dir->number) | |
142 { | |
143 ULONG rc; | |
144 dir->count = 100; | |
145 if(!FindNextFile(dir->handle, &(dir->data))) | |
146 { | |
147 error(rc); | |
148 return NULL; | |
149 } | |
150 | |
151 dir->index = 0; | |
152 } | |
153 | |
154 strcpy(dir->entry.d_name, dir->data.cFileName); | |
155 dir->entry.d_ino = dummy_ino++; | |
156 dir->entry.d_reclen = strlen(dir->data.cFileName); | |
157 dir->entry.d_namlen = strlen(dir->data.cFileName); | |
158 dir->entry.d_size = dir->data.nFileSizeLow; | |
159 dir->entry.d_attribute = dir->data.dwFileAttributes; | |
160 #if 0 | |
161 dir->entry.d_time = *(USHORT *)&dir->next->ftimeLastWrite; | |
162 dir->entry.d_date = *(USHORT *)&dir->next->fdateLastWrite; | |
163 #endif | |
164 | |
165 dir->number++; | |
166 dir->index++; | |
167 return &dir->entry; | |
168 } | |
169 | |
170 long | |
171 telldir(DIR *dir) | |
172 { | |
173 return dir->number; | |
174 } | |
175 | |
176 void | |
177 seekdir(DIR *dir, long off) | |
178 { | |
179 if (dir->number > off) { | |
180 char name[MAXPATHLEN+2]; | |
181 ULONG rc; | |
182 | |
183 FindClose(dir->handle); | |
184 | |
185 strcpy(name, dir->name); | |
186 strcat(name, "*"); | |
187 | |
188 if((dir->handle = FindFirstFile(name, &(dir->data)))==NULL) | |
189 { | |
190 error(rc); | |
191 return; | |
192 } | |
193 | |
194 dir->number = 0; | |
195 dir->index = 0; | |
196 } | |
197 | |
198 while (dir->number < off && readdir(dir)) | |
199 ; | |
200 } | |
201 | |
202 void | |
203 closedir(DIR *dir) | |
204 { | |
205 FindClose(dir->handle); | |
206 free(dir); | |
207 } | |
208 | |
209 /*****************************************************************************/ | |
210 | |
211 #ifdef TEST | |
212 | |
213 main(int argc, char **argv) | |
214 { | |
215 int i; | |
216 DIR *dir; | |
217 struct dirent *ep; | |
218 | |
219 for (i = 1; i < argc; ++i) { | |
220 dir = opendir(argv[i]); | |
221 if (!dir) | |
222 continue; | |
223 while (ep = readdir(dir)) | |
224 if (strchr("\\/:", argv[i] [strlen(argv[i]) - 1])) | |
225 printf("%s%s\n", argv[i], ep->d_name); | |
226 else | |
227 printf("%s/%s\n", argv[i], ep->d_name); | |
228 closedir(dir); | |
229 } | |
230 | |
231 return 0; | |
232 } | |
233 | |
234 #endif |