1 /*********************************************************************** 2 * * 3 * This software is part of the ast package * 4 * Copyright (c) 1985-2011 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 Bell Laboratories 26 * 27 * generate 14 char lookup key for lang path in key 28 * based on 32-bit checksum on path 29 * 30 * if key==0 then space is malloc'd 31 * if attr != 0 then attribute var assignments placed here: 32 * ATTRIBUTES list of attribute names 33 */ 34 35 #define _AST_API_H 1 36 37 #include <ast.h> 38 #include <ctype.h> 39 #include <fs3d.h> 40 #include <preroot.h> 41 #include <ls.h> 42 43 char* 44 pathkey(char* key, char* attr, const char* lang, const char* tool, const char* path) 45 { 46 return pathkey_20100601(lang, tool, path, key, 16, attr, PATH_MAX); 47 } 48 49 #undef _AST_API_H 50 51 #include <ast_api.h> 52 53 char* 54 pathkey_20100601(const char* lang, const char* tool, const char* apath, char* key, size_t keysize, char* attr, size_t attrsize) 55 { 56 register char* path = (char*)apath; 57 register char* s; 58 register char* k; 59 char* t; 60 char* flags; 61 char** p; 62 int c; 63 unsigned long n; 64 char buf[15]; 65 char* usr[16]; 66 char* env[elementsof(usr) + 3]; 67 char* ver[2]; 68 char tmp[PATH_MAX]; 69 #if _UWIN 70 struct stat st; 71 #endif 72 73 static char let[] = "ABCDEFGHIJKLMNOP"; 74 75 if (!key) 76 key = buf; 77 if (tool && streq(tool, "mam")) 78 { 79 for (n = 0; *path; path++) 80 n = n * 0x63c63cd9L + *path + 0x9c39c33dL; 81 k = key; 82 for (n &= 0xffffffffL; n; n >>= 4) 83 *k++ = let[n & 0xf]; 84 *k = 0; 85 } 86 else 87 { 88 for (c = 0; c < elementsof(env); c++) 89 env[c] = 0; 90 n = 0; 91 92 /* 93 * trailing flags in path 94 */ 95 96 if (flags = strchr(path, ' ')) 97 { 98 if (flags == path) 99 flags = 0; 100 else 101 { 102 strlcpy(tmp, path, sizeof(tmp)); 103 *(flags = tmp + (flags - path)) = 0; 104 path = tmp; 105 } 106 } 107 108 /* 109 * 3D 110 */ 111 112 if (!flags && fs3d(FS3D_TEST) && (c = mount(path, tmp, FS3D_GET|FS3D_ALL|FS3D_SIZE(PATH_MAX), NiL)) > 1 && c < PATH_MAX) 113 path = tmp; 114 115 /* 116 * preroot 117 */ 118 119 if (attr) 120 attr = strcopy(attr, "PREROOT='"); 121 #if FS_PREROOT 122 if (k = getenv(PR_BASE)) 123 { 124 if (s = strrchr(k, '/')) 125 k = s + 1; 126 n = memsum(k, strlen(k), n); 127 } 128 if (attr && (getpreroot(attr, path) || getpreroot(attr, NiL))) 129 attr += strlen(attr); 130 #else 131 if ((k = getenv("VIRTUAL_ROOT")) && *k == '/') 132 { 133 n = memsum(k, strlen(k), n); 134 if (attr) 135 attr = strcopy(attr, k); 136 } 137 #endif 138 #if _UWIN 139 if (!stat("/", &st) && st.st_ino == 64) 140 { 141 k = "/64"; 142 n = memsum(k, strlen(k), n); 143 if (attr) 144 attr = strcopy(attr, k); 145 } 146 #endif 147 148 /* 149 * universe 150 */ 151 152 if (attr) 153 attr = strcopy(attr, "' UNIVERSE='"); 154 if (k = astconf("UNIVERSE", NiL, NiL)) 155 { 156 n = memsum(k, strlen(k), n); 157 if (attr) 158 attr = strcopy(attr, k); 159 } 160 161 /* 162 * environment 163 * 164 * ${PROBE_ATTRIBUTES} || ${VERSION_ENVIRONMENT} : list of alternate env vars 165 * ${VERSION_ENVIRONMENT} : list of alternate env vars 166 * ${VERSION_<lang>} 167 * ${VERSION_<base(path)>} 168 * ${<toupper(base(path))>VER} 169 * ${OBJTYPE} 170 */ 171 172 if (attr) 173 *attr++ = '\''; 174 c = 0; 175 usr[c++] = "OBJTYPE"; 176 if (!(k = getenv("PROBE_ATTRIBUTES"))) 177 k = getenv("VERSION_ENVIRONMENT"); 178 if (k) 179 while (c < (elementsof(usr) - 1)) 180 { 181 while (*k && (*k == ':' || *k == ' ')) 182 k++; 183 if (!*k) 184 break; 185 usr[c++] = k; 186 while (*k && *k != ':' && *k != ' ') 187 k++; 188 } 189 usr[c] = 0; 190 ver[0] = (char*)lang; 191 ver[1] = k = (s = strrchr(path, '/')) ? s + 1 : path; 192 s = buf; 193 if (isdigit(*k)) 194 { 195 if (*k == '3' && *(k + 1) == 'b') 196 { 197 /* 198 * cuteness never pays 199 */ 200 201 k += 2; 202 *s++ = 'B'; 203 *s++ = 'B'; 204 *s++ = 'B'; 205 } 206 else 207 *s++ = 'U'; 208 } 209 for (; (c = *k) && s < &buf[sizeof(buf) - 1]; k++) 210 { 211 if (!isalnum(c)) 212 c = '_'; 213 else if (islower(c)) 214 c = toupper(c); 215 *s++ = c; 216 } 217 *s = 0; 218 for (p = environ; *p; p++) 219 { 220 s = "VERSION_"; 221 for (k = *p; *k && *k == *s; k++, s++); 222 if (*k && !*s) 223 { 224 for (c = 0; c < elementsof(ver); c++) 225 if (!env[c] && (s = ver[c])) 226 { 227 for (t = k; *t && *t != '=' && *t++ == *s; s++); 228 if (*t == '=' && (!*s || (s - ver[c]) > 1)) 229 { 230 env[c] = *p; 231 goto found; 232 } 233 } 234 } 235 if (!env[2]) 236 { 237 s = buf; 238 for (k = *p; *k && *s++ == *k; k++); 239 if ((s - buf) > 2 && k[0] == 'V' && k[1] == 'E' && k[2] == 'R' && k[3] == '=') 240 { 241 env[2] = *p; 242 goto found; 243 } 244 } 245 for (c = 0; c < elementsof(usr) && (s = usr[c]); c++) 246 if (!env[c + elementsof(env) - elementsof(usr)]) 247 { 248 for (k = *p; *k && *k == *s; k++, s++); 249 if (*k == '=' && (!*s || *s == ':' || *s == ' ')) 250 { 251 env[c + elementsof(env) - elementsof(usr)] = *p; 252 goto found; 253 } 254 } 255 found: ; 256 } 257 for (c = 0; c < elementsof(env); c++) 258 if (k = env[c]) 259 { 260 if (attr) 261 { 262 *attr++ = ' '; 263 while ((*attr++ = *k++) != '='); 264 *attr++ = '\''; 265 attr = strcopy(attr, k); 266 *attr++ = '\''; 267 } 268 else 269 while (*k && *k++ != '='); 270 n = memsum(k, strlen(k), n); 271 } 272 if (attr) 273 { 274 attr = strcopy(attr, " ATTRIBUTES='PREROOT UNIVERSE"); 275 for (c = 0; c < elementsof(env); c++) 276 if (k = env[c]) 277 { 278 *attr++ = ' '; 279 while ((*attr = *k++) != '=') 280 attr++; 281 } 282 *attr++ = '\''; 283 *attr = 0; 284 } 285 286 /* 287 * now the normal stuff 288 */ 289 290 if (flags) 291 *flags = ' '; 292 s = path + strlen(path); 293 sfsprintf(key, 15, "%08lX", memsum(path, s - path, n)); 294 k = key + 14; 295 *k = 0; 296 if (!flags) 297 t = path; 298 else if ((t = s - 4) < flags) 299 t = flags + 1; 300 for (;;) 301 { 302 if (--s < t) 303 { 304 if (t == path) 305 break; 306 s = flags - 2; 307 t = path; 308 } 309 if (*s != '/' && *s != ' ') 310 { 311 *--k = *s; 312 if (k <= key + 8) 313 break; 314 } 315 } 316 while (k > key + 8) 317 *--k = '.'; 318 } 319 return key == buf ? strdup(key) : key; 320 } 321