source: trunk/poppler/mypoppler/goo/gfile.cc @ 515

Last change on this file since 515 was 515, checked in by Silvan Scherrer, 9 years ago

updated poppler to 0.20.3

File size: 18.4 KB
Line 
1//========================================================================
2//
3// gfile.cc
4//
5// Miscellaneous file and directory name manipulation.
6//
7// Copyright 1996-2003 Glyph & Cog, LLC
8//
9//========================================================================
10
11//========================================================================
12//
13// Modified under the Poppler project - http://poppler.freedesktop.org
14//
15// All changes made under the Poppler project to this file are licensed
16// under GPL version 2 or later
17//
18// Copyright (C) 2006 Takashi Iwai <tiwai@suse.de>
19// Copyright (C) 2006 Kristian HÞgsberg <krh@redhat.com>
20// Copyright (C) 2008 Adam Batkin <adam@batkin.net>
21// Copyright (C) 2008, 2010 Hib Eris <hib@hiberis.nl>
22// Copyright (C) 2009 Albert Astals Cid <aacid@kde.org>
23// Copyright (C) 2009 Kovid Goyal <kovid@kovidgoyal.net>
24//
25// To see a description of the changes please see the Changelog file that
26// came with your tarball or type make ChangeLog if you are building from git
27//
28//========================================================================
29
30#include <config.h>
31
32#ifdef _WIN32
33#  include <time.h>
34#else
35#  if defined(MACOS)
36#    include <sys/stat.h>
37#  elif !defined(ACORN)
38#    include <sys/types.h>
39#    include <sys/stat.h>
40#    include <fcntl.h>
41#  endif
42#  include <time.h>
43#  include <limits.h>
44#  include <string.h>
45#  if !defined(VMS) && !defined(ACORN) && !defined(MACOS) && !defined(OS2)
46#    include <pwd.h>
47#  endif
48#  if defined(VMS) && (__DECCXX_VER < 50200000)
49#    include <unixlib.h>
50#  endif
51#endif // _WIN32
52#include "GooString.h"
53#include "gfile.h"
54
55// Some systems don't define this, so just make it something reasonably
56// large.
57#ifndef PATH_MAX
58#define PATH_MAX 1024
59#endif
60
61//------------------------------------------------------------------------
62
63GooString *getHomeDir() {
64#ifdef VMS
65  //---------- VMS ----------
66  return new GooString("SYS$LOGIN:");
67
68#elif defined(__EMX__) || defined(_WIN32) || defined(OS2)
69  //---------- OS/2+EMX and Win32 ----------
70  char *s;
71  GooString *ret;
72
73  if ((s = getenv("HOME")))
74    ret = new GooString(s);
75  else
76    ret = new GooString(".");
77  return ret;
78
79#elif defined(ACORN)
80  //---------- RISCOS ----------
81  return new GooString("@");
82
83#elif defined(MACOS)
84  //---------- MacOS ----------
85  return new GooString(":");
86
87#else
88  //---------- Unix ----------
89  char *s;
90  struct passwd *pw;
91  GooString *ret;
92
93  if ((s = getenv("HOME"))) {
94    ret = new GooString(s);
95  } else {
96    if ((s = getenv("USER")))
97      pw = getpwnam(s);
98    else
99      pw = getpwuid(getuid());
100    if (pw)
101      ret = new GooString(pw->pw_dir);
102    else
103      ret = new GooString(".");
104  }
105  return ret;
106#endif
107}
108
109GooString *getCurrentDir() {
110  char buf[PATH_MAX+1];
111
112#if defined(__EMX__)
113  if (_getcwd2(buf, sizeof(buf)))
114#elif defined(_WIN32)
115  if (GetCurrentDirectory(sizeof(buf), buf))
116#elif defined(ACORN)
117  if (strcpy(buf, "@"))
118#elif defined(MACOS)
119  if (strcpy(buf, ":"))
120#else
121  if (getcwd(buf, sizeof(buf)))
122#endif
123    return new GooString(buf);
124  return new GooString();
125}
126
127GooString *appendToPath(GooString *path, const char *fileName) {
128#if defined(VMS)
129  //---------- VMS ----------
130  //~ this should handle everything necessary for file
131  //~ requesters, but it's certainly not complete
132  char *p0, *p1, *p2;
133  char *q1;
134
135  p0 = path->getCString();
136  p1 = p0 + path->getLength() - 1;
137  if (!strcmp(fileName, "-")) {
138    if (*p1 == ']') {
139      for (p2 = p1; p2 > p0 && *p2 != '.' && *p2 != '['; --p2) ;
140      if (*p2 == '[')
141        ++p2;
142      path->del(p2 - p0, p1 - p2);
143    } else if (*p1 == ':') {
144      path->append("[-]");
145    } else {
146      path->clear();
147      path->append("[-]");
148    }
149  } else if ((q1 = strrchr(fileName, '.')) && !strncmp(q1, ".DIR;", 5)) {
150    if (*p1 == ']') {
151      path->insert(p1 - p0, '.');
152      path->insert(p1 - p0 + 1, fileName, q1 - fileName);
153    } else if (*p1 == ':') {
154      path->append('[');
155      path->append(']');
156      path->append(fileName, q1 - fileName);
157    } else {
158      path->clear();
159      path->append(fileName, q1 - fileName);
160    }
161  } else {
162    if (*p1 != ']' && *p1 != ':')
163      path->clear();
164    path->append(fileName);
165  }
166  return path;
167
168#elif defined(_WIN32)
169  //---------- Win32 ----------
170  GooString *tmp;
171  char buf[256];
172  char *fp;
173
174  tmp = new GooString(path);
175  tmp->append('/');
176  tmp->append(fileName);
177  GetFullPathName(tmp->getCString(), sizeof(buf), buf, &fp);
178  delete tmp;
179  path->clear();
180  path->append(buf);
181  return path;
182
183#elif defined(ACORN)
184  //---------- RISCOS ----------
185  char *p;
186  int i;
187
188  path->append(".");
189  i = path->getLength();
190  path->append(fileName);
191  for (p = path->getCString() + i; *p; ++p) {
192    if (*p == '/') {
193      *p = '.';
194    } else if (*p == '.') {
195      *p = '/';
196    }
197  }
198  return path;
199
200#elif defined(MACOS)
201  //---------- MacOS ----------
202  char *p;
203  int i;
204
205  path->append(":");
206  i = path->getLength();
207  path->append(fileName);
208  for (p = path->getCString() + i; *p; ++p) {
209    if (*p == '/') {
210      *p = ':';
211    } else if (*p == '.') {
212      *p = ':';
213    }
214  }
215  return path;
216
217#elif defined(__EMX__) || defined(OS2)
218  //---------- OS/2+EMX ----------
219  int i;
220
221  // appending "." does nothing
222  if (!strcmp(fileName, "."))
223    return path;
224
225  // appending ".." goes up one directory
226  if (!strcmp(fileName, "..")) {
227    for (i = path->getLength() - 2; i >= 0; --i) {
228      if (path->getChar(i) == '/' || path->getChar(i) == '\\' ||
229          path->getChar(i) == ':')
230        break;
231    }
232    if (i <= 0) {
233      if (path->getChar(0) == '/' || path->getChar(0) == '\\') {
234        path->del(1, path->getLength() - 1);
235      } else if (path->getLength() >= 2 && path->getChar(1) == ':') {
236        path->del(2, path->getLength() - 2);
237      } else {
238        path->clear();
239        path->append("..");
240      }
241    } else {
242      if (path->getChar(i-1) == ':')
243        ++i;
244      path->del(i, path->getLength() - i);
245    }
246    return path;
247  }
248
249  // otherwise, append "/" and new path component
250  if (path->getLength() > 0 &&
251      path->getChar(path->getLength() - 1) != '/' &&
252      path->getChar(path->getLength() - 1) != '\\')
253    path->append('/');
254  path->append(fileName);
255  return path;
256
257#else
258  //---------- Unix ----------
259  int i;
260
261  // appending "." does nothing
262  if (!strcmp(fileName, "."))
263    return path;
264
265  // appending ".." goes up one directory
266  if (!strcmp(fileName, "..")) {
267    for (i = path->getLength() - 2; i >= 0; --i) {
268      if (path->getChar(i) == '/')
269        break;
270    }
271    if (i <= 0) {
272      if (path->getChar(0) == '/') {
273        path->del(1, path->getLength() - 1);
274      } else {
275        path->clear();
276        path->append("..");
277      }
278    } else {
279      path->del(i, path->getLength() - i);
280    }
281    return path;
282  }
283
284  // otherwise, append "/" and new path component
285  if (path->getLength() > 0 &&
286      path->getChar(path->getLength() - 1) != '/')
287    path->append('/');
288  path->append(fileName);
289  return path;
290#endif
291}
292
293GooString *grabPath(char *fileName) {
294#ifdef VMS
295  //---------- VMS ----------
296  char *p;
297
298  if ((p = strrchr(fileName, ']')))
299    return new GooString(fileName, p + 1 - fileName);
300  if ((p = strrchr(fileName, ':')))
301    return new GooString(fileName, p + 1 - fileName);
302  return new GooString();
303
304#elif defined(__EMX__) || defined(_WIN32) || defined(OS2)
305  //---------- OS/2+EMX and Win32 ----------
306  char *p;
307
308  if ((p = strrchr(fileName, '/')))
309    return new GooString(fileName, p - fileName);
310  if ((p = strrchr(fileName, '\\')))
311    return new GooString(fileName, p - fileName);
312  if ((p = strrchr(fileName, ':')))
313    return new GooString(fileName, p + 1 - fileName);
314  return new GooString();
315
316#elif defined(ACORN)
317  //---------- RISCOS ----------
318  char *p;
319
320  if ((p = strrchr(fileName, '.')))
321    return new GooString(fileName, p - fileName);
322  return new GooString();
323
324#elif defined(MACOS)
325  //---------- MacOS ----------
326  char *p;
327
328  if ((p = strrchr(fileName, ':')))
329    return new GooString(fileName, p - fileName);
330  return new GooString();
331
332#else
333  //---------- Unix ----------
334  char *p;
335
336  if ((p = strrchr(fileName, '/')))
337    return new GooString(fileName, p - fileName);
338  return new GooString();
339#endif
340}
341
342GBool isAbsolutePath(char *path) {
343#ifdef VMS
344  //---------- VMS ----------
345  return strchr(path, ':') ||
346         (path[0] == '[' && path[1] != '.' && path[1] != '-');
347
348#elif defined(__EMX__) || defined(_WIN32) || defined(OS2)
349  //---------- OS/2+EMX and Win32 ----------
350  return path[0] == '/' || path[0] == '\\' || path[1] == ':';
351
352#elif defined(ACORN)
353  //---------- RISCOS ----------
354  return path[0] == '$';
355
356#elif defined(MACOS)
357  //---------- MacOS ----------
358  return path[0] != ':';
359
360#else
361  //---------- Unix ----------
362  return path[0] == '/';
363#endif
364}
365
366GooString *makePathAbsolute(GooString *path) {
367#ifdef VMS
368  //---------- VMS ----------
369  char buf[PATH_MAX+1];
370
371  if (!isAbsolutePath(path->getCString())) {
372    if (getcwd(buf, sizeof(buf))) {
373      path->insert(0, buf);
374    }
375  }
376  return path;
377
378#elif defined(_WIN32)
379  //---------- Win32 ----------
380  char buf[MAX_PATH];
381  char *fp;
382
383  buf[0] = '\0';
384  if (!GetFullPathName(path->getCString(), MAX_PATH, buf, &fp)) {
385    path->clear();
386    return path;
387  }
388  path->clear();
389  path->append(buf);
390  return path;
391
392#elif defined(ACORN)
393  //---------- RISCOS ----------
394  path->insert(0, '@');
395  return path;
396
397#elif defined(MACOS)
398  //---------- MacOS ----------
399  path->del(0, 1);
400  return path;
401
402#elif defined(OS2)
403  //---------- OS/2 -----------
404  char buf[_MAX_PATH];
405  buf[0] = '\0';
406  if (!_fullpath( buf, path->getCString(), _MAX_PATH ) ) {
407    path->clear();
408    return path;
409  }
410  path->clear();
411  path->append(buf);
412  return path;
413
414#else
415  //---------- Unix and OS/2+EMX ----------
416  struct passwd *pw;
417  char buf[PATH_MAX+1];
418  GooString *s;
419  char *p1, *p2;
420  int n;
421
422  if (path->getChar(0) == '~') {
423    if (path->getChar(1) == '/' ||
424#ifdef __EMX__
425        path->getChar(1) == '\\' ||
426#endif
427        path->getLength() == 1) {
428      path->del(0, 1);
429      s = getHomeDir();
430      path->insert(0, s);
431      delete s;
432    } else {
433      p1 = path->getCString() + 1;
434#ifdef __EMX__
435      for (p2 = p1; *p2 && *p2 != '/' && *p2 != '\\'; ++p2) ;
436#else
437      for (p2 = p1; *p2 && *p2 != '/'; ++p2) ;
438#endif
439      if ((n = p2 - p1) > PATH_MAX)
440        n = PATH_MAX;
441      strncpy(buf, p1, n);
442      buf[n] = '\0';
443      if ((pw = getpwnam(buf))) {
444        path->del(0, p2 - p1 + 1);
445        path->insert(0, pw->pw_dir);
446      }
447    }
448  } else if (!isAbsolutePath(path->getCString())) {
449    if (getcwd(buf, sizeof(buf))) {
450#ifndef __EMX__
451      path->insert(0, '/');
452#endif
453      path->insert(0, buf);
454    }
455  }
456  return path;
457#endif
458}
459
460time_t getModTime(char *fileName) {
461#ifdef _WIN32
462  //~ should implement this, but it's (currently) only used in xpdf
463  return 0;
464#else
465  struct stat statBuf;
466
467  if (stat(fileName, &statBuf)) {
468    return 0;
469  }
470  return statBuf.st_mtime;
471#endif
472}
473
474GBool openTempFile(GooString **name, FILE **f, const char *mode) {
475#if defined(_WIN32)
476  //---------- Win32 ----------
477  char *tempDir;
478  GooString *s, *s2;
479  char buf[32];
480  FILE *f2;
481  int t, i;
482
483  // this has the standard race condition problem, but I haven't found
484  // a better way to generate temp file names with extensions on
485  // Windows
486  if ((tempDir = getenv("TEMP"))) {
487    s = new GooString(tempDir);
488    s->append('\\');
489  } else {
490    s = new GooString();
491  }
492  s->appendf("x_{0:d}_{1:d}_",
493             (int)GetCurrentProcessId(), (int)GetCurrentThreadId());
494  t = (int)time(NULL);
495  for (i = 0; i < 1000; ++i) {
496    s2 = s->copy()->appendf("{0:d}", t + i);
497    if (!(f2 = fopen(s2->getCString(), "r"))) {
498      if (!(f2 = fopen(s2->getCString(), mode))) {
499        delete s2;
500        delete s;
501        return gFalse;
502      }
503      *name = s2;
504      *f = f2;
505      delete s;
506      return gTrue;
507    }
508    fclose(f2);
509    delete s2;
510  }
511  delete s;
512  return gFalse;
513
514#elif defined(VMS) || defined(__EMX__) || defined(ACORN) || defined(MACOS) || defined(OS2)
515  //---------- non-Unix ----------
516  char *s;
517
518  // There is a security hole here: an attacker can create a symlink
519  // with this file name after the tmpnam call and before the fopen
520  // call.  I will happily accept fixes to this function for non-Unix
521  // OSs.
522  if (!(s = tmpnam(NULL))) {
523    return gFalse;
524  }
525  *name = new GooString(s);
526  if (!(*f = fopen((*name)->getCString(), mode))) {
527    delete (*name);
528    *name = NULL;
529    return gFalse;
530  }
531  return gTrue;
532#else
533  //---------- Unix ----------
534  char *s;
535  int fd;
536
537#if HAVE_MKSTEMP
538  if ((s = getenv("TMPDIR"))) {
539    *name = new GooString(s);
540  } else {
541    *name = new GooString("/tmp");
542  }
543  (*name)->append("/XXXXXX");
544  fd = mkstemp((*name)->getCString());
545#else // HAVE_MKSTEMP
546  if (!(s = tmpnam(NULL))) {
547    return gFalse;
548  }
549  *name = new GooString(s);
550  fd = open((*name)->getCString(), O_WRONLY | O_CREAT | O_EXCL, 0600);
551#endif // HAVE_MKSTEMP
552  if (fd < 0 || !(*f = fdopen(fd, mode))) {
553    delete *name;
554    *name = NULL;
555    return gFalse;
556  }
557  return gTrue;
558#endif
559}
560
561GBool executeCommand(char *cmd) {
562#ifdef VMS
563  return system(cmd) ? gTrue : gFalse;
564#else
565  return system(cmd) ? gFalse : gTrue;
566#endif
567}
568
569#ifdef WIN32
570GooString *fileNameToUTF8(char *path) {
571  GooString *s;
572  char *p;
573
574  s = new GooString();
575  for (p = path; *p; ++p) {
576    if (*p & 0x80) {
577      s->append((char)(0xc0 | ((*p >> 6) & 0x03)));
578      s->append((char)(0x80 | (*p & 0x3f)));
579    } else {
580      s->append(*p);
581    }
582  }
583  return s;
584}
585
586GooString *fileNameToUTF8(wchar_t *path) {
587  GooString *s;
588  wchar_t *p;
589
590  s = new GooString();
591  for (p = path; *p; ++p) {
592    if (*p < 0x80) {
593      s->append((char)*p);
594    } else if (*p < 0x800) {
595      s->append((char)(0xc0 | ((*p >> 6) & 0x1f)));
596      s->append((char)(0x80 | (*p & 0x3f)));
597    } else {
598      s->append((char)(0xe0 | ((*p >> 12) & 0x0f)));
599      s->append((char)(0x80 | ((*p >> 6) & 0x3f)));
600      s->append((char)(0x80 | (*p & 0x3f)));
601    }
602  }
603  return s;
604}
605#endif
606
607FILE *openFile(const char *path, const char *mode) {
608#ifdef WIN32
609  OSVERSIONINFO version;
610  wchar_t wPath[_MAX_PATH + 1];
611  char nPath[_MAX_PATH + 1];
612  wchar_t wMode[8];
613  const char *p;
614  int i;
615
616  // NB: _wfopen is only available in NT
617  version.dwOSVersionInfoSize = sizeof(version);
618  GetVersionEx(&version);
619  if (version.dwPlatformId == VER_PLATFORM_WIN32_NT) {
620    for (p = path, i = 0; *p && i < _MAX_PATH; ++i) {
621      if ((p[0] & 0xe0) == 0xc0 &&
622          p[1] && (p[1] & 0xc0) == 0x80) {
623        wPath[i] = (wchar_t)(((p[0] & 0x1f) << 6) |
624                             (p[1] & 0x3f));
625        p += 2;
626      } else if ((p[0] & 0xf0) == 0xe0 &&
627                 p[1] && (p[1] & 0xc0) == 0x80 &&
628                 p[2] && (p[2] & 0xc0) == 0x80) {
629        wPath[i] = (wchar_t)(((p[0] & 0x0f) << 12) |
630                             ((p[1] & 0x3f) << 6) |
631                             (p[2] & 0x3f));
632        p += 3;
633      } else {
634        wPath[i] = (wchar_t)(p[0] & 0xff);
635        p += 1;
636      }
637    }
638    wPath[i] = (wchar_t)0;
639    for (i = 0; mode[i] && i < sizeof(mode) - 1; ++i) {
640      wMode[i] = (wchar_t)(mode[i] & 0xff);
641    }
642    wMode[i] = (wchar_t)0;
643    return _wfopen(wPath, wMode);
644  } else {
645    for (p = path, i = 0; *p && i < _MAX_PATH; ++i) {
646      if ((p[0] & 0xe0) == 0xc0 &&
647          p[1] && (p[1] & 0xc0) == 0x80) {
648        nPath[i] = (char)(((p[0] & 0x1f) << 6) |
649                          (p[1] & 0x3f));
650        p += 2;
651      } else if ((p[0] & 0xf0) == 0xe0 &&
652                 p[1] && (p[1] & 0xc0) == 0x80 &&
653                 p[2] && (p[2] & 0xc0) == 0x80) {
654        nPath[i] = (char)(((p[1] & 0x3f) << 6) |
655                          (p[2] & 0x3f));
656        p += 3;
657      } else {
658        nPath[i] = p[0];
659        p += 1;
660      }
661    }
662    nPath[i] = '\0';
663    return fopen(nPath, mode);
664  }
665#else
666  return fopen(path, mode);
667#endif
668}
669
670char *getLine(char *buf, int size, FILE *f) {
671  int c, i;
672
673  i = 0;
674  while (i < size - 1) {
675    if ((c = fgetc(f)) == EOF) {
676      break;
677    }
678    buf[i++] = (char)c;
679    if (c == '\x0a') {
680      break;
681    }
682    if (c == '\x0d') {
683      c = fgetc(f);
684      if (c == '\x0a' && i < size - 1) {
685        buf[i++] = (char)c;
686      } else if (c != EOF) {
687        ungetc(c, f);
688      }
689      break;
690    }
691  }
692  buf[i] = '\0';
693  if (i == 0) {
694    return NULL;
695  }
696  return buf;
697}
698
699//------------------------------------------------------------------------
700// GDir and GDirEntry
701//------------------------------------------------------------------------
702
703GDirEntry::GDirEntry(char *dirPath, char *nameA, GBool doStat) {
704#ifdef VMS
705  char *p;
706#elif defined(_WIN32)
707  DWORD fa;
708#elif defined(ACORN)
709#else
710  struct stat st;
711#endif
712
713  name = new GooString(nameA);
714  dir = gFalse;
715  fullPath = new GooString(dirPath);
716  appendToPath(fullPath, nameA);
717  if (doStat) {
718#ifdef VMS
719    if (!strcmp(nameA, "-") ||
720        ((p = strrchr(nameA, '.')) && !strncmp(p, ".DIR;", 5)))
721      dir = gTrue;
722#elif defined(ACORN)
723#else
724#ifdef _WIN32
725    fa = GetFileAttributes(fullPath->getCString());
726    dir = (fa != 0xFFFFFFFF && (fa & FILE_ATTRIBUTE_DIRECTORY));
727#else
728    if (stat(fullPath->getCString(), &st) == 0)
729      dir = S_ISDIR(st.st_mode);
730#endif
731#endif
732  }
733}
734
735GDirEntry::~GDirEntry() {
736  delete fullPath;
737  delete name;
738}
739
740GDir::GDir(char *name, GBool doStatA) {
741  path = new GooString(name);
742  doStat = doStatA;
743#if defined(_WIN32)
744  GooString *tmp;
745
746  tmp = path->copy();
747  tmp->append("/*.*");
748  hnd = FindFirstFile(tmp->getCString(), &ffd);
749  delete tmp;
750#elif defined(ACORN)
751#elif defined(MACOS)
752#else
753  dir = opendir(name);
754#ifdef VMS
755  needParent = strchr(name, '[') != NULL;
756#endif
757#endif
758}
759
760GDir::~GDir() {
761  delete path;
762#if defined(_WIN32)
763  if (hnd != INVALID_HANDLE_VALUE) {
764    FindClose(hnd);
765    hnd = INVALID_HANDLE_VALUE;
766  }
767#elif defined(ACORN)
768#elif defined(MACOS)
769#else
770  if (dir)
771    closedir(dir);
772#endif
773}
774
775GDirEntry *GDir::getNextEntry() {
776  GDirEntry *e;
777
778#if defined(_WIN32)
779  if (hnd != INVALID_HANDLE_VALUE) {
780    e = new GDirEntry(path->getCString(), ffd.cFileName, doStat);
781    if (!FindNextFile(hnd, &ffd)) {
782      FindClose(hnd);
783      hnd = INVALID_HANDLE_VALUE;
784    }
785  } else {
786    e = NULL;
787  }
788#elif defined(ACORN)
789#elif defined(MACOS)
790#elif defined(VMS)
791  struct dirent *ent;
792  e = NULL;
793  if (dir) {
794    if (needParent) {
795      e = new GDirEntry(path->getCString(), "-", doStat);
796      needParent = gFalse;
797      return e;
798    }
799    ent = readdir(dir);
800    if (ent) {
801      e = new GDirEntry(path->getCString(), ent->d_name, doStat);
802    }
803  }
804#else
805  struct dirent *ent;
806  e = NULL;
807  if (dir) {
808    do {
809      ent = readdir(dir);
810    }
811    while (ent && (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..")));
812    if (ent) {
813      e = new GDirEntry(path->getCString(), ent->d_name, doStat);
814    }
815  }
816#endif
817
818  return e;
819}
820
821void GDir::rewind() {
822#ifdef _WIN32
823  GooString *tmp;
824
825  if (hnd != INVALID_HANDLE_VALUE)
826    FindClose(hnd);
827  tmp = path->copy();
828  tmp->append("/*.*");
829  hnd = FindFirstFile(tmp->getCString(), &ffd);
830  delete tmp;
831#elif defined(ACORN)
832#elif defined(MACOS)
833#else
834  if (dir)
835    rewinddir(dir);
836#ifdef VMS
837  needParent = strchr(path->getCString(), '[') != NULL;
838#endif
839#endif
840}
Note: See TracBrowser for help on using the repository browser.