home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 110 / EnigmaAmiga110CD.iso / indispensabili / utility / apdf / xpdf-0.80 / goo / gfile.cc next >
C/C++ Source or Header  |  1999-06-10  |  11KB  |  500 lines

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