16# include <kpathsea/win32lib.h>
23# include <sys/types.h>
29# if !defined(VMS) && !defined(ACORN) && !defined(MACOS)
32# if defined(VMS) && (__DECCXX_VER < 50200000)
47GString *getHomeDir() {
50 return new GString(
"SYS$LOGIN:");
52#elif defined(__EMX__) || defined(WIN32)
57 if ((s = getenv(
"HOME")))
60 ret =
new GString(
".");
65 return new GString(
"@");
69 return new GString(
":");
77 if ((s = getenv(
"HOME"))) {
80 if ((s = getenv(
"USER")))
83 pw = getpwuid(getuid());
85 ret =
new GString(pw->pw_dir);
87 ret =
new GString(
".");
93GString *getCurrentDir() {
97 if (_getcwd2(buf,
sizeof(buf)))
99 if (GetCurrentDirectory(
sizeof(buf), buf))
101 if (strcpy(buf,
"@"))
103 if (strcpy(buf,
":"))
105 if (getcwd(buf,
sizeof(buf)))
107 return new GString(buf);
108 return new GString();
111GString *appendToPath(GString *path,
const char *fileName) {
119 p0 = path->getCString();
120 p1 = p0 + path->getLength() - 1;
121 if (!strcmp(fileName,
"-")) {
123 for (p2 = p1; p2 > p0 && *p2 !=
'.' && *p2 !=
'['; --p2) ;
126 path->del(p2 - p0, p1 - p2);
127 }
else if (*p1 ==
':') {
133 }
else if ((q1 = strrchr(fileName,
'.')) && !strncmp(q1,
".DIR;", 5)) {
135 path->insert(p1 - p0,
'.');
136 path->insert(p1 - p0 + 1, fileName, q1 - fileName);
137 }
else if (*p1 ==
':') {
140 path->append(fileName, q1 - fileName);
143 path->append(fileName, q1 - fileName);
146 if (*p1 !=
']' && *p1 !=
':')
148 path->append(fileName);
158 tmp =
new GString(path);
160 tmp->append(fileName);
161 GetFullPathName(tmp->getCString(),
sizeof(buf), buf, &fp);
173 i = path->getLength();
174 path->append(fileName);
175 for (p = path->getCString() + i; *p; ++p) {
178 }
else if (*p ==
'.') {
190 i = path->getLength();
191 path->append(fileName);
192 for (p = path->getCString() + i; *p; ++p) {
195 }
else if (*p ==
'.') {
201#elif defined(__EMX__)
206 if (!strcmp(fileName,
"."))
210 if (!strcmp(fileName,
"..")) {
211 for (i = path->getLength() - 2; i >= 0; --i) {
212 if (path->getChar(i) ==
'/' || path->getChar(i) ==
'\\' ||
213 path->getChar(i) ==
':')
217 if (path->getChar(0) ==
'/' || path->getChar(0) ==
'\\') {
218 path->del(1, path->getLength() - 1);
219 }
else if (path->getLength() >= 2 && path->getChar(1) ==
':') {
220 path->del(2, path->getLength() - 2);
226 if (path->getChar(i-1) ==
':')
228 path->del(i, path->getLength() - i);
234 if (path->getLength() > 0 &&
235 path->getChar(path->getLength() - 1) !=
'/' &&
236 path->getChar(path->getLength() - 1) !=
'\\')
238 path->append(fileName);
246 if (!strcmp(fileName,
"."))
250 if (!strcmp(fileName,
"..")) {
251 for (i = path->getLength() - 2; i >= 0; --i) {
252 if (path->getChar(i) ==
'/')
256 if (path->getChar(0) ==
'/') {
257 path->del(1, path->getLength() - 1);
263 path->del(i, path->getLength() - i);
269 if (path->getLength() > 0 &&
270 path->getChar(path->getLength() - 1) !=
'/')
272 path->append(fileName);
277GString *grabPath(
const char *fileName) {
282 if ((p = strrchr(fileName,
']')))
283 return new GString(fileName, p + 1 - fileName);
284 if ((p = strrchr(fileName,
':')))
285 return new GString(fileName, p + 1 - fileName);
286 return new GString();
288#elif defined(__EMX__) || defined(WIN32)
292 if ((p = strrchr(fileName,
'/')))
293 return new GString(fileName, p - fileName);
294 if ((p = strrchr(fileName,
'\\')))
295 return new GString(fileName, p - fileName);
296 if ((p = strrchr(fileName,
':')))
297 return new GString(fileName, p + 1 - fileName);
298 return new GString();
304 if ((p = strrchr(fileName,
'.')))
305 return new GString(fileName, p - fileName);
306 return new GString();
312 if ((p = strrchr(fileName,
':')))
313 return new GString(fileName, p - fileName);
314 return new GString();
320 if ((p = strrchr(fileName,
'/')))
321 return new GString(fileName, p - fileName);
322 return new GString();
326GBool isAbsolutePath(
const char *path) {
329 return strchr(path,
':') ||
330 (path[0] ==
'[' && path[1] !=
'.' && path[1] !=
'-');
332#elif defined(__EMX__) || defined(WIN32)
334 return path[0] ==
'/' || path[0] ==
'\\' || path[1] ==
':';
338 return path[0] ==
'$';
342 return path[0] !=
':';
346 return path[0] ==
'/';
350GString *makePathAbsolute(GString *path) {
353 char buf[PATH_MAX+1];
355 if (!isAbsolutePath(path->getCString())) {
356 if (getcwd(buf,
sizeof(buf))) {
357 path->insert(0, buf);
368 if (!GetFullPathName(path->getCString(), _MAX_PATH, buf, &fp)) {
378 path->insert(0,
'@');
389 char buf[PATH_MAX+1];
394 if (path->getChar(0) ==
'~') {
395 if (path->getChar(1) ==
'/' ||
397 path->getChar(1) ==
'\\' ||
399 path->getLength() == 1) {
405 p1 = path->getCString() + 1;
407 for (p2 = p1; *p2 && *p2 !=
'/' && *p2 !=
'\\'; ++p2) ;
409 for (p2 = p1; *p2 && *p2 !=
'/'; ++p2) ;
411 if ((n = p2 - p1) > PATH_MAX)
415 if ((pw = getpwnam(buf))) {
416 path->del(0, p2 - p1 + 1);
417 path->insert(0, pw->pw_dir);
420 }
else if (!isAbsolutePath(path->getCString())) {
421 if (getcwd(buf,
sizeof(buf))) {
423 path->insert(0,
'/');
425 path->insert(0, buf);
432time_t getModTime(
const char *fileName) {
439 if (stat(fileName, &statBuf)) {
442 return statBuf.st_mtime;
446GBool openTempFile(GString **name, FILE **f,
const char *mode) {
453 if (!(s = _tempnam(getenv(
"TEMP"), NULL))) {
456 *name =
new GString(s);
459 (*name)->append(ext);
461 if (!(*f = fopen((*name)->getCString(), mode))) {
466#elif defined(VMS) || defined(__EMX__) || defined(ACORN) || defined(MACOS)
474 if (!(s = tmpnam(NULL))) {
477 *name =
new GString(s);
479 (*name)->append(ext);
481 if (!(*f = fopen((*name)->getCString(), mode))) {
510 if ((s = getenv(
"TMPDIR"))) {
511 *name =
new GString(s);
513 *name =
new GString(
"/tmp");
515 (*name)->append(
"/XXXXXX");
516 fd = mkstemp((*name)->getCString());
518 if (!(s = tmpnam(NULL))) {
521 *name =
new GString(s);
522 fd = open((*name)->getCString(), O_WRONLY | O_CREAT | O_EXCL, 0600);
525 if (fd < 0 || !(*f = fdopen(fd, mode))) {
533GBool executeCommand(
const char *cmd) {
535 return system(cmd) ? gTrue : gFalse;
537 return system(cmd) ? gFalse : gTrue;
541char *getLine(
char *buf,
int size, FILE *f) {
545 while (i < size - 1) {
546 if ((c = fgetc(f)) == EOF) {
555 if (c ==
'\x0a' && i < size - 1) {
557 }
else if (c != EOF) {
574GDirEntry::GDirEntry(
const char *dirPath,
const char *nameA, GBool doStat) {
586 name =
new GString(nameA);
590 if (!strcmp(nameA,
"-") ||
591 ((p = strrchr(nameA,
'.')) && !strncmp(p,
".DIR;", 5)))
595 s =
new GString(dirPath);
596 appendToPath(s, nameA);
598 fa = GetFileAttributes(s->getCString());
599 dir = (fa != 0xFFFFFFFF && (fa & FILE_ATTRIBUTE_DIRECTORY));
601 if (stat(s->getCString(), &st) == 0)
602 dir = S_ISDIR(st.st_mode);
609GDirEntry::~GDirEntry() {
613GDir::GDir(
const char *name, GBool doStatA) {
614 path =
new GString(name);
621 hnd = FindFirstFile(tmp->getCString(), &ffd);
628 needParent = strchr(name,
'[') != NULL;
648GDirEntry *GDir::getNextEntry() {
654 e =
new GDirEntry(path->getCString(), ffd.cFileName, doStat);
655 if (hnd && !FindNextFile(hnd, &ffd)) {
665 e =
new GDirEntry(path->getCString(),
"-", doStat);
672 if (ent && !strcmp(ent->d_name,
"."))
676 e =
new GDirEntry(path->getCString(), ent->d_name, doStat);
690 hnd = FindFirstFile(tmp->getCString(), &ffd);
697 needParent = strchr(path->getCString(),
'[') != NULL;