14887Schin /*********************************************************************** 24887Schin * * 34887Schin * This software is part of the ast package * 4*12068SRoger.Faulkner@Oracle.COM * Copyright (c) 1985-2010 AT&T Intellectual Property * 54887Schin * and is licensed under the * 64887Schin * Common Public License, Version 1.0 * 78462SApril.Chin@Sun.COM * by AT&T Intellectual Property * 84887Schin * * 94887Schin * A copy of the License is available at * 104887Schin * http://www.opensource.org/licenses/cpl1.0.txt * 114887Schin * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) * 124887Schin * * 134887Schin * Information and Software Systems Research * 144887Schin * AT&T Research * 154887Schin * Florham Park NJ * 164887Schin * * 174887Schin * Glenn Fowler <gsf@research.att.com> * 184887Schin * David Korn <dgk@research.att.com> * 194887Schin * Phong Vo <kpv@research.att.com> * 204887Schin * * 214887Schin ***********************************************************************/ 224887Schin #pragma prototyped 234887Schin /* 244887Schin * Glenn Fowler 254887Schin * AT&T Research 264887Schin * 274887Schin * return full path to p with mode access using $PATH 284887Schin * a!=0 enables related root search 294887Schin * a!=0 && a!="" searches a dir first 304887Schin * the related root must have a bin subdir 314887Schin * p==0 sets the cached relative dir to a 324887Schin * full path returned in path buffer 334887Schin * if path==0 then the space is malloc'd 344887Schin */ 354887Schin 364887Schin #include <ast.h> 374887Schin 384887Schin char* 394887Schin pathpath(register char* path, const char* p, const char* a, int mode) 404887Schin { 414887Schin register char* s; 424887Schin char* x; 434887Schin char buf[PATH_MAX]; 444887Schin 454887Schin static char* cmd; 464887Schin 474887Schin if (!path) 484887Schin path = buf; 494887Schin if (!p) 504887Schin { 514887Schin if (cmd) 524887Schin free(cmd); 534887Schin cmd = a ? strdup(a) : (char*)0; 544887Schin return 0; 554887Schin } 564887Schin if (strlen(p) < PATH_MAX) 574887Schin { 584887Schin strcpy(path, p); 594887Schin if (pathexists(path, mode)) 604887Schin { 614887Schin if (*p != '/' && (mode & PATH_ABSOLUTE)) 624887Schin { 634887Schin getcwd(buf, sizeof(buf)); 644887Schin s = buf + strlen(buf); 654887Schin sfsprintf(s, sizeof(buf) - (s - buf), "/%s", p); 664887Schin if (path != buf) 674887Schin strcpy(path, buf); 684887Schin } 694887Schin return (path == buf) ? strdup(path) : path; 704887Schin } 714887Schin } 724887Schin if (*p == '/') 734887Schin a = 0; 744887Schin else if (s = (char*)a) 754887Schin { 764887Schin x = s; 774887Schin if (strchr(p, '/')) 784887Schin { 794887Schin a = p; 804887Schin p = ".."; 814887Schin } 824887Schin else 834887Schin a = 0; 844887Schin if ((!cmd || *cmd) && (strchr(s, '/') || (s = cmd))) 854887Schin { 864887Schin if (!cmd && *s == '/') 874887Schin cmd = strdup(s); 884887Schin if (strlen(s) < (sizeof(buf) - 6)) 894887Schin { 904887Schin s = strcopy(path, s); 914887Schin for (;;) 924887Schin { 934887Schin do if (s <= path) goto normal; while (*--s == '/'); 944887Schin do if (s <= path) goto normal; while (*--s != '/'); 954887Schin strcpy(s + 1, "bin"); 964887Schin if (pathexists(path, PATH_EXECUTE)) 974887Schin { 984887Schin if (s = pathaccess(path, path, p, a, mode)) 994887Schin return path == buf ? strdup(s) : s; 1004887Schin goto normal; 1014887Schin } 1024887Schin } 1034887Schin normal: ; 1044887Schin } 1054887Schin } 1064887Schin } 1074887Schin x = !a && strchr(p, '/') ? "" : pathbin(); 1084887Schin if (!(s = pathaccess(path, x, p, a, mode)) && !*x && (x = getenv("FPATH"))) 1094887Schin s = pathaccess(path, x, p, a, mode); 1104887Schin return (s && path == buf) ? strdup(s) : s; 1114887Schin } 112