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