]> www.fi.muni.cz Git - evince.git/blob - pdf/goo/gfile.cc
Initial revision
[evince.git] / pdf / goo / gfile.cc
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" {
13 #include <sys/stat.h>
14 #include <kpathsea/win32lib.h>
15 }
16 #else // !WIN32
17 #include <sys/stat.h>
18 #include <limits.h>
19 #include <string.h>
20 #ifndef VMS
21 #include <pwd.h>
22 #endif
23 #endif // WIN32
24 #if defined(VMS) && (__DECCXX_VER < 50200000)
25 #include <unixlib.h>
26 #endif
27 #include "GString.h"
28 #include "gfile.h"
29
30 // Some systems don't define this, so just make it something reasonably
31 // large.
32 #ifndef PATH_MAX
33 #define PATH_MAX 1024
34 #endif
35
36 //------------------------------------------------------------------------
37
38 GString *getHomeDir() {
39 #ifdef VMS
40   //---------- VMS ----------
41   return new GString("SYS$LOGIN:");
42
43 #elif defined(__EMX__) || defined(WIN32)
44   //---------- OS/2+EMX and Win32 ----------
45   char *s;
46   GString *ret;
47
48   if ((s = getenv("HOME")))
49     ret = new GString(s);
50   else
51     ret = new GString(".");
52   return ret;
53
54 #else
55   //---------- Unix ----------
56   char *s;
57   struct passwd *pw;
58   GString *ret;
59
60   if ((s = getenv("HOME"))) {
61     ret = new GString(s);
62   } else {
63     if ((s = getenv("USER")))
64       pw = getpwnam(s);
65     else
66       pw = getpwuid(getuid());
67     if (pw)
68       ret = new GString(pw->pw_dir);
69     else
70       ret = new GString(".");
71   }
72   return ret;
73 #endif
74 }
75
76 GString *getCurrentDir() {
77   char buf[PATH_MAX+1];
78
79 #if defined(__EMX__)
80   if (!_getcwd2(buf, sizeof(buf)))
81 #elif defined(WIN32)
82   if (!GetCurrentDirectory(sizeof(buf), buf))
83 #else
84   if (!getcwd(buf, sizeof(buf)))
85 #endif
86     return new GString();
87   return new GString(buf);
88 }
89
90 GString *appendToPath(GString *path, char *fileName) {
91 #if defined(VMS)
92   //---------- VMS ----------
93   //~ this should handle everything necessary for file
94   //~ requesters, but it's certainly not complete
95   char *p0, *p1, *p2;
96   char *q1;
97
98   p0 = path->getCString();
99   p1 = p0 + path->getLength() - 1;
100   if (!strcmp(fileName, "-")) {
101     if (*p1 == ']') {
102       for (p2 = p1; p2 > p0 && *p2 != '.' && *p2 != '['; --p2) ;
103       if (*p2 == '[')
104         ++p2;
105       path->del(p2 - p0, p1 - p2);
106     } else if (*p1 == ':') {
107       path->append("[-]");
108     } else {
109       path->clear();
110       path->append("[-]");
111     }
112   } else if ((q1 = strrchr(fileName, '.')) && !strncmp(q1, ".DIR;", 5)) {
113     if (*p1 == ']') {
114       path->insert(p1 - p0, '.');
115       path->insert(p1 - p0 + 1, fileName, q1 - fileName);
116     } else if (*p1 == ':') {
117       path->append('[');
118       path->append(']');
119       path->append(fileName, q1 - fileName);
120     } else {
121       path->clear();
122       path->append(fileName, q1 - fileName);
123     }
124   } else {
125     if (*p1 != ']' && *p1 != ':')
126       path->clear();
127     path->append(fileName);
128   }
129   return path;
130
131 #elif defined(WIN32)
132   //---------- Win32 ----------
133   GString *tmp;
134   char buf[256];
135   char *fp;
136
137   tmp = new GString(path);
138   tmp->append('/');
139   tmp->append(fileName);
140   GetFullPathName(tmp->getCString(), sizeof(buf), buf, &fp);
141   delete tmp;
142   path->clear();
143   path->append(buf);
144   return path;
145
146 #else
147   //---------- Unix and OS/2+EMX ----------
148   int i;
149
150   // appending "." does nothing
151   if (!strcmp(fileName, "."))
152     return path;
153
154   // appending ".." goes up one directory
155   if (!strcmp(fileName, "..")) {
156     for (i = path->getLength() - 2; i >= 0; --i) {
157 #ifdef __EMX__
158       if (path->getChar(i) == '/' || path->getChar(i) == '\\' ||
159           path->getChar(i) == ':')
160 #else
161       if (path->getChar(i) == '/')
162 #endif
163         break;
164     }
165     if (i <= 0) {
166 #ifdef __EMX__
167       if (path->getChar[0] == '/' || path->getChar[0] == '\\') {
168         path->del(1, path->getLength() - 1);
169       } else if (path->getLength() >= 2 && path->getChar[1] == ':') {
170         path->del(2, path->getLength() - 2);
171       } else {
172         path->clear();
173         path->append("..");
174       }
175 #else
176       if (path->getChar(0) == '/') {
177         path->del(1, path->getLength() - 1);
178       } else {
179         path->clear();
180         path->append("..");
181       }
182 #endif
183     } else {
184 #ifdef __EMX__
185       if (path->getChar(i) == ':')
186         ++i;
187 #endif
188       path->del(i, path->getLength() - i);
189     }
190     return path;
191   }
192
193   // otherwise, append "/" and new path component
194 #ifdef __EMX__
195   if (path->getLength() > 0 &&
196       path->getChar(path->getLength() - 1) != '/' &&
197       path->getChar(path->getLength() - 1) != '\\')
198 #else
199   if (path->getLength() > 0 &&
200       path->getChar(path->getLength() - 1) != '/')
201 #endif
202     path->append('/');
203   path->append(fileName);
204   return path;
205 #endif
206 }
207
208 GString *grabPath(char *fileName) {
209 #ifdef VMS
210   //---------- VMS ----------
211   char *p;
212
213   if ((p = strrchr(fileName, ']')))
214     return new GString(fileName, p + 1 - fileName);
215   if ((p = strrchr(fileName, ':')))
216     return new GString(fileName, p + 1 - fileName);
217   return new GString();
218
219 #elif defined(__EMX__) || defined(WIN32)
220   //---------- OS/2+EMX and Win32 ----------
221   char *p;
222
223   if ((p = strrchr(fileName, '/')))
224     return new GString(fileName, p - fileName);
225   if ((p = strrchr(fileName, '\\')))
226     return new GString(fileName, p - fileName);
227   if ((p = strrchr(fileName, ':')))
228     return new GString(fileName, p + 1 - fileName);
229   return new GString();
230
231 #else
232   //---------- Unix ----------
233   char *p;
234
235   if ((p = strrchr(fileName, '/')))
236     return new GString(fileName, p - fileName);
237   return new GString();
238 #endif
239 }
240
241 GBool isAbsolutePath(char *path) {
242 #ifdef VMS
243   //---------- VMS ----------
244   return strchr(path, ':') ||
245          (path[0] == '[' && path[1] != '.' && path[1] != '-');
246
247 #elif defined(__EMX__) || defined(WIN32)
248   //---------- OS/2+EMX and Win32 ----------
249   return path[0] == '/' || path[0] == '\\' || path[1] == ':';
250
251 #else
252   //---------- Unix ----------
253   return path[0] == '/';
254 #endif
255 }
256
257 GString *makePathAbsolute(GString *path) {
258 #ifdef VMS
259   //---------- VMS ----------
260   char buf[PATH_MAX+1];
261
262   if (!isAbsolutePath(path->getCString())) {
263     if (getcwd(buf, sizeof(buf))) {
264       if (path->getChar(0) == '[') {
265         if (path->getChar(1) != '.')
266           path->insert(0, '.');
267         path->insert(0, buf);
268       } else {
269         path->insert(0, '[');
270         path->insert(1, ']');
271         path->insert(1, buf);
272       }
273     }
274   }
275   return path;
276
277 #elif WIN32
278   //---------- Win32 ----------
279   char buf[_MAX_PATH];
280   char *fp;
281
282   buf[0] = '\0';
283   if (!GetFullPathName(path->getCString(), _MAX_PATH, buf, &fp)) {
284     path->clear();
285     return path;
286   }
287   path->clear();
288   path->append(buf);
289   return path;
290
291 #else
292   //---------- Unix and OS/2+EMX ----------
293   struct passwd *pw;
294   char buf[PATH_MAX+1];
295   GString *s;
296   char *p1, *p2;
297   int n;
298
299   if (path->getChar(0) == '~') {
300     if (path->getChar(1) == '/' ||
301 #ifdef __EMX__
302         path->getChar(1) == '\\' ||
303 #endif
304         path->getLength() == 1) {
305       path->del(0, 1);
306       s = getHomeDir();
307       path->insert(0, s);
308       delete s;
309     } else {
310       p1 = path->getCString() + 1;
311 #ifdef __EMX__
312       for (p2 = p1; *p2 && *p2 != '/' && *p2 != '\\'; ++p2) ;
313 #else
314       for (p2 = p1; *p2 && *p2 != '/'; ++p2) ;
315 #endif
316       if ((n = p2 - p1) > PATH_MAX)
317         n = PATH_MAX;
318       strncpy(buf, p1, n);
319       buf[n] = '\0';
320       if ((pw = getpwnam(buf))) {
321         path->del(0, p2 - p1 + 1);
322         path->insert(0, pw->pw_dir);
323       }
324     }
325   } else if (!isAbsolutePath(path->getCString())) {
326     if (getcwd(buf, sizeof(buf))) {
327       path->insert(0, '/');
328       path->insert(0, buf);
329     }
330   }
331   return path;
332 #endif
333 }
334
335 //------------------------------------------------------------------------
336 // GDir and GDirEntry
337 //------------------------------------------------------------------------
338
339 GDirEntry::GDirEntry(char *dirPath, char *name1, GBool doStat) {
340 #ifdef VMS
341   char *p;
342 #elif WIN32
343   int fa;
344   GString *s;
345 #else
346   struct stat st;
347   GString *s;
348 #endif
349
350   name = new GString(name1);
351   dir = gFalse;
352   if (doStat) {
353 #ifdef VMS
354     if (!strcmp(name1, "-") ||
355         ((p = strrchr(name1, '.')) && !strncmp(p, ".DIR;", 5)))
356       dir = gTrue;
357 #else
358     s = new GString(dirPath);
359     appendToPath(s, name1);
360 #ifdef WIN32
361     fa = GetFileAttributes(s->getCString());
362     dir = (fa != 0xFFFFFFFF && (fa & FILE_ATTRIBUTE_DIRECTORY));
363 #else
364     if (stat(s->getCString(), &st) == 0)
365       dir = S_ISDIR(st.st_mode);
366 #endif
367     delete s;
368 #endif
369   }
370 }
371
372 GDirEntry::~GDirEntry() {
373   delete name;
374 }
375
376 GDir::GDir(char *name, GBool doStat1) {
377   path = new GString(name);
378   doStat = doStat1;
379 #ifdef WIN32
380   GString *tmp;
381
382   tmp = path->copy();
383   tmp->append("/*.*");
384   hnd = FindFirstFile(tmp->getCString(), &ffd);
385   delete tmp;
386 #else
387   dir = opendir(name);
388 #endif
389 #ifdef VMS
390   needParent = strchr(name, '[') != NULL;
391 #endif
392 }
393
394 GDir::~GDir() {
395   delete path;
396 #ifdef WIN32
397   if (hnd) {
398     FindClose(hnd);
399     hnd = NULL;
400   }
401 #else
402   if (dir)
403     closedir(dir);
404 #endif
405 }
406
407 GDirEntry *GDir::getNextEntry() {
408   struct dirent *ent;
409   GDirEntry *e;
410
411   e = NULL;
412 #ifdef WIN32
413   e = new GDirEntry(path->getCString(), ffd.cFileName, doStat);
414   if (hnd  && !FindNextFile(hnd, &ffd)) {
415     FindClose(hnd);
416     hnd = NULL;
417   }
418 #else
419   if (dir) {
420 #ifdef VMS
421     if (needParent) {
422       e = new GDirEntry(path->getCString(), "-", doStat);
423       needParent = gFalse;
424       return e;
425     }
426 #endif
427     ent = readdir(dir);
428 #ifndef VMS
429     if (ent && !strcmp(ent->d_name, "."))
430       ent = readdir(dir);
431 #endif
432     if (ent)
433       e = new GDirEntry(path->getCString(), ent->d_name, doStat);
434   }
435 #endif
436   return e;
437 }
438
439 void GDir::rewind() {
440 #ifdef WIN32
441   GString *tmp;
442
443   if (hnd)
444     FindClose(hnd);
445   tmp = path->copy();
446   tmp->append("/*.*");
447   hnd = FindFirstFile(tmp->getCString(), &ffd);
448 #else
449   if (dir)
450     rewinddir(dir);
451 #endif
452 #ifdef VMS
453   needParent = strchr(path->getCString(), '[') != NULL;
454 #endif
455 }