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 2006 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 #include <stdio.h>
32*9781SMoriah.Waterland@Sun.COM #include <string.h>
33*9781SMoriah.Waterland@Sun.COM #include <errno.h>
34*9781SMoriah.Waterland@Sun.COM #include <ctype.h>
35*9781SMoriah.Waterland@Sun.COM #include <sys/types.h>
36*9781SMoriah.Waterland@Sun.COM #include <sys/stat.h>
37*9781SMoriah.Waterland@Sun.COM #include <limits.h>
38*9781SMoriah.Waterland@Sun.COM #include <pkgstrct.h>
39*9781SMoriah.Waterland@Sun.COM #include <pkginfo.h>
40*9781SMoriah.Waterland@Sun.COM #include <locale.h>
41*9781SMoriah.Waterland@Sun.COM #include <libintl.h>
42*9781SMoriah.Waterland@Sun.COM #include <unistd.h>
43*9781SMoriah.Waterland@Sun.COM #include <stdlib.h>
44*9781SMoriah.Waterland@Sun.COM #include <pkglib.h>
45*9781SMoriah.Waterland@Sun.COM #include <install.h>
46*9781SMoriah.Waterland@Sun.COM #include <libadm.h>
47*9781SMoriah.Waterland@Sun.COM #include <libinst.h>
48*9781SMoriah.Waterland@Sun.COM
49*9781SMoriah.Waterland@Sun.COM extern char *basedir, *root, *rootlist[], **environ;
50*9781SMoriah.Waterland@Sun.COM
51*9781SMoriah.Waterland@Sun.COM /*
52*9781SMoriah.Waterland@Sun.COM * IMPORTANT NOTE: PLEASE SEE THE DEFINITION OF temp[] BELOW BEFORE
53*9781SMoriah.Waterland@Sun.COM * CHANGING THE DEFINITION OF PATH_LGTH!!!!
54*9781SMoriah.Waterland@Sun.COM */
55*9781SMoriah.Waterland@Sun.COM
56*9781SMoriah.Waterland@Sun.COM #define PATH_LGTH 4096
57*9781SMoriah.Waterland@Sun.COM
58*9781SMoriah.Waterland@Sun.COM #define MAXPARAMS 256
59*9781SMoriah.Waterland@Sun.COM #define NRECURS 20
60*9781SMoriah.Waterland@Sun.COM
61*9781SMoriah.Waterland@Sun.COM #define MSG_BPARAMC "parametric class specification for <%s> not allowed"
62*9781SMoriah.Waterland@Sun.COM #define MSG_SRCHLOC "no object for <%s> found in local path"
63*9781SMoriah.Waterland@Sun.COM #define MSG_SRCHSRCH "no object for <%s> found in search path"
64*9781SMoriah.Waterland@Sun.COM #define MSG_SRCHROOT "no object for <%s> found in root directory"
65*9781SMoriah.Waterland@Sun.COM #define MSG_CONTENTS "unable to process contents of object <%s>"
66*9781SMoriah.Waterland@Sun.COM #define MSG_WRITE "write of entry failed, errno=%d"
67*9781SMoriah.Waterland@Sun.COM #define MSG_GARBDEFLT "garbled default settings: %s"
68*9781SMoriah.Waterland@Sun.COM #define MSG_BANG "unknown directive: %s"
69*9781SMoriah.Waterland@Sun.COM #define MSG_CHDIR "unable to change directory to <%s>"
70*9781SMoriah.Waterland@Sun.COM #define MSG_INCOMPLETE "processing of <%s> may be incomplete"
71*9781SMoriah.Waterland@Sun.COM #define MSG_NRECURS "too many levels of include (limit is %d)"
72*9781SMoriah.Waterland@Sun.COM #define MSG_RDINCLUDE "unable to process include file <%s>, errno=%d"
73*9781SMoriah.Waterland@Sun.COM #define MSG_IGNINCLUDE "ignoring include file <%s>"
74*9781SMoriah.Waterland@Sun.COM #define MSG_NODEVICE "device numbers cannot be determined for <%s>"
75*9781SMoriah.Waterland@Sun.COM
76*9781SMoriah.Waterland@Sun.COM #define WRN_BADATTR "WARNING: attributes set to %04o %s %s for <%s>"
77*9781SMoriah.Waterland@Sun.COM #define WRN_BADATTRM "WARNING: attributes set to %s %s %s for <%s>"
78*9781SMoriah.Waterland@Sun.COM #define WRN_FAKEBD "WARNING: parametric paths may ignore BASEDIR"
79*9781SMoriah.Waterland@Sun.COM
80*9781SMoriah.Waterland@Sun.COM #define ERR_TEMP "unable to obtain temporary file resources, errno=%d"
81*9781SMoriah.Waterland@Sun.COM #define ERR_ENVBUILD "unable to build parameter environment, errno=%d"
82*9781SMoriah.Waterland@Sun.COM #define ERR_MAXPARAMS "too many parameter definitions (limit is %d)"
83*9781SMoriah.Waterland@Sun.COM #define ERR_GETCWD "unable to get current directory, errno=%d"
84*9781SMoriah.Waterland@Sun.COM #define ERR_PATHVAR "cannot resolve all build parameters associated with " \
85*9781SMoriah.Waterland@Sun.COM "path <%s>."
86*9781SMoriah.Waterland@Sun.COM
87*9781SMoriah.Waterland@Sun.COM static struct cfent entry;
88*9781SMoriah.Waterland@Sun.COM static FILE *fp,
89*9781SMoriah.Waterland@Sun.COM *sfp[20];
90*9781SMoriah.Waterland@Sun.COM static char *dname[NRECURS],
91*9781SMoriah.Waterland@Sun.COM *params[256],
92*9781SMoriah.Waterland@Sun.COM *proto[NRECURS],
93*9781SMoriah.Waterland@Sun.COM *rootp[NRECURS][16],
94*9781SMoriah.Waterland@Sun.COM *srchp[NRECURS][16],
95*9781SMoriah.Waterland@Sun.COM *d_own[NRECURS],
96*9781SMoriah.Waterland@Sun.COM *d_grp[NRECURS],
97*9781SMoriah.Waterland@Sun.COM *rdonly[256];
98*9781SMoriah.Waterland@Sun.COM static mode_t d_mod[NRECURS];
99*9781SMoriah.Waterland@Sun.COM static int nfp = (-1);
100*9781SMoriah.Waterland@Sun.COM static int nrdonly = 0;
101*9781SMoriah.Waterland@Sun.COM static int errflg = 0;
102*9781SMoriah.Waterland@Sun.COM static char *separ = " \t\n, ";
103*9781SMoriah.Waterland@Sun.COM
104*9781SMoriah.Waterland@Sun.COM /* libpkg/gpkgmap.c */
105*9781SMoriah.Waterland@Sun.COM extern void attrpreset(int mode, char *owner, char *group);
106*9781SMoriah.Waterland@Sun.COM extern void attrdefault();
107*9781SMoriah.Waterland@Sun.COM static char *findfile(char *path, char *local);
108*9781SMoriah.Waterland@Sun.COM static char *srchroot(char *path, char *copy);
109*9781SMoriah.Waterland@Sun.COM
110*9781SMoriah.Waterland@Sun.COM static int popenv(void);
111*9781SMoriah.Waterland@Sun.COM
112*9781SMoriah.Waterland@Sun.COM static int doattrib(void);
113*9781SMoriah.Waterland@Sun.COM static void doinclude(void);
114*9781SMoriah.Waterland@Sun.COM static void dorsearch(void);
115*9781SMoriah.Waterland@Sun.COM static void dosearch(void);
116*9781SMoriah.Waterland@Sun.COM static void error(int flag);
117*9781SMoriah.Waterland@Sun.COM static void lputenv(char *s);
118*9781SMoriah.Waterland@Sun.COM static void pushenv(char *file);
119*9781SMoriah.Waterland@Sun.COM static void translate(register char *pt, register char *copy);
120*9781SMoriah.Waterland@Sun.COM
121*9781SMoriah.Waterland@Sun.COM int
mkpkgmap(char * outfile,char * protofile,char ** envparam)122*9781SMoriah.Waterland@Sun.COM mkpkgmap(char *outfile, char *protofile, char **envparam)
123*9781SMoriah.Waterland@Sun.COM {
124*9781SMoriah.Waterland@Sun.COM FILE *tmpfp;
125*9781SMoriah.Waterland@Sun.COM char *pt, *path, mybuff[PATH_LGTH];
126*9781SMoriah.Waterland@Sun.COM char **envsave;
127*9781SMoriah.Waterland@Sun.COM int c, fakebasedir;
128*9781SMoriah.Waterland@Sun.COM int i, n;
129*9781SMoriah.Waterland@Sun.COM
130*9781SMoriah.Waterland@Sun.COM /*
131*9781SMoriah.Waterland@Sun.COM * NOTE: THE SIZE OF temp IS HARD CODED INTO CALLS TO fscanf.
132*9781SMoriah.Waterland@Sun.COM * YOU *MUST* MAKE SURE TO CHANGE THOSE CALLS IF THE SIZE OF temp
133*9781SMoriah.Waterland@Sun.COM * IS EVER CHANGED!!!!!!
134*9781SMoriah.Waterland@Sun.COM */
135*9781SMoriah.Waterland@Sun.COM char temp[PATH_LGTH];
136*9781SMoriah.Waterland@Sun.COM
137*9781SMoriah.Waterland@Sun.COM if ((tmpfp = fopen(outfile, "w")) == NULL) {
138*9781SMoriah.Waterland@Sun.COM progerr(gettext(ERR_TEMP), errno);
139*9781SMoriah.Waterland@Sun.COM quit(99);
140*9781SMoriah.Waterland@Sun.COM }
141*9781SMoriah.Waterland@Sun.COM envsave = environ;
142*9781SMoriah.Waterland@Sun.COM environ = params; /* use only local environ */
143*9781SMoriah.Waterland@Sun.COM attrdefault(); /* assume no default attributes */
144*9781SMoriah.Waterland@Sun.COM
145*9781SMoriah.Waterland@Sun.COM /*
146*9781SMoriah.Waterland@Sun.COM * Environment parameters are optional, so variable
147*9781SMoriah.Waterland@Sun.COM * (envparam[i]) could be NULL.
148*9781SMoriah.Waterland@Sun.COM */
149*9781SMoriah.Waterland@Sun.COM for (i = 0; (envparam[i] != NULL) &&
150*9781SMoriah.Waterland@Sun.COM (pt = strchr(envparam[i], '=')); i++) {
151*9781SMoriah.Waterland@Sun.COM *pt = '\0';
152*9781SMoriah.Waterland@Sun.COM rdonly[nrdonly++] = qstrdup(envparam[i]);
153*9781SMoriah.Waterland@Sun.COM *pt = '=';
154*9781SMoriah.Waterland@Sun.COM if (putenv(qstrdup(envparam[i]))) { /* bugid 1090920 */
155*9781SMoriah.Waterland@Sun.COM progerr(gettext(ERR_ENVBUILD), errno);
156*9781SMoriah.Waterland@Sun.COM quit(99);
157*9781SMoriah.Waterland@Sun.COM }
158*9781SMoriah.Waterland@Sun.COM if (nrdonly >= MAXPARAMS) {
159*9781SMoriah.Waterland@Sun.COM progerr(gettext(ERR_MAXPARAMS), MAXPARAMS);
160*9781SMoriah.Waterland@Sun.COM quit(1);
161*9781SMoriah.Waterland@Sun.COM }
162*9781SMoriah.Waterland@Sun.COM }
163*9781SMoriah.Waterland@Sun.COM
164*9781SMoriah.Waterland@Sun.COM pushenv(protofile);
165*9781SMoriah.Waterland@Sun.COM errflg = 0;
166*9781SMoriah.Waterland@Sun.COM again:
167*9781SMoriah.Waterland@Sun.COM fakebasedir = 0;
168*9781SMoriah.Waterland@Sun.COM while (!feof(fp)) {
169*9781SMoriah.Waterland@Sun.COM c = getc(fp);
170*9781SMoriah.Waterland@Sun.COM while (isspace(c))
171*9781SMoriah.Waterland@Sun.COM c = getc(fp);
172*9781SMoriah.Waterland@Sun.COM
173*9781SMoriah.Waterland@Sun.COM if (c == '#') {
174*9781SMoriah.Waterland@Sun.COM do c = getc(fp); while ((c != EOF) && (c != '\n'));
175*9781SMoriah.Waterland@Sun.COM continue;
176*9781SMoriah.Waterland@Sun.COM }
177*9781SMoriah.Waterland@Sun.COM if (c == EOF)
178*9781SMoriah.Waterland@Sun.COM break;
179*9781SMoriah.Waterland@Sun.COM
180*9781SMoriah.Waterland@Sun.COM if (c == '!') {
181*9781SMoriah.Waterland@Sun.COM /*
182*9781SMoriah.Waterland@Sun.COM * IMPORTANT NOTE: THE SIZE OF temp IS HARD CODED INTO
183*9781SMoriah.Waterland@Sun.COM * the FOLLOWING CALL TO fscanf -- YOU MUST CHANGE THIS
184*9781SMoriah.Waterland@Sun.COM * LINE IF THE SIZE OF fscanf IS EVER CHANGED!!!
185*9781SMoriah.Waterland@Sun.COM */
186*9781SMoriah.Waterland@Sun.COM (void) fscanf(fp, "%4096s", temp);
187*9781SMoriah.Waterland@Sun.COM
188*9781SMoriah.Waterland@Sun.COM if (strcmp(temp, "include") == 0)
189*9781SMoriah.Waterland@Sun.COM doinclude();
190*9781SMoriah.Waterland@Sun.COM else if (strcmp(temp, "rsearch") == 0)
191*9781SMoriah.Waterland@Sun.COM dorsearch();
192*9781SMoriah.Waterland@Sun.COM else if (strcmp(temp, "search") == 0)
193*9781SMoriah.Waterland@Sun.COM dosearch();
194*9781SMoriah.Waterland@Sun.COM else if (strcmp(temp, "default") == 0) {
195*9781SMoriah.Waterland@Sun.COM if (doattrib())
196*9781SMoriah.Waterland@Sun.COM break;
197*9781SMoriah.Waterland@Sun.COM } else if (strchr(temp, '=')) {
198*9781SMoriah.Waterland@Sun.COM translate(temp, mybuff);
199*9781SMoriah.Waterland@Sun.COM /* put this into the local environment */
200*9781SMoriah.Waterland@Sun.COM lputenv(mybuff);
201*9781SMoriah.Waterland@Sun.COM (void) fscanf(fp, "%*[^\n]"); /* rest of line */
202*9781SMoriah.Waterland@Sun.COM (void) fscanf(fp, "\n"); /* rest of line */
203*9781SMoriah.Waterland@Sun.COM } else {
204*9781SMoriah.Waterland@Sun.COM error(1);
205*9781SMoriah.Waterland@Sun.COM logerr(gettext(MSG_BANG), temp);
206*9781SMoriah.Waterland@Sun.COM (void) fscanf(fp, "%*[^\n]"); /* read of line */
207*9781SMoriah.Waterland@Sun.COM (void) fscanf(fp, "\n"); /* read of line */
208*9781SMoriah.Waterland@Sun.COM }
209*9781SMoriah.Waterland@Sun.COM continue;
210*9781SMoriah.Waterland@Sun.COM }
211*9781SMoriah.Waterland@Sun.COM (void) ungetc(c, fp);
212*9781SMoriah.Waterland@Sun.COM
213*9781SMoriah.Waterland@Sun.COM if ((n = gpkgmap(&entry, fp)) < 0) {
214*9781SMoriah.Waterland@Sun.COM char *errstr;
215*9781SMoriah.Waterland@Sun.COM
216*9781SMoriah.Waterland@Sun.COM error(1);
217*9781SMoriah.Waterland@Sun.COM errstr = getErrstr();
218*9781SMoriah.Waterland@Sun.COM logerr(gettext("garbled entry"));
219*9781SMoriah.Waterland@Sun.COM logerr(gettext("- pathname: %s"),
220*9781SMoriah.Waterland@Sun.COM (entry.path && *entry.path) ? entry.path :
221*9781SMoriah.Waterland@Sun.COM "Unknown");
222*9781SMoriah.Waterland@Sun.COM logerr(gettext("- problem: %s"),
223*9781SMoriah.Waterland@Sun.COM (errstr && *errstr) ? errstr : "Unknown");
224*9781SMoriah.Waterland@Sun.COM break;
225*9781SMoriah.Waterland@Sun.COM }
226*9781SMoriah.Waterland@Sun.COM if (n == 0)
227*9781SMoriah.Waterland@Sun.COM break; /* done with file */
228*9781SMoriah.Waterland@Sun.COM
229*9781SMoriah.Waterland@Sun.COM /* don't allow classname to be parametric */
230*9781SMoriah.Waterland@Sun.COM if (entry.ftype != 'i') {
231*9781SMoriah.Waterland@Sun.COM if (entry.pkg_class[0] == '$') {
232*9781SMoriah.Waterland@Sun.COM error(1);
233*9781SMoriah.Waterland@Sun.COM logerr(gettext(MSG_BPARAMC), entry.path);
234*9781SMoriah.Waterland@Sun.COM }
235*9781SMoriah.Waterland@Sun.COM }
236*9781SMoriah.Waterland@Sun.COM
237*9781SMoriah.Waterland@Sun.COM if (strchr("dxlscbp", entry.ftype)) {
238*9781SMoriah.Waterland@Sun.COM /*
239*9781SMoriah.Waterland@Sun.COM * We don't need to search for things without any
240*9781SMoriah.Waterland@Sun.COM * contents in them.
241*9781SMoriah.Waterland@Sun.COM */
242*9781SMoriah.Waterland@Sun.COM if (strchr("cb", entry.ftype)) {
243*9781SMoriah.Waterland@Sun.COM if (entry.ainfo.major == BADMAJOR ||
244*9781SMoriah.Waterland@Sun.COM entry.ainfo.minor == BADMINOR) {
245*9781SMoriah.Waterland@Sun.COM error(1);
246*9781SMoriah.Waterland@Sun.COM logerr(gettext(MSG_NODEVICE),
247*9781SMoriah.Waterland@Sun.COM entry.path);
248*9781SMoriah.Waterland@Sun.COM }
249*9781SMoriah.Waterland@Sun.COM }
250*9781SMoriah.Waterland@Sun.COM path = NULL;
251*9781SMoriah.Waterland@Sun.COM } else {
252*9781SMoriah.Waterland@Sun.COM path = findfile(entry.path, entry.ainfo.local);
253*9781SMoriah.Waterland@Sun.COM if (!path)
254*9781SMoriah.Waterland@Sun.COM continue;
255*9781SMoriah.Waterland@Sun.COM
256*9781SMoriah.Waterland@Sun.COM entry.ainfo.local = path;
257*9781SMoriah.Waterland@Sun.COM if (strchr("fevin?", entry.ftype)) {
258*9781SMoriah.Waterland@Sun.COM if (cverify(0, &entry.ftype, path,
259*9781SMoriah.Waterland@Sun.COM &entry.cinfo, 1)) {
260*9781SMoriah.Waterland@Sun.COM error(1);
261*9781SMoriah.Waterland@Sun.COM logerr(gettext(MSG_CONTENTS), path);
262*9781SMoriah.Waterland@Sun.COM }
263*9781SMoriah.Waterland@Sun.COM }
264*9781SMoriah.Waterland@Sun.COM }
265*9781SMoriah.Waterland@Sun.COM
266*9781SMoriah.Waterland@Sun.COM /* Warn if attributes are not set correctly. */
267*9781SMoriah.Waterland@Sun.COM if (!strchr("isl", entry.ftype)) {
268*9781SMoriah.Waterland@Sun.COM int dowarning = 0;
269*9781SMoriah.Waterland@Sun.COM int hasbadmode = 0;
270*9781SMoriah.Waterland@Sun.COM
271*9781SMoriah.Waterland@Sun.COM if (entry.ainfo.mode == NOMODE) {
272*9781SMoriah.Waterland@Sun.COM entry.ainfo.mode = CURMODE;
273*9781SMoriah.Waterland@Sun.COM dowarning = 1;
274*9781SMoriah.Waterland@Sun.COM hasbadmode = 1;
275*9781SMoriah.Waterland@Sun.COM }
276*9781SMoriah.Waterland@Sun.COM
277*9781SMoriah.Waterland@Sun.COM if (strcmp(entry.ainfo.owner, NOOWNER) == 0) {
278*9781SMoriah.Waterland@Sun.COM (void) strlcpy(entry.ainfo.owner, CUROWNER,
279*9781SMoriah.Waterland@Sun.COM sizeof (entry.ainfo.owner));
280*9781SMoriah.Waterland@Sun.COM dowarning = 1;
281*9781SMoriah.Waterland@Sun.COM }
282*9781SMoriah.Waterland@Sun.COM
283*9781SMoriah.Waterland@Sun.COM if (strcmp(entry.ainfo.group, NOGROUP) == 0) {
284*9781SMoriah.Waterland@Sun.COM (void) strlcpy(entry.ainfo.group, CURGROUP,
285*9781SMoriah.Waterland@Sun.COM sizeof (entry.ainfo.group));
286*9781SMoriah.Waterland@Sun.COM dowarning = 1;
287*9781SMoriah.Waterland@Sun.COM }
288*9781SMoriah.Waterland@Sun.COM
289*9781SMoriah.Waterland@Sun.COM
290*9781SMoriah.Waterland@Sun.COM if (dowarning) {
291*9781SMoriah.Waterland@Sun.COM if (hasbadmode)
292*9781SMoriah.Waterland@Sun.COM logerr(gettext(WRN_BADATTRM),
293*9781SMoriah.Waterland@Sun.COM "?",
294*9781SMoriah.Waterland@Sun.COM entry.ainfo.owner,
295*9781SMoriah.Waterland@Sun.COM entry.ainfo.group,
296*9781SMoriah.Waterland@Sun.COM entry.path);
297*9781SMoriah.Waterland@Sun.COM else
298*9781SMoriah.Waterland@Sun.COM logerr(gettext(WRN_BADATTR),
299*9781SMoriah.Waterland@Sun.COM (int)entry.ainfo.mode,
300*9781SMoriah.Waterland@Sun.COM entry.ainfo.owner,
301*9781SMoriah.Waterland@Sun.COM entry.ainfo.group,
302*9781SMoriah.Waterland@Sun.COM entry.path);
303*9781SMoriah.Waterland@Sun.COM }
304*9781SMoriah.Waterland@Sun.COM }
305*9781SMoriah.Waterland@Sun.COM
306*9781SMoriah.Waterland@Sun.COM /*
307*9781SMoriah.Waterland@Sun.COM * Resolve build parameters (initial lower case) in
308*9781SMoriah.Waterland@Sun.COM * the link and target paths.
309*9781SMoriah.Waterland@Sun.COM */
310*9781SMoriah.Waterland@Sun.COM if (strchr("ls", entry.ftype)) {
311*9781SMoriah.Waterland@Sun.COM if (!RELATIVE(entry.ainfo.local) ||
312*9781SMoriah.Waterland@Sun.COM PARAMETRIC(entry.ainfo.local)) {
313*9781SMoriah.Waterland@Sun.COM if (mappath(1, entry.ainfo.local)) {
314*9781SMoriah.Waterland@Sun.COM error(1);
315*9781SMoriah.Waterland@Sun.COM logerr(gettext(ERR_PATHVAR),
316*9781SMoriah.Waterland@Sun.COM entry.ainfo.local);
317*9781SMoriah.Waterland@Sun.COM break;
318*9781SMoriah.Waterland@Sun.COM }
319*9781SMoriah.Waterland@Sun.COM
320*9781SMoriah.Waterland@Sun.COM canonize(entry.ainfo.local);
321*9781SMoriah.Waterland@Sun.COM }
322*9781SMoriah.Waterland@Sun.COM }
323*9781SMoriah.Waterland@Sun.COM
324*9781SMoriah.Waterland@Sun.COM /*
325*9781SMoriah.Waterland@Sun.COM * Warn if top level file or directory is an install
326*9781SMoriah.Waterland@Sun.COM * parameter
327*9781SMoriah.Waterland@Sun.COM */
328*9781SMoriah.Waterland@Sun.COM if (entry.ftype != 'i') {
329*9781SMoriah.Waterland@Sun.COM if (entry.path[0] == '$' && isupper(entry.path[1]))
330*9781SMoriah.Waterland@Sun.COM fakebasedir = 1;
331*9781SMoriah.Waterland@Sun.COM }
332*9781SMoriah.Waterland@Sun.COM
333*9781SMoriah.Waterland@Sun.COM if (mappath(1, entry.path)) {
334*9781SMoriah.Waterland@Sun.COM error(1);
335*9781SMoriah.Waterland@Sun.COM logerr(gettext(ERR_PATHVAR), entry.path);
336*9781SMoriah.Waterland@Sun.COM break;
337*9781SMoriah.Waterland@Sun.COM }
338*9781SMoriah.Waterland@Sun.COM
339*9781SMoriah.Waterland@Sun.COM canonize(entry.path);
340*9781SMoriah.Waterland@Sun.COM if (ppkgmap(&entry, tmpfp)) {
341*9781SMoriah.Waterland@Sun.COM error(1);
342*9781SMoriah.Waterland@Sun.COM logerr(gettext(MSG_WRITE), errno);
343*9781SMoriah.Waterland@Sun.COM break;
344*9781SMoriah.Waterland@Sun.COM }
345*9781SMoriah.Waterland@Sun.COM }
346*9781SMoriah.Waterland@Sun.COM
347*9781SMoriah.Waterland@Sun.COM if (fakebasedir) {
348*9781SMoriah.Waterland@Sun.COM logerr(gettext(WRN_FAKEBD));
349*9781SMoriah.Waterland@Sun.COM fakebasedir = 0;
350*9781SMoriah.Waterland@Sun.COM }
351*9781SMoriah.Waterland@Sun.COM
352*9781SMoriah.Waterland@Sun.COM if (popenv())
353*9781SMoriah.Waterland@Sun.COM goto again;
354*9781SMoriah.Waterland@Sun.COM
355*9781SMoriah.Waterland@Sun.COM (void) fclose(tmpfp);
356*9781SMoriah.Waterland@Sun.COM environ = envsave; /* restore environment */
357*9781SMoriah.Waterland@Sun.COM
358*9781SMoriah.Waterland@Sun.COM return (errflg ? 1 : 0);
359*9781SMoriah.Waterland@Sun.COM }
360*9781SMoriah.Waterland@Sun.COM
361*9781SMoriah.Waterland@Sun.COM static char *
findfile(char * path,char * local)362*9781SMoriah.Waterland@Sun.COM findfile(char *path, char *local)
363*9781SMoriah.Waterland@Sun.COM {
364*9781SMoriah.Waterland@Sun.COM struct stat statbuf;
365*9781SMoriah.Waterland@Sun.COM static char host[PATH_MAX];
366*9781SMoriah.Waterland@Sun.COM register char *pt;
367*9781SMoriah.Waterland@Sun.COM char temp[PATH_MAX], *basename;
368*9781SMoriah.Waterland@Sun.COM int i;
369*9781SMoriah.Waterland@Sun.COM
370*9781SMoriah.Waterland@Sun.COM /*
371*9781SMoriah.Waterland@Sun.COM * map any parameters specified in path to their corresponding values
372*9781SMoriah.Waterland@Sun.COM * and make sure the path is in its canonical form; any parmeters for
373*9781SMoriah.Waterland@Sun.COM * which a value is not defined will be left unexpanded. Since this
374*9781SMoriah.Waterland@Sun.COM * is an actual search for a real file (which will not end up in the
375*9781SMoriah.Waterland@Sun.COM * package) - we map ALL variables (both build and Install).
376*9781SMoriah.Waterland@Sun.COM */
377*9781SMoriah.Waterland@Sun.COM (void) strlcpy(temp, (local && local[0] ? local : path), sizeof (temp));
378*9781SMoriah.Waterland@Sun.COM mappath(0, temp);
379*9781SMoriah.Waterland@Sun.COM canonize(temp);
380*9781SMoriah.Waterland@Sun.COM
381*9781SMoriah.Waterland@Sun.COM *host = '\0';
382*9781SMoriah.Waterland@Sun.COM if (rootlist[0] || (basedir && (*temp != '/'))) {
383*9781SMoriah.Waterland@Sun.COM /*
384*9781SMoriah.Waterland@Sun.COM * search for path in the pseudo-root/basedir directory; note
385*9781SMoriah.Waterland@Sun.COM * that package information files should NOT be included in
386*9781SMoriah.Waterland@Sun.COM * this list
387*9781SMoriah.Waterland@Sun.COM */
388*9781SMoriah.Waterland@Sun.COM if (entry.ftype != 'i')
389*9781SMoriah.Waterland@Sun.COM return (srchroot(temp, host));
390*9781SMoriah.Waterland@Sun.COM }
391*9781SMoriah.Waterland@Sun.COM
392*9781SMoriah.Waterland@Sun.COM /* looking for local object file */
393*9781SMoriah.Waterland@Sun.COM if (local && *local) {
394*9781SMoriah.Waterland@Sun.COM basepath(temp, dname[nfp], NULL);
395*9781SMoriah.Waterland@Sun.COM /*
396*9781SMoriah.Waterland@Sun.COM * If it equals "/dev/null", that just means it's an empty
397*9781SMoriah.Waterland@Sun.COM * file. Otherwise, we'll really be writing stuff, so we need
398*9781SMoriah.Waterland@Sun.COM * to verify the source.
399*9781SMoriah.Waterland@Sun.COM */
400*9781SMoriah.Waterland@Sun.COM if (strcmp(temp, "/dev/null") != 0) {
401*9781SMoriah.Waterland@Sun.COM if (stat(temp, &statbuf) ||
402*9781SMoriah.Waterland@Sun.COM !(statbuf.st_mode & S_IFREG)) {
403*9781SMoriah.Waterland@Sun.COM error(1);
404*9781SMoriah.Waterland@Sun.COM logerr(gettext(MSG_SRCHLOC), path);
405*9781SMoriah.Waterland@Sun.COM return (NULL);
406*9781SMoriah.Waterland@Sun.COM }
407*9781SMoriah.Waterland@Sun.COM }
408*9781SMoriah.Waterland@Sun.COM (void) strlcpy(host, temp, sizeof (host));
409*9781SMoriah.Waterland@Sun.COM return (host);
410*9781SMoriah.Waterland@Sun.COM }
411*9781SMoriah.Waterland@Sun.COM
412*9781SMoriah.Waterland@Sun.COM for (i = 0; rootp[nfp][i]; i++) {
413*9781SMoriah.Waterland@Sun.COM (void) snprintf(host, sizeof (host), "%s/%s", rootp[nfp][i],
414*9781SMoriah.Waterland@Sun.COM temp + (*temp == '/' ? 1 : 0));
415*9781SMoriah.Waterland@Sun.COM if ((stat(host, &statbuf) == 0) &&
416*9781SMoriah.Waterland@Sun.COM (statbuf.st_mode & S_IFREG)) {
417*9781SMoriah.Waterland@Sun.COM return (host);
418*9781SMoriah.Waterland@Sun.COM }
419*9781SMoriah.Waterland@Sun.COM }
420*9781SMoriah.Waterland@Sun.COM
421*9781SMoriah.Waterland@Sun.COM pt = strrchr(temp, '/');
422*9781SMoriah.Waterland@Sun.COM if (!pt++)
423*9781SMoriah.Waterland@Sun.COM pt = temp;
424*9781SMoriah.Waterland@Sun.COM
425*9781SMoriah.Waterland@Sun.COM basename = pt;
426*9781SMoriah.Waterland@Sun.COM
427*9781SMoriah.Waterland@Sun.COM for (i = 0; srchp[nfp][i]; i++) {
428*9781SMoriah.Waterland@Sun.COM (void) snprintf(host, sizeof (host), "%s/%s",
429*9781SMoriah.Waterland@Sun.COM srchp[nfp][i], basename);
430*9781SMoriah.Waterland@Sun.COM if ((stat(host, &statbuf) == 0) &&
431*9781SMoriah.Waterland@Sun.COM (statbuf.st_mode & S_IFREG)) {
432*9781SMoriah.Waterland@Sun.COM return (host);
433*9781SMoriah.Waterland@Sun.COM }
434*9781SMoriah.Waterland@Sun.COM }
435*9781SMoriah.Waterland@Sun.COM
436*9781SMoriah.Waterland@Sun.COM /* check current directory as a last resort */
437*9781SMoriah.Waterland@Sun.COM (void) snprintf(host, sizeof (host), "%s/%s", dname[nfp], basename);
438*9781SMoriah.Waterland@Sun.COM if ((stat(host, &statbuf) == 0) && (statbuf.st_mode & S_IFREG))
439*9781SMoriah.Waterland@Sun.COM return (host);
440*9781SMoriah.Waterland@Sun.COM
441*9781SMoriah.Waterland@Sun.COM error(1);
442*9781SMoriah.Waterland@Sun.COM logerr(gettext(MSG_SRCHSRCH), path);
443*9781SMoriah.Waterland@Sun.COM return (NULL);
444*9781SMoriah.Waterland@Sun.COM }
445*9781SMoriah.Waterland@Sun.COM
446*9781SMoriah.Waterland@Sun.COM static void
dosearch(void)447*9781SMoriah.Waterland@Sun.COM dosearch(void)
448*9781SMoriah.Waterland@Sun.COM {
449*9781SMoriah.Waterland@Sun.COM char temp[PATH_MAX], lookpath[PATH_MAX], *pt;
450*9781SMoriah.Waterland@Sun.COM int n;
451*9781SMoriah.Waterland@Sun.COM
452*9781SMoriah.Waterland@Sun.COM (void) fgets(temp, PATH_MAX, fp);
453*9781SMoriah.Waterland@Sun.COM translate(temp, lookpath);
454*9781SMoriah.Waterland@Sun.COM
455*9781SMoriah.Waterland@Sun.COM for (n = 0; srchp[nfp][n]; n++)
456*9781SMoriah.Waterland@Sun.COM free(srchp[nfp][n]);
457*9781SMoriah.Waterland@Sun.COM
458*9781SMoriah.Waterland@Sun.COM n = 0;
459*9781SMoriah.Waterland@Sun.COM pt = strtok(lookpath, separ);
460*9781SMoriah.Waterland@Sun.COM if (pt && *pt) {
461*9781SMoriah.Waterland@Sun.COM do {
462*9781SMoriah.Waterland@Sun.COM if (*pt != '/') {
463*9781SMoriah.Waterland@Sun.COM /* make relative path an absolute directory */
464*9781SMoriah.Waterland@Sun.COM (void) snprintf(temp, sizeof (temp),
465*9781SMoriah.Waterland@Sun.COM "%s/%s", dname[nfp], pt);
466*9781SMoriah.Waterland@Sun.COM pt = temp;
467*9781SMoriah.Waterland@Sun.COM }
468*9781SMoriah.Waterland@Sun.COM canonize(pt);
469*9781SMoriah.Waterland@Sun.COM srchp[nfp][n++] = qstrdup(pt);
470*9781SMoriah.Waterland@Sun.COM } while (pt = strtok(NULL, separ));
471*9781SMoriah.Waterland@Sun.COM srchp[nfp][n] = NULL;
472*9781SMoriah.Waterland@Sun.COM }
473*9781SMoriah.Waterland@Sun.COM }
474*9781SMoriah.Waterland@Sun.COM
475*9781SMoriah.Waterland@Sun.COM static void
dorsearch(void)476*9781SMoriah.Waterland@Sun.COM dorsearch(void)
477*9781SMoriah.Waterland@Sun.COM {
478*9781SMoriah.Waterland@Sun.COM char temp[PATH_MAX], lookpath[PATH_MAX], *pt;
479*9781SMoriah.Waterland@Sun.COM int n;
480*9781SMoriah.Waterland@Sun.COM
481*9781SMoriah.Waterland@Sun.COM (void) fgets(temp, PATH_MAX, fp);
482*9781SMoriah.Waterland@Sun.COM translate(temp, lookpath);
483*9781SMoriah.Waterland@Sun.COM
484*9781SMoriah.Waterland@Sun.COM for (n = 0; rootp[nfp][n]; n++)
485*9781SMoriah.Waterland@Sun.COM free(rootp[nfp][n]);
486*9781SMoriah.Waterland@Sun.COM
487*9781SMoriah.Waterland@Sun.COM n = 0;
488*9781SMoriah.Waterland@Sun.COM pt = strtok(lookpath, separ);
489*9781SMoriah.Waterland@Sun.COM do {
490*9781SMoriah.Waterland@Sun.COM if (*pt != '/') {
491*9781SMoriah.Waterland@Sun.COM /* make relative path an absolute directory */
492*9781SMoriah.Waterland@Sun.COM (void) snprintf(temp, sizeof (temp),
493*9781SMoriah.Waterland@Sun.COM "%s/%s", dname[nfp], pt);
494*9781SMoriah.Waterland@Sun.COM pt = temp;
495*9781SMoriah.Waterland@Sun.COM }
496*9781SMoriah.Waterland@Sun.COM canonize(pt);
497*9781SMoriah.Waterland@Sun.COM rootp[nfp][n++] = qstrdup(pt);
498*9781SMoriah.Waterland@Sun.COM } while (pt = strtok(NULL, separ));
499*9781SMoriah.Waterland@Sun.COM rootp[nfp][n] = NULL;
500*9781SMoriah.Waterland@Sun.COM }
501*9781SMoriah.Waterland@Sun.COM
502*9781SMoriah.Waterland@Sun.COM /*
503*9781SMoriah.Waterland@Sun.COM * This function reads the default mode, owner and group from the prototype
504*9781SMoriah.Waterland@Sun.COM * file and makes that available.
505*9781SMoriah.Waterland@Sun.COM */
506*9781SMoriah.Waterland@Sun.COM static int
doattrib(void)507*9781SMoriah.Waterland@Sun.COM doattrib(void)
508*9781SMoriah.Waterland@Sun.COM {
509*9781SMoriah.Waterland@Sun.COM char *pt, attrib[PATH_MAX], *mode_ptr, *owner_ptr, *group_ptr, *eol;
510*9781SMoriah.Waterland@Sun.COM int mode;
511*9781SMoriah.Waterland@Sun.COM char owner[ATRSIZ+1], group[ATRSIZ+1], attrib_save[(4*ATRSIZ)];
512*9781SMoriah.Waterland@Sun.COM
513*9781SMoriah.Waterland@Sun.COM (void) fgets(attrib, PATH_MAX, fp);
514*9781SMoriah.Waterland@Sun.COM
515*9781SMoriah.Waterland@Sun.COM (void) strlcpy(attrib_save, attrib, sizeof (attrib_save));
516*9781SMoriah.Waterland@Sun.COM
517*9781SMoriah.Waterland@Sun.COM /*
518*9781SMoriah.Waterland@Sun.COM * Now resolve any variables that may be present. Start on group and
519*9781SMoriah.Waterland@Sun.COM * move backward since that keeps the resolved string from
520*9781SMoriah.Waterland@Sun.COM * overwriting any of the other entries. This is required since
521*9781SMoriah.Waterland@Sun.COM * mapvar() writes the resolved string over the string provided.
522*9781SMoriah.Waterland@Sun.COM */
523*9781SMoriah.Waterland@Sun.COM mode_ptr = strtok(attrib, " \t");
524*9781SMoriah.Waterland@Sun.COM owner_ptr = strtok(NULL, " \t");
525*9781SMoriah.Waterland@Sun.COM group_ptr = strtok(NULL, " \t\n");
526*9781SMoriah.Waterland@Sun.COM eol = strtok(NULL, " \t\n");
527*9781SMoriah.Waterland@Sun.COM if (strtok(NULL, " \t\n")) {
528*9781SMoriah.Waterland@Sun.COM /* extra tokens on the line */
529*9781SMoriah.Waterland@Sun.COM error(1);
530*9781SMoriah.Waterland@Sun.COM logerr(gettext(MSG_GARBDEFLT), (eol) ? eol :
531*9781SMoriah.Waterland@Sun.COM gettext("unreadable at end of line"));
532*9781SMoriah.Waterland@Sun.COM return (1);
533*9781SMoriah.Waterland@Sun.COM }
534*9781SMoriah.Waterland@Sun.COM
535*9781SMoriah.Waterland@Sun.COM if (group_ptr && mapvar(1, group_ptr) == 0)
536*9781SMoriah.Waterland@Sun.COM (void) strncpy(group, group_ptr, ATRSIZ);
537*9781SMoriah.Waterland@Sun.COM else {
538*9781SMoriah.Waterland@Sun.COM error(1);
539*9781SMoriah.Waterland@Sun.COM logerr(gettext(MSG_GARBDEFLT), (attrib_save) ?
540*9781SMoriah.Waterland@Sun.COM ((attrib_save[0]) ? attrib_save : gettext("none")) :
541*9781SMoriah.Waterland@Sun.COM gettext("unreadable at group"));
542*9781SMoriah.Waterland@Sun.COM return (1);
543*9781SMoriah.Waterland@Sun.COM }
544*9781SMoriah.Waterland@Sun.COM
545*9781SMoriah.Waterland@Sun.COM if (owner_ptr && mapvar(1, owner_ptr) == 0)
546*9781SMoriah.Waterland@Sun.COM (void) strncpy(owner, owner_ptr, ATRSIZ);
547*9781SMoriah.Waterland@Sun.COM else {
548*9781SMoriah.Waterland@Sun.COM error(1);
549*9781SMoriah.Waterland@Sun.COM logerr(gettext(MSG_GARBDEFLT), (attrib_save) ?
550*9781SMoriah.Waterland@Sun.COM ((attrib_save[0]) ? attrib_save : gettext("none")) :
551*9781SMoriah.Waterland@Sun.COM gettext("unreadable at owner"));
552*9781SMoriah.Waterland@Sun.COM return (1);
553*9781SMoriah.Waterland@Sun.COM }
554*9781SMoriah.Waterland@Sun.COM
555*9781SMoriah.Waterland@Sun.COM /*
556*9781SMoriah.Waterland@Sun.COM * For mode, don't use scanf, since we want to force an octal
557*9781SMoriah.Waterland@Sun.COM * interpretation and need to limit the length of the owner and group
558*9781SMoriah.Waterland@Sun.COM * specifications.
559*9781SMoriah.Waterland@Sun.COM */
560*9781SMoriah.Waterland@Sun.COM if (mode_ptr && mapvar(1, mode_ptr) == 0)
561*9781SMoriah.Waterland@Sun.COM mode = strtol(mode_ptr, &pt, 8);
562*9781SMoriah.Waterland@Sun.COM else {
563*9781SMoriah.Waterland@Sun.COM error(1);
564*9781SMoriah.Waterland@Sun.COM logerr(gettext(MSG_GARBDEFLT), (attrib_save) ?
565*9781SMoriah.Waterland@Sun.COM ((attrib_save[0]) ? attrib_save : gettext("none")) :
566*9781SMoriah.Waterland@Sun.COM gettext("unreadable at mode"));
567*9781SMoriah.Waterland@Sun.COM return (1);
568*9781SMoriah.Waterland@Sun.COM }
569*9781SMoriah.Waterland@Sun.COM
570*9781SMoriah.Waterland@Sun.COM /* free any previous memory from qstrdup */
571*9781SMoriah.Waterland@Sun.COM if (d_own[nfp])
572*9781SMoriah.Waterland@Sun.COM free(d_own[nfp]);
573*9781SMoriah.Waterland@Sun.COM if (d_grp[nfp])
574*9781SMoriah.Waterland@Sun.COM free(d_grp[nfp]);
575*9781SMoriah.Waterland@Sun.COM
576*9781SMoriah.Waterland@Sun.COM d_mod[nfp] = mode;
577*9781SMoriah.Waterland@Sun.COM d_own[nfp] = qstrdup(owner);
578*9781SMoriah.Waterland@Sun.COM d_grp[nfp] = qstrdup(group);
579*9781SMoriah.Waterland@Sun.COM
580*9781SMoriah.Waterland@Sun.COM attrpreset(d_mod[nfp], d_own[nfp], d_grp[nfp]);
581*9781SMoriah.Waterland@Sun.COM
582*9781SMoriah.Waterland@Sun.COM return (0);
583*9781SMoriah.Waterland@Sun.COM }
584*9781SMoriah.Waterland@Sun.COM
585*9781SMoriah.Waterland@Sun.COM static void
doinclude(void)586*9781SMoriah.Waterland@Sun.COM doinclude(void)
587*9781SMoriah.Waterland@Sun.COM {
588*9781SMoriah.Waterland@Sun.COM char file[PATH_MAX];
589*9781SMoriah.Waterland@Sun.COM char temp[PATH_MAX];
590*9781SMoriah.Waterland@Sun.COM
591*9781SMoriah.Waterland@Sun.COM (void) fgets(temp, PATH_MAX, fp);
592*9781SMoriah.Waterland@Sun.COM
593*9781SMoriah.Waterland@Sun.COM /*
594*9781SMoriah.Waterland@Sun.COM * IMPORTANT NOTE: THE SIZE OF temp IS HARD CODED INTO THE
595*9781SMoriah.Waterland@Sun.COM * FOLLOWING CALL TO fscanf -- YOU MUST CHANGE THIS LINE IF
596*9781SMoriah.Waterland@Sun.COM * THE SIZE OF fscanf IS EVER CHANGED!!!
597*9781SMoriah.Waterland@Sun.COM */
598*9781SMoriah.Waterland@Sun.COM (void) sscanf(temp, "%1024s", file);
599*9781SMoriah.Waterland@Sun.COM
600*9781SMoriah.Waterland@Sun.COM translate(file, temp);
601*9781SMoriah.Waterland@Sun.COM canonize(temp);
602*9781SMoriah.Waterland@Sun.COM
603*9781SMoriah.Waterland@Sun.COM if (*temp == NULL)
604*9781SMoriah.Waterland@Sun.COM return;
605*9781SMoriah.Waterland@Sun.COM else if (*temp != '/')
606*9781SMoriah.Waterland@Sun.COM (void) snprintf(file, sizeof (file), "%s/%s", dname[nfp], temp);
607*9781SMoriah.Waterland@Sun.COM else
608*9781SMoriah.Waterland@Sun.COM (void) strlcpy(file, temp, sizeof (file));
609*9781SMoriah.Waterland@Sun.COM
610*9781SMoriah.Waterland@Sun.COM canonize(file);
611*9781SMoriah.Waterland@Sun.COM pushenv(file);
612*9781SMoriah.Waterland@Sun.COM }
613*9781SMoriah.Waterland@Sun.COM
614*9781SMoriah.Waterland@Sun.COM /*
615*9781SMoriah.Waterland@Sun.COM * This does what mappath() does except that it does it for ALL variables
616*9781SMoriah.Waterland@Sun.COM * using whitespace as a token separator. This is used to resolve search
617*9781SMoriah.Waterland@Sun.COM * paths and assignment statements. It doesn't effect the build versus
618*9781SMoriah.Waterland@Sun.COM * install decision made for pkgmap variables.
619*9781SMoriah.Waterland@Sun.COM */
620*9781SMoriah.Waterland@Sun.COM static void
translate(register char * pt,register char * copy)621*9781SMoriah.Waterland@Sun.COM translate(register char *pt, register char *copy)
622*9781SMoriah.Waterland@Sun.COM {
623*9781SMoriah.Waterland@Sun.COM char *pt2, varname[MAX_PKG_PARAM_LENGTH];
624*9781SMoriah.Waterland@Sun.COM
625*9781SMoriah.Waterland@Sun.COM token:
626*9781SMoriah.Waterland@Sun.COM /* eat white space */
627*9781SMoriah.Waterland@Sun.COM while (isspace(*pt))
628*9781SMoriah.Waterland@Sun.COM pt++;
629*9781SMoriah.Waterland@Sun.COM while (*pt && !isspace(*pt)) {
630*9781SMoriah.Waterland@Sun.COM if (*pt == '$') {
631*9781SMoriah.Waterland@Sun.COM pt2 = varname;
632*9781SMoriah.Waterland@Sun.COM while (*++pt && !strchr("/= \t\n\r", *pt))
633*9781SMoriah.Waterland@Sun.COM *pt2++ = *pt;
634*9781SMoriah.Waterland@Sun.COM *pt2 = '\0';
635*9781SMoriah.Waterland@Sun.COM if (pt2 = getenv(varname)) {
636*9781SMoriah.Waterland@Sun.COM while (*pt2)
637*9781SMoriah.Waterland@Sun.COM *copy++ = *pt2++;
638*9781SMoriah.Waterland@Sun.COM }
639*9781SMoriah.Waterland@Sun.COM } else
640*9781SMoriah.Waterland@Sun.COM *copy++ = *pt++;
641*9781SMoriah.Waterland@Sun.COM }
642*9781SMoriah.Waterland@Sun.COM if (*pt) {
643*9781SMoriah.Waterland@Sun.COM *copy++ = ' ';
644*9781SMoriah.Waterland@Sun.COM goto token;
645*9781SMoriah.Waterland@Sun.COM }
646*9781SMoriah.Waterland@Sun.COM *copy = '\0';
647*9781SMoriah.Waterland@Sun.COM }
648*9781SMoriah.Waterland@Sun.COM
649*9781SMoriah.Waterland@Sun.COM static void
error(int flag)650*9781SMoriah.Waterland@Sun.COM error(int flag)
651*9781SMoriah.Waterland@Sun.COM {
652*9781SMoriah.Waterland@Sun.COM static char *lasterr = NULL;
653*9781SMoriah.Waterland@Sun.COM
654*9781SMoriah.Waterland@Sun.COM if (lasterr != proto[nfp]) {
655*9781SMoriah.Waterland@Sun.COM lasterr = proto[nfp];
656*9781SMoriah.Waterland@Sun.COM (void) fprintf(stderr, gettext("ERROR in %s:\n"), lasterr);
657*9781SMoriah.Waterland@Sun.COM }
658*9781SMoriah.Waterland@Sun.COM if (flag)
659*9781SMoriah.Waterland@Sun.COM errflg++;
660*9781SMoriah.Waterland@Sun.COM }
661*9781SMoriah.Waterland@Sun.COM
662*9781SMoriah.Waterland@Sun.COM /* Set up defaults and change to the build directory. */
663*9781SMoriah.Waterland@Sun.COM static void
pushenv(char * file)664*9781SMoriah.Waterland@Sun.COM pushenv(char *file)
665*9781SMoriah.Waterland@Sun.COM {
666*9781SMoriah.Waterland@Sun.COM register char *pt;
667*9781SMoriah.Waterland@Sun.COM static char topdir[PATH_MAX];
668*9781SMoriah.Waterland@Sun.COM
669*9781SMoriah.Waterland@Sun.COM if ((nfp+1) >= NRECURS) {
670*9781SMoriah.Waterland@Sun.COM error(1);
671*9781SMoriah.Waterland@Sun.COM logerr(gettext(MSG_NRECURS), NRECURS);
672*9781SMoriah.Waterland@Sun.COM logerr(gettext(MSG_IGNINCLUDE), file);
673*9781SMoriah.Waterland@Sun.COM return;
674*9781SMoriah.Waterland@Sun.COM }
675*9781SMoriah.Waterland@Sun.COM
676*9781SMoriah.Waterland@Sun.COM if (strcmp(file, "-") == 0) {
677*9781SMoriah.Waterland@Sun.COM fp = stdin;
678*9781SMoriah.Waterland@Sun.COM } else if ((fp = fopen(file, "r")) == NULL) {
679*9781SMoriah.Waterland@Sun.COM error(1);
680*9781SMoriah.Waterland@Sun.COM logerr(gettext(MSG_RDINCLUDE), file, errno);
681*9781SMoriah.Waterland@Sun.COM if (nfp >= 0) {
682*9781SMoriah.Waterland@Sun.COM logerr(gettext(MSG_IGNINCLUDE), file);
683*9781SMoriah.Waterland@Sun.COM fp = sfp[nfp];
684*9781SMoriah.Waterland@Sun.COM return;
685*9781SMoriah.Waterland@Sun.COM } else
686*9781SMoriah.Waterland@Sun.COM quit(1);
687*9781SMoriah.Waterland@Sun.COM }
688*9781SMoriah.Waterland@Sun.COM sfp[++nfp] = fp;
689*9781SMoriah.Waterland@Sun.COM srchp[nfp][0] = NULL;
690*9781SMoriah.Waterland@Sun.COM rootp[nfp][0] = NULL;
691*9781SMoriah.Waterland@Sun.COM d_mod[nfp] = (mode_t)(-1);
692*9781SMoriah.Waterland@Sun.COM d_own[nfp] = NULL;
693*9781SMoriah.Waterland@Sun.COM d_grp[nfp] = NULL;
694*9781SMoriah.Waterland@Sun.COM
695*9781SMoriah.Waterland@Sun.COM if (!nfp) {
696*9781SMoriah.Waterland@Sun.COM /* upper level proto file */
697*9781SMoriah.Waterland@Sun.COM proto[nfp] = file;
698*9781SMoriah.Waterland@Sun.COM if (file[0] == '/')
699*9781SMoriah.Waterland@Sun.COM pt = strcpy(topdir, file);
700*9781SMoriah.Waterland@Sun.COM else {
701*9781SMoriah.Waterland@Sun.COM /* path is relative to the prototype file specified */
702*9781SMoriah.Waterland@Sun.COM pt = getcwd(NULL, PATH_MAX);
703*9781SMoriah.Waterland@Sun.COM if (pt == NULL) {
704*9781SMoriah.Waterland@Sun.COM progerr(gettext(ERR_GETCWD), errno);
705*9781SMoriah.Waterland@Sun.COM quit(99);
706*9781SMoriah.Waterland@Sun.COM }
707*9781SMoriah.Waterland@Sun.COM (void) snprintf(topdir, sizeof (topdir),
708*9781SMoriah.Waterland@Sun.COM "%s/%s", pt, file);
709*9781SMoriah.Waterland@Sun.COM }
710*9781SMoriah.Waterland@Sun.COM if (pt = strrchr(topdir, '/'))
711*9781SMoriah.Waterland@Sun.COM *pt = '\0'; /* should always happen */
712*9781SMoriah.Waterland@Sun.COM if (topdir[0] == '\0')
713*9781SMoriah.Waterland@Sun.COM (void) strlcpy(topdir, "/", sizeof (topdir));
714*9781SMoriah.Waterland@Sun.COM dname[nfp] = topdir;
715*9781SMoriah.Waterland@Sun.COM } else {
716*9781SMoriah.Waterland@Sun.COM proto[nfp] = qstrdup(file);
717*9781SMoriah.Waterland@Sun.COM dname[nfp] = qstrdup(file);
718*9781SMoriah.Waterland@Sun.COM if (pt = strrchr(dname[nfp], '/'))
719*9781SMoriah.Waterland@Sun.COM *pt = '\0';
720*9781SMoriah.Waterland@Sun.COM else {
721*9781SMoriah.Waterland@Sun.COM /* same directory as the last prototype */
722*9781SMoriah.Waterland@Sun.COM free(dname[nfp]);
723*9781SMoriah.Waterland@Sun.COM dname[nfp] = qstrdup(dname[nfp-1]);
724*9781SMoriah.Waterland@Sun.COM return; /* no need to canonize() or chdir() */
725*9781SMoriah.Waterland@Sun.COM }
726*9781SMoriah.Waterland@Sun.COM }
727*9781SMoriah.Waterland@Sun.COM
728*9781SMoriah.Waterland@Sun.COM canonize(dname[nfp]);
729*9781SMoriah.Waterland@Sun.COM
730*9781SMoriah.Waterland@Sun.COM if (chdir(dname[nfp])) {
731*9781SMoriah.Waterland@Sun.COM error(1);
732*9781SMoriah.Waterland@Sun.COM logerr(gettext(MSG_CHDIR), dname[nfp]);
733*9781SMoriah.Waterland@Sun.COM if (!nfp)
734*9781SMoriah.Waterland@Sun.COM quit(1); /* must be able to cd to upper level */
735*9781SMoriah.Waterland@Sun.COM logerr(gettext(MSG_IGNINCLUDE), proto[nfp]);
736*9781SMoriah.Waterland@Sun.COM (void) popenv();
737*9781SMoriah.Waterland@Sun.COM }
738*9781SMoriah.Waterland@Sun.COM }
739*9781SMoriah.Waterland@Sun.COM
740*9781SMoriah.Waterland@Sun.COM /* Restore defaults and return to the prior directory. */
741*9781SMoriah.Waterland@Sun.COM static int
popenv(void)742*9781SMoriah.Waterland@Sun.COM popenv(void)
743*9781SMoriah.Waterland@Sun.COM {
744*9781SMoriah.Waterland@Sun.COM int i;
745*9781SMoriah.Waterland@Sun.COM
746*9781SMoriah.Waterland@Sun.COM (void) fclose(fp);
747*9781SMoriah.Waterland@Sun.COM if (nfp) {
748*9781SMoriah.Waterland@Sun.COM if (proto[nfp])
749*9781SMoriah.Waterland@Sun.COM free(proto[nfp]);
750*9781SMoriah.Waterland@Sun.COM if (dname[nfp])
751*9781SMoriah.Waterland@Sun.COM free(dname[nfp]);
752*9781SMoriah.Waterland@Sun.COM for (i = 0; srchp[nfp][i]; i++)
753*9781SMoriah.Waterland@Sun.COM free(srchp[nfp][i]);
754*9781SMoriah.Waterland@Sun.COM for (i = 0; rootp[nfp][i]; i++)
755*9781SMoriah.Waterland@Sun.COM free(rootp[nfp][i]);
756*9781SMoriah.Waterland@Sun.COM if (d_own[nfp])
757*9781SMoriah.Waterland@Sun.COM free(d_own[nfp]);
758*9781SMoriah.Waterland@Sun.COM if (d_grp[nfp])
759*9781SMoriah.Waterland@Sun.COM free(d_grp[nfp]);
760*9781SMoriah.Waterland@Sun.COM
761*9781SMoriah.Waterland@Sun.COM fp = sfp[--nfp];
762*9781SMoriah.Waterland@Sun.COM
763*9781SMoriah.Waterland@Sun.COM if (chdir(dname[nfp])) {
764*9781SMoriah.Waterland@Sun.COM error(1);
765*9781SMoriah.Waterland@Sun.COM logerr(gettext(MSG_CHDIR), dname[nfp]);
766*9781SMoriah.Waterland@Sun.COM logerr(gettext(MSG_INCOMPLETE), proto[nfp]);
767*9781SMoriah.Waterland@Sun.COM return (popenv());
768*9781SMoriah.Waterland@Sun.COM }
769*9781SMoriah.Waterland@Sun.COM return (1);
770*9781SMoriah.Waterland@Sun.COM }
771*9781SMoriah.Waterland@Sun.COM return (0);
772*9781SMoriah.Waterland@Sun.COM }
773*9781SMoriah.Waterland@Sun.COM
774*9781SMoriah.Waterland@Sun.COM /*
775*9781SMoriah.Waterland@Sun.COM * If this parameter isn't already in place, put it into the local
776*9781SMoriah.Waterland@Sun.COM * environment. This means that command line directives override prototype
777*9781SMoriah.Waterland@Sun.COM * file directives.
778*9781SMoriah.Waterland@Sun.COM */
779*9781SMoriah.Waterland@Sun.COM static void
lputenv(char * s)780*9781SMoriah.Waterland@Sun.COM lputenv(char *s)
781*9781SMoriah.Waterland@Sun.COM {
782*9781SMoriah.Waterland@Sun.COM char *pt;
783*9781SMoriah.Waterland@Sun.COM int i;
784*9781SMoriah.Waterland@Sun.COM
785*9781SMoriah.Waterland@Sun.COM pt = strchr(s, '=');
786*9781SMoriah.Waterland@Sun.COM if (!pt)
787*9781SMoriah.Waterland@Sun.COM return;
788*9781SMoriah.Waterland@Sun.COM
789*9781SMoriah.Waterland@Sun.COM *pt = '\0';
790*9781SMoriah.Waterland@Sun.COM for (i = 0; i < nrdonly; i++) {
791*9781SMoriah.Waterland@Sun.COM if (strcmp(rdonly[i], s) == 0) {
792*9781SMoriah.Waterland@Sun.COM *pt = '=';
793*9781SMoriah.Waterland@Sun.COM return;
794*9781SMoriah.Waterland@Sun.COM }
795*9781SMoriah.Waterland@Sun.COM }
796*9781SMoriah.Waterland@Sun.COM *pt = '=';
797*9781SMoriah.Waterland@Sun.COM
798*9781SMoriah.Waterland@Sun.COM if (putenv(qstrdup(s))) {
799*9781SMoriah.Waterland@Sun.COM progerr(gettext(ERR_ENVBUILD), errno);
800*9781SMoriah.Waterland@Sun.COM quit(99);
801*9781SMoriah.Waterland@Sun.COM }
802*9781SMoriah.Waterland@Sun.COM }
803*9781SMoriah.Waterland@Sun.COM
804*9781SMoriah.Waterland@Sun.COM static char *
srchroot(char * path,char * copy)805*9781SMoriah.Waterland@Sun.COM srchroot(char *path, char *copy)
806*9781SMoriah.Waterland@Sun.COM {
807*9781SMoriah.Waterland@Sun.COM struct stat statbuf;
808*9781SMoriah.Waterland@Sun.COM int i;
809*9781SMoriah.Waterland@Sun.COM
810*9781SMoriah.Waterland@Sun.COM i = 0;
811*9781SMoriah.Waterland@Sun.COM root = rootlist[i++];
812*9781SMoriah.Waterland@Sun.COM do {
813*9781SMoriah.Waterland@Sun.COM /* convert with root & basedir info */
814*9781SMoriah.Waterland@Sun.COM cvtpath(path, copy);
815*9781SMoriah.Waterland@Sun.COM /* make it pretty again */
816*9781SMoriah.Waterland@Sun.COM canonize(copy);
817*9781SMoriah.Waterland@Sun.COM
818*9781SMoriah.Waterland@Sun.COM if (stat(copy, &statbuf) || !(statbuf.st_mode & S_IFREG)) {
819*9781SMoriah.Waterland@Sun.COM root = rootlist[i++];
820*9781SMoriah.Waterland@Sun.COM continue; /* host source must be a regular file */
821*9781SMoriah.Waterland@Sun.COM }
822*9781SMoriah.Waterland@Sun.COM return (copy);
823*9781SMoriah.Waterland@Sun.COM } while (root != NULL);
824*9781SMoriah.Waterland@Sun.COM error(1);
825*9781SMoriah.Waterland@Sun.COM logerr(gettext(MSG_SRCHROOT), path);
826*9781SMoriah.Waterland@Sun.COM return (NULL);
827*9781SMoriah.Waterland@Sun.COM }
828