xref: /onnv-gate/usr/src/cmd/svr4pkg/pkgmk/mkpkgmap.c (revision 9781:ccf49524d5dc)
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