Blame src/lib/libast/path/pathpath.c

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