1da2e3ebdSchin /***********************************************************************
2da2e3ebdSchin * *
3da2e3ebdSchin * This software is part of the ast package *
4*3e14f97fSRoger A. Faulkner * Copyright (c) 1985-2010 AT&T Intellectual Property *
5da2e3ebdSchin * and is licensed under the *
6da2e3ebdSchin * Common Public License, Version 1.0 *
77c2fbfb3SApril Chin * by AT&T Intellectual Property *
8da2e3ebdSchin * *
9da2e3ebdSchin * A copy of the License is available at *
10da2e3ebdSchin * http://www.opensource.org/licenses/cpl1.0.txt *
11da2e3ebdSchin * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
12da2e3ebdSchin * *
13da2e3ebdSchin * Information and Software Systems Research *
14da2e3ebdSchin * AT&T Research *
15da2e3ebdSchin * Florham Park NJ *
16da2e3ebdSchin * *
17da2e3ebdSchin * Glenn Fowler <gsf@research.att.com> *
18da2e3ebdSchin * David Korn <dgk@research.att.com> *
19da2e3ebdSchin * Phong Vo <kpv@research.att.com> *
20da2e3ebdSchin * *
21da2e3ebdSchin ***********************************************************************/
22da2e3ebdSchin #pragma prototyped
23da2e3ebdSchin /*
24da2e3ebdSchin * Glenn Fowler
25da2e3ebdSchin * AT&T Bell Laboratories
26da2e3ebdSchin *
27da2e3ebdSchin * generate 14 char lookup key for lang path in key
28da2e3ebdSchin * based on 32-bit checksum on path
29da2e3ebdSchin *
30da2e3ebdSchin * if key==0 then space is malloc'd
31da2e3ebdSchin * if attr != 0 then attribute var assignments placed here:
32da2e3ebdSchin * ATTRIBUTES list of attribute names
33da2e3ebdSchin */
34da2e3ebdSchin
35da2e3ebdSchin #include <ast.h>
36da2e3ebdSchin #include <ctype.h>
37da2e3ebdSchin #include <fs3d.h>
38da2e3ebdSchin #include <preroot.h>
39da2e3ebdSchin
40da2e3ebdSchin char*
pathkey(char * key,char * attr,const char * lang,const char * tool,const char * apath)41da2e3ebdSchin pathkey(char* key, char* attr, const char* lang, const char* tool, const char* apath)
42da2e3ebdSchin {
43da2e3ebdSchin register char* path = (char*)apath;
44da2e3ebdSchin register char* s;
45da2e3ebdSchin register char* k;
46da2e3ebdSchin char* t;
47da2e3ebdSchin char* flags;
48da2e3ebdSchin char** p;
49da2e3ebdSchin int c;
50da2e3ebdSchin unsigned long n;
51da2e3ebdSchin char buf[15];
52da2e3ebdSchin char* usr[16];
53da2e3ebdSchin char* env[elementsof(usr) + 3];
54da2e3ebdSchin char* ver[2];
55da2e3ebdSchin char tmp[PATH_MAX];
56da2e3ebdSchin
57da2e3ebdSchin static char let[] = "ABCDEFGHIJKLMNOP";
58da2e3ebdSchin
59da2e3ebdSchin if (!key)
60da2e3ebdSchin key = buf;
61da2e3ebdSchin if (tool && streq(tool, "mam"))
62da2e3ebdSchin {
63da2e3ebdSchin for (n = 0; *path; path++)
64da2e3ebdSchin n = n * 0x63c63cd9L + *path + 0x9c39c33dL;
65da2e3ebdSchin k = key;
66da2e3ebdSchin for (n &= 0xffffffffL; n; n >>= 4)
67da2e3ebdSchin *k++ = let[n & 0xf];
68da2e3ebdSchin *k = 0;
69da2e3ebdSchin }
70da2e3ebdSchin else
71da2e3ebdSchin {
72da2e3ebdSchin for (c = 0; c < elementsof(env); c++)
73da2e3ebdSchin env[c] = 0;
74da2e3ebdSchin n = 0;
75da2e3ebdSchin
76da2e3ebdSchin /*
77da2e3ebdSchin * trailing flags in path
78da2e3ebdSchin */
79da2e3ebdSchin
80da2e3ebdSchin if (flags = strchr(path, ' '))
81da2e3ebdSchin {
82da2e3ebdSchin if (flags == path)
83da2e3ebdSchin flags = 0;
84da2e3ebdSchin else
85da2e3ebdSchin {
86da2e3ebdSchin strcpy(tmp, path);
87da2e3ebdSchin *(flags = tmp + (flags - path)) = 0;
88da2e3ebdSchin path = tmp;
89da2e3ebdSchin }
90da2e3ebdSchin }
91da2e3ebdSchin
92da2e3ebdSchin /*
93da2e3ebdSchin * 3D
94da2e3ebdSchin */
95da2e3ebdSchin
96da2e3ebdSchin if (fs3d(FS3D_TEST) && (c = mount(path, tmp, FS3D_GET|FS3D_ALL|FS3D_SIZE(PATH_MAX), NiL)) > 1 && c < PATH_MAX)
97da2e3ebdSchin path = tmp;
98da2e3ebdSchin
99da2e3ebdSchin /*
100da2e3ebdSchin * preroot
101da2e3ebdSchin */
102da2e3ebdSchin
103da2e3ebdSchin if (attr)
104da2e3ebdSchin attr = strcopy(attr, "PREROOT='");
105da2e3ebdSchin #if FS_PREROOT
106da2e3ebdSchin if (k = getenv(PR_BASE))
107da2e3ebdSchin {
108da2e3ebdSchin if (s = strrchr(k, '/'))
109da2e3ebdSchin k = s + 1;
110da2e3ebdSchin n = memsum(k, strlen(k), n);
111da2e3ebdSchin }
112da2e3ebdSchin if (attr && (getpreroot(attr, path) || getpreroot(attr, NiL)))
113da2e3ebdSchin attr += strlen(attr);
114da2e3ebdSchin #else
115da2e3ebdSchin if ((k = getenv("VIRTUAL_ROOT")) && *k == '/')
116da2e3ebdSchin {
117da2e3ebdSchin n = memsum(k, strlen(k), n);
118da2e3ebdSchin if (attr)
119da2e3ebdSchin attr = strcopy(attr, k);
120da2e3ebdSchin }
121da2e3ebdSchin #endif
122da2e3ebdSchin
123da2e3ebdSchin /*
124da2e3ebdSchin * universe
125da2e3ebdSchin */
126da2e3ebdSchin
127da2e3ebdSchin if (attr)
128da2e3ebdSchin attr = strcopy(attr, "' UNIVERSE='");
129da2e3ebdSchin if (k = astconf("UNIVERSE", NiL, NiL))
130da2e3ebdSchin {
131da2e3ebdSchin n = memsum(k, strlen(k), n);
132da2e3ebdSchin if (attr)
133da2e3ebdSchin attr = strcopy(attr, k);
134da2e3ebdSchin }
135da2e3ebdSchin
136da2e3ebdSchin /*
137da2e3ebdSchin * environment
138da2e3ebdSchin *
139da2e3ebdSchin * ${PROBE_ATTRIBUTES} || ${VERSION_ENVIRONMENT} : list of alternate env vars
140da2e3ebdSchin * ${VERSION_ENVIRONMENT} : list of alternate env vars
141da2e3ebdSchin * ${VERSION_<lang>}
142da2e3ebdSchin * ${VERSION_<base(path)>}
143da2e3ebdSchin * ${<toupper(base(path))>VER}
144da2e3ebdSchin * ${OBJTYPE}
145da2e3ebdSchin */
146da2e3ebdSchin
147da2e3ebdSchin if (attr)
148da2e3ebdSchin *attr++ = '\'';
149da2e3ebdSchin c = 0;
150da2e3ebdSchin usr[c++] = "OBJTYPE";
151da2e3ebdSchin if (!(k = getenv("PROBE_ATTRIBUTES")))
152da2e3ebdSchin k = getenv("VERSION_ENVIRONMENT");
153da2e3ebdSchin if (k)
15434f9b3eeSRoland Mainz while (c < (elementsof(usr) - 1))
155da2e3ebdSchin {
156da2e3ebdSchin while (*k && (*k == ':' || *k == ' '))
157da2e3ebdSchin k++;
158da2e3ebdSchin if (!*k)
159da2e3ebdSchin break;
160da2e3ebdSchin usr[c++] = k;
161da2e3ebdSchin while (*k && *k != ':' && *k != ' ')
162da2e3ebdSchin k++;
163da2e3ebdSchin }
164da2e3ebdSchin usr[c] = 0;
165da2e3ebdSchin ver[0] = (char*)lang;
166da2e3ebdSchin ver[1] = k = (s = strrchr(path, '/')) ? s + 1 : path;
167da2e3ebdSchin s = buf;
168da2e3ebdSchin if (isdigit(*k))
169da2e3ebdSchin {
170da2e3ebdSchin if (*k == '3' && *(k + 1) == 'b')
171da2e3ebdSchin {
172da2e3ebdSchin /*
173da2e3ebdSchin * cuteness never pays
174da2e3ebdSchin */
175da2e3ebdSchin
176da2e3ebdSchin k += 2;
177da2e3ebdSchin *s++ = 'B';
178da2e3ebdSchin *s++ = 'B';
179da2e3ebdSchin *s++ = 'B';
180da2e3ebdSchin }
181da2e3ebdSchin else
182da2e3ebdSchin *s++ = 'U';
183da2e3ebdSchin }
184da2e3ebdSchin for (; (c = *k) && s < &buf[sizeof(buf) - 1]; k++)
185da2e3ebdSchin {
186da2e3ebdSchin if (!isalnum(c))
187da2e3ebdSchin c = '_';
188da2e3ebdSchin else if (islower(c))
189da2e3ebdSchin c = toupper(c);
190da2e3ebdSchin *s++ = c;
191da2e3ebdSchin }
192da2e3ebdSchin *s = 0;
193da2e3ebdSchin for (p = environ; *p; p++)
194da2e3ebdSchin {
195da2e3ebdSchin s = "VERSION_";
196da2e3ebdSchin for (k = *p; *k && *k == *s; k++, s++);
197da2e3ebdSchin if (*k && !*s)
198da2e3ebdSchin {
199da2e3ebdSchin for (c = 0; c < elementsof(ver); c++)
200da2e3ebdSchin if (!env[c] && (s = ver[c]))
201da2e3ebdSchin {
202da2e3ebdSchin for (t = k; *t && *t != '=' && *t++ == *s; s++);
203da2e3ebdSchin if (*t == '=' && (!*s || (s - ver[c]) > 1))
204da2e3ebdSchin {
205da2e3ebdSchin env[c] = *p;
206da2e3ebdSchin goto found;
207da2e3ebdSchin }
208da2e3ebdSchin }
209da2e3ebdSchin }
210da2e3ebdSchin if (!env[2])
211da2e3ebdSchin {
212da2e3ebdSchin s = buf;
213da2e3ebdSchin for (k = *p; *k && *s++ == *k; k++);
214da2e3ebdSchin if ((s - buf) > 2 && k[0] == 'V' && k[1] == 'E' && k[2] == 'R' && k[3] == '=')
215da2e3ebdSchin {
216da2e3ebdSchin env[2] = *p;
217da2e3ebdSchin goto found;
218da2e3ebdSchin }
219da2e3ebdSchin }
220da2e3ebdSchin for (c = 0; c < elementsof(usr) && (s = usr[c]); c++)
221da2e3ebdSchin if (!env[c + elementsof(env) - elementsof(usr)])
222da2e3ebdSchin {
223da2e3ebdSchin for (k = *p; *k && *k == *s; k++, s++);
224da2e3ebdSchin if (*k == '=' && (!*s || *s == ':' || *s == ' '))
225da2e3ebdSchin {
226da2e3ebdSchin env[c + elementsof(env) - elementsof(usr)] = *p;
227da2e3ebdSchin goto found;
228da2e3ebdSchin }
229da2e3ebdSchin }
230da2e3ebdSchin found: ;
231da2e3ebdSchin }
232da2e3ebdSchin for (c = 0; c < elementsof(env); c++)
233da2e3ebdSchin if (k = env[c])
234da2e3ebdSchin {
235da2e3ebdSchin if (attr)
236da2e3ebdSchin {
237da2e3ebdSchin *attr++ = ' ';
238da2e3ebdSchin while ((*attr++ = *k++) != '=');
239da2e3ebdSchin *attr++ = '\'';
240da2e3ebdSchin attr = strcopy(attr, k);
241da2e3ebdSchin *attr++ = '\'';
242da2e3ebdSchin }
243da2e3ebdSchin else
244da2e3ebdSchin while (*k && *k++ != '=');
245da2e3ebdSchin n = memsum(k, strlen(k), n);
246da2e3ebdSchin }
247da2e3ebdSchin if (attr)
248da2e3ebdSchin {
249da2e3ebdSchin attr = strcopy(attr, " ATTRIBUTES='PREROOT UNIVERSE");
250da2e3ebdSchin for (c = 0; c < elementsof(env); c++)
251da2e3ebdSchin if (k = env[c])
252da2e3ebdSchin {
253da2e3ebdSchin *attr++ = ' ';
254da2e3ebdSchin while ((*attr = *k++) != '=')
255da2e3ebdSchin attr++;
256da2e3ebdSchin }
257da2e3ebdSchin *attr++ = '\'';
258da2e3ebdSchin *attr = 0;
259da2e3ebdSchin }
260da2e3ebdSchin
261da2e3ebdSchin /*
262da2e3ebdSchin * now the normal stuff
263da2e3ebdSchin */
264da2e3ebdSchin
265da2e3ebdSchin if (flags)
266da2e3ebdSchin *flags = ' ';
267da2e3ebdSchin s = path + strlen(path);
268da2e3ebdSchin sfsprintf(key, 15, "%08lX", memsum(path, s - path, n));
269da2e3ebdSchin k = key + 14;
270da2e3ebdSchin *k = 0;
271da2e3ebdSchin if (!flags)
272da2e3ebdSchin t = path;
273da2e3ebdSchin else if ((t = s - 4) < flags)
274da2e3ebdSchin t = flags + 1;
275da2e3ebdSchin for (;;)
276da2e3ebdSchin {
277da2e3ebdSchin if (--s < t)
278da2e3ebdSchin {
279da2e3ebdSchin if (t == path)
280da2e3ebdSchin break;
281da2e3ebdSchin s = flags - 2;
282da2e3ebdSchin t = path;
283da2e3ebdSchin }
284da2e3ebdSchin if (*s != '/' && *s != ' ')
285da2e3ebdSchin {
286da2e3ebdSchin *--k = *s;
287da2e3ebdSchin if (k <= key + 8)
288da2e3ebdSchin break;
289da2e3ebdSchin }
290da2e3ebdSchin }
291da2e3ebdSchin while (k > key + 8)
292da2e3ebdSchin *--k = '.';
293da2e3ebdSchin }
294da2e3ebdSchin return key == buf ? strdup(key) : key;
295da2e3ebdSchin }
296