xref: /onnv-gate/usr/src/cmd/svr4pkg/pkgmk/main.c (revision 11956:872ffb603131)
19781SMoriah.Waterland@Sun.COM /*
29781SMoriah.Waterland@Sun.COM  * CDDL HEADER START
39781SMoriah.Waterland@Sun.COM  *
49781SMoriah.Waterland@Sun.COM  * The contents of this file are subject to the terms of the
59781SMoriah.Waterland@Sun.COM  * Common Development and Distribution License (the "License").
69781SMoriah.Waterland@Sun.COM  * You may not use this file except in compliance with the License.
79781SMoriah.Waterland@Sun.COM  *
89781SMoriah.Waterland@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
99781SMoriah.Waterland@Sun.COM  * or http://www.opensolaris.org/os/licensing.
109781SMoriah.Waterland@Sun.COM  * See the License for the specific language governing permissions
119781SMoriah.Waterland@Sun.COM  * and limitations under the License.
129781SMoriah.Waterland@Sun.COM  *
139781SMoriah.Waterland@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
149781SMoriah.Waterland@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
159781SMoriah.Waterland@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
169781SMoriah.Waterland@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
179781SMoriah.Waterland@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
189781SMoriah.Waterland@Sun.COM  *
199781SMoriah.Waterland@Sun.COM  * CDDL HEADER END
209781SMoriah.Waterland@Sun.COM  */
219781SMoriah.Waterland@Sun.COM 
229781SMoriah.Waterland@Sun.COM /*
23*11956SNagaraj.Yedathore@Sun.COM  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
249781SMoriah.Waterland@Sun.COM  * Use is subject to license terms.
259781SMoriah.Waterland@Sun.COM  */
269781SMoriah.Waterland@Sun.COM 
279781SMoriah.Waterland@Sun.COM /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
289781SMoriah.Waterland@Sun.COM /* All Rights Reserved */
299781SMoriah.Waterland@Sun.COM 
309781SMoriah.Waterland@Sun.COM 
319781SMoriah.Waterland@Sun.COM #include <stdio.h>
329781SMoriah.Waterland@Sun.COM #include <string.h>
339781SMoriah.Waterland@Sun.COM #include <signal.h>
349781SMoriah.Waterland@Sun.COM #include <errno.h>
359781SMoriah.Waterland@Sun.COM #include <malloc.h>
369781SMoriah.Waterland@Sun.COM #include <stdlib.h>
379781SMoriah.Waterland@Sun.COM #include <unistd.h>
389781SMoriah.Waterland@Sun.COM #include <time.h>
399781SMoriah.Waterland@Sun.COM #include <fcntl.h>
409781SMoriah.Waterland@Sun.COM #include <sys/types.h>
419781SMoriah.Waterland@Sun.COM #include <sys/stat.h>
429781SMoriah.Waterland@Sun.COM #include <sys/param.h>
439781SMoriah.Waterland@Sun.COM #include <ctype.h>
449781SMoriah.Waterland@Sun.COM #include <sys/mman.h>
459781SMoriah.Waterland@Sun.COM #include <sys/sysmacros.h>
469781SMoriah.Waterland@Sun.COM #include <strings.h>
479781SMoriah.Waterland@Sun.COM #include <pkgstrct.h>
489781SMoriah.Waterland@Sun.COM #include <pkgdev.h>
499781SMoriah.Waterland@Sun.COM #include <pkginfo.h>
509781SMoriah.Waterland@Sun.COM #include <pkglocs.h>
519781SMoriah.Waterland@Sun.COM #include <locale.h>
529781SMoriah.Waterland@Sun.COM #include <libintl.h>
539781SMoriah.Waterland@Sun.COM #include <sys/statvfs.h>
549781SMoriah.Waterland@Sun.COM #include <sys/utsname.h>
559781SMoriah.Waterland@Sun.COM #include <instzones_api.h>
569781SMoriah.Waterland@Sun.COM #include <pkglib.h>
579781SMoriah.Waterland@Sun.COM #include <libadm.h>
589781SMoriah.Waterland@Sun.COM #include <libinst.h>
599781SMoriah.Waterland@Sun.COM 
609781SMoriah.Waterland@Sun.COM extern char	**environ, *pkgdir;
619781SMoriah.Waterland@Sun.COM 
629781SMoriah.Waterland@Sun.COM /* mkpkgmap.c */
639781SMoriah.Waterland@Sun.COM extern int	mkpkgmap(char *outfile, char *protofile, char **cmdparam);
649781SMoriah.Waterland@Sun.COM /* splpkgmap.c */
659781SMoriah.Waterland@Sun.COM extern int	splpkgmap(struct cfent **eptlist, unsigned int eptnum,
669781SMoriah.Waterland@Sun.COM     char *order[], ulong_t bsize, ulong_t frsize, fsblkcnt_t *plimit,
679781SMoriah.Waterland@Sun.COM     fsfilcnt_t *pilimit, fsblkcnt_t *pllimit);
689781SMoriah.Waterland@Sun.COM /* scriptvfy.c */
699781SMoriah.Waterland@Sun.COM extern int	checkscripts(char *inst_dir, int silent);
709781SMoriah.Waterland@Sun.COM 
719781SMoriah.Waterland@Sun.COM /* libpkg/gpkgmap.c */
729781SMoriah.Waterland@Sun.COM extern void	setmapmode(int mode_no);
739781SMoriah.Waterland@Sun.COM 
749781SMoriah.Waterland@Sun.COM static boolean_t valid_zone_attr(struct cfent **eptlist);
759781SMoriah.Waterland@Sun.COM 
769781SMoriah.Waterland@Sun.COM #define	MALSIZ	16
779781SMoriah.Waterland@Sun.COM #define	NROOT	8
789781SMoriah.Waterland@Sun.COM #define	SPOOLDEV	"spool"
799781SMoriah.Waterland@Sun.COM 
809781SMoriah.Waterland@Sun.COM #define	MSG_PROTOTYPE	"## Building pkgmap from package prototype file.\n"
819781SMoriah.Waterland@Sun.COM #define	MSG_PKGINFO	"## Processing pkginfo file.\n"
829781SMoriah.Waterland@Sun.COM #define	MSG_VOLUMIZE	"## Attempting to volumize %d entries in pkgmap.\n"
839781SMoriah.Waterland@Sun.COM #define	MSG_PACKAGE1	"## Packaging one part.\n"
849781SMoriah.Waterland@Sun.COM #define	MSG_PACKAGEM	"## Packaging %d parts.\n"
859781SMoriah.Waterland@Sun.COM #define	MSG_VALSCRIPTS	"## Validating control scripts.\n"
869781SMoriah.Waterland@Sun.COM 
879781SMoriah.Waterland@Sun.COM /* Other problems */
889781SMoriah.Waterland@Sun.COM #define	ERR_MEMORY	"memory allocation failure, errno=%d"
899781SMoriah.Waterland@Sun.COM #define	ERR_NROOT	"too many paths listed with -r option, limit is %d"
909781SMoriah.Waterland@Sun.COM #define	ERR_PKGINST	"invalid package instance identifier <%s>"
919781SMoriah.Waterland@Sun.COM #define	ERR_PKGABRV	"invalid package abbreviation <%s>"
929781SMoriah.Waterland@Sun.COM #define	ERR_BADDEV	"unknown or invalid device specified <%s>"
939781SMoriah.Waterland@Sun.COM #define	ERR_TEMP	"unable to obtain temporary file resources, errno=%d"
949781SMoriah.Waterland@Sun.COM #define	ERR_DSTREAM	"invalid device specified (datastream) <%s>"
959781SMoriah.Waterland@Sun.COM #define	ERR_SPLIT	"unable to volumize package"
969781SMoriah.Waterland@Sun.COM #define	ERR_MKDIR	"unable to make directory <%s>"
979781SMoriah.Waterland@Sun.COM #define	ERR_SYMLINK	"unable to create symbolic link for <%s>"
989781SMoriah.Waterland@Sun.COM #define	ERR_OVERWRITE	"must use -o option to overwrite <%s>"
999781SMoriah.Waterland@Sun.COM #define	ERR_UMOUNT	"unable to unmount device <%s>"
1009781SMoriah.Waterland@Sun.COM #define	ERR_NOPKGINFO	"required pkginfo file is not specified in prototype " \
1019781SMoriah.Waterland@Sun.COM 			"file"
1029781SMoriah.Waterland@Sun.COM #define	ERR_RDPKGINFO	"unable to process pkginfo file <%s>"
1039781SMoriah.Waterland@Sun.COM #define	ERR_PROTOTYPE	"unable to locate prototype file"
1049781SMoriah.Waterland@Sun.COM #define	ERR_STATVFS	"unable to stat filesystem <%s>"
1059781SMoriah.Waterland@Sun.COM #define	ERR_WHATVFS	"unable to determine or access output filesystem for " \
1069781SMoriah.Waterland@Sun.COM 			"device <%s>"
1079781SMoriah.Waterland@Sun.COM #define	ERR_DEVICE	"unable to find info for device <%s>"
1089781SMoriah.Waterland@Sun.COM #define	ERR_BUILD	"unable to build pkgmap from prototype file"
1099781SMoriah.Waterland@Sun.COM #define	ERR_ONEVOL	"other packages found - package must fit on a single " \
1109781SMoriah.Waterland@Sun.COM 			"volume"
1119781SMoriah.Waterland@Sun.COM #define	ERR_NOPARAM	"parameter <%s> is not defined in <%s>"
1129781SMoriah.Waterland@Sun.COM #define	ERR_PKGMTCH	"PKG parameter <%s> does not match instance <%s>"
1139781SMoriah.Waterland@Sun.COM #define	ERR_NO_PKG_INFOFILE	"unable to open pkginfo file <%s>: %s"
1149781SMoriah.Waterland@Sun.COM #define	ERR_ALLZONES_AND_THISZONE	"The package <%s> has <%s> = true " \
1159781SMoriah.Waterland@Sun.COM 					"and <%s> = true: the package may " \
1169781SMoriah.Waterland@Sun.COM 					"set either parameter to true, but " \
1179781SMoriah.Waterland@Sun.COM 					"may not set both parameters to " \
1189781SMoriah.Waterland@Sun.COM 					"true. NOTE: if the package " \
1199781SMoriah.Waterland@Sun.COM 					"contains a request script, it is " \
1209781SMoriah.Waterland@Sun.COM 					"treated as though it has " \
1219781SMoriah.Waterland@Sun.COM 					"<SUNW_PKG_THISZONE> = true"
1229781SMoriah.Waterland@Sun.COM #define	ERR_NO_ALLZONES_AND_HOLLOW	"The package <%s> has <%s> = false " \
1239781SMoriah.Waterland@Sun.COM 					"and <%s> = true: a hollow package " \
1249781SMoriah.Waterland@Sun.COM 					"must also be set to install in all " \
1259781SMoriah.Waterland@Sun.COM 					"zones"
1269781SMoriah.Waterland@Sun.COM #define	ERR_PKGINFO_INVALID_OPTION_COMB	"Invalid combinations of zone " \
1279781SMoriah.Waterland@Sun.COM 					"parameters in pkginfo file"
1289781SMoriah.Waterland@Sun.COM 
1299781SMoriah.Waterland@Sun.COM #define	ERR_USAGE	"usage: %s [options] [VAR=value [VAR=value]] " \
1309781SMoriah.Waterland@Sun.COM 			"[pkginst]\n" \
1319781SMoriah.Waterland@Sun.COM 			"   where options may include:\n" \
1329781SMoriah.Waterland@Sun.COM 			"\t-o\n" \
1339781SMoriah.Waterland@Sun.COM 			"\t-a arch\n" \
1349781SMoriah.Waterland@Sun.COM 			"\t-v version\n" \
1359781SMoriah.Waterland@Sun.COM 			"\t-p pstamp\n" \
1369781SMoriah.Waterland@Sun.COM 			"\t-l limit\n" \
1379781SMoriah.Waterland@Sun.COM 			"\t-r rootpath\n" \
1389781SMoriah.Waterland@Sun.COM 			"\t-b basedir\n" \
1399781SMoriah.Waterland@Sun.COM 			"\t-d device\n" \
1409781SMoriah.Waterland@Sun.COM 			"\t-f protofile\n"
1419781SMoriah.Waterland@Sun.COM #define	WRN_MISSINGDIR	"WARNING: missing directory entry for <%s>"
1429781SMoriah.Waterland@Sun.COM #define	WRN_SETPARAM	"WARNING: parameter <%s> set to \"%s\""
1439781SMoriah.Waterland@Sun.COM #define	WRN_CLASSES	"WARNING: unreferenced class <%s> in prototype file"
1449781SMoriah.Waterland@Sun.COM 
1459781SMoriah.Waterland@Sun.COM #define	LINK    1
1469781SMoriah.Waterland@Sun.COM 
1479781SMoriah.Waterland@Sun.COM struct pkgdev pkgdev; 	/* holds info about the installation device */
1489781SMoriah.Waterland@Sun.COM int	started;
1499781SMoriah.Waterland@Sun.COM char	pkgloc[PATH_MAX];
1509781SMoriah.Waterland@Sun.COM char	*basedir;
1519781SMoriah.Waterland@Sun.COM char	*root;
1529781SMoriah.Waterland@Sun.COM char	*rootlist[NROOT];
1539781SMoriah.Waterland@Sun.COM char	*t_pkgmap;
1549781SMoriah.Waterland@Sun.COM char	*t_pkginfo;
1559781SMoriah.Waterland@Sun.COM 
1569781SMoriah.Waterland@Sun.COM static struct cfent *svept;
1579781SMoriah.Waterland@Sun.COM static char	*protofile,
1589781SMoriah.Waterland@Sun.COM 		*device;
1599781SMoriah.Waterland@Sun.COM static fsblkcnt_t limit = 0;
1609781SMoriah.Waterland@Sun.COM static fsblkcnt_t llimit = 0;
1619781SMoriah.Waterland@Sun.COM static fsfilcnt_t ilimit = 0;
1629781SMoriah.Waterland@Sun.COM static int	overwrite,
1639781SMoriah.Waterland@Sun.COM 		nflag,
1649781SMoriah.Waterland@Sun.COM 		sflag;
1659781SMoriah.Waterland@Sun.COM static void	ckmissing(char *path, char type);
1669781SMoriah.Waterland@Sun.COM static void	outvol(struct cfent **eptlist, unsigned int eptnum, int part,
1679781SMoriah.Waterland@Sun.COM 			int nparts);
1689781SMoriah.Waterland@Sun.COM static void	trap(int n);
1699781SMoriah.Waterland@Sun.COM static void	usage(void);
1709781SMoriah.Waterland@Sun.COM 
1719781SMoriah.Waterland@Sun.COM static int	slinkf(char *from, char *to);
1729781SMoriah.Waterland@Sun.COM 
1739781SMoriah.Waterland@Sun.COM int
main(int argc,char * argv[])1749781SMoriah.Waterland@Sun.COM main(int argc, char *argv[])
1759781SMoriah.Waterland@Sun.COM {
1769781SMoriah.Waterland@Sun.COM 	struct utsname utsbuf;
1779781SMoriah.Waterland@Sun.COM 	struct statvfs64 svfsb;
1789781SMoriah.Waterland@Sun.COM 	struct cfent	**eptlist;
1799781SMoriah.Waterland@Sun.COM 	FILE	*fp;
1809781SMoriah.Waterland@Sun.COM 	VFP_T	*vfp;
1819781SMoriah.Waterland@Sun.COM 	int	c, n, found;
1829781SMoriah.Waterland@Sun.COM 	int	part, nparts, npkgs, objects;
1839781SMoriah.Waterland@Sun.COM 	char	buf[MAX_PKG_PARAM_LENGTH];
1849781SMoriah.Waterland@Sun.COM 	char	temp[MAX_PKG_PARAM_LENGTH];
1859781SMoriah.Waterland@Sun.COM 	char	param[MAX_PKG_PARAM_LENGTH];
1869781SMoriah.Waterland@Sun.COM 	char	*pt, *value, *pkginst, *tmpdir, *abi_sym_ptr,
1879781SMoriah.Waterland@Sun.COM 		**cmdparam;
1889781SMoriah.Waterland@Sun.COM 	char	*pkgname;
1899781SMoriah.Waterland@Sun.COM 	char	*pkgvers;
1909781SMoriah.Waterland@Sun.COM 	char	*pkgarch;
1919781SMoriah.Waterland@Sun.COM 	char	*pkgcat;
1929781SMoriah.Waterland@Sun.COM 	void	(*func)();
1939781SMoriah.Waterland@Sun.COM 	time_t	clock;
1949781SMoriah.Waterland@Sun.COM 	ulong_t	bsize = 0;
1959781SMoriah.Waterland@Sun.COM 	ulong_t	frsize = 0;
1969781SMoriah.Waterland@Sun.COM 	struct cl_attr	**allclass = NULL;
1979781SMoriah.Waterland@Sun.COM 	struct cl_attr	**order;
1989781SMoriah.Waterland@Sun.COM 	unsigned int eptnum, i;
1999781SMoriah.Waterland@Sun.COM 
2009781SMoriah.Waterland@Sun.COM 	/* initialize locale environment */
2019781SMoriah.Waterland@Sun.COM 
2029781SMoriah.Waterland@Sun.COM 	(void) setlocale(LC_ALL, "");
2039781SMoriah.Waterland@Sun.COM 
2049781SMoriah.Waterland@Sun.COM #if !defined(TEXT_DOMAIN)	/* Should be defined by cc -D */
2059781SMoriah.Waterland@Sun.COM #define	TEXT_DOMAIN "SYS_TEST"
2069781SMoriah.Waterland@Sun.COM #endif
2079781SMoriah.Waterland@Sun.COM 	(void) textdomain(TEXT_DOMAIN);
2089781SMoriah.Waterland@Sun.COM 
2099781SMoriah.Waterland@Sun.COM 	/* initialize program name */
2109781SMoriah.Waterland@Sun.COM 
2119781SMoriah.Waterland@Sun.COM 	(void) set_prog_name(argv[0]);
2129781SMoriah.Waterland@Sun.COM 
2139781SMoriah.Waterland@Sun.COM 	/* tell spmi zones interface how to access package output functions */
2149781SMoriah.Waterland@Sun.COM 
2159781SMoriah.Waterland@Sun.COM 	z_set_output_functions(echo, echoDebug, progerr);
2169781SMoriah.Waterland@Sun.COM 
2179781SMoriah.Waterland@Sun.COM 	func = sigset(SIGINT, trap);
2189781SMoriah.Waterland@Sun.COM 	if (func != SIG_DFL)
2199781SMoriah.Waterland@Sun.COM 		func = sigset(SIGINT, func);
2209781SMoriah.Waterland@Sun.COM 	func = sigset(SIGHUP, trap);
2219781SMoriah.Waterland@Sun.COM 	setmapmode(MAPBUILD);	/* variable binding */
2229781SMoriah.Waterland@Sun.COM 	if (func != SIG_DFL)
2239781SMoriah.Waterland@Sun.COM 		func = sigset(SIGHUP, func);
2249781SMoriah.Waterland@Sun.COM 
2259781SMoriah.Waterland@Sun.COM 	environ = NULL;
2269781SMoriah.Waterland@Sun.COM 	while ((c = getopt(argc, argv, "osnp:l:r:b:d:f:a:v:?")) != EOF) {
2279781SMoriah.Waterland@Sun.COM 		switch (c) {
2289781SMoriah.Waterland@Sun.COM 		    case 'n':
2299781SMoriah.Waterland@Sun.COM 			nflag++;
2309781SMoriah.Waterland@Sun.COM 			break;
2319781SMoriah.Waterland@Sun.COM 
2329781SMoriah.Waterland@Sun.COM 		    case 's':
2339781SMoriah.Waterland@Sun.COM 			sflag++;
2349781SMoriah.Waterland@Sun.COM 			break;
2359781SMoriah.Waterland@Sun.COM 
2369781SMoriah.Waterland@Sun.COM 		    case 'o':
2379781SMoriah.Waterland@Sun.COM 			overwrite++;
2389781SMoriah.Waterland@Sun.COM 			break;
2399781SMoriah.Waterland@Sun.COM 
2409781SMoriah.Waterland@Sun.COM 		    case 'p':
2419781SMoriah.Waterland@Sun.COM 			putparam("PSTAMP", optarg);
2429781SMoriah.Waterland@Sun.COM 			break;
2439781SMoriah.Waterland@Sun.COM 
2449781SMoriah.Waterland@Sun.COM 		    case 'l':
2459781SMoriah.Waterland@Sun.COM 			llimit = strtoull(optarg, NULL, 10);
2469781SMoriah.Waterland@Sun.COM 			break;
2479781SMoriah.Waterland@Sun.COM 
2489781SMoriah.Waterland@Sun.COM 		    case 'r':
2499781SMoriah.Waterland@Sun.COM 			pt = strtok(optarg, " \t\n, ");
2509781SMoriah.Waterland@Sun.COM 			n = 0;
2519781SMoriah.Waterland@Sun.COM 			do {
2529781SMoriah.Waterland@Sun.COM 				rootlist[n++] = flex_device(pt, 0);
2539781SMoriah.Waterland@Sun.COM 				if (n >= NROOT) {
2549781SMoriah.Waterland@Sun.COM 					progerr(gettext(ERR_NROOT), NROOT);
2559781SMoriah.Waterland@Sun.COM 					quit(1);
2569781SMoriah.Waterland@Sun.COM 				}
2579781SMoriah.Waterland@Sun.COM 			} while (pt = strtok(NULL, " \t\n, "));
2589781SMoriah.Waterland@Sun.COM 			rootlist[n] = NULL;
2599781SMoriah.Waterland@Sun.COM 			break;
2609781SMoriah.Waterland@Sun.COM 
2619781SMoriah.Waterland@Sun.COM 		    case 'b':
2629781SMoriah.Waterland@Sun.COM 			basedir = optarg;
2639781SMoriah.Waterland@Sun.COM 			break;
2649781SMoriah.Waterland@Sun.COM 
2659781SMoriah.Waterland@Sun.COM 		    case 'f':
2669781SMoriah.Waterland@Sun.COM 			protofile = optarg;
2679781SMoriah.Waterland@Sun.COM 			break;
2689781SMoriah.Waterland@Sun.COM 
2699781SMoriah.Waterland@Sun.COM 		    case 'd':
2709781SMoriah.Waterland@Sun.COM 			device = flex_device(optarg, 1);
2719781SMoriah.Waterland@Sun.COM 			break;
2729781SMoriah.Waterland@Sun.COM 
2739781SMoriah.Waterland@Sun.COM 		    case 'a':
2749781SMoriah.Waterland@Sun.COM 			putparam("ARCH", optarg);
2759781SMoriah.Waterland@Sun.COM 			break;
2769781SMoriah.Waterland@Sun.COM 
2779781SMoriah.Waterland@Sun.COM 		    case 'v':
2789781SMoriah.Waterland@Sun.COM 			putparam("VERSION", optarg);
2799781SMoriah.Waterland@Sun.COM 			break;
2809781SMoriah.Waterland@Sun.COM 
2819781SMoriah.Waterland@Sun.COM 		    default:
2829781SMoriah.Waterland@Sun.COM 			usage();
2839781SMoriah.Waterland@Sun.COM 			/*NOTREACHED*/
2849781SMoriah.Waterland@Sun.COM 			/*
2859781SMoriah.Waterland@Sun.COM 			 * Although usage() calls a noreturn function,
2869781SMoriah.Waterland@Sun.COM 			 * needed to add return (1);  so that main() would
2879781SMoriah.Waterland@Sun.COM 			 * pass compilation checks. The statement below
2889781SMoriah.Waterland@Sun.COM 			 * should never be executed.
2899781SMoriah.Waterland@Sun.COM 			 */
2909781SMoriah.Waterland@Sun.COM 			return (1);
2919781SMoriah.Waterland@Sun.COM 		}
2929781SMoriah.Waterland@Sun.COM 	}
2939781SMoriah.Waterland@Sun.COM 
2949781SMoriah.Waterland@Sun.COM 	/*
2959781SMoriah.Waterland@Sun.COM 	 * Store command line variable assignments for later
2969781SMoriah.Waterland@Sun.COM 	 * incorporation into the environment.
2979781SMoriah.Waterland@Sun.COM 	 */
2989781SMoriah.Waterland@Sun.COM 	cmdparam = &argv[optind];
2999781SMoriah.Waterland@Sun.COM 
3009781SMoriah.Waterland@Sun.COM 	/* Skip past equates. */
3019781SMoriah.Waterland@Sun.COM 	while (argv[optind] && strchr(argv[optind], '='))
3029781SMoriah.Waterland@Sun.COM 		optind++;
3039781SMoriah.Waterland@Sun.COM 
3049781SMoriah.Waterland@Sun.COM 	/* Confirm that the instance name is valid */
3059781SMoriah.Waterland@Sun.COM 	if ((pkginst = argv[optind]) != NULL) {
3069781SMoriah.Waterland@Sun.COM 		if (pkgnmchk(pkginst, "all", 0)) {
3079781SMoriah.Waterland@Sun.COM 			progerr(gettext(ERR_PKGINST), pkginst);
3089781SMoriah.Waterland@Sun.COM 			quit(1);
3099781SMoriah.Waterland@Sun.COM 		}
3109781SMoriah.Waterland@Sun.COM 		argv[optind++] = NULL;
3119781SMoriah.Waterland@Sun.COM 	}
3129781SMoriah.Waterland@Sun.COM 	if (optind != argc)
3139781SMoriah.Waterland@Sun.COM 		usage();
3149781SMoriah.Waterland@Sun.COM 
3159781SMoriah.Waterland@Sun.COM 	tmpdir = getenv("TMPDIR");
3169781SMoriah.Waterland@Sun.COM 	if (tmpdir == NULL)
3179781SMoriah.Waterland@Sun.COM 		tmpdir = P_tmpdir;
3189781SMoriah.Waterland@Sun.COM 
3199781SMoriah.Waterland@Sun.COM 	/* bug id 4244631, not ABI compliant */
3209781SMoriah.Waterland@Sun.COM 	abi_sym_ptr = getenv("PKG_NONABI_SYMLINKS");
3219781SMoriah.Waterland@Sun.COM 	if (abi_sym_ptr && (strncasecmp(abi_sym_ptr, "TRUE", 4) == 0)) {
3229781SMoriah.Waterland@Sun.COM 		set_nonABI_symlinks();
3239781SMoriah.Waterland@Sun.COM 	}
3249781SMoriah.Waterland@Sun.COM 
3259781SMoriah.Waterland@Sun.COM 	if (device == NULL) {
3269781SMoriah.Waterland@Sun.COM 		device = devattr(SPOOLDEV, "pathname");
3279781SMoriah.Waterland@Sun.COM 		if (device == NULL) {
3289781SMoriah.Waterland@Sun.COM 			progerr(gettext(ERR_DEVICE), SPOOLDEV);
3299781SMoriah.Waterland@Sun.COM 			exit(99);
3309781SMoriah.Waterland@Sun.COM 		}
3319781SMoriah.Waterland@Sun.COM 	}
3329781SMoriah.Waterland@Sun.COM 
3339781SMoriah.Waterland@Sun.COM 	if (protofile == NULL) {
3349781SMoriah.Waterland@Sun.COM 		if (access("prototype", 0) == 0)
3359781SMoriah.Waterland@Sun.COM 			protofile = "prototype";
3369781SMoriah.Waterland@Sun.COM 		else if (access("Prototype", 0) == 0)
3379781SMoriah.Waterland@Sun.COM 			protofile = "Prototype";
3389781SMoriah.Waterland@Sun.COM 		else {
3399781SMoriah.Waterland@Sun.COM 			progerr(gettext(ERR_PROTOTYPE));
3409781SMoriah.Waterland@Sun.COM 			quit(1);
3419781SMoriah.Waterland@Sun.COM 		}
3429781SMoriah.Waterland@Sun.COM 	}
3439781SMoriah.Waterland@Sun.COM 
3449781SMoriah.Waterland@Sun.COM 	if (devtype(device, &pkgdev)) {
3459781SMoriah.Waterland@Sun.COM 		progerr(gettext(ERR_BADDEV), device);
3469781SMoriah.Waterland@Sun.COM 		quit(1);
3479781SMoriah.Waterland@Sun.COM 	}
3489781SMoriah.Waterland@Sun.COM 	if (pkgdev.norewind) {
3499781SMoriah.Waterland@Sun.COM 		/* initialize datastream */
3509781SMoriah.Waterland@Sun.COM 		progerr(gettext(ERR_DSTREAM), device);
3519781SMoriah.Waterland@Sun.COM 		quit(1);
3529781SMoriah.Waterland@Sun.COM 	}
3539781SMoriah.Waterland@Sun.COM 	if (pkgdev.mount) {
3549781SMoriah.Waterland@Sun.COM 		if (n = pkgmount(&pkgdev, NULL, 0, 0, 1))
3559781SMoriah.Waterland@Sun.COM 			quit(n);
3569781SMoriah.Waterland@Sun.COM 	}
3579781SMoriah.Waterland@Sun.COM 
3589781SMoriah.Waterland@Sun.COM 	/*
3599781SMoriah.Waterland@Sun.COM 	 * convert prototype file to a pkgmap, while locating
3609781SMoriah.Waterland@Sun.COM 	 * package objects in the current environment
3619781SMoriah.Waterland@Sun.COM 	 */
3629781SMoriah.Waterland@Sun.COM 	t_pkgmap = tempnam(tmpdir, "tmpmap");
3639781SMoriah.Waterland@Sun.COM 	if (t_pkgmap == NULL) {
3649781SMoriah.Waterland@Sun.COM 		progerr(gettext(ERR_TEMP), errno);
3659781SMoriah.Waterland@Sun.COM 		exit(99);
3669781SMoriah.Waterland@Sun.COM 	}
3679781SMoriah.Waterland@Sun.COM 
3689781SMoriah.Waterland@Sun.COM 	(void) fprintf(stderr, gettext(MSG_PROTOTYPE));
3699781SMoriah.Waterland@Sun.COM 	if (n = mkpkgmap(t_pkgmap, protofile, cmdparam)) {
3709781SMoriah.Waterland@Sun.COM 		progerr(gettext(ERR_BUILD));
3719781SMoriah.Waterland@Sun.COM 		quit(1);
3729781SMoriah.Waterland@Sun.COM 	}
3739781SMoriah.Waterland@Sun.COM 
3749781SMoriah.Waterland@Sun.COM 	setmapmode(MAPNONE);	/* All appropriate variables are now bound */
3759781SMoriah.Waterland@Sun.COM 
3769781SMoriah.Waterland@Sun.COM 	if (vfpOpen(&vfp, t_pkgmap, "r", VFP_NEEDNOW) != 0) {
3779781SMoriah.Waterland@Sun.COM 		progerr(gettext(ERR_TEMP), errno);
3789781SMoriah.Waterland@Sun.COM 		quit(99);
3799781SMoriah.Waterland@Sun.COM 	}
3809781SMoriah.Waterland@Sun.COM 
3819781SMoriah.Waterland@Sun.COM 	eptlist = procmap(vfp, 0, NULL);
3829781SMoriah.Waterland@Sun.COM 
3839781SMoriah.Waterland@Sun.COM 	if (eptlist == NULL) {
3849781SMoriah.Waterland@Sun.COM 		quit(1);
3859781SMoriah.Waterland@Sun.COM 	}
3869781SMoriah.Waterland@Sun.COM 
3879781SMoriah.Waterland@Sun.COM 	(void) vfpClose(&vfp);
3889781SMoriah.Waterland@Sun.COM 
3899781SMoriah.Waterland@Sun.COM 	/* Validate the zone attributes in pkginfo, before creation */
3909781SMoriah.Waterland@Sun.COM 	if (!valid_zone_attr(eptlist)) {
3919781SMoriah.Waterland@Sun.COM 		progerr(ERR_PKGINFO_INVALID_OPTION_COMB);
3929781SMoriah.Waterland@Sun.COM 		quit(1);
3939781SMoriah.Waterland@Sun.COM 	}
3949781SMoriah.Waterland@Sun.COM 
3959781SMoriah.Waterland@Sun.COM 	(void) fprintf(stderr, gettext(MSG_PKGINFO));
3969781SMoriah.Waterland@Sun.COM 	pt = NULL;
3979781SMoriah.Waterland@Sun.COM 	for (i = 0; eptlist[i]; i++) {
3989781SMoriah.Waterland@Sun.COM 		ckmissing(eptlist[i]->path, eptlist[i]->ftype);
3999781SMoriah.Waterland@Sun.COM 		if (eptlist[i]->ftype != 'i')
4009781SMoriah.Waterland@Sun.COM 			continue;
4019781SMoriah.Waterland@Sun.COM 		if (strcmp(eptlist[i]->path, "pkginfo") == 0)
4029781SMoriah.Waterland@Sun.COM 			svept = eptlist[i];
4039781SMoriah.Waterland@Sun.COM 	}
4049781SMoriah.Waterland@Sun.COM 	if (svept == NULL) {
4059781SMoriah.Waterland@Sun.COM 		progerr(gettext(ERR_NOPKGINFO));
4069781SMoriah.Waterland@Sun.COM 		quit(99);
4079781SMoriah.Waterland@Sun.COM 	}
4089781SMoriah.Waterland@Sun.COM 	eptnum = i;
4099781SMoriah.Waterland@Sun.COM 
4109781SMoriah.Waterland@Sun.COM 	/*
4119781SMoriah.Waterland@Sun.COM 	 * process all parameters from the pkginfo file
4129781SMoriah.Waterland@Sun.COM 	 * and place them in the execution environment
4139781SMoriah.Waterland@Sun.COM 	 */
4149781SMoriah.Waterland@Sun.COM 
4159781SMoriah.Waterland@Sun.COM 	if ((fp = fopen(svept->ainfo.local, "r")) == NULL) {
4169781SMoriah.Waterland@Sun.COM 		progerr(gettext(ERR_RDPKGINFO), svept->ainfo.local);
4179781SMoriah.Waterland@Sun.COM 		quit(99);
4189781SMoriah.Waterland@Sun.COM 	}
4199781SMoriah.Waterland@Sun.COM 	param[0] = '\0';
4209781SMoriah.Waterland@Sun.COM 	while (value = fpkgparam(fp, param)) {
4219781SMoriah.Waterland@Sun.COM 		if (getenv(param) == NULL)
4229781SMoriah.Waterland@Sun.COM 			putparam(param, value);
4239781SMoriah.Waterland@Sun.COM 		free((void *)value);
4249781SMoriah.Waterland@Sun.COM 		param[0] = '\0';
4259781SMoriah.Waterland@Sun.COM 	}
4269781SMoriah.Waterland@Sun.COM 	(void) fclose(fp);
4279781SMoriah.Waterland@Sun.COM 
4289781SMoriah.Waterland@Sun.COM 	/* add command line variables */
4299781SMoriah.Waterland@Sun.COM 	while (*cmdparam && (value = strchr(*cmdparam, '=')) != NULL) {
4309781SMoriah.Waterland@Sun.COM 		*value = NULL;	/* terminate the parameter */
4319781SMoriah.Waterland@Sun.COM 		value++;	/* value is now the value (not '=') */
4329781SMoriah.Waterland@Sun.COM 		putparam(*cmdparam++, value);  /* store it in environ */
4339781SMoriah.Waterland@Sun.COM 	}
4349781SMoriah.Waterland@Sun.COM 
4359781SMoriah.Waterland@Sun.COM 	/* make sure parameters are valid */
4369781SMoriah.Waterland@Sun.COM 	(void) time(&clock);
4379781SMoriah.Waterland@Sun.COM 	if (pt = getenv("PKG")) {
4389781SMoriah.Waterland@Sun.COM 		if (pkgnmchk(pt, NULL, 0) || strchr(pt, '.')) {
4399781SMoriah.Waterland@Sun.COM 			progerr(gettext(ERR_PKGABRV), pt);
4409781SMoriah.Waterland@Sun.COM 			quit(1);
4419781SMoriah.Waterland@Sun.COM 		}
4429781SMoriah.Waterland@Sun.COM 		if (pkginst == NULL)
4439781SMoriah.Waterland@Sun.COM 			pkginst = pt;
4449781SMoriah.Waterland@Sun.COM 	} else {
4459781SMoriah.Waterland@Sun.COM 		progerr(gettext(ERR_NOPARAM), "PKG", svept->path);
4469781SMoriah.Waterland@Sun.COM 		quit(1);
4479781SMoriah.Waterland@Sun.COM 	}
4489781SMoriah.Waterland@Sun.COM 	/*
4499781SMoriah.Waterland@Sun.COM 	 * verify consistency between PKG parameter and pkginst
4509781SMoriah.Waterland@Sun.COM 	 */
4519781SMoriah.Waterland@Sun.COM 	(void) snprintf(param, sizeof (param), "%s.*", pt);
4529781SMoriah.Waterland@Sun.COM 	if (pkgnmchk(pkginst, param, 0)) {
4539781SMoriah.Waterland@Sun.COM 		progerr(gettext(ERR_PKGMTCH), pt, pkginst);
4549781SMoriah.Waterland@Sun.COM 		quit(1);
4559781SMoriah.Waterland@Sun.COM 	}
4569781SMoriah.Waterland@Sun.COM 
4579781SMoriah.Waterland@Sun.COM 	/*
4589781SMoriah.Waterland@Sun.COM 	 * *********************************************************************
4599781SMoriah.Waterland@Sun.COM 	 * this feature is removed starting with Solaris 10 - there is no built
4609781SMoriah.Waterland@Sun.COM 	 * in list of packages that should be run "the old way"
4619781SMoriah.Waterland@Sun.COM 	 * *********************************************************************
4629781SMoriah.Waterland@Sun.COM 	 */
4639781SMoriah.Waterland@Sun.COM 
4649781SMoriah.Waterland@Sun.COM #ifdef	ALLOW_EXCEPTION_PKG_LIST
4659781SMoriah.Waterland@Sun.COM 	/* Until 2.9, set it from the execption list */
4669781SMoriah.Waterland@Sun.COM 	if (exception_pkg(pkginst, LINK))
4679781SMoriah.Waterland@Sun.COM 		set_nonABI_symlinks();
4689781SMoriah.Waterland@Sun.COM #endif
4699781SMoriah.Waterland@Sun.COM 
4709781SMoriah.Waterland@Sun.COM 	if ((pkgname = getenv("NAME")) == NULL) {
4719781SMoriah.Waterland@Sun.COM 		progerr(gettext(ERR_NOPARAM), "NAME", svept->path);
4729781SMoriah.Waterland@Sun.COM 		quit(1);
4739781SMoriah.Waterland@Sun.COM 	}
4749781SMoriah.Waterland@Sun.COM 	if (ckparam("NAME", pkgname))
4759781SMoriah.Waterland@Sun.COM 		quit(1);
4769781SMoriah.Waterland@Sun.COM 	if ((pkgvers = getenv("VERSION")) == NULL) {
4779781SMoriah.Waterland@Sun.COM 		/* XXX - I18n */
4789781SMoriah.Waterland@Sun.COM 		/* LINTED do not use cftime(); use strftime instead */
4799781SMoriah.Waterland@Sun.COM 		(void) cftime(buf, "\045m/\045d/\045Y", &clock);
4809781SMoriah.Waterland@Sun.COM 		(void) snprintf(temp, sizeof (temp),
4819781SMoriah.Waterland@Sun.COM 			gettext("Dev Release %s"), buf);
4829781SMoriah.Waterland@Sun.COM 		putparam("VERSION", temp);
4839781SMoriah.Waterland@Sun.COM 		pkgvers = getenv("VERSION");
4849781SMoriah.Waterland@Sun.COM 		logerr(gettext(WRN_SETPARAM), "VERSION", temp);
4859781SMoriah.Waterland@Sun.COM 	}
4869781SMoriah.Waterland@Sun.COM 	if (ckparam("VERSION", pkgvers))
4879781SMoriah.Waterland@Sun.COM 		quit(1);
4889781SMoriah.Waterland@Sun.COM 	if ((pkgarch = getenv("ARCH")) == NULL) {
4899781SMoriah.Waterland@Sun.COM 		(void) uname(&utsbuf);
4909781SMoriah.Waterland@Sun.COM 		putparam("ARCH", utsbuf.machine);
4919781SMoriah.Waterland@Sun.COM 		pkgarch = getenv("ARCH");
4929781SMoriah.Waterland@Sun.COM 		logerr(gettext(WRN_SETPARAM), "ARCH", utsbuf.machine);
4939781SMoriah.Waterland@Sun.COM 	}
4949781SMoriah.Waterland@Sun.COM 	if (ckparam("ARCH", pkgarch))
4959781SMoriah.Waterland@Sun.COM 		quit(1);
4969781SMoriah.Waterland@Sun.COM 	if (getenv("PSTAMP") == NULL) {
4979781SMoriah.Waterland@Sun.COM 		/* use octal value of '%' to fight sccs expansion */
4989781SMoriah.Waterland@Sun.COM 		/* XXX - I18n */
4999781SMoriah.Waterland@Sun.COM 		/* LINTED do not use cftime(); use strftime instead */
5009781SMoriah.Waterland@Sun.COM 		(void) cftime(buf, "\045Y\045m\045d\045H\045M\045S", &clock);
5019781SMoriah.Waterland@Sun.COM 		(void) uname(&utsbuf);
5029781SMoriah.Waterland@Sun.COM 		(void) snprintf(temp, sizeof (temp), "%s%s",
5039781SMoriah.Waterland@Sun.COM 			utsbuf.nodename, buf);
5049781SMoriah.Waterland@Sun.COM 		putparam("PSTAMP", temp);
5059781SMoriah.Waterland@Sun.COM 		logerr(gettext(WRN_SETPARAM), "PSTAMP", temp);
5069781SMoriah.Waterland@Sun.COM 	}
5079781SMoriah.Waterland@Sun.COM 	if ((pkgcat = getenv("CATEGORY")) == NULL) {
5089781SMoriah.Waterland@Sun.COM 		progerr(gettext(ERR_NOPARAM), "CATEGORY", svept->path);
5099781SMoriah.Waterland@Sun.COM 		quit(1);
5109781SMoriah.Waterland@Sun.COM 	}
5119781SMoriah.Waterland@Sun.COM 	if (ckparam("CATEGORY", pkgcat))
5129781SMoriah.Waterland@Sun.COM 		quit(1);
5139781SMoriah.Waterland@Sun.COM 
5149781SMoriah.Waterland@Sun.COM 	/*
5159781SMoriah.Waterland@Sun.COM 	 * warn user of classes listed in package which do
5169781SMoriah.Waterland@Sun.COM 	 * not appear in CLASSES variable in pkginfo file
5179781SMoriah.Waterland@Sun.COM 	 */
5189781SMoriah.Waterland@Sun.COM 	objects = 0;
5199781SMoriah.Waterland@Sun.COM 	for (i = 0; eptlist[i]; i++) {
5209781SMoriah.Waterland@Sun.COM 		if (eptlist[i]->ftype != 'i') {
5219781SMoriah.Waterland@Sun.COM 			objects++;
5229781SMoriah.Waterland@Sun.COM 			addlist(&allclass, eptlist[i]->pkg_class);
5239781SMoriah.Waterland@Sun.COM 		}
5249781SMoriah.Waterland@Sun.COM 	}
5259781SMoriah.Waterland@Sun.COM 
5269781SMoriah.Waterland@Sun.COM 	if ((pt = getenv("CLASSES")) == NULL) {
5279781SMoriah.Waterland@Sun.COM 		if (allclass && *allclass) {
5289781SMoriah.Waterland@Sun.COM 			cl_setl(allclass);
5299781SMoriah.Waterland@Sun.COM 			cl_putl("CLASSES", allclass);
5309781SMoriah.Waterland@Sun.COM 			logerr(gettext(WRN_SETPARAM), "CLASSES",
5319781SMoriah.Waterland@Sun.COM 			    getenv("CLASSES"));
5329781SMoriah.Waterland@Sun.COM 		}
5339781SMoriah.Waterland@Sun.COM 	} else {
5349781SMoriah.Waterland@Sun.COM 		cl_sets(qstrdup(pt));
5359781SMoriah.Waterland@Sun.COM 		if (allclass && *allclass) {
5369781SMoriah.Waterland@Sun.COM 			for (i = 0; allclass[i]; i++) {
5379781SMoriah.Waterland@Sun.COM 				found = 0;
5389781SMoriah.Waterland@Sun.COM 				if (cl_idx(allclass[i]->name) != -1) {
5399781SMoriah.Waterland@Sun.COM 					found++;
5409781SMoriah.Waterland@Sun.COM 					break;
5419781SMoriah.Waterland@Sun.COM 				}
5429781SMoriah.Waterland@Sun.COM 				if (!found) {
5439781SMoriah.Waterland@Sun.COM 					logerr(gettext(WRN_CLASSES),
5449781SMoriah.Waterland@Sun.COM 					    (char *)allclass[i]);
5459781SMoriah.Waterland@Sun.COM 				}
5469781SMoriah.Waterland@Sun.COM 			}
5479781SMoriah.Waterland@Sun.COM 		}
5489781SMoriah.Waterland@Sun.COM 	}
5499781SMoriah.Waterland@Sun.COM 
5509781SMoriah.Waterland@Sun.COM 	(void) fprintf(stderr, gettext(MSG_VOLUMIZE), objects);
5519781SMoriah.Waterland@Sun.COM 	order = (struct cl_attr **)0;
5529781SMoriah.Waterland@Sun.COM 	if (pt = getenv("ORDER")) {
5539781SMoriah.Waterland@Sun.COM 		pt = qstrdup(pt);
5549781SMoriah.Waterland@Sun.COM 		(void) setlist(&order, pt);
5559781SMoriah.Waterland@Sun.COM 		cl_putl("ORDER", order);
5569781SMoriah.Waterland@Sun.COM 	}
5579781SMoriah.Waterland@Sun.COM 
5589781SMoriah.Waterland@Sun.COM 	/* stat the intended output filesystem to get blocking information */
5599781SMoriah.Waterland@Sun.COM 	if (pkgdev.dirname == NULL) {
5609781SMoriah.Waterland@Sun.COM 		progerr(gettext(ERR_WHATVFS), device);
5619781SMoriah.Waterland@Sun.COM 		quit(99);
5629781SMoriah.Waterland@Sun.COM 	}
5639781SMoriah.Waterland@Sun.COM 	if (statvfs64(pkgdev.dirname, &svfsb)) {
5649781SMoriah.Waterland@Sun.COM 		progerr(gettext(ERR_STATVFS), pkgdev.dirname);
5659781SMoriah.Waterland@Sun.COM 		quit(99);
5669781SMoriah.Waterland@Sun.COM 	}
5679781SMoriah.Waterland@Sun.COM 
5689781SMoriah.Waterland@Sun.COM 	if (bsize == 0) {
5699781SMoriah.Waterland@Sun.COM 		bsize = svfsb.f_bsize;
5709781SMoriah.Waterland@Sun.COM 	}
5719781SMoriah.Waterland@Sun.COM 	if (frsize == 0) {
5729781SMoriah.Waterland@Sun.COM 		frsize = svfsb.f_frsize;
5739781SMoriah.Waterland@Sun.COM 	}
5749781SMoriah.Waterland@Sun.COM 
5759781SMoriah.Waterland@Sun.COM 	if (limit == 0)
5769781SMoriah.Waterland@Sun.COM 		/*
5779781SMoriah.Waterland@Sun.COM 		 * bavail is in terms of fragment size blocks - change
5789781SMoriah.Waterland@Sun.COM 		 * to 512 byte blocks
5799781SMoriah.Waterland@Sun.COM 		 */
5809781SMoriah.Waterland@Sun.COM 		limit = (fsblkcnt_t)(((fsblkcnt_t)frsize > 0) ?
5819781SMoriah.Waterland@Sun.COM 			howmany(frsize, DEV_BSIZE) :
5829781SMoriah.Waterland@Sun.COM 			howmany(bsize, DEV_BSIZE)) * svfsb.f_bavail;
5839781SMoriah.Waterland@Sun.COM 
5849781SMoriah.Waterland@Sun.COM 	if (ilimit == 0) {
5859781SMoriah.Waterland@Sun.COM 		ilimit = (svfsb.f_favail > 0) ?
5869781SMoriah.Waterland@Sun.COM 		    svfsb.f_favail : svfsb.f_ffree;
5879781SMoriah.Waterland@Sun.COM 	}
5889781SMoriah.Waterland@Sun.COM 
5899781SMoriah.Waterland@Sun.COM 	nparts = splpkgmap(eptlist, eptnum, (char **)order, bsize, frsize,
5909781SMoriah.Waterland@Sun.COM 	    &limit, &ilimit, &llimit);
5919781SMoriah.Waterland@Sun.COM 
5929781SMoriah.Waterland@Sun.COM 	if (nparts <= 0) {
5939781SMoriah.Waterland@Sun.COM 		progerr(gettext(ERR_SPLIT));
5949781SMoriah.Waterland@Sun.COM 		quit(1);
5959781SMoriah.Waterland@Sun.COM 	}
5969781SMoriah.Waterland@Sun.COM 
5979781SMoriah.Waterland@Sun.COM 	if (nflag) {
5989781SMoriah.Waterland@Sun.COM 		for (i = 0; eptlist[i]; i++)
5999781SMoriah.Waterland@Sun.COM 			(void) ppkgmap(eptlist[i], stdout);
6009781SMoriah.Waterland@Sun.COM 		exit(0);
6019781SMoriah.Waterland@Sun.COM 		/*NOTREACHED*/
6029781SMoriah.Waterland@Sun.COM 	}
6039781SMoriah.Waterland@Sun.COM 
6049781SMoriah.Waterland@Sun.COM 	(void) snprintf(pkgloc, sizeof (pkgloc), "%s/%s",
6059781SMoriah.Waterland@Sun.COM 			pkgdev.dirname, pkginst);
6069781SMoriah.Waterland@Sun.COM 	if (!isdir(pkgloc) && !overwrite) {
6079781SMoriah.Waterland@Sun.COM 		progerr(gettext(ERR_OVERWRITE), pkgloc);
6089781SMoriah.Waterland@Sun.COM 		quit(1);
6099781SMoriah.Waterland@Sun.COM 	}
6109781SMoriah.Waterland@Sun.COM 
6119781SMoriah.Waterland@Sun.COM 	/* output all environment install parameters */
6129781SMoriah.Waterland@Sun.COM 	t_pkginfo = tempnam(tmpdir, "pkginfo");
6139781SMoriah.Waterland@Sun.COM 	if ((fp = fopen(t_pkginfo, "w")) == NULL) {
6149781SMoriah.Waterland@Sun.COM 		progerr(gettext(ERR_TEMP), errno);
6159781SMoriah.Waterland@Sun.COM 		exit(99);
6169781SMoriah.Waterland@Sun.COM 	}
6179781SMoriah.Waterland@Sun.COM 	for (i = 0; environ[i]; i++) {
6189781SMoriah.Waterland@Sun.COM 		if (isupper(*environ[i])) {
6199781SMoriah.Waterland@Sun.COM 			(void) fputs(environ[i], fp);
6209781SMoriah.Waterland@Sun.COM 			(void) fputc('\n', fp);
6219781SMoriah.Waterland@Sun.COM 		}
6229781SMoriah.Waterland@Sun.COM 	}
6239781SMoriah.Waterland@Sun.COM 	(void) fclose(fp);
6249781SMoriah.Waterland@Sun.COM 
6259781SMoriah.Waterland@Sun.COM 	started++;
6269781SMoriah.Waterland@Sun.COM 	(void) rrmdir(pkgloc);
6279781SMoriah.Waterland@Sun.COM 	if (mkdir(pkgloc, 0755)) {
6289781SMoriah.Waterland@Sun.COM 		progerr(gettext(ERR_MKDIR), pkgloc);
6299781SMoriah.Waterland@Sun.COM 		quit(1);
6309781SMoriah.Waterland@Sun.COM 	}
6319781SMoriah.Waterland@Sun.COM 
6329781SMoriah.Waterland@Sun.COM 	/* determine how many packages already reside on the medium */
6339781SMoriah.Waterland@Sun.COM 	pkgdir = pkgdev.dirname;
6349781SMoriah.Waterland@Sun.COM 	npkgs = 0;
6359781SMoriah.Waterland@Sun.COM 	while (pt = fpkginst("all", NULL, NULL))
6369781SMoriah.Waterland@Sun.COM 		npkgs++;
6379781SMoriah.Waterland@Sun.COM 	(void) fpkginst(NULL); /* free resource usage */
6389781SMoriah.Waterland@Sun.COM 
6399781SMoriah.Waterland@Sun.COM 	if (nparts > 1) {
6409781SMoriah.Waterland@Sun.COM 		if (pkgdev.mount && npkgs) {
6419781SMoriah.Waterland@Sun.COM 			progerr(gettext(ERR_ONEVOL));
6429781SMoriah.Waterland@Sun.COM 			quit(1);
6439781SMoriah.Waterland@Sun.COM 		}
6449781SMoriah.Waterland@Sun.COM 	}
6459781SMoriah.Waterland@Sun.COM 
6469781SMoriah.Waterland@Sun.COM 	/*
6479781SMoriah.Waterland@Sun.COM 	 *  update pkgmap entry for pkginfo file, since it may
6489781SMoriah.Waterland@Sun.COM 	 *  have changed due to command line or failure to
6499781SMoriah.Waterland@Sun.COM 	 *  specify all neccessary parameters
6509781SMoriah.Waterland@Sun.COM 	 */
6519781SMoriah.Waterland@Sun.COM 	for (i = 0; eptlist[i]; i++) {
6529781SMoriah.Waterland@Sun.COM 		if (eptlist[i]->ftype != 'i')
6539781SMoriah.Waterland@Sun.COM 			continue;
6549781SMoriah.Waterland@Sun.COM 		if (strcmp(eptlist[i]->path, "pkginfo") == 0) {
6559781SMoriah.Waterland@Sun.COM 			svept = eptlist[i];
6569781SMoriah.Waterland@Sun.COM 			svept->ftype = '?';
6579781SMoriah.Waterland@Sun.COM 			svept->ainfo.local = t_pkginfo;
6589781SMoriah.Waterland@Sun.COM 			(void) cverify(0, &svept->ftype, t_pkginfo,
6599781SMoriah.Waterland@Sun.COM 				&svept->cinfo, 1);
6609781SMoriah.Waterland@Sun.COM 			svept->ftype = 'i';
6619781SMoriah.Waterland@Sun.COM 			break;
6629781SMoriah.Waterland@Sun.COM 		}
6639781SMoriah.Waterland@Sun.COM 	}
6649781SMoriah.Waterland@Sun.COM 
6659781SMoriah.Waterland@Sun.COM 	if (nparts > 1)
6669781SMoriah.Waterland@Sun.COM 		(void) fprintf(stderr, gettext(MSG_PACKAGEM), nparts);
6679781SMoriah.Waterland@Sun.COM 	else
6689781SMoriah.Waterland@Sun.COM 		(void) fprintf(stderr, gettext(MSG_PACKAGE1));
6699781SMoriah.Waterland@Sun.COM 
6709781SMoriah.Waterland@Sun.COM 	for (part = 1; part <= nparts; part++) {
6719781SMoriah.Waterland@Sun.COM 		if ((part > 1) && pkgdev.mount) {
6729781SMoriah.Waterland@Sun.COM 			if (pkgumount(&pkgdev)) {
6739781SMoriah.Waterland@Sun.COM 				progerr(gettext(ERR_UMOUNT), pkgdev.mount);
6749781SMoriah.Waterland@Sun.COM 				quit(99);
6759781SMoriah.Waterland@Sun.COM 			}
6769781SMoriah.Waterland@Sun.COM 			if (n = pkgmount(&pkgdev, NULL, part, nparts, 1))
6779781SMoriah.Waterland@Sun.COM 				quit(n);
6789781SMoriah.Waterland@Sun.COM 			(void) rrmdir(pkgloc);
6799781SMoriah.Waterland@Sun.COM 			if (mkdir(pkgloc, 0555)) {
6809781SMoriah.Waterland@Sun.COM 				progerr(gettext(ERR_MKDIR), pkgloc);
6819781SMoriah.Waterland@Sun.COM 				quit(99);
6829781SMoriah.Waterland@Sun.COM 			}
6839781SMoriah.Waterland@Sun.COM 		}
6849781SMoriah.Waterland@Sun.COM 		outvol(eptlist, eptnum, part, nparts);
6859781SMoriah.Waterland@Sun.COM 
6869781SMoriah.Waterland@Sun.COM 		/* Validate (as much as possible) the control scripts. */
6879781SMoriah.Waterland@Sun.COM 		if (part == 1) {
6889781SMoriah.Waterland@Sun.COM 			char inst_path[PATH_MAX];
6899781SMoriah.Waterland@Sun.COM 
6909781SMoriah.Waterland@Sun.COM 			(void) fprintf(stderr, gettext(MSG_VALSCRIPTS));
6919781SMoriah.Waterland@Sun.COM 			(void) snprintf(inst_path, sizeof (inst_path),
6929781SMoriah.Waterland@Sun.COM 					"%s/install", pkgloc);
6939781SMoriah.Waterland@Sun.COM 			checkscripts(inst_path, 0);
6949781SMoriah.Waterland@Sun.COM 		}
6959781SMoriah.Waterland@Sun.COM 	}
6969781SMoriah.Waterland@Sun.COM 
6979781SMoriah.Waterland@Sun.COM 	quit(0);
6989781SMoriah.Waterland@Sun.COM 	/* LINTED: no return */
6999781SMoriah.Waterland@Sun.COM }
7009781SMoriah.Waterland@Sun.COM 
7019781SMoriah.Waterland@Sun.COM static void
trap(int n)7029781SMoriah.Waterland@Sun.COM trap(int n)
7039781SMoriah.Waterland@Sun.COM {
7049781SMoriah.Waterland@Sun.COM 	(void) signal(SIGINT, SIG_IGN);
7059781SMoriah.Waterland@Sun.COM 	(void) signal(SIGHUP, SIG_IGN);
7069781SMoriah.Waterland@Sun.COM 
7079781SMoriah.Waterland@Sun.COM 	if (n == SIGINT)
7089781SMoriah.Waterland@Sun.COM 		quit(3);
7099781SMoriah.Waterland@Sun.COM 	else {
7109781SMoriah.Waterland@Sun.COM 		(void) fprintf(stderr, gettext("%s terminated (signal %d).\n"),
7119781SMoriah.Waterland@Sun.COM 				get_prog_name(), n);
7129781SMoriah.Waterland@Sun.COM 		quit(99);
7139781SMoriah.Waterland@Sun.COM 	}
7149781SMoriah.Waterland@Sun.COM }
7159781SMoriah.Waterland@Sun.COM 
7169781SMoriah.Waterland@Sun.COM static void
outvol(struct cfent ** eptlist,unsigned int eptnum,int part,int nparts)7179781SMoriah.Waterland@Sun.COM outvol(struct cfent **eptlist, unsigned int eptnum, int part, int nparts)
7189781SMoriah.Waterland@Sun.COM {
7199781SMoriah.Waterland@Sun.COM 	FILE	*fp;
7209781SMoriah.Waterland@Sun.COM 	char	*svpt, *path, temp[PATH_MAX];
7219781SMoriah.Waterland@Sun.COM 	unsigned int	i;
7229781SMoriah.Waterland@Sun.COM 
7239781SMoriah.Waterland@Sun.COM 
7249781SMoriah.Waterland@Sun.COM 	if (nparts > 1)
7259781SMoriah.Waterland@Sun.COM 		(void) fprintf(stderr, gettext(" -- part %2d:\n"), part);
7269781SMoriah.Waterland@Sun.COM 	if (part == 1) {
7279781SMoriah.Waterland@Sun.COM 		/* re-write pkgmap, but exclude local pathnames */
7289781SMoriah.Waterland@Sun.COM 		(void) snprintf(temp, sizeof (temp), "%s/pkgmap", pkgloc);
7299781SMoriah.Waterland@Sun.COM 		if ((fp = fopen(temp, "w")) == NULL) {
7309781SMoriah.Waterland@Sun.COM 			progerr(gettext(ERR_TEMP), errno);
7319781SMoriah.Waterland@Sun.COM 			quit(99);
7329781SMoriah.Waterland@Sun.COM 		}
733*11956SNagaraj.Yedathore@Sun.COM 		(void) fprintf(fp, ": %d %llu\n", nparts, limit);
7349781SMoriah.Waterland@Sun.COM 		for (i = 0; eptlist[i]; i++) {
7359781SMoriah.Waterland@Sun.COM 			svpt = eptlist[i]->ainfo.local;
7369781SMoriah.Waterland@Sun.COM 			if (!strchr("sl", eptlist[i]->ftype))
7379781SMoriah.Waterland@Sun.COM 				eptlist[i]->ainfo.local = NULL;
7389781SMoriah.Waterland@Sun.COM 			if (ppkgmap(eptlist[i], fp)) {
7399781SMoriah.Waterland@Sun.COM 				progerr(gettext(ERR_TEMP), errno);
7409781SMoriah.Waterland@Sun.COM 				quit(99);
7419781SMoriah.Waterland@Sun.COM 			}
7429781SMoriah.Waterland@Sun.COM 			eptlist[i]->ainfo.local = svpt;
7439781SMoriah.Waterland@Sun.COM 		}
7449781SMoriah.Waterland@Sun.COM 		(void) fclose(fp);
7459781SMoriah.Waterland@Sun.COM 		(void) fprintf(stderr, "%s\n", temp);
7469781SMoriah.Waterland@Sun.COM 	}
7479781SMoriah.Waterland@Sun.COM 
7489781SMoriah.Waterland@Sun.COM 	(void) snprintf(temp, sizeof (temp), "%s/pkginfo", pkgloc);
7499781SMoriah.Waterland@Sun.COM 	if (copyf(svept->ainfo.local, temp, svept->cinfo.modtime))
7509781SMoriah.Waterland@Sun.COM 		quit(1);
7519781SMoriah.Waterland@Sun.COM 	(void) fprintf(stderr, "%s\n", temp);
7529781SMoriah.Waterland@Sun.COM 
7539781SMoriah.Waterland@Sun.COM 	for (i = 0; i < eptnum; i++) {
7549781SMoriah.Waterland@Sun.COM 		if (eptlist[i]->volno != part)
7559781SMoriah.Waterland@Sun.COM 			continue;
7569781SMoriah.Waterland@Sun.COM 		if (strchr("dxslcbp", eptlist[i]->ftype))
7579781SMoriah.Waterland@Sun.COM 			continue;
7589781SMoriah.Waterland@Sun.COM 		if (eptlist[i]->ftype == 'i') {
7599781SMoriah.Waterland@Sun.COM 			if (eptlist[i] == svept)
7609781SMoriah.Waterland@Sun.COM 				continue; /* don't copy pkginfo file */
7619781SMoriah.Waterland@Sun.COM 			(void) snprintf(temp, sizeof (temp),
7629781SMoriah.Waterland@Sun.COM 				"%s/install/%s", pkgloc,
7639781SMoriah.Waterland@Sun.COM 				eptlist[i]->path);
7649781SMoriah.Waterland@Sun.COM 			path = temp;
7659781SMoriah.Waterland@Sun.COM 		} else
7669781SMoriah.Waterland@Sun.COM 			path = srcpath(pkgloc, eptlist[i]->path, part, nparts);
7679781SMoriah.Waterland@Sun.COM 		if (sflag) {
7689781SMoriah.Waterland@Sun.COM 			if (slinkf(eptlist[i]->ainfo.local, path))
7699781SMoriah.Waterland@Sun.COM 				quit(1);
7709781SMoriah.Waterland@Sun.COM 		} else if (copyf(eptlist[i]->ainfo.local, path,
7719781SMoriah.Waterland@Sun.COM 				eptlist[i]->cinfo.modtime)) {
7729781SMoriah.Waterland@Sun.COM 			quit(1);
7739781SMoriah.Waterland@Sun.COM 		}
7749781SMoriah.Waterland@Sun.COM 
7759781SMoriah.Waterland@Sun.COM 		/*
7769781SMoriah.Waterland@Sun.COM 		 * If the package file attributes can be sync'd up with
7779781SMoriah.Waterland@Sun.COM 		 * the pkgmap, we fix the attributes here.
7789781SMoriah.Waterland@Sun.COM 		 */
7799781SMoriah.Waterland@Sun.COM 		if (*(eptlist[i]->ainfo.owner) != '$' &&
78010449SNorm.Jacobs@Sun.COM 		    *(eptlist[i]->ainfo.group) != '$') {
7819781SMoriah.Waterland@Sun.COM 			/* Clear dangerous bits. */
7829781SMoriah.Waterland@Sun.COM 			eptlist[i]->ainfo.mode=
7839781SMoriah.Waterland@Sun.COM 			    (eptlist[i]->ainfo.mode & S_IAMB);
7849781SMoriah.Waterland@Sun.COM 			/*
7859781SMoriah.Waterland@Sun.COM 			 * Make sure it can be read by the world and written
78610449SNorm.Jacobs@Sun.COM 			 * by the owner.
7879781SMoriah.Waterland@Sun.COM 			 */
7889781SMoriah.Waterland@Sun.COM 			eptlist[i]->ainfo.mode |= 0644;
7899781SMoriah.Waterland@Sun.COM 			if (!strchr("in", eptlist[i]->ftype)) {
7909781SMoriah.Waterland@Sun.COM 				/* Set the safe attributes. */
7919781SMoriah.Waterland@Sun.COM 				averify(1, &(eptlist[i]->ftype),
7929781SMoriah.Waterland@Sun.COM 				    path, &(eptlist[i]->ainfo));
7939781SMoriah.Waterland@Sun.COM 			}
7949781SMoriah.Waterland@Sun.COM 		}
7959781SMoriah.Waterland@Sun.COM 
7969781SMoriah.Waterland@Sun.COM 		(void) fprintf(stderr, "%s\n", path);
7979781SMoriah.Waterland@Sun.COM 	}
7989781SMoriah.Waterland@Sun.COM }
7999781SMoriah.Waterland@Sun.COM 
8009781SMoriah.Waterland@Sun.COM static void
ckmissing(char * path,char type)8019781SMoriah.Waterland@Sun.COM ckmissing(char *path, char type)
8029781SMoriah.Waterland@Sun.COM {
8039781SMoriah.Waterland@Sun.COM 	static char	**dir;
8049781SMoriah.Waterland@Sun.COM 	static int	ndir;
8059781SMoriah.Waterland@Sun.COM 	char	*pt;
8069781SMoriah.Waterland@Sun.COM 	int	i, found;
8079781SMoriah.Waterland@Sun.COM 
8089781SMoriah.Waterland@Sun.COM 	if (dir == NULL) {
8099781SMoriah.Waterland@Sun.COM 		dir = (char **)calloc(MALSIZ, sizeof (char *));
8109781SMoriah.Waterland@Sun.COM 		if (dir == NULL) {
8119781SMoriah.Waterland@Sun.COM 			progerr(gettext(ERR_MEMORY), errno);
8129781SMoriah.Waterland@Sun.COM 			quit(99);
8139781SMoriah.Waterland@Sun.COM 		}
8149781SMoriah.Waterland@Sun.COM 	}
8159781SMoriah.Waterland@Sun.COM 
8169781SMoriah.Waterland@Sun.COM 	if (strchr("dx", type)) {
8179781SMoriah.Waterland@Sun.COM 		dir[ndir] = path;
8189781SMoriah.Waterland@Sun.COM 		if ((++ndir % MALSIZ) == 0) {
8199781SMoriah.Waterland@Sun.COM 			dir = (char **)realloc((void *)dir,
8209781SMoriah.Waterland@Sun.COM 				(ndir+MALSIZ)*sizeof (char *));
8219781SMoriah.Waterland@Sun.COM 			if (dir == NULL) {
8229781SMoriah.Waterland@Sun.COM 				progerr(gettext(ERR_MEMORY), errno);
8239781SMoriah.Waterland@Sun.COM 				quit(99);
8249781SMoriah.Waterland@Sun.COM 			}
8259781SMoriah.Waterland@Sun.COM 		}
8269781SMoriah.Waterland@Sun.COM 		dir[ndir] = (char *)NULL;
8279781SMoriah.Waterland@Sun.COM 	}
8289781SMoriah.Waterland@Sun.COM 
8299781SMoriah.Waterland@Sun.COM 	pt = path;
8309781SMoriah.Waterland@Sun.COM 	if (*pt == '/')
8319781SMoriah.Waterland@Sun.COM 		pt++;
8329781SMoriah.Waterland@Sun.COM 	while (pt = strchr(pt, '/')) {
8339781SMoriah.Waterland@Sun.COM 		*pt = '\0';
8349781SMoriah.Waterland@Sun.COM 		found = 0;
8359781SMoriah.Waterland@Sun.COM 		for (i = 0; i < ndir; i++) {
8369781SMoriah.Waterland@Sun.COM 			if (strcmp(path, dir[i]) == 0) {
8379781SMoriah.Waterland@Sun.COM 				found++;
8389781SMoriah.Waterland@Sun.COM 				break;
8399781SMoriah.Waterland@Sun.COM 			}
8409781SMoriah.Waterland@Sun.COM 		}
8419781SMoriah.Waterland@Sun.COM 		if (!found) {
8429781SMoriah.Waterland@Sun.COM 			logerr(gettext(WRN_MISSINGDIR), path);
8439781SMoriah.Waterland@Sun.COM 			ckmissing(qstrdup(path), 'd');
8449781SMoriah.Waterland@Sun.COM 		}
8459781SMoriah.Waterland@Sun.COM 		*pt++ = '/';
8469781SMoriah.Waterland@Sun.COM 	}
8479781SMoriah.Waterland@Sun.COM }
8489781SMoriah.Waterland@Sun.COM 
8499781SMoriah.Waterland@Sun.COM static int
slinkf(char * from,char * to)8509781SMoriah.Waterland@Sun.COM slinkf(char *from, char *to)
8519781SMoriah.Waterland@Sun.COM {
8529781SMoriah.Waterland@Sun.COM 	char	*pt;
8539781SMoriah.Waterland@Sun.COM 
8549781SMoriah.Waterland@Sun.COM 	pt = to;
8559781SMoriah.Waterland@Sun.COM 	while (pt = strchr(pt+1, '/')) {
8569781SMoriah.Waterland@Sun.COM 		*pt = '\0';
8579781SMoriah.Waterland@Sun.COM 		if (isdir(to) && mkdir(to, 0755)) {
8589781SMoriah.Waterland@Sun.COM 			progerr(gettext(ERR_MKDIR), to);
8599781SMoriah.Waterland@Sun.COM 			*pt = '/';
8609781SMoriah.Waterland@Sun.COM 			return (-1);
8619781SMoriah.Waterland@Sun.COM 		}
8629781SMoriah.Waterland@Sun.COM 		*pt = '/';
8639781SMoriah.Waterland@Sun.COM 	}
8649781SMoriah.Waterland@Sun.COM 	if (symlink(from, to)) {
8659781SMoriah.Waterland@Sun.COM 		progerr(gettext(ERR_SYMLINK), to);
8669781SMoriah.Waterland@Sun.COM 		return (-1);
8679781SMoriah.Waterland@Sun.COM 	}
8689781SMoriah.Waterland@Sun.COM 	return (0);
8699781SMoriah.Waterland@Sun.COM }
8709781SMoriah.Waterland@Sun.COM 
8719781SMoriah.Waterland@Sun.COM static void
usage(void)8729781SMoriah.Waterland@Sun.COM usage(void)
8739781SMoriah.Waterland@Sun.COM {
8749781SMoriah.Waterland@Sun.COM 	(void) fprintf(stderr, gettext(ERR_USAGE), get_prog_name());
8759781SMoriah.Waterland@Sun.COM 	exit(1);
8769781SMoriah.Waterland@Sun.COM 	/*NOTREACHED*/
8779781SMoriah.Waterland@Sun.COM }
8789781SMoriah.Waterland@Sun.COM 
8799781SMoriah.Waterland@Sun.COM /*
8809781SMoriah.Waterland@Sun.COM  * valid_zone_attr:	Validates the zone attributes specified in
8819781SMoriah.Waterland@Sun.COM  *			pkginfo file for this package. The package
8829781SMoriah.Waterland@Sun.COM  *			can not be created with certain combinations
8839781SMoriah.Waterland@Sun.COM  *			of the attributes.
8849781SMoriah.Waterland@Sun.COM  */
8859781SMoriah.Waterland@Sun.COM static boolean_t
valid_zone_attr(struct cfent ** eptlist)8869781SMoriah.Waterland@Sun.COM valid_zone_attr(struct cfent **eptlist)
8879781SMoriah.Waterland@Sun.COM {
8889781SMoriah.Waterland@Sun.COM 	FILE		*pkginfoFP;
8899781SMoriah.Waterland@Sun.COM 	boolean_t	all_zones;	/* pkg is "all zones" only */
8909781SMoriah.Waterland@Sun.COM 	boolean_t	is_hollow;	/* pkg is "hollow" */
8919781SMoriah.Waterland@Sun.COM 	boolean_t	this_zone;	/* pkg is "this zone" only */
8929781SMoriah.Waterland@Sun.COM 	char 		pkginfoPath[PATH_MAX];	/* pkginfo file path */
8939781SMoriah.Waterland@Sun.COM 	char		*pkgInst;
8949781SMoriah.Waterland@Sun.COM 	int i;
8959781SMoriah.Waterland@Sun.COM 
8969781SMoriah.Waterland@Sun.COM 	/* Path to pkginfo file within the package to be installed */
8979781SMoriah.Waterland@Sun.COM 
8989781SMoriah.Waterland@Sun.COM 	this_zone = B_FALSE;
8999781SMoriah.Waterland@Sun.COM 	for (i = 0; eptlist[i]; i++) {
9009781SMoriah.Waterland@Sun.COM 		if (eptlist[i]->ftype != 'i')
9019781SMoriah.Waterland@Sun.COM 			continue;
9029781SMoriah.Waterland@Sun.COM 		if (strcmp(eptlist[i]->path, "pkginfo") == 0)
9039781SMoriah.Waterland@Sun.COM 			(void) strcpy(pkginfoPath, eptlist[i]->ainfo.local);
9049781SMoriah.Waterland@Sun.COM 
9059781SMoriah.Waterland@Sun.COM 		/*
9069781SMoriah.Waterland@Sun.COM 		 * Check to see if this package has a request script. If this
9079781SMoriah.Waterland@Sun.COM 		 * package does have a request script, then mark the package
9089781SMoriah.Waterland@Sun.COM 		 * for installation in this zone only. Any package with a
9099781SMoriah.Waterland@Sun.COM 		 * request script cannot be installed outside of the zone the
9109781SMoriah.Waterland@Sun.COM 		 * pkgadd command is being run in, nor can such a package be
9119781SMoriah.Waterland@Sun.COM 		 * installed as part of a new zone install. A new zone install
9129781SMoriah.Waterland@Sun.COM 		 * must be non-interactive, which is required by all packages
9139781SMoriah.Waterland@Sun.COM 		 * integrated into the Solaris WOS.
9149781SMoriah.Waterland@Sun.COM 		 * If request file is set in prototype, then this_zone is TRUE.
9159781SMoriah.Waterland@Sun.COM 		 */
9169781SMoriah.Waterland@Sun.COM 		if (strcmp(eptlist[i]->path, "request") == 0)
9179781SMoriah.Waterland@Sun.COM 			this_zone = B_TRUE;
9189781SMoriah.Waterland@Sun.COM 	}
9199781SMoriah.Waterland@Sun.COM 
9209781SMoriah.Waterland@Sun.COM 	/* Gather information from the pkginfo file */
9219781SMoriah.Waterland@Sun.COM 
9229781SMoriah.Waterland@Sun.COM 	pkginfoFP = fopen(pkginfoPath, "r");
9239781SMoriah.Waterland@Sun.COM 
9249781SMoriah.Waterland@Sun.COM 	if (pkginfoFP == NULL) {
9259781SMoriah.Waterland@Sun.COM 		progerr(ERR_NO_PKG_INFOFILE, pkginfoPath, strerror(errno));
9269781SMoriah.Waterland@Sun.COM 		return (B_FALSE);
9279781SMoriah.Waterland@Sun.COM 	}
9289781SMoriah.Waterland@Sun.COM 
9299781SMoriah.Waterland@Sun.COM 	if ((pkgInst = fpkgparam(pkginfoFP, "PKG")) == NULL) {
9309781SMoriah.Waterland@Sun.COM 		progerr(gettext(ERR_NOPARAM), "PKG", pkginfoPath);
9319781SMoriah.Waterland@Sun.COM 		return (B_FALSE);
9329781SMoriah.Waterland@Sun.COM 	}
9339781SMoriah.Waterland@Sun.COM 
9349781SMoriah.Waterland@Sun.COM 
9359781SMoriah.Waterland@Sun.COM 	/* Determine "HOLLOW" setting for this package */
9369781SMoriah.Waterland@Sun.COM 	is_hollow = pkginfoParamTruth(pkginfoFP, PKG_HOLLOW_VARIABLE,
9379781SMoriah.Waterland@Sun.COM 			"true", B_FALSE);
9389781SMoriah.Waterland@Sun.COM 
9399781SMoriah.Waterland@Sun.COM 	/* Determine "ALLZONES" setting for this package */
9409781SMoriah.Waterland@Sun.COM 	all_zones = pkginfoParamTruth(pkginfoFP, PKG_ALLZONES_VARIABLE,
9419781SMoriah.Waterland@Sun.COM 			"true", B_FALSE);
9429781SMoriah.Waterland@Sun.COM 
9439781SMoriah.Waterland@Sun.COM 	/* Determine "THISZONE" setting for this package, if no request file */
9449781SMoriah.Waterland@Sun.COM 	if (!this_zone)
9459781SMoriah.Waterland@Sun.COM 		this_zone = pkginfoParamTruth(pkginfoFP, PKG_THISZONE_VARIABLE,
9469781SMoriah.Waterland@Sun.COM 			"true", B_FALSE);
9479781SMoriah.Waterland@Sun.COM 
9489781SMoriah.Waterland@Sun.COM 	/* Close pkginfo file */
9499781SMoriah.Waterland@Sun.COM 	(void) fclose(pkginfoFP);
9509781SMoriah.Waterland@Sun.COM 
9519781SMoriah.Waterland@Sun.COM 	/*
9529781SMoriah.Waterland@Sun.COM 	 * Validate zone attributes based on information gathered,
9539781SMoriah.Waterland@Sun.COM 	 * and validate the three SUNW_PKG_ options:
9549781SMoriah.Waterland@Sun.COM 	 *
9559781SMoriah.Waterland@Sun.COM 	 * -----------------------------|---------------|
9569781SMoriah.Waterland@Sun.COM 	 * <ALLZONES><HOLLOW><THISZONE> |  If Allowed   |
9579781SMoriah.Waterland@Sun.COM 	 * ----1------------------------|---------------|
9589781SMoriah.Waterland@Sun.COM 	 *		F F F		|	OK	|
9599781SMoriah.Waterland@Sun.COM 	 *		F F T		|	OK	|
9609781SMoriah.Waterland@Sun.COM 	 *		F T *		|	NO	|
9619781SMoriah.Waterland@Sun.COM 	 * ----2------------------------|---------------|
9629781SMoriah.Waterland@Sun.COM 	 *		T F F		|	OK	|
9639781SMoriah.Waterland@Sun.COM 	 *		T T F		|	OK	|
9649781SMoriah.Waterland@Sun.COM 	 *		T * T		|	NO	|
9659781SMoriah.Waterland@Sun.COM 	 * -----------------------------|---------------|
9669781SMoriah.Waterland@Sun.COM 	 */
9679781SMoriah.Waterland@Sun.COM 
9689781SMoriah.Waterland@Sun.COM 	/* pkg "all zones" && "this zone" (#2) */
9699781SMoriah.Waterland@Sun.COM 
9709781SMoriah.Waterland@Sun.COM 	if (all_zones && this_zone) {
9719781SMoriah.Waterland@Sun.COM 		progerr(ERR_ALLZONES_AND_THISZONE, pkgInst,
9729781SMoriah.Waterland@Sun.COM 		    PKG_ALLZONES_VARIABLE, PKG_THISZONE_VARIABLE);
9739781SMoriah.Waterland@Sun.COM 		return (B_FALSE);
9749781SMoriah.Waterland@Sun.COM 	}
9759781SMoriah.Waterland@Sun.COM 
9769781SMoriah.Waterland@Sun.COM 	/* pkg "!all zones" && "hollow" (#1) */
9779781SMoriah.Waterland@Sun.COM 
9789781SMoriah.Waterland@Sun.COM 	if ((!all_zones) && is_hollow) {
9799781SMoriah.Waterland@Sun.COM 		progerr(ERR_NO_ALLZONES_AND_HOLLOW, pkgInst,
9809781SMoriah.Waterland@Sun.COM 		    PKG_ALLZONES_VARIABLE, PKG_HOLLOW_VARIABLE);
9819781SMoriah.Waterland@Sun.COM 		return (B_FALSE);
9829781SMoriah.Waterland@Sun.COM 	}
9839781SMoriah.Waterland@Sun.COM 
9849781SMoriah.Waterland@Sun.COM 	return (B_TRUE);
9859781SMoriah.Waterland@Sun.COM }
986