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