diff options
Diffstat (limited to 'usr/src/lib/libpkg/common/mappath.c')
-rw-r--r-- | usr/src/lib/libpkg/common/mappath.c | 236 |
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); +} |