summaryrefslogtreecommitdiff
path: root/usr/src/lib/libpkg/common/mappath.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/lib/libpkg/common/mappath.c')
-rw-r--r--usr/src/lib/libpkg/common/mappath.c236
1 files changed, 236 insertions, 0 deletions
diff --git a/usr/src/lib/libpkg/common/mappath.c b/usr/src/lib/libpkg/common/mappath.c
new file mode 100644
index 0000000000..b0ae99d827
--- /dev/null
+++ b/usr/src/lib/libpkg/common/mappath.c
@@ -0,0 +1,236 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
+/* All Rights Reserved */
+
+
+
+#include <limits.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <ctype.h>
+
+/* 0 = both upper and lower case */
+/* 1 = initial lower case only (build variables) */
+/* 2 = initial upper case only (install variables) */
+#define mode(flag, pt) (!flag || ((flag == 1) && islower(pt[1])) || \
+ ((flag == 2) && isupper(pt[1])))
+
+/*
+ * For next and last functions below, values indicate whether resolution
+ * was possible.
+ *
+ * 0 = all OK - the variable resolved within the established parameters
+ * or it wasn't time for the variable to bind.
+ * 1 = parameter did not resolve because there was no value in the
+ * environment or because it was a build variable at install
+ * time.
+ */
+
+/*
+ * This gets a raw path which may contain shell variables and returns in path
+ * a pathname with all appropriate parameters resolved. If it comes in
+ * relative, it goes out relative.
+ */
+int
+mappath(int flag, char *path)
+{
+ char buffer[PATH_MAX];
+ char varname[64];
+ char *npt, *pt, *pt2, *copy;
+ char *token;
+ int retvalue = 0;
+
+ copy = buffer;
+
+ /*
+ * For each "/" separated token. If the token contains an environment
+ * variable, then evaluate the variable and insert it into path.
+ */
+ for (pt = path; *pt; /* void */) {
+ /*
+ * If this is a token and it's an environment variable
+ * properly situated in the path...
+ */
+ if ((*pt == '$') && isalpha(pt[1]) &&
+ ((pt == path) || (pt[-1] == '/'))) {
+ /* ... and it's the right time to evaluate it... */
+ if (mode(flag, pt)) {
+ /* replace the parameter with its value. */
+ pt2 = varname;
+ for (npt = pt+1; *npt && (*npt != '/');
+ /* void */)
+ *pt2++ = *npt++;
+ *pt2 = '\0';
+ /*
+ * At this point EVERY token should evaluate
+ * to a value. If it doesn't, there's an
+ * error.
+ */
+ if ((token = getenv(varname)) != NULL &&
+ *token != NULL) {
+ /* copy in parameter value */
+ while (*token)
+ *copy++ = *token++;
+ pt = npt;
+ } else {
+ retvalue = 1;
+ *copy++ = *pt++;
+ }
+ /*
+ * If evaluate time is wrong, determine of this is an
+ * error.
+ */
+ } else {
+ if (flag == 2) { /* install-time. */
+ /*
+ * ALL variables MUST evaluate at
+ * install time.
+ */
+ *copy++ = *pt++;
+ retvalue = 1;
+ } else if (flag == 1 && /* build-time */
+ islower(pt[1])) {
+ /*
+ * All build-time variables must
+ * evaluate at build time.
+ */
+ retvalue = 1;
+ *copy++ = *pt++;
+ } else /* no problem. */
+ *copy++ = *pt++;
+ }
+ /*
+ * If it's a separator, copy it over to the target buffer and
+ * move to the start of the next token.
+ */
+ } else if (*pt == '/') {
+ while (pt[1] == '/')
+ pt++;
+ if ((pt[1] == '\0') && (pt > path))
+ break;
+ *copy++ = *pt++;
+ /*
+ * If we're in the middle of a non-parametric token, copy
+ * that character over and try the next character.
+ */
+ } else
+ *copy++ = *pt++;
+ }
+ *copy = '\0';
+ (void) strcpy(path, buffer);
+ return (retvalue);
+}
+
+/*
+ * This function resolves the path into an absolute path referred to
+ * an install root of ir.
+ */
+void
+basepath(char *path, char *basedir, char *ir)
+{
+ char buffer[PATH_MAX];
+
+ /* For a relative path, prepend the basedir */
+ if (*path != '/') {
+ (void) strcpy(buffer, path);
+ if (ir && *ir) {
+ while (*ir)
+ *path++ = *ir++;
+ if (path[-1] == '/')
+ path--;
+ }
+ if (basedir && *basedir) {
+ if (ir && *ir && *basedir != '/')
+ *path++ = '/';
+ while (*basedir)
+ *path++ = *basedir++;
+ if (path[-1] == '/')
+ path--;
+ }
+ *path++ = '/';
+ (void) strcpy(path, buffer);
+
+ /* For an absolute path, just prepend the install root */
+ } else {
+ if (ir && *ir) {
+ (void) strcpy(buffer, path);
+ while (*ir)
+ *path++ = *ir++;
+ if (path[-1] == '/')
+ path--;
+ (void) strcpy(path, buffer);
+ }
+ }
+}
+
+/*
+ * Evaluate varname and return with environment variables resolved.
+ * NOTE: This assumes that varname is a buffer long enough to hold the
+ * evaluated string.
+ */
+int
+mapvar(int flag, char *varname)
+{
+ char *token;
+ int retvalue = 0;
+
+ /* If its a parametric entry beginning with an alpha character. */
+ if (*varname == '$' && isalpha(varname[1])) {
+ /* ...and it's the right time to evaluate it... */
+ if (mode(flag, varname)) {
+ /*
+ * then it MUST be possible to evaluate it. If not,
+ * there's an error.
+ */
+ if (((token = getenv(&varname[1])) != NULL) &&
+ *token) {
+ /* copy token into varname */
+ while (*token)
+ *varname++ = *token++;
+ *varname = '\0';
+ } else
+ retvalue = 1;
+ } else {
+ if (flag == 2) /* install-time. */
+ /*
+ * ALL variables MUST evaluate at install
+ * time.
+ */
+ retvalue = 1;
+ else if (flag == 1 && /* build-time */
+ islower(varname[1]))
+ /*
+ * all build-time variables must evaluate at
+ * build time.
+ */
+ retvalue = 1;
+ }
+ }
+ return (retvalue);
+}