1 /*********************************************************************** 2 * * 3 * This software is part of the ast package * 4 * Copyright (c) 1985-2012 AT&T Intellectual Property * 5 * and is licensed under the * 6 * Eclipse Public License, Version 1.0 * 7 * by AT&T Intellectual Property * 8 * * 9 * A copy of the License is available at * 10 * http://www.eclipse.org/org/documents/epl-v10.html * 11 * (with md5 checksum b35adb5213ca9657e911e9befb180842) * 12 * * 13 * Information and Software Systems Research * 14 * AT&T Research * 15 * Florham Park NJ * 16 * * 17 * Glenn Fowler <gsf@research.att.com> * 18 * David Korn <dgk@research.att.com> * 19 * Phong Vo <kpv@research.att.com> * 20 * * 21 ***********************************************************************/ 22 #pragma prototyped 23 /* 24 * Glenn Fowler 25 * AT&T Research 26 * 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 34 */ 35 36 #define _AST_API_H 1 37 38 #include <ast.h> 39 40 char* 41 pathpath(char* path, const char* p, const char* a, int mode) 42 { 43 return pathpath_20100601(p, a, mode, path, PATH_MAX); 44 } 45 46 #undef _AST_API_H 47 48 #include <ast_api.h> 49 50 char* 51 pathpath_20100601(const char* p, const char* a, int mode, register char* path, size_t size) 52 { 53 register char* s; 54 char* x; 55 char buf[PATH_MAX]; 56 57 static char* cmd; 58 59 if (!path) 60 { 61 path = buf; 62 if (!size || size > sizeof(buf)) 63 size = sizeof(buf); 64 } 65 if (!p) 66 { 67 if (cmd) 68 free(cmd); 69 cmd = a ? strdup(a) : (char*)0; 70 return 0; 71 } 72 if (strlen(p) < size) 73 { 74 strcpy(path, p); 75 if (pathexists(path, mode)) 76 { 77 if (*p != '/' && (mode & PATH_ABSOLUTE)) 78 { 79 getcwd(buf, sizeof(buf)); 80 s = buf + strlen(buf); 81 sfsprintf(s, sizeof(buf) - (s - buf), "/%s", p); 82 if (path != buf) 83 strcpy(path, buf); 84 } 85 return (path == buf) ? strdup(path) : path; 86 } 87 } 88 if (*p == '/') 89 a = 0; 90 else if (s = (char*)a) 91 { 92 x = s; 93 if (strchr(p, '/')) 94 { 95 a = p; 96 p = ".."; 97 } 98 else 99 a = 0; 100 if ((!cmd || *cmd) && (strchr(s, '/') || (s = cmd))) 101 { 102 if (!cmd && *s == '/') 103 cmd = strdup(s); 104 if (strlen(s) < (sizeof(buf) - 6)) 105 { 106 s = strcopy(path, s); 107 for (;;) 108 { 109 do if (s <= path) goto normal; while (*--s == '/'); 110 do if (s <= path) goto normal; while (*--s != '/'); 111 strcpy(s + 1, "bin"); 112 if (pathexists(path, PATH_EXECUTE)) 113 { 114 if (s = pathaccess(path, p, a, mode, path, size)) 115 return path == buf ? strdup(s) : s; 116 goto normal; 117 } 118 } 119 normal: ; 120 } 121 } 122 } 123 x = !a && strchr(p, '/') ? "" : pathbin(); 124 if (!(s = pathaccess(x, p, a, mode, path, size)) && !*x && (x = getenv("FPATH"))) 125 s = pathaccess(x, p, a, mode, path, size); 126 return (s && path == buf) ? strdup(s) : s; 127 } 128