xref: /titanic_41/usr/src/lib/libast/common/path/pathkey.c (revision fd06a699040f011e80ab8ac5213bb0a47858e69b)
1 /***********************************************************************
2 *                                                                      *
3 *               This software is part of the ast package               *
4 *           Copyright (c) 1985-2007 AT&T Knowledge Ventures            *
5 *                      and is licensed under the                       *
6 *                  Common Public License, Version 1.0                  *
7 *                      by AT&T Knowledge Ventures                      *
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))
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