xref: /onnv-gate/usr/src/lib/libast/common/path/pathkey.c (revision 12068:08a39a083754)
14887Schin /***********************************************************************
24887Schin *                                                                      *
34887Schin *               This software is part of the ast package               *
4*12068SRoger.Faulkner@Oracle.COM *          Copyright (c) 1985-2010 AT&T Intellectual Property          *
54887Schin *                      and is licensed under the                       *
64887Schin *                  Common Public License, Version 1.0                  *
78462SApril.Chin@Sun.COM *                    by AT&T Intellectual Property                     *
84887Schin *                                                                      *
94887Schin *                A copy of the License is available at                 *
104887Schin *            http://www.opensource.org/licenses/cpl1.0.txt             *
114887Schin *         (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9)         *
124887Schin *                                                                      *
134887Schin *              Information and Software Systems Research               *
144887Schin *                            AT&T Research                             *
154887Schin *                           Florham Park NJ                            *
164887Schin *                                                                      *
174887Schin *                 Glenn Fowler <gsf@research.att.com>                  *
184887Schin *                  David Korn <dgk@research.att.com>                   *
194887Schin *                   Phong Vo <kpv@research.att.com>                    *
204887Schin *                                                                      *
214887Schin ***********************************************************************/
224887Schin #pragma prototyped
234887Schin /*
244887Schin  * Glenn Fowler
254887Schin  * AT&T Bell Laboratories
264887Schin  *
274887Schin  * generate 14 char lookup key for lang path in key
284887Schin  * based on 32-bit checksum on path
294887Schin  *
304887Schin  * if key==0 then space is malloc'd
314887Schin  * if attr != 0 then attribute var assignments placed here:
324887Schin  *	ATTRIBUTES	list of attribute names
334887Schin  */
344887Schin 
354887Schin #include <ast.h>
364887Schin #include <ctype.h>
374887Schin #include <fs3d.h>
384887Schin #include <preroot.h>
394887Schin 
404887Schin char*
pathkey(char * key,char * attr,const char * lang,const char * tool,const char * apath)414887Schin pathkey(char* key, char* attr, const char* lang, const char* tool, const char* apath)
424887Schin {
434887Schin 	register char*		path = (char*)apath;
444887Schin 	register char*		s;
454887Schin 	register char*		k;
464887Schin 	char*			t;
474887Schin 	char*			flags;
484887Schin 	char**			p;
494887Schin 	int			c;
504887Schin 	unsigned long		n;
514887Schin 	char			buf[15];
524887Schin 	char*			usr[16];
534887Schin 	char*			env[elementsof(usr) + 3];
544887Schin 	char*			ver[2];
554887Schin 	char			tmp[PATH_MAX];
564887Schin 
574887Schin 	static char		let[] = "ABCDEFGHIJKLMNOP";
584887Schin 
594887Schin 	if (!key)
604887Schin 		key = buf;
614887Schin 	if (tool && streq(tool, "mam"))
624887Schin 	{
634887Schin 		for (n = 0; *path; path++)
644887Schin 			n = n * 0x63c63cd9L + *path + 0x9c39c33dL;
654887Schin 		k = key;
664887Schin 		for (n &= 0xffffffffL; n; n >>= 4)
674887Schin 			*k++ = let[n & 0xf];
684887Schin 		*k = 0;
694887Schin 	}
704887Schin 	else
714887Schin 	{
724887Schin 		for (c = 0; c < elementsof(env); c++)
734887Schin 			env[c] = 0;
744887Schin 		n = 0;
754887Schin 
764887Schin 		/*
774887Schin 		 * trailing flags in path
784887Schin 		 */
794887Schin 
804887Schin 		if (flags = strchr(path, ' '))
814887Schin 		{
824887Schin 			if (flags == path)
834887Schin 				flags = 0;
844887Schin 			else
854887Schin 			{
864887Schin 				strcpy(tmp, path);
874887Schin 				*(flags = tmp + (flags - path)) = 0;
884887Schin 				path = tmp;
894887Schin 			}
904887Schin 		}
914887Schin 
924887Schin 		/*
934887Schin 		 * 3D
944887Schin 		 */
954887Schin 
964887Schin 		if (fs3d(FS3D_TEST) && (c = mount(path, tmp, FS3D_GET|FS3D_ALL|FS3D_SIZE(PATH_MAX), NiL)) > 1 && c < PATH_MAX)
974887Schin 			path = tmp;
984887Schin 
994887Schin 		/*
1004887Schin 		 * preroot
1014887Schin 		 */
1024887Schin 
1034887Schin 		if (attr)
1044887Schin 			attr = strcopy(attr, "PREROOT='");
1054887Schin #if FS_PREROOT
1064887Schin 		if (k = getenv(PR_BASE))
1074887Schin 		{
1084887Schin 			if (s = strrchr(k, '/'))
1094887Schin 				k = s + 1;
1104887Schin 			n = memsum(k, strlen(k), n);
1114887Schin 		}
1124887Schin 		if (attr && (getpreroot(attr, path) || getpreroot(attr, NiL)))
1134887Schin 			attr += strlen(attr);
1144887Schin #else
1154887Schin 		if ((k = getenv("VIRTUAL_ROOT")) && *k == '/')
1164887Schin 		{
1174887Schin 			n = memsum(k, strlen(k), n);
1184887Schin 			if (attr)
1194887Schin 				attr = strcopy(attr, k);
1204887Schin 		}
1214887Schin #endif
1224887Schin 
1234887Schin 		/*
1244887Schin 		 * universe
1254887Schin 		 */
1264887Schin 
1274887Schin 		if (attr)
1284887Schin 			attr = strcopy(attr, "' UNIVERSE='");
1294887Schin 		if (k = astconf("UNIVERSE", NiL, NiL))
1304887Schin 		{
1314887Schin 			n = memsum(k, strlen(k), n);
1324887Schin 			if (attr)
1334887Schin 				attr = strcopy(attr, k);
1344887Schin 		}
1354887Schin 
1364887Schin 		/*
1374887Schin 		 * environment
1384887Schin 		 *
1394887Schin 		 *	${PROBE_ATTRIBUTES} || ${VERSION_ENVIRONMENT} : list of alternate env vars
1404887Schin 		 *	${VERSION_ENVIRONMENT}	: list of alternate env vars
1414887Schin 		 *	${VERSION_<lang>}
1424887Schin 		 *	${VERSION_<base(path)>}
1434887Schin 		 *	${<toupper(base(path))>VER}
1444887Schin 		 *	${OBJTYPE}
1454887Schin 		 */
1464887Schin 
1474887Schin 		if (attr)
1484887Schin 			*attr++ = '\'';
1494887Schin 		c = 0;
1504887Schin 		usr[c++] = "OBJTYPE";
1514887Schin 		if (!(k = getenv("PROBE_ATTRIBUTES")))
1524887Schin 			k = getenv("VERSION_ENVIRONMENT");
1534887Schin 		if (k)
15410898Sroland.mainz@nrubsig.org 			while (c < (elementsof(usr) - 1))
1554887Schin 			{
1564887Schin 				while (*k && (*k == ':' || *k == ' '))
1574887Schin 					k++;
1584887Schin 				if (!*k)
1594887Schin 					break;
1604887Schin 				usr[c++] = k;
1614887Schin 				while (*k && *k != ':' && *k != ' ')
1624887Schin 					k++;
1634887Schin 			}
1644887Schin 		usr[c] = 0;
1654887Schin 		ver[0] = (char*)lang;
1664887Schin 		ver[1] = k = (s = strrchr(path, '/')) ? s + 1 : path;
1674887Schin 		s = buf;
1684887Schin 		if (isdigit(*k))
1694887Schin 		{
1704887Schin 			if (*k == '3' && *(k + 1) == 'b')
1714887Schin 			{
1724887Schin 				/*
1734887Schin 				 * cuteness never pays
1744887Schin 				 */
1754887Schin 
1764887Schin 				k += 2;
1774887Schin 				*s++ = 'B';
1784887Schin 				*s++ = 'B';
1794887Schin 				*s++ = 'B';
1804887Schin 			}
1814887Schin 			else
1824887Schin 				*s++ = 'U';
1834887Schin 		}
1844887Schin 		for (; (c = *k) && s < &buf[sizeof(buf) - 1]; k++)
1854887Schin 		{
1864887Schin 			if (!isalnum(c))
1874887Schin 				c = '_';
1884887Schin 			else if (islower(c))
1894887Schin 				c = toupper(c);
1904887Schin 			*s++ = c;
1914887Schin 		}
1924887Schin 		*s = 0;
1934887Schin 		for (p = environ; *p; p++)
1944887Schin 		{
1954887Schin 			s = "VERSION_";
1964887Schin 			for (k = *p; *k && *k == *s; k++, s++);
1974887Schin 			if (*k && !*s)
1984887Schin 			{
1994887Schin 				for (c = 0; c < elementsof(ver); c++)
2004887Schin 					if (!env[c] && (s = ver[c]))
2014887Schin 					{
2024887Schin 						for (t = k; *t && *t != '=' && *t++ == *s; s++);
2034887Schin 						if (*t == '=' && (!*s || (s - ver[c]) > 1))
2044887Schin 						{
2054887Schin 							env[c] = *p;
2064887Schin 							goto found;
2074887Schin 						}
2084887Schin 					}
2094887Schin 			}
2104887Schin 			if (!env[2])
2114887Schin 			{
2124887Schin 				s = buf;
2134887Schin 				for (k = *p; *k && *s++ == *k; k++);
2144887Schin 				if ((s - buf) > 2 && k[0] == 'V' && k[1] == 'E' && k[2] == 'R' && k[3] == '=')
2154887Schin 				{
2164887Schin 					env[2] = *p;
2174887Schin 					goto found;
2184887Schin 				}
2194887Schin 			}
2204887Schin 			for (c = 0; c < elementsof(usr) && (s = usr[c]); c++)
2214887Schin 				if (!env[c + elementsof(env) - elementsof(usr)])
2224887Schin 				{
2234887Schin 					for (k = *p; *k && *k == *s; k++, s++);
2244887Schin 					if (*k == '=' && (!*s || *s == ':' || *s == ' '))
2254887Schin 					{
2264887Schin 						env[c + elementsof(env) - elementsof(usr)] = *p;
2274887Schin 						goto found;
2284887Schin 					}
2294887Schin 				}
2304887Schin 		found:	;
2314887Schin 		}
2324887Schin 		for (c = 0; c < elementsof(env); c++)
2334887Schin 			if (k = env[c])
2344887Schin 			{
2354887Schin 				if (attr)
2364887Schin 				{
2374887Schin 					*attr++ = ' ';
2384887Schin 					while ((*attr++ = *k++) != '=');
2394887Schin 					*attr++ = '\'';
2404887Schin 					attr = strcopy(attr, k);
2414887Schin 					*attr++ = '\'';
2424887Schin 				}
2434887Schin 				else
2444887Schin 					while (*k && *k++ != '=');
2454887Schin 				n = memsum(k, strlen(k), n);
2464887Schin 			}
2474887Schin 		if (attr)
2484887Schin 		{
2494887Schin 			attr = strcopy(attr, " ATTRIBUTES='PREROOT UNIVERSE");
2504887Schin 			for (c = 0; c < elementsof(env); c++)
2514887Schin 				if (k = env[c])
2524887Schin 				{
2534887Schin 					*attr++ = ' ';
2544887Schin 					while ((*attr = *k++) != '=')
2554887Schin 						attr++;
2564887Schin 				}
2574887Schin 			*attr++ = '\'';
2584887Schin 			*attr = 0;
2594887Schin 		}
2604887Schin 
2614887Schin 		/*
2624887Schin 		 * now the normal stuff
2634887Schin 		 */
2644887Schin 
2654887Schin 		if (flags)
2664887Schin 			*flags = ' ';
2674887Schin 		s = path + strlen(path);
2684887Schin 		sfsprintf(key, 15, "%08lX", memsum(path, s - path, n));
2694887Schin 		k = key + 14;
2704887Schin 		*k = 0;
2714887Schin 		if (!flags)
2724887Schin 			t = path;
2734887Schin 		else if ((t = s - 4) < flags)
2744887Schin 			t = flags + 1;
2754887Schin 		for (;;)
2764887Schin 		{
2774887Schin 			if (--s < t)
2784887Schin 			{
2794887Schin 				if (t == path)
2804887Schin 					break;
2814887Schin 				s = flags - 2;
2824887Schin 				t = path;
2834887Schin 			}
2844887Schin 			if (*s != '/' && *s != ' ')
2854887Schin 			{
2864887Schin 				*--k = *s;
2874887Schin 				if (k <= key + 8)
2884887Schin 					break;
2894887Schin 			}
2904887Schin 		}
2914887Schin 		while (k > key + 8)
2924887Schin 			*--k = '.';
2934887Schin 	}
2944887Schin 	return key == buf ? strdup(key) : key;
2954887Schin }
296