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
)
52 cmd
= a
? strdup(a
) : (char*)0;
55 if (strlen(p
) < PATH_MAX
)
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
);
68 return (path
== buf
) ? strdup(path
) : path
;
73 else if (s
= (char*)a
)
83 if ((!cmd
|| *cmd
) && (strchr(s
, '/') || (s
= cmd
)))
85 if (!cmd
&& *s
== '/')
87 if (strlen(s
) < (sizeof(buf
) - 6))
92 do if (s
<= path
) goto normal
; while (*--s
== '/');
93 do if (s
<= path
) goto normal
; while (*--s
!= '/');
95 if (pathexists(path
, PATH_EXECUTE
))
97 if (s
= pathaccess(path
, path
, p
, a
, mode
))
98 return path
== buf
? strdup(s
) : s
;
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
;