]>
Commit | Line | Data |
---|---|---|
9c72faab | 1 | //======================================================================== |
2 | // | |
3 | // gfile.cc | |
4 | // | |
5 | // Miscellaneous file and directory name manipulation. | |
6 | // | |
7 | // Copyright 1996 Derek B. Noonburg | |
8 | // | |
9 | //======================================================================== | |
10 | ||
11 | #ifdef WIN32 | |
12 | extern "C" { | |
9c72faab | 13 | # ifndef _MSC_VER |
14 | # include <kpathsea/win32lib.h> | |
15 | # endif | |
16 | } | |
17 | #else // !WIN32 | |
52118ca3 | 18 | # if defined(MACOS) |
19 | # include <sys/stat.h> | |
20 | # elif !defined(ACORN) | |
9c72faab | 21 | # include <sys/types.h> |
22 | # include <sys/stat.h> | |
52118ca3 | 23 | # include <fcntl.h> |
9c72faab | 24 | # endif |
25 | # include <limits.h> | |
26 | # include <string.h> | |
52118ca3 | 27 | # if !defined(VMS) && !defined(ACORN) && !defined(MACOS) |
9c72faab | 28 | # include <pwd.h> |
29 | # endif | |
30 | # if defined(VMS) && (__DECCXX_VER < 50200000) | |
31 | # include <unixlib.h> | |
32 | # endif | |
33 | #endif // WIN32 | |
34 | #include "GString.h" | |
35 | #include "gfile.h" | |
b5cb0608 | 36 | |
37 | #ifdef HAVE_LIBCUPS | |
38 | # include <cups/cups.h> | |
39 | #endif // HAVE_LIBCUPS | |
9c72faab | 40 | |
41 | // Some systems don't define this, so just make it something reasonably | |
42 | // large. | |
43 | #ifndef PATH_MAX | |
44 | #define PATH_MAX 1024 | |
45 | #endif | |
46 | ||
47 | //------------------------------------------------------------------------ | |
48 | ||
49 | GString *getHomeDir() { | |
50 | #ifdef VMS | |
51 | //---------- VMS ---------- | |
52 | return new GString("SYS$LOGIN:"); | |
53 | ||
54 | #elif defined(__EMX__) || defined(WIN32) | |
55 | //---------- OS/2+EMX and Win32 ---------- | |
56 | char *s; | |
57 | GString *ret; | |
58 | ||
59 | if ((s = getenv("HOME"))) | |
60 | ret = new GString(s); | |
61 | else | |
62 | ret = new GString("."); | |
63 | return ret; | |
64 | ||
65 | #elif defined(ACORN) | |
66 | //---------- RISCOS ---------- | |
67 | return new GString("@"); | |
68 | ||
52118ca3 | 69 | #elif defined(MACOS) |
70 | //---------- MacOS ---------- | |
71 | return new GString(":"); | |
72 | ||
9c72faab | 73 | #else |
74 | //---------- Unix ---------- | |
75 | char *s; | |
76 | struct passwd *pw; | |
77 | GString *ret; | |
78 | ||
79 | if ((s = getenv("HOME"))) { | |
80 | ret = new GString(s); | |
b5cb0608 | 81 | # ifdef HAVE_LIBCUPS |
82 | } else if ((s = getenv("CUPS_SERVERROOT"))) { | |
83 | ret = new GString(s); | |
84 | # endif // HAVE_LIBCUPS | |
9c72faab | 85 | } else { |
86 | if ((s = getenv("USER"))) | |
87 | pw = getpwnam(s); | |
88 | else | |
89 | pw = getpwuid(getuid()); | |
90 | if (pw) | |
91 | ret = new GString(pw->pw_dir); | |
92 | else | |
93 | ret = new GString("."); | |
94 | } | |
95 | return ret; | |
96 | #endif | |
97 | } | |
98 | ||
99 | GString *getCurrentDir() { | |
100 | char buf[PATH_MAX+1]; | |
101 | ||
102 | #if defined(__EMX__) | |
103 | if (_getcwd2(buf, sizeof(buf))) | |
104 | #elif defined(WIN32) | |
105 | if (GetCurrentDirectory(sizeof(buf), buf)) | |
106 | #elif defined(ACORN) | |
107 | if (strcpy(buf, "@")) | |
52118ca3 | 108 | #elif defined(MACOS) |
109 | if (strcpy(buf, ":")) | |
9c72faab | 110 | #else |
111 | if (getcwd(buf, sizeof(buf))) | |
112 | #endif | |
113 | return new GString(buf); | |
114 | return new GString(); | |
115 | } | |
116 | ||
b5cb0608 | 117 | GString *appendToPath(GString *path, const char *fileName) { |
9c72faab | 118 | #if defined(VMS) |
119 | //---------- VMS ---------- | |
120 | //~ this should handle everything necessary for file | |
121 | //~ requesters, but it's certainly not complete | |
122 | char *p0, *p1, *p2; | |
123 | char *q1; | |
124 | ||
125 | p0 = path->getCString(); | |
126 | p1 = p0 + path->getLength() - 1; | |
127 | if (!strcmp(fileName, "-")) { | |
128 | if (*p1 == ']') { | |
129 | for (p2 = p1; p2 > p0 && *p2 != '.' && *p2 != '['; --p2) ; | |
130 | if (*p2 == '[') | |
131 | ++p2; | |
132 | path->del(p2 - p0, p1 - p2); | |
133 | } else if (*p1 == ':') { | |
134 | path->append("[-]"); | |
135 | } else { | |
136 | path->clear(); | |
137 | path->append("[-]"); | |
138 | } | |
139 | } else if ((q1 = strrchr(fileName, '.')) && !strncmp(q1, ".DIR;", 5)) { | |
140 | if (*p1 == ']') { | |
141 | path->insert(p1 - p0, '.'); | |
142 | path->insert(p1 - p0 + 1, fileName, q1 - fileName); | |
143 | } else if (*p1 == ':') { | |
144 | path->append('['); | |
145 | path->append(']'); | |
146 | path->append(fileName, q1 - fileName); | |
147 | } else { | |
148 | path->clear(); | |
149 | path->append(fileName, q1 - fileName); | |
150 | } | |
151 | } else { | |
152 | if (*p1 != ']' && *p1 != ':') | |
153 | path->clear(); | |
154 | path->append(fileName); | |
155 | } | |
156 | return path; | |
157 | ||
158 | #elif defined(WIN32) | |
159 | //---------- Win32 ---------- | |
160 | GString *tmp; | |
161 | char buf[256]; | |
162 | char *fp; | |
163 | ||
164 | tmp = new GString(path); | |
165 | tmp->append('/'); | |
166 | tmp->append(fileName); | |
167 | GetFullPathName(tmp->getCString(), sizeof(buf), buf, &fp); | |
168 | delete tmp; | |
169 | path->clear(); | |
170 | path->append(buf); | |
171 | return path; | |
172 | ||
173 | #elif defined(ACORN) | |
174 | //---------- RISCOS ---------- | |
175 | char *p; | |
176 | int i; | |
177 | ||
178 | path->append("."); | |
179 | i = path->getLength(); | |
180 | path->append(fileName); | |
181 | for (p = path->getCString() + i; *p; ++p) { | |
182 | if (*p == '/') { | |
183 | *p = '.'; | |
184 | } else if (*p == '.') { | |
185 | *p = '/'; | |
186 | } | |
187 | } | |
188 | return path; | |
189 | ||
52118ca3 | 190 | #elif defined(MACOS) |
191 | //---------- MacOS ---------- | |
192 | char *p; | |
193 | int i; | |
194 | ||
195 | path->append(":"); | |
196 | i = path->getLength(); | |
197 | path->append(fileName); | |
198 | for (p = path->getCString() + i; *p; ++p) { | |
199 | if (*p == '/') { | |
200 | *p = ':'; | |
201 | } else if (*p == '.') { | |
202 | *p = ':'; | |
203 | } | |
204 | } | |
205 | return path; | |
206 | ||
9c72faab | 207 | #elif defined(__EMX__) |
208 | //---------- OS/2+EMX ---------- | |
209 | int i; | |
210 | ||
211 | // appending "." does nothing | |
212 | if (!strcmp(fileName, ".")) | |
213 | return path; | |
214 | ||
215 | // appending ".." goes up one directory | |
216 | if (!strcmp(fileName, "..")) { | |
217 | for (i = path->getLength() - 2; i >= 0; --i) { | |
218 | if (path->getChar(i) == '/' || path->getChar(i) == '\\' || | |
219 | path->getChar(i) == ':') | |
220 | break; | |
221 | } | |
222 | if (i <= 0) { | |
223 | if (path->getChar(0) == '/' || path->getChar(0) == '\\') { | |
224 | path->del(1, path->getLength() - 1); | |
225 | } else if (path->getLength() >= 2 && path->getChar(1) == ':') { | |
226 | path->del(2, path->getLength() - 2); | |
227 | } else { | |
228 | path->clear(); | |
229 | path->append(".."); | |
230 | } | |
231 | } else { | |
232 | if (path->getChar(i-1) == ':') | |
233 | ++i; | |
234 | path->del(i, path->getLength() - i); | |
235 | } | |
236 | return path; | |
237 | } | |
238 | ||
239 | // otherwise, append "/" and new path component | |
240 | if (path->getLength() > 0 && | |
241 | path->getChar(path->getLength() - 1) != '/' && | |
242 | path->getChar(path->getLength() - 1) != '\\') | |
243 | path->append('/'); | |
244 | path->append(fileName); | |
245 | return path; | |
246 | ||
247 | #else | |
248 | //---------- Unix ---------- | |
249 | int i; | |
250 | ||
251 | // appending "." does nothing | |
252 | if (!strcmp(fileName, ".")) | |
253 | return path; | |
254 | ||
255 | // appending ".." goes up one directory | |
256 | if (!strcmp(fileName, "..")) { | |
257 | for (i = path->getLength() - 2; i >= 0; --i) { | |
258 | if (path->getChar(i) == '/') | |
259 | break; | |
260 | } | |
261 | if (i <= 0) { | |
262 | if (path->getChar(0) == '/') { | |
263 | path->del(1, path->getLength() - 1); | |
264 | } else { | |
265 | path->clear(); | |
266 | path->append(".."); | |
267 | } | |
268 | } else { | |
269 | path->del(i, path->getLength() - i); | |
270 | } | |
271 | return path; | |
272 | } | |
273 | ||
274 | // otherwise, append "/" and new path component | |
275 | if (path->getLength() > 0 && | |
276 | path->getChar(path->getLength() - 1) != '/') | |
277 | path->append('/'); | |
278 | path->append(fileName); | |
279 | return path; | |
280 | #endif | |
281 | } | |
282 | ||
b5cb0608 | 283 | GString *grabPath(const char *fileName) { |
9c72faab | 284 | #ifdef VMS |
285 | //---------- VMS ---------- | |
b5cb0608 | 286 | const char *p; |
9c72faab | 287 | |
288 | if ((p = strrchr(fileName, ']'))) | |
289 | return new GString(fileName, p + 1 - fileName); | |
290 | if ((p = strrchr(fileName, ':'))) | |
291 | return new GString(fileName, p + 1 - fileName); | |
292 | return new GString(); | |
293 | ||
294 | #elif defined(__EMX__) || defined(WIN32) | |
295 | //---------- OS/2+EMX and Win32 ---------- | |
b5cb0608 | 296 | const char *p; |
9c72faab | 297 | |
298 | if ((p = strrchr(fileName, '/'))) | |
299 | return new GString(fileName, p - fileName); | |
300 | if ((p = strrchr(fileName, '\\'))) | |
301 | return new GString(fileName, p - fileName); | |
302 | if ((p = strrchr(fileName, ':'))) | |
303 | return new GString(fileName, p + 1 - fileName); | |
304 | return new GString(); | |
305 | ||
306 | #elif defined(ACORN) | |
307 | //---------- RISCOS ---------- | |
b5cb0608 | 308 | const char *p; |
9c72faab | 309 | |
310 | if ((p = strrchr(fileName, '.'))) | |
311 | return new GString(fileName, p - fileName); | |
312 | return new GString(); | |
313 | ||
52118ca3 | 314 | #elif defined(MACOS) |
315 | //---------- MacOS ---------- | |
b5cb0608 | 316 | const char *p; |
52118ca3 | 317 | |
318 | if ((p = strrchr(fileName, ':'))) | |
319 | return new GString(fileName, p - fileName); | |
320 | return new GString(); | |
321 | ||
9c72faab | 322 | #else |
323 | //---------- Unix ---------- | |
b5cb0608 | 324 | const char *p; |
9c72faab | 325 | |
326 | if ((p = strrchr(fileName, '/'))) | |
327 | return new GString(fileName, p - fileName); | |
328 | return new GString(); | |
329 | #endif | |
330 | } | |
331 | ||
b5cb0608 | 332 | GBool isAbsolutePath(const char *path) { |
9c72faab | 333 | #ifdef VMS |
334 | //---------- VMS ---------- | |
335 | return strchr(path, ':') || | |
336 | (path[0] == '[' && path[1] != '.' && path[1] != '-'); | |
337 | ||
338 | #elif defined(__EMX__) || defined(WIN32) | |
339 | //---------- OS/2+EMX and Win32 ---------- | |
340 | return path[0] == '/' || path[0] == '\\' || path[1] == ':'; | |
341 | ||
342 | #elif defined(ACORN) | |
343 | //---------- RISCOS ---------- | |
344 | return path[0] == '$'; | |
345 | ||
52118ca3 | 346 | #elif defined(MACOS) |
347 | //---------- MacOS ---------- | |
348 | return path[0] != ':'; | |
349 | ||
9c72faab | 350 | #else |
351 | //---------- Unix ---------- | |
352 | return path[0] == '/'; | |
353 | #endif | |
354 | } | |
355 | ||
356 | GString *makePathAbsolute(GString *path) { | |
357 | #ifdef VMS | |
358 | //---------- VMS ---------- | |
359 | char buf[PATH_MAX+1]; | |
360 | ||
361 | if (!isAbsolutePath(path->getCString())) { | |
362 | if (getcwd(buf, sizeof(buf))) { | |
52118ca3 | 363 | path->insert(0, buf); |
9c72faab | 364 | } |
365 | } | |
366 | return path; | |
367 | ||
368 | #elif defined(WIN32) | |
369 | //---------- Win32 ---------- | |
370 | char buf[_MAX_PATH]; | |
371 | char *fp; | |
372 | ||
373 | buf[0] = '\0'; | |
374 | if (!GetFullPathName(path->getCString(), _MAX_PATH, buf, &fp)) { | |
375 | path->clear(); | |
376 | return path; | |
377 | } | |
378 | path->clear(); | |
379 | path->append(buf); | |
380 | return path; | |
381 | ||
382 | #elif defined(ACORN) | |
383 | //---------- RISCOS ---------- | |
384 | path->insert(0, '@'); | |
385 | return path; | |
386 | ||
52118ca3 | 387 | #elif defined(MACOS) |
388 | //---------- MacOS ---------- | |
389 | path->del(0, 1); | |
390 | return path; | |
391 | ||
9c72faab | 392 | #else |
393 | //---------- Unix and OS/2+EMX ---------- | |
394 | struct passwd *pw; | |
395 | char buf[PATH_MAX+1]; | |
396 | GString *s; | |
397 | char *p1, *p2; | |
398 | int n; | |
399 | ||
400 | if (path->getChar(0) == '~') { | |
401 | if (path->getChar(1) == '/' || | |
402 | #ifdef __EMX__ | |
403 | path->getChar(1) == '\\' || | |
404 | #endif | |
405 | path->getLength() == 1) { | |
406 | path->del(0, 1); | |
407 | s = getHomeDir(); | |
408 | path->insert(0, s); | |
409 | delete s; | |
410 | } else { | |
411 | p1 = path->getCString() + 1; | |
412 | #ifdef __EMX__ | |
413 | for (p2 = p1; *p2 && *p2 != '/' && *p2 != '\\'; ++p2) ; | |
414 | #else | |
415 | for (p2 = p1; *p2 && *p2 != '/'; ++p2) ; | |
416 | #endif | |
417 | if ((n = p2 - p1) > PATH_MAX) | |
418 | n = PATH_MAX; | |
419 | strncpy(buf, p1, n); | |
420 | buf[n] = '\0'; | |
421 | if ((pw = getpwnam(buf))) { | |
422 | path->del(0, p2 - p1 + 1); | |
423 | path->insert(0, pw->pw_dir); | |
424 | } | |
425 | } | |
426 | } else if (!isAbsolutePath(path->getCString())) { | |
427 | if (getcwd(buf, sizeof(buf))) { | |
428 | #ifndef __EMX__ | |
429 | path->insert(0, '/'); | |
430 | #endif | |
431 | path->insert(0, buf); | |
432 | } | |
433 | } | |
434 | return path; | |
435 | #endif | |
436 | } | |
437 | ||
b5cb0608 | 438 | time_t getModTime(const char *fileName) { |
52118ca3 | 439 | #ifdef WIN32 |
440 | //~ should implement this, but it's (currently) only used in xpdf | |
441 | return 0; | |
442 | #else | |
443 | struct stat statBuf; | |
444 | ||
445 | if (stat(fileName, &statBuf)) { | |
446 | return 0; | |
447 | } | |
448 | return statBuf.st_mtime; | |
449 | #endif | |
450 | } | |
451 | ||
b5cb0608 | 452 | GBool openTempFile(GString **name, FILE **f, const char *mode, const char *ext) { |
453 | #ifdef HAVE_LIBCUPS | |
9d13ae31 | 454 | char filename[1024]; // Name of temporary file... |
455 | int fd; // File descriptor... | |
52118ca3 | 456 | |
52118ca3 | 457 | |
b5cb0608 | 458 | (void)ext; |
459 | ||
9d13ae31 | 460 | // Use the CUPS temporary file function on all platforms... |
461 | if ((fd = cupsTempFd(filename, sizeof(filename))) < 0) | |
462 | return (gFalse); | |
463 | ||
464 | // Make the file descriptor a FILE *, and copy the temp filename... | |
465 | *f = fdopen(fd, mode); | |
466 | *name = new GString(filename); | |
467 | ||
468 | return (gTrue); | |
b5cb0608 | 469 | #elif defined(VMS) || defined(__EMX__) || defined(WIN32) || defined(ACORN) || defined(MACOS) |
470 | //---------- non-Unix ---------- | |
471 | char *s; | |
472 | ||
473 | // There is a security hole here: an attacker can create a symlink | |
474 | // with this file name after the tmpnam call and before the fopen | |
475 | // call. I will happily accept fixes to this function for non-Unix | |
476 | // OSs. | |
477 | if (!(s = tmpnam(NULL))) { | |
478 | return gFalse; | |
479 | } | |
480 | *name = new GString(s); | |
481 | if (ext) { | |
482 | (*name)->append(ext); | |
483 | } | |
484 | if (!(*f = fopen((*name)->getCString(), mode))) { | |
485 | delete (*name); | |
486 | return gFalse; | |
487 | } | |
488 | return gTrue; | |
489 | #else | |
490 | //---------- Unix ---------- | |
491 | char *s, *p; | |
492 | int fd; | |
493 | ||
494 | if (ext) { | |
495 | if (!(s = tmpnam(NULL))) { | |
496 | return gFalse; | |
497 | } | |
498 | *name = new GString(s); | |
499 | s = (*name)->getCString(); | |
500 | if ((p = strrchr(s, '.'))) { | |
501 | (*name)->del(p - s, (*name)->getLength() - (p - s)); | |
502 | } | |
503 | (*name)->append(ext); | |
504 | fd = open((*name)->getCString(), O_WRONLY | O_CREAT | O_EXCL, 0600); | |
505 | } else { | |
506 | # if HAVE_MKSTEMP | |
507 | if ((s = getenv("TMPDIR"))) { | |
508 | *name = new GString(s); | |
509 | } else { | |
510 | *name = new GString("/tmp"); | |
511 | } | |
512 | (*name)->append("/XXXXXX"); | |
513 | fd = mkstemp((*name)->getCString()); | |
514 | # else // HAVE_MKSTEMP | |
515 | if (!(s = tmpnam(NULL))) { | |
516 | return gFalse; | |
517 | } | |
518 | *name = new GString(s); | |
519 | fd = open((*name)->getCString(), O_WRONLY | O_CREAT | O_EXCL, 0600); | |
520 | # endif // HAVE_MKSTEMP | |
521 | } | |
522 | if (fd < 0 || !(*f = fdopen(fd, mode))) { | |
523 | delete *name; | |
524 | return gFalse; | |
525 | } | |
526 | return gTrue; | |
527 | #endif | |
52118ca3 | 528 | } |
529 | ||
9c72faab | 530 | //------------------------------------------------------------------------ |
531 | // GDir and GDirEntry | |
532 | //------------------------------------------------------------------------ | |
533 | ||
b5cb0608 | 534 | GDirEntry::GDirEntry(const char *dirPath, const char *name1, GBool doStat) { |
9c72faab | 535 | #ifdef VMS |
536 | char *p; | |
537 | #elif defined(WIN32) | |
538 | int fa; | |
539 | GString *s; | |
540 | #elif defined(ACORN) | |
541 | #else | |
542 | struct stat st; | |
543 | GString *s; | |
544 | #endif | |
545 | ||
546 | name = new GString(name1); | |
547 | dir = gFalse; | |
548 | if (doStat) { | |
549 | #ifdef VMS | |
550 | if (!strcmp(name1, "-") || | |
551 | ((p = strrchr(name1, '.')) && !strncmp(p, ".DIR;", 5))) | |
552 | dir = gTrue; | |
553 | #elif defined(ACORN) | |
554 | #else | |
555 | s = new GString(dirPath); | |
556 | appendToPath(s, name1); | |
557 | #ifdef WIN32 | |
558 | fa = GetFileAttributes(s->getCString()); | |
559 | dir = (fa != 0xFFFFFFFF && (fa & FILE_ATTRIBUTE_DIRECTORY)); | |
560 | #else | |
561 | if (stat(s->getCString(), &st) == 0) | |
562 | dir = S_ISDIR(st.st_mode); | |
563 | #endif | |
564 | delete s; | |
565 | #endif | |
566 | } | |
567 | } | |
568 | ||
569 | GDirEntry::~GDirEntry() { | |
570 | delete name; | |
571 | } | |
572 | ||
b5cb0608 | 573 | GDir::GDir(const char *name, GBool doStat1) { |
9c72faab | 574 | path = new GString(name); |
575 | doStat = doStat1; | |
576 | #if defined(WIN32) | |
577 | GString *tmp; | |
578 | ||
579 | tmp = path->copy(); | |
580 | tmp->append("/*.*"); | |
581 | hnd = FindFirstFile(tmp->getCString(), &ffd); | |
582 | delete tmp; | |
583 | #elif defined(ACORN) | |
52118ca3 | 584 | #elif defined(MACOS) |
9c72faab | 585 | #else |
586 | dir = opendir(name); | |
587 | #ifdef VMS | |
588 | needParent = strchr(name, '[') != NULL; | |
589 | #endif | |
590 | #endif | |
591 | } | |
592 | ||
593 | GDir::~GDir() { | |
594 | delete path; | |
595 | #if defined(WIN32) | |
596 | if (hnd) { | |
597 | FindClose(hnd); | |
598 | hnd = NULL; | |
599 | } | |
600 | #elif defined(ACORN) | |
52118ca3 | 601 | #elif defined(MACOS) |
9c72faab | 602 | #else |
603 | if (dir) | |
604 | closedir(dir); | |
605 | #endif | |
606 | } | |
607 | ||
608 | GDirEntry *GDir::getNextEntry() { | |
609 | struct dirent *ent; | |
610 | GDirEntry *e; | |
611 | ||
612 | e = NULL; | |
613 | #if defined(WIN32) | |
614 | e = new GDirEntry(path->getCString(), ffd.cFileName, doStat); | |
615 | if (hnd && !FindNextFile(hnd, &ffd)) { | |
616 | FindClose(hnd); | |
617 | hnd = NULL; | |
618 | } | |
619 | #elif defined(ACORN) | |
52118ca3 | 620 | #elif defined(MACOS) |
9c72faab | 621 | #else |
622 | if (dir) { | |
623 | #ifdef VMS | |
624 | if (needParent) { | |
625 | e = new GDirEntry(path->getCString(), "-", doStat); | |
626 | needParent = gFalse; | |
627 | return e; | |
628 | } | |
629 | #endif | |
630 | ent = readdir(dir); | |
631 | #ifndef VMS | |
632 | if (ent && !strcmp(ent->d_name, ".")) | |
633 | ent = readdir(dir); | |
634 | #endif | |
635 | if (ent) | |
636 | e = new GDirEntry(path->getCString(), ent->d_name, doStat); | |
637 | } | |
638 | #endif | |
639 | return e; | |
640 | } | |
641 | ||
642 | void GDir::rewind() { | |
643 | #ifdef WIN32 | |
644 | GString *tmp; | |
645 | ||
646 | if (hnd) | |
647 | FindClose(hnd); | |
648 | tmp = path->copy(); | |
649 | tmp->append("/*.*"); | |
650 | hnd = FindFirstFile(tmp->getCString(), &ffd); | |
651 | #elif defined(ACORN) | |
52118ca3 | 652 | #elif defined(MACOS) |
9c72faab | 653 | #else |
654 | if (dir) | |
655 | rewinddir(dir); | |
656 | #ifdef VMS | |
657 | needParent = strchr(path->getCString(), '[') != NULL; | |
658 | #endif | |
659 | #endif | |
660 | } |