2 * Directory and path functions
4 * (C) 1992 Joseph H. Allen
6 * This file is part of JOE (Joe's Own Editor)
11 __RCSID("$MirOS: contrib/code/jupp/path.c,v 1.13 2017/12/02 02:07:29 tg Exp $");
13 #ifdef HAVE_SYS_STAT_H
20 # include <paths.h> /* for _PATH_TMP */
29 #ifdef HAVE_BSD_STRING_H
30 #include <bsd/string.h>
37 #ifdef TIME_WITH_SYS_TIME
38 # include <sys/time.h>
41 # ifdef HAVE_SYS_TIME_H
42 # include <sys/time.h>
50 # define NAMLEN(dirent) strlen((dirent)->d_name)
52 # ifdef HAVE_SYS_DIRENT_H
53 # include <sys/dirent.h>
54 # define NAMLEN(dirent) strlen((dirent)->d_name)
56 # define direct dirent
57 # define NAMLEN(dirent) (dirent)->d_namlen
58 # ifdef HAVE_SYS_NDIR_H
59 # include <sys/ndir.h>
61 # ifdef HAVE_SYS_DIR_H
76 #if HAVE_DRIVE_LETTERS
77 #define do_if_drive_letter(path, command) do { \
78 if ((path)[1] == ':' && ( \
79 ((path)[0] >= 'a' && (path)[0] <= 'z') || \
80 ((path)[0] >= 'A' && (path)[0] <= 'Z'))) { \
83 } while (/* CONSTCOND */ 0)
85 #define do_if_drive_letter(path, command) do { } while (/* CONSTCOND */ 0)
87 #define skip_drive_letter(path) do_if_drive_letter((path), (path) += 2)
93 # define _PATH_TMP "/tmp/"
97 #if !defined(PATH_MAX) && !defined(HAVE_GET_CURRENT_DIR_NAME)
98 #warning What should we include to have PATH_MAX defined?
102 /********************************************************************/
103 #if HAVE_BACKSLASH_PATHS
104 unsigned char *joesep(unsigned char *path)
108 for (x = 0; path[x]; ++x)
114 /********************************************************************/
115 unsigned char *namprt(unsigned char *path)
119 skip_drive_letter(path);
120 z = path + slen(path);
121 while ((z != path) && (z[-1] != '/'))
123 return vsncpy(NULL, 0, sz(z));
125 /********************************************************************/
126 unsigned char *namepart(unsigned char *tmp, unsigned char *path)
130 skip_drive_letter(path);
131 z = path + strlen((char *)path);
132 while ((z != path) && (z[-1] != '/'))
134 strlcpy((char *)tmp, (char *)z, 1024);
137 /********************************************************************/
138 unsigned char *dirprt_ptr(unsigned char *path)
140 unsigned char *b = path;
141 unsigned char *z = path + slen(path);
143 skip_drive_letter(b);
144 while ((z != b) && (z[-1] != '/'))
148 unsigned char *dirprt(unsigned char *path)
150 return vsncpy(NULL, 0, path, dirprt_ptr(path) - path);
152 /********************************************************************/
153 unsigned char *begprt(unsigned char *path)
155 unsigned char *z = path + slen(path);
158 do_if_drive_letter(path, drv = 2);
159 while ((z != path + drv) && (z[-1] == '/'))
162 return vsncpy(NULL, 0, sz(path));
164 while ((z != path + drv) && (z[-1] != '/'))
166 return vsncpy(NULL, 0, path, z - path);
169 /********************************************************************/
170 unsigned char *endprt(unsigned char *path)
172 unsigned char *z = path + slen(path);
175 do_if_drive_letter(path, drv = 2);
176 while ((z != path + drv) && (z[-1] == '/'))
179 return vsncpy(NULL, 0, sc(""));
181 while (z != path + drv && z[-1] != '/')
183 return vsncpy(NULL, 0, sz(z));
186 /********************************************************************/
187 int mkpath(unsigned char *path)
191 if (path[0] == '/') {
201 for (s = path; (*s) && (*s != '/'); s++) ;
204 if (chddir((char *)path)) {
205 if (mkdir((char *)path, 0777))
207 if (chddir((char *)path))
218 /********************************************************************/
219 /* Create a temporary file */
220 /********************************************************************/
221 unsigned char *mktmp(unsigned char *where, int *fdp)
224 static unsigned seq = 0;
231 where = (unsigned char *)getenv("TMPDIR");
233 where = (unsigned char *)getenv("TEMP");
235 where = US _PATH_TMP;
237 namesize = strlen((char *)where) + 20;
238 name = vsmk(namesize); /* [G.Ghibo'] we need to use vsmk() and not malloc() as
239 area returned by mktmp() is destroyed later with
242 joe_snprintf_1((char *)name, namesize, "%s/joe.tmp.XXXXXXXXXX", where);
243 if ((fd = mkstemp((char *)name)) == -1)
244 return (NULL); /* FIXME: vflsh() and vflshf() */
245 /* expect mktmp() always succeed!!! */
246 fchmod(fd, 0600); /* Linux glibc 2.0 mkstemp() creates it with */
247 /* 0666 mode --> change it to 0600, so nobody */
248 /* else sees content of temporary file */
250 #warning "Waah, this is insane! Consider getting mkstemp!"
252 seq = (seq + 1) % 10000;
253 joe_snprintf_3(name, namesize, "%s/joe.tmp.%04u%05u", where, seq,
254 (unsigned)(time(NULL) % 100000));
255 if ((fd = open(name, O_RDONLY)) != -1) {
257 goto loop; /* FIXME: possible endless loop --> DoS attack */
259 if ((fd = open(name, O_RDWR | O_CREAT | O_EXCL, 0600)) == -1)
260 return (NULL); /* FIXME: see above */
268 /********************************************************************/
269 int rmatch(unsigned char *a, unsigned char *b)
293 while (*a && (c = *a++) != ']')
294 if ((c == '-') && (a[-2] != '[') && (*a)) {
295 if ((*b >= a[-2]) && (*b <= *a))
299 if ((!flag && !inv) || (flag && inv) || (!*b))
319 /********************************************************************/
320 int isreg(unsigned char *s)
324 for (x = 0; s[x]; ++x)
325 if ((s[x] == '*') || (s[x] == '?') || (s[x] == '['))
329 /********************************************************************/
335 unsigned char d_name[16];
339 unsigned char *dirpath = NULL;
341 void *opendir(unsigned char *path)
351 struct direct *readdir()
356 if (findnext(&ffblk))
359 if (findfirst("*.*", &ffblk, FA_DIREC))
364 strcpy(direc.d_name, ffblk.ff_name);
365 for (x = 0; direc.d_name[x]; ++x)
366 direc.d_name[x] = tolower(direc.d_name[x]);
370 /********************************************************************/
371 unsigned char **rexpnd(unsigned char *word)
374 unsigned char **lst = NULL;
379 while ((de = readdir(dir)) != NULL)
380 if (strcmp(".", de->d_name))
381 if (rmatch(word, (unsigned char *)de->d_name))
382 lst = vaadd(lst, vsncpy(NULL, 0, sz((unsigned char *)de->d_name)));
387 /********************************************************************/
388 int chJpwd(const unsigned char *path)
390 unsigned char *fullpath;
395 fullpath = vsncpy(NULL, 0, sz(get_JOERC));
396 fullpath = vsncpy(sv(fullpath), sz(path));
397 rv = chpwd(fullpath);
402 int chpwd(const unsigned char *path)
405 unsigned char buf[256];
410 if ((path[0]) && (path[1] == ':')) {
411 if (_chdrive(path[0] & 0x1F))
421 if ((buf[x] == '/') || (buf[x] == '\\'))
428 if ((!path) || (!path[0]))
430 return chdir((char *)path);
434 /* The pwd function */
435 unsigned char *pwd(void)
437 #if defined(PATH_MAX) || !defined(HAVE_GET_CURRENT_DIR_NAME)
438 static unsigned char buf[PATH_MAX];
442 ret = (unsigned char *)getcwd((char *)buf, PATH_MAX - 1);
444 ret = (unsigned char *)getwd((char *)buf);
446 buf[PATH_MAX - 1] = '\0';
451 static char *wd = NULL;
454 wd = get_current_dir_name();
460 unsigned char has_JOERC = 0;
461 unsigned char *get_JOERC = NULL;
463 extern char *cygwin32_argv0(void);
465 void init_JOERC(void)
470 if ((get_JOERC = (unsigned char *)cygwin32_argv0()) == NULL)
473 if ((sep = strrchr((char *)get_JOERC, '/')) == NULL)
475 if (stat(get_JOERC, &sb))