home *** CD-ROM | disk | FTP | other *** search
- //========================================================================
- //
- // gfile.cc
- //
- // Miscellaneous file and directory name manipulation.
- //
- // Copyright 1996 Derek B. Noonburg
- //
- // EL: Added Amiga support.
- //
- //========================================================================
-
- #ifdef WIN32
- extern "C" {
- #include <sys/stat.h>
- #include <kpathsea/win32lib.h>
- }
- #elif defined(__AMIGA__)
- #include <sys/stat.h>
- #include <limits.h>
- #include <string.h>
- #ifdef __PPC__
- #include <powerup/ppcproto/dos.h>
- #else
- #include <proto/dos.h>
- #endif
- #else // !WIN32
- #include <sys/stat.h>
- #include <limits.h>
- #include <string.h>
- #ifndef VMS
- #include <pwd.h>
- #endif
- #endif // WIN32
- #if defined(VMS) && (__DECCXX_VER < 50200000)
- #include <unixlib.h>
- #endif
- #include "GString.h"
- #include "gfile.h"
-
- // Some systems don't define this, so just make it something reasonably
- // large.
- #ifndef PATH_MAX
- #define PATH_MAX 1024
- #endif
-
- //------------------------------------------------------------------------
-
- GString *getHomeDir() {
- #ifdef __AMIGA__
- return new GString("");
- #elif VMS
- //---------- VMS ----------
- return new GString("SYS$LOGIN:");
-
- #elif defined(__EMX__) || defined(WIN32)
- //---------- OS/2+EMX and Win32 ----------
- char *s;
- GString *ret;
-
- if ((s = getenv("HOME")))
- ret = new GString(s);
- else
- ret = new GString(".");
- return ret;
-
- #else
- //---------- Unix ----------
- char *s;
- struct passwd *pw;
- GString *ret;
-
- if ((s = getenv("HOME"))) {
- ret = new GString(s);
- } else {
- if ((s = getenv("USER")))
- pw = getpwnam(s);
- else
- pw = getpwuid(getuid());
- if (pw)
- ret = new GString(pw->pw_dir);
- else
- ret = new GString(".");
- }
- return ret;
- #endif
- }
-
- GString *getCurrentDir() {
- char buf[PATH_MAX+1];
-
- #if defined(__EMX__)
- if (!_getcwd2(buf, sizeof(buf)))
- #elif defined(WIN32)
- if (!GetCurrentDirectory(sizeof(buf), buf))
- #elif defined(__AMIGA__)
- if (!GetCurrentDirName(buf, sizeof(buf)))
- #else
- if (!getcwd(buf, sizeof(buf)))
- #endif
- return new GString();
- return new GString(buf);
- }
-
- GString *appendToPath(GString *path, char *fileName) {
- #if defined(VMS)
- //---------- VMS ----------
- //~ this should handle everything necessary for file
- //~ requesters, but it's certainly not complete
- char *p0, *p1, *p2;
- char *q1;
-
- p0 = path->getCString();
- p1 = p0 + path->getLength() - 1;
- if (!strcmp(fileName, "-")) {
- if (*p1 == ']') {
- for (p2 = p1; p2 > p0 && *p2 != '.' && *p2 != '['; --p2) ;
- if (*p2 == '[')
- ++p2;
- path->del(p2 - p0, p1 - p2);
- } else if (*p1 == ':') {
- path->append("[-]");
- } else {
- path->clear();
- path->append("[-]");
- }
- } else if ((q1 = strrchr(fileName, '.')) && !strncmp(q1, ".DIR;", 5)) {
- if (*p1 == ']') {
- path->insert(p1 - p0, '.');
- path->insert(p1 - p0 + 1, fileName, q1 - fileName);
- } else if (*p1 == ':') {
- path->append('[');
- path->append(']');
- path->append(fileName, q1 - fileName);
- } else {
- path->clear();
- path->append(fileName, q1 - fileName);
- }
- } else {
- if (*p1 != ']' && *p1 != ':')
- path->clear();
- path->append(fileName);
- }
- return path;
-
- #elif defined(WIN32)
- //---------- Win32 ----------
- GString *tmp;
- char buf[256];
- char *fp;
-
- tmp = new GString(path);
- tmp->append('/');
- tmp->append(fileName);
- GetFullPathName(tmp->getCString(), sizeof(buf), buf, &fp);
- delete tmp;
- path->clear();
- path->append(buf);
- return path;
-
- #elif defined(__AMIGA__)
- // --------- Amiga ----------
- char buf[256];
- strncpy(buf, path->getCString(), sizeof(buf)-1);
- buf[sizeof(buf)-1] = '\0';
- AddPart(buf, fileName, sizeof(buf));
- return new GString(buf);
-
- #else
- //---------- Unix and OS/2+EMX ----------
- int i;
-
- // appending "." does nothing
- if (!strcmp(fileName, "."))
- return path;
-
- // appending ".." goes up one directory
- if (!strcmp(fileName, "..")) {
- for (i = path->getLength() - 2; i >= 0; --i) {
- #ifdef __EMX__
- if (path->getChar(i) == '/' || path->getChar(i) == '\\' ||
- path->getChar(i) == ':')
- #else
- if (path->getChar(i) == '/')
- #endif
- break;
- }
- if (i <= 0) {
- #ifdef __EMX__
- if (path->getChar[0] == '/' || path->getChar[0] == '\\') {
- path->del(1, path->getLength() - 1);
- } else if (path->getLength() >= 2 && path->getChar[1] == ':') {
- path->del(2, path->getLength() - 2);
- } else {
- path->clear();
- path->append("..");
- }
- #else
- if (path->getChar(0) == '/') {
- path->del(1, path->getLength() - 1);
- } else {
- path->clear();
- path->append("..");
- }
- #endif
- } else {
- #ifdef __EMX__
- if (path->getChar(i) == ':')
- ++i;
- #endif
- path->del(i, path->getLength() - i);
- }
- return path;
- }
-
- // otherwise, append "/" and new path component
- #ifdef __EMX__
- if (path->getLength() > 0 &&
- path->getChar(path->getLength() - 1) != '/' &&
- path->getChar(path->getLength() - 1) != '\\')
- #else
- if (path->getLength() > 0 &&
- path->getChar(path->getLength() - 1) != '/')
- #endif
- path->append('/');
- path->append(fileName);
- return path;
- #endif
- }
-
- GString *grabPath(char *fileName) {
- #ifdef VMS
- //---------- VMS ----------
- char *p;
-
- if ((p = strrchr(fileName, ']')))
- return new GString(fileName, p + 1 - fileName);
- if ((p = strrchr(fileName, ':')))
- return new GString(fileName, p + 1 - fileName);
- return new GString();
-
- #elif defined(__EMX__) || defined(WIN32)
- //---------- OS/2+EMX and Win32 ----------
- char *p;
-
- if ((p = strrchr(fileName, '/')))
- return new GString(fileName, p - fileName);
- if ((p = strrchr(fileName, '\\')))
- return new GString(fileName, p - fileName);
- if ((p = strrchr(fileName, ':')))
- return new GString(fileName, p + 1 - fileName);
- return new GString();
-
- #elif defined(__AMIGA__)
- //---------- Amiga ------------
- return new GString(fileName, PathPart(fileName) - fileName);
-
- #else
- //---------- Unix ----------
- char *p;
-
- if ((p = strrchr(fileName, '/')))
- return new GString(fileName, p - fileName);
- return new GString();
- #endif
- }
-
- GBool isAbsolutePath(char *path) {
- #ifdef VMS
- //---------- VMS ----------
- return strchr(path, ':') ||
- (path[0] == '[' && path[1] != '.' && path[1] != '-');
-
- #elif defined(__EMX__) || defined(WIN32)
- //---------- OS/2+EMX and Win32 ----------
- return path[0] == '/' || path[0] == '\\' || path[1] == ':';
-
- #elif defined(__AMIGA__)
- //--------- Amiga -----------
- return strchr(path, ':')!=NULL;
-
- #else
- //---------- Unix ----------
- return path[0] == '/';
- #endif
- }
-
- GString *makePathAbsolute(GString *path) {
- #ifdef VMS
- //---------- VMS ----------
- char buf[PATH_MAX+1];
-
- if (!isAbsolutePath(path->getCString())) {
- if (getcwd(buf, sizeof(buf))) {
- if (path->getChar(0) == '[') {
- if (path->getChar(1) != '.')
- path->insert(0, '.');
- path->insert(0, buf);
- } else {
- path->insert(0, '[');
- path->insert(1, ']');
- path->insert(1, buf);
- }
- }
- }
- return path;
-
- #elif WIN32
- //---------- Win32 ----------
- char buf[_MAX_PATH];
- char *fp;
-
- buf[0] = '\0';
- if (!GetFullPathName(path->getCString(), _MAX_PATH, buf, &fp)) {
- path->clear();
- return path;
- }
- path->clear();
- path->append(buf);
- return path;
-
- #elif defined(__AMIGA__)
- //---------- Amiga -----------
- char buf[256];
- GetCurrentDirName(buf, sizeof(buf));
- AddPart(buf, path->getCString(), sizeof(buf));
- return new GString(buf);
-
- #else
- //---------- Unix and OS/2+EMX ----------
- struct passwd *pw;
- char buf[PATH_MAX+1];
- GString *s;
- char *p1, *p2;
- int n;
-
- #ifndef __AMIGA__
- if (path->getChar(0) == '~') {
- if (path->getChar(1) == '/' ||
- #ifdef __EMX__
- path->getChar(1) == '\\' ||
- #endif
- path->getLength() == 1) {
- path->del(0, 1);
- s = getHomeDir();
- path->insert(0, s);
- delete s;
- } else {
- p1 = path->getCString() + 1;
- #ifdef __EMX__
- for (p2 = p1; *p2 && *p2 != '/' && *p2 != '\\'; ++p2) ;
- #else
- for (p2 = p1; *p2 && *p2 != '/'; ++p2) ;
- #endif
- if ((n = p2 - p1) > PATH_MAX)
- n = PATH_MAX;
- strncpy(buf, p1, n);
- buf[n] = '\0';
- if ((pw = getpwnam(buf))) {
- path->del(0, p2 - p1 + 1);
- path->insert(0, pw->pw_dir);
- }
- }
- } else
- #endif
- if (!isAbsolutePath(path->getCString())) {
- if (getcwd(buf, sizeof(buf))) {
- path->insert(0, '/');
- path->insert(0, buf);
- }
- }
- return path;
- #endif
- }
-
- #ifdef DIR_FUNCS
- //------------------------------------------------------------------------
- // GDir and GDirEntry
- //------------------------------------------------------------------------
-
- GDirEntry::GDirEntry(char *dirPath, char *name1, GBool doStat) {
- #ifdef VMS
- char *p;
- #elif WIN32
- int fa;
- GString *s;
- #else
- struct stat st;
- GString *s;
- #endif
-
- name = new GString(name1);
- dir = gFalse;
- if (doStat) {
- #ifdef VMS
- if (!strcmp(name1, "-") ||
- ((p = strrchr(name1, '.')) && !strncmp(p, ".DIR;", 5)))
- dir = gTrue;
- #else
- s = new GString(dirPath);
- appendToPath(s, name1);
- #ifdef WIN32
- fa = GetFileAttributes(s->getCString());
- dir = (fa != 0xFFFFFFFF && (fa & FILE_ATTRIBUTE_DIRECTORY));
- #else
- if (stat(s->getCString(), &st) == 0)
- dir = S_ISDIR(st.st_mode);
- #endif
- delete s;
- #endif
- }
- }
-
- GDirEntry::~GDirEntry() {
- delete name;
- }
-
- GDir::GDir(char *name, GBool doStat1) {
- path = new GString(name);
- doStat = doStat1;
- #ifdef WIN32
- GString *tmp;
-
- tmp = path->copy();
- tmp->append("/*.*");
- hnd = FindFirstFile(tmp->getCString(), &ffd);
- delete tmp;
- #else
- dir = opendir(name);
- #endif
- #ifdef VMS
- needParent = strchr(name, '[') != NULL;
- #endif
- }
-
- GDir::~GDir() {
- delete path;
- #ifdef WIN32
- if (hnd) {
- FindClose(hnd);
- hnd = NULL;
- }
- #else
- if (dir)
- closedir(dir);
- #endif
- }
-
- GDirEntry *GDir::getNextEntry() {
- struct dirent *ent;
- GDirEntry *e;
-
- e = NULL;
- #ifdef WIN32
- e = new GDirEntry(path->getCString(), ffd.cFileName, doStat);
- if (hnd && !FindNextFile(hnd, &ffd)) {
- FindClose(hnd);
- hnd = NULL;
- }
- #else
- if (dir) {
- #ifdef VMS
- if (needParent) {
- e = new GDirEntry(path->getCString(), "-", doStat);
- needParent = gFalse;
- return e;
- }
- #endif
- ent = readdir(dir);
- #ifndef VMS
- if (ent && !strcmp(ent->d_name, "."))
- ent = readdir(dir);
- #endif
- if (ent)
- e = new GDirEntry(path->getCString(), ent->d_name, doStat);
- }
- #endif
- return e;
- }
-
- void GDir::rewind() {
- #ifdef WIN32
- GString *tmp;
-
- if (hnd)
- FindClose(hnd);
- tmp = path->copy();
- tmp->append("/*.*");
- hnd = FindFirstFile(tmp->getCString(), &ffd);
- #else
- if (dir)
- rewinddir(dir);
- #endif
- #ifdef VMS
- needParent = strchr(path->getCString(), '[') != NULL;
- #endif
- }
- #endif
-
-