import less(1)
[unleashed/tickless.git] / usr / src / lib / libast / common / path / pathpath.c
blob00591e4be2da2bc322a6d6049534f4a300b3ac47
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 free(cmd);
52 cmd = a ? strdup(a) : (char*)0;
53 return 0;
55 if (strlen(p) < PATH_MAX)
57 strcpy(path, p);
58 if (pathexists(path, mode))
60 if (*p != '/' && (mode & PATH_ABSOLUTE))
62 getcwd(buf, sizeof(buf));
63 s = buf + strlen(buf);
64 sfsprintf(s, sizeof(buf) - (s - buf), "/%s", p);
65 if (path != buf)
66 strcpy(path, buf);
68 return (path == buf) ? strdup(path) : path;
71 if (*p == '/')
72 a = 0;
73 else if (s = (char*)a)
75 x = s;
76 if (strchr(p, '/'))
78 a = p;
79 p = "..";
81 else
82 a = 0;
83 if ((!cmd || *cmd) && (strchr(s, '/') || (s = cmd)))
85 if (!cmd && *s == '/')
86 cmd = strdup(s);
87 if (strlen(s) < (sizeof(buf) - 6))
89 s = strcopy(path, s);
90 for (;;)
92 do if (s <= path) goto normal; while (*--s == '/');
93 do if (s <= path) goto normal; while (*--s != '/');
94 strcpy(s + 1, "bin");
95 if (pathexists(path, PATH_EXECUTE))
97 if (s = pathaccess(path, path, p, a, mode))
98 return path == buf ? strdup(s) : s;
99 goto normal;
102 normal: ;
106 x = !a && strchr(p, '/') ? "" : pathbin();
107 if (!(s = pathaccess(path, x, p, a, mode)) && !*x && (x = getenv("FPATH")))
108 s = pathaccess(path, x, p, a, mode);
109 return (s && path == buf) ? strdup(s) : s;