00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include <aconf.h>
00012
00013 #ifdef WIN32
00014 extern "C" {
00015 # ifndef _MSC_VER
00016 # include <kpathsea/win32lib.h>
00017 # endif
00018 }
00019 #else // !WIN32
00020 # if defined(MACOS)
00021 # include <sys/stat.h>
00022 # elif !defined(ACORN)
00023 # include <sys/types.h>
00024 # include <sys/stat.h>
00025 # include <fcntl.h>
00026 # endif
00027 # include <limits.h>
00028 # include <string.h>
00029 # if !defined(VMS) && !defined(ACORN) && !defined(MACOS)
00030 # include <pwd.h>
00031 # endif
00032 # if defined(VMS) && (__DECCXX_VER < 50200000)
00033 # include <unixlib.h>
00034 # endif
00035 #endif // WIN32
00036 #include "GString.h"
00037 #include "gfile.h"
00038
00039
00040
00041 #ifndef PATH_MAX
00042 #define PATH_MAX 1024
00043 #endif
00044
00045
00046
00047 GString *getHomeDir() {
00048 #ifdef VMS
00049
00050 return new GString("SYS$LOGIN:");
00051
00052 #elif defined(__EMX__) || defined(WIN32)
00053
00054 char *s;
00055 GString *ret;
00056
00057 if ((s = getenv("HOME")))
00058 ret = new GString(s);
00059 else
00060 ret = new GString(".");
00061 return ret;
00062
00063 #elif defined(ACORN)
00064
00065 return new GString("@");
00066
00067 #elif defined(MACOS)
00068
00069 return new GString(":");
00070
00071 #else
00072
00073 char *s;
00074 struct passwd *pw;
00075 GString *ret;
00076
00077 if ((s = getenv("HOME"))) {
00078 ret = new GString(s);
00079 } else {
00080 if ((s = getenv("USER")))
00081 pw = getpwnam(s);
00082 else
00083 pw = getpwuid(getuid());
00084 if (pw)
00085 ret = new GString(pw->pw_dir);
00086 else
00087 ret = new GString(".");
00088 }
00089 return ret;
00090 #endif
00091 }
00092
00093 GString *getCurrentDir() {
00094 char buf[PATH_MAX+1];
00095
00096 #if defined(__EMX__)
00097 if (_getcwd2(buf, sizeof(buf)))
00098 #elif defined(WIN32)
00099 if (GetCurrentDirectory(sizeof(buf), buf))
00100 #elif defined(ACORN)
00101 if (strcpy(buf, "@"))
00102 #elif defined(MACOS)
00103 if (strcpy(buf, ":"))
00104 #else
00105 if (getcwd(buf, sizeof(buf)))
00106 #endif
00107 return new GString(buf);
00108 return new GString();
00109 }
00110
00111 GString *appendToPath(GString *path, const char *fileName) {
00112 #if defined(VMS)
00113
00114
00115
00116 char *p0, *p1, *p2;
00117 char *q1;
00118
00119 p0 = path->getCString();
00120 p1 = p0 + path->getLength() - 1;
00121 if (!strcmp(fileName, "-")) {
00122 if (*p1 == ']') {
00123 for (p2 = p1; p2 > p0 && *p2 != '.' && *p2 != '['; --p2) ;
00124 if (*p2 == '[')
00125 ++p2;
00126 path->del(p2 - p0, p1 - p2);
00127 } else if (*p1 == ':') {
00128 path->append("[-]");
00129 } else {
00130 path->clear();
00131 path->append("[-]");
00132 }
00133 } else if ((q1 = strrchr(fileName, '.')) && !strncmp(q1, ".DIR;", 5)) {
00134 if (*p1 == ']') {
00135 path->insert(p1 - p0, '.');
00136 path->insert(p1 - p0 + 1, fileName, q1 - fileName);
00137 } else if (*p1 == ':') {
00138 path->append('[');
00139 path->append(']');
00140 path->append(fileName, q1 - fileName);
00141 } else {
00142 path->clear();
00143 path->append(fileName, q1 - fileName);
00144 }
00145 } else {
00146 if (*p1 != ']' && *p1 != ':')
00147 path->clear();
00148 path->append(fileName);
00149 }
00150 return path;
00151
00152 #elif defined(WIN32)
00153
00154 GString *tmp;
00155 char buf[256];
00156 char *fp;
00157
00158 tmp = new GString(path);
00159 tmp->append('/');
00160 tmp->append(fileName);
00161 GetFullPathName(tmp->getCString(), sizeof(buf), buf, &fp);
00162 delete tmp;
00163 path->clear();
00164 path->append(buf);
00165 return path;
00166
00167 #elif defined(ACORN)
00168
00169 char *p;
00170 int i;
00171
00172 path->append(".");
00173 i = path->getLength();
00174 path->append(fileName);
00175 for (p = path->getCString() + i; *p; ++p) {
00176 if (*p == '/') {
00177 *p = '.';
00178 } else if (*p == '.') {
00179 *p = '/';
00180 }
00181 }
00182 return path;
00183
00184 #elif defined(MACOS)
00185
00186 char *p;
00187 int i;
00188
00189 path->append(":");
00190 i = path->getLength();
00191 path->append(fileName);
00192 for (p = path->getCString() + i; *p; ++p) {
00193 if (*p == '/') {
00194 *p = ':';
00195 } else if (*p == '.') {
00196 *p = ':';
00197 }
00198 }
00199 return path;
00200
00201 #elif defined(__EMX__)
00202
00203 int i;
00204
00205
00206 if (!strcmp(fileName, "."))
00207 return path;
00208
00209
00210 if (!strcmp(fileName, "..")) {
00211 for (i = path->getLength() - 2; i >= 0; --i) {
00212 if (path->getChar(i) == '/' || path->getChar(i) == '\\' ||
00213 path->getChar(i) == ':')
00214 break;
00215 }
00216 if (i <= 0) {
00217 if (path->getChar(0) == '/' || path->getChar(0) == '\\') {
00218 path->del(1, path->getLength() - 1);
00219 } else if (path->getLength() >= 2 && path->getChar(1) == ':') {
00220 path->del(2, path->getLength() - 2);
00221 } else {
00222 path->clear();
00223 path->append("..");
00224 }
00225 } else {
00226 if (path->getChar(i-1) == ':')
00227 ++i;
00228 path->del(i, path->getLength() - i);
00229 }
00230 return path;
00231 }
00232
00233
00234 if (path->getLength() > 0 &&
00235 path->getChar(path->getLength() - 1) != '/' &&
00236 path->getChar(path->getLength() - 1) != '\\')
00237 path->append('/');
00238 path->append(fileName);
00239 return path;
00240
00241 #else
00242
00243 int i;
00244
00245
00246 if (!strcmp(fileName, "."))
00247 return path;
00248
00249
00250 if (!strcmp(fileName, "..")) {
00251 for (i = path->getLength() - 2; i >= 0; --i) {
00252 if (path->getChar(i) == '/')
00253 break;
00254 }
00255 if (i <= 0) {
00256 if (path->getChar(0) == '/') {
00257 path->del(1, path->getLength() - 1);
00258 } else {
00259 path->clear();
00260 path->append("..");
00261 }
00262 } else {
00263 path->del(i, path->getLength() - i);
00264 }
00265 return path;
00266 }
00267
00268
00269 if (path->getLength() > 0 &&
00270 path->getChar(path->getLength() - 1) != '/')
00271 path->append('/');
00272 path->append(fileName);
00273 return path;
00274 #endif
00275 }
00276
00277 GString *grabPath(const char *fileName) {
00278 #ifdef VMS
00279
00280 char *p;
00281
00282 if ((p = strrchr(fileName, ']')))
00283 return new GString(fileName, p + 1 - fileName);
00284 if ((p = strrchr(fileName, ':')))
00285 return new GString(fileName, p + 1 - fileName);
00286 return new GString();
00287
00288 #elif defined(__EMX__) || defined(WIN32)
00289
00290 char *p;
00291
00292 if ((p = strrchr(fileName, '/')))
00293 return new GString(fileName, p - fileName);
00294 if ((p = strrchr(fileName, '\\')))
00295 return new GString(fileName, p - fileName);
00296 if ((p = strrchr(fileName, ':')))
00297 return new GString(fileName, p + 1 - fileName);
00298 return new GString();
00299
00300 #elif defined(ACORN)
00301
00302 char *p;
00303
00304 if ((p = strrchr(fileName, '.')))
00305 return new GString(fileName, p - fileName);
00306 return new GString();
00307
00308 #elif defined(MACOS)
00309
00310 char *p;
00311
00312 if ((p = strrchr(fileName, ':')))
00313 return new GString(fileName, p - fileName);
00314 return new GString();
00315
00316 #else
00317
00318 char *p;
00319
00320 if ((p = strrchr(fileName, '/')))
00321 return new GString(fileName, p - fileName);
00322 return new GString();
00323 #endif
00324 }
00325
00326 GBool isAbsolutePath(const char *path) {
00327 #ifdef VMS
00328
00329 return strchr(path, ':') ||
00330 (path[0] == '[' && path[1] != '.' && path[1] != '-');
00331
00332 #elif defined(__EMX__) || defined(WIN32)
00333
00334 return path[0] == '/' || path[0] == '\\' || path[1] == ':';
00335
00336 #elif defined(ACORN)
00337
00338 return path[0] == '$';
00339
00340 #elif defined(MACOS)
00341
00342 return path[0] != ':';
00343
00344 #else
00345
00346 return path[0] == '/';
00347 #endif
00348 }
00349
00350 GString *makePathAbsolute(GString *path) {
00351 #ifdef VMS
00352
00353 char buf[PATH_MAX+1];
00354
00355 if (!isAbsolutePath(path->getCString())) {
00356 if (getcwd(buf, sizeof(buf))) {
00357 path->insert(0, buf);
00358 }
00359 }
00360 return path;
00361
00362 #elif defined(WIN32)
00363
00364 char buf[_MAX_PATH];
00365 char *fp;
00366
00367 buf[0] = '\0';
00368 if (!GetFullPathName(path->getCString(), _MAX_PATH, buf, &fp)) {
00369 path->clear();
00370 return path;
00371 }
00372 path->clear();
00373 path->append(buf);
00374 return path;
00375
00376 #elif defined(ACORN)
00377
00378 path->insert(0, '@');
00379 return path;
00380
00381 #elif defined(MACOS)
00382
00383 path->del(0, 1);
00384 return path;
00385
00386 #else
00387
00388 struct passwd *pw;
00389 char buf[PATH_MAX+1];
00390 GString *s;
00391 char *p1, *p2;
00392 int n;
00393
00394 if (path->getChar(0) == '~') {
00395 if (path->getChar(1) == '/' ||
00396 #ifdef __EMX__
00397 path->getChar(1) == '\\' ||
00398 #endif
00399 path->getLength() == 1) {
00400 path->del(0, 1);
00401 s = getHomeDir();
00402 path->insert(0, s);
00403 delete s;
00404 } else {
00405 p1 = path->getCString() + 1;
00406 #ifdef __EMX__
00407 for (p2 = p1; *p2 && *p2 != '/' && *p2 != '\\'; ++p2) ;
00408 #else
00409 for (p2 = p1; *p2 && *p2 != '/'; ++p2) ;
00410 #endif
00411 if ((n = p2 - p1) > PATH_MAX)
00412 n = PATH_MAX;
00413 strncpy(buf, p1, n);
00414 buf[n] = '\0';
00415 if ((pw = getpwnam(buf))) {
00416 path->del(0, p2 - p1 + 1);
00417 path->insert(0, pw->pw_dir);
00418 }
00419 }
00420 } else if (!isAbsolutePath(path->getCString())) {
00421 if (getcwd(buf, sizeof(buf))) {
00422 #ifndef __EMX__
00423 path->insert(0, '/');
00424 #endif
00425 path->insert(0, buf);
00426 }
00427 }
00428 return path;
00429 #endif
00430 }
00431
00432 time_t getModTime(const char *fileName) {
00433 #ifdef WIN32
00434
00435 return 0;
00436 #else
00437 struct stat statBuf;
00438
00439 if (stat(fileName, &statBuf)) {
00440 return 0;
00441 }
00442 return statBuf.st_mtime;
00443 #endif
00444 }
00445
00446 GBool openTempFile(GString **name, FILE **f, const char *mode) {
00447 #if defined(WIN32)
00448
00449 char *s;
00450 char buf[_MAX_PATH];
00451 char *fp;
00452
00453 if (!(s = _tempnam(getenv("TEMP"), NULL))) {
00454 return gFalse;
00455 }
00456 *name = new GString(s);
00457 free(s);
00458 if (ext) {
00459 (*name)->append(ext);
00460 }
00461 if (!(*f = fopen((*name)->getCString(), mode))) {
00462 delete (*name);
00463 return gFalse;
00464 }
00465 return gTrue;
00466 #elif defined(VMS) || defined(__EMX__) || defined(ACORN) || defined(MACOS)
00467
00468 char *s;
00469
00470
00471
00472
00473
00474 if (!(s = tmpnam(NULL))) {
00475 return gFalse;
00476 }
00477 *name = new GString(s);
00478 if (ext) {
00479 (*name)->append(ext);
00480 }
00481 if (!(*f = fopen((*name)->getCString(), mode))) {
00482 delete (*name);
00483 return gFalse;
00484 }
00485 return gTrue;
00486 #else
00487
00488 char *s;
00489 int fd;
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509 #if HAVE_MKSTEMP
00510 if ((s = getenv("TMPDIR"))) {
00511 *name = new GString(s);
00512 } else {
00513 *name = new GString("/tmp");
00514 }
00515 (*name)->append("/XXXXXX");
00516 fd = mkstemp((*name)->getCString());
00517 #else // HAVE_MKSTEMP
00518 if (!(s = tmpnam(NULL))) {
00519 return gFalse;
00520 }
00521 *name = new GString(s);
00522 fd = open((*name)->getCString(), O_WRONLY | O_CREAT | O_EXCL, 0600);
00523 #endif // HAVE_MKSTEMP
00524
00525 if (fd < 0 || !(*f = fdopen(fd, mode))) {
00526 delete *name;
00527 return gFalse;
00528 }
00529 return gTrue;
00530 #endif
00531 }
00532
00533 GBool executeCommand(const char *cmd) {
00534 #ifdef VMS
00535 return system(cmd) ? gTrue : gFalse;
00536 #else
00537 return system(cmd) ? gFalse : gTrue;
00538 #endif
00539 }
00540
00541 char *getLine(char *buf, int size, FILE *f) {
00542 int c, i;
00543
00544 i = 0;
00545 while (i < size - 1) {
00546 if ((c = fgetc(f)) == EOF) {
00547 break;
00548 }
00549 buf[i++] = (char)c;
00550 if (c == '\x0a') {
00551 break;
00552 }
00553 if (c == '\x0d') {
00554 c = fgetc(f);
00555 if (c == '\x0a' && i < size - 1) {
00556 buf[i++] = (char)c;
00557 } else if (c != EOF) {
00558 ungetc(c, f);
00559 }
00560 break;
00561 }
00562 }
00563 buf[i] = '\0';
00564 if (i == 0) {
00565 return NULL;
00566 }
00567 return buf;
00568 }
00569
00570
00571
00572
00573
00574 GDirEntry::GDirEntry(const char *dirPath, const char *nameA, GBool doStat) {
00575 #ifdef VMS
00576 char *p;
00577 #elif defined(WIN32)
00578 int fa;
00579 GString *s;
00580 #elif defined(ACORN)
00581 #else
00582 struct stat st;
00583 GString *s;
00584 #endif
00585
00586 name = new GString(nameA);
00587 dir = gFalse;
00588 if (doStat) {
00589 #ifdef VMS
00590 if (!strcmp(nameA, "-") ||
00591 ((p = strrchr(nameA, '.')) && !strncmp(p, ".DIR;", 5)))
00592 dir = gTrue;
00593 #elif defined(ACORN)
00594 #else
00595 s = new GString(dirPath);
00596 appendToPath(s, nameA);
00597 #ifdef WIN32
00598 fa = GetFileAttributes(s->getCString());
00599 dir = (fa != 0xFFFFFFFF && (fa & FILE_ATTRIBUTE_DIRECTORY));
00600 #else
00601 if (stat(s->getCString(), &st) == 0)
00602 dir = S_ISDIR(st.st_mode);
00603 #endif
00604 delete s;
00605 #endif
00606 }
00607 }
00608
00609 GDirEntry::~GDirEntry() {
00610 delete name;
00611 }
00612
00613 GDir::GDir(const char *name, GBool doStatA) {
00614 path = new GString(name);
00615 doStat = doStatA;
00616 #if defined(WIN32)
00617 GString *tmp;
00618
00619 tmp = path->copy();
00620 tmp->append("/*.*");
00621 hnd = FindFirstFile(tmp->getCString(), &ffd);
00622 delete tmp;
00623 #elif defined(ACORN)
00624 #elif defined(MACOS)
00625 #else
00626 dir = opendir(name);
00627 #ifdef VMS
00628 needParent = strchr(name, '[') != NULL;
00629 #endif
00630 #endif
00631 }
00632
00633 GDir::~GDir() {
00634 delete path;
00635 #if defined(WIN32)
00636 if (hnd) {
00637 FindClose(hnd);
00638 hnd = NULL;
00639 }
00640 #elif defined(ACORN)
00641 #elif defined(MACOS)
00642 #else
00643 if (dir)
00644 closedir(dir);
00645 #endif
00646 }
00647
00648 GDirEntry *GDir::getNextEntry() {
00649 struct dirent *ent;
00650 GDirEntry *e;
00651
00652 e = NULL;
00653 #if defined(WIN32)
00654 e = new GDirEntry(path->getCString(), ffd.cFileName, doStat);
00655 if (hnd && !FindNextFile(hnd, &ffd)) {
00656 FindClose(hnd);
00657 hnd = NULL;
00658 }
00659 #elif defined(ACORN)
00660 #elif defined(MACOS)
00661 #else
00662 if (dir) {
00663 #ifdef VMS
00664 if (needParent) {
00665 e = new GDirEntry(path->getCString(), "-", doStat);
00666 needParent = gFalse;
00667 return e;
00668 }
00669 #endif
00670 ent = readdir(dir);
00671 #ifndef VMS
00672 if (ent && !strcmp(ent->d_name, "."))
00673 ent = readdir(dir);
00674 #endif
00675 if (ent)
00676 e = new GDirEntry(path->getCString(), ent->d_name, doStat);
00677 }
00678 #endif
00679 return e;
00680 }
00681
00682 void GDir::rewind() {
00683 #ifdef WIN32
00684 GString *tmp;
00685
00686 if (hnd)
00687 FindClose(hnd);
00688 tmp = path->copy();
00689 tmp->append("/*.*");
00690 hnd = FindFirstFile(tmp->getCString(), &ffd);
00691 #elif defined(ACORN)
00692 #elif defined(MACOS)
00693 #else
00694 if (dir)
00695 rewinddir(dir);
00696 #ifdef VMS
00697 needParent = strchr(path->getCString(), '[') != NULL;
00698 #endif
00699 #endif
00700 }