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