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*
pathkey(char * key,char * attr,const char * lang,const char * tool,const char * path)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*
pathkey_20100601(const char * lang,const char * tool,const char * apath,char * key,size_t keysize,char * attr,size_t attrsize)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