1 /* $MirOS: contrib/code/jupp/path.c,v 1.12 2016/10/29 23:44:45 tg Exp $ */
3 * Directory and path functions
5 * (C) 1992 Joseph H. Allen
7 * This file is part of JOE (Joe's Own Editor)
13 #include <sys/types.h>
14 #ifdef HAVE_SYS_STAT_H
21 # include <paths.h> /* for _PATH_TMP */
30 #ifdef HAVE_BSD_STRING_H
31 #include <bsd/string.h>
38 #ifdef TIME_WITH_SYS_TIME
39 # include <sys/time.h>
42 # ifdef HAVE_SYS_TIME_H
43 # include <sys/time.h>
51 # define NAMLEN(dirent) strlen((dirent)->d_name)
53 # ifdef HAVE_SYS_DIRENT_H
54 # include <sys/dirent.h>
55 # define NAMLEN(dirent) strlen((dirent)->d_name)
57 # define direct dirent
58 # define NAMLEN(dirent) (dirent)->d_namlen
59 # ifdef HAVE_SYS_NDIR_H
60 # include <sys/ndir.h>
62 # ifdef HAVE_SYS_DIR_H
77 #if HAVE_DRIVE_LETTERS
78 #define do_if_drive_letter(path, command) do { \
79 if ((path)[1] == ':' && ( \
80 ((path)[0] >= 'a' && (path)[0] <= 'z') || \
81 ((path)[0] >= 'A' && (path)[0] <= 'Z'))) { \
84 } while (/* CONSTCOND */ 0)
86 #define do_if_drive_letter(path, command) do { } while (/* CONSTCOND */ 0)
88 #define skip_drive_letter(path) do_if_drive_letter((path), (path) += 2)
94 # define _PATH_TMP "/tmp/"
98 #if !defined(PATH_MAX) && !defined(HAVE_GET_CURRENT_DIR_NAME)
99 #warning What should we include to have PATH_MAX defined?
100 #define PATH_MAX 4096
103 /********************************************************************/
104 #if HAVE_BACKSLASH_PATHS
105 unsigned char *joesep(unsigned char *path)
109 for (x = 0; path[x]; ++x)
115 /********************************************************************/
116 unsigned char *namprt(unsigned char *path)
120 skip_drive_letter(path);
121 z = path + slen(path);
122 while ((z != path) && (z[-1] != '/'))
124 return vsncpy(NULL, 0, sz(z));
126 /********************************************************************/
127 unsigned char *namepart(unsigned char *tmp, unsigned char *path)
131 skip_drive_letter(path);
132 z = path + strlen((char *)path);
133 while ((z != path) && (z[-1] != '/'))
135 strlcpy((char *)tmp, (char *)z, 1024);
138 /********************************************************************/
139 unsigned char *dirprt_ptr(unsigned char *path)
141 unsigned char *b = path;
142 unsigned char *z = path + slen(path);
144 skip_drive_letter(b);
145 while ((z != b) && (z[-1] != '/'))
149 unsigned char *dirprt(unsigned char *path)
151 return vsncpy(NULL, 0, path, dirprt_ptr(path) - path);
153 /********************************************************************/
154 unsigned char *begprt(unsigned char *path)
156 unsigned char *z = path + slen(path);
159 do_if_drive_letter(path, drv = 2);
160 while ((z != path + drv) && (z[-1] == '/'))
163 return vsncpy(NULL, 0, sz(path));
165 while ((z != path + drv) && (z[-1] != '/'))
167 return vsncpy(NULL, 0, path, z - path);
170 /********************************************************************/
171 unsigned char *endprt(unsigned char *path)
173 unsigned char *z = path + slen(path);
176 do_if_drive_letter(path, drv = 2);
177 while ((z != path + drv) && (z[-1] == '/'))
180 return vsncpy(NULL, 0, sc(""));
182 while (z != path + drv && z[-1] != '/')
184 return vsncpy(NULL, 0, sz(z));
187 /********************************************************************/
188 int mkpath(unsigned char *path)
192 if (path[0] == '/') {
202 for (s = path; (*s) && (*s != '/'); s++) ;
205 if (chddir((char *)path)) {
206 if (mkdir((char *)path, 0777))
208 if (chddir((char *)path))
219 /********************************************************************/
220 /* Create a temporary file */
221 /********************************************************************/
222 unsigned char *mktmp(unsigned char *where, int *fdp)
225 static unsigned seq = 0;
232 where = (unsigned char *)getenv("TMPDIR");
234 where = (unsigned char *)getenv("TEMP");
236 where = US _PATH_TMP;
238 namesize = strlen((char *)where) + 20;
239 name = vsmk(namesize); /* [G.Ghibo'] we need to use vsmk() and not malloc() as
240 area returned by mktmp() is destroyed later with
243 joe_snprintf_1((char *)name, namesize, "%s/joe.tmp.XXXXXXXXXX", where);
244 if ((fd = mkstemp((char *)name)) == -1)
245 return (NULL); /* FIXME: vflsh() and vflshf() */
246 /* expect mktmp() always succeed!!! */
247 fchmod(fd, 0600); /* Linux glibc 2.0 mkstemp() creates it with */
248 /* 0666 mode --> change it to 0600, so nobody */
249 /* else sees content of temporary file */
251 #warning "Waah, this is insane! Consider getting mkstemp!"
253 seq = (seq + 1) % 10000;
254 joe_snprintf_3(name, namesize, "%s/joe.tmp.%04u%05u", where, seq,
255 (unsigned)(time(NULL) % 100000));
256 if ((fd = open(name, O_RDONLY)) != -1) {
258 goto loop; /* FIXME: possible endless loop --> DoS attack */
260 if ((fd = open(name, O_RDWR | O_CREAT | O_EXCL, 0600)) == -1)
261 return (NULL); /* FIXME: see above */
269 /********************************************************************/
270 int rmatch(unsigned char *a, unsigned char *b)
294 while (*a && (c = *a++) != ']')
295 if ((c == '-') && (a[-2] != '[') && (*a)) {
296 if ((*b >= a[-2]) && (*b <= *a))
300 if ((!flag && !inv) || (flag && inv) || (!*b))
320 /********************************************************************/
321 int isreg(unsigned char *s)
325 for (x = 0; s[x]; ++x)
326 if ((s[x] == '*') || (s[x] == '?') || (s[x] == '['))
330 /********************************************************************/
336 unsigned char d_name[16];
340 unsigned char *dirpath = NULL;
342 void *opendir(unsigned char *path)
352 struct direct *readdir()
357 if (findnext(&ffblk))
360 if (findfirst("*.*", &ffblk, FA_DIREC))
365 strcpy(direc.d_name, ffblk.ff_name);
366 for (x = 0; direc.d_name[x]; ++x)
367 direc.d_name[x] = tolower(direc.d_name[x]);
371 /********************************************************************/
372 unsigned char **rexpnd(unsigned char *word)
375 unsigned char **lst = NULL;
380 while ((de = readdir(dir)) != NULL)
381 if (strcmp(".", de->d_name))
382 if (rmatch(word, (unsigned char *)de->d_name))
383 lst = vaadd(lst, vsncpy(NULL, 0, sz((unsigned char *)de->d_name)));
388 /********************************************************************/
389 int chJpwd(const unsigned char *path)
391 unsigned char *fullpath;
396 fullpath = vsncpy(NULL, 0, sz(get_JOERC));
397 fullpath = vsncpy(sv(fullpath), sz(path));
398 rv = chpwd(fullpath);
403 int chpwd(const unsigned char *path)
406 unsigned char buf[256];
411 if ((path[0]) && (path[1] == ':')) {
412 if (_chdrive(path[0] & 0x1F))
422 if ((buf[x] == '/') || (buf[x] == '\\'))
429 if ((!path) || (!path[0]))
431 return chdir((char *)path);
435 /* The pwd function */
436 unsigned char *pwd(void)
438 #if defined(PATH_MAX) || !defined(HAVE_GET_CURRENT_DIR_NAME)
439 static unsigned char buf[PATH_MAX];
443 ret = (unsigned char *)getcwd((char *)buf, PATH_MAX - 1);
445 ret = (unsigned char *)getwd((char *)buf);
447 buf[PATH_MAX - 1] = '\0';
452 static char *wd = NULL;
455 wd = get_current_dir_name();
461 unsigned char has_JOERC = 0;
462 unsigned char *get_JOERC = NULL;
464 extern char *cygwin32_argv0(void);
466 void init_JOERC(void)
471 if ((get_JOERC = (unsigned char *)cygwin32_argv0()) == NULL)
474 if ((sep = strrchr((char *)get_JOERC, '/')) == NULL)
476 if (stat(get_JOERC, &sb))