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