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