1 /***********************************************************************
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 *
9 * A copy of the License is available at *
10 * http://www.opensource.org/licenses/cpl1.0.txt *
11 * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
13 * Information and Software Systems Research *
17 * Glenn Fowler <gsf@research.att.com> *
18 * David Korn <dgk@research.att.com> *
19 * Phong Vo <kpv@research.att.com> *
21 ***********************************************************************/
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
39 pathpath(register char* path
, const char* p
, const char* a
, int mode
)
53 cmd
= a
? strdup(a
) : (char*)0;
56 if (strlen(p
) < PATH_MAX
)
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
);
69 return (path
== buf
) ? strdup(path
) : path
;
74 else if (s
= (char*)a
)
84 if ((!cmd
|| *cmd
) && (strchr(s
, '/') || (s
= cmd
)))
86 if (!cmd
&& *s
== '/')
88 if (strlen(s
) < (sizeof(buf
) - 6))
93 do if (s
<= path
) goto normal
; while (*--s
== '/');
94 do if (s
<= path
) goto normal
; while (*--s
!= '/');
96 if (pathexists(path
, PATH_EXECUTE
))
98 if (s
= pathaccess(path
, path
, p
, a
, mode
))
99 return path
== buf
? strdup(s
) : s
;
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
;