1 /*********************************************************************** 2 * * 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 * 8 * * 9 * A copy of the License is available at * 10 * http://www.opensource.org/licenses/cpl1.0.txt * 11 * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) * 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 1 if path exisis 28 * maintains a cache to minimize stat(2) calls 29 * path is modified in-place but restored on return 30 * path components checked in pairs to cut stat()'s 31 * in half by checking ENOTDIR vs. ENOENT 32 * case ignorance infection unavoidable here 33 */ 34 35 #include "lclib.h" 36 37 #include <ls.h> 38 #include <error.h> 39 40 typedef struct Tree_s 41 { 42 struct Tree_s* next; 43 struct Tree_s* tree; 44 int mode; 45 char name[1]; 46 } Tree_t; 47 48 int 49 pathexists(char* path, int mode) 50 { 51 register char* s; 52 register char* e; 53 register Tree_t* p; 54 register Tree_t* t; 55 register int c; 56 char* ee; 57 int cc; 58 int x; 59 struct stat st; 60 int (*cmp)(const char*, const char*); 61 62 static Tree_t tree; 63 64 t = &tree; 65 e = (c = *path) == '/' ? path + 1 : path; 66 cmp = strchr(astconf("PATH_ATTRIBUTES", path, NiL), 'c') ? strcasecmp : strcmp; 67 if ((ast.locale.set & (AST_LC_debug|AST_LC_find)) == (AST_LC_debug|AST_LC_find)) 68 sfprintf(sfstderr, "locale test %s\n", path); 69 while (c) 70 { 71 p = t; 72 for (s = e; *e && *e != '/'; e++); 73 c = *e; 74 *e = 0; 75 for (t = p->tree; t && (*cmp)(s, t->name); t = t->next); 76 if (!t) 77 { 78 if (!(t = newof(0, Tree_t, 1, strlen(s)))) 79 { 80 *e = c; 81 return 0; 82 } 83 strcpy(t->name, s); 84 t->next = p->tree; 85 p->tree = t; 86 if (c) 87 { 88 *e = c; 89 for (s = ee = e + 1; *ee && *ee != '/'; ee++); 90 cc = *ee; 91 *ee = 0; 92 } 93 else 94 ee = 0; 95 if ((ast.locale.set & (AST_LC_debug|AST_LC_find)) == (AST_LC_debug|AST_LC_find)) 96 sfprintf(sfstderr, "locale stat %s\n", path); 97 x = stat(path, &st); 98 if (ee) 99 { 100 e = ee; 101 c = cc; 102 if (!x || errno == ENOENT) 103 t->mode = PATH_READ|PATH_EXECUTE; 104 if (!(p = newof(0, Tree_t, 1, strlen(s)))) 105 { 106 *e = c; 107 return 0; 108 } 109 strcpy(p->name, s); 110 p->next = t->tree; 111 t->tree = p; 112 t = p; 113 } 114 if (x) 115 { 116 *e = c; 117 return 0; 118 } 119 if (st.st_mode & (S_IRUSR|S_IRGRP|S_IROTH)) 120 t->mode |= PATH_READ; 121 if (st.st_mode & (S_IWUSR|S_IWGRP|S_IWOTH)) 122 t->mode |= PATH_WRITE; 123 if (st.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH)) 124 t->mode |= PATH_EXECUTE; 125 if (!S_ISDIR(st.st_mode)) 126 t->mode |= PATH_REGULAR; 127 } 128 *e++ = c; 129 if (!t->mode || c && (t->mode & PATH_REGULAR)) 130 return 0; 131 } 132 mode &= (PATH_READ|PATH_WRITE|PATH_EXECUTE|PATH_REGULAR); 133 return (t->mode & mode) == mode; 134 } 135