1N/A/***********************************************************************
1N/A* *
1N/A* This software is part of the ast package *
1N/A* Copyright (c) 1985-2011 AT&T Intellectual Property *
1N/A* and is licensed under the *
1N/A* Common Public License, Version 1.0 *
1N/A* by AT&T Intellectual Property *
1N/A* *
1N/A* A copy of the License is available at *
1N/A* http://www.opensource.org/licenses/cpl1.0.txt *
1N/A* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
1N/A* *
1N/A* Information and Software Systems Research *
1N/A* AT&T Research *
1N/A* Florham Park NJ *
1N/A* *
1N/A* Glenn Fowler <gsf@research.att.com> *
1N/A* David Korn <dgk@research.att.com> *
1N/A* Phong Vo <kpv@research.att.com> *
1N/A* *
1N/A***********************************************************************/
1N/A#pragma prototyped
1N/A/*
1N/A * Glenn Fowler
1N/A * AT&T Bell Laboratories
1N/A *
1N/A * generate 14 char lookup key for lang path in key
1N/A * based on 32-bit checksum on path
1N/A *
1N/A * if key==0 then space is malloc'd
1N/A * if attr != 0 then attribute var assignments placed here:
1N/A * ATTRIBUTES list of attribute names
1N/A */
1N/A
1N/A#define _AST_API_H 1
1N/A
1N/A#include <ast.h>
1N/A#include <ctype.h>
1N/A#include <fs3d.h>
1N/A#include <preroot.h>
1N/A#include <ls.h>
1N/A
1N/Achar*
1N/Apathkey(char* key, char* attr, const char* lang, const char* tool, const char* path)
1N/A{
1N/A return pathkey_20100601(lang, tool, path, key, 16, attr, PATH_MAX);
1N/A}
1N/A
1N/A#undef _AST_API_H
1N/A
1N/A#include <ast_api.h>
1N/A
1N/Achar*
1N/Apathkey_20100601(const char* lang, const char* tool, const char* apath, char* key, size_t keysize, char* attr, size_t attrsize)
1N/A{
1N/A register char* path = (char*)apath;
1N/A register char* s;
1N/A register char* k;
1N/A char* t;
1N/A char* flags;
1N/A char** p;
1N/A int c;
1N/A unsigned long n;
1N/A char buf[15];
1N/A char* usr[16];
1N/A char* env[elementsof(usr) + 3];
1N/A char* ver[2];
1N/A char tmp[PATH_MAX];
1N/A#if _UWIN
1N/A struct stat st;
1N/A#endif
1N/A
1N/A static char let[] = "ABCDEFGHIJKLMNOP";
1N/A
1N/A if (!key)
1N/A key = buf;
1N/A if (tool && streq(tool, "mam"))
1N/A {
1N/A for (n = 0; *path; path++)
1N/A n = n * 0x63c63cd9L + *path + 0x9c39c33dL;
1N/A k = key;
1N/A for (n &= 0xffffffffL; n; n >>= 4)
1N/A *k++ = let[n & 0xf];
1N/A *k = 0;
1N/A }
1N/A else
1N/A {
1N/A for (c = 0; c < elementsof(env); c++)
1N/A env[c] = 0;
1N/A n = 0;
1N/A
1N/A /*
1N/A * trailing flags in path
1N/A */
1N/A
1N/A if (flags = strchr(path, ' '))
1N/A {
1N/A if (flags == path)
1N/A flags = 0;
1N/A else
1N/A {
1N/A strlcpy(tmp, path, sizeof(tmp));
1N/A *(flags = tmp + (flags - path)) = 0;
1N/A path = tmp;
1N/A }
1N/A }
1N/A
1N/A /*
1N/A * 3D
1N/A */
1N/A
1N/A if (!flags && fs3d(FS3D_TEST) && (c = mount(path, tmp, FS3D_GET|FS3D_ALL|FS3D_SIZE(PATH_MAX), NiL)) > 1 && c < PATH_MAX)
1N/A path = tmp;
1N/A
1N/A /*
1N/A * preroot
1N/A */
1N/A
1N/A if (attr)
1N/A attr = strcopy(attr, "PREROOT='");
1N/A#if FS_PREROOT
1N/A if (k = getenv(PR_BASE))
1N/A {
1N/A if (s = strrchr(k, '/'))
1N/A k = s + 1;
1N/A n = memsum(k, strlen(k), n);
1N/A }
1N/A if (attr && (getpreroot(attr, path) || getpreroot(attr, NiL)))
1N/A attr += strlen(attr);
1N/A#else
1N/A if ((k = getenv("VIRTUAL_ROOT")) && *k == '/')
1N/A {
1N/A n = memsum(k, strlen(k), n);
1N/A if (attr)
1N/A attr = strcopy(attr, k);
1N/A }
1N/A#endif
1N/A#if _UWIN
1N/A if (!stat("/", &st) && st.st_ino != 8 * sizeof(char*) && (st.st_ino == 32 || st.st_ino == 64))
1N/A {
1N/A k = sizeof(char*) == 4 ? "/64" : "/32";
1N/A n = memsum(k, strlen(k), n);
1N/A if (attr)
1N/A attr = strcopy(attr, k);
1N/A }
1N/A#endif
1N/A
1N/A /*
1N/A * universe
1N/A */
1N/A
1N/A if (attr)
1N/A attr = strcopy(attr, "' UNIVERSE='");
1N/A if (k = astconf("UNIVERSE", NiL, NiL))
1N/A {
1N/A n = memsum(k, strlen(k), n);
1N/A if (attr)
1N/A attr = strcopy(attr, k);
1N/A }
1N/A
1N/A /*
1N/A * environment
1N/A *
1N/A * ${PROBE_ATTRIBUTES} || ${VERSION_ENVIRONMENT} : list of alternate env vars
1N/A * ${VERSION_ENVIRONMENT} : list of alternate env vars
1N/A * ${VERSION_<lang>}
1N/A * ${VERSION_<base(path)>}
1N/A * ${<toupper(base(path))>VER}
1N/A * ${OBJTYPE}
1N/A */
1N/A
1N/A if (attr)
1N/A *attr++ = '\'';
1N/A c = 0;
1N/A usr[c++] = "OBJTYPE";
1N/A if (!(k = getenv("PROBE_ATTRIBUTES")))
1N/A k = getenv("VERSION_ENVIRONMENT");
1N/A if (k)
1N/A while (c < (elementsof(usr) - 1))
1N/A {
1N/A while (*k && (*k == ':' || *k == ' '))
1N/A k++;
1N/A if (!*k)
1N/A break;
1N/A usr[c++] = k;
1N/A while (*k && *k != ':' && *k != ' ')
1N/A k++;
1N/A }
1N/A usr[c] = 0;
1N/A ver[0] = (char*)lang;
1N/A ver[1] = k = (s = strrchr(path, '/')) ? s + 1 : path;
1N/A s = buf;
1N/A if (isdigit(*k))
1N/A {
1N/A if (*k == '3' && *(k + 1) == 'b')
1N/A {
1N/A /*
1N/A * cuteness never pays
1N/A */
1N/A
1N/A k += 2;
1N/A *s++ = 'B';
1N/A *s++ = 'B';
1N/A *s++ = 'B';
1N/A }
1N/A else
1N/A *s++ = 'U';
1N/A }
1N/A for (; (c = *k) && s < &buf[sizeof(buf) - 1]; k++)
1N/A {
1N/A if (!isalnum(c))
1N/A c = '_';
1N/A else if (islower(c))
1N/A c = toupper(c);
1N/A *s++ = c;
1N/A }
1N/A *s = 0;
1N/A for (p = environ; *p; p++)
1N/A {
1N/A s = "VERSION_";
1N/A for (k = *p; *k && *k == *s; k++, s++);
1N/A if (*k && !*s)
1N/A {
1N/A for (c = 0; c < elementsof(ver); c++)
1N/A if (!env[c] && (s = ver[c]))
1N/A {
1N/A for (t = k; *t && *t != '=' && *t++ == *s; s++);
1N/A if (*t == '=' && (!*s || (s - ver[c]) > 1))
1N/A {
1N/A env[c] = *p;
1N/A goto found;
1N/A }
1N/A }
1N/A }
1N/A if (!env[2])
1N/A {
1N/A s = buf;
1N/A for (k = *p; *k && *s++ == *k; k++);
1N/A if ((s - buf) > 2 && k[0] == 'V' && k[1] == 'E' && k[2] == 'R' && k[3] == '=')
1N/A {
1N/A env[2] = *p;
1N/A goto found;
1N/A }
1N/A }
1N/A for (c = 0; c < elementsof(usr) && (s = usr[c]); c++)
1N/A if (!env[c + elementsof(env) - elementsof(usr)])
1N/A {
1N/A for (k = *p; *k && *k == *s; k++, s++);
1N/A if (*k == '=' && (!*s || *s == ':' || *s == ' '))
1N/A {
1N/A env[c + elementsof(env) - elementsof(usr)] = *p;
1N/A goto found;
1N/A }
1N/A }
1N/A found: ;
1N/A }
1N/A for (c = 0; c < elementsof(env); c++)
1N/A if (k = env[c])
1N/A {
1N/A if (attr)
1N/A {
1N/A *attr++ = ' ';
1N/A while ((*attr++ = *k++) != '=');
1N/A *attr++ = '\'';
1N/A attr = strcopy(attr, k);
1N/A *attr++ = '\'';
1N/A }
1N/A else
1N/A while (*k && *k++ != '=');
1N/A n = memsum(k, strlen(k), n);
1N/A }
1N/A if (attr)
1N/A {
1N/A attr = strcopy(attr, " ATTRIBUTES='PREROOT UNIVERSE");
1N/A for (c = 0; c < elementsof(env); c++)
1N/A if (k = env[c])
1N/A {
1N/A *attr++ = ' ';
1N/A while ((*attr = *k++) != '=')
1N/A attr++;
1N/A }
1N/A *attr++ = '\'';
1N/A *attr = 0;
1N/A }
1N/A
1N/A /*
1N/A * now the normal stuff
1N/A */
1N/A
1N/A if (flags)
1N/A *flags = ' ';
1N/A s = path + strlen(path);
1N/A sfsprintf(key, 15, "%08lX", memsum(path, s - path, n));
1N/A k = key + 14;
1N/A *k = 0;
1N/A if (!flags)
1N/A t = path;
1N/A else if ((t = s - 4) < flags)
1N/A t = flags + 1;
1N/A for (;;)
1N/A {
1N/A if (--s < t)
1N/A {
1N/A if (t == path)
1N/A break;
1N/A s = flags - 2;
1N/A t = path;
1N/A }
1N/A if (*s != '/' && *s != ' ')
1N/A {
1N/A *--k = *s;
1N/A if (k <= key + 8)
1N/A break;
1N/A }
1N/A }
1N/A while (k > key + 8)
1N/A *--k = '.';
1N/A }
1N/A return key == buf ? strdup(key) : key;
1N/A}