xref: /onnv-gate/usr/src/cmd/svr4pkg/pkgmk/main.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 2009 Sun Microsystems, Inc.  All rights reserved.
24*9781SMoriah.Waterland@Sun.COM  * Use is subject to license terms.
25*9781SMoriah.Waterland@Sun.COM  */
26*9781SMoriah.Waterland@Sun.COM 
27*9781SMoriah.Waterland@Sun.COM /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
28*9781SMoriah.Waterland@Sun.COM /* All Rights Reserved */
29*9781SMoriah.Waterland@Sun.COM 
30*9781SMoriah.Waterland@Sun.COM 
31*9781SMoriah.Waterland@Sun.COM #include <stdio.h>
32*9781SMoriah.Waterland@Sun.COM #include <string.h>
33*9781SMoriah.Waterland@Sun.COM #include <signal.h>
34*9781SMoriah.Waterland@Sun.COM #include <errno.h>
35*9781SMoriah.Waterland@Sun.COM #include <malloc.h>
36*9781SMoriah.Waterland@Sun.COM #include <stdlib.h>
37*9781SMoriah.Waterland@Sun.COM #include <unistd.h>
38*9781SMoriah.Waterland@Sun.COM #include <time.h>
39*9781SMoriah.Waterland@Sun.COM #include <fcntl.h>
40*9781SMoriah.Waterland@Sun.COM #include <sys/types.h>
41*9781SMoriah.Waterland@Sun.COM #include <sys/stat.h>
42*9781SMoriah.Waterland@Sun.COM #include <sys/param.h>
43*9781SMoriah.Waterland@Sun.COM #include <ctype.h>
44*9781SMoriah.Waterland@Sun.COM #include <sys/mman.h>
45*9781SMoriah.Waterland@Sun.COM #include <sys/sysmacros.h>
46*9781SMoriah.Waterland@Sun.COM #include <strings.h>
47*9781SMoriah.Waterland@Sun.COM #include <pkgstrct.h>
48*9781SMoriah.Waterland@Sun.COM #include <pkgdev.h>
49*9781SMoriah.Waterland@Sun.COM #include <pkginfo.h>
50*9781SMoriah.Waterland@Sun.COM #include <pkglocs.h>
51*9781SMoriah.Waterland@Sun.COM #include <locale.h>
52*9781SMoriah.Waterland@Sun.COM #include <libintl.h>
53*9781SMoriah.Waterland@Sun.COM #include <sys/statvfs.h>
54*9781SMoriah.Waterland@Sun.COM #include <sys/utsname.h>
55*9781SMoriah.Waterland@Sun.COM #include <instzones_api.h>
56*9781SMoriah.Waterland@Sun.COM #include <pkglib.h>
57*9781SMoriah.Waterland@Sun.COM #include <libadm.h>
58*9781SMoriah.Waterland@Sun.COM #include <libinst.h>
59*9781SMoriah.Waterland@Sun.COM 
60*9781SMoriah.Waterland@Sun.COM extern char	**environ, *pkgdir;
61*9781SMoriah.Waterland@Sun.COM 
62*9781SMoriah.Waterland@Sun.COM /* mkpkgmap.c */
63*9781SMoriah.Waterland@Sun.COM extern int	mkpkgmap(char *outfile, char *protofile, char **cmdparam);
64*9781SMoriah.Waterland@Sun.COM /* splpkgmap.c */
65*9781SMoriah.Waterland@Sun.COM extern int	splpkgmap(struct cfent **eptlist, unsigned int eptnum,
66*9781SMoriah.Waterland@Sun.COM     char *order[], ulong_t bsize, ulong_t frsize, fsblkcnt_t *plimit,
67*9781SMoriah.Waterland@Sun.COM     fsfilcnt_t *pilimit, fsblkcnt_t *pllimit);
68*9781SMoriah.Waterland@Sun.COM /* scriptvfy.c */
69*9781SMoriah.Waterland@Sun.COM extern int	checkscripts(char *inst_dir, int silent);
70*9781SMoriah.Waterland@Sun.COM 
71*9781SMoriah.Waterland@Sun.COM /* libpkg/gpkgmap.c */
72*9781SMoriah.Waterland@Sun.COM extern void	setmapmode(int mode_no);
73*9781SMoriah.Waterland@Sun.COM 
74*9781SMoriah.Waterland@Sun.COM static boolean_t valid_zone_attr(struct cfent **eptlist);
75*9781SMoriah.Waterland@Sun.COM 
76*9781SMoriah.Waterland@Sun.COM #define	MALSIZ	16
77*9781SMoriah.Waterland@Sun.COM #define	NROOT	8
78*9781SMoriah.Waterland@Sun.COM #define	SPOOLDEV	"spool"
79*9781SMoriah.Waterland@Sun.COM 
80*9781SMoriah.Waterland@Sun.COM #define	MSG_PROTOTYPE	"## Building pkgmap from package prototype file.\n"
81*9781SMoriah.Waterland@Sun.COM #define	MSG_PKGINFO	"## Processing pkginfo file.\n"
82*9781SMoriah.Waterland@Sun.COM #define	MSG_VOLUMIZE	"## Attempting to volumize %d entries in pkgmap.\n"
83*9781SMoriah.Waterland@Sun.COM #define	MSG_PACKAGE1	"## Packaging one part.\n"
84*9781SMoriah.Waterland@Sun.COM #define	MSG_PACKAGEM	"## Packaging %d parts.\n"
85*9781SMoriah.Waterland@Sun.COM #define	MSG_VALSCRIPTS	"## Validating control scripts.\n"
86*9781SMoriah.Waterland@Sun.COM 
87*9781SMoriah.Waterland@Sun.COM /* Other problems */
88*9781SMoriah.Waterland@Sun.COM #define	ERR_MEMORY	"memory allocation failure, errno=%d"
89*9781SMoriah.Waterland@Sun.COM #define	ERR_NROOT	"too many paths listed with -r option, limit is %d"
90*9781SMoriah.Waterland@Sun.COM #define	ERR_PKGINST	"invalid package instance identifier <%s>"
91*9781SMoriah.Waterland@Sun.COM #define	ERR_PKGABRV	"invalid package abbreviation <%s>"
92*9781SMoriah.Waterland@Sun.COM #define	ERR_BADDEV	"unknown or invalid device specified <%s>"
93*9781SMoriah.Waterland@Sun.COM #define	ERR_TEMP	"unable to obtain temporary file resources, errno=%d"
94*9781SMoriah.Waterland@Sun.COM #define	ERR_DSTREAM	"invalid device specified (datastream) <%s>"
95*9781SMoriah.Waterland@Sun.COM #define	ERR_SPLIT	"unable to volumize package"
96*9781SMoriah.Waterland@Sun.COM #define	ERR_MKDIR	"unable to make directory <%s>"
97*9781SMoriah.Waterland@Sun.COM #define	ERR_SYMLINK	"unable to create symbolic link for <%s>"
98*9781SMoriah.Waterland@Sun.COM #define	ERR_OVERWRITE	"must use -o option to overwrite <%s>"
99*9781SMoriah.Waterland@Sun.COM #define	ERR_UMOUNT	"unable to unmount device <%s>"
100*9781SMoriah.Waterland@Sun.COM #define	ERR_NOPKGINFO	"required pkginfo file is not specified in prototype " \
101*9781SMoriah.Waterland@Sun.COM 			"file"
102*9781SMoriah.Waterland@Sun.COM #define	ERR_RDPKGINFO	"unable to process pkginfo file <%s>"
103*9781SMoriah.Waterland@Sun.COM #define	ERR_PROTOTYPE	"unable to locate prototype file"
104*9781SMoriah.Waterland@Sun.COM #define	ERR_STATVFS	"unable to stat filesystem <%s>"
105*9781SMoriah.Waterland@Sun.COM #define	ERR_WHATVFS	"unable to determine or access output filesystem for " \
106*9781SMoriah.Waterland@Sun.COM 			"device <%s>"
107*9781SMoriah.Waterland@Sun.COM #define	ERR_DEVICE	"unable to find info for device <%s>"
108*9781SMoriah.Waterland@Sun.COM #define	ERR_BUILD	"unable to build pkgmap from prototype file"
109*9781SMoriah.Waterland@Sun.COM #define	ERR_ONEVOL	"other packages found - package must fit on a single " \
110*9781SMoriah.Waterland@Sun.COM 			"volume"
111*9781SMoriah.Waterland@Sun.COM #define	ERR_NOPARAM	"parameter <%s> is not defined in <%s>"
112*9781SMoriah.Waterland@Sun.COM #define	ERR_PKGMTCH	"PKG parameter <%s> does not match instance <%s>"
113*9781SMoriah.Waterland@Sun.COM #define	ERR_NO_PKG_INFOFILE	"unable to open pkginfo file <%s>: %s"
114*9781SMoriah.Waterland@Sun.COM #define	ERR_ALLZONES_AND_THISZONE	"The package <%s> has <%s> = true " \
115*9781SMoriah.Waterland@Sun.COM 					"and <%s> = true: the package may " \
116*9781SMoriah.Waterland@Sun.COM 					"set either parameter to true, but " \
117*9781SMoriah.Waterland@Sun.COM 					"may not set both parameters to " \
118*9781SMoriah.Waterland@Sun.COM 					"true. NOTE: if the package " \
119*9781SMoriah.Waterland@Sun.COM 					"contains a request script, it is " \
120*9781SMoriah.Waterland@Sun.COM 					"treated as though it has " \
121*9781SMoriah.Waterland@Sun.COM 					"<SUNW_PKG_THISZONE> = true"
122*9781SMoriah.Waterland@Sun.COM #define	ERR_NO_ALLZONES_AND_HOLLOW	"The package <%s> has <%s> = false " \
123*9781SMoriah.Waterland@Sun.COM 					"and <%s> = true: a hollow package " \
124*9781SMoriah.Waterland@Sun.COM 					"must also be set to install in all " \
125*9781SMoriah.Waterland@Sun.COM 					"zones"
126*9781SMoriah.Waterland@Sun.COM #define	ERR_PKGINFO_INVALID_OPTION_COMB	"Invalid combinations of zone " \
127*9781SMoriah.Waterland@Sun.COM 					"parameters in pkginfo file"
128*9781SMoriah.Waterland@Sun.COM 
129*9781SMoriah.Waterland@Sun.COM #define	ERR_USAGE	"usage: %s [options] [VAR=value [VAR=value]] " \
130*9781SMoriah.Waterland@Sun.COM 			"[pkginst]\n" \
131*9781SMoriah.Waterland@Sun.COM 			"   where options may include:\n" \
132*9781SMoriah.Waterland@Sun.COM 			"\t-o\n" \
133*9781SMoriah.Waterland@Sun.COM 			"\t-a arch\n" \
134*9781SMoriah.Waterland@Sun.COM 			"\t-v version\n" \
135*9781SMoriah.Waterland@Sun.COM 			"\t-p pstamp\n" \
136*9781SMoriah.Waterland@Sun.COM 			"\t-l limit\n" \
137*9781SMoriah.Waterland@Sun.COM 			"\t-r rootpath\n" \
138*9781SMoriah.Waterland@Sun.COM 			"\t-b basedir\n" \
139*9781SMoriah.Waterland@Sun.COM 			"\t-d device\n" \
140*9781SMoriah.Waterland@Sun.COM 			"\t-f protofile\n"
141*9781SMoriah.Waterland@Sun.COM #define	WRN_MISSINGDIR	"WARNING: missing directory entry for <%s>"
142*9781SMoriah.Waterland@Sun.COM #define	WRN_SETPARAM	"WARNING: parameter <%s> set to \"%s\""
143*9781SMoriah.Waterland@Sun.COM #define	WRN_CLASSES	"WARNING: unreferenced class <%s> in prototype file"
144*9781SMoriah.Waterland@Sun.COM 
145*9781SMoriah.Waterland@Sun.COM #define	LINK    1
146*9781SMoriah.Waterland@Sun.COM 
147*9781SMoriah.Waterland@Sun.COM struct pkgdev pkgdev; 	/* holds info about the installation device */
148*9781SMoriah.Waterland@Sun.COM int	started;
149*9781SMoriah.Waterland@Sun.COM char	pkgloc[PATH_MAX];
150*9781SMoriah.Waterland@Sun.COM char	*basedir;
151*9781SMoriah.Waterland@Sun.COM char	*root;
152*9781SMoriah.Waterland@Sun.COM char	*rootlist[NROOT];
153*9781SMoriah.Waterland@Sun.COM char	*t_pkgmap;
154*9781SMoriah.Waterland@Sun.COM char	*t_pkginfo;
155*9781SMoriah.Waterland@Sun.COM 
156*9781SMoriah.Waterland@Sun.COM static struct cfent *svept;
157*9781SMoriah.Waterland@Sun.COM static char	*protofile,
158*9781SMoriah.Waterland@Sun.COM 		*device;
159*9781SMoriah.Waterland@Sun.COM static fsblkcnt_t limit = 0;
160*9781SMoriah.Waterland@Sun.COM static fsblkcnt_t llimit = 0;
161*9781SMoriah.Waterland@Sun.COM static fsfilcnt_t ilimit = 0;
162*9781SMoriah.Waterland@Sun.COM static int	overwrite,
163*9781SMoriah.Waterland@Sun.COM 		nflag,
164*9781SMoriah.Waterland@Sun.COM 		sflag;
165*9781SMoriah.Waterland@Sun.COM static void	ckmissing(char *path, char type);
166*9781SMoriah.Waterland@Sun.COM static void	outvol(struct cfent **eptlist, unsigned int eptnum, int part,
167*9781SMoriah.Waterland@Sun.COM 			int nparts);
168*9781SMoriah.Waterland@Sun.COM static void	trap(int n);
169*9781SMoriah.Waterland@Sun.COM static void	usage(void);
170*9781SMoriah.Waterland@Sun.COM 
171*9781SMoriah.Waterland@Sun.COM static int	slinkf(char *from, char *to);
172*9781SMoriah.Waterland@Sun.COM 
173*9781SMoriah.Waterland@Sun.COM int
174*9781SMoriah.Waterland@Sun.COM main(int argc, char *argv[])
175*9781SMoriah.Waterland@Sun.COM {
176*9781SMoriah.Waterland@Sun.COM 	struct utsname utsbuf;
177*9781SMoriah.Waterland@Sun.COM 	struct statvfs64 svfsb;
178*9781SMoriah.Waterland@Sun.COM 	struct cfent	**eptlist;
179*9781SMoriah.Waterland@Sun.COM 	FILE	*fp;
180*9781SMoriah.Waterland@Sun.COM 	VFP_T	*vfp;
181*9781SMoriah.Waterland@Sun.COM 	int	c, n, found;
182*9781SMoriah.Waterland@Sun.COM 	int	part, nparts, npkgs, objects;
183*9781SMoriah.Waterland@Sun.COM 	char	buf[MAX_PKG_PARAM_LENGTH];
184*9781SMoriah.Waterland@Sun.COM 	char	temp[MAX_PKG_PARAM_LENGTH];
185*9781SMoriah.Waterland@Sun.COM 	char	param[MAX_PKG_PARAM_LENGTH];
186*9781SMoriah.Waterland@Sun.COM 	char	*pt, *value, *pkginst, *tmpdir, *abi_sym_ptr,
187*9781SMoriah.Waterland@Sun.COM 		**cmdparam;
188*9781SMoriah.Waterland@Sun.COM 	char	*pkgname;
189*9781SMoriah.Waterland@Sun.COM 	char	*pkgvers;
190*9781SMoriah.Waterland@Sun.COM 	char	*pkgarch;
191*9781SMoriah.Waterland@Sun.COM 	char	*pkgcat;
192*9781SMoriah.Waterland@Sun.COM 	void	(*func)();
193*9781SMoriah.Waterland@Sun.COM 	time_t	clock;
194*9781SMoriah.Waterland@Sun.COM 	ulong_t	bsize = 0;
195*9781SMoriah.Waterland@Sun.COM 	ulong_t	frsize = 0;
196*9781SMoriah.Waterland@Sun.COM 	struct cl_attr	**allclass = NULL;
197*9781SMoriah.Waterland@Sun.COM 	struct cl_attr	**order;
198*9781SMoriah.Waterland@Sun.COM 	unsigned int eptnum, i;
199*9781SMoriah.Waterland@Sun.COM 
200*9781SMoriah.Waterland@Sun.COM 	/* initialize locale environment */
201*9781SMoriah.Waterland@Sun.COM 
202*9781SMoriah.Waterland@Sun.COM 	(void) setlocale(LC_ALL, "");
203*9781SMoriah.Waterland@Sun.COM 
204*9781SMoriah.Waterland@Sun.COM #if !defined(TEXT_DOMAIN)	/* Should be defined by cc -D */
205*9781SMoriah.Waterland@Sun.COM #define	TEXT_DOMAIN "SYS_TEST"
206*9781SMoriah.Waterland@Sun.COM #endif
207*9781SMoriah.Waterland@Sun.COM 	(void) textdomain(TEXT_DOMAIN);
208*9781SMoriah.Waterland@Sun.COM 
209*9781SMoriah.Waterland@Sun.COM 	/* initialize program name */
210*9781SMoriah.Waterland@Sun.COM 
211*9781SMoriah.Waterland@Sun.COM 	(void) set_prog_name(argv[0]);
212*9781SMoriah.Waterland@Sun.COM 
213*9781SMoriah.Waterland@Sun.COM 	/* tell spmi zones interface how to access package output functions */
214*9781SMoriah.Waterland@Sun.COM 
215*9781SMoriah.Waterland@Sun.COM 	z_set_output_functions(echo, echoDebug, progerr);
216*9781SMoriah.Waterland@Sun.COM 
217*9781SMoriah.Waterland@Sun.COM 	func = sigset(SIGINT, trap);
218*9781SMoriah.Waterland@Sun.COM 	if (func != SIG_DFL)
219*9781SMoriah.Waterland@Sun.COM 		func = sigset(SIGINT, func);
220*9781SMoriah.Waterland@Sun.COM 	func = sigset(SIGHUP, trap);
221*9781SMoriah.Waterland@Sun.COM 	setmapmode(MAPBUILD);	/* variable binding */
222*9781SMoriah.Waterland@Sun.COM 	if (func != SIG_DFL)
223*9781SMoriah.Waterland@Sun.COM 		func = sigset(SIGHUP, func);
224*9781SMoriah.Waterland@Sun.COM 
225*9781SMoriah.Waterland@Sun.COM 	environ = NULL;
226*9781SMoriah.Waterland@Sun.COM 	while ((c = getopt(argc, argv, "osnp:l:r:b:d:f:a:v:?")) != EOF) {
227*9781SMoriah.Waterland@Sun.COM 		switch (c) {
228*9781SMoriah.Waterland@Sun.COM 		    case 'n':
229*9781SMoriah.Waterland@Sun.COM 			nflag++;
230*9781SMoriah.Waterland@Sun.COM 			break;
231*9781SMoriah.Waterland@Sun.COM 
232*9781SMoriah.Waterland@Sun.COM 		    case 's':
233*9781SMoriah.Waterland@Sun.COM 			sflag++;
234*9781SMoriah.Waterland@Sun.COM 			break;
235*9781SMoriah.Waterland@Sun.COM 
236*9781SMoriah.Waterland@Sun.COM 		    case 'o':
237*9781SMoriah.Waterland@Sun.COM 			overwrite++;
238*9781SMoriah.Waterland@Sun.COM 			break;
239*9781SMoriah.Waterland@Sun.COM 
240*9781SMoriah.Waterland@Sun.COM 		    case 'p':
241*9781SMoriah.Waterland@Sun.COM 			putparam("PSTAMP", optarg);
242*9781SMoriah.Waterland@Sun.COM 			break;
243*9781SMoriah.Waterland@Sun.COM 
244*9781SMoriah.Waterland@Sun.COM 		    case 'l':
245*9781SMoriah.Waterland@Sun.COM 			llimit = strtoull(optarg, NULL, 10);
246*9781SMoriah.Waterland@Sun.COM 			break;
247*9781SMoriah.Waterland@Sun.COM 
248*9781SMoriah.Waterland@Sun.COM 		    case 'r':
249*9781SMoriah.Waterland@Sun.COM 			pt = strtok(optarg, " \t\n, ");
250*9781SMoriah.Waterland@Sun.COM 			n = 0;
251*9781SMoriah.Waterland@Sun.COM 			do {
252*9781SMoriah.Waterland@Sun.COM 				rootlist[n++] = flex_device(pt, 0);
253*9781SMoriah.Waterland@Sun.COM 				if (n >= NROOT) {
254*9781SMoriah.Waterland@Sun.COM 					progerr(gettext(ERR_NROOT), NROOT);
255*9781SMoriah.Waterland@Sun.COM 					quit(1);
256*9781SMoriah.Waterland@Sun.COM 				}
257*9781SMoriah.Waterland@Sun.COM 			} while (pt = strtok(NULL, " \t\n, "));
258*9781SMoriah.Waterland@Sun.COM 			rootlist[n] = NULL;
259*9781SMoriah.Waterland@Sun.COM 			break;
260*9781SMoriah.Waterland@Sun.COM 
261*9781SMoriah.Waterland@Sun.COM 		    case 'b':
262*9781SMoriah.Waterland@Sun.COM 			basedir = optarg;
263*9781SMoriah.Waterland@Sun.COM 			break;
264*9781SMoriah.Waterland@Sun.COM 
265*9781SMoriah.Waterland@Sun.COM 		    case 'f':
266*9781SMoriah.Waterland@Sun.COM 			protofile = optarg;
267*9781SMoriah.Waterland@Sun.COM 			break;
268*9781SMoriah.Waterland@Sun.COM 
269*9781SMoriah.Waterland@Sun.COM 		    case 'd':
270*9781SMoriah.Waterland@Sun.COM 			device = flex_device(optarg, 1);
271*9781SMoriah.Waterland@Sun.COM 			break;
272*9781SMoriah.Waterland@Sun.COM 
273*9781SMoriah.Waterland@Sun.COM 		    case 'a':
274*9781SMoriah.Waterland@Sun.COM 			putparam("ARCH", optarg);
275*9781SMoriah.Waterland@Sun.COM 			break;
276*9781SMoriah.Waterland@Sun.COM 
277*9781SMoriah.Waterland@Sun.COM 		    case 'v':
278*9781SMoriah.Waterland@Sun.COM 			putparam("VERSION", optarg);
279*9781SMoriah.Waterland@Sun.COM 			break;
280*9781SMoriah.Waterland@Sun.COM 
281*9781SMoriah.Waterland@Sun.COM 		    default:
282*9781SMoriah.Waterland@Sun.COM 			usage();
283*9781SMoriah.Waterland@Sun.COM 			/*NOTREACHED*/
284*9781SMoriah.Waterland@Sun.COM 			/*
285*9781SMoriah.Waterland@Sun.COM 			 * Although usage() calls a noreturn function,
286*9781SMoriah.Waterland@Sun.COM 			 * needed to add return (1);  so that main() would
287*9781SMoriah.Waterland@Sun.COM 			 * pass compilation checks. The statement below
288*9781SMoriah.Waterland@Sun.COM 			 * should never be executed.
289*9781SMoriah.Waterland@Sun.COM 			 */
290*9781SMoriah.Waterland@Sun.COM 			return (1);
291*9781SMoriah.Waterland@Sun.COM 		}
292*9781SMoriah.Waterland@Sun.COM 	}
293*9781SMoriah.Waterland@Sun.COM 
294*9781SMoriah.Waterland@Sun.COM 	/*
295*9781SMoriah.Waterland@Sun.COM 	 * Store command line variable assignments for later
296*9781SMoriah.Waterland@Sun.COM 	 * incorporation into the environment.
297*9781SMoriah.Waterland@Sun.COM 	 */
298*9781SMoriah.Waterland@Sun.COM 	cmdparam = &argv[optind];
299*9781SMoriah.Waterland@Sun.COM 
300*9781SMoriah.Waterland@Sun.COM 	/* Skip past equates. */
301*9781SMoriah.Waterland@Sun.COM 	while (argv[optind] && strchr(argv[optind], '='))
302*9781SMoriah.Waterland@Sun.COM 		optind++;
303*9781SMoriah.Waterland@Sun.COM 
304*9781SMoriah.Waterland@Sun.COM 	/* Confirm that the instance name is valid */
305*9781SMoriah.Waterland@Sun.COM 	if ((pkginst = argv[optind]) != NULL) {
306*9781SMoriah.Waterland@Sun.COM 		if (pkgnmchk(pkginst, "all", 0)) {
307*9781SMoriah.Waterland@Sun.COM 			progerr(gettext(ERR_PKGINST), pkginst);
308*9781SMoriah.Waterland@Sun.COM 			quit(1);
309*9781SMoriah.Waterland@Sun.COM 		}
310*9781SMoriah.Waterland@Sun.COM 		argv[optind++] = NULL;
311*9781SMoriah.Waterland@Sun.COM 	}
312*9781SMoriah.Waterland@Sun.COM 	if (optind != argc)
313*9781SMoriah.Waterland@Sun.COM 		usage();
314*9781SMoriah.Waterland@Sun.COM 
315*9781SMoriah.Waterland@Sun.COM 	tmpdir = getenv("TMPDIR");
316*9781SMoriah.Waterland@Sun.COM 	if (tmpdir == NULL)
317*9781SMoriah.Waterland@Sun.COM 		tmpdir = P_tmpdir;
318*9781SMoriah.Waterland@Sun.COM 
319*9781SMoriah.Waterland@Sun.COM 	/* bug id 4244631, not ABI compliant */
320*9781SMoriah.Waterland@Sun.COM 	abi_sym_ptr = getenv("PKG_NONABI_SYMLINKS");
321*9781SMoriah.Waterland@Sun.COM 	if (abi_sym_ptr && (strncasecmp(abi_sym_ptr, "TRUE", 4) == 0)) {
322*9781SMoriah.Waterland@Sun.COM 		set_nonABI_symlinks();
323*9781SMoriah.Waterland@Sun.COM 	}
324*9781SMoriah.Waterland@Sun.COM 
325*9781SMoriah.Waterland@Sun.COM 	if (device == NULL) {
326*9781SMoriah.Waterland@Sun.COM 		device = devattr(SPOOLDEV, "pathname");
327*9781SMoriah.Waterland@Sun.COM 		if (device == NULL) {
328*9781SMoriah.Waterland@Sun.COM 			progerr(gettext(ERR_DEVICE), SPOOLDEV);
329*9781SMoriah.Waterland@Sun.COM 			exit(99);
330*9781SMoriah.Waterland@Sun.COM 		}
331*9781SMoriah.Waterland@Sun.COM 	}
332*9781SMoriah.Waterland@Sun.COM 
333*9781SMoriah.Waterland@Sun.COM 	if (protofile == NULL) {
334*9781SMoriah.Waterland@Sun.COM 		if (access("prototype", 0) == 0)
335*9781SMoriah.Waterland@Sun.COM 			protofile = "prototype";
336*9781SMoriah.Waterland@Sun.COM 		else if (access("Prototype", 0) == 0)
337*9781SMoriah.Waterland@Sun.COM 			protofile = "Prototype";
338*9781SMoriah.Waterland@Sun.COM 		else {
339*9781SMoriah.Waterland@Sun.COM 			progerr(gettext(ERR_PROTOTYPE));
340*9781SMoriah.Waterland@Sun.COM 			quit(1);
341*9781SMoriah.Waterland@Sun.COM 		}
342*9781SMoriah.Waterland@Sun.COM 	}
343*9781SMoriah.Waterland@Sun.COM 
344*9781SMoriah.Waterland@Sun.COM 	if (devtype(device, &pkgdev)) {
345*9781SMoriah.Waterland@Sun.COM 		progerr(gettext(ERR_BADDEV), device);
346*9781SMoriah.Waterland@Sun.COM 		quit(1);
347*9781SMoriah.Waterland@Sun.COM 	}
348*9781SMoriah.Waterland@Sun.COM 	if (pkgdev.norewind) {
349*9781SMoriah.Waterland@Sun.COM 		/* initialize datastream */
350*9781SMoriah.Waterland@Sun.COM 		progerr(gettext(ERR_DSTREAM), device);
351*9781SMoriah.Waterland@Sun.COM 		quit(1);
352*9781SMoriah.Waterland@Sun.COM 	}
353*9781SMoriah.Waterland@Sun.COM 	if (pkgdev.mount) {
354*9781SMoriah.Waterland@Sun.COM 		if (n = pkgmount(&pkgdev, NULL, 0, 0, 1))
355*9781SMoriah.Waterland@Sun.COM 			quit(n);
356*9781SMoriah.Waterland@Sun.COM 	}
357*9781SMoriah.Waterland@Sun.COM 
358*9781SMoriah.Waterland@Sun.COM 	/*
359*9781SMoriah.Waterland@Sun.COM 	 * convert prototype file to a pkgmap, while locating
360*9781SMoriah.Waterland@Sun.COM 	 * package objects in the current environment
361*9781SMoriah.Waterland@Sun.COM 	 */
362*9781SMoriah.Waterland@Sun.COM 	t_pkgmap = tempnam(tmpdir, "tmpmap");
363*9781SMoriah.Waterland@Sun.COM 	if (t_pkgmap == NULL) {
364*9781SMoriah.Waterland@Sun.COM 		progerr(gettext(ERR_TEMP), errno);
365*9781SMoriah.Waterland@Sun.COM 		exit(99);
366*9781SMoriah.Waterland@Sun.COM 	}
367*9781SMoriah.Waterland@Sun.COM 
368*9781SMoriah.Waterland@Sun.COM 	(void) fprintf(stderr, gettext(MSG_PROTOTYPE));
369*9781SMoriah.Waterland@Sun.COM 	if (n = mkpkgmap(t_pkgmap, protofile, cmdparam)) {
370*9781SMoriah.Waterland@Sun.COM 		progerr(gettext(ERR_BUILD));
371*9781SMoriah.Waterland@Sun.COM 		quit(1);
372*9781SMoriah.Waterland@Sun.COM 	}
373*9781SMoriah.Waterland@Sun.COM 
374*9781SMoriah.Waterland@Sun.COM 	setmapmode(MAPNONE);	/* All appropriate variables are now bound */
375*9781SMoriah.Waterland@Sun.COM 
376*9781SMoriah.Waterland@Sun.COM 	if (vfpOpen(&vfp, t_pkgmap, "r", VFP_NEEDNOW) != 0) {
377*9781SMoriah.Waterland@Sun.COM 		progerr(gettext(ERR_TEMP), errno);
378*9781SMoriah.Waterland@Sun.COM 		quit(99);
379*9781SMoriah.Waterland@Sun.COM 	}
380*9781SMoriah.Waterland@Sun.COM 
381*9781SMoriah.Waterland@Sun.COM 	eptlist = procmap(vfp, 0, NULL);
382*9781SMoriah.Waterland@Sun.COM 
383*9781SMoriah.Waterland@Sun.COM 	if (eptlist == NULL) {
384*9781SMoriah.Waterland@Sun.COM 		quit(1);
385*9781SMoriah.Waterland@Sun.COM 	}
386*9781SMoriah.Waterland@Sun.COM 
387*9781SMoriah.Waterland@Sun.COM 	(void) vfpClose(&vfp);
388*9781SMoriah.Waterland@Sun.COM 
389*9781SMoriah.Waterland@Sun.COM 	/* Validate the zone attributes in pkginfo, before creation */
390*9781SMoriah.Waterland@Sun.COM 	if (!valid_zone_attr(eptlist)) {
391*9781SMoriah.Waterland@Sun.COM 		progerr(ERR_PKGINFO_INVALID_OPTION_COMB);
392*9781SMoriah.Waterland@Sun.COM 		quit(1);
393*9781SMoriah.Waterland@Sun.COM 	}
394*9781SMoriah.Waterland@Sun.COM 
395*9781SMoriah.Waterland@Sun.COM 	(void) fprintf(stderr, gettext(MSG_PKGINFO));
396*9781SMoriah.Waterland@Sun.COM 	pt = NULL;
397*9781SMoriah.Waterland@Sun.COM 	for (i = 0; eptlist[i]; i++) {
398*9781SMoriah.Waterland@Sun.COM 		ckmissing(eptlist[i]->path, eptlist[i]->ftype);
399*9781SMoriah.Waterland@Sun.COM 		if (eptlist[i]->ftype != 'i')
400*9781SMoriah.Waterland@Sun.COM 			continue;
401*9781SMoriah.Waterland@Sun.COM 		if (strcmp(eptlist[i]->path, "pkginfo") == 0)
402*9781SMoriah.Waterland@Sun.COM 			svept = eptlist[i];
403*9781SMoriah.Waterland@Sun.COM 	}
404*9781SMoriah.Waterland@Sun.COM 	if (svept == NULL) {
405*9781SMoriah.Waterland@Sun.COM 		progerr(gettext(ERR_NOPKGINFO));
406*9781SMoriah.Waterland@Sun.COM 		quit(99);
407*9781SMoriah.Waterland@Sun.COM 	}
408*9781SMoriah.Waterland@Sun.COM 	eptnum = i;
409*9781SMoriah.Waterland@Sun.COM 
410*9781SMoriah.Waterland@Sun.COM 	/*
411*9781SMoriah.Waterland@Sun.COM 	 * process all parameters from the pkginfo file
412*9781SMoriah.Waterland@Sun.COM 	 * and place them in the execution environment
413*9781SMoriah.Waterland@Sun.COM 	 */
414*9781SMoriah.Waterland@Sun.COM 
415*9781SMoriah.Waterland@Sun.COM 	if ((fp = fopen(svept->ainfo.local, "r")) == NULL) {
416*9781SMoriah.Waterland@Sun.COM 		progerr(gettext(ERR_RDPKGINFO), svept->ainfo.local);
417*9781SMoriah.Waterland@Sun.COM 		quit(99);
418*9781SMoriah.Waterland@Sun.COM 	}
419*9781SMoriah.Waterland@Sun.COM 	param[0] = '\0';
420*9781SMoriah.Waterland@Sun.COM 	while (value = fpkgparam(fp, param)) {
421*9781SMoriah.Waterland@Sun.COM 		if (getenv(param) == NULL)
422*9781SMoriah.Waterland@Sun.COM 			putparam(param, value);
423*9781SMoriah.Waterland@Sun.COM 		free((void *)value);
424*9781SMoriah.Waterland@Sun.COM 		param[0] = '\0';
425*9781SMoriah.Waterland@Sun.COM 	}
426*9781SMoriah.Waterland@Sun.COM 	(void) fclose(fp);
427*9781SMoriah.Waterland@Sun.COM 
428*9781SMoriah.Waterland@Sun.COM 	/* add command line variables */
429*9781SMoriah.Waterland@Sun.COM 	while (*cmdparam && (value = strchr(*cmdparam, '=')) != NULL) {
430*9781SMoriah.Waterland@Sun.COM 		*value = NULL;	/* terminate the parameter */
431*9781SMoriah.Waterland@Sun.COM 		value++;	/* value is now the value (not '=') */
432*9781SMoriah.Waterland@Sun.COM 		putparam(*cmdparam++, value);  /* store it in environ */
433*9781SMoriah.Waterland@Sun.COM 	}
434*9781SMoriah.Waterland@Sun.COM 
435*9781SMoriah.Waterland@Sun.COM 	/* make sure parameters are valid */
436*9781SMoriah.Waterland@Sun.COM 	(void) time(&clock);
437*9781SMoriah.Waterland@Sun.COM 	if (pt = getenv("PKG")) {
438*9781SMoriah.Waterland@Sun.COM 		if (pkgnmchk(pt, NULL, 0) || strchr(pt, '.')) {
439*9781SMoriah.Waterland@Sun.COM 			progerr(gettext(ERR_PKGABRV), pt);
440*9781SMoriah.Waterland@Sun.COM 			quit(1);
441*9781SMoriah.Waterland@Sun.COM 		}
442*9781SMoriah.Waterland@Sun.COM 		if (pkginst == NULL)
443*9781SMoriah.Waterland@Sun.COM 			pkginst = pt;
444*9781SMoriah.Waterland@Sun.COM 	} else {
445*9781SMoriah.Waterland@Sun.COM 		progerr(gettext(ERR_NOPARAM), "PKG", svept->path);
446*9781SMoriah.Waterland@Sun.COM 		quit(1);
447*9781SMoriah.Waterland@Sun.COM 	}
448*9781SMoriah.Waterland@Sun.COM 	/*
449*9781SMoriah.Waterland@Sun.COM 	 * verify consistency between PKG parameter and pkginst
450*9781SMoriah.Waterland@Sun.COM 	 */
451*9781SMoriah.Waterland@Sun.COM 	(void) snprintf(param, sizeof (param), "%s.*", pt);
452*9781SMoriah.Waterland@Sun.COM 	if (pkgnmchk(pkginst, param, 0)) {
453*9781SMoriah.Waterland@Sun.COM 		progerr(gettext(ERR_PKGMTCH), pt, pkginst);
454*9781SMoriah.Waterland@Sun.COM 		quit(1);
455*9781SMoriah.Waterland@Sun.COM 	}
456*9781SMoriah.Waterland@Sun.COM 
457*9781SMoriah.Waterland@Sun.COM 	/*
458*9781SMoriah.Waterland@Sun.COM 	 * *********************************************************************
459*9781SMoriah.Waterland@Sun.COM 	 * this feature is removed starting with Solaris 10 - there is no built
460*9781SMoriah.Waterland@Sun.COM 	 * in list of packages that should be run "the old way"
461*9781SMoriah.Waterland@Sun.COM 	 * *********************************************************************
462*9781SMoriah.Waterland@Sun.COM 	 */
463*9781SMoriah.Waterland@Sun.COM 
464*9781SMoriah.Waterland@Sun.COM #ifdef	ALLOW_EXCEPTION_PKG_LIST
465*9781SMoriah.Waterland@Sun.COM 	/* Until 2.9, set it from the execption list */
466*9781SMoriah.Waterland@Sun.COM 	if (exception_pkg(pkginst, LINK))
467*9781SMoriah.Waterland@Sun.COM 		set_nonABI_symlinks();
468*9781SMoriah.Waterland@Sun.COM #endif
469*9781SMoriah.Waterland@Sun.COM 
470*9781SMoriah.Waterland@Sun.COM 	if ((pkgname = getenv("NAME")) == NULL) {
471*9781SMoriah.Waterland@Sun.COM 		progerr(gettext(ERR_NOPARAM), "NAME", svept->path);
472*9781SMoriah.Waterland@Sun.COM 		quit(1);
473*9781SMoriah.Waterland@Sun.COM 	}
474*9781SMoriah.Waterland@Sun.COM 	if (ckparam("NAME", pkgname))
475*9781SMoriah.Waterland@Sun.COM 		quit(1);
476*9781SMoriah.Waterland@Sun.COM 	if ((pkgvers = getenv("VERSION")) == NULL) {
477*9781SMoriah.Waterland@Sun.COM 		/* XXX - I18n */
478*9781SMoriah.Waterland@Sun.COM 		/* LINTED do not use cftime(); use strftime instead */
479*9781SMoriah.Waterland@Sun.COM 		(void) cftime(buf, "\045m/\045d/\045Y", &clock);
480*9781SMoriah.Waterland@Sun.COM 		(void) snprintf(temp, sizeof (temp),
481*9781SMoriah.Waterland@Sun.COM 			gettext("Dev Release %s"), buf);
482*9781SMoriah.Waterland@Sun.COM 		putparam("VERSION", temp);
483*9781SMoriah.Waterland@Sun.COM 		pkgvers = getenv("VERSION");
484*9781SMoriah.Waterland@Sun.COM 		logerr(gettext(WRN_SETPARAM), "VERSION", temp);
485*9781SMoriah.Waterland@Sun.COM 	}
486*9781SMoriah.Waterland@Sun.COM 	if (ckparam("VERSION", pkgvers))
487*9781SMoriah.Waterland@Sun.COM 		quit(1);
488*9781SMoriah.Waterland@Sun.COM 	if ((pkgarch = getenv("ARCH")) == NULL) {
489*9781SMoriah.Waterland@Sun.COM 		(void) uname(&utsbuf);
490*9781SMoriah.Waterland@Sun.COM 		putparam("ARCH", utsbuf.machine);
491*9781SMoriah.Waterland@Sun.COM 		pkgarch = getenv("ARCH");
492*9781SMoriah.Waterland@Sun.COM 		logerr(gettext(WRN_SETPARAM), "ARCH", utsbuf.machine);
493*9781SMoriah.Waterland@Sun.COM 	}
494*9781SMoriah.Waterland@Sun.COM 	if (ckparam("ARCH", pkgarch))
495*9781SMoriah.Waterland@Sun.COM 		quit(1);
496*9781SMoriah.Waterland@Sun.COM 	if (getenv("PSTAMP") == NULL) {
497*9781SMoriah.Waterland@Sun.COM 		/* use octal value of '%' to fight sccs expansion */
498*9781SMoriah.Waterland@Sun.COM 		/* XXX - I18n */
499*9781SMoriah.Waterland@Sun.COM 		/* LINTED do not use cftime(); use strftime instead */
500*9781SMoriah.Waterland@Sun.COM 		(void) cftime(buf, "\045Y\045m\045d\045H\045M\045S", &clock);
501*9781SMoriah.Waterland@Sun.COM 		(void) uname(&utsbuf);
502*9781SMoriah.Waterland@Sun.COM 		(void) snprintf(temp, sizeof (temp), "%s%s",
503*9781SMoriah.Waterland@Sun.COM 			utsbuf.nodename, buf);
504*9781SMoriah.Waterland@Sun.COM 		putparam("PSTAMP", temp);
505*9781SMoriah.Waterland@Sun.COM 		logerr(gettext(WRN_SETPARAM), "PSTAMP", temp);
506*9781SMoriah.Waterland@Sun.COM 	}
507*9781SMoriah.Waterland@Sun.COM 	if ((pkgcat = getenv("CATEGORY")) == NULL) {
508*9781SMoriah.Waterland@Sun.COM 		progerr(gettext(ERR_NOPARAM), "CATEGORY", svept->path);
509*9781SMoriah.Waterland@Sun.COM 		quit(1);
510*9781SMoriah.Waterland@Sun.COM 	}
511*9781SMoriah.Waterland@Sun.COM 	if (ckparam("CATEGORY", pkgcat))
512*9781SMoriah.Waterland@Sun.COM 		quit(1);
513*9781SMoriah.Waterland@Sun.COM 
514*9781SMoriah.Waterland@Sun.COM 	/*
515*9781SMoriah.Waterland@Sun.COM 	 * warn user of classes listed in package which do
516*9781SMoriah.Waterland@Sun.COM 	 * not appear in CLASSES variable in pkginfo file
517*9781SMoriah.Waterland@Sun.COM 	 */
518*9781SMoriah.Waterland@Sun.COM 	objects = 0;
519*9781SMoriah.Waterland@Sun.COM 	for (i = 0; eptlist[i]; i++) {
520*9781SMoriah.Waterland@Sun.COM 		if (eptlist[i]->ftype != 'i') {
521*9781SMoriah.Waterland@Sun.COM 			objects++;
522*9781SMoriah.Waterland@Sun.COM 			addlist(&allclass, eptlist[i]->pkg_class);
523*9781SMoriah.Waterland@Sun.COM 		}
524*9781SMoriah.Waterland@Sun.COM 	}
525*9781SMoriah.Waterland@Sun.COM 
526*9781SMoriah.Waterland@Sun.COM 	if ((pt = getenv("CLASSES")) == NULL) {
527*9781SMoriah.Waterland@Sun.COM 		if (allclass && *allclass) {
528*9781SMoriah.Waterland@Sun.COM 			cl_setl(allclass);
529*9781SMoriah.Waterland@Sun.COM 			cl_putl("CLASSES", allclass);
530*9781SMoriah.Waterland@Sun.COM 			logerr(gettext(WRN_SETPARAM), "CLASSES",
531*9781SMoriah.Waterland@Sun.COM 			    getenv("CLASSES"));
532*9781SMoriah.Waterland@Sun.COM 		}
533*9781SMoriah.Waterland@Sun.COM 	} else {
534*9781SMoriah.Waterland@Sun.COM 		cl_sets(qstrdup(pt));
535*9781SMoriah.Waterland@Sun.COM 		if (allclass && *allclass) {
536*9781SMoriah.Waterland@Sun.COM 			for (i = 0; allclass[i]; i++) {
537*9781SMoriah.Waterland@Sun.COM 				found = 0;
538*9781SMoriah.Waterland@Sun.COM 				if (cl_idx(allclass[i]->name) != -1) {
539*9781SMoriah.Waterland@Sun.COM 					found++;
540*9781SMoriah.Waterland@Sun.COM 					break;
541*9781SMoriah.Waterland@Sun.COM 				}
542*9781SMoriah.Waterland@Sun.COM 				if (!found) {
543*9781SMoriah.Waterland@Sun.COM 					logerr(gettext(WRN_CLASSES),
544*9781SMoriah.Waterland@Sun.COM 					    (char *)allclass[i]);
545*9781SMoriah.Waterland@Sun.COM 				}
546*9781SMoriah.Waterland@Sun.COM 			}
547*9781SMoriah.Waterland@Sun.COM 		}
548*9781SMoriah.Waterland@Sun.COM 	}
549*9781SMoriah.Waterland@Sun.COM 
550*9781SMoriah.Waterland@Sun.COM 	(void) fprintf(stderr, gettext(MSG_VOLUMIZE), objects);
551*9781SMoriah.Waterland@Sun.COM 	order = (struct cl_attr **)0;
552*9781SMoriah.Waterland@Sun.COM 	if (pt = getenv("ORDER")) {
553*9781SMoriah.Waterland@Sun.COM 		pt = qstrdup(pt);
554*9781SMoriah.Waterland@Sun.COM 		(void) setlist(&order, pt);
555*9781SMoriah.Waterland@Sun.COM 		cl_putl("ORDER", order);
556*9781SMoriah.Waterland@Sun.COM 	}
557*9781SMoriah.Waterland@Sun.COM 
558*9781SMoriah.Waterland@Sun.COM 	/* stat the intended output filesystem to get blocking information */
559*9781SMoriah.Waterland@Sun.COM 	if (pkgdev.dirname == NULL) {
560*9781SMoriah.Waterland@Sun.COM 		progerr(gettext(ERR_WHATVFS), device);
561*9781SMoriah.Waterland@Sun.COM 		quit(99);
562*9781SMoriah.Waterland@Sun.COM 	}
563*9781SMoriah.Waterland@Sun.COM 	if (statvfs64(pkgdev.dirname, &svfsb)) {
564*9781SMoriah.Waterland@Sun.COM 		progerr(gettext(ERR_STATVFS), pkgdev.dirname);
565*9781SMoriah.Waterland@Sun.COM 		quit(99);
566*9781SMoriah.Waterland@Sun.COM 	}
567*9781SMoriah.Waterland@Sun.COM 
568*9781SMoriah.Waterland@Sun.COM 	if (bsize == 0) {
569*9781SMoriah.Waterland@Sun.COM 		bsize = svfsb.f_bsize;
570*9781SMoriah.Waterland@Sun.COM 	}
571*9781SMoriah.Waterland@Sun.COM 	if (frsize == 0) {
572*9781SMoriah.Waterland@Sun.COM 		frsize = svfsb.f_frsize;
573*9781SMoriah.Waterland@Sun.COM 	}
574*9781SMoriah.Waterland@Sun.COM 
575*9781SMoriah.Waterland@Sun.COM 	if (limit == 0)
576*9781SMoriah.Waterland@Sun.COM 		/*
577*9781SMoriah.Waterland@Sun.COM 		 * bavail is in terms of fragment size blocks - change
578*9781SMoriah.Waterland@Sun.COM 		 * to 512 byte blocks
579*9781SMoriah.Waterland@Sun.COM 		 */
580*9781SMoriah.Waterland@Sun.COM 		limit = (fsblkcnt_t)(((fsblkcnt_t)frsize > 0) ?
581*9781SMoriah.Waterland@Sun.COM 			howmany(frsize, DEV_BSIZE) :
582*9781SMoriah.Waterland@Sun.COM 			howmany(bsize, DEV_BSIZE)) * svfsb.f_bavail;
583*9781SMoriah.Waterland@Sun.COM 
584*9781SMoriah.Waterland@Sun.COM 	if (ilimit == 0) {
585*9781SMoriah.Waterland@Sun.COM 		ilimit = (svfsb.f_favail > 0) ?
586*9781SMoriah.Waterland@Sun.COM 		    svfsb.f_favail : svfsb.f_ffree;
587*9781SMoriah.Waterland@Sun.COM 	}
588*9781SMoriah.Waterland@Sun.COM 
589*9781SMoriah.Waterland@Sun.COM 	nparts = splpkgmap(eptlist, eptnum, (char **)order, bsize, frsize,
590*9781SMoriah.Waterland@Sun.COM 	    &limit, &ilimit, &llimit);
591*9781SMoriah.Waterland@Sun.COM 
592*9781SMoriah.Waterland@Sun.COM 	if (nparts <= 0) {
593*9781SMoriah.Waterland@Sun.COM 		progerr(gettext(ERR_SPLIT));
594*9781SMoriah.Waterland@Sun.COM 		quit(1);
595*9781SMoriah.Waterland@Sun.COM 	}
596*9781SMoriah.Waterland@Sun.COM 
597*9781SMoriah.Waterland@Sun.COM 	if (nflag) {
598*9781SMoriah.Waterland@Sun.COM 		for (i = 0; eptlist[i]; i++)
599*9781SMoriah.Waterland@Sun.COM 			(void) ppkgmap(eptlist[i], stdout);
600*9781SMoriah.Waterland@Sun.COM 		exit(0);
601*9781SMoriah.Waterland@Sun.COM 		/*NOTREACHED*/
602*9781SMoriah.Waterland@Sun.COM 	}
603*9781SMoriah.Waterland@Sun.COM 
604*9781SMoriah.Waterland@Sun.COM 	(void) snprintf(pkgloc, sizeof (pkgloc), "%s/%s",
605*9781SMoriah.Waterland@Sun.COM 			pkgdev.dirname, pkginst);
606*9781SMoriah.Waterland@Sun.COM 	if (!isdir(pkgloc) && !overwrite) {
607*9781SMoriah.Waterland@Sun.COM 		progerr(gettext(ERR_OVERWRITE), pkgloc);
608*9781SMoriah.Waterland@Sun.COM 		quit(1);
609*9781SMoriah.Waterland@Sun.COM 	}
610*9781SMoriah.Waterland@Sun.COM 
611*9781SMoriah.Waterland@Sun.COM 	/* output all environment install parameters */
612*9781SMoriah.Waterland@Sun.COM 	t_pkginfo = tempnam(tmpdir, "pkginfo");
613*9781SMoriah.Waterland@Sun.COM 	if ((fp = fopen(t_pkginfo, "w")) == NULL) {
614*9781SMoriah.Waterland@Sun.COM 		progerr(gettext(ERR_TEMP), errno);
615*9781SMoriah.Waterland@Sun.COM 		exit(99);
616*9781SMoriah.Waterland@Sun.COM 	}
617*9781SMoriah.Waterland@Sun.COM 	for (i = 0; environ[i]; i++) {
618*9781SMoriah.Waterland@Sun.COM 		if (isupper(*environ[i])) {
619*9781SMoriah.Waterland@Sun.COM 			(void) fputs(environ[i], fp);
620*9781SMoriah.Waterland@Sun.COM 			(void) fputc('\n', fp);
621*9781SMoriah.Waterland@Sun.COM 		}
622*9781SMoriah.Waterland@Sun.COM 	}
623*9781SMoriah.Waterland@Sun.COM 	(void) fclose(fp);
624*9781SMoriah.Waterland@Sun.COM 
625*9781SMoriah.Waterland@Sun.COM 	started++;
626*9781SMoriah.Waterland@Sun.COM 	(void) rrmdir(pkgloc);
627*9781SMoriah.Waterland@Sun.COM 	if (mkdir(pkgloc, 0755)) {
628*9781SMoriah.Waterland@Sun.COM 		progerr(gettext(ERR_MKDIR), pkgloc);
629*9781SMoriah.Waterland@Sun.COM 		quit(1);
630*9781SMoriah.Waterland@Sun.COM 	}
631*9781SMoriah.Waterland@Sun.COM 
632*9781SMoriah.Waterland@Sun.COM 	/* determine how many packages already reside on the medium */
633*9781SMoriah.Waterland@Sun.COM 	pkgdir = pkgdev.dirname;
634*9781SMoriah.Waterland@Sun.COM 	npkgs = 0;
635*9781SMoriah.Waterland@Sun.COM 	while (pt = fpkginst("all", NULL, NULL))
636*9781SMoriah.Waterland@Sun.COM 		npkgs++;
637*9781SMoriah.Waterland@Sun.COM 	(void) fpkginst(NULL); /* free resource usage */
638*9781SMoriah.Waterland@Sun.COM 
639*9781SMoriah.Waterland@Sun.COM 	if (nparts > 1) {
640*9781SMoriah.Waterland@Sun.COM 		if (pkgdev.mount && npkgs) {
641*9781SMoriah.Waterland@Sun.COM 			progerr(gettext(ERR_ONEVOL));
642*9781SMoriah.Waterland@Sun.COM 			quit(1);
643*9781SMoriah.Waterland@Sun.COM 		}
644*9781SMoriah.Waterland@Sun.COM 	}
645*9781SMoriah.Waterland@Sun.COM 
646*9781SMoriah.Waterland@Sun.COM 	/*
647*9781SMoriah.Waterland@Sun.COM 	 *  update pkgmap entry for pkginfo file, since it may
648*9781SMoriah.Waterland@Sun.COM 	 *  have changed due to command line or failure to
649*9781SMoriah.Waterland@Sun.COM 	 *  specify all neccessary parameters
650*9781SMoriah.Waterland@Sun.COM 	 */
651*9781SMoriah.Waterland@Sun.COM 	for (i = 0; eptlist[i]; i++) {
652*9781SMoriah.Waterland@Sun.COM 		if (eptlist[i]->ftype != 'i')
653*9781SMoriah.Waterland@Sun.COM 			continue;
654*9781SMoriah.Waterland@Sun.COM 		if (strcmp(eptlist[i]->path, "pkginfo") == 0) {
655*9781SMoriah.Waterland@Sun.COM 			svept = eptlist[i];
656*9781SMoriah.Waterland@Sun.COM 			svept->ftype = '?';
657*9781SMoriah.Waterland@Sun.COM 			svept->ainfo.local = t_pkginfo;
658*9781SMoriah.Waterland@Sun.COM 			(void) cverify(0, &svept->ftype, t_pkginfo,
659*9781SMoriah.Waterland@Sun.COM 				&svept->cinfo, 1);
660*9781SMoriah.Waterland@Sun.COM 			svept->ftype = 'i';
661*9781SMoriah.Waterland@Sun.COM 			break;
662*9781SMoriah.Waterland@Sun.COM 		}
663*9781SMoriah.Waterland@Sun.COM 	}
664*9781SMoriah.Waterland@Sun.COM 
665*9781SMoriah.Waterland@Sun.COM 	if (nparts > 1)
666*9781SMoriah.Waterland@Sun.COM 		(void) fprintf(stderr, gettext(MSG_PACKAGEM), nparts);
667*9781SMoriah.Waterland@Sun.COM 	else
668*9781SMoriah.Waterland@Sun.COM 		(void) fprintf(stderr, gettext(MSG_PACKAGE1));
669*9781SMoriah.Waterland@Sun.COM 
670*9781SMoriah.Waterland@Sun.COM 	for (part = 1; part <= nparts; part++) {
671*9781SMoriah.Waterland@Sun.COM 		if ((part > 1) && pkgdev.mount) {
672*9781SMoriah.Waterland@Sun.COM 			if (pkgumount(&pkgdev)) {
673*9781SMoriah.Waterland@Sun.COM 				progerr(gettext(ERR_UMOUNT), pkgdev.mount);
674*9781SMoriah.Waterland@Sun.COM 				quit(99);
675*9781SMoriah.Waterland@Sun.COM 			}
676*9781SMoriah.Waterland@Sun.COM 			if (n = pkgmount(&pkgdev, NULL, part, nparts, 1))
677*9781SMoriah.Waterland@Sun.COM 				quit(n);
678*9781SMoriah.Waterland@Sun.COM 			(void) rrmdir(pkgloc);
679*9781SMoriah.Waterland@Sun.COM 			if (mkdir(pkgloc, 0555)) {
680*9781SMoriah.Waterland@Sun.COM 				progerr(gettext(ERR_MKDIR), pkgloc);
681*9781SMoriah.Waterland@Sun.COM 				quit(99);
682*9781SMoriah.Waterland@Sun.COM 			}
683*9781SMoriah.Waterland@Sun.COM 		}
684*9781SMoriah.Waterland@Sun.COM 		outvol(eptlist, eptnum, part, nparts);
685*9781SMoriah.Waterland@Sun.COM 
686*9781SMoriah.Waterland@Sun.COM 		/* Validate (as much as possible) the control scripts. */
687*9781SMoriah.Waterland@Sun.COM 		if (part == 1) {
688*9781SMoriah.Waterland@Sun.COM 			char inst_path[PATH_MAX];
689*9781SMoriah.Waterland@Sun.COM 
690*9781SMoriah.Waterland@Sun.COM 			(void) fprintf(stderr, gettext(MSG_VALSCRIPTS));
691*9781SMoriah.Waterland@Sun.COM 			(void) snprintf(inst_path, sizeof (inst_path),
692*9781SMoriah.Waterland@Sun.COM 					"%s/install", pkgloc);
693*9781SMoriah.Waterland@Sun.COM 			checkscripts(inst_path, 0);
694*9781SMoriah.Waterland@Sun.COM 		}
695*9781SMoriah.Waterland@Sun.COM 	}
696*9781SMoriah.Waterland@Sun.COM 
697*9781SMoriah.Waterland@Sun.COM 	quit(0);
698*9781SMoriah.Waterland@Sun.COM 	/* LINTED: no return */
699*9781SMoriah.Waterland@Sun.COM }
700*9781SMoriah.Waterland@Sun.COM 
701*9781SMoriah.Waterland@Sun.COM static void
702*9781SMoriah.Waterland@Sun.COM trap(int n)
703*9781SMoriah.Waterland@Sun.COM {
704*9781SMoriah.Waterland@Sun.COM 	(void) signal(SIGINT, SIG_IGN);
705*9781SMoriah.Waterland@Sun.COM 	(void) signal(SIGHUP, SIG_IGN);
706*9781SMoriah.Waterland@Sun.COM 
707*9781SMoriah.Waterland@Sun.COM 	if (n == SIGINT)
708*9781SMoriah.Waterland@Sun.COM 		quit(3);
709*9781SMoriah.Waterland@Sun.COM 	else {
710*9781SMoriah.Waterland@Sun.COM 		(void) fprintf(stderr, gettext("%s terminated (signal %d).\n"),
711*9781SMoriah.Waterland@Sun.COM 				get_prog_name(), n);
712*9781SMoriah.Waterland@Sun.COM 		quit(99);
713*9781SMoriah.Waterland@Sun.COM 	}
714*9781SMoriah.Waterland@Sun.COM }
715*9781SMoriah.Waterland@Sun.COM 
716*9781SMoriah.Waterland@Sun.COM static void
717*9781SMoriah.Waterland@Sun.COM outvol(struct cfent **eptlist, unsigned int eptnum, int part, int nparts)
718*9781SMoriah.Waterland@Sun.COM {
719*9781SMoriah.Waterland@Sun.COM 	FILE	*fp;
720*9781SMoriah.Waterland@Sun.COM 	char	*svpt, *path, temp[PATH_MAX];
721*9781SMoriah.Waterland@Sun.COM 	unsigned int	i;
722*9781SMoriah.Waterland@Sun.COM 
723*9781SMoriah.Waterland@Sun.COM 
724*9781SMoriah.Waterland@Sun.COM 	if (nparts > 1)
725*9781SMoriah.Waterland@Sun.COM 		(void) fprintf(stderr, gettext(" -- part %2d:\n"), part);
726*9781SMoriah.Waterland@Sun.COM 	if (part == 1) {
727*9781SMoriah.Waterland@Sun.COM 		/* re-write pkgmap, but exclude local pathnames */
728*9781SMoriah.Waterland@Sun.COM 		(void) snprintf(temp, sizeof (temp), "%s/pkgmap", pkgloc);
729*9781SMoriah.Waterland@Sun.COM 		if ((fp = fopen(temp, "w")) == NULL) {
730*9781SMoriah.Waterland@Sun.COM 			progerr(gettext(ERR_TEMP), errno);
731*9781SMoriah.Waterland@Sun.COM 			quit(99);
732*9781SMoriah.Waterland@Sun.COM 		}
733*9781SMoriah.Waterland@Sun.COM 		(void) fprintf(fp, ": %d %ld\n", nparts, limit);
734*9781SMoriah.Waterland@Sun.COM 		for (i = 0; eptlist[i]; i++) {
735*9781SMoriah.Waterland@Sun.COM 			svpt = eptlist[i]->ainfo.local;
736*9781SMoriah.Waterland@Sun.COM 			if (!strchr("sl", eptlist[i]->ftype))
737*9781SMoriah.Waterland@Sun.COM 				eptlist[i]->ainfo.local = NULL;
738*9781SMoriah.Waterland@Sun.COM 			if (ppkgmap(eptlist[i], fp)) {
739*9781SMoriah.Waterland@Sun.COM 				progerr(gettext(ERR_TEMP), errno);
740*9781SMoriah.Waterland@Sun.COM 				quit(99);
741*9781SMoriah.Waterland@Sun.COM 			}
742*9781SMoriah.Waterland@Sun.COM 			eptlist[i]->ainfo.local = svpt;
743*9781SMoriah.Waterland@Sun.COM 		}
744*9781SMoriah.Waterland@Sun.COM 		(void) fclose(fp);
745*9781SMoriah.Waterland@Sun.COM 		(void) fprintf(stderr, "%s\n", temp);
746*9781SMoriah.Waterland@Sun.COM 	}
747*9781SMoriah.Waterland@Sun.COM 
748*9781SMoriah.Waterland@Sun.COM 	(void) snprintf(temp, sizeof (temp), "%s/pkginfo", pkgloc);
749*9781SMoriah.Waterland@Sun.COM 	if (copyf(svept->ainfo.local, temp, svept->cinfo.modtime))
750*9781SMoriah.Waterland@Sun.COM 		quit(1);
751*9781SMoriah.Waterland@Sun.COM 	(void) fprintf(stderr, "%s\n", temp);
752*9781SMoriah.Waterland@Sun.COM 
753*9781SMoriah.Waterland@Sun.COM 	for (i = 0; i < eptnum; i++) {
754*9781SMoriah.Waterland@Sun.COM 		if (eptlist[i]->volno != part)
755*9781SMoriah.Waterland@Sun.COM 			continue;
756*9781SMoriah.Waterland@Sun.COM 		if (strchr("dxslcbp", eptlist[i]->ftype))
757*9781SMoriah.Waterland@Sun.COM 			continue;
758*9781SMoriah.Waterland@Sun.COM 		if (eptlist[i]->ftype == 'i') {
759*9781SMoriah.Waterland@Sun.COM 			if (eptlist[i] == svept)
760*9781SMoriah.Waterland@Sun.COM 				continue; /* don't copy pkginfo file */
761*9781SMoriah.Waterland@Sun.COM 			(void) snprintf(temp, sizeof (temp),
762*9781SMoriah.Waterland@Sun.COM 				"%s/install/%s", pkgloc,
763*9781SMoriah.Waterland@Sun.COM 				eptlist[i]->path);
764*9781SMoriah.Waterland@Sun.COM 			path = temp;
765*9781SMoriah.Waterland@Sun.COM 		} else
766*9781SMoriah.Waterland@Sun.COM 			path = srcpath(pkgloc, eptlist[i]->path, part, nparts);
767*9781SMoriah.Waterland@Sun.COM 		if (sflag) {
768*9781SMoriah.Waterland@Sun.COM 			if (slinkf(eptlist[i]->ainfo.local, path))
769*9781SMoriah.Waterland@Sun.COM 				quit(1);
770*9781SMoriah.Waterland@Sun.COM 		} else if (copyf(eptlist[i]->ainfo.local, path,
771*9781SMoriah.Waterland@Sun.COM 				eptlist[i]->cinfo.modtime)) {
772*9781SMoriah.Waterland@Sun.COM 			quit(1);
773*9781SMoriah.Waterland@Sun.COM 		}
774*9781SMoriah.Waterland@Sun.COM 
775*9781SMoriah.Waterland@Sun.COM 		/*
776*9781SMoriah.Waterland@Sun.COM 		 * If the package file attributes can be sync'd up with
777*9781SMoriah.Waterland@Sun.COM 		 * the pkgmap, we fix the attributes here.
778*9781SMoriah.Waterland@Sun.COM 		 */
779*9781SMoriah.Waterland@Sun.COM 		if (*(eptlist[i]->ainfo.owner) != '$' &&
780*9781SMoriah.Waterland@Sun.COM 		    *(eptlist[i]->ainfo.group) != '$' && getuid() == 0) {
781*9781SMoriah.Waterland@Sun.COM 			/* Clear dangerous bits. */
782*9781SMoriah.Waterland@Sun.COM 			eptlist[i]->ainfo.mode=
783*9781SMoriah.Waterland@Sun.COM 			    (eptlist[i]->ainfo.mode & S_IAMB);
784*9781SMoriah.Waterland@Sun.COM 			/*
785*9781SMoriah.Waterland@Sun.COM 			 * Make sure it can be read by the world and written
786*9781SMoriah.Waterland@Sun.COM 			 * by root.
787*9781SMoriah.Waterland@Sun.COM 			 */
788*9781SMoriah.Waterland@Sun.COM 			eptlist[i]->ainfo.mode |= 0644;
789*9781SMoriah.Waterland@Sun.COM 			if (!strchr("in", eptlist[i]->ftype)) {
790*9781SMoriah.Waterland@Sun.COM 				/* Set the safe attributes. */
791*9781SMoriah.Waterland@Sun.COM 				averify(1, &(eptlist[i]->ftype),
792*9781SMoriah.Waterland@Sun.COM 				    path, &(eptlist[i]->ainfo));
793*9781SMoriah.Waterland@Sun.COM 			}
794*9781SMoriah.Waterland@Sun.COM 		}
795*9781SMoriah.Waterland@Sun.COM 
796*9781SMoriah.Waterland@Sun.COM 		(void) fprintf(stderr, "%s\n", path);
797*9781SMoriah.Waterland@Sun.COM 	}
798*9781SMoriah.Waterland@Sun.COM }
799*9781SMoriah.Waterland@Sun.COM 
800*9781SMoriah.Waterland@Sun.COM static void
801*9781SMoriah.Waterland@Sun.COM ckmissing(char *path, char type)
802*9781SMoriah.Waterland@Sun.COM {
803*9781SMoriah.Waterland@Sun.COM 	static char	**dir;
804*9781SMoriah.Waterland@Sun.COM 	static int	ndir;
805*9781SMoriah.Waterland@Sun.COM 	char	*pt;
806*9781SMoriah.Waterland@Sun.COM 	int	i, found;
807*9781SMoriah.Waterland@Sun.COM 
808*9781SMoriah.Waterland@Sun.COM 	if (dir == NULL) {
809*9781SMoriah.Waterland@Sun.COM 		dir = (char **)calloc(MALSIZ, sizeof (char *));
810*9781SMoriah.Waterland@Sun.COM 		if (dir == NULL) {
811*9781SMoriah.Waterland@Sun.COM 			progerr(gettext(ERR_MEMORY), errno);
812*9781SMoriah.Waterland@Sun.COM 			quit(99);
813*9781SMoriah.Waterland@Sun.COM 		}
814*9781SMoriah.Waterland@Sun.COM 	}
815*9781SMoriah.Waterland@Sun.COM 
816*9781SMoriah.Waterland@Sun.COM 	if (strchr("dx", type)) {
817*9781SMoriah.Waterland@Sun.COM 		dir[ndir] = path;
818*9781SMoriah.Waterland@Sun.COM 		if ((++ndir % MALSIZ) == 0) {
819*9781SMoriah.Waterland@Sun.COM 			dir = (char **)realloc((void *)dir,
820*9781SMoriah.Waterland@Sun.COM 				(ndir+MALSIZ)*sizeof (char *));
821*9781SMoriah.Waterland@Sun.COM 			if (dir == NULL) {
822*9781SMoriah.Waterland@Sun.COM 				progerr(gettext(ERR_MEMORY), errno);
823*9781SMoriah.Waterland@Sun.COM 				quit(99);
824*9781SMoriah.Waterland@Sun.COM 			}
825*9781SMoriah.Waterland@Sun.COM 		}
826*9781SMoriah.Waterland@Sun.COM 		dir[ndir] = (char *)NULL;
827*9781SMoriah.Waterland@Sun.COM 	}
828*9781SMoriah.Waterland@Sun.COM 
829*9781SMoriah.Waterland@Sun.COM 	pt = path;
830*9781SMoriah.Waterland@Sun.COM 	if (*pt == '/')
831*9781SMoriah.Waterland@Sun.COM 		pt++;
832*9781SMoriah.Waterland@Sun.COM 	while (pt = strchr(pt, '/')) {
833*9781SMoriah.Waterland@Sun.COM 		*pt = '\0';
834*9781SMoriah.Waterland@Sun.COM 		found = 0;
835*9781SMoriah.Waterland@Sun.COM 		for (i = 0; i < ndir; i++) {
836*9781SMoriah.Waterland@Sun.COM 			if (strcmp(path, dir[i]) == 0) {
837*9781SMoriah.Waterland@Sun.COM 				found++;
838*9781SMoriah.Waterland@Sun.COM 				break;
839*9781SMoriah.Waterland@Sun.COM 			}
840*9781SMoriah.Waterland@Sun.COM 		}
841*9781SMoriah.Waterland@Sun.COM 		if (!found) {
842*9781SMoriah.Waterland@Sun.COM 			logerr(gettext(WRN_MISSINGDIR), path);
843*9781SMoriah.Waterland@Sun.COM 			ckmissing(qstrdup(path), 'd');
844*9781SMoriah.Waterland@Sun.COM 		}
845*9781SMoriah.Waterland@Sun.COM 		*pt++ = '/';
846*9781SMoriah.Waterland@Sun.COM 	}
847*9781SMoriah.Waterland@Sun.COM }
848*9781SMoriah.Waterland@Sun.COM 
849*9781SMoriah.Waterland@Sun.COM static int
850*9781SMoriah.Waterland@Sun.COM slinkf(char *from, char *to)
851*9781SMoriah.Waterland@Sun.COM {
852*9781SMoriah.Waterland@Sun.COM 	char	*pt;
853*9781SMoriah.Waterland@Sun.COM 
854*9781SMoriah.Waterland@Sun.COM 	pt = to;
855*9781SMoriah.Waterland@Sun.COM 	while (pt = strchr(pt+1, '/')) {
856*9781SMoriah.Waterland@Sun.COM 		*pt = '\0';
857*9781SMoriah.Waterland@Sun.COM 		if (isdir(to) && mkdir(to, 0755)) {
858*9781SMoriah.Waterland@Sun.COM 			progerr(gettext(ERR_MKDIR), to);
859*9781SMoriah.Waterland@Sun.COM 			*pt = '/';
860*9781SMoriah.Waterland@Sun.COM 			return (-1);
861*9781SMoriah.Waterland@Sun.COM 		}
862*9781SMoriah.Waterland@Sun.COM 		*pt = '/';
863*9781SMoriah.Waterland@Sun.COM 	}
864*9781SMoriah.Waterland@Sun.COM 	if (symlink(from, to)) {
865*9781SMoriah.Waterland@Sun.COM 		progerr(gettext(ERR_SYMLINK), to);
866*9781SMoriah.Waterland@Sun.COM 		return (-1);
867*9781SMoriah.Waterland@Sun.COM 	}
868*9781SMoriah.Waterland@Sun.COM 	return (0);
869*9781SMoriah.Waterland@Sun.COM }
870*9781SMoriah.Waterland@Sun.COM 
871*9781SMoriah.Waterland@Sun.COM static void
872*9781SMoriah.Waterland@Sun.COM usage(void)
873*9781SMoriah.Waterland@Sun.COM {
874*9781SMoriah.Waterland@Sun.COM 	(void) fprintf(stderr, gettext(ERR_USAGE), get_prog_name());
875*9781SMoriah.Waterland@Sun.COM 	exit(1);
876*9781SMoriah.Waterland@Sun.COM 	/*NOTREACHED*/
877*9781SMoriah.Waterland@Sun.COM }
878*9781SMoriah.Waterland@Sun.COM 
879*9781SMoriah.Waterland@Sun.COM /*
880*9781SMoriah.Waterland@Sun.COM  * valid_zone_attr:	Validates the zone attributes specified in
881*9781SMoriah.Waterland@Sun.COM  *			pkginfo file for this package. The package
882*9781SMoriah.Waterland@Sun.COM  *			can not be created with certain combinations
883*9781SMoriah.Waterland@Sun.COM  *			of the attributes.
884*9781SMoriah.Waterland@Sun.COM  */
885*9781SMoriah.Waterland@Sun.COM static boolean_t
886*9781SMoriah.Waterland@Sun.COM valid_zone_attr(struct cfent **eptlist)
887*9781SMoriah.Waterland@Sun.COM {
888*9781SMoriah.Waterland@Sun.COM 	FILE		*pkginfoFP;
889*9781SMoriah.Waterland@Sun.COM 	boolean_t	all_zones;	/* pkg is "all zones" only */
890*9781SMoriah.Waterland@Sun.COM 	boolean_t	is_hollow;	/* pkg is "hollow" */
891*9781SMoriah.Waterland@Sun.COM 	boolean_t	this_zone;	/* pkg is "this zone" only */
892*9781SMoriah.Waterland@Sun.COM 	char 		pkginfoPath[PATH_MAX];	/* pkginfo file path */
893*9781SMoriah.Waterland@Sun.COM 	char		*pkgInst;
894*9781SMoriah.Waterland@Sun.COM 	int i;
895*9781SMoriah.Waterland@Sun.COM 
896*9781SMoriah.Waterland@Sun.COM 	/* Path to pkginfo file within the package to be installed */
897*9781SMoriah.Waterland@Sun.COM 
898*9781SMoriah.Waterland@Sun.COM 	this_zone = B_FALSE;
899*9781SMoriah.Waterland@Sun.COM 	for (i = 0; eptlist[i]; i++) {
900*9781SMoriah.Waterland@Sun.COM 		if (eptlist[i]->ftype != 'i')
901*9781SMoriah.Waterland@Sun.COM 			continue;
902*9781SMoriah.Waterland@Sun.COM 		if (strcmp(eptlist[i]->path, "pkginfo") == 0)
903*9781SMoriah.Waterland@Sun.COM 			(void) strcpy(pkginfoPath, eptlist[i]->ainfo.local);
904*9781SMoriah.Waterland@Sun.COM 
905*9781SMoriah.Waterland@Sun.COM 		/*
906*9781SMoriah.Waterland@Sun.COM 		 * Check to see if this package has a request script. If this
907*9781SMoriah.Waterland@Sun.COM 		 * package does have a request script, then mark the package
908*9781SMoriah.Waterland@Sun.COM 		 * for installation in this zone only. Any package with a
909*9781SMoriah.Waterland@Sun.COM 		 * request script cannot be installed outside of the zone the
910*9781SMoriah.Waterland@Sun.COM 		 * pkgadd command is being run in, nor can such a package be
911*9781SMoriah.Waterland@Sun.COM 		 * installed as part of a new zone install. A new zone install
912*9781SMoriah.Waterland@Sun.COM 		 * must be non-interactive, which is required by all packages
913*9781SMoriah.Waterland@Sun.COM 		 * integrated into the Solaris WOS.
914*9781SMoriah.Waterland@Sun.COM 		 * If request file is set in prototype, then this_zone is TRUE.
915*9781SMoriah.Waterland@Sun.COM 		 */
916*9781SMoriah.Waterland@Sun.COM 		if (strcmp(eptlist[i]->path, "request") == 0)
917*9781SMoriah.Waterland@Sun.COM 			this_zone = B_TRUE;
918*9781SMoriah.Waterland@Sun.COM 	}
919*9781SMoriah.Waterland@Sun.COM 
920*9781SMoriah.Waterland@Sun.COM 	/* Gather information from the pkginfo file */
921*9781SMoriah.Waterland@Sun.COM 
922*9781SMoriah.Waterland@Sun.COM 	pkginfoFP = fopen(pkginfoPath, "r");
923*9781SMoriah.Waterland@Sun.COM 
924*9781SMoriah.Waterland@Sun.COM 	if (pkginfoFP == NULL) {
925*9781SMoriah.Waterland@Sun.COM 		progerr(ERR_NO_PKG_INFOFILE, pkginfoPath, strerror(errno));
926*9781SMoriah.Waterland@Sun.COM 		return (B_FALSE);
927*9781SMoriah.Waterland@Sun.COM 	}
928*9781SMoriah.Waterland@Sun.COM 
929*9781SMoriah.Waterland@Sun.COM 	if ((pkgInst = fpkgparam(pkginfoFP, "PKG")) == NULL) {
930*9781SMoriah.Waterland@Sun.COM 		progerr(gettext(ERR_NOPARAM), "PKG", pkginfoPath);
931*9781SMoriah.Waterland@Sun.COM 		return (B_FALSE);
932*9781SMoriah.Waterland@Sun.COM 	}
933*9781SMoriah.Waterland@Sun.COM 
934*9781SMoriah.Waterland@Sun.COM 
935*9781SMoriah.Waterland@Sun.COM 	/* Determine "HOLLOW" setting for this package */
936*9781SMoriah.Waterland@Sun.COM 	is_hollow = pkginfoParamTruth(pkginfoFP, PKG_HOLLOW_VARIABLE,
937*9781SMoriah.Waterland@Sun.COM 			"true", B_FALSE);
938*9781SMoriah.Waterland@Sun.COM 
939*9781SMoriah.Waterland@Sun.COM 	/* Determine "ALLZONES" setting for this package */
940*9781SMoriah.Waterland@Sun.COM 	all_zones = pkginfoParamTruth(pkginfoFP, PKG_ALLZONES_VARIABLE,
941*9781SMoriah.Waterland@Sun.COM 			"true", B_FALSE);
942*9781SMoriah.Waterland@Sun.COM 
943*9781SMoriah.Waterland@Sun.COM 	/* Determine "THISZONE" setting for this package, if no request file */
944*9781SMoriah.Waterland@Sun.COM 	if (!this_zone)
945*9781SMoriah.Waterland@Sun.COM 		this_zone = pkginfoParamTruth(pkginfoFP, PKG_THISZONE_VARIABLE,
946*9781SMoriah.Waterland@Sun.COM 			"true", B_FALSE);
947*9781SMoriah.Waterland@Sun.COM 
948*9781SMoriah.Waterland@Sun.COM 	/* Close pkginfo file */
949*9781SMoriah.Waterland@Sun.COM 	(void) fclose(pkginfoFP);
950*9781SMoriah.Waterland@Sun.COM 
951*9781SMoriah.Waterland@Sun.COM 	/*
952*9781SMoriah.Waterland@Sun.COM 	 * Validate zone attributes based on information gathered,
953*9781SMoriah.Waterland@Sun.COM 	 * and validate the three SUNW_PKG_ options:
954*9781SMoriah.Waterland@Sun.COM 	 *
955*9781SMoriah.Waterland@Sun.COM 	 * -----------------------------|---------------|
956*9781SMoriah.Waterland@Sun.COM 	 * <ALLZONES><HOLLOW><THISZONE> |  If Allowed   |
957*9781SMoriah.Waterland@Sun.COM 	 * ----1------------------------|---------------|
958*9781SMoriah.Waterland@Sun.COM 	 *		F F F		|	OK	|
959*9781SMoriah.Waterland@Sun.COM 	 *		F F T		|	OK	|
960*9781SMoriah.Waterland@Sun.COM 	 *		F T *		|	NO	|
961*9781SMoriah.Waterland@Sun.COM 	 * ----2------------------------|---------------|
962*9781SMoriah.Waterland@Sun.COM 	 *		T F F		|	OK	|
963*9781SMoriah.Waterland@Sun.COM 	 *		T T F		|	OK	|
964*9781SMoriah.Waterland@Sun.COM 	 *		T * T		|	NO	|
965*9781SMoriah.Waterland@Sun.COM 	 * -----------------------------|---------------|
966*9781SMoriah.Waterland@Sun.COM 	 */
967*9781SMoriah.Waterland@Sun.COM 
968*9781SMoriah.Waterland@Sun.COM 	/* pkg "all zones" && "this zone" (#2) */
969*9781SMoriah.Waterland@Sun.COM 
970*9781SMoriah.Waterland@Sun.COM 	if (all_zones && this_zone) {
971*9781SMoriah.Waterland@Sun.COM 		progerr(ERR_ALLZONES_AND_THISZONE, pkgInst,
972*9781SMoriah.Waterland@Sun.COM 		    PKG_ALLZONES_VARIABLE, PKG_THISZONE_VARIABLE);
973*9781SMoriah.Waterland@Sun.COM 		return (B_FALSE);
974*9781SMoriah.Waterland@Sun.COM 	}
975*9781SMoriah.Waterland@Sun.COM 
976*9781SMoriah.Waterland@Sun.COM 	/* pkg "!all zones" && "hollow" (#1) */
977*9781SMoriah.Waterland@Sun.COM 
978*9781SMoriah.Waterland@Sun.COM 	if ((!all_zones) && is_hollow) {
979*9781SMoriah.Waterland@Sun.COM 		progerr(ERR_NO_ALLZONES_AND_HOLLOW, pkgInst,
980*9781SMoriah.Waterland@Sun.COM 		    PKG_ALLZONES_VARIABLE, PKG_HOLLOW_VARIABLE);
981*9781SMoriah.Waterland@Sun.COM 		return (B_FALSE);
982*9781SMoriah.Waterland@Sun.COM 	}
983*9781SMoriah.Waterland@Sun.COM 
984*9781SMoriah.Waterland@Sun.COM 	return (B_TRUE);
985*9781SMoriah.Waterland@Sun.COM }
986