1N/A/***********************************************************************
1N/A* *
1N/A* This software is part of the ast package *
1N/A* Copyright (c) 1985-2011 AT&T Intellectual Property *
1N/A* and is licensed under the *
1N/A* Common Public License, Version 1.0 *
1N/A* by AT&T Intellectual Property *
1N/A* *
1N/A* A copy of the License is available at *
1N/A* http://www.opensource.org/licenses/cpl1.0.txt *
1N/A* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
1N/A* *
1N/A* Information and Software Systems Research *
1N/A* AT&T Research *
1N/A* Florham Park NJ *
1N/A* *
1N/A* Glenn Fowler <gsf@research.att.com> *
1N/A* David Korn <dgk@research.att.com> *
1N/A* Phong Vo <kpv@research.att.com> *
1N/A* *
1N/A***********************************************************************/
1N/A#pragma prototyped
1N/A/*
1N/A * Glenn Fowler
1N/A * AT&T Research
1N/A *
1N/A * return full path to p with mode access using $PATH
1N/A * a!=0 enables related root search
1N/A * a!=0 && a!="" searches a dir first
1N/A * the related root must have a bin subdir
1N/A * p==0 sets the cached relative dir to a
1N/A * full path returned in path buffer
1N/A * if path==0 then the space is malloc'd
1N/A */
1N/A
1N/A#define _AST_API_H 1
1N/A
1N/A#include <ast.h>
1N/A
1N/Achar*
1N/Apathpath(char* path, const char* p, const char* a, int mode)
1N/A{
1N/A return pathpath_20100601(p, a, mode, path, PATH_MAX);
1N/A}
1N/A
1N/A#undef _AST_API_H
1N/A
1N/A#include <ast_api.h>
1N/A
1N/Achar*
1N/Apathpath_20100601(const char* p, const char* a, int mode, register char* path, size_t size)
1N/A{
1N/A register char* s;
1N/A char* x;
1N/A char buf[PATH_MAX];
1N/A
1N/A static char* cmd;
1N/A
1N/A if (!path)
1N/A path = buf;
1N/A if (!p)
1N/A {
1N/A if (cmd)
1N/A free(cmd);
1N/A cmd = a ? strdup(a) : (char*)0;
1N/A return 0;
1N/A }
1N/A if (strlen(p) < size)
1N/A {
1N/A strcpy(path, p);
1N/A if (pathexists(path, mode))
1N/A {
1N/A if (*p != '/' && (mode & PATH_ABSOLUTE))
1N/A {
1N/A getcwd(buf, sizeof(buf));
1N/A s = buf + strlen(buf);
1N/A sfsprintf(s, sizeof(buf) - (s - buf), "/%s", p);
1N/A if (path != buf)
1N/A strcpy(path, buf);
1N/A }
1N/A return (path == buf) ? strdup(path) : path;
1N/A }
1N/A }
1N/A if (*p == '/')
1N/A a = 0;
1N/A else if (s = (char*)a)
1N/A {
1N/A x = s;
1N/A if (strchr(p, '/'))
1N/A {
1N/A a = p;
1N/A p = "..";
1N/A }
1N/A else
1N/A a = 0;
1N/A if ((!cmd || *cmd) && (strchr(s, '/') || (s = cmd)))
1N/A {
1N/A if (!cmd && *s == '/')
1N/A cmd = strdup(s);
1N/A if (strlen(s) < (sizeof(buf) - 6))
1N/A {
1N/A s = strcopy(path, s);
1N/A for (;;)
1N/A {
1N/A do if (s <= path) goto normal; while (*--s == '/');
1N/A do if (s <= path) goto normal; while (*--s != '/');
1N/A strcpy(s + 1, "bin");
1N/A if (pathexists(path, PATH_EXECUTE))
1N/A {
1N/A if (s = pathaccess(path, p, a, mode, path, size))
1N/A return path == buf ? strdup(s) : s;
1N/A goto normal;
1N/A }
1N/A }
1N/A normal: ;
1N/A }
1N/A }
1N/A }
1N/A x = !a && strchr(p, '/') ? "" : pathbin();
1N/A if (!(s = pathaccess(x, p, a, mode, path, size)) && !*x && (x = getenv("FPATH")))
1N/A s = pathaccess(x, p, a, mode, path, size);
1N/A return (s && path == buf) ? strdup(s) : s;
1N/A}