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
mappath(int flag,char * path)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
basepath(char * path,char * basedir,char * ir)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
mapvar(int flag,char * varname)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