8354 sync regcomp(3C) with upstream (fix make catalog)
[unleashed/tickless.git] / usr / src / lib / libast / common / path / pathpath.c
blob36be12d741ec83b784db764242eeaf4501765511
1 /***********************************************************************
2 * *
3 * This software is part of the ast package *
4 * Copyright (c) 1985-2010 AT&T Intellectual Property *
5 * and is licensed under the *
6 * Common Public License, Version 1.0 *
7 * by AT&T Intellectual Property *
8 * *
9 * A copy of the License is available at *
10 * http://www.opensource.org/licenses/cpl1.0.txt *
11 * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
12 * *
13 * Information and Software Systems Research *
14 * AT&T Research *
15 * Florham Park NJ *
16 * *
17 * Glenn Fowler <gsf@research.att.com> *
18 * David Korn <dgk@research.att.com> *
19 * Phong Vo <kpv@research.att.com> *
20 * *
21 ***********************************************************************/
22 #pragma prototyped
24 * Glenn Fowler
25 * AT&T Research
27 * return full path to p with mode access using $PATH
28 * a!=0 enables related root search
29 * a!=0 && a!="" searches a dir first
30 * the related root must have a bin subdir
31 * p==0 sets the cached relative dir to a
32 * full path returned in path buffer
33 * if path==0 then the space is malloc'd
36 #include <ast.h>
38 char*
39 pathpath(register char* path, const char* p, const char* a, int mode)
41 register char* s;
42 char* x;
43 char buf[PATH_MAX];
45 static char* cmd;
47 if (!path)
48 path = buf;
49 if (!p)
51 if (cmd)
52 free(cmd);
53 cmd = a ? strdup(a) : (char*)0;
54 return 0;
56 if (strlen(p) < PATH_MAX)
58 strcpy(path, p);
59 if (pathexists(path, mode))
61 if (*p != '/' && (mode & PATH_ABSOLUTE))
63 getcwd(buf, sizeof(buf));
64 s = buf + strlen(buf);
65 sfsprintf(s, sizeof(buf) - (s - buf), "/%s", p);
66 if (path != buf)
67 strcpy(path, buf);
69 return (path == buf) ? strdup(path) : path;
72 if (*p == '/')
73 a = 0;
74 else if (s = (char*)a)
76 x = s;
77 if (strchr(p, '/'))
79 a = p;
80 p = "..";
82 else
83 a = 0;
84 if ((!cmd || *cmd) && (strchr(s, '/') || (s = cmd)))
86 if (!cmd && *s == '/')
87 cmd = strdup(s);
88 if (strlen(s) < (sizeof(buf) - 6))
90 s = strcopy(path, s);
91 for (;;)
93 do if (s <= path) goto normal; while (*--s == '/');
94 do if (s <= path) goto normal; while (*--s != '/');
95 strcpy(s + 1, "bin");
96 if (pathexists(path, PATH_EXECUTE))
98 if (s = pathaccess(path, path, p, a, mode))
99 return path == buf ? strdup(s) : s;
100 goto normal;
103 normal: ;
107 x = !a && strchr(p, '/') ? "" : pathbin();
108 if (!(s = pathaccess(path, x, p, a, mode)) && !*x && (x = getenv("FPATH")))
109 s = pathaccess(path, x, p, a, mode);
110 return (s && path == buf) ? strdup(s) : s;