1*9781SMoriah.Waterland@Sun.COM /* 2*9781SMoriah.Waterland@Sun.COM * CDDL HEADER START 3*9781SMoriah.Waterland@Sun.COM * 4*9781SMoriah.Waterland@Sun.COM * The contents of this file are subject to the terms of the 5*9781SMoriah.Waterland@Sun.COM * Common Development and Distribution License (the "License"). 6*9781SMoriah.Waterland@Sun.COM * You may not use this file except in compliance with the License. 7*9781SMoriah.Waterland@Sun.COM * 8*9781SMoriah.Waterland@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*9781SMoriah.Waterland@Sun.COM * or http://www.opensolaris.org/os/licensing. 10*9781SMoriah.Waterland@Sun.COM * See the License for the specific language governing permissions 11*9781SMoriah.Waterland@Sun.COM * and limitations under the License. 12*9781SMoriah.Waterland@Sun.COM * 13*9781SMoriah.Waterland@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each 14*9781SMoriah.Waterland@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*9781SMoriah.Waterland@Sun.COM * If applicable, add the following below this CDDL HEADER, with the 16*9781SMoriah.Waterland@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying 17*9781SMoriah.Waterland@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner] 18*9781SMoriah.Waterland@Sun.COM * 19*9781SMoriah.Waterland@Sun.COM * CDDL HEADER END 20*9781SMoriah.Waterland@Sun.COM */ 21*9781SMoriah.Waterland@Sun.COM 22*9781SMoriah.Waterland@Sun.COM /* 23*9781SMoriah.Waterland@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24*9781SMoriah.Waterland@Sun.COM * Use is subject to license terms. 25*9781SMoriah.Waterland@Sun.COM */ 26*9781SMoriah.Waterland@Sun.COM 27*9781SMoriah.Waterland@Sun.COM /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 28*9781SMoriah.Waterland@Sun.COM /* All Rights Reserved */ 29*9781SMoriah.Waterland@Sun.COM 30*9781SMoriah.Waterland@Sun.COM 31*9781SMoriah.Waterland@Sun.COM 32*9781SMoriah.Waterland@Sun.COM #include <limits.h> 33*9781SMoriah.Waterland@Sun.COM #include <string.h> 34*9781SMoriah.Waterland@Sun.COM #include <stdlib.h> 35*9781SMoriah.Waterland@Sun.COM #include <unistd.h> 36*9781SMoriah.Waterland@Sun.COM #include <ctype.h> 37*9781SMoriah.Waterland@Sun.COM 38*9781SMoriah.Waterland@Sun.COM /* 0 = both upper and lower case */ 39*9781SMoriah.Waterland@Sun.COM /* 1 = initial lower case only (build variables) */ 40*9781SMoriah.Waterland@Sun.COM /* 2 = initial upper case only (install variables) */ 41*9781SMoriah.Waterland@Sun.COM #define mode(flag, pt) (!flag || ((flag == 1) && islower(pt[1])) || \ 42*9781SMoriah.Waterland@Sun.COM ((flag == 2) && isupper(pt[1]))) 43*9781SMoriah.Waterland@Sun.COM 44*9781SMoriah.Waterland@Sun.COM /* 45*9781SMoriah.Waterland@Sun.COM * For next and last functions below, values indicate whether resolution 46*9781SMoriah.Waterland@Sun.COM * was possible. 47*9781SMoriah.Waterland@Sun.COM * 48*9781SMoriah.Waterland@Sun.COM * 0 = all OK - the variable resolved within the established parameters 49*9781SMoriah.Waterland@Sun.COM * or it wasn't time for the variable to bind. 50*9781SMoriah.Waterland@Sun.COM * 1 = parameter did not resolve because there was no value in the 51*9781SMoriah.Waterland@Sun.COM * environment or because it was a build variable at install 52*9781SMoriah.Waterland@Sun.COM * time. 53*9781SMoriah.Waterland@Sun.COM */ 54*9781SMoriah.Waterland@Sun.COM 55*9781SMoriah.Waterland@Sun.COM /* 56*9781SMoriah.Waterland@Sun.COM * This gets a raw path which may contain shell variables and returns in path 57*9781SMoriah.Waterland@Sun.COM * a pathname with all appropriate parameters resolved. If it comes in 58*9781SMoriah.Waterland@Sun.COM * relative, it goes out relative. 59*9781SMoriah.Waterland@Sun.COM */ 60*9781SMoriah.Waterland@Sun.COM int 61*9781SMoriah.Waterland@Sun.COM mappath(int flag, char *path) 62*9781SMoriah.Waterland@Sun.COM { 63*9781SMoriah.Waterland@Sun.COM char buffer[PATH_MAX]; 64*9781SMoriah.Waterland@Sun.COM char varname[64]; 65*9781SMoriah.Waterland@Sun.COM char *npt, *pt, *pt2, *copy; 66*9781SMoriah.Waterland@Sun.COM char *token; 67*9781SMoriah.Waterland@Sun.COM int retvalue = 0; 68*9781SMoriah.Waterland@Sun.COM 69*9781SMoriah.Waterland@Sun.COM copy = buffer; 70*9781SMoriah.Waterland@Sun.COM 71*9781SMoriah.Waterland@Sun.COM /* 72*9781SMoriah.Waterland@Sun.COM * For each "/" separated token. If the token contains an environment 73*9781SMoriah.Waterland@Sun.COM * variable, then evaluate the variable and insert it into path. 74*9781SMoriah.Waterland@Sun.COM */ 75*9781SMoriah.Waterland@Sun.COM for (pt = path; *pt; /* void */) { 76*9781SMoriah.Waterland@Sun.COM /* 77*9781SMoriah.Waterland@Sun.COM * If this is a token and it's an environment variable 78*9781SMoriah.Waterland@Sun.COM * properly situated in the path... 79*9781SMoriah.Waterland@Sun.COM */ 80*9781SMoriah.Waterland@Sun.COM if ((*pt == '$') && isalpha(pt[1]) && 81*9781SMoriah.Waterland@Sun.COM ((pt == path) || (pt[-1] == '/'))) { 82*9781SMoriah.Waterland@Sun.COM /* ... and it's the right time to evaluate it... */ 83*9781SMoriah.Waterland@Sun.COM if (mode(flag, pt)) { 84*9781SMoriah.Waterland@Sun.COM /* replace the parameter with its value. */ 85*9781SMoriah.Waterland@Sun.COM pt2 = varname; 86*9781SMoriah.Waterland@Sun.COM for (npt = pt+1; *npt && (*npt != '/'); 87*9781SMoriah.Waterland@Sun.COM /* void */) 88*9781SMoriah.Waterland@Sun.COM *pt2++ = *npt++; 89*9781SMoriah.Waterland@Sun.COM *pt2 = '\0'; 90*9781SMoriah.Waterland@Sun.COM /* 91*9781SMoriah.Waterland@Sun.COM * At this point EVERY token should evaluate 92*9781SMoriah.Waterland@Sun.COM * to a value. If it doesn't, there's an 93*9781SMoriah.Waterland@Sun.COM * error. 94*9781SMoriah.Waterland@Sun.COM */ 95*9781SMoriah.Waterland@Sun.COM if ((token = getenv(varname)) != NULL && 96*9781SMoriah.Waterland@Sun.COM *token != NULL) { 97*9781SMoriah.Waterland@Sun.COM /* copy in parameter value */ 98*9781SMoriah.Waterland@Sun.COM while (*token) 99*9781SMoriah.Waterland@Sun.COM *copy++ = *token++; 100*9781SMoriah.Waterland@Sun.COM pt = npt; 101*9781SMoriah.Waterland@Sun.COM } else { 102*9781SMoriah.Waterland@Sun.COM retvalue = 1; 103*9781SMoriah.Waterland@Sun.COM *copy++ = *pt++; 104*9781SMoriah.Waterland@Sun.COM } 105*9781SMoriah.Waterland@Sun.COM /* 106*9781SMoriah.Waterland@Sun.COM * If evaluate time is wrong, determine of this is an 107*9781SMoriah.Waterland@Sun.COM * error. 108*9781SMoriah.Waterland@Sun.COM */ 109*9781SMoriah.Waterland@Sun.COM } else { 110*9781SMoriah.Waterland@Sun.COM if (flag == 2) { /* install-time. */ 111*9781SMoriah.Waterland@Sun.COM /* 112*9781SMoriah.Waterland@Sun.COM * ALL variables MUST evaluate at 113*9781SMoriah.Waterland@Sun.COM * install time. 114*9781SMoriah.Waterland@Sun.COM */ 115*9781SMoriah.Waterland@Sun.COM *copy++ = *pt++; 116*9781SMoriah.Waterland@Sun.COM retvalue = 1; 117*9781SMoriah.Waterland@Sun.COM } else if (flag == 1 && /* build-time */ 118*9781SMoriah.Waterland@Sun.COM islower(pt[1])) { 119*9781SMoriah.Waterland@Sun.COM /* 120*9781SMoriah.Waterland@Sun.COM * All build-time variables must 121*9781SMoriah.Waterland@Sun.COM * evaluate at build time. 122*9781SMoriah.Waterland@Sun.COM */ 123*9781SMoriah.Waterland@Sun.COM retvalue = 1; 124*9781SMoriah.Waterland@Sun.COM *copy++ = *pt++; 125*9781SMoriah.Waterland@Sun.COM } else /* no problem. */ 126*9781SMoriah.Waterland@Sun.COM *copy++ = *pt++; 127*9781SMoriah.Waterland@Sun.COM } 128*9781SMoriah.Waterland@Sun.COM /* 129*9781SMoriah.Waterland@Sun.COM * If it's a separator, copy it over to the target buffer and 130*9781SMoriah.Waterland@Sun.COM * move to the start of the next token. 131*9781SMoriah.Waterland@Sun.COM */ 132*9781SMoriah.Waterland@Sun.COM } else if (*pt == '/') { 133*9781SMoriah.Waterland@Sun.COM while (pt[1] == '/') 134*9781SMoriah.Waterland@Sun.COM pt++; 135*9781SMoriah.Waterland@Sun.COM if ((pt[1] == '\0') && (pt > path)) 136*9781SMoriah.Waterland@Sun.COM break; 137*9781SMoriah.Waterland@Sun.COM *copy++ = *pt++; 138*9781SMoriah.Waterland@Sun.COM /* 139*9781SMoriah.Waterland@Sun.COM * If we're in the middle of a non-parametric token, copy 140*9781SMoriah.Waterland@Sun.COM * that character over and try the next character. 141*9781SMoriah.Waterland@Sun.COM */ 142*9781SMoriah.Waterland@Sun.COM } else 143*9781SMoriah.Waterland@Sun.COM *copy++ = *pt++; 144*9781SMoriah.Waterland@Sun.COM } 145*9781SMoriah.Waterland@Sun.COM *copy = '\0'; 146*9781SMoriah.Waterland@Sun.COM (void) strcpy(path, buffer); 147*9781SMoriah.Waterland@Sun.COM return (retvalue); 148*9781SMoriah.Waterland@Sun.COM } 149*9781SMoriah.Waterland@Sun.COM 150*9781SMoriah.Waterland@Sun.COM /* 151*9781SMoriah.Waterland@Sun.COM * This function resolves the path into an absolute path referred to 152*9781SMoriah.Waterland@Sun.COM * an install root of ir. 153*9781SMoriah.Waterland@Sun.COM */ 154*9781SMoriah.Waterland@Sun.COM void 155*9781SMoriah.Waterland@Sun.COM basepath(char *path, char *basedir, char *ir) 156*9781SMoriah.Waterland@Sun.COM { 157*9781SMoriah.Waterland@Sun.COM char buffer[PATH_MAX]; 158*9781SMoriah.Waterland@Sun.COM 159*9781SMoriah.Waterland@Sun.COM /* For a relative path, prepend the basedir */ 160*9781SMoriah.Waterland@Sun.COM if (*path != '/') { 161*9781SMoriah.Waterland@Sun.COM (void) strcpy(buffer, path); 162*9781SMoriah.Waterland@Sun.COM if (ir && *ir) { 163*9781SMoriah.Waterland@Sun.COM while (*ir) 164*9781SMoriah.Waterland@Sun.COM *path++ = *ir++; 165*9781SMoriah.Waterland@Sun.COM if (path[-1] == '/') 166*9781SMoriah.Waterland@Sun.COM path--; 167*9781SMoriah.Waterland@Sun.COM } 168*9781SMoriah.Waterland@Sun.COM if (basedir && *basedir) { 169*9781SMoriah.Waterland@Sun.COM if (ir && *ir && *basedir != '/') 170*9781SMoriah.Waterland@Sun.COM *path++ = '/'; 171*9781SMoriah.Waterland@Sun.COM while (*basedir) 172*9781SMoriah.Waterland@Sun.COM *path++ = *basedir++; 173*9781SMoriah.Waterland@Sun.COM if (path[-1] == '/') 174*9781SMoriah.Waterland@Sun.COM path--; 175*9781SMoriah.Waterland@Sun.COM } 176*9781SMoriah.Waterland@Sun.COM *path++ = '/'; 177*9781SMoriah.Waterland@Sun.COM (void) strcpy(path, buffer); 178*9781SMoriah.Waterland@Sun.COM 179*9781SMoriah.Waterland@Sun.COM /* For an absolute path, just prepend the install root */ 180*9781SMoriah.Waterland@Sun.COM } else { 181*9781SMoriah.Waterland@Sun.COM if (ir && *ir) { 182*9781SMoriah.Waterland@Sun.COM (void) strcpy(buffer, path); 183*9781SMoriah.Waterland@Sun.COM while (*ir) 184*9781SMoriah.Waterland@Sun.COM *path++ = *ir++; 185*9781SMoriah.Waterland@Sun.COM if (path[-1] == '/') 186*9781SMoriah.Waterland@Sun.COM path--; 187*9781SMoriah.Waterland@Sun.COM (void) strcpy(path, buffer); 188*9781SMoriah.Waterland@Sun.COM } 189*9781SMoriah.Waterland@Sun.COM } 190*9781SMoriah.Waterland@Sun.COM } 191*9781SMoriah.Waterland@Sun.COM 192*9781SMoriah.Waterland@Sun.COM /* 193*9781SMoriah.Waterland@Sun.COM * Evaluate varname and return with environment variables resolved. 194*9781SMoriah.Waterland@Sun.COM * NOTE: This assumes that varname is a buffer long enough to hold the 195*9781SMoriah.Waterland@Sun.COM * evaluated string. 196*9781SMoriah.Waterland@Sun.COM */ 197*9781SMoriah.Waterland@Sun.COM int 198*9781SMoriah.Waterland@Sun.COM mapvar(int flag, char *varname) 199*9781SMoriah.Waterland@Sun.COM { 200*9781SMoriah.Waterland@Sun.COM char *token; 201*9781SMoriah.Waterland@Sun.COM int retvalue = 0; 202*9781SMoriah.Waterland@Sun.COM 203*9781SMoriah.Waterland@Sun.COM /* If its a parametric entry beginning with an alpha character. */ 204*9781SMoriah.Waterland@Sun.COM if (*varname == '$' && isalpha(varname[1])) { 205*9781SMoriah.Waterland@Sun.COM /* ...and it's the right time to evaluate it... */ 206*9781SMoriah.Waterland@Sun.COM if (mode(flag, varname)) { 207*9781SMoriah.Waterland@Sun.COM /* 208*9781SMoriah.Waterland@Sun.COM * then it MUST be possible to evaluate it. If not, 209*9781SMoriah.Waterland@Sun.COM * there's an error. 210*9781SMoriah.Waterland@Sun.COM */ 211*9781SMoriah.Waterland@Sun.COM if (((token = getenv(&varname[1])) != NULL) && 212*9781SMoriah.Waterland@Sun.COM *token) { 213*9781SMoriah.Waterland@Sun.COM /* copy token into varname */ 214*9781SMoriah.Waterland@Sun.COM while (*token) 215*9781SMoriah.Waterland@Sun.COM *varname++ = *token++; 216*9781SMoriah.Waterland@Sun.COM *varname = '\0'; 217*9781SMoriah.Waterland@Sun.COM } else 218*9781SMoriah.Waterland@Sun.COM retvalue = 1; 219*9781SMoriah.Waterland@Sun.COM } else { 220*9781SMoriah.Waterland@Sun.COM if (flag == 2) /* install-time. */ 221*9781SMoriah.Waterland@Sun.COM /* 222*9781SMoriah.Waterland@Sun.COM * ALL variables MUST evaluate at install 223*9781SMoriah.Waterland@Sun.COM * time. 224*9781SMoriah.Waterland@Sun.COM */ 225*9781SMoriah.Waterland@Sun.COM retvalue = 1; 226*9781SMoriah.Waterland@Sun.COM else if (flag == 1 && /* build-time */ 227*9781SMoriah.Waterland@Sun.COM islower(varname[1])) 228*9781SMoriah.Waterland@Sun.COM /* 229*9781SMoriah.Waterland@Sun.COM * all build-time variables must evaluate at 230*9781SMoriah.Waterland@Sun.COM * build time. 231*9781SMoriah.Waterland@Sun.COM */ 232*9781SMoriah.Waterland@Sun.COM retvalue = 1; 233*9781SMoriah.Waterland@Sun.COM } 234*9781SMoriah.Waterland@Sun.COM } 235*9781SMoriah.Waterland@Sun.COM return (retvalue); 236*9781SMoriah.Waterland@Sun.COM } 237