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