summaryrefslogtreecommitdiff
path: root/usr/src/lib/libast/common/path/pathkey.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/lib/libast/common/path/pathkey.c')
-rw-r--r--usr/src/lib/libast/common/path/pathkey.c295
1 files changed, 295 insertions, 0 deletions
diff --git a/usr/src/lib/libast/common/path/pathkey.c b/usr/src/lib/libast/common/path/pathkey.c
new file mode 100644
index 0000000000..ddbb9e7659
--- /dev/null
+++ b/usr/src/lib/libast/common/path/pathkey.c
@@ -0,0 +1,295 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2007 AT&T Knowledge Ventures *
+* and is licensed under the *
+* Common Public License, Version 1.0 *
+* by AT&T Knowledge Ventures *
+* *
+* A copy of the License is available at *
+* http://www.opensource.org/licenses/cpl1.0.txt *
+* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Bell Laboratories
+ *
+ * generate 14 char lookup key for lang path in key
+ * based on 32-bit checksum on path
+ *
+ * if key==0 then space is malloc'd
+ * if attr != 0 then attribute var assignments placed here:
+ * ATTRIBUTES list of attribute names
+ */
+
+#include <ast.h>
+#include <ctype.h>
+#include <fs3d.h>
+#include <preroot.h>
+
+char*
+pathkey(char* key, char* attr, const char* lang, const char* tool, const char* apath)
+{
+ register char* path = (char*)apath;
+ register char* s;
+ register char* k;
+ char* t;
+ char* flags;
+ char** p;
+ int c;
+ unsigned long n;
+ char buf[15];
+ char* usr[16];
+ char* env[elementsof(usr) + 3];
+ char* ver[2];
+ char tmp[PATH_MAX];
+
+ static char let[] = "ABCDEFGHIJKLMNOP";
+
+ if (!key)
+ key = buf;
+ if (tool && streq(tool, "mam"))
+ {
+ for (n = 0; *path; path++)
+ n = n * 0x63c63cd9L + *path + 0x9c39c33dL;
+ k = key;
+ for (n &= 0xffffffffL; n; n >>= 4)
+ *k++ = let[n & 0xf];
+ *k = 0;
+ }
+ else
+ {
+ for (c = 0; c < elementsof(env); c++)
+ env[c] = 0;
+ n = 0;
+
+ /*
+ * trailing flags in path
+ */
+
+ if (flags = strchr(path, ' '))
+ {
+ if (flags == path)
+ flags = 0;
+ else
+ {
+ strcpy(tmp, path);
+ *(flags = tmp + (flags - path)) = 0;
+ path = tmp;
+ }
+ }
+
+ /*
+ * 3D
+ */
+
+ if (fs3d(FS3D_TEST) && (c = mount(path, tmp, FS3D_GET|FS3D_ALL|FS3D_SIZE(PATH_MAX), NiL)) > 1 && c < PATH_MAX)
+ path = tmp;
+
+ /*
+ * preroot
+ */
+
+ if (attr)
+ attr = strcopy(attr, "PREROOT='");
+#if FS_PREROOT
+ if (k = getenv(PR_BASE))
+ {
+ if (s = strrchr(k, '/'))
+ k = s + 1;
+ n = memsum(k, strlen(k), n);
+ }
+ if (attr && (getpreroot(attr, path) || getpreroot(attr, NiL)))
+ attr += strlen(attr);
+#else
+ if ((k = getenv("VIRTUAL_ROOT")) && *k == '/')
+ {
+ n = memsum(k, strlen(k), n);
+ if (attr)
+ attr = strcopy(attr, k);
+ }
+#endif
+
+ /*
+ * universe
+ */
+
+ if (attr)
+ attr = strcopy(attr, "' UNIVERSE='");
+ if (k = astconf("UNIVERSE", NiL, NiL))
+ {
+ n = memsum(k, strlen(k), n);
+ if (attr)
+ attr = strcopy(attr, k);
+ }
+
+ /*
+ * environment
+ *
+ * ${PROBE_ATTRIBUTES} || ${VERSION_ENVIRONMENT} : list of alternate env vars
+ * ${VERSION_ENVIRONMENT} : list of alternate env vars
+ * ${VERSION_<lang>}
+ * ${VERSION_<base(path)>}
+ * ${<toupper(base(path))>VER}
+ * ${OBJTYPE}
+ */
+
+ if (attr)
+ *attr++ = '\'';
+ c = 0;
+ usr[c++] = "OBJTYPE";
+ if (!(k = getenv("PROBE_ATTRIBUTES")))
+ k = getenv("VERSION_ENVIRONMENT");
+ if (k)
+ while (c < elementsof(usr))
+ {
+ while (*k && (*k == ':' || *k == ' '))
+ k++;
+ if (!*k)
+ break;
+ usr[c++] = k;
+ while (*k && *k != ':' && *k != ' ')
+ k++;
+ }
+ usr[c] = 0;
+ ver[0] = (char*)lang;
+ ver[1] = k = (s = strrchr(path, '/')) ? s + 1 : path;
+ s = buf;
+ if (isdigit(*k))
+ {
+ if (*k == '3' && *(k + 1) == 'b')
+ {
+ /*
+ * cuteness never pays
+ */
+
+ k += 2;
+ *s++ = 'B';
+ *s++ = 'B';
+ *s++ = 'B';
+ }
+ else
+ *s++ = 'U';
+ }
+ for (; (c = *k) && s < &buf[sizeof(buf) - 1]; k++)
+ {
+ if (!isalnum(c))
+ c = '_';
+ else if (islower(c))
+ c = toupper(c);
+ *s++ = c;
+ }
+ *s = 0;
+ for (p = environ; *p; p++)
+ {
+ s = "VERSION_";
+ for (k = *p; *k && *k == *s; k++, s++);
+ if (*k && !*s)
+ {
+ for (c = 0; c < elementsof(ver); c++)
+ if (!env[c] && (s = ver[c]))
+ {
+ for (t = k; *t && *t != '=' && *t++ == *s; s++);
+ if (*t == '=' && (!*s || (s - ver[c]) > 1))
+ {
+ env[c] = *p;
+ goto found;
+ }
+ }
+ }
+ if (!env[2])
+ {
+ s = buf;
+ for (k = *p; *k && *s++ == *k; k++);
+ if ((s - buf) > 2 && k[0] == 'V' && k[1] == 'E' && k[2] == 'R' && k[3] == '=')
+ {
+ env[2] = *p;
+ goto found;
+ }
+ }
+ for (c = 0; c < elementsof(usr) && (s = usr[c]); c++)
+ if (!env[c + elementsof(env) - elementsof(usr)])
+ {
+ for (k = *p; *k && *k == *s; k++, s++);
+ if (*k == '=' && (!*s || *s == ':' || *s == ' '))
+ {
+ env[c + elementsof(env) - elementsof(usr)] = *p;
+ goto found;
+ }
+ }
+ found: ;
+ }
+ for (c = 0; c < elementsof(env); c++)
+ if (k = env[c])
+ {
+ if (attr)
+ {
+ *attr++ = ' ';
+ while ((*attr++ = *k++) != '=');
+ *attr++ = '\'';
+ attr = strcopy(attr, k);
+ *attr++ = '\'';
+ }
+ else
+ while (*k && *k++ != '=');
+ n = memsum(k, strlen(k), n);
+ }
+ if (attr)
+ {
+ attr = strcopy(attr, " ATTRIBUTES='PREROOT UNIVERSE");
+ for (c = 0; c < elementsof(env); c++)
+ if (k = env[c])
+ {
+ *attr++ = ' ';
+ while ((*attr = *k++) != '=')
+ attr++;
+ }
+ *attr++ = '\'';
+ *attr = 0;
+ }
+
+ /*
+ * now the normal stuff
+ */
+
+ if (flags)
+ *flags = ' ';
+ s = path + strlen(path);
+ sfsprintf(key, 15, "%08lX", memsum(path, s - path, n));
+ k = key + 14;
+ *k = 0;
+ if (!flags)
+ t = path;
+ else if ((t = s - 4) < flags)
+ t = flags + 1;
+ for (;;)
+ {
+ if (--s < t)
+ {
+ if (t == path)
+ break;
+ s = flags - 2;
+ t = path;
+ }
+ if (*s != '/' && *s != ' ')
+ {
+ *--k = *s;
+ if (k <= key + 8)
+ break;
+ }
+ }
+ while (k > key + 8)
+ *--k = '.';
+ }
+ return key == buf ? strdup(key) : key;
+}