xref: /onnv-gate/usr/src/cmd/svr4pkg/pkgadd/main.c (revision 9869:9bff8d14ecc3)
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 /*
239781SMoriah.Waterland@Sun.COM  * Copyright 2009 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 /*
329781SMoriah.Waterland@Sun.COM  * Program:	pkgadd / pkgask
339781SMoriah.Waterland@Sun.COM  *
349781SMoriah.Waterland@Sun.COM  * Function:	public command and private utility functions that
359781SMoriah.Waterland@Sun.COM  *		implement the package add and package ask operations.
369781SMoriah.Waterland@Sun.COM  *
379781SMoriah.Waterland@Sun.COM  */
389781SMoriah.Waterland@Sun.COM 
399781SMoriah.Waterland@Sun.COM /*
409781SMoriah.Waterland@Sun.COM  * System includes
419781SMoriah.Waterland@Sun.COM  */
429781SMoriah.Waterland@Sun.COM 
439781SMoriah.Waterland@Sun.COM #include <stdio.h>
449781SMoriah.Waterland@Sun.COM #include <limits.h>
459781SMoriah.Waterland@Sun.COM #include <stdlib.h>
469781SMoriah.Waterland@Sun.COM #include <unistd.h>
479781SMoriah.Waterland@Sun.COM #include <string.h>
489781SMoriah.Waterland@Sun.COM #include <fcntl.h>
499781SMoriah.Waterland@Sun.COM #include <sys/types.h>
509781SMoriah.Waterland@Sun.COM #include <sys/stat.h>
519781SMoriah.Waterland@Sun.COM #include <signal.h>
529781SMoriah.Waterland@Sun.COM #include <errno.h>
539781SMoriah.Waterland@Sun.COM #include <pkgdev.h>
549781SMoriah.Waterland@Sun.COM #include <pkginfo.h>
559781SMoriah.Waterland@Sun.COM #include <pkglocs.h>
569781SMoriah.Waterland@Sun.COM #include <locale.h>
579781SMoriah.Waterland@Sun.COM #include <libintl.h>
589781SMoriah.Waterland@Sun.COM #include <pkgtrans.h>
599781SMoriah.Waterland@Sun.COM #include <boot_http.h>
609781SMoriah.Waterland@Sun.COM #include <assert.h>
619781SMoriah.Waterland@Sun.COM 
629781SMoriah.Waterland@Sun.COM /*
639781SMoriah.Waterland@Sun.COM  * consolidation pkg command library includes
649781SMoriah.Waterland@Sun.COM  */
659781SMoriah.Waterland@Sun.COM #include <pkglib.h>
669781SMoriah.Waterland@Sun.COM #include <pkgerr.h>
679781SMoriah.Waterland@Sun.COM #include <pkgweb.h>
689781SMoriah.Waterland@Sun.COM 
699781SMoriah.Waterland@Sun.COM #include <instzones_api.h>
709781SMoriah.Waterland@Sun.COM 
719781SMoriah.Waterland@Sun.COM /*
729781SMoriah.Waterland@Sun.COM  * local pkg command library includes
739781SMoriah.Waterland@Sun.COM  */
749781SMoriah.Waterland@Sun.COM #include <install.h>
759781SMoriah.Waterland@Sun.COM #include <libinst.h>
769781SMoriah.Waterland@Sun.COM #include <libadm.h>
779781SMoriah.Waterland@Sun.COM #include <messages.h>
789781SMoriah.Waterland@Sun.COM 
799781SMoriah.Waterland@Sun.COM 
809781SMoriah.Waterland@Sun.COM /*
819781SMoriah.Waterland@Sun.COM  * pkgadd local includes
829781SMoriah.Waterland@Sun.COM  */
839781SMoriah.Waterland@Sun.COM 
849781SMoriah.Waterland@Sun.COM #include "quit.h"
859781SMoriah.Waterland@Sun.COM 
869781SMoriah.Waterland@Sun.COM /*
879781SMoriah.Waterland@Sun.COM  * imported global variables/functions
889781SMoriah.Waterland@Sun.COM  */
899781SMoriah.Waterland@Sun.COM 
909781SMoriah.Waterland@Sun.COM /* presvr4.c */
919781SMoriah.Waterland@Sun.COM extern int	presvr4(char **ppkg, int a_nointeract);
929781SMoriah.Waterland@Sun.COM 
939781SMoriah.Waterland@Sun.COM /* check.c */
949781SMoriah.Waterland@Sun.COM extern int	preinstall_verify(char **a_pkgList, zoneList_t a_zlst,
959781SMoriah.Waterland@Sun.COM 			char *a_zoneTempDir);
969781SMoriah.Waterland@Sun.COM 
979781SMoriah.Waterland@Sun.COM /*
989781SMoriah.Waterland@Sun.COM  * ckquit is a global that controls 'ckyorn' (defined in libadm)
999781SMoriah.Waterland@Sun.COM  * If ckquit is non-zero, then "quit" is allowed as an answer when
1009781SMoriah.Waterland@Sun.COM  * ckyorn is called. If is it zero, then "quit" is not an allowed answer.
1019781SMoriah.Waterland@Sun.COM  */
1029781SMoriah.Waterland@Sun.COM extern int	ckquit;
1039781SMoriah.Waterland@Sun.COM 
1049781SMoriah.Waterland@Sun.COM /*
1059781SMoriah.Waterland@Sun.COM  * exported global variables
1069781SMoriah.Waterland@Sun.COM  */
1079781SMoriah.Waterland@Sun.COM 
1089781SMoriah.Waterland@Sun.COM /* these globals are set by ckreturn and used by quit.c */
1099781SMoriah.Waterland@Sun.COM 
1109781SMoriah.Waterland@Sun.COM int	admnflag = 0;	/* != 0 if any pkg op admin setting failure (4) */
1119781SMoriah.Waterland@Sun.COM int	doreboot = 0;	/* != 0 if reboot required after installation */
1129781SMoriah.Waterland@Sun.COM int	failflag = 0;	/* != 0 if fatal error has occurred (1) */
1139781SMoriah.Waterland@Sun.COM int	intrflag = 0;	/* != 0 if user selected quit (3) */
1149781SMoriah.Waterland@Sun.COM int	ireboot = 0;	/* != 0 if immediate reboot required */
1159781SMoriah.Waterland@Sun.COM int	nullflag = 0;	/* != 0 if admin interaction required (5) */
1169781SMoriah.Waterland@Sun.COM int	warnflag = 0;	/* != 0 if non-fatal error has occurred (2) */
1179781SMoriah.Waterland@Sun.COM 
1189781SMoriah.Waterland@Sun.COM /* imported by quit.c */
1199781SMoriah.Waterland@Sun.COM int	npkgs = 0;	/* the number of packages yet to be installed */
1209781SMoriah.Waterland@Sun.COM 
1219781SMoriah.Waterland@Sun.COM /* imported by various (many) */
1229781SMoriah.Waterland@Sun.COM char	*respfile = NULL;	/* response pathname (or NULL) */
1239781SMoriah.Waterland@Sun.COM char	*tmpdir = NULL;		/* location to place temporary files */
1249781SMoriah.Waterland@Sun.COM 
1259781SMoriah.Waterland@Sun.COM struct admin	adm;		/* holds info about installation admin */
1269781SMoriah.Waterland@Sun.COM struct pkgdev	pkgdev;		/* holds info about the installation device */
1279781SMoriah.Waterland@Sun.COM 
1289781SMoriah.Waterland@Sun.COM /*
1299781SMoriah.Waterland@Sun.COM  * internal global variables
1309781SMoriah.Waterland@Sun.COM  */
1319781SMoriah.Waterland@Sun.COM 
1329781SMoriah.Waterland@Sun.COM static char	*admnfile = NULL;	/* file to use for installation admin */
1339781SMoriah.Waterland@Sun.COM static char	*ids_name = NULL;	/* name of data stream device */
1349781SMoriah.Waterland@Sun.COM static char	*pkgcontsrc = NULL;	/* continuation file (-c option) */
1359781SMoriah.Waterland@Sun.COM static char	*pkgdrtarg = NULL;	/* dry run file (-D option) */
1369781SMoriah.Waterland@Sun.COM static char	*pkginst = NULL;	/* current pkg/src instance 2 process */
1379781SMoriah.Waterland@Sun.COM static char	*respdir = NULL;	/* respfile is a directory spec */
1389781SMoriah.Waterland@Sun.COM static char	*rw_block_size = NULL;
1399781SMoriah.Waterland@Sun.COM static char	*vfstab_file = NULL;
1409781SMoriah.Waterland@Sun.COM static int	askflag = 0;		/* non-zero if invoked as "pkgask" */
1419781SMoriah.Waterland@Sun.COM static int	disableAttributes = 0;	/* Disabling attribute checking */
1429781SMoriah.Waterland@Sun.COM static int	disableChecksum = 0;	/* Disable checksumming */
1439781SMoriah.Waterland@Sun.COM static int	disableSaveSpool = 0;	/* Disable partial spool dir create */
1449781SMoriah.Waterland@Sun.COM static int	init_install = 0;	/* inform scripts initial install */
1459781SMoriah.Waterland@Sun.COM static int	no_map_client = 0;	/* do not map from vfstab file */
1469781SMoriah.Waterland@Sun.COM static int	nointeract = 0;		/* non-zero - no user interaction */
1479781SMoriah.Waterland@Sun.COM static int	pkgverbose = 0;		/* non-zero if verbose mode selected */
1489781SMoriah.Waterland@Sun.COM static int	saveSpoolInstall = 0;	/* installing from save spool dir */
1499781SMoriah.Waterland@Sun.COM static int	suppressCopyright = 0;	/* suppress copyright notices */
1509781SMoriah.Waterland@Sun.COM 
1519781SMoriah.Waterland@Sun.COM /* set by ckreturn() */
1529781SMoriah.Waterland@Sun.COM 
1539781SMoriah.Waterland@Sun.COM static int	interrupted = 0;	/* last pkg op was quit (1,2,3,4,5) */
1549781SMoriah.Waterland@Sun.COM static int	needconsult = 0;	/* essential ask admin now (1,2,3,5) */
1559781SMoriah.Waterland@Sun.COM 
1569781SMoriah.Waterland@Sun.COM /* Set by -O nozones: do not process any zones */
1579781SMoriah.Waterland@Sun.COM 
1589781SMoriah.Waterland@Sun.COM static boolean_t	noZones = B_FALSE;
1599781SMoriah.Waterland@Sun.COM 
1609781SMoriah.Waterland@Sun.COM /* Set by -O zonelist=<names...>: process only named zones */
1619781SMoriah.Waterland@Sun.COM 
1629781SMoriah.Waterland@Sun.COM static boolean_t	usedZoneList = B_FALSE;
1639781SMoriah.Waterland@Sun.COM 
1649781SMoriah.Waterland@Sun.COM /* Set by -O debug: debug output is enabled? */
1659781SMoriah.Waterland@Sun.COM 
1669781SMoriah.Waterland@Sun.COM static boolean_t	debugFlag = B_FALSE;
1679781SMoriah.Waterland@Sun.COM 
1689781SMoriah.Waterland@Sun.COM /* Set by the -G option: install packages in global zone only */
1699781SMoriah.Waterland@Sun.COM 
1709781SMoriah.Waterland@Sun.COM static boolean_t	globalZoneOnly = B_FALSE;
1719781SMoriah.Waterland@Sun.COM 
1729781SMoriah.Waterland@Sun.COM /* Set by -O patchPkgRemoval */
1739781SMoriah.Waterland@Sun.COM 
1749781SMoriah.Waterland@Sun.COM static boolean_t	patchPkgRemoval = B_FALSE;
1759781SMoriah.Waterland@Sun.COM 
1769781SMoriah.Waterland@Sun.COM /*
1779781SMoriah.Waterland@Sun.COM  * Assume the package is ABI and POSIX compliant as regards user
1789781SMoriah.Waterland@Sun.COM  * interactiion during procedure scripts.
1799781SMoriah.Waterland@Sun.COM  */
1809781SMoriah.Waterland@Sun.COM 
1819781SMoriah.Waterland@Sun.COM static int	old_pkg = 0;
1829781SMoriah.Waterland@Sun.COM 
1839781SMoriah.Waterland@Sun.COM /* Assume pkg should be installed according to the ABI */
1849781SMoriah.Waterland@Sun.COM 
1859781SMoriah.Waterland@Sun.COM static int	old_symlinks = 0;
1869781SMoriah.Waterland@Sun.COM 
1879781SMoriah.Waterland@Sun.COM /*
1889781SMoriah.Waterland@Sun.COM  * Default name length will be 32 chars - if this is set,
1899781SMoriah.Waterland@Sun.COM  * disable the 32 char name limit extension
1909781SMoriah.Waterland@Sun.COM  */
1919781SMoriah.Waterland@Sun.COM 
1929781SMoriah.Waterland@Sun.COM static int	ABI_namelength = 0;
1939781SMoriah.Waterland@Sun.COM 
1949781SMoriah.Waterland@Sun.COM #if	!defined(TEXT_DOMAIN)	/* Should be defined by cc -D */
1959781SMoriah.Waterland@Sun.COM #define	TEXT_DOMAIN	"SYS_TEST"
1969781SMoriah.Waterland@Sun.COM #endif
1979781SMoriah.Waterland@Sun.COM 
1989781SMoriah.Waterland@Sun.COM /* printable string - if string is null results in ??? */
1999781SMoriah.Waterland@Sun.COM 
2009781SMoriah.Waterland@Sun.COM #define	PSTR(STR) (((STR) == (char *)NULL) ? "???" : (STR))
2019781SMoriah.Waterland@Sun.COM 
2029781SMoriah.Waterland@Sun.COM #define	MAX_FDS	20
2039781SMoriah.Waterland@Sun.COM 
2049781SMoriah.Waterland@Sun.COM #define	INHERITFS	"inherited-filesystem="
2059781SMoriah.Waterland@Sun.COM #define	INHERITFS_LEN	((sizeof (INHERITFS))-1)
2069781SMoriah.Waterland@Sun.COM 
2079781SMoriah.Waterland@Sun.COM /*
2089781SMoriah.Waterland@Sun.COM  * forward declarations
2099781SMoriah.Waterland@Sun.COM  */
2109781SMoriah.Waterland@Sun.COM 
2119781SMoriah.Waterland@Sun.COM static int		boot_and_pkginstall_check_in_zones(zoneList_t a_zlst,
2129781SMoriah.Waterland@Sun.COM 				char *a_idsName, char *a_altBinDir,
2139781SMoriah.Waterland@Sun.COM 				char *a_zoneAdminFile, char *a_zoneTempDir);
2149781SMoriah.Waterland@Sun.COM static int		boot_and_install_in_zones(zoneList_t a_zlst,
2159781SMoriah.Waterland@Sun.COM 				char *a_idsName, char *a_altBinDir,
2169781SMoriah.Waterland@Sun.COM 				char *a_zoneAdminFile, char *a_zoneTempDir);
2179781SMoriah.Waterland@Sun.COM static void		pkginstall_check_in_one_zone(char **a_inheritedPkgDirs,
2189781SMoriah.Waterland@Sun.COM 				char *a_zoneName, char *a_idsName,
2199781SMoriah.Waterland@Sun.COM 				char *a_zoneAdminFile, char *a_zoneTempDir,
2209781SMoriah.Waterland@Sun.COM 				char *a_altBinDir, char *a_scratchName,
221*9869SCasper.Dik@Sun.COM 				zone_state_t a_zoneState, boolean_t a_tmpzn);
2229781SMoriah.Waterland@Sun.COM static void		ckreturn(int retcode);
2239781SMoriah.Waterland@Sun.COM static void		create_zone_adminfile(char **r_zoneAdminFile,
2249781SMoriah.Waterland@Sun.COM 				char *a_zoneTempDir, char *a_admnfile);
2259781SMoriah.Waterland@Sun.COM static void		create_zone_tempdir(char **r_zoneTempDir,
2269781SMoriah.Waterland@Sun.COM 				char *a_tmpdir);
2279781SMoriah.Waterland@Sun.COM static void		install_in_one_zone(char **a_inheritedPkgDirs,
2289781SMoriah.Waterland@Sun.COM 				char *a_zoneName, char *a_idsName,
2299781SMoriah.Waterland@Sun.COM 				char *a_zoneAdminFile, char *a_zoneTempDir,
230*9869SCasper.Dik@Sun.COM 				char *a_altBinDir, zone_state_t a_zoneState,
231*9869SCasper.Dik@Sun.COM 				boolean_t a_tmpzn);
2329781SMoriah.Waterland@Sun.COM static int		pkginstall_check_in_zones(zoneList_t a_zlst,
2339781SMoriah.Waterland@Sun.COM 				char *a_idsName, char *a_altBinDir,
2349781SMoriah.Waterland@Sun.COM 				char *a_zoneAdminFile, char *a_zoneTempDir);
2359781SMoriah.Waterland@Sun.COM static int		install_in_zones(zoneList_t a_zlst, char *a_idsName,
2369781SMoriah.Waterland@Sun.COM 				char *a_altBinDir, char *a_zoneAdminFile,
2379781SMoriah.Waterland@Sun.COM 				char *a_zoneTempDir);
2389781SMoriah.Waterland@Sun.COM static int		pkgInstall(char *ir, char *a_idsName, char *a_pkgDir,
2399781SMoriah.Waterland@Sun.COM 				char *a_altBinDir, char **a_inheritedPkgDirs);
2409781SMoriah.Waterland@Sun.COM static int		pkgZoneCheckInstall(char *a_zoneName,
2419781SMoriah.Waterland@Sun.COM 				char **a_inheritedPkgDirs,
2429781SMoriah.Waterland@Sun.COM 				zone_state_t a_zoneState,
2439781SMoriah.Waterland@Sun.COM 				char *a_idsName, char *a_altBinDir,
244*9869SCasper.Dik@Sun.COM 				char *a_adminFile, char *a_stdoutPath,
245*9869SCasper.Dik@Sun.COM 				boolean_t a_tmpzn);
2469781SMoriah.Waterland@Sun.COM static int		pkgZoneInstall(char *a_zoneName,
2479781SMoriah.Waterland@Sun.COM 				char **a_inheritedPkgDirs,
2489781SMoriah.Waterland@Sun.COM 				zone_state_t a_zoneState,
2499781SMoriah.Waterland@Sun.COM 				char *a_idsName, char *a_altBinDir,
250*9869SCasper.Dik@Sun.COM 				char *a_adminFile, boolean_t a_tmpzn);
2519781SMoriah.Waterland@Sun.COM static void		resetreturn();
2529781SMoriah.Waterland@Sun.COM static void		usage(void);
2539781SMoriah.Waterland@Sun.COM static boolean_t	add_packages(char **a_pkgList, char *a_uri,
2549781SMoriah.Waterland@Sun.COM 				char *a_idsName, int a_repeat,
2559781SMoriah.Waterland@Sun.COM 				char *a_altBinDir, char *a_device,
2569781SMoriah.Waterland@Sun.COM 				boolean_t a_noZones);
2579781SMoriah.Waterland@Sun.COM static boolean_t	add_packages_in_global_no_zones(char **a_pkgList,
2589781SMoriah.Waterland@Sun.COM 				char *a_uri, char *a_idsName, int a_repeat,
2599781SMoriah.Waterland@Sun.COM 				char *a_altBinDir, char *a_device);
2609781SMoriah.Waterland@Sun.COM static boolean_t	add_packages_in_global_with_zones(char **a_pkgList,
2619781SMoriah.Waterland@Sun.COM 				char *a_uri, char *a_idsName, int a_repeat,
2629781SMoriah.Waterland@Sun.COM 				char *a_altBinDir, char *a_device,
2639781SMoriah.Waterland@Sun.COM 				zoneList_t a_zlst);
2649781SMoriah.Waterland@Sun.COM static boolean_t	add_packages_in_nonglobal_zone(char **a_pkgList,
2659781SMoriah.Waterland@Sun.COM 				char *a_uri, char *a_idsName, int a_repeat,
2669781SMoriah.Waterland@Sun.COM 				char *a_altBinDir, char *a_device);
2679781SMoriah.Waterland@Sun.COM static boolean_t	check_applicability(char *a_packageDir,
2689781SMoriah.Waterland@Sun.COM 				char *a_pkgInst, char *a_rootPath,
2699781SMoriah.Waterland@Sun.COM 				CAF_T a_flags);
2709781SMoriah.Waterland@Sun.COM static boolean_t	get_package_list(char ***r_pkgList, char **a_argv,
2719781SMoriah.Waterland@Sun.COM 				char *a_categories, char **a_categoryList,
2729781SMoriah.Waterland@Sun.COM 				int a_ignoreSignatures, PKG_ERR *a_err,
2739781SMoriah.Waterland@Sun.COM 				ushort_t a_httpProxyPort, char *a_httpProxyName,
2749781SMoriah.Waterland@Sun.COM 				keystore_handle_t a_keystore,
2759781SMoriah.Waterland@Sun.COM 				char *a_keystoreFile, char *a_idsName,
2769781SMoriah.Waterland@Sun.COM 				int *r_repeat);
2779781SMoriah.Waterland@Sun.COM static boolean_t	continue_installation(void);
2789781SMoriah.Waterland@Sun.COM static boolean_t	unpack_and_check_packages(char **a_pkgList,
2799781SMoriah.Waterland@Sun.COM 				char *a_idsName, char *a_packageDir);
2809781SMoriah.Waterland@Sun.COM /*
2819781SMoriah.Waterland@Sun.COM  * *****************************************************************************
2829781SMoriah.Waterland@Sun.COM  * global external (public) functions
2839781SMoriah.Waterland@Sun.COM  * *****************************************************************************
2849781SMoriah.Waterland@Sun.COM  */
2859781SMoriah.Waterland@Sun.COM 
2869781SMoriah.Waterland@Sun.COM /*
2879781SMoriah.Waterland@Sun.COM  * Name:	main
2889781SMoriah.Waterland@Sun.COM  * Description:	main entry point for pkgadd/pkgask
2899781SMoriah.Waterland@Sun.COM  * Returns:	int
2909781SMoriah.Waterland@Sun.COM  *   0        Successful completion
2919781SMoriah.Waterland@Sun.COM  *   1        Fatal error.
2929781SMoriah.Waterland@Sun.COM  *   2        Warning.
2939781SMoriah.Waterland@Sun.COM  *   3        Interruption.
2949781SMoriah.Waterland@Sun.COM  *   4        Administration.
2959781SMoriah.Waterland@Sun.COM  *   5        Administration. Interaction is required. Do not use pkgadd -n.
2969781SMoriah.Waterland@Sun.COM  * In addition, one of the following values may be added to the previous value
2979781SMoriah.Waterland@Sun.COM  * as appropriate:
2989781SMoriah.Waterland@Sun.COM  *  10       Reboot after installation of all packages.
2999781SMoriah.Waterland@Sun.COM  *  20       Reboot after installation of this package.
3009781SMoriah.Waterland@Sun.COM  * For example, "14" would indicate both "administration" and "reboot after
3019781SMoriah.Waterland@Sun.COM  * installation of all packages".
3029781SMoriah.Waterland@Sun.COM  */
3039781SMoriah.Waterland@Sun.COM 
3049781SMoriah.Waterland@Sun.COM int
3059781SMoriah.Waterland@Sun.COM main(int argc, char **argv)
3069781SMoriah.Waterland@Sun.COM {
3079781SMoriah.Waterland@Sun.COM 	PKG_ERR			*err = NULL;
3089781SMoriah.Waterland@Sun.COM 	WebScheme		scheme = none;
3099781SMoriah.Waterland@Sun.COM 	char			**category = NULL;
3109781SMoriah.Waterland@Sun.COM 	char			*abiPtr;
3119781SMoriah.Waterland@Sun.COM 	char			*altBinDir = (char *)NULL;
3129781SMoriah.Waterland@Sun.COM 	char			*catg_arg = NULL;
3139781SMoriah.Waterland@Sun.COM 	char			*device = NULL;		/* dev pkg stored on */
3149781SMoriah.Waterland@Sun.COM 	char			*dwnld_dir = NULL;
3159781SMoriah.Waterland@Sun.COM 	char			*keystore_file = NULL;
3169781SMoriah.Waterland@Sun.COM 	char			*p;
3179781SMoriah.Waterland@Sun.COM 	char			*q;
3189781SMoriah.Waterland@Sun.COM 	char			*prog;
3199781SMoriah.Waterland@Sun.COM 	char			*prog_full_name = NULL;
3209781SMoriah.Waterland@Sun.COM 	char			*proxy = NULL;
3219781SMoriah.Waterland@Sun.COM 	char			*spoolDir = NULL;	/* specified with -s */
3229781SMoriah.Waterland@Sun.COM 	char			*uri = NULL;
3239781SMoriah.Waterland@Sun.COM 	char			Rpath[PATH_MAX+1] = {'\0'};
3249781SMoriah.Waterland@Sun.COM 	int			c;
3259781SMoriah.Waterland@Sun.COM 	int			ignore_sig = 0;
3269781SMoriah.Waterland@Sun.COM 	int			n;
3279781SMoriah.Waterland@Sun.COM 	int			repeat;
3289781SMoriah.Waterland@Sun.COM 	int			retries = NET_RETRIES_DEFAULT;
3299781SMoriah.Waterland@Sun.COM 	int			timeout = NET_TIMEOUT_DEFAULT;
3309781SMoriah.Waterland@Sun.COM 	keystore_handle_t	keystore = NULL;
3319781SMoriah.Waterland@Sun.COM 	struct sigaction	nact;
3329781SMoriah.Waterland@Sun.COM 	struct sigaction	oact;
3339781SMoriah.Waterland@Sun.COM 	ushort_t		proxy_port = 0;
3349781SMoriah.Waterland@Sun.COM 
3359781SMoriah.Waterland@Sun.COM 	/* initialize locale environment */
3369781SMoriah.Waterland@Sun.COM 
3379781SMoriah.Waterland@Sun.COM 	(void) setlocale(LC_ALL, "");
3389781SMoriah.Waterland@Sun.COM 	(void) textdomain(TEXT_DOMAIN);
3399781SMoriah.Waterland@Sun.COM 
3409781SMoriah.Waterland@Sun.COM 	/* initialize program name */
3419781SMoriah.Waterland@Sun.COM 
3429781SMoriah.Waterland@Sun.COM 	prog_full_name = argv[0];
3439781SMoriah.Waterland@Sun.COM 	prog = set_prog_name(argv[0]);
3449781SMoriah.Waterland@Sun.COM 
3459781SMoriah.Waterland@Sun.COM 	/* tell spmi zones interface how to access package output functions */
3469781SMoriah.Waterland@Sun.COM 
3479781SMoriah.Waterland@Sun.COM 	z_set_output_functions(echo, echoDebug, progerr);
3489781SMoriah.Waterland@Sun.COM 
3499781SMoriah.Waterland@Sun.COM 	askflag = (strcmp(prog, "pkgask") == 0);
3509781SMoriah.Waterland@Sun.COM 
3519781SMoriah.Waterland@Sun.COM 	/* set sane umask */
3529781SMoriah.Waterland@Sun.COM 
3539781SMoriah.Waterland@Sun.COM 	(void) umask(0022);
3549781SMoriah.Waterland@Sun.COM 
3559781SMoriah.Waterland@Sun.COM 	/* tell quit which ckreturn function to call */
3569781SMoriah.Waterland@Sun.COM 
3579781SMoriah.Waterland@Sun.COM 	quitSetCkreturnFunc(&ckreturn);
3589781SMoriah.Waterland@Sun.COM 
3599781SMoriah.Waterland@Sun.COM 	/* initially no source "device" */
3609781SMoriah.Waterland@Sun.COM 
3619781SMoriah.Waterland@Sun.COM 	device = NULL;
3629781SMoriah.Waterland@Sun.COM 
3639781SMoriah.Waterland@Sun.COM 	/* reset npkgs (used as pkg remaining count in quit.c) */
3649781SMoriah.Waterland@Sun.COM 
3659781SMoriah.Waterland@Sun.COM 	npkgs = 0;
3669781SMoriah.Waterland@Sun.COM 
3679781SMoriah.Waterland@Sun.COM 	/* set default password prompt for encrypted packages */
3689781SMoriah.Waterland@Sun.COM 
3699781SMoriah.Waterland@Sun.COM 	set_passphrase_prompt(MSG_PASSPROMPT);
3709781SMoriah.Waterland@Sun.COM 
3719781SMoriah.Waterland@Sun.COM 	/* initialize security operations structures and libraries */
3729781SMoriah.Waterland@Sun.COM 
3739781SMoriah.Waterland@Sun.COM 	sec_init();
3749781SMoriah.Waterland@Sun.COM 
3759781SMoriah.Waterland@Sun.COM 	if (z_running_in_global_zone() && !enable_local_fs()) {
3769781SMoriah.Waterland@Sun.COM 		progerr(ERR_CANNOT_ENABLE_LOCAL_FS);
3779781SMoriah.Waterland@Sun.COM 	}
3789781SMoriah.Waterland@Sun.COM 
379*9869SCasper.Dik@Sun.COM 	pkgserversetmode(DEFAULTMODE);
380*9869SCasper.Dik@Sun.COM 
3819781SMoriah.Waterland@Sun.COM 	/*
3829781SMoriah.Waterland@Sun.COM 	 * ********************************************************************
3839781SMoriah.Waterland@Sun.COM 	 * parse command line options
3849781SMoriah.Waterland@Sun.COM 	 * ********************************************************************
3859781SMoriah.Waterland@Sun.COM 	 */
3869781SMoriah.Waterland@Sun.COM 
3879781SMoriah.Waterland@Sun.COM 	while ((c = getopt(argc, argv,
3889781SMoriah.Waterland@Sun.COM 		"?Aa:b:B:Cc:D:d:GhIik:MnO:P:R:r:Ss:tV:vx:Y:zZ")) != EOF) {
3899781SMoriah.Waterland@Sun.COM 		switch (c) {
3909781SMoriah.Waterland@Sun.COM 
3919781SMoriah.Waterland@Sun.COM 		/*
3929781SMoriah.Waterland@Sun.COM 		 * Not a public interface: This disables attribute checking.
3939781SMoriah.Waterland@Sun.COM 		 * It speeds up installation a little bit.
3949781SMoriah.Waterland@Sun.COM 		 */
3959781SMoriah.Waterland@Sun.COM 		case 'A':
3969781SMoriah.Waterland@Sun.COM 			disableAttributes++;
3979781SMoriah.Waterland@Sun.COM 			break;
3989781SMoriah.Waterland@Sun.COM 
3999781SMoriah.Waterland@Sun.COM 		/*
4009781SMoriah.Waterland@Sun.COM 		 * Public interface: Define an installation administration
4019781SMoriah.Waterland@Sun.COM 		 * file, admin, to be used in place of the default
4029781SMoriah.Waterland@Sun.COM 		 * administration file.	 The token none overrides the use
4039781SMoriah.Waterland@Sun.COM 		 * of any admin file, and thus forces interaction with the
4049781SMoriah.Waterland@Sun.COM 		 * user. Unless a full path name is given, pkgadd first
4059781SMoriah.Waterland@Sun.COM 		 * looks in the current working directory for the
4069781SMoriah.Waterland@Sun.COM 		 * administration file.	 If the specified administration
4079781SMoriah.Waterland@Sun.COM 		 * file is not in the current working directory, pkgadd
4089781SMoriah.Waterland@Sun.COM 		 * looks in the /var/sadm/install/admin directory for the
4099781SMoriah.Waterland@Sun.COM 		 * administration file.
4109781SMoriah.Waterland@Sun.COM 		 */
4119781SMoriah.Waterland@Sun.COM 		case 'a':
4129781SMoriah.Waterland@Sun.COM 			admnfile = flex_device(optarg, 0);
4139781SMoriah.Waterland@Sun.COM 			break;
4149781SMoriah.Waterland@Sun.COM 
4159781SMoriah.Waterland@Sun.COM 		/*
4169781SMoriah.Waterland@Sun.COM 		 * Not a public interface: control block size given to
4179781SMoriah.Waterland@Sun.COM 		 * pkginstall - block size used in read()/write() loop;
4189781SMoriah.Waterland@Sun.COM 		 * default is st_blksize from stat() of source file.
4199781SMoriah.Waterland@Sun.COM 		 */
4209781SMoriah.Waterland@Sun.COM 		case 'B':
4219781SMoriah.Waterland@Sun.COM 			if (optarg[0] == '-') {
4229781SMoriah.Waterland@Sun.COM 				usage();
4239781SMoriah.Waterland@Sun.COM 				quit(1);
4249781SMoriah.Waterland@Sun.COM 			}
4259781SMoriah.Waterland@Sun.COM 			rw_block_size = optarg;
4269781SMoriah.Waterland@Sun.COM 			break;
4279781SMoriah.Waterland@Sun.COM 
4289781SMoriah.Waterland@Sun.COM 		/*
4299781SMoriah.Waterland@Sun.COM 		 * Not a public interface:  location where package executables
4309781SMoriah.Waterland@Sun.COM 		 * can be found - default is /usr/sadm/install/bin.
4319781SMoriah.Waterland@Sun.COM 		 */
4329781SMoriah.Waterland@Sun.COM 		case 'b':
4339781SMoriah.Waterland@Sun.COM 			if (optarg[0] == '-') {
4349781SMoriah.Waterland@Sun.COM 				usage();
4359781SMoriah.Waterland@Sun.COM 				quit(1);
4369781SMoriah.Waterland@Sun.COM 			}
4379781SMoriah.Waterland@Sun.COM 			if (!path_valid(optarg)) {
4389781SMoriah.Waterland@Sun.COM 				progerr(ERR_PATH, optarg);
4399781SMoriah.Waterland@Sun.COM 				quit(1);
4409781SMoriah.Waterland@Sun.COM 			}
4419781SMoriah.Waterland@Sun.COM 			if (isdir(optarg) != 0) {
4429781SMoriah.Waterland@Sun.COM 				p = strerror(errno);
4439781SMoriah.Waterland@Sun.COM 				progerr(ERR_CANNOT_USE_DIR, optarg, p);
4449781SMoriah.Waterland@Sun.COM 				quit(1);
4459781SMoriah.Waterland@Sun.COM 			}
4469781SMoriah.Waterland@Sun.COM 			altBinDir = optarg;
4479781SMoriah.Waterland@Sun.COM 			break;
4489781SMoriah.Waterland@Sun.COM 
4499781SMoriah.Waterland@Sun.COM 		/*
4509781SMoriah.Waterland@Sun.COM 		 * Not a public interface: This disables checksum tests on
4519781SMoriah.Waterland@Sun.COM 		 * the source files. It speeds up installation a little bit.
4529781SMoriah.Waterland@Sun.COM 		 */
4539781SMoriah.Waterland@Sun.COM 		case 'C':
4549781SMoriah.Waterland@Sun.COM 			disableChecksum++;
4559781SMoriah.Waterland@Sun.COM 			break;
4569781SMoriah.Waterland@Sun.COM 
4579781SMoriah.Waterland@Sun.COM 		/*
4589781SMoriah.Waterland@Sun.COM 		 * Not a public interface: This allows designation of a
4599781SMoriah.Waterland@Sun.COM 		 * continuation file. It is the same format as a dryrun file
4609781SMoriah.Waterland@Sun.COM 		 * but it is used to take up where the dryrun left off.
4619781SMoriah.Waterland@Sun.COM 		 */
4629781SMoriah.Waterland@Sun.COM 		case 'c':
4639781SMoriah.Waterland@Sun.COM 			pkgcontsrc = flex_device(optarg, 0);
4649781SMoriah.Waterland@Sun.COM 			break;
4659781SMoriah.Waterland@Sun.COM 
4669781SMoriah.Waterland@Sun.COM 		/*
4679781SMoriah.Waterland@Sun.COM 		 * Not a public interface: This allows designation of a
4689781SMoriah.Waterland@Sun.COM 		 * dryrun file. This pkgadd will create dryrun files
4699781SMoriah.Waterland@Sun.COM 		 * in the directory provided.
4709781SMoriah.Waterland@Sun.COM 		 */
4719781SMoriah.Waterland@Sun.COM 		case 'D':
4729781SMoriah.Waterland@Sun.COM 			if (optarg[0] == '-') {
4739781SMoriah.Waterland@Sun.COM 				usage();
4749781SMoriah.Waterland@Sun.COM 				quit(1);
4759781SMoriah.Waterland@Sun.COM 			}
4769781SMoriah.Waterland@Sun.COM 			pkgdrtarg = flex_device(optarg, 0);
4779781SMoriah.Waterland@Sun.COM 			break;
4789781SMoriah.Waterland@Sun.COM 
4799781SMoriah.Waterland@Sun.COM 		/*
4809781SMoriah.Waterland@Sun.COM 		 * Public interface: Install or copy a package from
4819781SMoriah.Waterland@Sun.COM 		 * device. device can be a full path name to a directory
4829781SMoriah.Waterland@Sun.COM 		 * or the identifiers for tape, floppy disk, or removable
4839781SMoriah.Waterland@Sun.COM 		 * disk - for example, /var/tmp or /floppy/floppy_name.
4849781SMoriah.Waterland@Sun.COM 		 * It can also be a device alias - for example,
4859781SMoriah.Waterland@Sun.COM 		 * /floppy/floppy0, or a datastream created by pkgtrans.
4869781SMoriah.Waterland@Sun.COM 		 */
4879781SMoriah.Waterland@Sun.COM 		case 'd':
4889781SMoriah.Waterland@Sun.COM 			if (optarg[0] == '-') {
4899781SMoriah.Waterland@Sun.COM 				usage();
4909781SMoriah.Waterland@Sun.COM 				quit(1);
4919781SMoriah.Waterland@Sun.COM 			}
4929781SMoriah.Waterland@Sun.COM 			if (!path_valid(optarg)) {
4939781SMoriah.Waterland@Sun.COM 				progerr(ERR_PATH, optarg);
4949781SMoriah.Waterland@Sun.COM 				quit(1);
4959781SMoriah.Waterland@Sun.COM 				/* NOTREACHED */
4969781SMoriah.Waterland@Sun.COM 			}
4979781SMoriah.Waterland@Sun.COM 
4989781SMoriah.Waterland@Sun.COM 			if (strncmp(optarg, HTTP, 7) == 0) {
4999781SMoriah.Waterland@Sun.COM 				scheme = web_http;
5009781SMoriah.Waterland@Sun.COM 			} else if (strncmp(optarg, HTTPS, 8) == 0) {
5019781SMoriah.Waterland@Sun.COM 				scheme = web_https;
5029781SMoriah.Waterland@Sun.COM 			}
5039781SMoriah.Waterland@Sun.COM 
5049781SMoriah.Waterland@Sun.COM 			if (scheme == web_https || scheme == web_http) {
5059781SMoriah.Waterland@Sun.COM 				uri = optarg;
5069781SMoriah.Waterland@Sun.COM 				if ((device = malloc(PATH_MAX)) == NULL) {
5079781SMoriah.Waterland@Sun.COM 					progerr(ERR_MEM);
5089781SMoriah.Waterland@Sun.COM 					exit(1);
5099781SMoriah.Waterland@Sun.COM 				}
5109781SMoriah.Waterland@Sun.COM 				(void) memset(device, '\0', PATH_MAX);
5119781SMoriah.Waterland@Sun.COM 			} else {
5129781SMoriah.Waterland@Sun.COM 				device = flex_device(optarg, 1);
5139781SMoriah.Waterland@Sun.COM 			}
5149781SMoriah.Waterland@Sun.COM 			break;
5159781SMoriah.Waterland@Sun.COM 
5169781SMoriah.Waterland@Sun.COM 		/*
5179781SMoriah.Waterland@Sun.COM 		 * Public interface: install package in global zone only.
5189781SMoriah.Waterland@Sun.COM 		 */
5199781SMoriah.Waterland@Sun.COM 		case 'G':
5209781SMoriah.Waterland@Sun.COM 			globalZoneOnly = B_TRUE;
5219781SMoriah.Waterland@Sun.COM 			break;
5229781SMoriah.Waterland@Sun.COM 
5239781SMoriah.Waterland@Sun.COM 		/*
5249781SMoriah.Waterland@Sun.COM 		 * Not a public interface: Enable hollow package support. When
5259781SMoriah.Waterland@Sun.COM 		 * specified, for any package that has SUNW_PKG_HOLLOW=true:
5269781SMoriah.Waterland@Sun.COM 		 *  Do not calculate and verify package size against target.
5279781SMoriah.Waterland@Sun.COM 		 *  Do not run any package procedure or class action scripts.
5289781SMoriah.Waterland@Sun.COM 		 *  Do not create any target directories.
5299781SMoriah.Waterland@Sun.COM 		 *  Do not perform any script locking.
5309781SMoriah.Waterland@Sun.COM 		 *  Do not install any components of any package.
5319781SMoriah.Waterland@Sun.COM 		 *  Do not output any status or database update messages.
5329781SMoriah.Waterland@Sun.COM 		 */
5339781SMoriah.Waterland@Sun.COM 		case 'h':
5349781SMoriah.Waterland@Sun.COM 			set_depend_pkginfo_DB(B_TRUE);
5359781SMoriah.Waterland@Sun.COM 			break;
5369781SMoriah.Waterland@Sun.COM 
5379781SMoriah.Waterland@Sun.COM 		/*
5389781SMoriah.Waterland@Sun.COM 		 * Not a public interface: Informs scripts that this is
5399781SMoriah.Waterland@Sun.COM 		 * an initial install by setting the environment parameter
5409781SMoriah.Waterland@Sun.COM 		 * PKG_INIT_INSTALL=TRUE for all scripts. They may use it as
5419781SMoriah.Waterland@Sun.COM 		 * they see fit, safe in the knowledge that the target
5429781SMoriah.Waterland@Sun.COM 		 * filesystem is tabula rasa.
5439781SMoriah.Waterland@Sun.COM 		 */
5449781SMoriah.Waterland@Sun.COM 		case 'I':
5459781SMoriah.Waterland@Sun.COM 			init_install++;
5469781SMoriah.Waterland@Sun.COM 			break;
5479781SMoriah.Waterland@Sun.COM 
5489781SMoriah.Waterland@Sun.COM 		/*
5499781SMoriah.Waterland@Sun.COM 		 * Not a public interface: ignore signatures.
5509781SMoriah.Waterland@Sun.COM 		 */
5519781SMoriah.Waterland@Sun.COM 		case 'i':
5529781SMoriah.Waterland@Sun.COM 			ignore_sig++;
5539781SMoriah.Waterland@Sun.COM 			break;
5549781SMoriah.Waterland@Sun.COM 
5559781SMoriah.Waterland@Sun.COM 		/*
5569781SMoriah.Waterland@Sun.COM 		 * Public interface: Use keystore as the location from which to
5579781SMoriah.Waterland@Sun.COM 		 * get trusted certificate authority certificates when verifying
5589781SMoriah.Waterland@Sun.COM 		 * digital signatures found in packages. If no keystore is
5599781SMoriah.Waterland@Sun.COM 		 * specified, then the default keystore locations are searched
5609781SMoriah.Waterland@Sun.COM 		 * for valid trusted certificates.
5619781SMoriah.Waterland@Sun.COM 		 */
5629781SMoriah.Waterland@Sun.COM 		case 'k':
5639781SMoriah.Waterland@Sun.COM 			if (!path_valid(optarg)) {
5649781SMoriah.Waterland@Sun.COM 				progerr(ERR_PATH, optarg);
5659781SMoriah.Waterland@Sun.COM 				quit(1);
5669781SMoriah.Waterland@Sun.COM 				/* NOTREACHED */
5679781SMoriah.Waterland@Sun.COM 			}
5689781SMoriah.Waterland@Sun.COM 			keystore_file = optarg;
5699781SMoriah.Waterland@Sun.COM 			break;
5709781SMoriah.Waterland@Sun.COM 
5719781SMoriah.Waterland@Sun.COM 		/*
5729781SMoriah.Waterland@Sun.COM 		 * Public interface: Instruct pkgadd not to use the
5739781SMoriah.Waterland@Sun.COM 		 * $root_path/etc/vfstab file for determining the client's
5749781SMoriah.Waterland@Sun.COM 		 * mount points. This option assumes the mount points are
5759781SMoriah.Waterland@Sun.COM 		 * correct on the server and it behaves consistently with
5769781SMoriah.Waterland@Sun.COM 		 * Solaris 2.5 and earlier releases.
5779781SMoriah.Waterland@Sun.COM 		 */
5789781SMoriah.Waterland@Sun.COM 		case 'M':
5799781SMoriah.Waterland@Sun.COM 			no_map_client = 1;
5809781SMoriah.Waterland@Sun.COM 			break;
5819781SMoriah.Waterland@Sun.COM 
5829781SMoriah.Waterland@Sun.COM 		/*
5839781SMoriah.Waterland@Sun.COM 		 * Not a public interface: the -O option allows the behavior
5849781SMoriah.Waterland@Sun.COM 		 * of the package tools to be modified. Recognized options:
5859781SMoriah.Waterland@Sun.COM 		 * -> debug
5869781SMoriah.Waterland@Sun.COM 		 * ---> enable debugging output
5879781SMoriah.Waterland@Sun.COM 		 * -> addzonename
5889781SMoriah.Waterland@Sun.COM 		 * ---> add zone name to appropriate messages
5899781SMoriah.Waterland@Sun.COM 		 * -> nozones
5909781SMoriah.Waterland@Sun.COM 		 * ---> act as though in global zone with no non-global zones
5919781SMoriah.Waterland@Sun.COM 		 * -> inherited-filesystems
5929781SMoriah.Waterland@Sun.COM 		 * ---> add specified file system to list of file systems
5939781SMoriah.Waterland@Sun.COM 		 * ---> that are inherited from the global zone
5949781SMoriah.Waterland@Sun.COM 		 * -> enable-hollow-package-support
5959781SMoriah.Waterland@Sun.COM 		 * ---> Enable hollow package support. When specified, for any
5969781SMoriah.Waterland@Sun.COM 		 * ---> package that has SUNW_PKG_HOLLOW=true:
5979781SMoriah.Waterland@Sun.COM 		 * ---> Do not calculate and verify package size against target
5989781SMoriah.Waterland@Sun.COM 		 * ---> Do not run any package procedure or class action scripts
5999781SMoriah.Waterland@Sun.COM 		 * ---> Do not create any target directories
6009781SMoriah.Waterland@Sun.COM 		 * ---> Do not perform any script locking
6019781SMoriah.Waterland@Sun.COM 		 * ---> Do not install any components of any package
6029781SMoriah.Waterland@Sun.COM 		 * ---> Do not output any status or database update messages
6039781SMoriah.Waterland@Sun.COM 		 * -> zonelist="<names...>"
6049781SMoriah.Waterland@Sun.COM 		 * ---> add package to space/colon separated list of zones only
6059781SMoriah.Waterland@Sun.COM 		 */
6069781SMoriah.Waterland@Sun.COM 
6079781SMoriah.Waterland@Sun.COM 		case 'O':
6089781SMoriah.Waterland@Sun.COM 			for (p = strtok(optarg, ","); p != (char *)NULL;
6099781SMoriah.Waterland@Sun.COM 				p = strtok(NULL, ",")) {
6109781SMoriah.Waterland@Sun.COM 
6119781SMoriah.Waterland@Sun.COM 				if (strcmp(p, "debug") == 0) {
6129781SMoriah.Waterland@Sun.COM 					/* set debug flag/enable debug output */
6139781SMoriah.Waterland@Sun.COM 					debugFlag = B_TRUE;
6149781SMoriah.Waterland@Sun.COM 					(void) echoDebugSetFlag(debugFlag);
6159781SMoriah.Waterland@Sun.COM 
6169781SMoriah.Waterland@Sun.COM 					/* debug info on arguments to pkgadd */
6179781SMoriah.Waterland@Sun.COM 					for (n = 0; n < argc && argv[n]; n++) {
6189781SMoriah.Waterland@Sun.COM 						echoDebug(DBG_ARG, n, argv[n]);
6199781SMoriah.Waterland@Sun.COM 					}
6209781SMoriah.Waterland@Sun.COM 
6219781SMoriah.Waterland@Sun.COM 					continue;
6229781SMoriah.Waterland@Sun.COM 				}
6239781SMoriah.Waterland@Sun.COM 
6249781SMoriah.Waterland@Sun.COM 				if (strcmp(p,
6259781SMoriah.Waterland@Sun.COM 					"enable-hollow-package-support") == 0) {
6269781SMoriah.Waterland@Sun.COM 					set_depend_pkginfo_DB(B_TRUE);
6279781SMoriah.Waterland@Sun.COM 					continue;
6289781SMoriah.Waterland@Sun.COM 				}
6299781SMoriah.Waterland@Sun.COM 
6309781SMoriah.Waterland@Sun.COM 				if (strncmp(p, INHERITFS, INHERITFS_LEN) == 0) {
6319781SMoriah.Waterland@Sun.COM 					if (z_add_inherited_file_system(
6329781SMoriah.Waterland@Sun.COM 						p+INHERITFS_LEN) == B_FALSE) {
6339781SMoriah.Waterland@Sun.COM 						progerr(ERR_NOSUCH_INHERITED,
6349781SMoriah.Waterland@Sun.COM 							p+INHERITFS_LEN);
6359781SMoriah.Waterland@Sun.COM 						quit(1);
6369781SMoriah.Waterland@Sun.COM 						/* NOTREACHED */
6379781SMoriah.Waterland@Sun.COM 					}
6389781SMoriah.Waterland@Sun.COM 					continue;
6399781SMoriah.Waterland@Sun.COM 				}
6409781SMoriah.Waterland@Sun.COM 
6419781SMoriah.Waterland@Sun.COM 				if (strcmp(p, "addzonename") == 0) {
6429781SMoriah.Waterland@Sun.COM 					quitSetZoneName(z_get_zonename());
6439781SMoriah.Waterland@Sun.COM 					continue;
6449781SMoriah.Waterland@Sun.COM 				}
6459781SMoriah.Waterland@Sun.COM 
6469781SMoriah.Waterland@Sun.COM 				if (strcmp(p, "nozones") == 0) {
6479781SMoriah.Waterland@Sun.COM 					noZones = B_TRUE;
6489781SMoriah.Waterland@Sun.COM 					continue;
6499781SMoriah.Waterland@Sun.COM 				}
6509781SMoriah.Waterland@Sun.COM 
6519781SMoriah.Waterland@Sun.COM 				/*
6529781SMoriah.Waterland@Sun.COM 				 * Private interface: package is being
6539781SMoriah.Waterland@Sun.COM 				 * installed as a patch package.
6549781SMoriah.Waterland@Sun.COM 				 */
6559781SMoriah.Waterland@Sun.COM 
6569781SMoriah.Waterland@Sun.COM 				if (strcmp(p, "patchPkgInstall") == 0) {
6579781SMoriah.Waterland@Sun.COM 					setPatchUpdate();
6589781SMoriah.Waterland@Sun.COM 					continue;
6599781SMoriah.Waterland@Sun.COM 				}
6609781SMoriah.Waterland@Sun.COM 
6619781SMoriah.Waterland@Sun.COM 				/*
6629781SMoriah.Waterland@Sun.COM 				 * If this is a patch removal
6639781SMoriah.Waterland@Sun.COM 				 * then call setPatchUpdate() and set
6649781SMoriah.Waterland@Sun.COM 				 * patchPkgRemoval flag.
6659781SMoriah.Waterland@Sun.COM 				 */
6669781SMoriah.Waterland@Sun.COM 				if (strcmp(p, "patchPkgRemoval") == 0) {
6679781SMoriah.Waterland@Sun.COM 					setPatchUpdate();
6689781SMoriah.Waterland@Sun.COM 					patchPkgRemoval = B_TRUE;
6699781SMoriah.Waterland@Sun.COM 					continue;
6709781SMoriah.Waterland@Sun.COM 				}
6719781SMoriah.Waterland@Sun.COM 
6729781SMoriah.Waterland@Sun.COM 				if (strncmp(p, "zonelist=", 9) == 0) {
6739781SMoriah.Waterland@Sun.COM 					/*
6749781SMoriah.Waterland@Sun.COM 					 * If colons used as separators,
6759781SMoriah.Waterland@Sun.COM 					 * convert to spaces.
6769781SMoriah.Waterland@Sun.COM 					 */
6779781SMoriah.Waterland@Sun.COM 					q = p + 9;
6789781SMoriah.Waterland@Sun.COM 					while (*q != '\0') {
6799781SMoriah.Waterland@Sun.COM 						if (*q == ':') {
6809781SMoriah.Waterland@Sun.COM 							*q = ' ';
6819781SMoriah.Waterland@Sun.COM 						}
6829781SMoriah.Waterland@Sun.COM 						q++;
6839781SMoriah.Waterland@Sun.COM 					}
6849781SMoriah.Waterland@Sun.COM 
6859781SMoriah.Waterland@Sun.COM 					if (z_set_zone_spec(p + 9) == -1)
6869781SMoriah.Waterland@Sun.COM 						quit(1);
6879781SMoriah.Waterland@Sun.COM 					usedZoneList = B_TRUE;
6889781SMoriah.Waterland@Sun.COM 					continue;
6899781SMoriah.Waterland@Sun.COM 				}
6909781SMoriah.Waterland@Sun.COM 
6919781SMoriah.Waterland@Sun.COM 				progerr(ERR_INVALID_O_OPTION, p);
6929781SMoriah.Waterland@Sun.COM 				continue;
6939781SMoriah.Waterland@Sun.COM 			}
6949781SMoriah.Waterland@Sun.COM 			break;
6959781SMoriah.Waterland@Sun.COM 
6969781SMoriah.Waterland@Sun.COM 		/*
6979781SMoriah.Waterland@Sun.COM 		 * Public interface: installation occurs in
6989781SMoriah.Waterland@Sun.COM 		 * non-interactive mode.  Suppress output of the list of
6999781SMoriah.Waterland@Sun.COM 		 * installed files. The default mode is interactive.
7009781SMoriah.Waterland@Sun.COM 		 */
7019781SMoriah.Waterland@Sun.COM 		case 'n':
7029781SMoriah.Waterland@Sun.COM 			nointeract++;
7039781SMoriah.Waterland@Sun.COM 			(void) echoSetFlag(B_FALSE);
7049781SMoriah.Waterland@Sun.COM 			break;
7059781SMoriah.Waterland@Sun.COM 
7069781SMoriah.Waterland@Sun.COM 		/*
7079781SMoriah.Waterland@Sun.COM 		 * Public interface: Password to use to decrypt keystore
7089781SMoriah.Waterland@Sun.COM 		 * specified with -k, if required. See PASS PHRASE
7099781SMoriah.Waterland@Sun.COM 		 * ARGUMENTS for more information about the format of this
7109781SMoriah.Waterland@Sun.COM 		 * option's argument.
7119781SMoriah.Waterland@Sun.COM 		 */
7129781SMoriah.Waterland@Sun.COM 		case 'P':
7139781SMoriah.Waterland@Sun.COM 			if (optarg[0] == '-') {
7149781SMoriah.Waterland@Sun.COM 				usage();
7159781SMoriah.Waterland@Sun.COM 				quit(1);
7169781SMoriah.Waterland@Sun.COM 			}
7179781SMoriah.Waterland@Sun.COM 			set_passphrase_passarg(optarg);
7189781SMoriah.Waterland@Sun.COM 			if (ci_strneq(optarg, "pass:", 5)) {
7199781SMoriah.Waterland@Sun.COM 				/*
7209781SMoriah.Waterland@Sun.COM 				 * passwords on the command line are highly
7219781SMoriah.Waterland@Sun.COM 				 * insecure.  complain.
7229781SMoriah.Waterland@Sun.COM 				 */
7239781SMoriah.Waterland@Sun.COM 				logerr(PASSWD_CMDLINE, "pass:<pass>");
7249781SMoriah.Waterland@Sun.COM 			}
7259781SMoriah.Waterland@Sun.COM 			break;
7269781SMoriah.Waterland@Sun.COM 
7279781SMoriah.Waterland@Sun.COM 		/*
7289781SMoriah.Waterland@Sun.COM 		 * Public interface: Define the full path name of a
7299781SMoriah.Waterland@Sun.COM 		 * directory to use as the root_path.  All files,
7309781SMoriah.Waterland@Sun.COM 		 * including package system information files, are
7319781SMoriah.Waterland@Sun.COM 		 * relocated to a directory tree starting in the specified
7329781SMoriah.Waterland@Sun.COM 		 * root_path. The root_path may be specified when
7339781SMoriah.Waterland@Sun.COM 		 * installing to a client from a server (for example,
7349781SMoriah.Waterland@Sun.COM 		 * /export/root/client1).
7359781SMoriah.Waterland@Sun.COM 		 */
7369781SMoriah.Waterland@Sun.COM 		case 'R':
7379781SMoriah.Waterland@Sun.COM 			if (optarg[0] == '-') {
7389781SMoriah.Waterland@Sun.COM 				usage();
7399781SMoriah.Waterland@Sun.COM 				quit(1);
7409781SMoriah.Waterland@Sun.COM 			}
7419781SMoriah.Waterland@Sun.COM 			/* determine the real path specified */
7429781SMoriah.Waterland@Sun.COM 
7439781SMoriah.Waterland@Sun.COM 			n = resolvepath(optarg, Rpath, sizeof (Rpath)-1);
7449781SMoriah.Waterland@Sun.COM 
7459781SMoriah.Waterland@Sun.COM 			/* use supplied path if not resolvable */
7469781SMoriah.Waterland@Sun.COM 
7479781SMoriah.Waterland@Sun.COM 			if (n == -1) {
7489781SMoriah.Waterland@Sun.COM 				(void) strlcpy(Rpath, optarg, sizeof (Rpath));
7499781SMoriah.Waterland@Sun.COM 			} else {
7509781SMoriah.Waterland@Sun.COM 				/* null terminate string */
7519781SMoriah.Waterland@Sun.COM 				Rpath[n] = '\0';
7529781SMoriah.Waterland@Sun.COM 			}
7539781SMoriah.Waterland@Sun.COM 
7549781SMoriah.Waterland@Sun.COM 			/* set the alternative root path */
7559781SMoriah.Waterland@Sun.COM 
7569781SMoriah.Waterland@Sun.COM 			if (!set_inst_root(Rpath)) {
7579781SMoriah.Waterland@Sun.COM 				progerr(ERR_ROOT_CMD);
7589781SMoriah.Waterland@Sun.COM 				exit(1);
7599781SMoriah.Waterland@Sun.COM 			}
7609781SMoriah.Waterland@Sun.COM 			break;
7619781SMoriah.Waterland@Sun.COM 
7629781SMoriah.Waterland@Sun.COM 		/*
7639781SMoriah.Waterland@Sun.COM 		 * Public interface: Identify a file or directory which
7649781SMoriah.Waterland@Sun.COM 		 * contains output from a previous pkgask(1M)
7659781SMoriah.Waterland@Sun.COM 		 * session. This file supplies the interaction responses
7669781SMoriah.Waterland@Sun.COM 		 * that would be requested by the package in interactive
7679781SMoriah.Waterland@Sun.COM 		 * mode. response must be a full pathname.
7689781SMoriah.Waterland@Sun.COM 		 */
7699781SMoriah.Waterland@Sun.COM 		case 'r':
7709781SMoriah.Waterland@Sun.COM 			if (optarg[0] == '-') {
7719781SMoriah.Waterland@Sun.COM 				usage();
7729781SMoriah.Waterland@Sun.COM 				quit(1);
7739781SMoriah.Waterland@Sun.COM 			}
7749781SMoriah.Waterland@Sun.COM 			respfile = flex_device(optarg, 2);
7759781SMoriah.Waterland@Sun.COM 			if (isdir(respfile) == 0)
7769781SMoriah.Waterland@Sun.COM 				respdir = respfile;
7779781SMoriah.Waterland@Sun.COM 			break;
7789781SMoriah.Waterland@Sun.COM 
7799781SMoriah.Waterland@Sun.COM 		/*
7809781SMoriah.Waterland@Sun.COM 		 * Not a public interface: suppress copyright notice being
7819781SMoriah.Waterland@Sun.COM 		 * output during installation.
7829781SMoriah.Waterland@Sun.COM 		 */
7839781SMoriah.Waterland@Sun.COM 		case 'S':
7849781SMoriah.Waterland@Sun.COM 			suppressCopyright++;
7859781SMoriah.Waterland@Sun.COM 			break;
7869781SMoriah.Waterland@Sun.COM 
7879781SMoriah.Waterland@Sun.COM 		/*
7889781SMoriah.Waterland@Sun.COM 		 * Public interface: Write the package into the directory
7899781SMoriah.Waterland@Sun.COM 		 * spool instead of installing it. The default directory
7909781SMoriah.Waterland@Sun.COM 		 * for spooled packages is /var/sadm/pkg.
7919781SMoriah.Waterland@Sun.COM 		 */
7929781SMoriah.Waterland@Sun.COM 		case 's':
7939781SMoriah.Waterland@Sun.COM 			spoolDir = flex_device(optarg, 1);
7949781SMoriah.Waterland@Sun.COM 			break;
7959781SMoriah.Waterland@Sun.COM 
7969781SMoriah.Waterland@Sun.COM 		/*
7979781SMoriah.Waterland@Sun.COM 		 * Not a public interface: disable save spool area creation;
7989781SMoriah.Waterland@Sun.COM 		 * suppress the creation and population of the package save
7999781SMoriah.Waterland@Sun.COM 		 * spool area (var/sadm/pkg/PKG/save/pspool/PKG).
8009781SMoriah.Waterland@Sun.COM 		 */
8019781SMoriah.Waterland@Sun.COM 		case 't':
8029781SMoriah.Waterland@Sun.COM 			disableSaveSpool++;
8039781SMoriah.Waterland@Sun.COM 			break;
8049781SMoriah.Waterland@Sun.COM 
8059781SMoriah.Waterland@Sun.COM 		/*
8069781SMoriah.Waterland@Sun.COM 		 * Public interface: Specify an alternative fs_file to map
8079781SMoriah.Waterland@Sun.COM 		 * the client's file systems.  For example, used in
8089781SMoriah.Waterland@Sun.COM 		 * situations where the $root_path/etc/vfstab file is
8099781SMoriah.Waterland@Sun.COM 		 * non-existent or unreliable. Informs the pkginstall
8109781SMoriah.Waterland@Sun.COM 		 * portion to mount up a client filesystem based upon the
8119781SMoriah.Waterland@Sun.COM 		 * supplied vfstab-like file of stable format.
8129781SMoriah.Waterland@Sun.COM 		 */
8139781SMoriah.Waterland@Sun.COM 		case 'V':
8149781SMoriah.Waterland@Sun.COM 			vfstab_file = flex_device(optarg, 2);
8159781SMoriah.Waterland@Sun.COM 			no_map_client = 0;
8169781SMoriah.Waterland@Sun.COM 			break;
8179781SMoriah.Waterland@Sun.COM 
8189781SMoriah.Waterland@Sun.COM 		/*
8199781SMoriah.Waterland@Sun.COM 		 * Public interface: Trace all of the scripts that get
8209781SMoriah.Waterland@Sun.COM 		 * executed by pkgadd, located in the pkginst/install
8219781SMoriah.Waterland@Sun.COM 		 * directory. This option is used for debugging the
8229781SMoriah.Waterland@Sun.COM 		 * procedural and non-procedural scripts
8239781SMoriah.Waterland@Sun.COM 		 */
8249781SMoriah.Waterland@Sun.COM 		case 'v':
8259781SMoriah.Waterland@Sun.COM 			pkgverbose++;
8269781SMoriah.Waterland@Sun.COM 			break;
8279781SMoriah.Waterland@Sun.COM 
8289781SMoriah.Waterland@Sun.COM 		/*
8299781SMoriah.Waterland@Sun.COM 		 * Public interface: Specify a HTTP[S] proxy to use when
8309781SMoriah.Waterland@Sun.COM 		 * downloading packages The format of proxy is host:port,
8319781SMoriah.Waterland@Sun.COM 		 * where host is the hostname of the HTTP[S] proxy, and
8329781SMoriah.Waterland@Sun.COM 		 * port is the port number associated with the proxy. This
8339781SMoriah.Waterland@Sun.COM 		 * switch overrides all other methods of specifying a
8349781SMoriah.Waterland@Sun.COM 		 * proxy. See ENVIRONMENT VARIABLES for more information
8359781SMoriah.Waterland@Sun.COM 		 * on alternate methods of specifying a default proxy.
8369781SMoriah.Waterland@Sun.COM 		 */
8379781SMoriah.Waterland@Sun.COM 		case 'x':
8389781SMoriah.Waterland@Sun.COM 			if (!path_valid(optarg)) {
8399781SMoriah.Waterland@Sun.COM 				progerr(ERR_PATH, optarg);
8409781SMoriah.Waterland@Sun.COM 				quit(1);
8419781SMoriah.Waterland@Sun.COM 				/* NOTREACHED */
8429781SMoriah.Waterland@Sun.COM 			}
8439781SMoriah.Waterland@Sun.COM 			proxy = optarg;
8449781SMoriah.Waterland@Sun.COM 			break;
8459781SMoriah.Waterland@Sun.COM 
8469781SMoriah.Waterland@Sun.COM 		/*
8479781SMoriah.Waterland@Sun.COM 		 * Public interface: Install packages based on the value
8489781SMoriah.Waterland@Sun.COM 		 * of the CATEGORY parameter stored in the package's
8499781SMoriah.Waterland@Sun.COM 		 * pkginfo(4) file. All packages on the source medium
8509781SMoriah.Waterland@Sun.COM 		 * whose CATEGORY matches one of the specified categories
8519781SMoriah.Waterland@Sun.COM 		 * will be selected for installation or spooling. Install
8529781SMoriah.Waterland@Sun.COM 		 * packages that contain the same CATEGORY as the one
8539781SMoriah.Waterland@Sun.COM 		 * provided on the command line.
8549781SMoriah.Waterland@Sun.COM 		 */
8559781SMoriah.Waterland@Sun.COM 		case 'Y':
8569781SMoriah.Waterland@Sun.COM 			if (optarg[0] == '-') {
8579781SMoriah.Waterland@Sun.COM 				usage();
8589781SMoriah.Waterland@Sun.COM 				quit(1);
8599781SMoriah.Waterland@Sun.COM 			}
8609781SMoriah.Waterland@Sun.COM 			catg_arg = strdup(optarg);
8619781SMoriah.Waterland@Sun.COM 
8629781SMoriah.Waterland@Sun.COM 			if ((category = get_categories(catg_arg)) == NULL) {
8639781SMoriah.Waterland@Sun.COM 				progerr(ERR_CAT_INV, catg_arg);
8649781SMoriah.Waterland@Sun.COM 				exit(1);
8659781SMoriah.Waterland@Sun.COM 			} else if (is_not_valid_length(category)) {
8669781SMoriah.Waterland@Sun.COM 				progerr(ERR_CAT_LNGTH);
8679781SMoriah.Waterland@Sun.COM 				exit(1);
8689781SMoriah.Waterland@Sun.COM 			}
8699781SMoriah.Waterland@Sun.COM 			break;
8709781SMoriah.Waterland@Sun.COM 
8719781SMoriah.Waterland@Sun.COM 		/*
8729781SMoriah.Waterland@Sun.COM 		 * Not a public interface: perform fresh install from
8739781SMoriah.Waterland@Sun.COM 		 * package save spool area. When set, the package contents
8749781SMoriah.Waterland@Sun.COM 		 * are installed from the package spool save area instead
8759781SMoriah.Waterland@Sun.COM 		 * of from the package root area, so that the original
8769781SMoriah.Waterland@Sun.COM 		 * source packages are not required to install the
8779781SMoriah.Waterland@Sun.COM 		 * package. If the -h option is also specified and the
8789781SMoriah.Waterland@Sun.COM 		 * package is hollow, then this option is ignored. When -z
8799781SMoriah.Waterland@Sun.COM 		 * is specified:
8809781SMoriah.Waterland@Sun.COM 		 *  - Editable files are installed from the package instance
8819781SMoriah.Waterland@Sun.COM 		 *    save area.
8829781SMoriah.Waterland@Sun.COM 		 *  - Volatile files are installed from the package instance
8839781SMoriah.Waterland@Sun.COM 		 *    save area.
8849781SMoriah.Waterland@Sun.COM 		 *  - Executable and data files are installed from the final
8859781SMoriah.Waterland@Sun.COM 		 *    installed location as specified in the pkgmap file.
8869781SMoriah.Waterland@Sun.COM 		 *  - Installation scripts are run from the package spool
8879781SMoriah.Waterland@Sun.COM 		 *    save area.
8889781SMoriah.Waterland@Sun.COM 		 */
8899781SMoriah.Waterland@Sun.COM 		case 'z':
8909781SMoriah.Waterland@Sun.COM 			saveSpoolInstall++;
8919781SMoriah.Waterland@Sun.COM 			break;
8929781SMoriah.Waterland@Sun.COM 
8939781SMoriah.Waterland@Sun.COM 		/*
8949781SMoriah.Waterland@Sun.COM 		 * unrecognized option
8959781SMoriah.Waterland@Sun.COM 		 */
8969781SMoriah.Waterland@Sun.COM 
8979781SMoriah.Waterland@Sun.COM 		default:
8989781SMoriah.Waterland@Sun.COM 			usage();
8999781SMoriah.Waterland@Sun.COM 			return (1);
9009781SMoriah.Waterland@Sun.COM 		}
9019781SMoriah.Waterland@Sun.COM 	}
9029781SMoriah.Waterland@Sun.COM 
9039781SMoriah.Waterland@Sun.COM 	/*
9049781SMoriah.Waterland@Sun.COM 	 * ********************************************************************
9059781SMoriah.Waterland@Sun.COM 	 * validate command line options
9069781SMoriah.Waterland@Sun.COM 	 * ********************************************************************
9079781SMoriah.Waterland@Sun.COM 	 */
9089781SMoriah.Waterland@Sun.COM 
9099781SMoriah.Waterland@Sun.COM 	/* set "debug echo" flag according to setting of "-O debug" option */
9109781SMoriah.Waterland@Sun.COM 
9119781SMoriah.Waterland@Sun.COM 	(void) echoDebugSetFlag(debugFlag);
9129781SMoriah.Waterland@Sun.COM 
9139781SMoriah.Waterland@Sun.COM 	/* output entry debugging information */
9149781SMoriah.Waterland@Sun.COM 
9159781SMoriah.Waterland@Sun.COM 	if (z_running_in_global_zone()) {
9169781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_ENTRY_IN_GZ, prog_full_name);
9179781SMoriah.Waterland@Sun.COM 	} else {
9189781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_ENTRY_IN_LZ, prog_full_name, getzoneid(),
9199781SMoriah.Waterland@Sun.COM 			z_get_zonename());
9209781SMoriah.Waterland@Sun.COM 	}
9219781SMoriah.Waterland@Sun.COM 
9229781SMoriah.Waterland@Sun.COM 	/*
9239781SMoriah.Waterland@Sun.COM 	 * Later, it may be decided to pursue this ability to continue to an
9249781SMoriah.Waterland@Sun.COM 	 * actual installation based only on the dryrun data. At this time,
9259781SMoriah.Waterland@Sun.COM 	 * it is too risky.
9269781SMoriah.Waterland@Sun.COM 	 */
9279781SMoriah.Waterland@Sun.COM 
9289781SMoriah.Waterland@Sun.COM 	if (pkgcontsrc && !pkgdrtarg) {
9299781SMoriah.Waterland@Sun.COM 		progerr(ERR_NO_LIVE_MODE);
9309781SMoriah.Waterland@Sun.COM 		usage();
9319781SMoriah.Waterland@Sun.COM 		return (1);
9329781SMoriah.Waterland@Sun.COM 	}
9339781SMoriah.Waterland@Sun.COM 
9349781SMoriah.Waterland@Sun.COM 	/* ignore -G option if not used in the global zone */
9359781SMoriah.Waterland@Sun.COM 
9369781SMoriah.Waterland@Sun.COM 	if (!z_running_in_global_zone()) {
9379781SMoriah.Waterland@Sun.COM 		globalZoneOnly = B_FALSE;
9389781SMoriah.Waterland@Sun.COM 	}
9399781SMoriah.Waterland@Sun.COM 
9409781SMoriah.Waterland@Sun.COM 	/* if zonelist used, must be in global zone */
9419781SMoriah.Waterland@Sun.COM 
9429781SMoriah.Waterland@Sun.COM 	if (usedZoneList && !z_running_in_global_zone()) {
9439781SMoriah.Waterland@Sun.COM 		progerr(ERR_Z_USED_IN_NONGLOBAL_ZONE);
9449781SMoriah.Waterland@Sun.COM 		return (1);
9459781SMoriah.Waterland@Sun.COM 	}
9469781SMoriah.Waterland@Sun.COM 
9479781SMoriah.Waterland@Sun.COM 	/* -G and zonelist cannot be used together */
9489781SMoriah.Waterland@Sun.COM 
9499781SMoriah.Waterland@Sun.COM 	if (globalZoneOnly && usedZoneList) {
9509781SMoriah.Waterland@Sun.COM 		progerr(ERR_GZ_USED_TOGETHER);
9519781SMoriah.Waterland@Sun.COM 		usage();
9529781SMoriah.Waterland@Sun.COM 		return (1);
9539781SMoriah.Waterland@Sun.COM 	}
9549781SMoriah.Waterland@Sun.COM 
9559781SMoriah.Waterland@Sun.COM 	/* -s cannot be used with either -G or zonelist */
9569781SMoriah.Waterland@Sun.COM 
9579781SMoriah.Waterland@Sun.COM 	if (spoolDir != NULL) {
9589781SMoriah.Waterland@Sun.COM 		if (globalZoneOnly) {
9599781SMoriah.Waterland@Sun.COM 			progerr(ERR_SPOOLDIR_USED_WITH_G);
9609781SMoriah.Waterland@Sun.COM 			usage();
9619781SMoriah.Waterland@Sun.COM 			return (1);
9629781SMoriah.Waterland@Sun.COM 		}
9639781SMoriah.Waterland@Sun.COM 		if (usedZoneList) {
9649781SMoriah.Waterland@Sun.COM 			progerr(ERR_SPOOLDIR_USED_WITH_Z);
9659781SMoriah.Waterland@Sun.COM 			usage();
9669781SMoriah.Waterland@Sun.COM 			return (1);
9679781SMoriah.Waterland@Sun.COM 		}
9689781SMoriah.Waterland@Sun.COM 		if (strcmp(spoolDir, "/var/sadm/pkg") == 0) {
9699781SMoriah.Waterland@Sun.COM 			progerr(ERR_SPOOLDIR_CANNOT_BE_SYS, "/var/sadm/pkg");
9709781SMoriah.Waterland@Sun.COM 			usage();
9719781SMoriah.Waterland@Sun.COM 			return (1);
9729781SMoriah.Waterland@Sun.COM 		}
9739781SMoriah.Waterland@Sun.COM 	}
9749781SMoriah.Waterland@Sun.COM 
9759781SMoriah.Waterland@Sun.COM 	/* pkgask does not support the same options as pkgadd */
9769781SMoriah.Waterland@Sun.COM 
9779781SMoriah.Waterland@Sun.COM 	if (askflag && proxy) {
9789781SMoriah.Waterland@Sun.COM 		progerr(ERR_PKGASK_AND_PROXY);
9799781SMoriah.Waterland@Sun.COM 		usage();
9809781SMoriah.Waterland@Sun.COM 		return (1);
9819781SMoriah.Waterland@Sun.COM 	}
9829781SMoriah.Waterland@Sun.COM 
9839781SMoriah.Waterland@Sun.COM 	if (askflag && uri) {
9849781SMoriah.Waterland@Sun.COM 		progerr(ERR_PKGASK_AND_URI);
9859781SMoriah.Waterland@Sun.COM 		usage();
9869781SMoriah.Waterland@Sun.COM 		return (1);
9879781SMoriah.Waterland@Sun.COM 	}
9889781SMoriah.Waterland@Sun.COM 
9899781SMoriah.Waterland@Sun.COM 	if (askflag && keystore_file) {
9909781SMoriah.Waterland@Sun.COM 		progerr(ERR_PKGASK_AND_KEYSTORE_FILE);
9919781SMoriah.Waterland@Sun.COM 		usage();
9929781SMoriah.Waterland@Sun.COM 		return (1);
9939781SMoriah.Waterland@Sun.COM 	}
9949781SMoriah.Waterland@Sun.COM 
9959781SMoriah.Waterland@Sun.COM 	if (askflag && ignore_sig) {
9969781SMoriah.Waterland@Sun.COM 		progerr(ERR_PKGASK_AND_IGNORE_SIG);
9979781SMoriah.Waterland@Sun.COM 		usage();
9989781SMoriah.Waterland@Sun.COM 		return (1);
9999781SMoriah.Waterland@Sun.COM 	}
10009781SMoriah.Waterland@Sun.COM 
10019781SMoriah.Waterland@Sun.COM 	if (askflag && spoolDir) {
10029781SMoriah.Waterland@Sun.COM 		progerr(ERR_PKGASK_AND_SPOOLDIR);
10039781SMoriah.Waterland@Sun.COM 		usage();
10049781SMoriah.Waterland@Sun.COM 		return (1);
10059781SMoriah.Waterland@Sun.COM 	}
10069781SMoriah.Waterland@Sun.COM 
10079781SMoriah.Waterland@Sun.COM 	if (askflag && nointeract) {
10089781SMoriah.Waterland@Sun.COM 		progerr(ERR_PKGASK_AND_NOINTERACT);
10099781SMoriah.Waterland@Sun.COM 		usage();
10109781SMoriah.Waterland@Sun.COM 		return (1);
10119781SMoriah.Waterland@Sun.COM 	}
10129781SMoriah.Waterland@Sun.COM 
10139781SMoriah.Waterland@Sun.COM 	/* cannot use response file and web address together */
10149781SMoriah.Waterland@Sun.COM 
10159781SMoriah.Waterland@Sun.COM 	if (respfile && uri) {
10169781SMoriah.Waterland@Sun.COM 		progerr(ERR_RESPFILE_AND_URI);
10179781SMoriah.Waterland@Sun.COM 		usage();
10189781SMoriah.Waterland@Sun.COM 		return (1);
10199781SMoriah.Waterland@Sun.COM 	}
10209781SMoriah.Waterland@Sun.COM 
10219781SMoriah.Waterland@Sun.COM 	/* cannot use response file/not-interactive and spool-to directory */
10229781SMoriah.Waterland@Sun.COM 
10239781SMoriah.Waterland@Sun.COM 	if (spoolDir && nointeract) {
10249781SMoriah.Waterland@Sun.COM 		progerr(ERR_SPOOLDIR_AND_NOINTERACT);
10259781SMoriah.Waterland@Sun.COM 		usage();
10269781SMoriah.Waterland@Sun.COM 		return (1);
10279781SMoriah.Waterland@Sun.COM 	}
10289781SMoriah.Waterland@Sun.COM 
10299781SMoriah.Waterland@Sun.COM 	if (spoolDir && respfile) {
10309781SMoriah.Waterland@Sun.COM 		progerr(ERR_SPOOLDIR_AND_RESPFILE);
10319781SMoriah.Waterland@Sun.COM 		usage();
10329781SMoriah.Waterland@Sun.COM 		return (1);
10339781SMoriah.Waterland@Sun.COM 	}
10349781SMoriah.Waterland@Sun.COM 
10359781SMoriah.Waterland@Sun.COM 	if (usedZoneList) {
10369781SMoriah.Waterland@Sun.COM 		/* Verify supplied zone list valid for the target */
10379781SMoriah.Waterland@Sun.COM 		if (z_verify_zone_spec() == -1)
10389781SMoriah.Waterland@Sun.COM 			return (1);
10399781SMoriah.Waterland@Sun.COM 
10409781SMoriah.Waterland@Sun.COM 		/* -z zonelist=global is logically the same as -G */
10419781SMoriah.Waterland@Sun.COM 		if (z_global_only() && z_running_in_global_zone())
10429781SMoriah.Waterland@Sun.COM 			globalZoneOnly = B_TRUE;
10439781SMoriah.Waterland@Sun.COM 	}
10449781SMoriah.Waterland@Sun.COM 
10459781SMoriah.Waterland@Sun.COM 	/*
10469781SMoriah.Waterland@Sun.COM 	 * hook SIGINT and SIGHUP interrupts into quit.c's trap handler
10479781SMoriah.Waterland@Sun.COM 	 */
10489781SMoriah.Waterland@Sun.COM 
10499781SMoriah.Waterland@Sun.COM 	/* hold SIGINT/SIGHUP interrupts */
10509781SMoriah.Waterland@Sun.COM 
10519781SMoriah.Waterland@Sun.COM 	(void) sighold(SIGHUP);
10529781SMoriah.Waterland@Sun.COM 	(void) sighold(SIGINT);
10539781SMoriah.Waterland@Sun.COM 
10549781SMoriah.Waterland@Sun.COM 	/* connect quit.c:trap() to SIGINT */
10559781SMoriah.Waterland@Sun.COM 
10569781SMoriah.Waterland@Sun.COM 	nact.sa_handler = quitGetTrapHandler();
10579781SMoriah.Waterland@Sun.COM 	nact.sa_flags = SA_RESTART;
10589781SMoriah.Waterland@Sun.COM 	(void) sigemptyset(&nact.sa_mask);
10599781SMoriah.Waterland@Sun.COM 
10609781SMoriah.Waterland@Sun.COM 	(void) sigaction(SIGINT, &nact, &oact);
10619781SMoriah.Waterland@Sun.COM 
10629781SMoriah.Waterland@Sun.COM 	/* connect quit.c:trap() to SIGHUP */
10639781SMoriah.Waterland@Sun.COM 
10649781SMoriah.Waterland@Sun.COM 	nact.sa_handler = quitGetTrapHandler();
10659781SMoriah.Waterland@Sun.COM 	nact.sa_flags = SA_RESTART;
10669781SMoriah.Waterland@Sun.COM 	(void) sigemptyset(&nact.sa_mask);
10679781SMoriah.Waterland@Sun.COM 
10689781SMoriah.Waterland@Sun.COM 	(void) sigaction(SIGHUP, &nact, &oact);
10699781SMoriah.Waterland@Sun.COM 
10709781SMoriah.Waterland@Sun.COM 	/* release hold on signals */
10719781SMoriah.Waterland@Sun.COM 
10729781SMoriah.Waterland@Sun.COM 	(void) sigrelse(SIGHUP);
10739781SMoriah.Waterland@Sun.COM 	(void) sigrelse(SIGINT);
10749781SMoriah.Waterland@Sun.COM 
10759781SMoriah.Waterland@Sun.COM 	/*
10769781SMoriah.Waterland@Sun.COM 	 * This function is in the libadm library; it sets:
10779781SMoriah.Waterland@Sun.COM 	 * -> get_PKGLOC() = <install_root>/var/sadm/pkg
10789781SMoriah.Waterland@Sun.COM 	 * -> get_PKGOLD() = <install_root>/usr/options
10799781SMoriah.Waterland@Sun.COM 	 * -> get_PKGADM() = <install_root>/var/sadm/install
10809781SMoriah.Waterland@Sun.COM 	 * -> pkgdir = <install_root>/var/sadm/pkg
10819781SMoriah.Waterland@Sun.COM 	 * -> pkg_install_root = <install_root>
10829781SMoriah.Waterland@Sun.COM 	 * This controls operations of libadm functions such as:
10839781SMoriah.Waterland@Sun.COM 	 * -> pkginfofind, pkginfopen, fpkgparam, pkgparam, get_PKGLOC,
10849781SMoriah.Waterland@Sun.COM 	 * -> get_PKGOLD, get_PKGADM, get_install_root
10859781SMoriah.Waterland@Sun.COM 	 */
10869781SMoriah.Waterland@Sun.COM 
10879781SMoriah.Waterland@Sun.COM 	set_PKGpaths(get_inst_root());
10889781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_PKGADD_PKGPATHS,
10899781SMoriah.Waterland@Sun.COM 		get_PKGLOC() ? get_PKGLOC() : "",
10909781SMoriah.Waterland@Sun.COM 		get_PKGADM() ? get_PKGADM() : "");
10919781SMoriah.Waterland@Sun.COM 
10929781SMoriah.Waterland@Sun.COM 	/*
10939781SMoriah.Waterland@Sun.COM 	 * This function is in the libinst library; it reads the specified
10949781SMoriah.Waterland@Sun.COM 	 * admin(4) file and, using fpkgparam(), sets the global "adm" structure
10959781SMoriah.Waterland@Sun.COM 	 * values to match what is in the specified admin file.
10969781SMoriah.Waterland@Sun.COM 	 */
10979781SMoriah.Waterland@Sun.COM 
10989781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_PKGADD_ADMINFILE, admnfile ? admnfile : "");
10999781SMoriah.Waterland@Sun.COM 	setadminFile(admnfile);
11009781SMoriah.Waterland@Sun.COM 
11019781SMoriah.Waterland@Sun.COM 	/*
11029781SMoriah.Waterland@Sun.COM 	 * if running in the global zone, and non-global zones exist, then
11039781SMoriah.Waterland@Sun.COM 	 * enable hollow package support so that any packages that are marked
11049781SMoriah.Waterland@Sun.COM 	 * SUNW_PKG_HOLLOW=true will be correctly installed in non-global zones
11059781SMoriah.Waterland@Sun.COM 	 * when added directly in the global zone by the global zone admin.
11069781SMoriah.Waterland@Sun.COM 	 */
11079781SMoriah.Waterland@Sun.COM 
11089781SMoriah.Waterland@Sun.COM 	if (is_depend_pkginfo_DB()) {
11099781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_PKGADD_HOLLOW_ENABLED);
11109781SMoriah.Waterland@Sun.COM 	} else if ((z_running_in_global_zone() == B_TRUE) &&
11119781SMoriah.Waterland@Sun.COM 		(z_non_global_zones_exist() == B_TRUE)) {
11129781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_PKGADD_ENABLING_HOLLOW);
11139781SMoriah.Waterland@Sun.COM 		set_depend_pkginfo_DB(B_TRUE);
11149781SMoriah.Waterland@Sun.COM 	}
11159781SMoriah.Waterland@Sun.COM 
11169781SMoriah.Waterland@Sun.COM 	/* if no device and no url, get and validate default device */
11179781SMoriah.Waterland@Sun.COM 
11189781SMoriah.Waterland@Sun.COM 	if ((device == NULL) && (uri == NULL)) {
11199781SMoriah.Waterland@Sun.COM 		device = devattr("spool", "pathname");
11209781SMoriah.Waterland@Sun.COM 		if (device == NULL) {
11219781SMoriah.Waterland@Sun.COM 			progerr(ERR_NODEVICE);
11229781SMoriah.Waterland@Sun.COM 			quit(1);
11239781SMoriah.Waterland@Sun.COM 			/* NOTREACHED */
11249781SMoriah.Waterland@Sun.COM 		}
11259781SMoriah.Waterland@Sun.COM 	}
11269781SMoriah.Waterland@Sun.COM 
11279781SMoriah.Waterland@Sun.COM 	/* must be root if not directing results to spool directory */
11289781SMoriah.Waterland@Sun.COM 
11299781SMoriah.Waterland@Sun.COM 	if ((getuid() != 0) && (spoolDir == NULL)) {
11309781SMoriah.Waterland@Sun.COM 		progerr(ERR_NOT_ROOT, prog);
11319781SMoriah.Waterland@Sun.COM 		exit(1);
11329781SMoriah.Waterland@Sun.COM 	}
11339781SMoriah.Waterland@Sun.COM 
11349781SMoriah.Waterland@Sun.COM 	/*
11359781SMoriah.Waterland@Sun.COM 	 * process response file argument
11369781SMoriah.Waterland@Sun.COM 	 */
11379781SMoriah.Waterland@Sun.COM 
11389781SMoriah.Waterland@Sun.COM 	if (respfile) {
11399781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_PKGADD_RESPFILE,
11409781SMoriah.Waterland@Sun.COM 			respfile, respdir ? respdir : "");
11419781SMoriah.Waterland@Sun.COM 
11429781SMoriah.Waterland@Sun.COM 		if (respfile[0] != '/') {
11439781SMoriah.Waterland@Sun.COM 			progerr(ERR_RSP_FILE_NOTFULLPATH, respfile);
11449781SMoriah.Waterland@Sun.COM 			quit(1);
11459781SMoriah.Waterland@Sun.COM 			/* NOTREACHED */
11469781SMoriah.Waterland@Sun.COM 		}
11479781SMoriah.Waterland@Sun.COM 		if (respdir == NULL) {
11489781SMoriah.Waterland@Sun.COM 			if (askflag) {
11499781SMoriah.Waterland@Sun.COM 				if (access(respfile, F_OK) == 0) {
11509781SMoriah.Waterland@Sun.COM 					progerr(ERR_NORESP, respfile);
11519781SMoriah.Waterland@Sun.COM 					quit(1);
11529781SMoriah.Waterland@Sun.COM 					/* NOTREACHED */
11539781SMoriah.Waterland@Sun.COM 				}
11549781SMoriah.Waterland@Sun.COM 			} else if (access(respfile, F_OK) != 0) {
11559781SMoriah.Waterland@Sun.COM 				progerr(ERR_ACCRESP, respfile);
11569781SMoriah.Waterland@Sun.COM 				quit(1);
11579781SMoriah.Waterland@Sun.COM 				/* NOTREACHED */
11589781SMoriah.Waterland@Sun.COM 			}
11599781SMoriah.Waterland@Sun.COM 		}
11609781SMoriah.Waterland@Sun.COM 	} else if (askflag) {
11619781SMoriah.Waterland@Sun.COM 		progerr(ERR_RSP_FILE_NOT_GIVEN);
11629781SMoriah.Waterland@Sun.COM 		usage();
11639781SMoriah.Waterland@Sun.COM 		quit(1);
11649781SMoriah.Waterland@Sun.COM 		/* NOTREACHED */
11659781SMoriah.Waterland@Sun.COM 	}
11669781SMoriah.Waterland@Sun.COM 
11679781SMoriah.Waterland@Sun.COM 	/* establish temporary directory to use */
11689781SMoriah.Waterland@Sun.COM 
11699781SMoriah.Waterland@Sun.COM 	if ((tmpdir = getenv("TMPDIR")) == NULL) {
11709781SMoriah.Waterland@Sun.COM 		/* use default - no override specified */
11719781SMoriah.Waterland@Sun.COM 		tmpdir = P_tmpdir;
11729781SMoriah.Waterland@Sun.COM 	}
11739781SMoriah.Waterland@Sun.COM 
11749781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_PKGADD_TMPDIR, tmpdir);
11759781SMoriah.Waterland@Sun.COM 
11769781SMoriah.Waterland@Sun.COM 	/*
11779781SMoriah.Waterland@Sun.COM 	 * setup and prepare secure package operations
11789781SMoriah.Waterland@Sun.COM 	 */
11799781SMoriah.Waterland@Sun.COM 
11809781SMoriah.Waterland@Sun.COM 	/* initialize error object used by security functions */
11819781SMoriah.Waterland@Sun.COM 
11829781SMoriah.Waterland@Sun.COM 	err = pkgerr_new();
11839781SMoriah.Waterland@Sun.COM 
11849781SMoriah.Waterland@Sun.COM 	/* validate keystore file */
11859781SMoriah.Waterland@Sun.COM 
11869781SMoriah.Waterland@Sun.COM 	if (!check_keystore_admin(&keystore_file)) {
11879781SMoriah.Waterland@Sun.COM 		progerr(ERR_ADM_KEYSTORE);
11889781SMoriah.Waterland@Sun.COM 		quit(1);
11899781SMoriah.Waterland@Sun.COM 		/* NOTREACHED */
11909781SMoriah.Waterland@Sun.COM 	}
11919781SMoriah.Waterland@Sun.COM 
11929781SMoriah.Waterland@Sun.COM 	/* if uri provided, establish session */
11939781SMoriah.Waterland@Sun.COM 
11949781SMoriah.Waterland@Sun.COM 	if (uri != NULL) {
11959781SMoriah.Waterland@Sun.COM 		boolean_t	b;
11969781SMoriah.Waterland@Sun.COM 		int		len;
11979781SMoriah.Waterland@Sun.COM 		char		*bname = (char *)NULL;
11989781SMoriah.Waterland@Sun.COM 
11999781SMoriah.Waterland@Sun.COM 		set_web_install();
12009781SMoriah.Waterland@Sun.COM 
12019781SMoriah.Waterland@Sun.COM 		if (!get_proxy_port(err, &proxy, &proxy_port)) {
12029781SMoriah.Waterland@Sun.COM 			pkgerr(err);
12039781SMoriah.Waterland@Sun.COM 			quit(1);
12049781SMoriah.Waterland@Sun.COM 			/* NOTREACHED */
12059781SMoriah.Waterland@Sun.COM 		}
12069781SMoriah.Waterland@Sun.COM 
12079781SMoriah.Waterland@Sun.COM 		if (proxy == NULL) {
12089781SMoriah.Waterland@Sun.COM 			if (!get_proxy_port_admin(&proxy, &proxy_port)) {
12099781SMoriah.Waterland@Sun.COM 				progerr(ERR_ADM_PROXY);
12109781SMoriah.Waterland@Sun.COM 				quit(1);
12119781SMoriah.Waterland@Sun.COM 				/* NOTREACHED */
12129781SMoriah.Waterland@Sun.COM 			}
12139781SMoriah.Waterland@Sun.COM 		}
12149781SMoriah.Waterland@Sun.COM 
12159781SMoriah.Waterland@Sun.COM 		if ((retries = web_ck_retries()) == 0) {
12169781SMoriah.Waterland@Sun.COM 			pkgerr(err);
12179781SMoriah.Waterland@Sun.COM 			quit(1);
12189781SMoriah.Waterland@Sun.COM 			/* NOTREACHED */
12199781SMoriah.Waterland@Sun.COM 		}
12209781SMoriah.Waterland@Sun.COM 
12219781SMoriah.Waterland@Sun.COM 		if ((timeout = web_ck_timeout()) == 0) {
12229781SMoriah.Waterland@Sun.COM 			pkgerr(err);
12239781SMoriah.Waterland@Sun.COM 			quit(1);
12249781SMoriah.Waterland@Sun.COM 			/* NOTREACHED */
12259781SMoriah.Waterland@Sun.COM 		}
12269781SMoriah.Waterland@Sun.COM 
12279781SMoriah.Waterland@Sun.COM 		/* create temporary directory */
12289781SMoriah.Waterland@Sun.COM 
12299781SMoriah.Waterland@Sun.COM 		b = setup_temporary_directory(&dwnld_dir, tmpdir, "dwnld");
12309781SMoriah.Waterland@Sun.COM 		if (b != B_TRUE) {
12319781SMoriah.Waterland@Sun.COM 			progerr(ERR_DWNLDTEMPDIR, tmpdir, strerror(errno));
12329781SMoriah.Waterland@Sun.COM 			quit(1);
12339781SMoriah.Waterland@Sun.COM 			/* NOTREACHED */
12349781SMoriah.Waterland@Sun.COM 		}
12359781SMoriah.Waterland@Sun.COM 		canonize_slashes(dwnld_dir);
12369781SMoriah.Waterland@Sun.COM 
12379781SMoriah.Waterland@Sun.COM 		/* register with quit() so directory is removed on exit */
12389781SMoriah.Waterland@Sun.COM 
12399781SMoriah.Waterland@Sun.COM 		quitSetDwnldTmpdir(dwnld_dir);	/* DO NOT FREE() */
12409781SMoriah.Waterland@Sun.COM 
12419781SMoriah.Waterland@Sun.COM 		/* open keystore if this is a secure download */
12429781SMoriah.Waterland@Sun.COM 		if (scheme == web_https) {
12439781SMoriah.Waterland@Sun.COM 			if (open_keystore(err, keystore_file,
12449781SMoriah.Waterland@Sun.COM 			    get_prog_name(),  pkg_passphrase_cb,
12459781SMoriah.Waterland@Sun.COM 			    KEYSTORE_DFLT_FLAGS, &keystore) != 0) {
12469781SMoriah.Waterland@Sun.COM 				pkgerr(err);
12479781SMoriah.Waterland@Sun.COM 				web_cleanup();
12489781SMoriah.Waterland@Sun.COM 				quit(1);
12499781SMoriah.Waterland@Sun.COM 				/* NOTREACHED */
12509781SMoriah.Waterland@Sun.COM 			}
12519781SMoriah.Waterland@Sun.COM 		}
12529781SMoriah.Waterland@Sun.COM 
12539781SMoriah.Waterland@Sun.COM 		if (!web_session_control(err, uri, dwnld_dir, keystore, proxy,
12549781SMoriah.Waterland@Sun.COM 			proxy_port, retries, timeout, nointeract, &bname)) {
12559781SMoriah.Waterland@Sun.COM 			pkgerr(err);
12569781SMoriah.Waterland@Sun.COM 			web_cleanup();
12579781SMoriah.Waterland@Sun.COM 			quit(1);
12589781SMoriah.Waterland@Sun.COM 			/* NOTREACHED */
12599781SMoriah.Waterland@Sun.COM 		}
12609781SMoriah.Waterland@Sun.COM 
12619781SMoriah.Waterland@Sun.COM 		/*
12629781SMoriah.Waterland@Sun.COM 		 * reset device to point to newly-downloaded file; note
12639781SMoriah.Waterland@Sun.COM 		 * when (scheme == web_https || scheme == web_http) that
12649781SMoriah.Waterland@Sun.COM 		 * device gets preloaded with a pointer to PATH_MAX bytes
12659781SMoriah.Waterland@Sun.COM 		 * allocated via malloc().
12669781SMoriah.Waterland@Sun.COM 		 */
12679781SMoriah.Waterland@Sun.COM 
12689781SMoriah.Waterland@Sun.COM 		len = snprintf(device, PATH_MAX, "%s/%s", dwnld_dir, bname);
12699781SMoriah.Waterland@Sun.COM 		if ((len < 0) || (len >= PATH_MAX)) {
12709781SMoriah.Waterland@Sun.COM 			progerr(ERR_DIR_CONST, tmpdir);
12719781SMoriah.Waterland@Sun.COM 			quit(1);
12729781SMoriah.Waterland@Sun.COM 			/* NOTREACHED */
12739781SMoriah.Waterland@Sun.COM 		}
12749781SMoriah.Waterland@Sun.COM 	}
12759781SMoriah.Waterland@Sun.COM 
12769781SMoriah.Waterland@Sun.COM 	/*
12779781SMoriah.Waterland@Sun.COM 	 * See if user wants this to be handled as an old style pkg.
12789781SMoriah.Waterland@Sun.COM 	 * NOTE : the ``exception_pkg()'' stuff is to be used only
12799781SMoriah.Waterland@Sun.COM 	 * through on495. This function comes out for on1095. See
12809781SMoriah.Waterland@Sun.COM 	 * PSARC 1993-546. -- JST
12819781SMoriah.Waterland@Sun.COM 	 */
12829781SMoriah.Waterland@Sun.COM 
12839781SMoriah.Waterland@Sun.COM 	if (getenv("NONABI_SCRIPTS") != NULL) {
12849781SMoriah.Waterland@Sun.COM 		old_pkg = 1;
12859781SMoriah.Waterland@Sun.COM 	}
12869781SMoriah.Waterland@Sun.COM 
12879781SMoriah.Waterland@Sun.COM 	/*
12889781SMoriah.Waterland@Sun.COM 	 * See if the user wants to process symlinks consistent with
12899781SMoriah.Waterland@Sun.COM 	 * the old behavior.
12909781SMoriah.Waterland@Sun.COM 	 */
12919781SMoriah.Waterland@Sun.COM 
12929781SMoriah.Waterland@Sun.COM 	if (getenv("PKG_NONABI_SYMLINKS") != NULL) {
12939781SMoriah.Waterland@Sun.COM 		old_symlinks = 1;
12949781SMoriah.Waterland@Sun.COM 	}
12959781SMoriah.Waterland@Sun.COM 
12969781SMoriah.Waterland@Sun.COM 	/*
12979781SMoriah.Waterland@Sun.COM 	 * See if the user wants the package name length restricted.
12989781SMoriah.Waterland@Sun.COM 	 */
12999781SMoriah.Waterland@Sun.COM 
13009781SMoriah.Waterland@Sun.COM 	abiPtr = getenv("PKG_ABI_NAMELENGTH");
13019781SMoriah.Waterland@Sun.COM 	if (abiPtr && strncasecmp(abiPtr, "TRUE", 4) == 0) {
13029781SMoriah.Waterland@Sun.COM 		ABI_namelength = 1;
13039781SMoriah.Waterland@Sun.COM 	}
13049781SMoriah.Waterland@Sun.COM 
13059781SMoriah.Waterland@Sun.COM 	/*
13069781SMoriah.Waterland@Sun.COM 	 * validate the package source device - return pkgdev info that
13079781SMoriah.Waterland@Sun.COM 	 * describes the package source device.
13089781SMoriah.Waterland@Sun.COM 	 */
13099781SMoriah.Waterland@Sun.COM 
13109781SMoriah.Waterland@Sun.COM 	if (devtype(device, &pkgdev)) {
13119781SMoriah.Waterland@Sun.COM 		progerr(ERR_BAD_DEVICE, device);
13129781SMoriah.Waterland@Sun.COM 		quit(1);
13139781SMoriah.Waterland@Sun.COM 		/* NOTREACHED */
13149781SMoriah.Waterland@Sun.COM 	}
13159781SMoriah.Waterland@Sun.COM 
13169781SMoriah.Waterland@Sun.COM 	/*
13179781SMoriah.Waterland@Sun.COM 	 * If writing the packages into a spool directory instead of
13189781SMoriah.Waterland@Sun.COM 	 * installing the packages, open the package datastream and
13199781SMoriah.Waterland@Sun.COM 	 * invoke pkgtrans to perform the conversion and exit.
13209781SMoriah.Waterland@Sun.COM 	 */
13219781SMoriah.Waterland@Sun.COM 
13229781SMoriah.Waterland@Sun.COM 	if (spoolDir != (char *)NULL) {
13239781SMoriah.Waterland@Sun.COM 		boolean_t	b;
13249781SMoriah.Waterland@Sun.COM 		int		n;
13259781SMoriah.Waterland@Sun.COM 
13269781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_INSTALLING_TO_SPOOL, spoolDir);
13279781SMoriah.Waterland@Sun.COM 
13289781SMoriah.Waterland@Sun.COM 		b = open_package_datastream(argc, argv, spoolDir, device,
13299781SMoriah.Waterland@Sun.COM 						&repeat, &ids_name, tmpdir,
13309781SMoriah.Waterland@Sun.COM 						&pkgdev, optind);
13319781SMoriah.Waterland@Sun.COM 
13329781SMoriah.Waterland@Sun.COM 		quitSetIdsName(ids_name);
13339781SMoriah.Waterland@Sun.COM 
13349781SMoriah.Waterland@Sun.COM 		if (b != B_TRUE) {
13359781SMoriah.Waterland@Sun.COM 			progerr(ERR_CANNOT_OPEN_PKG_STREAM, PSTR(device));
13369781SMoriah.Waterland@Sun.COM 			quit(1);
13379781SMoriah.Waterland@Sun.COM 		}
13389781SMoriah.Waterland@Sun.COM 
13399781SMoriah.Waterland@Sun.COM 		n = pkgtrans(device, spoolDir, &argv[optind],
13409781SMoriah.Waterland@Sun.COM 				0, NULL, NULL);
13419781SMoriah.Waterland@Sun.COM 		quit(n);
13429781SMoriah.Waterland@Sun.COM 		/* NOTREACHED */
13439781SMoriah.Waterland@Sun.COM 	}
13449781SMoriah.Waterland@Sun.COM 
13459781SMoriah.Waterland@Sun.COM 	/*
13469781SMoriah.Waterland@Sun.COM 	 * error if there are packages on the command line and a category
13479781SMoriah.Waterland@Sun.COM 	 * was specified
13489781SMoriah.Waterland@Sun.COM 	 */
13499781SMoriah.Waterland@Sun.COM 
13509781SMoriah.Waterland@Sun.COM 	if ((optind < argc) && (catg_arg != NULL)) {
13519781SMoriah.Waterland@Sun.COM 		progerr(ERR_PKGS_AND_CAT_PKGADD);
13529781SMoriah.Waterland@Sun.COM 		usage();
13539781SMoriah.Waterland@Sun.COM 		quit(1);
13549781SMoriah.Waterland@Sun.COM 		/* NOTREACHED */
13559781SMoriah.Waterland@Sun.COM 	}
13569781SMoriah.Waterland@Sun.COM 
13579781SMoriah.Waterland@Sun.COM 	/*
13589781SMoriah.Waterland@Sun.COM 	 * ********************************************************************
13599781SMoriah.Waterland@Sun.COM 	 * main package processing "loop"
13609781SMoriah.Waterland@Sun.COM 	 * ********************************************************************
13619781SMoriah.Waterland@Sun.COM 	 */
13629781SMoriah.Waterland@Sun.COM 
13639781SMoriah.Waterland@Sun.COM 	ids_name = NULL;
13649781SMoriah.Waterland@Sun.COM 	quitSetIdsName(ids_name);
13659781SMoriah.Waterland@Sun.COM 
13669781SMoriah.Waterland@Sun.COM 	for (;;) {
13679781SMoriah.Waterland@Sun.COM 		boolean_t	b;
13689781SMoriah.Waterland@Sun.COM 		char		**pkglist;	/* points to array of pkgs */
13699781SMoriah.Waterland@Sun.COM 
13709781SMoriah.Waterland@Sun.COM 		/*
13719781SMoriah.Waterland@Sun.COM 		 * open next package data stream
13729781SMoriah.Waterland@Sun.COM 		 */
13739781SMoriah.Waterland@Sun.COM 
13749781SMoriah.Waterland@Sun.COM 		b = open_package_datastream(argc, argv, spoolDir, device,
13759781SMoriah.Waterland@Sun.COM 						&repeat, &ids_name, tmpdir,
13769781SMoriah.Waterland@Sun.COM 						&pkgdev, optind);
13779781SMoriah.Waterland@Sun.COM 
13789781SMoriah.Waterland@Sun.COM 		quitSetIdsName(ids_name);
13799781SMoriah.Waterland@Sun.COM 
13809781SMoriah.Waterland@Sun.COM 		if (b == B_FALSE) {
13819781SMoriah.Waterland@Sun.COM 			echoDebug(ERR_CANNOT_OPEN_PKG_STREAM, PSTR(device));
13829781SMoriah.Waterland@Sun.COM 			continue;
13839781SMoriah.Waterland@Sun.COM 		}
13849781SMoriah.Waterland@Sun.COM 
13859781SMoriah.Waterland@Sun.COM 		/*
13869781SMoriah.Waterland@Sun.COM 		 * package source data stream open - get the package list
13879781SMoriah.Waterland@Sun.COM 		 */
13889781SMoriah.Waterland@Sun.COM 
13899781SMoriah.Waterland@Sun.COM 		b = get_package_list(&pkglist, argv, catg_arg, category,
13909781SMoriah.Waterland@Sun.COM 			ignore_sig, err, proxy_port, proxy, keystore,
13919781SMoriah.Waterland@Sun.COM 			keystore_file, ids_name, &repeat);
13929781SMoriah.Waterland@Sun.COM 
13939781SMoriah.Waterland@Sun.COM 		if (b == B_FALSE) {
13949781SMoriah.Waterland@Sun.COM 			char	path[PATH_MAX];
13959781SMoriah.Waterland@Sun.COM 
13969781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_CANNOT_GET_PKGLIST);
13979781SMoriah.Waterland@Sun.COM 
13989781SMoriah.Waterland@Sun.COM 			/* check for existence of pre-SVR4 package */
13999781SMoriah.Waterland@Sun.COM 			(void) snprintf(path, sizeof (path),
14009781SMoriah.Waterland@Sun.COM 				"%s/install/INSTALL", pkgdev.dirname);
14019781SMoriah.Waterland@Sun.COM 			if (access(path, F_OK) == 0) {
14029781SMoriah.Waterland@Sun.COM 				pkginst = ((optind < argc) ?
14039781SMoriah.Waterland@Sun.COM 					argv[optind++] : NULL);
14049781SMoriah.Waterland@Sun.COM 				ckreturn(presvr4(&pkginst, nointeract));
14059781SMoriah.Waterland@Sun.COM 				if (repeat || (optind < argc)) {
14069781SMoriah.Waterland@Sun.COM 					continue;
14079781SMoriah.Waterland@Sun.COM 				}
14089781SMoriah.Waterland@Sun.COM 				quit(0);
14099781SMoriah.Waterland@Sun.COM 			}
14109781SMoriah.Waterland@Sun.COM 			progerr(ERR_NOPKGS, pkgdev.dirname);
14119781SMoriah.Waterland@Sun.COM 			quit(1);
14129781SMoriah.Waterland@Sun.COM 			/* NOTREACHED */
14139781SMoriah.Waterland@Sun.COM 		}
14149781SMoriah.Waterland@Sun.COM 
14159781SMoriah.Waterland@Sun.COM 		/*
14169781SMoriah.Waterland@Sun.COM 		 * count the number of packages to install
14179781SMoriah.Waterland@Sun.COM 		 * NOTE: npkgs is a global variable that is referenced by quit.c
14189781SMoriah.Waterland@Sun.COM 		 * when error messages are generated - it is referenced directly
14199781SMoriah.Waterland@Sun.COM 		 * by the other functions called below...
14209781SMoriah.Waterland@Sun.COM 		 */
14219781SMoriah.Waterland@Sun.COM 
14229781SMoriah.Waterland@Sun.COM 		for (npkgs = 0; pkglist[npkgs] != (char *)NULL; /* void */) {
14239781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_PKG_SELECTED, npkgs, pkglist[npkgs]);
14249781SMoriah.Waterland@Sun.COM 			npkgs++;
14259781SMoriah.Waterland@Sun.COM 		}
14269781SMoriah.Waterland@Sun.COM 
14279781SMoriah.Waterland@Sun.COM 		/* output number of packages to be added */
14289781SMoriah.Waterland@Sun.COM 
14299781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_NUM_PKGS_TO_ADD, npkgs);
14309781SMoriah.Waterland@Sun.COM 
14319781SMoriah.Waterland@Sun.COM 		/*
14329781SMoriah.Waterland@Sun.COM 		 * if pkgask and response container is a file (not a directory),
14339781SMoriah.Waterland@Sun.COM 		 * and there is more than one package to install, then it is an
14349781SMoriah.Waterland@Sun.COM 		 * error - too many packages to install when response container
14359781SMoriah.Waterland@Sun.COM 		 * is a file.
14369781SMoriah.Waterland@Sun.COM 		 */
14379781SMoriah.Waterland@Sun.COM 
14389781SMoriah.Waterland@Sun.COM 		if ((askflag != 0) && (respdir == (char *)NULL) &&
14399781SMoriah.Waterland@Sun.COM 			(npkgs > 1)) {
14409781SMoriah.Waterland@Sun.COM 			progerr(ERR_TOO_MANY_PKGS);
14419781SMoriah.Waterland@Sun.COM 			quit(1);
14429781SMoriah.Waterland@Sun.COM 			/* NOTREACHED */
14439781SMoriah.Waterland@Sun.COM 		}
14449781SMoriah.Waterland@Sun.COM 
14459781SMoriah.Waterland@Sun.COM 		/*
14469781SMoriah.Waterland@Sun.COM 		 * package list generated - add packages
14479781SMoriah.Waterland@Sun.COM 		 */
14489781SMoriah.Waterland@Sun.COM 
14499781SMoriah.Waterland@Sun.COM 		b = add_packages(pkglist, uri, ids_name, repeat,
14509781SMoriah.Waterland@Sun.COM 					altBinDir, device, noZones);
14519781SMoriah.Waterland@Sun.COM 
14529781SMoriah.Waterland@Sun.COM 		/*
14539781SMoriah.Waterland@Sun.COM 		 * close open input data stream (source package) if left open.
14549781SMoriah.Waterland@Sun.COM 		 */
14559781SMoriah.Waterland@Sun.COM 
14569781SMoriah.Waterland@Sun.COM 		if (ids_name) {
14579781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_CLOSING_STREAM, ids_name,
14589781SMoriah.Waterland@Sun.COM 					PSTR(pkgdev.dirname));
14599781SMoriah.Waterland@Sun.COM 			(void) ds_close(1);
14609781SMoriah.Waterland@Sun.COM 			rrmdir(pkgdev.dirname);
14619781SMoriah.Waterland@Sun.COM 			ids_name = NULL;
14629781SMoriah.Waterland@Sun.COM 			quitSetIdsName(ids_name);
14639781SMoriah.Waterland@Sun.COM 		}
14649781SMoriah.Waterland@Sun.COM 
14659781SMoriah.Waterland@Sun.COM 		/*
14669781SMoriah.Waterland@Sun.COM 		 * continue with next sequence of packages if continue set
14679781SMoriah.Waterland@Sun.COM 		 */
14689781SMoriah.Waterland@Sun.COM 
14699781SMoriah.Waterland@Sun.COM 		if (b == B_TRUE) {
14709781SMoriah.Waterland@Sun.COM 			continue;
14719781SMoriah.Waterland@Sun.COM 		}
14729781SMoriah.Waterland@Sun.COM 
14739781SMoriah.Waterland@Sun.COM 		/*
14749781SMoriah.Waterland@Sun.COM 		 * not continuing - quit with 0 exit code
14759781SMoriah.Waterland@Sun.COM 		 */
14769781SMoriah.Waterland@Sun.COM 
14779781SMoriah.Waterland@Sun.COM 		quit(0);
14789781SMoriah.Waterland@Sun.COM 		/* NOTREACHED */
14799781SMoriah.Waterland@Sun.COM 	}
14809781SMoriah.Waterland@Sun.COM 
14819781SMoriah.Waterland@Sun.COM 	/* NOTREACHED */
14829781SMoriah.Waterland@Sun.COM }
14839781SMoriah.Waterland@Sun.COM 
14849781SMoriah.Waterland@Sun.COM /*
14859781SMoriah.Waterland@Sun.COM  * *****************************************************************************
14869781SMoriah.Waterland@Sun.COM  * static internal (private) functions
14879781SMoriah.Waterland@Sun.COM  * *****************************************************************************
14889781SMoriah.Waterland@Sun.COM  */
14899781SMoriah.Waterland@Sun.COM 
14909781SMoriah.Waterland@Sun.COM /*
14919781SMoriah.Waterland@Sun.COM  * Name:	pkgZoneCheckInstall
14929781SMoriah.Waterland@Sun.COM  * Description:	Invoke pkginstall in a specified zone to perform a preinstall
14939781SMoriah.Waterland@Sun.COM  *		check of the a single package in the specified zone
14949781SMoriah.Waterland@Sun.COM  * Arguments:	a_zoneName - pointer to string representing the name of the
14959781SMoriah.Waterland@Sun.COM  *			zone to check install the package in.
14969781SMoriah.Waterland@Sun.COM  *		a_inheritedPkgDirs - pointer to array of strings, each one
14979781SMoriah.Waterland@Sun.COM  *			representing the non-global zones full path of a
14989781SMoriah.Waterland@Sun.COM  *			directory that is inherited from the global zone.
14999781SMoriah.Waterland@Sun.COM  *		a_zoneState - current state of the zone; must be mounted or
15009781SMoriah.Waterland@Sun.COM  *			running.
15019781SMoriah.Waterland@Sun.COM  *		a_idsName - pointer to string representing the data stream
15029781SMoriah.Waterland@Sun.COM  *			device (input data stream) containing the package to
15039781SMoriah.Waterland@Sun.COM  *			be check installed.
15049781SMoriah.Waterland@Sun.COM  *		a_altBinDir - pointer to string representing an alternative
15059781SMoriah.Waterland@Sun.COM  *			binary location directory to pass to pkginstall.
15069781SMoriah.Waterland@Sun.COM  *			If this is == NULL no alternative binary location is
15079781SMoriah.Waterland@Sun.COM  *			passed to pkginstall.
15089781SMoriah.Waterland@Sun.COM  *		a_adminFile - pointer to string representing the admin
15099781SMoriah.Waterland@Sun.COM  *			file to pass to pkginstall when installing the package.
15109781SMoriah.Waterland@Sun.COM  *			If this is == NULL no admin file is given to pkginstall.
15119781SMoriah.Waterland@Sun.COM  *		a_stdoutPath - pointer to string representing the local path
15129781SMoriah.Waterland@Sun.COM  *			into which all output written by pkginstall to stdout
15139781SMoriah.Waterland@Sun.COM  *			is stored.
15149781SMoriah.Waterland@Sun.COM  *			If this is == NULL stdout is redirected to /dev/null
1515*9869SCasper.Dik@Sun.COM  *		a_tmpzn - B_TRUE when this zone is booted by the package
1516*9869SCasper.Dik@Sun.COM  *			command or B_FALSE if it was running before.
15179781SMoriah.Waterland@Sun.COM  * Returns:	int	(see ckreturn() function for details)
15189781SMoriah.Waterland@Sun.COM  *		0 - success
15199781SMoriah.Waterland@Sun.COM  *		1 - package operation failed (fatal error)
15209781SMoriah.Waterland@Sun.COM  *		2 - non-fatal error (warning)
15219781SMoriah.Waterland@Sun.COM  *		3 - user selected quit (operation interrupted)
15229781SMoriah.Waterland@Sun.COM  *		4 - admin settings prevented operation
15239781SMoriah.Waterland@Sun.COM  *		5 - interaction required and -n (non-interactive) specified
15249781SMoriah.Waterland@Sun.COM  *		"10" will be added to indicate "immediate reboot required"
15259781SMoriah.Waterland@Sun.COM  *		"20" will be added to indicate "reboot after install required"
15269781SMoriah.Waterland@Sun.COM  */
15279781SMoriah.Waterland@Sun.COM 
15289781SMoriah.Waterland@Sun.COM static int
15299781SMoriah.Waterland@Sun.COM pkgZoneCheckInstall(char *a_zoneName, char **a_inheritedPkgDirs,
15309781SMoriah.Waterland@Sun.COM 	zone_state_t a_zoneState, char *a_idsName, char *a_altBinDir,
1531*9869SCasper.Dik@Sun.COM 	char *a_adminFile, char *a_stdoutPath, boolean_t a_tmpzn)
15329781SMoriah.Waterland@Sun.COM {
15339781SMoriah.Waterland@Sun.COM 	char	*arg[MAXARGS];
15349781SMoriah.Waterland@Sun.COM 	char	*p;
15359781SMoriah.Waterland@Sun.COM 	char	adminfd_path[PATH_MAX];
15369781SMoriah.Waterland@Sun.COM 	char	path[PATH_MAX];
15379781SMoriah.Waterland@Sun.COM 	char	pkgstreamfd_path[PATH_MAX];
15389781SMoriah.Waterland@Sun.COM 	int	fds[MAX_FDS];
15399781SMoriah.Waterland@Sun.COM 	int	maxfds;
15409781SMoriah.Waterland@Sun.COM 	int	n;
15419781SMoriah.Waterland@Sun.COM 	int	nargs;
15429781SMoriah.Waterland@Sun.COM 
15439781SMoriah.Waterland@Sun.COM 	/* entry assertions */
15449781SMoriah.Waterland@Sun.COM 
15459781SMoriah.Waterland@Sun.COM 	assert(a_zoneName != (char *)NULL);
15469781SMoriah.Waterland@Sun.COM 	assert(*a_zoneName != '\0');
15479781SMoriah.Waterland@Sun.COM 
15489781SMoriah.Waterland@Sun.COM 	/* entry debugging info */
15499781SMoriah.Waterland@Sun.COM 
15509781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_PKGZONECHECKINSTALL_ENTRY);
15519781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_PKGZONECHECKINSTALL_ARGS, a_zoneName, PSTR(pkginst),
15529781SMoriah.Waterland@Sun.COM 		PSTR(pkgdev.dirname), PSTR(pkgdev.mount), PSTR(pkgdev.bdevice),
15539781SMoriah.Waterland@Sun.COM 		a_zoneState == ZONE_STATE_MOUNTED ? "/a" : "/",
15549781SMoriah.Waterland@Sun.COM 		PSTR(a_idsName), PSTR(a_adminFile), PSTR(a_stdoutPath));
15559781SMoriah.Waterland@Sun.COM 
15569781SMoriah.Waterland@Sun.COM 	/* generate full path to 'phatinstall' to run in zone */
15579781SMoriah.Waterland@Sun.COM 
15589781SMoriah.Waterland@Sun.COM 	(void) snprintf(path, sizeof (path), "%s/pkginstall",
15599781SMoriah.Waterland@Sun.COM 			"/usr/sadm/install/bin");
15609781SMoriah.Waterland@Sun.COM 
15619781SMoriah.Waterland@Sun.COM 	/* start at first file descriptor */
15629781SMoriah.Waterland@Sun.COM 
15639781SMoriah.Waterland@Sun.COM 	maxfds = 0;
15649781SMoriah.Waterland@Sun.COM 
15659781SMoriah.Waterland@Sun.COM 	/*
15669781SMoriah.Waterland@Sun.COM 	 * generate argument list for call to pkginstall
15679781SMoriah.Waterland@Sun.COM 	 */
15689781SMoriah.Waterland@Sun.COM 
15699781SMoriah.Waterland@Sun.COM 	/* start at argument 0 */
15709781SMoriah.Waterland@Sun.COM 
15719781SMoriah.Waterland@Sun.COM 	nargs = 0;
15729781SMoriah.Waterland@Sun.COM 
15739781SMoriah.Waterland@Sun.COM 	/* first argument is always: full path to executable */
15749781SMoriah.Waterland@Sun.COM 
15759781SMoriah.Waterland@Sun.COM 	arg[nargs++] = path;
15769781SMoriah.Waterland@Sun.COM 
15779781SMoriah.Waterland@Sun.COM 	/*
15789781SMoriah.Waterland@Sun.COM 	 * second argument is always: pass -O debug to pkginstall: debug mode
15799781SMoriah.Waterland@Sun.COM 	 */
15809781SMoriah.Waterland@Sun.COM 	if (debugFlag == B_TRUE) {
15819781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-O";
15829781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "debug";
15839781SMoriah.Waterland@Sun.COM 	}
15849781SMoriah.Waterland@Sun.COM 
15859781SMoriah.Waterland@Sun.COM 	/* pkgadd -G: pass -G to pkginstall */
15869781SMoriah.Waterland@Sun.COM 
15879781SMoriah.Waterland@Sun.COM 	if (globalZoneOnly == B_TRUE) {
15889781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-G";
15899781SMoriah.Waterland@Sun.COM 	}
15909781SMoriah.Waterland@Sun.COM 
15919781SMoriah.Waterland@Sun.COM 	/* pkgadd -b dir: pass -b to pkginstall */
15929781SMoriah.Waterland@Sun.COM 
15939781SMoriah.Waterland@Sun.COM 	if (a_altBinDir != (char *)NULL) {
15949781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-b";
15959781SMoriah.Waterland@Sun.COM 		arg[nargs++] = a_altBinDir;
15969781SMoriah.Waterland@Sun.COM 	}
15979781SMoriah.Waterland@Sun.COM 
15989781SMoriah.Waterland@Sun.COM 	/* pkgadd -C: pass -C to pkginstall: disable checksum */
15999781SMoriah.Waterland@Sun.COM 
16009781SMoriah.Waterland@Sun.COM 	if (disableChecksum) {
16019781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-C";
16029781SMoriah.Waterland@Sun.COM 	}
16039781SMoriah.Waterland@Sun.COM 
16049781SMoriah.Waterland@Sun.COM 	/* pkgadd -A: pass -A to pkginstall: disable attribute checking */
16059781SMoriah.Waterland@Sun.COM 
16069781SMoriah.Waterland@Sun.COM 	if (disableAttributes) {
16079781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-A";
16089781SMoriah.Waterland@Sun.COM 	}
16099781SMoriah.Waterland@Sun.COM 
16109781SMoriah.Waterland@Sun.COM 	/*
16119781SMoriah.Waterland@Sun.COM 	 * NONABI_SCRIPTS defined: pass -o to pkginstall; refers to a
16129781SMoriah.Waterland@Sun.COM 	 * pkg requiring operator interaction during a procedure script
16139781SMoriah.Waterland@Sun.COM 	 * (common before on1093)
16149781SMoriah.Waterland@Sun.COM 	 */
16159781SMoriah.Waterland@Sun.COM 
16169781SMoriah.Waterland@Sun.COM 	if (old_pkg) {
16179781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-o";
16189781SMoriah.Waterland@Sun.COM 	}
16199781SMoriah.Waterland@Sun.COM 
16209781SMoriah.Waterland@Sun.COM 	/*
16219781SMoriah.Waterland@Sun.COM 	 * PKG_NONABI_SYMLINKS defined: pass -y to pkginstall; process
16229781SMoriah.Waterland@Sun.COM 	 * symlinks consistent with old behavior
16239781SMoriah.Waterland@Sun.COM 	 */
16249781SMoriah.Waterland@Sun.COM 
16259781SMoriah.Waterland@Sun.COM 	if (old_symlinks) {
16269781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-y";
16279781SMoriah.Waterland@Sun.COM 	}
16289781SMoriah.Waterland@Sun.COM 
16299781SMoriah.Waterland@Sun.COM 	/*
16309781SMoriah.Waterland@Sun.COM 	 * PKG_ABI_NAMELENGTH defined: pass -e to pkginstall; causes
16319781SMoriah.Waterland@Sun.COM 	 * package name length to be restricted
16329781SMoriah.Waterland@Sun.COM 	 */
16339781SMoriah.Waterland@Sun.COM 
16349781SMoriah.Waterland@Sun.COM 	if (ABI_namelength) {
16359781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-e";
16369781SMoriah.Waterland@Sun.COM 	}
16379781SMoriah.Waterland@Sun.COM 
16389781SMoriah.Waterland@Sun.COM 	/* pkgadd -S: pass -S to pkginstall: suppress copyright notices */
16399781SMoriah.Waterland@Sun.COM 
16409781SMoriah.Waterland@Sun.COM 	arg[nargs++] = "-S";
16419781SMoriah.Waterland@Sun.COM 
16429781SMoriah.Waterland@Sun.COM 	/* pkgadd -M: pass -M to pkginstall: dont mount client file systems */
16439781SMoriah.Waterland@Sun.COM 
16449781SMoriah.Waterland@Sun.COM 	arg[nargs++] = "-M";
16459781SMoriah.Waterland@Sun.COM 
16469781SMoriah.Waterland@Sun.COM 	/* pkgadd -v: pass -v to pkginstall: never trace scripts */
16479781SMoriah.Waterland@Sun.COM 
16489781SMoriah.Waterland@Sun.COM 	/* if running pkgask, pass -i to pkginstall: running pkgask */
16499781SMoriah.Waterland@Sun.COM 
16509781SMoriah.Waterland@Sun.COM 	if (askflag) {
16519781SMoriah.Waterland@Sun.COM 		return (0);
16529781SMoriah.Waterland@Sun.COM 	}
16539781SMoriah.Waterland@Sun.COM 
16549781SMoriah.Waterland@Sun.COM 	/* pass "-O enable-hollow-package-support" */
16559781SMoriah.Waterland@Sun.COM 
16569781SMoriah.Waterland@Sun.COM 	if (is_depend_pkginfo_DB()) {
16579781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-O";
16589781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "enable-hollow-package-support";
16599781SMoriah.Waterland@Sun.COM 	}
16609781SMoriah.Waterland@Sun.COM 
16619781SMoriah.Waterland@Sun.COM 	/* check is always in non-interactive mode */
16629781SMoriah.Waterland@Sun.COM 
16639781SMoriah.Waterland@Sun.COM 	arg[nargs++] = "-n";
16649781SMoriah.Waterland@Sun.COM 
16659781SMoriah.Waterland@Sun.COM 	/* pkgadd -a admin: pass -a admin to pkginstall in zone: admin file */
16669781SMoriah.Waterland@Sun.COM 
16679781SMoriah.Waterland@Sun.COM 	if (a_adminFile) {
16689781SMoriah.Waterland@Sun.COM 		int fd;
16699781SMoriah.Waterland@Sun.COM 		fd = openLocal(a_adminFile, O_RDONLY, tmpdir);
16709781SMoriah.Waterland@Sun.COM 		if (fd < 0) {
16719781SMoriah.Waterland@Sun.COM 			progerr(ERR_CANNOT_COPY_LOCAL, a_adminFile,
16729781SMoriah.Waterland@Sun.COM 				errno, strerror(errno));
16739781SMoriah.Waterland@Sun.COM 			return (1);
16749781SMoriah.Waterland@Sun.COM 		}
16759781SMoriah.Waterland@Sun.COM 		(void) snprintf(adminfd_path, sizeof (adminfd_path),
16769781SMoriah.Waterland@Sun.COM 			"/proc/self/fd/%d", fd);
16779781SMoriah.Waterland@Sun.COM 		fds[maxfds++] = fd;
16789781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-a";
16799781SMoriah.Waterland@Sun.COM 		arg[nargs++] = adminfd_path;
16809781SMoriah.Waterland@Sun.COM 	}
16819781SMoriah.Waterland@Sun.COM 
16829781SMoriah.Waterland@Sun.COM 	/* pkgadd -R root: pass -R /a to pkginstall when zone is mounted */
16839781SMoriah.Waterland@Sun.COM 
16849781SMoriah.Waterland@Sun.COM 	if (a_zoneState == ZONE_STATE_MOUNTED) {
16859781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-R";
16869781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "/a";
16879781SMoriah.Waterland@Sun.COM 	}
16889781SMoriah.Waterland@Sun.COM 
16899781SMoriah.Waterland@Sun.COM 	/* pass -N to pkginstall: program name to report */
16909781SMoriah.Waterland@Sun.COM 
16919781SMoriah.Waterland@Sun.COM 	arg[nargs++] = "-N";
16929781SMoriah.Waterland@Sun.COM 	arg[nargs++] = get_prog_name();
16939781SMoriah.Waterland@Sun.COM 
16949781SMoriah.Waterland@Sun.COM 	/* pass "-O preinstallcheck" */
16959781SMoriah.Waterland@Sun.COM 
16969781SMoriah.Waterland@Sun.COM 	arg[nargs++] = "-O";
16979781SMoriah.Waterland@Sun.COM 	arg[nargs++] = "preinstallcheck";
16989781SMoriah.Waterland@Sun.COM 
16999781SMoriah.Waterland@Sun.COM 	/* add "-O addzonename" */
17009781SMoriah.Waterland@Sun.COM 
17019781SMoriah.Waterland@Sun.COM 	arg[nargs++] = "-O";
17029781SMoriah.Waterland@Sun.COM 	arg[nargs++] = "addzonename";
17039781SMoriah.Waterland@Sun.COM 
17049781SMoriah.Waterland@Sun.COM 	if (isPatchUpdate()) {
17059781SMoriah.Waterland@Sun.COM 		if (patchPkgRemoval == B_TRUE) {
17069781SMoriah.Waterland@Sun.COM 			arg[nargs++] = "-O";
17079781SMoriah.Waterland@Sun.COM 			arg[nargs++] = "patchPkgRemoval";
17089781SMoriah.Waterland@Sun.COM 		} else {
17099781SMoriah.Waterland@Sun.COM 			arg[nargs++] = "-O";
17109781SMoriah.Waterland@Sun.COM 			arg[nargs++] = "patchPkgInstall";
17119781SMoriah.Waterland@Sun.COM 		}
17129781SMoriah.Waterland@Sun.COM 	}
17139781SMoriah.Waterland@Sun.COM 
17149781SMoriah.Waterland@Sun.COM 	/* add all inherited file systems */
17159781SMoriah.Waterland@Sun.COM 
17169781SMoriah.Waterland@Sun.COM 	if (a_inheritedPkgDirs != (char **)NULL) {
17179781SMoriah.Waterland@Sun.COM 		for (n = 0; a_inheritedPkgDirs[n] != (char *)NULL; n++) {
17189781SMoriah.Waterland@Sun.COM 			char	ifs[MAXPATHLEN+22];
17199781SMoriah.Waterland@Sun.COM 			(void) snprintf(ifs, sizeof (ifs),
17209781SMoriah.Waterland@Sun.COM 				"inherited-filesystem=%s",
17219781SMoriah.Waterland@Sun.COM 				a_inheritedPkgDirs[n]);
17229781SMoriah.Waterland@Sun.COM 			arg[nargs++] = "-O";
17239781SMoriah.Waterland@Sun.COM 			arg[nargs++] = strdup(ifs);
17249781SMoriah.Waterland@Sun.COM 		}
17259781SMoriah.Waterland@Sun.COM 	}
17269781SMoriah.Waterland@Sun.COM 
17279781SMoriah.Waterland@Sun.COM 	/*
17289781SMoriah.Waterland@Sun.COM 	 * add parent zone info/type
17299781SMoriah.Waterland@Sun.COM 	 */
17309781SMoriah.Waterland@Sun.COM 
17319781SMoriah.Waterland@Sun.COM 	p = z_get_zonename();
17329781SMoriah.Waterland@Sun.COM 	if ((p != NULL) && (*p != '\0')) {
17339781SMoriah.Waterland@Sun.COM 			char	zn[MAXPATHLEN];
17349781SMoriah.Waterland@Sun.COM 			(void) snprintf(zn, sizeof (zn),
17359781SMoriah.Waterland@Sun.COM 				"parent-zone-name=%s", p);
17369781SMoriah.Waterland@Sun.COM 			arg[nargs++] = "-O";
17379781SMoriah.Waterland@Sun.COM 			arg[nargs++] = strdup(zn);
17389781SMoriah.Waterland@Sun.COM 	}
17399781SMoriah.Waterland@Sun.COM 
17409781SMoriah.Waterland@Sun.COM 	/* current zone type */
17419781SMoriah.Waterland@Sun.COM 
17429781SMoriah.Waterland@Sun.COM 	arg[nargs++] = "-O";
17439781SMoriah.Waterland@Sun.COM 	if (z_running_in_global_zone() == B_TRUE) {
17449781SMoriah.Waterland@Sun.COM 			char	zn[MAXPATHLEN];
17459781SMoriah.Waterland@Sun.COM 			(void) snprintf(zn, sizeof (zn),
17469781SMoriah.Waterland@Sun.COM 				"parent-zone-type=%s",
17479781SMoriah.Waterland@Sun.COM 				TAG_VALUE_GLOBAL_ZONE);
17489781SMoriah.Waterland@Sun.COM 			arg[nargs++] = strdup(zn);
17499781SMoriah.Waterland@Sun.COM 	} else {
17509781SMoriah.Waterland@Sun.COM 			char	zn[MAXPATHLEN];
17519781SMoriah.Waterland@Sun.COM 			(void) snprintf(zn, sizeof (zn),
17529781SMoriah.Waterland@Sun.COM 				"parent-zone-type=%s",
17539781SMoriah.Waterland@Sun.COM 				TAG_VALUE_NONGLOBAL_ZONE);
17549781SMoriah.Waterland@Sun.COM 			arg[nargs++] = strdup(zn);
17559781SMoriah.Waterland@Sun.COM 	}
17569781SMoriah.Waterland@Sun.COM 
1757*9869SCasper.Dik@Sun.COM 	/* Add the pkgserv options */
1758*9869SCasper.Dik@Sun.COM 	arg[nargs++] = "-O";
1759*9869SCasper.Dik@Sun.COM 	arg[nargs++] = pkgmodeargument(a_tmpzn ? RUN_ONCE : pkgservergetmode());
1760*9869SCasper.Dik@Sun.COM 
17619781SMoriah.Waterland@Sun.COM 	/* add in the package stream file */
17629781SMoriah.Waterland@Sun.COM 
17639781SMoriah.Waterland@Sun.COM 	if (a_idsName != NULL) {
17649781SMoriah.Waterland@Sun.COM 		int fd;
17659781SMoriah.Waterland@Sun.COM 		fd = openLocal(a_idsName, O_RDONLY, tmpdir);
17669781SMoriah.Waterland@Sun.COM 		if (fd < 0) {
17679781SMoriah.Waterland@Sun.COM 			progerr(ERR_STREAM_UNAVAILABLE, a_idsName,
17689781SMoriah.Waterland@Sun.COM 				pkginst, strerror(errno));
17699781SMoriah.Waterland@Sun.COM 			quit(1);
17709781SMoriah.Waterland@Sun.COM 		}
17719781SMoriah.Waterland@Sun.COM 		(void) snprintf(pkgstreamfd_path, sizeof (pkgstreamfd_path),
17729781SMoriah.Waterland@Sun.COM 			"/proc/self/fd/%d", fd);
17739781SMoriah.Waterland@Sun.COM 		fds[maxfds++] = fd;
17749781SMoriah.Waterland@Sun.COM 		arg[nargs++] = pkgstreamfd_path;
17759781SMoriah.Waterland@Sun.COM 	} else {
17769781SMoriah.Waterland@Sun.COM 		progerr(ERR_PKGZONEINSTALL_NO_STREAM);
17779781SMoriah.Waterland@Sun.COM 		quit(1);
17789781SMoriah.Waterland@Sun.COM 	}
17799781SMoriah.Waterland@Sun.COM 
17809781SMoriah.Waterland@Sun.COM 	/* add package instance name */
17819781SMoriah.Waterland@Sun.COM 
17829781SMoriah.Waterland@Sun.COM 	arg[nargs++] = pkginst;
17839781SMoriah.Waterland@Sun.COM 
17849781SMoriah.Waterland@Sun.COM 	/* terminate the argument list */
17859781SMoriah.Waterland@Sun.COM 
17869781SMoriah.Waterland@Sun.COM 	arg[nargs++] = NULL;
17879781SMoriah.Waterland@Sun.COM 
17889781SMoriah.Waterland@Sun.COM 	/*
17899781SMoriah.Waterland@Sun.COM 	 * run the appropriate pkginstall command in the specified zone
17909781SMoriah.Waterland@Sun.COM 	 */
17919781SMoriah.Waterland@Sun.COM 
17929781SMoriah.Waterland@Sun.COM 	if (debugFlag == B_TRUE) {
17939781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_ZONE_EXEC_ENTER, a_zoneName, arg[0]);
17949781SMoriah.Waterland@Sun.COM 		for (n = 0; arg[n]; n++) {
17959781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_ARG, n, arg[n]);
17969781SMoriah.Waterland@Sun.COM 		}
17979781SMoriah.Waterland@Sun.COM 	}
17989781SMoriah.Waterland@Sun.COM 
17999781SMoriah.Waterland@Sun.COM 	/* terminate file descriptor list */
18009781SMoriah.Waterland@Sun.COM 
18019781SMoriah.Waterland@Sun.COM 	fds[maxfds] = -1;
18029781SMoriah.Waterland@Sun.COM 
18039781SMoriah.Waterland@Sun.COM 	/* exec command in zone */
18049781SMoriah.Waterland@Sun.COM 
18059781SMoriah.Waterland@Sun.COM 	n = z_zone_exec(a_zoneName, path, arg, a_stdoutPath, (char *)NULL, fds);
18069781SMoriah.Waterland@Sun.COM 
18079781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_ZONE_EXEC_EXIT, a_zoneName, arg[0], n,
18089781SMoriah.Waterland@Sun.COM 			PSTR(a_stdoutPath));
18099781SMoriah.Waterland@Sun.COM 
18109781SMoriah.Waterland@Sun.COM 	/*
18119781SMoriah.Waterland@Sun.COM 	 * close any files that were opened for use by the
18129781SMoriah.Waterland@Sun.COM 	 * /proc/self/fd interface so they could be passed to programs
18139781SMoriah.Waterland@Sun.COM 	 * via the z_zone_exec() interface
18149781SMoriah.Waterland@Sun.COM 	 */
18159781SMoriah.Waterland@Sun.COM 
18169781SMoriah.Waterland@Sun.COM 	for (; maxfds > 0; maxfds--) {
18179781SMoriah.Waterland@Sun.COM 		(void) close(fds[maxfds-1]);
18189781SMoriah.Waterland@Sun.COM 	}
18199781SMoriah.Waterland@Sun.COM 
18209781SMoriah.Waterland@Sun.COM 	/* return results of pkginstall in zone execution */
18219781SMoriah.Waterland@Sun.COM 
18229781SMoriah.Waterland@Sun.COM 	return (n);
18239781SMoriah.Waterland@Sun.COM }
18249781SMoriah.Waterland@Sun.COM 
18259781SMoriah.Waterland@Sun.COM /*
18269781SMoriah.Waterland@Sun.COM  * Name:	pkgZoneInstall
18279781SMoriah.Waterland@Sun.COM  * Description:	Invoke pkginstall in a specified zone to perform an install
18289781SMoriah.Waterland@Sun.COM  *		of a single package in the specified zone
18299781SMoriah.Waterland@Sun.COM  * Arguments:	a_zoneName - pointer to string representing the name of the
18309781SMoriah.Waterland@Sun.COM  *			zone to install the package in.
18319781SMoriah.Waterland@Sun.COM  *		a_inheritedPkgDirs - pointer to array of strings, each one
18329781SMoriah.Waterland@Sun.COM  *			representing the non-global zones full path of a
18339781SMoriah.Waterland@Sun.COM  *			directory that is inherited from the global zone.
18349781SMoriah.Waterland@Sun.COM  *		a_zoneState - current state of the zone; must be mounted or
18359781SMoriah.Waterland@Sun.COM  *			running.
18369781SMoriah.Waterland@Sun.COM  *		a_idsName - pointer to string representing the data stream
18379781SMoriah.Waterland@Sun.COM  *			device (input data stream) containing the package to
18389781SMoriah.Waterland@Sun.COM  *			be installed.
18399781SMoriah.Waterland@Sun.COM  *		a_altBinDir - pointer to string representing an alternative
18409781SMoriah.Waterland@Sun.COM  *			binary location directory to pass to pkginstall.
18419781SMoriah.Waterland@Sun.COM  *			If this is == NULL no alternative binary location is
18429781SMoriah.Waterland@Sun.COM  *			passed to pkginstall.
18439781SMoriah.Waterland@Sun.COM  *		a_adminFile - pointer to string representing the admin
18449781SMoriah.Waterland@Sun.COM  *			file to pass to pkginstall when installing the package.
18459781SMoriah.Waterland@Sun.COM  *			If this is == NULL no admin file is given to pkginstall.
18469781SMoriah.Waterland@Sun.COM  *		a_stdoutPath - pointer to string representing the local path
18479781SMoriah.Waterland@Sun.COM  *			into which all output written by pkginstall to stdout
18489781SMoriah.Waterland@Sun.COM  *			is stored.
18499781SMoriah.Waterland@Sun.COM  *			If this is == NULL stdout is redirected to /dev/null
1850*9869SCasper.Dik@Sun.COM  *		a_tmpzn - B_TRUE when this zone is booted by the package
1851*9869SCasper.Dik@Sun.COM  *			command or B_FALSE if it was running before.
18529781SMoriah.Waterland@Sun.COM  * Returns:	int	(see ckreturn() function for details)
18539781SMoriah.Waterland@Sun.COM  *		0 - success
18549781SMoriah.Waterland@Sun.COM  *		1 - package operation failed (fatal error)
18559781SMoriah.Waterland@Sun.COM  *		2 - non-fatal error (warning)
18569781SMoriah.Waterland@Sun.COM  *		3 - user selected quit (operation interrupted)
18579781SMoriah.Waterland@Sun.COM  *		4 - admin settings prevented operation
18589781SMoriah.Waterland@Sun.COM  *		5 - interaction required and -n (non-interactive) specified
18599781SMoriah.Waterland@Sun.COM  *		"10" will be added to indicate "immediate reboot required"
18609781SMoriah.Waterland@Sun.COM  *		"20" will be added to indicate "reboot after install required"
18619781SMoriah.Waterland@Sun.COM  */
18629781SMoriah.Waterland@Sun.COM 
18639781SMoriah.Waterland@Sun.COM static int
18649781SMoriah.Waterland@Sun.COM pkgZoneInstall(char *a_zoneName, char **a_inheritedPkgDirs,
18659781SMoriah.Waterland@Sun.COM     zone_state_t a_zoneState, char *a_idsName, char *a_altBinDir,
1866*9869SCasper.Dik@Sun.COM     char *a_adminFile, boolean_t a_tmpzn)
18679781SMoriah.Waterland@Sun.COM {
18689781SMoriah.Waterland@Sun.COM 	char	*arg[MAXARGS];
18699781SMoriah.Waterland@Sun.COM 	char	*p;
18709781SMoriah.Waterland@Sun.COM 	char	adminfd_path[PATH_MAX];
18719781SMoriah.Waterland@Sun.COM 	char	path[PATH_MAX];
18729781SMoriah.Waterland@Sun.COM 	char	pkgstreamfd_path[PATH_MAX];
18739781SMoriah.Waterland@Sun.COM 	char	respfilefd_path[PATH_MAX];
18749781SMoriah.Waterland@Sun.COM 	int	fds[MAX_FDS];
18759781SMoriah.Waterland@Sun.COM 	int	maxfds;
18769781SMoriah.Waterland@Sun.COM 	int	n;
18779781SMoriah.Waterland@Sun.COM 	int	nargs;
18789781SMoriah.Waterland@Sun.COM 
18799781SMoriah.Waterland@Sun.COM 	/* entry assertions */
18809781SMoriah.Waterland@Sun.COM 
18819781SMoriah.Waterland@Sun.COM 	assert(a_zoneName != (char *)NULL);
18829781SMoriah.Waterland@Sun.COM 	assert(*a_zoneName != '\0');
18839781SMoriah.Waterland@Sun.COM 
18849781SMoriah.Waterland@Sun.COM 	/* entry debugging info */
18859781SMoriah.Waterland@Sun.COM 
18869781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_PKGZONEINSTALL_ENTRY);
18879781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_PKGZONEINSTALL_ARGS, a_zoneName, PSTR(pkginst),
18889781SMoriah.Waterland@Sun.COM 		PSTR(pkgdev.dirname), PSTR(pkgdev.mount), PSTR(pkgdev.bdevice),
18899781SMoriah.Waterland@Sun.COM 		a_zoneState == ZONE_STATE_MOUNTED ? "/a" : "", PSTR(a_idsName),
18909781SMoriah.Waterland@Sun.COM 		a_adminFile);
18919781SMoriah.Waterland@Sun.COM 
18929781SMoriah.Waterland@Sun.COM 	/* generate path to pkginstall */
18939781SMoriah.Waterland@Sun.COM 
18949781SMoriah.Waterland@Sun.COM 	(void) snprintf(path, sizeof (path), "%s/pkginstall", PKGBIN);
18959781SMoriah.Waterland@Sun.COM 
18969781SMoriah.Waterland@Sun.COM 	/* start at first file descriptor */
18979781SMoriah.Waterland@Sun.COM 
18989781SMoriah.Waterland@Sun.COM 	maxfds = 0;
18999781SMoriah.Waterland@Sun.COM 
19009781SMoriah.Waterland@Sun.COM 	/*
19019781SMoriah.Waterland@Sun.COM 	 * generate argument list for call to pkginstall
19029781SMoriah.Waterland@Sun.COM 	 */
19039781SMoriah.Waterland@Sun.COM 
19049781SMoriah.Waterland@Sun.COM 	/* start at argument 0 */
19059781SMoriah.Waterland@Sun.COM 
19069781SMoriah.Waterland@Sun.COM 	nargs = 0;
19079781SMoriah.Waterland@Sun.COM 
19089781SMoriah.Waterland@Sun.COM 	/* first argument is path to executable */
19099781SMoriah.Waterland@Sun.COM 
19109781SMoriah.Waterland@Sun.COM 	arg[nargs++] = path;
19119781SMoriah.Waterland@Sun.COM 
19129781SMoriah.Waterland@Sun.COM 	/*
19139781SMoriah.Waterland@Sun.COM 	 * second argument is always: pass -O debug to pkginstall: debug mode
19149781SMoriah.Waterland@Sun.COM 	 */
19159781SMoriah.Waterland@Sun.COM 	if (debugFlag == B_TRUE) {
19169781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-O";
19179781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "debug";
19189781SMoriah.Waterland@Sun.COM 	}
19199781SMoriah.Waterland@Sun.COM 
19209781SMoriah.Waterland@Sun.COM 	/* pkgadd -G: pass -G to pkginstall */
19219781SMoriah.Waterland@Sun.COM 
19229781SMoriah.Waterland@Sun.COM 	if (globalZoneOnly == B_TRUE) {
19239781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-G";
19249781SMoriah.Waterland@Sun.COM 	}
19259781SMoriah.Waterland@Sun.COM 
19269781SMoriah.Waterland@Sun.COM 	/* pkgadd -b dir: pass -b to pkginstall in zone */
19279781SMoriah.Waterland@Sun.COM 
19289781SMoriah.Waterland@Sun.COM 	if (a_altBinDir != (char *)NULL) {
19299781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-b";
19309781SMoriah.Waterland@Sun.COM 		arg[nargs++] = a_altBinDir;
19319781SMoriah.Waterland@Sun.COM 	}
19329781SMoriah.Waterland@Sun.COM 
19339781SMoriah.Waterland@Sun.COM 	/* pkgadd -B blocksize: pass -B to pkginstall in zone */
19349781SMoriah.Waterland@Sun.COM 
19359781SMoriah.Waterland@Sun.COM 	if (rw_block_size != NULL) {
19369781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-B";
19379781SMoriah.Waterland@Sun.COM 		arg[nargs++] = rw_block_size;
19389781SMoriah.Waterland@Sun.COM 	}
19399781SMoriah.Waterland@Sun.COM 
19409781SMoriah.Waterland@Sun.COM 	/* pkgadd -C: pass -C to pkgadd in zone: disable checksum */
19419781SMoriah.Waterland@Sun.COM 
19429781SMoriah.Waterland@Sun.COM 	if (disableChecksum) {
19439781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-C";
19449781SMoriah.Waterland@Sun.COM 	}
19459781SMoriah.Waterland@Sun.COM 
19469781SMoriah.Waterland@Sun.COM 	/* pkgadd -A: pass -A to pkgadd in zone: disable attribute checking */
19479781SMoriah.Waterland@Sun.COM 
19489781SMoriah.Waterland@Sun.COM 	if (disableAttributes) {
19499781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-A";
19509781SMoriah.Waterland@Sun.COM 	}
19519781SMoriah.Waterland@Sun.COM 
19529781SMoriah.Waterland@Sun.COM 	/* pkgadd -S: pass -S to pkgadd in zone: suppress copyright notices */
19539781SMoriah.Waterland@Sun.COM 
19549781SMoriah.Waterland@Sun.COM 	arg[nargs++] = "-S";
19559781SMoriah.Waterland@Sun.COM 
19569781SMoriah.Waterland@Sun.COM 	/* pkgadd -I: pass -I to pkgadd in zone: initial install */
19579781SMoriah.Waterland@Sun.COM 
19589781SMoriah.Waterland@Sun.COM 	if (init_install) {
19599781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-I";
19609781SMoriah.Waterland@Sun.COM 	}
19619781SMoriah.Waterland@Sun.COM 
19629781SMoriah.Waterland@Sun.COM 	/* pkgadd -M: pass -M to pkgadd in zone: dont mount client file sys */
19639781SMoriah.Waterland@Sun.COM 
19649781SMoriah.Waterland@Sun.COM 	arg[nargs++] = "-M";
19659781SMoriah.Waterland@Sun.COM 
19669781SMoriah.Waterland@Sun.COM 	/* pkgadd -v: pass -v to pkgadd in zone: trace scripts */
19679781SMoriah.Waterland@Sun.COM 
19689781SMoriah.Waterland@Sun.COM 	if (pkgverbose) {
19699781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-v";
19709781SMoriah.Waterland@Sun.COM 	}
19719781SMoriah.Waterland@Sun.COM 
19729781SMoriah.Waterland@Sun.COM 	/* pkgadd -z: pass -z to pkgadd in zone fresh inst from pkg save area */
19739781SMoriah.Waterland@Sun.COM 
19749781SMoriah.Waterland@Sun.COM 	if (saveSpoolInstall) {
19759781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-z";
19769781SMoriah.Waterland@Sun.COM 	}
19779781SMoriah.Waterland@Sun.COM 
19789781SMoriah.Waterland@Sun.COM 	/* pass "-O enable-hollow-package-support" */
19799781SMoriah.Waterland@Sun.COM 
19809781SMoriah.Waterland@Sun.COM 	if (is_depend_pkginfo_DB()) {
19819781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-O";
19829781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "enable-hollow-package-support";
19839781SMoriah.Waterland@Sun.COM 	}
19849781SMoriah.Waterland@Sun.COM 
19859781SMoriah.Waterland@Sun.COM 	/* pkgadd -t pass -t to pkgadd in zone disable save spool area create */
19869781SMoriah.Waterland@Sun.COM 
19879781SMoriah.Waterland@Sun.COM 	if (disableSaveSpool) {
19889781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-t";
19899781SMoriah.Waterland@Sun.COM 	}
19909781SMoriah.Waterland@Sun.COM 
19919781SMoriah.Waterland@Sun.COM 	/* if running pkgask, pass -i to pkgadd in zone: running pkgask */
19929781SMoriah.Waterland@Sun.COM 
19939781SMoriah.Waterland@Sun.COM 	if (askflag) {
19949781SMoriah.Waterland@Sun.COM 		echo(MSG_BYPASSING_ZONE, a_zoneName);
19959781SMoriah.Waterland@Sun.COM 		return (0);
19969781SMoriah.Waterland@Sun.COM 	}
19979781SMoriah.Waterland@Sun.COM 
19989781SMoriah.Waterland@Sun.COM 	/*
19999781SMoriah.Waterland@Sun.COM 	 * pkgadd -n (not pkgask): pass -n to pkginstall: noninteractive mode
20009781SMoriah.Waterland@Sun.COM 	 */
20019781SMoriah.Waterland@Sun.COM 	if (nointeract && !askflag) {
20029781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-n";
20039781SMoriah.Waterland@Sun.COM 	}
20049781SMoriah.Waterland@Sun.COM 
20059781SMoriah.Waterland@Sun.COM 	/* pkgadd -a admin: pass -a admin to pkginstall in zone: admin file */
20069781SMoriah.Waterland@Sun.COM 
20079781SMoriah.Waterland@Sun.COM 	if (a_adminFile) {
20089781SMoriah.Waterland@Sun.COM 		int fd;
20099781SMoriah.Waterland@Sun.COM 		fd = openLocal(a_adminFile, O_RDONLY, tmpdir);
20109781SMoriah.Waterland@Sun.COM 		if (fd < 0) {
20119781SMoriah.Waterland@Sun.COM 			progerr(ERR_CANNOT_COPY_LOCAL, a_adminFile,
20129781SMoriah.Waterland@Sun.COM 				errno, strerror(errno));
20139781SMoriah.Waterland@Sun.COM 			return (1);
20149781SMoriah.Waterland@Sun.COM 		}
20159781SMoriah.Waterland@Sun.COM 		(void) snprintf(adminfd_path, sizeof (adminfd_path),
20169781SMoriah.Waterland@Sun.COM 			"/proc/self/fd/%d", fd);
20179781SMoriah.Waterland@Sun.COM 		fds[maxfds++] = fd;
20189781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-a";
20199781SMoriah.Waterland@Sun.COM 		arg[nargs++] = adminfd_path;
20209781SMoriah.Waterland@Sun.COM 	}
20219781SMoriah.Waterland@Sun.COM 
20229781SMoriah.Waterland@Sun.COM 	/* pkgadd -R root: pass -R /a to pkginstall when zone is mounted */
20239781SMoriah.Waterland@Sun.COM 	if (a_zoneState == ZONE_STATE_MOUNTED) {
20249781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-R";
20259781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "/a";
20269781SMoriah.Waterland@Sun.COM 	}
20279781SMoriah.Waterland@Sun.COM 
20289781SMoriah.Waterland@Sun.COM 	/*
20299781SMoriah.Waterland@Sun.COM 	 * pkgadd -D arg: pass -D dryrun to pkginstall in zone: dryrun
20309781SMoriah.Waterland@Sun.COM 	 * mode/file
20319781SMoriah.Waterland@Sun.COM 	 */
20329781SMoriah.Waterland@Sun.COM 	if (pkgdrtarg) {
20339781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-D";
20349781SMoriah.Waterland@Sun.COM 		arg[nargs++] = pkgdrtarg;
20359781SMoriah.Waterland@Sun.COM 	}
20369781SMoriah.Waterland@Sun.COM 
20379781SMoriah.Waterland@Sun.COM 	/*
20389781SMoriah.Waterland@Sun.COM 	 * pkgadd -c cont: pass -c cont to pkginstall in zone: continuation
20399781SMoriah.Waterland@Sun.COM 	 * file
20409781SMoriah.Waterland@Sun.COM 	 */
20419781SMoriah.Waterland@Sun.COM 	if (pkgcontsrc) {
20429781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-c";
20439781SMoriah.Waterland@Sun.COM 		arg[nargs++] = pkgcontsrc;
20449781SMoriah.Waterland@Sun.COM 	}
20459781SMoriah.Waterland@Sun.COM 
20469781SMoriah.Waterland@Sun.COM 	/* pkgadd -r resp: pass -r resp to pkginstall in zone: response file */
20479781SMoriah.Waterland@Sun.COM 
20489781SMoriah.Waterland@Sun.COM 	if (respfile) {
20499781SMoriah.Waterland@Sun.COM 		int fd;
20509781SMoriah.Waterland@Sun.COM 		fd = openLocal(respfile, O_RDONLY, tmpdir);
20519781SMoriah.Waterland@Sun.COM 		if (fd < 0) {
20529781SMoriah.Waterland@Sun.COM 			progerr(ERR_CANNOT_COPY_LOCAL, a_adminFile,
20539781SMoriah.Waterland@Sun.COM 				errno, strerror(errno));
20549781SMoriah.Waterland@Sun.COM 			return (1);
20559781SMoriah.Waterland@Sun.COM 		}
20569781SMoriah.Waterland@Sun.COM 		(void) snprintf(respfilefd_path,
20579781SMoriah.Waterland@Sun.COM 			sizeof (respfilefd_path),
20589781SMoriah.Waterland@Sun.COM 			"/proc/self/fd/%d", fd);
20599781SMoriah.Waterland@Sun.COM 		fds[maxfds++] = fd;
20609781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-r";
20619781SMoriah.Waterland@Sun.COM 		arg[nargs++] = respfilefd_path;
20629781SMoriah.Waterland@Sun.COM 	}
20639781SMoriah.Waterland@Sun.COM 
20649781SMoriah.Waterland@Sun.COM 	/* add "-O addzonename" */
20659781SMoriah.Waterland@Sun.COM 
20669781SMoriah.Waterland@Sun.COM 	arg[nargs++] = "-O";
20679781SMoriah.Waterland@Sun.COM 	arg[nargs++] = "addzonename";
20689781SMoriah.Waterland@Sun.COM 
20699781SMoriah.Waterland@Sun.COM 	if (isPatchUpdate()) {
20709781SMoriah.Waterland@Sun.COM 		if (patchPkgRemoval == B_TRUE) {
20719781SMoriah.Waterland@Sun.COM 			arg[nargs++] = "-O";
20729781SMoriah.Waterland@Sun.COM 			arg[nargs++] = "patchPkgRemoval";
20739781SMoriah.Waterland@Sun.COM 		} else {
20749781SMoriah.Waterland@Sun.COM 			arg[nargs++] = "-O";
20759781SMoriah.Waterland@Sun.COM 			arg[nargs++] = "patchPkgInstall";
20769781SMoriah.Waterland@Sun.COM 		}
20779781SMoriah.Waterland@Sun.COM 	}
20789781SMoriah.Waterland@Sun.COM 
20799781SMoriah.Waterland@Sun.COM 	/* add all inherited file systems */
20809781SMoriah.Waterland@Sun.COM 
20819781SMoriah.Waterland@Sun.COM 	if (a_inheritedPkgDirs != (char **)NULL) {
20829781SMoriah.Waterland@Sun.COM 		for (n = 0; a_inheritedPkgDirs[n] != (char *)NULL; n++) {
20839781SMoriah.Waterland@Sun.COM 			char	ifs[MAXPATHLEN+22];
20849781SMoriah.Waterland@Sun.COM 			(void) snprintf(ifs, sizeof (ifs),
20859781SMoriah.Waterland@Sun.COM 				"inherited-filesystem=%s",
20869781SMoriah.Waterland@Sun.COM 				a_inheritedPkgDirs[n]);
20879781SMoriah.Waterland@Sun.COM 			arg[nargs++] = "-O";
20889781SMoriah.Waterland@Sun.COM 			arg[nargs++] = strdup(ifs);
20899781SMoriah.Waterland@Sun.COM 		}
20909781SMoriah.Waterland@Sun.COM 	}
20919781SMoriah.Waterland@Sun.COM 
20929781SMoriah.Waterland@Sun.COM 	/*
20939781SMoriah.Waterland@Sun.COM 	 * add parent zone info/type
20949781SMoriah.Waterland@Sun.COM 	 */
20959781SMoriah.Waterland@Sun.COM 
20969781SMoriah.Waterland@Sun.COM 	p = z_get_zonename();
20979781SMoriah.Waterland@Sun.COM 	if ((p != NULL) && (*p != '\0')) {
20989781SMoriah.Waterland@Sun.COM 			char	zn[MAXPATHLEN];
20999781SMoriah.Waterland@Sun.COM 			(void) snprintf(zn, sizeof (zn),
21009781SMoriah.Waterland@Sun.COM 				"parent-zone-name=%s", p);
21019781SMoriah.Waterland@Sun.COM 			arg[nargs++] = "-O";
21029781SMoriah.Waterland@Sun.COM 			arg[nargs++] = strdup(zn);
21039781SMoriah.Waterland@Sun.COM 	}
21049781SMoriah.Waterland@Sun.COM 
21059781SMoriah.Waterland@Sun.COM 	/* current zone type */
21069781SMoriah.Waterland@Sun.COM 
21079781SMoriah.Waterland@Sun.COM 	arg[nargs++] = "-O";
21089781SMoriah.Waterland@Sun.COM 	if (z_running_in_global_zone() == B_TRUE) {
21099781SMoriah.Waterland@Sun.COM 			char	zn[MAXPATHLEN];
21109781SMoriah.Waterland@Sun.COM 			(void) snprintf(zn, sizeof (zn),
21119781SMoriah.Waterland@Sun.COM 				"parent-zone-type=%s",
21129781SMoriah.Waterland@Sun.COM 				TAG_VALUE_GLOBAL_ZONE);
21139781SMoriah.Waterland@Sun.COM 			arg[nargs++] = strdup(zn);
21149781SMoriah.Waterland@Sun.COM 	} else {
21159781SMoriah.Waterland@Sun.COM 			char	zn[MAXPATHLEN];
21169781SMoriah.Waterland@Sun.COM 			(void) snprintf(zn, sizeof (zn),
21179781SMoriah.Waterland@Sun.COM 				"parent-zone-type=%s",
21189781SMoriah.Waterland@Sun.COM 				TAG_VALUE_NONGLOBAL_ZONE);
21199781SMoriah.Waterland@Sun.COM 			arg[nargs++] = strdup(zn);
21209781SMoriah.Waterland@Sun.COM 	}
21219781SMoriah.Waterland@Sun.COM 
2122*9869SCasper.Dik@Sun.COM 	/* Add the pkgserv options */
2123*9869SCasper.Dik@Sun.COM 	arg[nargs++] = "-O";
2124*9869SCasper.Dik@Sun.COM 	arg[nargs++] = pkgmodeargument(a_tmpzn ? RUN_ONCE : pkgservergetmode());
2125*9869SCasper.Dik@Sun.COM 
21269781SMoriah.Waterland@Sun.COM 	/* add in the package stream file */
21279781SMoriah.Waterland@Sun.COM 
21289781SMoriah.Waterland@Sun.COM 	if (a_idsName != NULL) {
21299781SMoriah.Waterland@Sun.COM 		int fd;
21309781SMoriah.Waterland@Sun.COM 		fd = openLocal(a_idsName, O_RDONLY, tmpdir);
21319781SMoriah.Waterland@Sun.COM 		if (fd < 0) {
21329781SMoriah.Waterland@Sun.COM 			progerr(ERR_STREAM_UNAVAILABLE, a_idsName,
21339781SMoriah.Waterland@Sun.COM 				pkginst, strerror(errno));
21349781SMoriah.Waterland@Sun.COM 			quit(1);
21359781SMoriah.Waterland@Sun.COM 		}
21369781SMoriah.Waterland@Sun.COM 		(void) snprintf(pkgstreamfd_path, sizeof (pkgstreamfd_path),
21379781SMoriah.Waterland@Sun.COM 			"/proc/self/fd/%d", fd);
21389781SMoriah.Waterland@Sun.COM 		fds[maxfds++] = fd;
21399781SMoriah.Waterland@Sun.COM 		arg[nargs++] = pkgstreamfd_path;
21409781SMoriah.Waterland@Sun.COM 	} else {
21419781SMoriah.Waterland@Sun.COM 		progerr(ERR_PKGZONEINSTALL_NO_STREAM);
21429781SMoriah.Waterland@Sun.COM 		quit(1);
21439781SMoriah.Waterland@Sun.COM 	}
21449781SMoriah.Waterland@Sun.COM 
21459781SMoriah.Waterland@Sun.COM 	/* add package instance name */
21469781SMoriah.Waterland@Sun.COM 
21479781SMoriah.Waterland@Sun.COM 	arg[nargs++] = pkginst;
21489781SMoriah.Waterland@Sun.COM 
21499781SMoriah.Waterland@Sun.COM 	/* terminate the argument list */
21509781SMoriah.Waterland@Sun.COM 
21519781SMoriah.Waterland@Sun.COM 	arg[nargs++] = NULL;
21529781SMoriah.Waterland@Sun.COM 
21539781SMoriah.Waterland@Sun.COM 	/*
21549781SMoriah.Waterland@Sun.COM 	 * run the appropriate pkginstall command in the specified zone
21559781SMoriah.Waterland@Sun.COM 	 */
21569781SMoriah.Waterland@Sun.COM 
21579781SMoriah.Waterland@Sun.COM 	if (debugFlag == B_TRUE) {
21589781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_ZONE_EXEC_ENTER, a_zoneName, arg[0]);
21599781SMoriah.Waterland@Sun.COM 		for (n = 0; arg[n]; n++) {
21609781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_ARG, n, arg[n]);
21619781SMoriah.Waterland@Sun.COM 		}
21629781SMoriah.Waterland@Sun.COM 	}
21639781SMoriah.Waterland@Sun.COM 
21649781SMoriah.Waterland@Sun.COM 	/* terminate file descriptor list */
21659781SMoriah.Waterland@Sun.COM 
21669781SMoriah.Waterland@Sun.COM 	fds[maxfds] = -1;
21679781SMoriah.Waterland@Sun.COM 
21689781SMoriah.Waterland@Sun.COM 	/* exec command in zone */
21699781SMoriah.Waterland@Sun.COM 
21709781SMoriah.Waterland@Sun.COM 	n = z_zone_exec(a_zoneName, path, arg, (char *)NULL, (char *)NULL, fds);
21719781SMoriah.Waterland@Sun.COM 
21729781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_ZONE_EXEC_EXIT, a_zoneName, arg[0], n, "");
21739781SMoriah.Waterland@Sun.COM 
21749781SMoriah.Waterland@Sun.COM 	/*
21759781SMoriah.Waterland@Sun.COM 	 * close any files that were opened for use by the
21769781SMoriah.Waterland@Sun.COM 	 * /proc/self/fd interface so they could be passed to programs
21779781SMoriah.Waterland@Sun.COM 	 * via the z_zone_exec() interface
21789781SMoriah.Waterland@Sun.COM 	 */
21799781SMoriah.Waterland@Sun.COM 
21809781SMoriah.Waterland@Sun.COM 	for (; maxfds > 0; maxfds--) {
21819781SMoriah.Waterland@Sun.COM 		(void) close(fds[maxfds-1]);
21829781SMoriah.Waterland@Sun.COM 	}
21839781SMoriah.Waterland@Sun.COM 
21849781SMoriah.Waterland@Sun.COM 	/* return results of pkginstall in zone execution */
21859781SMoriah.Waterland@Sun.COM 
21869781SMoriah.Waterland@Sun.COM 	return (n);
21879781SMoriah.Waterland@Sun.COM }
21889781SMoriah.Waterland@Sun.COM 
21899781SMoriah.Waterland@Sun.COM /*
21909781SMoriah.Waterland@Sun.COM  * Name:	pkgInstall
21919781SMoriah.Waterland@Sun.COM  * Description:	Invoke pkginstall in the current zone to perform an install
21929781SMoriah.Waterland@Sun.COM  *		of a single package to the current zone or standalone system
21939781SMoriah.Waterland@Sun.COM  * Arguments:	a_altRoot - pointer to string representing the alternative
21949781SMoriah.Waterland@Sun.COM  *			root to use for the install
21959781SMoriah.Waterland@Sun.COM  *		a_idsName - pointer to string representing the data stream
21969781SMoriah.Waterland@Sun.COM  *			device (input data stream) containing the package to
21979781SMoriah.Waterland@Sun.COM  *			be installed.
21989781SMoriah.Waterland@Sun.COM  *		a_pkgDir - pointer to string representing the path to the
21999781SMoriah.Waterland@Sun.COM  *			directory containing the package
22009781SMoriah.Waterland@Sun.COM  *		a_altBinDir - pointer to string representing location of the
22019781SMoriah.Waterland@Sun.COM  *			pkginstall executable to run. If not NULL, then pass
22029781SMoriah.Waterland@Sun.COM  *			the path specified to the -b option to pkginstall.
22039781SMoriah.Waterland@Sun.COM  *		a_inheritedPkgDirs - pointer to array of strings, each one
22049781SMoriah.Waterland@Sun.COM  *			representing the non-global zones full path of a
22059781SMoriah.Waterland@Sun.COM  *			directory that is inherited from the global zone.
22069781SMoriah.Waterland@Sun.COM  * Returns:	int	(see ckreturn() function for details)
22079781SMoriah.Waterland@Sun.COM  *		0 - success
22089781SMoriah.Waterland@Sun.COM  *		1 - package operation failed (fatal error)
22099781SMoriah.Waterland@Sun.COM  *		2 - non-fatal error (warning)
22109781SMoriah.Waterland@Sun.COM  *		3 - user selected quit (operation interrupted)
22119781SMoriah.Waterland@Sun.COM  *		4 - admin settings prevented operation
22129781SMoriah.Waterland@Sun.COM  *		5 - interaction required and -n (non-interactive) specified
22139781SMoriah.Waterland@Sun.COM  *		"10" will be added to indicate "immediate reboot required"
22149781SMoriah.Waterland@Sun.COM  *		"20" will be added to indicate "reboot after install required"
22159781SMoriah.Waterland@Sun.COM  * NOTE:	Both a_idsName and a_pkgDir are used to determine where the
22169781SMoriah.Waterland@Sun.COM  *		package to be installed is located. If a_idsName is != NULL
22179781SMoriah.Waterland@Sun.COM  *		then it must be the path to a device containing a package
22189781SMoriah.Waterland@Sun.COM  *		stream that contains the package to be installed. If a_idsName
22199781SMoriah.Waterland@Sun.COM  *		is == NULL then a_pkgDir must contain a full path to a directory
22209781SMoriah.Waterland@Sun.COM  *		that contains the package to be installed.
22219781SMoriah.Waterland@Sun.COM  */
22229781SMoriah.Waterland@Sun.COM 
22239781SMoriah.Waterland@Sun.COM static int
22249781SMoriah.Waterland@Sun.COM pkgInstall(char *a_altRoot, char *a_idsName, char *a_pkgDir, char *a_altBinDir,
22259781SMoriah.Waterland@Sun.COM 	char **a_inheritedPkgDirs)
22269781SMoriah.Waterland@Sun.COM {
22279781SMoriah.Waterland@Sun.COM 	char	*arg[MAXARGS];
22289781SMoriah.Waterland@Sun.COM 	char	*p;
22299781SMoriah.Waterland@Sun.COM 	char	path[PATH_MAX];
22309781SMoriah.Waterland@Sun.COM 	char	buffer[256];
22319781SMoriah.Waterland@Sun.COM 	int	n, nargs;
22329781SMoriah.Waterland@Sun.COM 
22339781SMoriah.Waterland@Sun.COM 	/* entry debugging info */
22349781SMoriah.Waterland@Sun.COM 
22359781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_PKGINSTALL_ENTRY);
22369781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_PKGINSTALL_ARGS, PSTR(pkginst), PSTR(pkgdev.dirname),
22379781SMoriah.Waterland@Sun.COM 		PSTR(pkgdev.mount), PSTR(pkgdev.bdevice), PSTR(a_altRoot),
22389781SMoriah.Waterland@Sun.COM 		PSTR(a_idsName), PSTR(a_pkgDir));
22399781SMoriah.Waterland@Sun.COM 
22409781SMoriah.Waterland@Sun.COM 	/* generate full path to 'pkginstall' to run in zone */
22419781SMoriah.Waterland@Sun.COM 
22429781SMoriah.Waterland@Sun.COM 	(void) snprintf(path, sizeof (path), "%s/pkginstall",
22439781SMoriah.Waterland@Sun.COM 		a_altBinDir == (char *)NULL ? PKGBIN : a_altBinDir);
22449781SMoriah.Waterland@Sun.COM 	/*
22459781SMoriah.Waterland@Sun.COM 	 * generate argument list for call to pkginstall
22469781SMoriah.Waterland@Sun.COM 	 */
22479781SMoriah.Waterland@Sun.COM 
22489781SMoriah.Waterland@Sun.COM 	/* start at argument 0 */
22499781SMoriah.Waterland@Sun.COM 
22509781SMoriah.Waterland@Sun.COM 	nargs = 0;
22519781SMoriah.Waterland@Sun.COM 
22529781SMoriah.Waterland@Sun.COM 	/* first argument is path to executable */
22539781SMoriah.Waterland@Sun.COM 
22549781SMoriah.Waterland@Sun.COM 	arg[nargs++] = path;
22559781SMoriah.Waterland@Sun.COM 
22569781SMoriah.Waterland@Sun.COM 	/*
22579781SMoriah.Waterland@Sun.COM 	 * second argument is always: pass -O debug to pkginstall: debug mode
22589781SMoriah.Waterland@Sun.COM 	 */
22599781SMoriah.Waterland@Sun.COM 	if (debugFlag == B_TRUE) {
22609781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-O";
22619781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "debug";
22629781SMoriah.Waterland@Sun.COM 	}
22639781SMoriah.Waterland@Sun.COM 
22649781SMoriah.Waterland@Sun.COM 	/* Installation is from a patch package. */
22659781SMoriah.Waterland@Sun.COM 
22669781SMoriah.Waterland@Sun.COM 	if (isPatchUpdate()) {
22679781SMoriah.Waterland@Sun.COM 		if (patchPkgRemoval == B_TRUE) {
22689781SMoriah.Waterland@Sun.COM 			arg[nargs++] = "-O";
22699781SMoriah.Waterland@Sun.COM 			arg[nargs++] = "patchPkgRemoval";
22709781SMoriah.Waterland@Sun.COM 		} else {
22719781SMoriah.Waterland@Sun.COM 			arg[nargs++] = "-O";
22729781SMoriah.Waterland@Sun.COM 			arg[nargs++] = "patchPkgInstall";
22739781SMoriah.Waterland@Sun.COM 		}
22749781SMoriah.Waterland@Sun.COM 	}
22759781SMoriah.Waterland@Sun.COM 
2276*9869SCasper.Dik@Sun.COM 	arg[nargs++] = "-O";
2277*9869SCasper.Dik@Sun.COM 	arg[nargs++] = pkgmodeargument(pkgservergetmode());
2278*9869SCasper.Dik@Sun.COM 
22799781SMoriah.Waterland@Sun.COM 	/*
22809781SMoriah.Waterland@Sun.COM 	 * pkgadd -G: pass -G to pkginstall if:
22819781SMoriah.Waterland@Sun.COM 	 *  - the -G option is specified on the pkgadd command line
22829781SMoriah.Waterland@Sun.COM 	 *  - this package is marked 'this zone only':
22839781SMoriah.Waterland@Sun.COM 	 *  -- package has SUNW_PKG_THISZONE=true, or
22849781SMoriah.Waterland@Sun.COM 	 *  -- package has a request script
22859781SMoriah.Waterland@Sun.COM 	 * Setting -G for pkginstall causes pkginstall to install the package
22869781SMoriah.Waterland@Sun.COM 	 * in the target zone. If running in the global zone, will install the
22879781SMoriah.Waterland@Sun.COM 	 * package and mark the package as installed "in the global zone only".
22889781SMoriah.Waterland@Sun.COM 	 * If running in a non-global zone, will just install the package.
22899781SMoriah.Waterland@Sun.COM 	 */
22909781SMoriah.Waterland@Sun.COM 
22919781SMoriah.Waterland@Sun.COM 	if (globalZoneOnly == B_TRUE) {
22929781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-G";
22939781SMoriah.Waterland@Sun.COM 	} else if (pkgPackageIsThisZone(pkginst) == B_TRUE) {
22949781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-G";
22959781SMoriah.Waterland@Sun.COM 	}
22969781SMoriah.Waterland@Sun.COM 
22979781SMoriah.Waterland@Sun.COM 	/* pkgadd -b dir: pass -b to pkginstall */
22989781SMoriah.Waterland@Sun.COM 
22999781SMoriah.Waterland@Sun.COM 	if (a_altBinDir != (char *)NULL) {
23009781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-b";
23019781SMoriah.Waterland@Sun.COM 		arg[nargs++] = a_altBinDir;
23029781SMoriah.Waterland@Sun.COM 	}
23039781SMoriah.Waterland@Sun.COM 
23049781SMoriah.Waterland@Sun.COM 	/* pkgadd -B blocksize: pass -B to pkginstall */
23059781SMoriah.Waterland@Sun.COM 
23069781SMoriah.Waterland@Sun.COM 	if (rw_block_size != NULL) {
23079781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-B";
23089781SMoriah.Waterland@Sun.COM 		arg[nargs++] = rw_block_size;
23099781SMoriah.Waterland@Sun.COM 	}
23109781SMoriah.Waterland@Sun.COM 
23119781SMoriah.Waterland@Sun.COM 	/* pkgadd -C: pass -C to pkginstall: disable checksum */
23129781SMoriah.Waterland@Sun.COM 
23139781SMoriah.Waterland@Sun.COM 	if (disableChecksum) {
23149781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-C";
23159781SMoriah.Waterland@Sun.COM 	}
23169781SMoriah.Waterland@Sun.COM 
23179781SMoriah.Waterland@Sun.COM 	/* pkgadd -A: pass -A to pkginstall: disable attribute checking */
23189781SMoriah.Waterland@Sun.COM 
23199781SMoriah.Waterland@Sun.COM 	if (disableAttributes) {
23209781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-A";
23219781SMoriah.Waterland@Sun.COM 	}
23229781SMoriah.Waterland@Sun.COM 
23239781SMoriah.Waterland@Sun.COM 	/*
23249781SMoriah.Waterland@Sun.COM 	 * NONABI_SCRIPTS defined: pass -o to pkginstall; refers to a
23259781SMoriah.Waterland@Sun.COM 	 * pkg requiring operator interaction during a procedure script
23269781SMoriah.Waterland@Sun.COM 	 * (common before on1093)
23279781SMoriah.Waterland@Sun.COM 	 */
23289781SMoriah.Waterland@Sun.COM 
23299781SMoriah.Waterland@Sun.COM 	if (old_pkg) {
23309781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-o";
23319781SMoriah.Waterland@Sun.COM 	}
23329781SMoriah.Waterland@Sun.COM 
23339781SMoriah.Waterland@Sun.COM 	/*
23349781SMoriah.Waterland@Sun.COM 	 * PKG_NONABI_SYMLINKS defined: pass -y to pkginstall; process
23359781SMoriah.Waterland@Sun.COM 	 * symlinks consistent with old behavior
23369781SMoriah.Waterland@Sun.COM 	 */
23379781SMoriah.Waterland@Sun.COM 
23389781SMoriah.Waterland@Sun.COM 	if (old_symlinks) {
23399781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-y";
23409781SMoriah.Waterland@Sun.COM 	}
23419781SMoriah.Waterland@Sun.COM 
23429781SMoriah.Waterland@Sun.COM 	/*
23439781SMoriah.Waterland@Sun.COM 	 * PKG_ABI_NAMELENGTH defined: pass -e to pkginstall; causes
23449781SMoriah.Waterland@Sun.COM 	 * package name length to be restricted
23459781SMoriah.Waterland@Sun.COM 	 */
23469781SMoriah.Waterland@Sun.COM 
23479781SMoriah.Waterland@Sun.COM 	if (ABI_namelength) {
23489781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-e";
23499781SMoriah.Waterland@Sun.COM 	}
23509781SMoriah.Waterland@Sun.COM 
23519781SMoriah.Waterland@Sun.COM 	/* pkgadd -S: pass -S to pkginstall: suppress copyright notices */
23529781SMoriah.Waterland@Sun.COM 
23539781SMoriah.Waterland@Sun.COM 	if (suppressCopyright) {
23549781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-S";
23559781SMoriah.Waterland@Sun.COM 	}
23569781SMoriah.Waterland@Sun.COM 
23579781SMoriah.Waterland@Sun.COM 	/* pkgadd -I: pass -I to pkginstall: initial install being performed */
23589781SMoriah.Waterland@Sun.COM 
23599781SMoriah.Waterland@Sun.COM 	if (init_install) {
23609781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-I";
23619781SMoriah.Waterland@Sun.COM 	}
23629781SMoriah.Waterland@Sun.COM 
23639781SMoriah.Waterland@Sun.COM 	/* pkgadd -M: pass -M to pkginstall: dont mount client file systems */
23649781SMoriah.Waterland@Sun.COM 
23659781SMoriah.Waterland@Sun.COM 	if (no_map_client) {
23669781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-M";
23679781SMoriah.Waterland@Sun.COM 	}
23689781SMoriah.Waterland@Sun.COM 
23699781SMoriah.Waterland@Sun.COM 	/* pkgadd -v: pass -v to pkginstall: trace scripts */
23709781SMoriah.Waterland@Sun.COM 
23719781SMoriah.Waterland@Sun.COM 	if (pkgverbose) {
23729781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-v";
23739781SMoriah.Waterland@Sun.COM 	}
23749781SMoriah.Waterland@Sun.COM 
23759781SMoriah.Waterland@Sun.COM 	/* pkgadd -z: pass -z to pkginstall: fresh install from pkg save area */
23769781SMoriah.Waterland@Sun.COM 
23779781SMoriah.Waterland@Sun.COM 	if (saveSpoolInstall) {
23789781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-z";
23799781SMoriah.Waterland@Sun.COM 	}
23809781SMoriah.Waterland@Sun.COM 
23819781SMoriah.Waterland@Sun.COM 	/*
23829781SMoriah.Waterland@Sun.COM 	 * if running in a non-global zone and the 'hollow' attribute is
23839781SMoriah.Waterland@Sun.COM 	 * passed in, then pass -h to pkginstall so that it knows how to
23849781SMoriah.Waterland@Sun.COM 	 * handle hollow packages for this local zone.
23859781SMoriah.Waterland@Sun.COM 	 */
23869781SMoriah.Waterland@Sun.COM 
23879781SMoriah.Waterland@Sun.COM 	if (!z_running_in_global_zone() && is_depend_pkginfo_DB()) {
23889781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-h";
23899781SMoriah.Waterland@Sun.COM 	}
23909781SMoriah.Waterland@Sun.COM 
23919781SMoriah.Waterland@Sun.COM 	/* pkgadd -t: pass -t to pkginstall: disable save spool area creation */
23929781SMoriah.Waterland@Sun.COM 
23939781SMoriah.Waterland@Sun.COM 	if (disableSaveSpool) {
23949781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-t";
23959781SMoriah.Waterland@Sun.COM 	}
23969781SMoriah.Waterland@Sun.COM 
23979781SMoriah.Waterland@Sun.COM 	/* if running pkgask, pass -i to pkginstall: running pkgask */
23989781SMoriah.Waterland@Sun.COM 
23999781SMoriah.Waterland@Sun.COM 	if (askflag) {
24009781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-i";
24019781SMoriah.Waterland@Sun.COM 	}
24029781SMoriah.Waterland@Sun.COM 
24039781SMoriah.Waterland@Sun.COM 	/* pkgadd -n (not pkgask): pass -n to pkginstall: noninteractive mode */
24049781SMoriah.Waterland@Sun.COM 
24059781SMoriah.Waterland@Sun.COM 	if (nointeract && !askflag) {
24069781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-n";
24079781SMoriah.Waterland@Sun.COM 	}
24089781SMoriah.Waterland@Sun.COM 
24099781SMoriah.Waterland@Sun.COM 	/* pkgadd -a admin: pass -a admin to pkginstall: admin file */
24109781SMoriah.Waterland@Sun.COM 
24119781SMoriah.Waterland@Sun.COM 	if (admnfile) {
24129781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-a";
24139781SMoriah.Waterland@Sun.COM 		arg[nargs++] = admnfile;
24149781SMoriah.Waterland@Sun.COM 	}
24159781SMoriah.Waterland@Sun.COM 
24169781SMoriah.Waterland@Sun.COM 	/* pkgadd -D dryrun: pass -D dryrun to pkginstall: dryrun mode/file */
24179781SMoriah.Waterland@Sun.COM 
24189781SMoriah.Waterland@Sun.COM 	if (pkgdrtarg) {
24199781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-D";
24209781SMoriah.Waterland@Sun.COM 		arg[nargs++] = pkgdrtarg;
24219781SMoriah.Waterland@Sun.COM 	}
24229781SMoriah.Waterland@Sun.COM 
24239781SMoriah.Waterland@Sun.COM 	/* pkgadd -c cont: pass -c cont to pkginstall: continuation file */
24249781SMoriah.Waterland@Sun.COM 
24259781SMoriah.Waterland@Sun.COM 	if (pkgcontsrc) {
24269781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-c";
24279781SMoriah.Waterland@Sun.COM 		arg[nargs++] = pkgcontsrc;
24289781SMoriah.Waterland@Sun.COM 	}
24299781SMoriah.Waterland@Sun.COM 
24309781SMoriah.Waterland@Sun.COM 	/* pkgadd -V vfstab: pass -V vfstab to pkginstall: alternate vfstab */
24319781SMoriah.Waterland@Sun.COM 
24329781SMoriah.Waterland@Sun.COM 	if (vfstab_file) {
24339781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-V";
24349781SMoriah.Waterland@Sun.COM 		arg[nargs++] = vfstab_file;
24359781SMoriah.Waterland@Sun.COM 	}
24369781SMoriah.Waterland@Sun.COM 
24379781SMoriah.Waterland@Sun.COM 	/* pkgadd -r resp: pass -r resp to pkginstall: response file */
24389781SMoriah.Waterland@Sun.COM 
24399781SMoriah.Waterland@Sun.COM 	if (respfile) {
24409781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-r";
24419781SMoriah.Waterland@Sun.COM 		arg[nargs++] = respfile;
24429781SMoriah.Waterland@Sun.COM 	}
24439781SMoriah.Waterland@Sun.COM 
24449781SMoriah.Waterland@Sun.COM 	/* pkgadd -R root: pass -R root to pkginstall: alternative root */
24459781SMoriah.Waterland@Sun.COM 
24469781SMoriah.Waterland@Sun.COM 	if (a_altRoot && *a_altRoot) {
24479781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-R";
24489781SMoriah.Waterland@Sun.COM 		arg[nargs++] = a_altRoot;
24499781SMoriah.Waterland@Sun.COM 	}
24509781SMoriah.Waterland@Sun.COM 
24519781SMoriah.Waterland@Sun.COM 	/*
24529781SMoriah.Waterland@Sun.COM 	 * If input data stream is available,
24539781SMoriah.Waterland@Sun.COM 	 * - add: -d ids_name -p number_of_parts
24549781SMoriah.Waterland@Sun.COM 	 * else,
24559781SMoriah.Waterland@Sun.COM 	 * - add: -d device -m mount [-f type]
24569781SMoriah.Waterland@Sun.COM 	 */
24579781SMoriah.Waterland@Sun.COM 
24589781SMoriah.Waterland@Sun.COM 	if (a_idsName != NULL) {
24599781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-d";
24609781SMoriah.Waterland@Sun.COM 		arg[nargs++] = a_idsName;
24619781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-p";
24629781SMoriah.Waterland@Sun.COM 		ds_close(1);
24639781SMoriah.Waterland@Sun.COM 		ds_putinfo(buffer);
24649781SMoriah.Waterland@Sun.COM 		arg[nargs++] = buffer;
24659781SMoriah.Waterland@Sun.COM 	} else if (pkgdev.mount != NULL) {
24669781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-d";
24679781SMoriah.Waterland@Sun.COM 		arg[nargs++] = pkgdev.bdevice;
24689781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-m";
24699781SMoriah.Waterland@Sun.COM 		arg[nargs++] = pkgdev.mount;
24709781SMoriah.Waterland@Sun.COM 		if (pkgdev.fstyp != NULL) {
24719781SMoriah.Waterland@Sun.COM 			arg[nargs++] = "-f";
24729781SMoriah.Waterland@Sun.COM 			arg[nargs++] = pkgdev.fstyp;
24739781SMoriah.Waterland@Sun.COM 		}
24749781SMoriah.Waterland@Sun.COM 	}
24759781SMoriah.Waterland@Sun.COM 
24769781SMoriah.Waterland@Sun.COM 	/* add all inherited file systems */
24779781SMoriah.Waterland@Sun.COM 
24789781SMoriah.Waterland@Sun.COM 	if (a_inheritedPkgDirs != (char **)NULL) {
24799781SMoriah.Waterland@Sun.COM 		for (n = 0; a_inheritedPkgDirs[n] != (char *)NULL; n++) {
24809781SMoriah.Waterland@Sun.COM 			char	ifs[MAXPATHLEN+22];
24819781SMoriah.Waterland@Sun.COM 			(void) snprintf(ifs, sizeof (ifs),
24829781SMoriah.Waterland@Sun.COM 				"inherited-filesystem=%s",
24839781SMoriah.Waterland@Sun.COM 				a_inheritedPkgDirs[n]);
24849781SMoriah.Waterland@Sun.COM 			arg[nargs++] = "-O";
24859781SMoriah.Waterland@Sun.COM 			arg[nargs++] = strdup(ifs);
24869781SMoriah.Waterland@Sun.COM 		}
24879781SMoriah.Waterland@Sun.COM 	}
24889781SMoriah.Waterland@Sun.COM 
24899781SMoriah.Waterland@Sun.COM 	/*
24909781SMoriah.Waterland@Sun.COM 	 * add parent zone info/type
24919781SMoriah.Waterland@Sun.COM 	 */
24929781SMoriah.Waterland@Sun.COM 
24939781SMoriah.Waterland@Sun.COM 	p = z_get_zonename();
24949781SMoriah.Waterland@Sun.COM 	if ((p != NULL) && (*p != '\0')) {
24959781SMoriah.Waterland@Sun.COM 			char	zn[MAXPATHLEN];
24969781SMoriah.Waterland@Sun.COM 			(void) snprintf(zn, sizeof (zn),
24979781SMoriah.Waterland@Sun.COM 				"parent-zone-name=%s", p);
24989781SMoriah.Waterland@Sun.COM 			arg[nargs++] = "-O";
24999781SMoriah.Waterland@Sun.COM 			arg[nargs++] = strdup(zn);
25009781SMoriah.Waterland@Sun.COM 	}
25019781SMoriah.Waterland@Sun.COM 
25029781SMoriah.Waterland@Sun.COM 	/* current zone type */
25039781SMoriah.Waterland@Sun.COM 
25049781SMoriah.Waterland@Sun.COM 	arg[nargs++] = "-O";
25059781SMoriah.Waterland@Sun.COM 	if (z_running_in_global_zone() == B_TRUE) {
25069781SMoriah.Waterland@Sun.COM 			char	zn[MAXPATHLEN];
25079781SMoriah.Waterland@Sun.COM 			(void) snprintf(zn, sizeof (zn),
25089781SMoriah.Waterland@Sun.COM 				"parent-zone-type=%s",
25099781SMoriah.Waterland@Sun.COM 				TAG_VALUE_GLOBAL_ZONE);
25109781SMoriah.Waterland@Sun.COM 			arg[nargs++] = strdup(zn);
25119781SMoriah.Waterland@Sun.COM 	} else {
25129781SMoriah.Waterland@Sun.COM 			char	zn[MAXPATHLEN];
25139781SMoriah.Waterland@Sun.COM 			(void) snprintf(zn, sizeof (zn),
25149781SMoriah.Waterland@Sun.COM 				"parent-zone-type=%s",
25159781SMoriah.Waterland@Sun.COM 				TAG_VALUE_NONGLOBAL_ZONE);
25169781SMoriah.Waterland@Sun.COM 			arg[nargs++] = strdup(zn);
25179781SMoriah.Waterland@Sun.COM 	}
25189781SMoriah.Waterland@Sun.COM 
25199781SMoriah.Waterland@Sun.COM 	/* pass -N to pkginstall: program name to report */
25209781SMoriah.Waterland@Sun.COM 
25219781SMoriah.Waterland@Sun.COM 	arg[nargs++] = "-N";
25229781SMoriah.Waterland@Sun.COM 	arg[nargs++] = get_prog_name();
25239781SMoriah.Waterland@Sun.COM 
25249781SMoriah.Waterland@Sun.COM 	/* add package directory name */
25259781SMoriah.Waterland@Sun.COM 
25269781SMoriah.Waterland@Sun.COM 	arg[nargs++] = a_pkgDir;
25279781SMoriah.Waterland@Sun.COM 
25289781SMoriah.Waterland@Sun.COM 	/* add package instance name */
25299781SMoriah.Waterland@Sun.COM 
25309781SMoriah.Waterland@Sun.COM 	arg[nargs++] = pkginst;
25319781SMoriah.Waterland@Sun.COM 
25329781SMoriah.Waterland@Sun.COM 	/* terminate the argument list */
25339781SMoriah.Waterland@Sun.COM 
25349781SMoriah.Waterland@Sun.COM 	arg[nargs++] = NULL;
25359781SMoriah.Waterland@Sun.COM 
25369781SMoriah.Waterland@Sun.COM 	/*
25379781SMoriah.Waterland@Sun.COM 	 * run the appropriate pkginstall command in the specified zone
25389781SMoriah.Waterland@Sun.COM 	 */
25399781SMoriah.Waterland@Sun.COM 
25409781SMoriah.Waterland@Sun.COM 	if (debugFlag == B_TRUE) {
25419781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_ZONE_EXEC_ENTER, "global", arg[0]);
25429781SMoriah.Waterland@Sun.COM 		for (n = 0; arg[n]; n++) {
25439781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_ARG, n, arg[n]);
25449781SMoriah.Waterland@Sun.COM 		}
25459781SMoriah.Waterland@Sun.COM 	}
25469781SMoriah.Waterland@Sun.COM 
25479781SMoriah.Waterland@Sun.COM 	/* execute pkginstall command */
25489781SMoriah.Waterland@Sun.COM 
25499781SMoriah.Waterland@Sun.COM 	n = pkgexecv(NULL, NULL, NULL, NULL, arg);
25509781SMoriah.Waterland@Sun.COM 
25519781SMoriah.Waterland@Sun.COM 	/* return results of pkginstall execution */
25529781SMoriah.Waterland@Sun.COM 
25539781SMoriah.Waterland@Sun.COM 	return (n);
25549781SMoriah.Waterland@Sun.COM }
25559781SMoriah.Waterland@Sun.COM 
25569781SMoriah.Waterland@Sun.COM /*
25579781SMoriah.Waterland@Sun.COM  *  function to clear out any exisiting error return conditions that may have
25589781SMoriah.Waterland@Sun.COM  *  been set by previous calls to ckreturn()
25599781SMoriah.Waterland@Sun.COM  */
25609781SMoriah.Waterland@Sun.COM static void
25619781SMoriah.Waterland@Sun.COM resetreturn()
25629781SMoriah.Waterland@Sun.COM {
25639781SMoriah.Waterland@Sun.COM 	admnflag = 0;	/* != 0 if any pkg op admin setting failure (4) */
25649781SMoriah.Waterland@Sun.COM 	doreboot = 0;	/* != 0 if reboot required after installation (>= 10) */
25659781SMoriah.Waterland@Sun.COM 	failflag = 0;	/* != 0 if fatal error has occurred (1) */
25669781SMoriah.Waterland@Sun.COM 	intrflag = 0;	/* != 0 if user selected quit (3) */
25679781SMoriah.Waterland@Sun.COM 	ireboot = 0;	/* != 0 if immediate reboot required (>= 20) */
25689781SMoriah.Waterland@Sun.COM 	nullflag = 0;	/* != 0 if admin interaction required (5) */
25699781SMoriah.Waterland@Sun.COM 	warnflag = 0;	/* != 0 if non-fatal error has occurred (2) */
25709781SMoriah.Waterland@Sun.COM 	interrupted = 0;	/* last pkg op was quit (1,2,3,4,5) */
25719781SMoriah.Waterland@Sun.COM 	needconsult = 0;	/* essential ask admin now (1,2,3,5) */
25729781SMoriah.Waterland@Sun.COM }
25739781SMoriah.Waterland@Sun.COM 
25749781SMoriah.Waterland@Sun.COM /*
25759781SMoriah.Waterland@Sun.COM  *  function which checks the indicated return value
25769781SMoriah.Waterland@Sun.COM  *  and indicates disposition of installation
25779781SMoriah.Waterland@Sun.COM  */
25789781SMoriah.Waterland@Sun.COM static void
25799781SMoriah.Waterland@Sun.COM ckreturn(int retcode)
25809781SMoriah.Waterland@Sun.COM {
25819781SMoriah.Waterland@Sun.COM 	/*
25829781SMoriah.Waterland@Sun.COM 	 * entry debugging info
25839781SMoriah.Waterland@Sun.COM 	 */
25849781SMoriah.Waterland@Sun.COM 
25859781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_PKGADD_CKRETURN, retcode, PSTR(pkginst));
25869781SMoriah.Waterland@Sun.COM 
25879781SMoriah.Waterland@Sun.COM 	/* reset needconsult so it only reflects this call to ckreturn */
25889781SMoriah.Waterland@Sun.COM 	needconsult = 0;
25899781SMoriah.Waterland@Sun.COM 
25909781SMoriah.Waterland@Sun.COM 	switch (retcode) {
25919781SMoriah.Waterland@Sun.COM 	    case  0:		/* successful */
25929781SMoriah.Waterland@Sun.COM 	    case 10:
25939781SMoriah.Waterland@Sun.COM 	    case 20:
25949781SMoriah.Waterland@Sun.COM 		break; /* empty case */
25959781SMoriah.Waterland@Sun.COM 
25969781SMoriah.Waterland@Sun.COM 	    case  1:		/* package operation failed (fatal error) */
25979781SMoriah.Waterland@Sun.COM 	    case 11:
25989781SMoriah.Waterland@Sun.COM 	    case 21:
25999781SMoriah.Waterland@Sun.COM 		failflag++;
26009781SMoriah.Waterland@Sun.COM 		interrupted++;
26019781SMoriah.Waterland@Sun.COM 		needconsult++;
26029781SMoriah.Waterland@Sun.COM 		break;
26039781SMoriah.Waterland@Sun.COM 
26049781SMoriah.Waterland@Sun.COM 	    case  2:		/* non-fatal error (warning) */
26059781SMoriah.Waterland@Sun.COM 	    case 12:
26069781SMoriah.Waterland@Sun.COM 	    case 22:
26079781SMoriah.Waterland@Sun.COM 		warnflag++;
26089781SMoriah.Waterland@Sun.COM 		interrupted++;
26099781SMoriah.Waterland@Sun.COM 		needconsult++;
26109781SMoriah.Waterland@Sun.COM 		break;
26119781SMoriah.Waterland@Sun.COM 
26129781SMoriah.Waterland@Sun.COM 	    case  3:		/* user selected quit; operation interrupted */
26139781SMoriah.Waterland@Sun.COM 	    case 13:
26149781SMoriah.Waterland@Sun.COM 	    case 23:
26159781SMoriah.Waterland@Sun.COM 		intrflag++;
26169781SMoriah.Waterland@Sun.COM 		interrupted++;
26179781SMoriah.Waterland@Sun.COM 		needconsult++;
26189781SMoriah.Waterland@Sun.COM 		break;
26199781SMoriah.Waterland@Sun.COM 
26209781SMoriah.Waterland@Sun.COM 	    case  4:		/* admin settings prevented operation */
26219781SMoriah.Waterland@Sun.COM 	    case 14:
26229781SMoriah.Waterland@Sun.COM 	    case 24:
26239781SMoriah.Waterland@Sun.COM 		admnflag++;
26249781SMoriah.Waterland@Sun.COM 		interrupted++;
26259781SMoriah.Waterland@Sun.COM 		break;
26269781SMoriah.Waterland@Sun.COM 
26279781SMoriah.Waterland@Sun.COM 	    case  5:		/* administration: interaction req (no -n) */
26289781SMoriah.Waterland@Sun.COM 	    case 15:
26299781SMoriah.Waterland@Sun.COM 	    case 25:
26309781SMoriah.Waterland@Sun.COM 		nullflag++;
26319781SMoriah.Waterland@Sun.COM 		interrupted++;
26329781SMoriah.Waterland@Sun.COM 		needconsult++;
26339781SMoriah.Waterland@Sun.COM 		break;
26349781SMoriah.Waterland@Sun.COM 
26359781SMoriah.Waterland@Sun.COM 	    default:
26369781SMoriah.Waterland@Sun.COM 		failflag++;
26379781SMoriah.Waterland@Sun.COM 		interrupted++;
26389781SMoriah.Waterland@Sun.COM 		needconsult++;
26399781SMoriah.Waterland@Sun.COM 		return;
26409781SMoriah.Waterland@Sun.COM 	}
26419781SMoriah.Waterland@Sun.COM 
26429781SMoriah.Waterland@Sun.COM 	if (retcode >= 20) {
26439781SMoriah.Waterland@Sun.COM 		ireboot++;
26449781SMoriah.Waterland@Sun.COM 	} else if (retcode >= 10) {
26459781SMoriah.Waterland@Sun.COM 		doreboot++;
26469781SMoriah.Waterland@Sun.COM 	}
26479781SMoriah.Waterland@Sun.COM }
26489781SMoriah.Waterland@Sun.COM 
26499781SMoriah.Waterland@Sun.COM static void
26509781SMoriah.Waterland@Sun.COM usage(void)
26519781SMoriah.Waterland@Sun.COM {
26529781SMoriah.Waterland@Sun.COM 	char *prog = get_prog_name();
26539781SMoriah.Waterland@Sun.COM 
26549781SMoriah.Waterland@Sun.COM 	if (askflag) {
26559781SMoriah.Waterland@Sun.COM 		(void) fprintf(stderr, ERR_USAGE_PKGASK, prog);
26569781SMoriah.Waterland@Sun.COM 	} else if (z_running_in_global_zone() == B_FALSE) {
26579781SMoriah.Waterland@Sun.COM 		(void) fprintf(stderr, ERR_USAGE_PKGADD_NONGLOBALZONE,
26589781SMoriah.Waterland@Sun.COM 			prog, prog);
26599781SMoriah.Waterland@Sun.COM 	} else {
26609781SMoriah.Waterland@Sun.COM 		(void) fprintf(stderr, ERR_USAGE_PKGADD_GLOBALZONE,
26619781SMoriah.Waterland@Sun.COM 			prog, prog);
26629781SMoriah.Waterland@Sun.COM 	}
26639781SMoriah.Waterland@Sun.COM }
26649781SMoriah.Waterland@Sun.COM 
26659781SMoriah.Waterland@Sun.COM /*
26669781SMoriah.Waterland@Sun.COM  * Name:	check_applicability
26679781SMoriah.Waterland@Sun.COM  * Description:	determine if a package is installable in this zone; that is,
26689781SMoriah.Waterland@Sun.COM  *		does the scope of install conflict with existing installation
26699781SMoriah.Waterland@Sun.COM  *		or can the package be installed
26709781SMoriah.Waterland@Sun.COM  * Arguments:	a_packageDir - [RO, *RO] - (char *)
26719781SMoriah.Waterland@Sun.COM  *			Pointer to string representing the directory where the
26729781SMoriah.Waterland@Sun.COM  *			package is located
26739781SMoriah.Waterland@Sun.COM  *		a_pkgInst - [RO, *RO] - (char *)
26749781SMoriah.Waterland@Sun.COM  *			Pointer to string representing the name of the package
26759781SMoriah.Waterland@Sun.COM  *			to check
26769781SMoriah.Waterland@Sun.COM  *		a_rootPath - [RO, *RO] - (char *)
26779781SMoriah.Waterland@Sun.COM  *			Pointer to string representing path to the root of the
26789781SMoriah.Waterland@Sun.COM  *			file system where the package is to be installed - this
26799781SMoriah.Waterland@Sun.COM  *			is usually the same as the "-R" argument to pkgadd
26809781SMoriah.Waterland@Sun.COM  *		a_flags - [RO, *RO] - (CAF_T)
26819781SMoriah.Waterland@Sun.COM  *			Flags set by the caller to indicate the conditions
26829781SMoriah.Waterland@Sun.COM  *			under which the package is to be installed:
26839781SMoriah.Waterland@Sun.COM  *				CAF_IN_GLOBAL_ZONE - in global zone
26849781SMoriah.Waterland@Sun.COM  *				CAF_SCOPE_GLOBAL - -G specified
26859781SMoriah.Waterland@Sun.COM  *				CAF_SCOPE_NONGLOBAL - -Z specified
26869781SMoriah.Waterland@Sun.COM  * Returns:	boolean_t
26879781SMoriah.Waterland@Sun.COM  *			B_TRUE - the package can be installed
26889781SMoriah.Waterland@Sun.COM  *			B_FALSE - the package can not be installed
26899781SMoriah.Waterland@Sun.COM  */
26909781SMoriah.Waterland@Sun.COM 
26919781SMoriah.Waterland@Sun.COM static boolean_t
26929781SMoriah.Waterland@Sun.COM check_applicability(char *a_packageDir, char *a_pkgInst, char *a_rootPath,
26939781SMoriah.Waterland@Sun.COM 	CAF_T a_flags)
26949781SMoriah.Waterland@Sun.COM {
26959781SMoriah.Waterland@Sun.COM 	FILE		*pkginfoFP;
26969781SMoriah.Waterland@Sun.COM 	FILE		*pkgmapFP;
26979781SMoriah.Waterland@Sun.COM 	boolean_t	all_zones;	/* pkg is "all zones" only */
26989781SMoriah.Waterland@Sun.COM 	boolean_t	in_gz_only;	/* pkg installed in global zone only */
26999781SMoriah.Waterland@Sun.COM 	boolean_t	is_hollow;	/* pkg is "hollow" */
27009781SMoriah.Waterland@Sun.COM 	boolean_t	pkg_installed;	/* pkg is installed */
27019781SMoriah.Waterland@Sun.COM 	boolean_t	this_zone;	/* pkg is "this zone" only */
27029781SMoriah.Waterland@Sun.COM 	boolean_t	reqfile_found = B_FALSE;
27039781SMoriah.Waterland@Sun.COM 	char		instPkg[PKGSIZ+1];	/* installed pkg instance nam */
27049781SMoriah.Waterland@Sun.COM 	char		instPkgPath[PATH_MAX];	/* installed pkg toplevel dir */
27059781SMoriah.Waterland@Sun.COM 	char		pkginfoPath[PATH_MAX];	/* pkg 2 install pkginfo file */
27069781SMoriah.Waterland@Sun.COM 	char		pkgmapPath[PATH_MAX];	/* pkg 2 install pkgmap file */
27079781SMoriah.Waterland@Sun.COM 	char		pkgpath[PATH_MAX];	/* pkg 2 install toplevel dir */
27089781SMoriah.Waterland@Sun.COM 	int		len;
27099781SMoriah.Waterland@Sun.COM 	char		line[LINE_MAX];
27109781SMoriah.Waterland@Sun.COM 
27119781SMoriah.Waterland@Sun.COM 	/* entry assertions */
27129781SMoriah.Waterland@Sun.COM 
27139781SMoriah.Waterland@Sun.COM 	assert(a_packageDir != (char *)NULL);
27149781SMoriah.Waterland@Sun.COM 	assert(*a_packageDir != '\0');
27159781SMoriah.Waterland@Sun.COM 	assert(a_pkgInst != (char *)NULL);
27169781SMoriah.Waterland@Sun.COM 	assert(*a_pkgInst != '\0');
27179781SMoriah.Waterland@Sun.COM 
27189781SMoriah.Waterland@Sun.COM 	/* normalize root path */
27199781SMoriah.Waterland@Sun.COM 
27209781SMoriah.Waterland@Sun.COM 	if (a_rootPath == (char *)NULL) {
27219781SMoriah.Waterland@Sun.COM 		a_rootPath = "";
27229781SMoriah.Waterland@Sun.COM 	}
27239781SMoriah.Waterland@Sun.COM 
27249781SMoriah.Waterland@Sun.COM 	/* entry debugging info */
27259781SMoriah.Waterland@Sun.COM 
27269781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_CHECKAPP_ENTRY);
27279781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_CHECKAPP_ARGS, a_pkgInst, a_packageDir, a_rootPath);
27289781SMoriah.Waterland@Sun.COM 
27299781SMoriah.Waterland@Sun.COM 	/*
27309781SMoriah.Waterland@Sun.COM 	 * calculate paths to various objects
27319781SMoriah.Waterland@Sun.COM 	 */
27329781SMoriah.Waterland@Sun.COM 
27339781SMoriah.Waterland@Sun.COM 	/* path to package to be installed top level (main) directory */
27349781SMoriah.Waterland@Sun.COM 
27359781SMoriah.Waterland@Sun.COM 	len = snprintf(pkgpath, sizeof (pkgpath), "%s/%s", a_packageDir,
27369781SMoriah.Waterland@Sun.COM 			a_pkgInst);
27379781SMoriah.Waterland@Sun.COM 	if (len > sizeof (pkgpath)) {
27389781SMoriah.Waterland@Sun.COM 		progerr(ERR_CREATE_PATH_2, a_packageDir, a_pkgInst);
27399781SMoriah.Waterland@Sun.COM 		return (B_FALSE);
27409781SMoriah.Waterland@Sun.COM 	}
27419781SMoriah.Waterland@Sun.COM 
27429781SMoriah.Waterland@Sun.COM 	/* error if package top level directory does not exist */
27439781SMoriah.Waterland@Sun.COM 
27449781SMoriah.Waterland@Sun.COM 	if (isdir(pkgpath) != 0) {
27459781SMoriah.Waterland@Sun.COM 		progerr(ERR_NO_PKGDIR, pkgpath, a_pkgInst, strerror(errno));
27469781SMoriah.Waterland@Sun.COM 		return (B_FALSE);
27479781SMoriah.Waterland@Sun.COM 	}
27489781SMoriah.Waterland@Sun.COM 
27499781SMoriah.Waterland@Sun.COM 	/* path to pkginfo file within the package to be installed */
27509781SMoriah.Waterland@Sun.COM 
27519781SMoriah.Waterland@Sun.COM 	len = snprintf(pkginfoPath, sizeof (pkginfoPath), "%s/pkginfo",
27529781SMoriah.Waterland@Sun.COM 			pkgpath);
27539781SMoriah.Waterland@Sun.COM 	if (len > sizeof (pkginfoPath)) {
27549781SMoriah.Waterland@Sun.COM 		progerr(ERR_CREATE_PATH_2, pkgpath, "pkginfo");
27559781SMoriah.Waterland@Sun.COM 		return (B_FALSE);
27569781SMoriah.Waterland@Sun.COM 	}
27579781SMoriah.Waterland@Sun.COM 
27589781SMoriah.Waterland@Sun.COM 	/* path to highest instance of package currently installed */
27599781SMoriah.Waterland@Sun.COM 
27609781SMoriah.Waterland@Sun.COM 	pkgLocateHighestInst(instPkgPath, sizeof (instPkgPath),
27619781SMoriah.Waterland@Sun.COM 		instPkg, sizeof (instPkg), a_rootPath, a_pkgInst);
27629781SMoriah.Waterland@Sun.COM 
27639781SMoriah.Waterland@Sun.COM 	/*
27649781SMoriah.Waterland@Sun.COM 	 * gather information from this package's pkginfo file
27659781SMoriah.Waterland@Sun.COM 	 */
27669781SMoriah.Waterland@Sun.COM 
27679781SMoriah.Waterland@Sun.COM 	pkginfoFP = fopen(pkginfoPath, "r");
27689781SMoriah.Waterland@Sun.COM 
27699781SMoriah.Waterland@Sun.COM 	if (pkginfoFP == (FILE *)NULL) {
27709781SMoriah.Waterland@Sun.COM 		progerr(ERR_NO_PKG_INFOFILE, a_pkgInst, pkginfoPath,
27719781SMoriah.Waterland@Sun.COM 							strerror(errno));
27729781SMoriah.Waterland@Sun.COM 		return (B_FALSE);
27739781SMoriah.Waterland@Sun.COM 	}
27749781SMoriah.Waterland@Sun.COM 
27759781SMoriah.Waterland@Sun.COM 	/* determine "HOLLOW" setting for this package */
27769781SMoriah.Waterland@Sun.COM 
27779781SMoriah.Waterland@Sun.COM 	is_hollow = pkginfoParamTruth(pkginfoFP, PKG_HOLLOW_VARIABLE,
27789781SMoriah.Waterland@Sun.COM 			"true", B_FALSE);
27799781SMoriah.Waterland@Sun.COM 
27809781SMoriah.Waterland@Sun.COM 	/* determine "ALLZONES" setting for this package */
27819781SMoriah.Waterland@Sun.COM 
27829781SMoriah.Waterland@Sun.COM 	all_zones = pkginfoParamTruth(pkginfoFP, PKG_ALLZONES_VARIABLE,
27839781SMoriah.Waterland@Sun.COM 			"true", B_FALSE);
27849781SMoriah.Waterland@Sun.COM 
27859781SMoriah.Waterland@Sun.COM 	/* determine "THISZONE" setting for this package */
27869781SMoriah.Waterland@Sun.COM 
27879781SMoriah.Waterland@Sun.COM 	this_zone = pkginfoParamTruth(pkginfoFP, PKG_THISZONE_VARIABLE,
27889781SMoriah.Waterland@Sun.COM 			"true", B_FALSE);
27899781SMoriah.Waterland@Sun.COM 
27909781SMoriah.Waterland@Sun.COM 	/* close pkginfo file */
27919781SMoriah.Waterland@Sun.COM 
27929781SMoriah.Waterland@Sun.COM 	(void) fclose(pkginfoFP);
27939781SMoriah.Waterland@Sun.COM 
27949781SMoriah.Waterland@Sun.COM 	/*
27959781SMoriah.Waterland@Sun.COM 	 * If request file is not found, it may be in the datastream which
27969781SMoriah.Waterland@Sun.COM 	 * is not yet unpacked. Check in the pkgmap file.
27979781SMoriah.Waterland@Sun.COM 	 */
27989781SMoriah.Waterland@Sun.COM 	if (isfile(pkgpath, REQUEST_FILE) != 0) {
27999781SMoriah.Waterland@Sun.COM 
28009781SMoriah.Waterland@Sun.COM 		/* path to pkgmap file within the package to be installed */
28019781SMoriah.Waterland@Sun.COM 		(void) snprintf(pkgmapPath, sizeof (pkgmapPath), "%s/pkgmap",
28029781SMoriah.Waterland@Sun.COM 		    pkgpath);
28039781SMoriah.Waterland@Sun.COM 
28049781SMoriah.Waterland@Sun.COM 		pkgmapFP = fopen(pkgmapPath, "r");
28059781SMoriah.Waterland@Sun.COM 
28069781SMoriah.Waterland@Sun.COM 		if (pkgmapFP == NULL) {
28079781SMoriah.Waterland@Sun.COM 			progerr(ERR_NO_PKG_MAPFILE, a_pkgInst,
28089781SMoriah.Waterland@Sun.COM 			    pkgmapPath, strerror(errno));
28099781SMoriah.Waterland@Sun.COM 			return (B_FALSE);
28109781SMoriah.Waterland@Sun.COM 		}
28119781SMoriah.Waterland@Sun.COM 
28129781SMoriah.Waterland@Sun.COM 		while (fgets(line, LINE_MAX, pkgmapFP) != NULL) {
28139781SMoriah.Waterland@Sun.COM 			if (strstr(line, " i request") != NULL) {
28149781SMoriah.Waterland@Sun.COM 				reqfile_found = B_TRUE;
28159781SMoriah.Waterland@Sun.COM 				break;
28169781SMoriah.Waterland@Sun.COM 			}
28179781SMoriah.Waterland@Sun.COM 		}
28189781SMoriah.Waterland@Sun.COM 		(void) fclose(pkgmapFP);
28199781SMoriah.Waterland@Sun.COM 	} else {
28209781SMoriah.Waterland@Sun.COM 		reqfile_found = B_TRUE;
28219781SMoriah.Waterland@Sun.COM 	}
28229781SMoriah.Waterland@Sun.COM 
28239781SMoriah.Waterland@Sun.COM 	/*
28249781SMoriah.Waterland@Sun.COM 	 * If this package is not marked for installation in this zone only,
28259781SMoriah.Waterland@Sun.COM 	 * check to see if this package has a request script. If this package
28269781SMoriah.Waterland@Sun.COM 	 * does have a request script, then mark the package for installation
28279781SMoriah.Waterland@Sun.COM 	 * in this zone only. Any package with a request script cannot be
28289781SMoriah.Waterland@Sun.COM 	 * installed outside of the zone the pkgadd command is being run in,
28299781SMoriah.Waterland@Sun.COM 	 * nor can such a package be installed as part of a new zone install.
28309781SMoriah.Waterland@Sun.COM 	 * A new zone install must be non-interactive, which is required
28319781SMoriah.Waterland@Sun.COM 	 * by all packages integrated into the Solaris WOS.
28329781SMoriah.Waterland@Sun.COM 	 */
28339781SMoriah.Waterland@Sun.COM 
28349781SMoriah.Waterland@Sun.COM 	if ((!this_zone) && (reqfile_found)) {
28359781SMoriah.Waterland@Sun.COM 		if (a_flags & CAF_IN_GLOBAL_ZONE) {
28369781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_CHECKAPP_THISZONE_REQUEST, a_pkgInst);
28379781SMoriah.Waterland@Sun.COM 		}
28389781SMoriah.Waterland@Sun.COM 		this_zone = B_TRUE;
28399781SMoriah.Waterland@Sun.COM 	}
28409781SMoriah.Waterland@Sun.COM 
28419781SMoriah.Waterland@Sun.COM 	/*
28429781SMoriah.Waterland@Sun.COM 	 * If this package is already installed, see if the current installation
28439781SMoriah.Waterland@Sun.COM 	 * of the package has a request file - if it does, then act as though
28449781SMoriah.Waterland@Sun.COM 	 * the current package to be added has a request file - install the
28459781SMoriah.Waterland@Sun.COM 	 * package in the current zone only.
28469781SMoriah.Waterland@Sun.COM 	 */
28479781SMoriah.Waterland@Sun.COM 
28489781SMoriah.Waterland@Sun.COM 	if ((!this_zone) && (instPkgPath[0] != '\0') &&
28499781SMoriah.Waterland@Sun.COM 		(isfile(instPkgPath, REQUEST_FILE) == 0)) {
28509781SMoriah.Waterland@Sun.COM 		if (a_flags & CAF_IN_GLOBAL_ZONE) {
28519781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_CHECKAPP_THISZONE_INSTREQ,
28529781SMoriah.Waterland@Sun.COM 				a_pkgInst, instPkg);
28539781SMoriah.Waterland@Sun.COM 		}
28549781SMoriah.Waterland@Sun.COM 		this_zone = B_TRUE;
28559781SMoriah.Waterland@Sun.COM 	}
28569781SMoriah.Waterland@Sun.COM 
28579781SMoriah.Waterland@Sun.COM 	/* gather information from the global zone only file */
28589781SMoriah.Waterland@Sun.COM 
28599781SMoriah.Waterland@Sun.COM 	in_gz_only = B_FALSE;
28609781SMoriah.Waterland@Sun.COM 	if (a_flags & CAF_IN_GLOBAL_ZONE) {
28619781SMoriah.Waterland@Sun.COM 		in_gz_only = pkgIsPkgInGzOnly(a_rootPath, a_pkgInst);
28629781SMoriah.Waterland@Sun.COM 	}
28639781SMoriah.Waterland@Sun.COM 
28649781SMoriah.Waterland@Sun.COM 	/* determine if this package is currently installed */
28659781SMoriah.Waterland@Sun.COM 
28669781SMoriah.Waterland@Sun.COM 	pkg_installed = pkginfoIsPkgInstalled((struct pkginfo **)NULL,
28679781SMoriah.Waterland@Sun.COM 								a_pkgInst);
28689781SMoriah.Waterland@Sun.COM 
28699781SMoriah.Waterland@Sun.COM 	/*
28709781SMoriah.Waterland@Sun.COM 	 * verify package applicability based on information gathered,
28719781SMoriah.Waterland@Sun.COM 	 * and validate the three SUNW_PKG_ options:
28729781SMoriah.Waterland@Sun.COM 	 *
28739781SMoriah.Waterland@Sun.COM 	 * -----------|--------------|-------------|-------------|-----------
28749781SMoriah.Waterland@Sun.COM 	 * - - - - - -| GLOBAL ZONE -| GLOBAL ZONE | LOCAL ZONE	 | LOCAL ZONE
28759781SMoriah.Waterland@Sun.COM 	 * - - - - - -|	- - pkgadd - | pkgadd -G   | pkgadd	 | pkgadd -G
28769781SMoriah.Waterland@Sun.COM 	 * ----1------|--------------|-------------|-------------|------------
28779781SMoriah.Waterland@Sun.COM 	 * ALLZONES f | add to gz    | add to gz   | add to ls	 | add to ls
28789781SMoriah.Waterland@Sun.COM 	 * HOLLOW   f | current lz   | not to curr | only - - - -| only - - -
28799781SMoriah.Waterland@Sun.COM 	 * THISZONE f | futr lz - - -| or futr lz  | - - - - - - | - - - - - -
28809781SMoriah.Waterland@Sun.COM 	 * ----2------|--------------|-------------|-------------|------------
28819781SMoriah.Waterland@Sun.COM 	 * ALLZONES T | add to gz    | operation   | operation	 | operation
28829781SMoriah.Waterland@Sun.COM 	 * HOLLOW   f | current lz   | not allowed | not allowed | not allowed
28839781SMoriah.Waterland@Sun.COM 	 * THISZONE f | future lz    | - - - - - - | - - - - - - | - - - - - -
28849781SMoriah.Waterland@Sun.COM 	 * ----3------|--------------|-------------|-------------|------------
28859781SMoriah.Waterland@Sun.COM 	 * ALLZONES T | add to gz    | operation   | operation	 | operation
28869781SMoriah.Waterland@Sun.COM 	 * HOLLOW   T | pkg db only  | not allowed | not allowed | not allowed
28879781SMoriah.Waterland@Sun.COM 	 * THISZONE f | curr/futr lz | - - - - - - | - - - - - - | - - - - - -
28889781SMoriah.Waterland@Sun.COM 	 * ----4------|--------------|-------------|-------------|------------
28899781SMoriah.Waterland@Sun.COM 	 * ALLZONES T | bad option   | bad option  | bad option	 | bad option
28909781SMoriah.Waterland@Sun.COM 	 * HOLLOW   * | combo - - - -| combo - - - | combo - - - | combo - -
28919781SMoriah.Waterland@Sun.COM 	 * THISZONE T |	- - - - - - -|- - - - - - -|- - - - - - -|- - - - - -
28929781SMoriah.Waterland@Sun.COM 	 * ----5------|--------------|-------------|-------------|------------
28939781SMoriah.Waterland@Sun.COM 	 * ALLZONES f | bad option   | bad option  | bad option	 | bad option
28949781SMoriah.Waterland@Sun.COM 	 * HOLLOW   T | combo - - - -| combo - - - | combo - - - | combo - - -
28959781SMoriah.Waterland@Sun.COM 	 * THISZONE * | - - - - - - -| - - - - - - | - - - - - - | - - - - - -
28969781SMoriah.Waterland@Sun.COM 	 * ----6------|--------------|-------------|-------------|------------
28979781SMoriah.Waterland@Sun.COM 	 * ALLZONES f | add to gz    | add to gz   | add to lz	 | add to lz
28989781SMoriah.Waterland@Sun.COM 	 * HOLLOW   f | not current  | not current | only - - -	 | only - - -
28999781SMoriah.Waterland@Sun.COM 	 * THISZONE T | or future lz | or futr lz  | - - - - - - | - - - - - -
29009781SMoriah.Waterland@Sun.COM 	 * -----------|--------------|-------------|-------------|-----------
29019781SMoriah.Waterland@Sun.COM 	 */
29029781SMoriah.Waterland@Sun.COM 
29039781SMoriah.Waterland@Sun.COM 	/* pkg "all zones" && "this zone" (#4) */
29049781SMoriah.Waterland@Sun.COM 
29059781SMoriah.Waterland@Sun.COM 	if (all_zones && this_zone) {
29069781SMoriah.Waterland@Sun.COM 		progerr(ERR_ALLZONES_AND_THISZONE, a_pkgInst,
29079781SMoriah.Waterland@Sun.COM 			PKG_ALLZONES_VARIABLE, PKG_THISZONE_VARIABLE);
29089781SMoriah.Waterland@Sun.COM 		return (B_FALSE);
29099781SMoriah.Waterland@Sun.COM 	}
29109781SMoriah.Waterland@Sun.COM 
29119781SMoriah.Waterland@Sun.COM 	/* pkg "!all zones" && "hollow" (#5) */
29129781SMoriah.Waterland@Sun.COM 
29139781SMoriah.Waterland@Sun.COM 	if ((!all_zones) && is_hollow) {
29149781SMoriah.Waterland@Sun.COM 		progerr(ERR_NOW_ALLZONES_AND_HOLLOW, a_pkgInst,
29159781SMoriah.Waterland@Sun.COM 			PKG_ALLZONES_VARIABLE, PKG_HOLLOW_VARIABLE);
29169781SMoriah.Waterland@Sun.COM 		return (B_FALSE);
29179781SMoriah.Waterland@Sun.COM 	}
29189781SMoriah.Waterland@Sun.COM 
29199781SMoriah.Waterland@Sun.COM 	/* pkg ALLZONES=true && -Z specified */
29209781SMoriah.Waterland@Sun.COM 
29219781SMoriah.Waterland@Sun.COM 	if (all_zones && (a_flags & CAF_SCOPE_NONGLOBAL)) {
29229781SMoriah.Waterland@Sun.COM 		progerr(ERR_ALLZONES_AND_Z_USED, a_pkgInst);
29239781SMoriah.Waterland@Sun.COM 		return (B_FALSE);
29249781SMoriah.Waterland@Sun.COM 	}
29259781SMoriah.Waterland@Sun.COM 
29269781SMoriah.Waterland@Sun.COM 	/* pkg ALLZONES=true & not running in global zone (#2/#3) */
29279781SMoriah.Waterland@Sun.COM 
29289781SMoriah.Waterland@Sun.COM 	if (all_zones && (!(a_flags & CAF_IN_GLOBAL_ZONE))) {
29299781SMoriah.Waterland@Sun.COM 		progerr(ERR_ALLZONES_AND_IN_LZ, a_pkgInst);
29309781SMoriah.Waterland@Sun.COM 		return (B_FALSE);
29319781SMoriah.Waterland@Sun.COM 	}
29329781SMoriah.Waterland@Sun.COM 
29339781SMoriah.Waterland@Sun.COM 	/* pkg "in gz only" & pkg "NOT installed" */
29349781SMoriah.Waterland@Sun.COM 
29359781SMoriah.Waterland@Sun.COM 	if (in_gz_only && (!pkg_installed)) {
29369781SMoriah.Waterland@Sun.COM 		/* MAKE A WARNING */
29379781SMoriah.Waterland@Sun.COM 		echo(ERR_IN_GZ_AND_NOT_INSTALLED, a_pkgInst,
29389781SMoriah.Waterland@Sun.COM 			pkgGetGzOnlyPath());
29399781SMoriah.Waterland@Sun.COM 	}
29409781SMoriah.Waterland@Sun.COM 
29419781SMoriah.Waterland@Sun.COM 	/* pkg ALLZONES=true & pkg "in gz only" & pkg "is installed" */
29429781SMoriah.Waterland@Sun.COM 
29439781SMoriah.Waterland@Sun.COM 	if (all_zones && in_gz_only && pkg_installed) {
29449781SMoriah.Waterland@Sun.COM 		progerr(ERR_IN_GZ_AND_ALLZONES_AND_INSTALLED, a_pkgInst);
29459781SMoriah.Waterland@Sun.COM 		return (B_FALSE);
29469781SMoriah.Waterland@Sun.COM 	}
29479781SMoriah.Waterland@Sun.COM 
29489781SMoriah.Waterland@Sun.COM 	/* pkg ALLZONES=true && -G specified (#2/#3) */
29499781SMoriah.Waterland@Sun.COM 
29509781SMoriah.Waterland@Sun.COM 	if (all_zones && (a_flags & CAF_SCOPE_GLOBAL)) {
29519781SMoriah.Waterland@Sun.COM 		progerr(ERR_ALLZONES_AND_G_USED, a_pkgInst);
29529781SMoriah.Waterland@Sun.COM 		return (B_FALSE);
29539781SMoriah.Waterland@Sun.COM 	}
29549781SMoriah.Waterland@Sun.COM 
29559781SMoriah.Waterland@Sun.COM 	/* pkg "!this zone" && "in gz only" & -G not specified */
29569781SMoriah.Waterland@Sun.COM 
29579781SMoriah.Waterland@Sun.COM 	if ((!this_zone) && in_gz_only && (!(a_flags & CAF_SCOPE_GLOBAL))) {
29589781SMoriah.Waterland@Sun.COM 		progerr(ERR_IN_GZ_AND_NO_G_USED, a_pkgInst);
29599781SMoriah.Waterland@Sun.COM 		return (B_FALSE);
29609781SMoriah.Waterland@Sun.COM 	}
29619781SMoriah.Waterland@Sun.COM 
29629781SMoriah.Waterland@Sun.COM 	/* pkg "NOT in gz only" & -Z specified */
29639781SMoriah.Waterland@Sun.COM 
29649781SMoriah.Waterland@Sun.COM 	if ((!in_gz_only) && (a_flags & CAF_SCOPE_NONGLOBAL)) {
29659781SMoriah.Waterland@Sun.COM 		progerr(ERR_NOT_IN_GZ_AND_Z_USED, a_pkgInst);
29669781SMoriah.Waterland@Sun.COM 		return (B_FALSE);
29679781SMoriah.Waterland@Sun.COM 	}
29689781SMoriah.Waterland@Sun.COM 
29699781SMoriah.Waterland@Sun.COM 	/* pkg "this zone" && -Z specified */
29709781SMoriah.Waterland@Sun.COM 
29719781SMoriah.Waterland@Sun.COM 	if (this_zone && (a_flags & CAF_SCOPE_NONGLOBAL)) {
29729781SMoriah.Waterland@Sun.COM 		progerr(ERR_THISZONE_AND_Z_USED, PKG_THISZONE_VARIABLE,
29739781SMoriah.Waterland@Sun.COM 			a_pkgInst);
29749781SMoriah.Waterland@Sun.COM 		return (B_FALSE);
29759781SMoriah.Waterland@Sun.COM 	}
29769781SMoriah.Waterland@Sun.COM 
29779781SMoriah.Waterland@Sun.COM 	/*
29789781SMoriah.Waterland@Sun.COM 	 * If this package is marked 'this zone only', then mark the package
29799781SMoriah.Waterland@Sun.COM 	 * as "add to this zone only". This is referenced by the various
29809781SMoriah.Waterland@Sun.COM 	 * add_package_... functions to determine if the package should be
29819781SMoriah.Waterland@Sun.COM 	 * added to the current zone, or to all zones, depending on the
29829781SMoriah.Waterland@Sun.COM 	 * zone in which the command is being run.
29839781SMoriah.Waterland@Sun.COM 	 */
29849781SMoriah.Waterland@Sun.COM 
29859781SMoriah.Waterland@Sun.COM 	if (this_zone) {
29869781SMoriah.Waterland@Sun.COM 		pkgAddThisZonePackage(a_pkgInst);
29879781SMoriah.Waterland@Sun.COM 	}
29889781SMoriah.Waterland@Sun.COM 
29899781SMoriah.Waterland@Sun.COM 	return (B_TRUE);
29909781SMoriah.Waterland@Sun.COM }
29919781SMoriah.Waterland@Sun.COM 
29929781SMoriah.Waterland@Sun.COM /*
29939781SMoriah.Waterland@Sun.COM  * Name:	create_zone_adminfile
29949781SMoriah.Waterland@Sun.COM  * Description: Given a zone temporary directory and optionally an existing
29959781SMoriah.Waterland@Sun.COM  *		administration file, generate an administration file that
29969781SMoriah.Waterland@Sun.COM  *		can be used to perform "non-interactive" operations in a
29979781SMoriah.Waterland@Sun.COM  *		non-global zone.
29989781SMoriah.Waterland@Sun.COM  * Arguments:	r_zoneAdminFile - pointer to handle that will contain a
29999781SMoriah.Waterland@Sun.COM  *			string representing the path to the temporary
30009781SMoriah.Waterland@Sun.COM  *			administration file created - this must be NULL
30019781SMoriah.Waterland@Sun.COM  *			before the first call to this function - on
30029781SMoriah.Waterland@Sun.COM  *			subsequent calls if the pointer is NOT null then
30039781SMoriah.Waterland@Sun.COM  *			the existing string will NOT be overwritten.
30049781SMoriah.Waterland@Sun.COM  *		a_zoneTempDir - pointer to string representing the path
30059781SMoriah.Waterland@Sun.COM  *			to the zone temporary directory to create the
30069781SMoriah.Waterland@Sun.COM  *			temporary administration file in
30079781SMoriah.Waterland@Sun.COM  *		a_admnfile - pointer to string representing the path to
30089781SMoriah.Waterland@Sun.COM  *			an existing "user" administration file - the
30099781SMoriah.Waterland@Sun.COM  *			administration file created will contain the
30109781SMoriah.Waterland@Sun.COM  *			settings contained in this file, modified as
30119781SMoriah.Waterland@Sun.COM  *			appropriate to supress any interaction;
30129781SMoriah.Waterland@Sun.COM  *			If this is == NULL then the administration file
30139781SMoriah.Waterland@Sun.COM  *			created will not contain any extra settings
30149781SMoriah.Waterland@Sun.COM  * Returns:	void
30159781SMoriah.Waterland@Sun.COM  * NOTE:	Any string returned is placed in new storage for the
30169781SMoriah.Waterland@Sun.COM  *		calling method. The caller must use 'free' to dispose
30179781SMoriah.Waterland@Sun.COM  *		of the storage once the string is no longer needed.
30189781SMoriah.Waterland@Sun.COM  * NOTE:	On any error this function will call 'quit(1)'
30199781SMoriah.Waterland@Sun.COM  */
30209781SMoriah.Waterland@Sun.COM 
30219781SMoriah.Waterland@Sun.COM static void
30229781SMoriah.Waterland@Sun.COM create_zone_adminfile(char **r_zoneAdminFile, char *a_zoneTempDir,
30239781SMoriah.Waterland@Sun.COM 	char *a_admnfile)
30249781SMoriah.Waterland@Sun.COM {
30259781SMoriah.Waterland@Sun.COM 	boolean_t	b;
30269781SMoriah.Waterland@Sun.COM 
30279781SMoriah.Waterland@Sun.COM 	/* entry assertions */
30289781SMoriah.Waterland@Sun.COM 
30299781SMoriah.Waterland@Sun.COM 	assert(r_zoneAdminFile != (char **)NULL);
30309781SMoriah.Waterland@Sun.COM 	assert(a_zoneTempDir != (char *)NULL);
30319781SMoriah.Waterland@Sun.COM 	assert(*a_zoneTempDir != '\0');
30329781SMoriah.Waterland@Sun.COM 
30339781SMoriah.Waterland@Sun.COM 	/* entry debugging info */
30349781SMoriah.Waterland@Sun.COM 
30359781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_CREATE_ZONE_ADMINFILE, a_zoneTempDir, PSTR(a_admnfile));
30369781SMoriah.Waterland@Sun.COM 
30379781SMoriah.Waterland@Sun.COM 	/* if temporary name already exists, do not overwrite */
30389781SMoriah.Waterland@Sun.COM 
30399781SMoriah.Waterland@Sun.COM 	if (*r_zoneAdminFile != (char *)NULL) {
30409781SMoriah.Waterland@Sun.COM 		return;
30419781SMoriah.Waterland@Sun.COM 	}
30429781SMoriah.Waterland@Sun.COM 
30439781SMoriah.Waterland@Sun.COM 	/* create temporary name */
30449781SMoriah.Waterland@Sun.COM 
30459781SMoriah.Waterland@Sun.COM 	*r_zoneAdminFile = tempnam(a_zoneTempDir, "zadmn");
30469781SMoriah.Waterland@Sun.COM 	b = z_create_zone_admin_file(*r_zoneAdminFile, a_admnfile);
30479781SMoriah.Waterland@Sun.COM 	if (b == B_FALSE) {
30489781SMoriah.Waterland@Sun.COM 		progerr(ERR_CREATE_TMPADMIN, *r_zoneAdminFile,
30499781SMoriah.Waterland@Sun.COM 			strerror(errno));
30509781SMoriah.Waterland@Sun.COM 		quit(1);
30519781SMoriah.Waterland@Sun.COM 		/* NOTREACHED */
30529781SMoriah.Waterland@Sun.COM 	}
30539781SMoriah.Waterland@Sun.COM 
30549781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_CREATED_ZONE_ADMINFILE, *r_zoneAdminFile);
30559781SMoriah.Waterland@Sun.COM }
30569781SMoriah.Waterland@Sun.COM 
30579781SMoriah.Waterland@Sun.COM /*
30589781SMoriah.Waterland@Sun.COM  * Name:	create_zone_tempdir
30599781SMoriah.Waterland@Sun.COM  * Description: Given a system temporary directory, create a "zone" specific
30609781SMoriah.Waterland@Sun.COM  *		temporary directory and return the path to the directory
30619781SMoriah.Waterland@Sun.COM  *		created.
30629781SMoriah.Waterland@Sun.COM  * Arguments:	r_zoneTempDir - pointer to handle that will contain a
30639781SMoriah.Waterland@Sun.COM  *			string representing the path to the temporary
30649781SMoriah.Waterland@Sun.COM  *			directory created - this must be NULL before the
30659781SMoriah.Waterland@Sun.COM  *			first call to this function - on subsequent calls
30669781SMoriah.Waterland@Sun.COM  *			if the pointer is NOT null then the existing string
30679781SMoriah.Waterland@Sun.COM  *			will NOT be overwritten.
30689781SMoriah.Waterland@Sun.COM  *		a_zoneTempDir - pointer to string representing the path
30699781SMoriah.Waterland@Sun.COM  *			to the system temporary directory to create the
30709781SMoriah.Waterland@Sun.COM  *			temporary zone directory in
30719781SMoriah.Waterland@Sun.COM  * Returns:	void
30729781SMoriah.Waterland@Sun.COM  * NOTE:	Any string returned is placed in new storage for the
30739781SMoriah.Waterland@Sun.COM  *		calling method. The caller must use 'free' to dispose
30749781SMoriah.Waterland@Sun.COM  *		of the storage once the string is no longer needed.
30759781SMoriah.Waterland@Sun.COM  * NOTE:	On any error this function will call 'quit(1)'
30769781SMoriah.Waterland@Sun.COM  * NOTE:	This function calls "quitSetZoneTmpdir" on success to
30779781SMoriah.Waterland@Sun.COM  *		register the directory created with quit() so that the
30789781SMoriah.Waterland@Sun.COM  *		directory will be automatically deleted on exit.
30799781SMoriah.Waterland@Sun.COM  */
30809781SMoriah.Waterland@Sun.COM 
30819781SMoriah.Waterland@Sun.COM static void
30829781SMoriah.Waterland@Sun.COM create_zone_tempdir(char **r_zoneTempDir, char *a_tmpdir)
30839781SMoriah.Waterland@Sun.COM {
30849781SMoriah.Waterland@Sun.COM 	boolean_t	b;
30859781SMoriah.Waterland@Sun.COM 
30869781SMoriah.Waterland@Sun.COM 	/* entry assertions */
30879781SMoriah.Waterland@Sun.COM 
30889781SMoriah.Waterland@Sun.COM 	assert(r_zoneTempDir != (char **)NULL);
30899781SMoriah.Waterland@Sun.COM 	assert(a_tmpdir != (char *)NULL);
30909781SMoriah.Waterland@Sun.COM 	assert(*a_tmpdir != '\0');
30919781SMoriah.Waterland@Sun.COM 
30929781SMoriah.Waterland@Sun.COM 	/* entry debugging info */
30939781SMoriah.Waterland@Sun.COM 
30949781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_CREATE_ZONE_TEMPDIR, a_tmpdir);
30959781SMoriah.Waterland@Sun.COM 
30969781SMoriah.Waterland@Sun.COM 	/* if temporary directory already exists, do not overwrite */
30979781SMoriah.Waterland@Sun.COM 
30989781SMoriah.Waterland@Sun.COM 	if (*r_zoneTempDir != (char *)NULL) {
30999781SMoriah.Waterland@Sun.COM 		return;
31009781SMoriah.Waterland@Sun.COM 	}
31019781SMoriah.Waterland@Sun.COM 
31029781SMoriah.Waterland@Sun.COM 	/* create temporary directory */
31039781SMoriah.Waterland@Sun.COM 
31049781SMoriah.Waterland@Sun.COM 	b = setup_temporary_directory(r_zoneTempDir, a_tmpdir, "ztemp");
31059781SMoriah.Waterland@Sun.COM 	if (b == B_FALSE) {
31069781SMoriah.Waterland@Sun.COM 		progerr(ERR_ZONETEMPDIR, a_tmpdir, strerror(errno));
31079781SMoriah.Waterland@Sun.COM 		quit(1);
31089781SMoriah.Waterland@Sun.COM 		/* NOTREACHED */
31099781SMoriah.Waterland@Sun.COM 	}
31109781SMoriah.Waterland@Sun.COM 
31119781SMoriah.Waterland@Sun.COM 	/* register with quit() so directory is removed on exit */
31129781SMoriah.Waterland@Sun.COM 
31139781SMoriah.Waterland@Sun.COM 	quitSetZoneTmpdir(*r_zoneTempDir);
31149781SMoriah.Waterland@Sun.COM 
31159781SMoriah.Waterland@Sun.COM 	/* exit debugging info */
31169781SMoriah.Waterland@Sun.COM 
31179781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_CREATED_ZONE_TEMPDIR, *r_zoneTempDir);
31189781SMoriah.Waterland@Sun.COM }
31199781SMoriah.Waterland@Sun.COM 
31209781SMoriah.Waterland@Sun.COM /*
31219781SMoriah.Waterland@Sun.COM  * Name:	continue_installation
31229781SMoriah.Waterland@Sun.COM  * Description: Called from within a loop that is installing packages,
31239781SMoriah.Waterland@Sun.COM  *		this function examines various global variables and decides
31249781SMoriah.Waterland@Sun.COM  *		whether or not to ask an appropriate question, and wait for
31259781SMoriah.Waterland@Sun.COM  *		and appropriate reply.
31269781SMoriah.Waterland@Sun.COM  * Arguments:	<<global variables>>
31279781SMoriah.Waterland@Sun.COM  * Returns:	B_TRUE - continue processing with next package
31289781SMoriah.Waterland@Sun.COM  *		B_FALSE - do not continue processing with next package
31299781SMoriah.Waterland@Sun.COM  */
31309781SMoriah.Waterland@Sun.COM 
31319781SMoriah.Waterland@Sun.COM static boolean_t
31329781SMoriah.Waterland@Sun.COM continue_installation(void)
31339781SMoriah.Waterland@Sun.COM {
31349781SMoriah.Waterland@Sun.COM 	char	ans[MAX_INPUT];
31359781SMoriah.Waterland@Sun.COM 	int	n;
31369781SMoriah.Waterland@Sun.COM 
31379781SMoriah.Waterland@Sun.COM 	/* return TRUE if not interrupted */
31389781SMoriah.Waterland@Sun.COM 
31399781SMoriah.Waterland@Sun.COM 	if (!interrupted) {
31409781SMoriah.Waterland@Sun.COM 		return (B_TRUE);
31419781SMoriah.Waterland@Sun.COM 	}
31429781SMoriah.Waterland@Sun.COM 
31439781SMoriah.Waterland@Sun.COM 	/*
31449781SMoriah.Waterland@Sun.COM 	 * process interrupted - determine whether or not to continue
31459781SMoriah.Waterland@Sun.COM 	 */
31469781SMoriah.Waterland@Sun.COM 
31479781SMoriah.Waterland@Sun.COM 	/* output appropriate interrupted message */
31489781SMoriah.Waterland@Sun.COM 
31499781SMoriah.Waterland@Sun.COM 	if (askflag) {
31509781SMoriah.Waterland@Sun.COM 		echo(npkgs == 1 ? MSG_1MORE_PROC : MSG_MORE_PROC, npkgs);
31519781SMoriah.Waterland@Sun.COM 	} else {
31529781SMoriah.Waterland@Sun.COM 		echo(npkgs == 1 ? MSG_1MORE_INST : MSG_MORE_INST, npkgs);
31539781SMoriah.Waterland@Sun.COM 	}
31549781SMoriah.Waterland@Sun.COM 
31559781SMoriah.Waterland@Sun.COM 	/* if running with no interaction (-n) do not ask question */
31569781SMoriah.Waterland@Sun.COM 
31579781SMoriah.Waterland@Sun.COM 	if (nointeract) {
31589781SMoriah.Waterland@Sun.COM 		/* if admin required return 'dont continue' */
31599781SMoriah.Waterland@Sun.COM 		if (needconsult) {
31609781SMoriah.Waterland@Sun.COM 			return (B_FALSE);
31619781SMoriah.Waterland@Sun.COM 		}
31629781SMoriah.Waterland@Sun.COM 		ckquit = 1;
31639781SMoriah.Waterland@Sun.COM 		return (B_TRUE);
31649781SMoriah.Waterland@Sun.COM 	}
31659781SMoriah.Waterland@Sun.COM 
31669781SMoriah.Waterland@Sun.COM 	/* interaction possible: ask question */
31679781SMoriah.Waterland@Sun.COM 
31689781SMoriah.Waterland@Sun.COM 	ckquit = 0;
31699781SMoriah.Waterland@Sun.COM 	n = ckyorn(ans, NULL, NULL, NULL, ASK_CONTINUE_ADD);
31709781SMoriah.Waterland@Sun.COM 	if (n != 0) {
31719781SMoriah.Waterland@Sun.COM 		quit(n);
31729781SMoriah.Waterland@Sun.COM 		/* NOTREACHED */
31739781SMoriah.Waterland@Sun.COM 	}
31749781SMoriah.Waterland@Sun.COM 	ckquit = 1;
31759781SMoriah.Waterland@Sun.COM 	if (strchr("yY", *ans) == NULL) {
31769781SMoriah.Waterland@Sun.COM 		return (B_FALSE);
31779781SMoriah.Waterland@Sun.COM 	}
31789781SMoriah.Waterland@Sun.COM 	return (B_TRUE);
31799781SMoriah.Waterland@Sun.COM }
31809781SMoriah.Waterland@Sun.COM 
31819781SMoriah.Waterland@Sun.COM /*
31829781SMoriah.Waterland@Sun.COM  * package can be in a number of formats:
31839781SMoriah.Waterland@Sun.COM  * - file containing package stream (pkgadd -d file [pkgs])
31849781SMoriah.Waterland@Sun.COM  * - directory containing packages (pkgadd -d /dir [pkgs])
31859781SMoriah.Waterland@Sun.COM  * - device containing packages (pkgadd -d diskette1 [pkgs])
31869781SMoriah.Waterland@Sun.COM  * non-global zones can be passed open files and strings as arguments
31879781SMoriah.Waterland@Sun.COM  * - for file containing package stream
31889781SMoriah.Waterland@Sun.COM  * -- the stream can be passed directly to the non-global zone
31899781SMoriah.Waterland@Sun.COM  * - for directory
31909781SMoriah.Waterland@Sun.COM  * -- convert packages to datastream to pass to the non-global zone
31919781SMoriah.Waterland@Sun.COM  * - for device
31929781SMoriah.Waterland@Sun.COM  * -- ?
31939781SMoriah.Waterland@Sun.COM  */
31949781SMoriah.Waterland@Sun.COM 
31959781SMoriah.Waterland@Sun.COM static boolean_t
31969781SMoriah.Waterland@Sun.COM unpack_and_check_packages(char **a_pkgList, char *a_idsName, char *a_packageDir)
31979781SMoriah.Waterland@Sun.COM {
31989781SMoriah.Waterland@Sun.COM 	int	savenpkgs = npkgs;
31999781SMoriah.Waterland@Sun.COM 	int	i;
32009781SMoriah.Waterland@Sun.COM 	CAF_T	flags = 0;
32019781SMoriah.Waterland@Sun.COM 
32029781SMoriah.Waterland@Sun.COM 	/* entry assertions */
32039781SMoriah.Waterland@Sun.COM 
32049781SMoriah.Waterland@Sun.COM 	assert(a_pkgList != (char **)NULL);
32059781SMoriah.Waterland@Sun.COM 
32069781SMoriah.Waterland@Sun.COM 	/* entry debugging info */
32079781SMoriah.Waterland@Sun.COM 
32089781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_UNPACKCHECK_ENTRY);
32099781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_UNPACKCHECK_ARGS, PSTR(a_idsName), PSTR(a_packageDir));
32109781SMoriah.Waterland@Sun.COM 
32119781SMoriah.Waterland@Sun.COM 	/*
32129781SMoriah.Waterland@Sun.COM 	 * set flags for applicability check
32139781SMoriah.Waterland@Sun.COM 	 */
32149781SMoriah.Waterland@Sun.COM 
32159781SMoriah.Waterland@Sun.COM 	/* determine if running in the global zone */
32169781SMoriah.Waterland@Sun.COM 
32179781SMoriah.Waterland@Sun.COM 	if (z_running_in_global_zone() == B_TRUE) {
32189781SMoriah.Waterland@Sun.COM 		flags |= CAF_IN_GLOBAL_ZONE;
32199781SMoriah.Waterland@Sun.COM 	}
32209781SMoriah.Waterland@Sun.COM 
32219781SMoriah.Waterland@Sun.COM 	/* set -G flag */
32229781SMoriah.Waterland@Sun.COM 
32239781SMoriah.Waterland@Sun.COM 	if (globalZoneOnly == B_TRUE) {
32249781SMoriah.Waterland@Sun.COM 		flags |= CAF_SCOPE_GLOBAL;
32259781SMoriah.Waterland@Sun.COM 	}
32269781SMoriah.Waterland@Sun.COM 
32279781SMoriah.Waterland@Sun.COM 	/*
32289781SMoriah.Waterland@Sun.COM 	 * for each package to install:
32299781SMoriah.Waterland@Sun.COM 	 * - if packages from datastream, unpack package into package dir
32309781SMoriah.Waterland@Sun.COM 	 * - check applicability of installing package on this system/zone
32319781SMoriah.Waterland@Sun.COM 	 */
32329781SMoriah.Waterland@Sun.COM 
32339781SMoriah.Waterland@Sun.COM 	for (i = 0; (pkginst = a_pkgList[i]) != NULL; i++) {
32349781SMoriah.Waterland@Sun.COM 		if (a_idsName != (char *)NULL) {
32359781SMoriah.Waterland@Sun.COM 			/* create stream out of package if not already one */
32369781SMoriah.Waterland@Sun.COM 			if (unpack_package_from_stream(a_idsName, pkginst,
32379781SMoriah.Waterland@Sun.COM 				a_packageDir) == B_FALSE) {
32389781SMoriah.Waterland@Sun.COM 				progerr(ERR_CANNOT_UNPACK_PKGSTRM,
32399781SMoriah.Waterland@Sun.COM 					PSTR(pkginst), PSTR(a_idsName),
32409781SMoriah.Waterland@Sun.COM 					PSTR(a_packageDir));
32419781SMoriah.Waterland@Sun.COM 
32429781SMoriah.Waterland@Sun.COM 				npkgs = savenpkgs;
32439781SMoriah.Waterland@Sun.COM 				return (B_FALSE);
32449781SMoriah.Waterland@Sun.COM 			}
32459781SMoriah.Waterland@Sun.COM 		} else {
32469781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_PKG_IN_DIR, pkginst, a_packageDir);
32479781SMoriah.Waterland@Sun.COM 		}
32489781SMoriah.Waterland@Sun.COM 
32499781SMoriah.Waterland@Sun.COM 		/* check package applicability */
32509781SMoriah.Waterland@Sun.COM 		if (check_applicability(a_packageDir,
32519781SMoriah.Waterland@Sun.COM 			pkginst, get_inst_root(), flags) == B_FALSE) {
32529781SMoriah.Waterland@Sun.COM 			progerr(ERR_PKG_NOT_INSTALLABLE, pkginst);
32539781SMoriah.Waterland@Sun.COM 			npkgs = savenpkgs;
32549781SMoriah.Waterland@Sun.COM 			return (B_FALSE);
32559781SMoriah.Waterland@Sun.COM 		}
32569781SMoriah.Waterland@Sun.COM 		npkgs--;
32579781SMoriah.Waterland@Sun.COM 	}
32589781SMoriah.Waterland@Sun.COM 
32599781SMoriah.Waterland@Sun.COM 	npkgs = savenpkgs;
32609781SMoriah.Waterland@Sun.COM 	return (B_TRUE);
32619781SMoriah.Waterland@Sun.COM }
32629781SMoriah.Waterland@Sun.COM 
32639781SMoriah.Waterland@Sun.COM /*
32649781SMoriah.Waterland@Sun.COM  * returns:
32659781SMoriah.Waterland@Sun.COM  *	B_TRUE - package list generated
32669781SMoriah.Waterland@Sun.COM  *	B_FALSE - failed to generate package list
32679781SMoriah.Waterland@Sun.COM  *	Will call quit(n) on fatal error.
32689781SMoriah.Waterland@Sun.COM  */
32699781SMoriah.Waterland@Sun.COM 
32709781SMoriah.Waterland@Sun.COM static boolean_t
32719781SMoriah.Waterland@Sun.COM get_package_list(char ***r_pkgList, char **a_argv, char *a_categories,
32729781SMoriah.Waterland@Sun.COM 	char **a_categoryList, int a_ignoreSignatures, PKG_ERR *a_err,
32739781SMoriah.Waterland@Sun.COM 	ushort_t a_httpProxyPort, char *a_httpProxyName,
32749781SMoriah.Waterland@Sun.COM 	keystore_handle_t a_keystore, char *a_keystoreFile,
32759781SMoriah.Waterland@Sun.COM 	char *a_idsName, int *r_repeat)
32769781SMoriah.Waterland@Sun.COM {
32779781SMoriah.Waterland@Sun.COM 	int		n;
32789781SMoriah.Waterland@Sun.COM 	url_hport_t	*proxytmp = NULL;
32799781SMoriah.Waterland@Sun.COM 
32809781SMoriah.Waterland@Sun.COM 	/* entry assertions */
32819781SMoriah.Waterland@Sun.COM 
32829781SMoriah.Waterland@Sun.COM 	assert(r_repeat != (int *)NULL);
32839781SMoriah.Waterland@Sun.COM 
32849781SMoriah.Waterland@Sun.COM 	/* entry debugging info */
32859781SMoriah.Waterland@Sun.COM 
32869781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_GETPKGLIST_ENTRY);
32879781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_GETPKGLIST_ARGS, PSTR(a_idsName), PSTR(pkgdev.dirname),
32889781SMoriah.Waterland@Sun.COM 			*r_repeat);
32899781SMoriah.Waterland@Sun.COM 
32909781SMoriah.Waterland@Sun.COM 	/*
32919781SMoriah.Waterland@Sun.COM 	 * get the list of the packages to add
32929781SMoriah.Waterland@Sun.COM 	 */
32939781SMoriah.Waterland@Sun.COM 
32949781SMoriah.Waterland@Sun.COM 	n = pkgGetPackageList(r_pkgList, a_argv, optind, a_categories,
32959781SMoriah.Waterland@Sun.COM 				a_categoryList, &pkgdev);
32969781SMoriah.Waterland@Sun.COM 
32979781SMoriah.Waterland@Sun.COM 	switch (n) {
32989781SMoriah.Waterland@Sun.COM 		case -1:	/* no packages found */
32999781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_PKGLIST_NONFOUND, PSTR(a_idsName),
33009781SMoriah.Waterland@Sun.COM 					pkgdev.dirname);
33019781SMoriah.Waterland@Sun.COM 			return (B_FALSE);
33029781SMoriah.Waterland@Sun.COM 
33039781SMoriah.Waterland@Sun.COM 		case 0:		/* packages found */
33049781SMoriah.Waterland@Sun.COM 			break;
33059781SMoriah.Waterland@Sun.COM 
33069781SMoriah.Waterland@Sun.COM 		default:	/* "quit" error */
33079781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_PKGLIST_ERROR, PSTR(a_idsName),
33089781SMoriah.Waterland@Sun.COM 				pkgdev.dirname, n);
33099781SMoriah.Waterland@Sun.COM 			quit(n);
33109781SMoriah.Waterland@Sun.COM 			/* NOTREACHED */
33119781SMoriah.Waterland@Sun.COM 	}
33129781SMoriah.Waterland@Sun.COM 
33139781SMoriah.Waterland@Sun.COM 	/*
33149781SMoriah.Waterland@Sun.COM 	 * If we are not ignoring signatures, check the package's
33159781SMoriah.Waterland@Sun.COM 	 * signature if one exists.  pkgask doesn't care about
33169781SMoriah.Waterland@Sun.COM 	 * signatures though.
33179781SMoriah.Waterland@Sun.COM 	 */
33189781SMoriah.Waterland@Sun.COM 	if (!askflag && !a_ignoreSignatures && a_idsName &&
33199781SMoriah.Waterland@Sun.COM 		(web_ck_authentication() == AUTH_QUIT)) {
33209781SMoriah.Waterland@Sun.COM 
33219781SMoriah.Waterland@Sun.COM 		PKCS7		*sig = NULL;
33229781SMoriah.Waterland@Sun.COM 		STACK_OF(X509)	*cas = NULL;
33239781SMoriah.Waterland@Sun.COM 
33249781SMoriah.Waterland@Sun.COM 		/* Retrieve signature */
33259781SMoriah.Waterland@Sun.COM 		if (!get_signature(a_err, a_idsName, &pkgdev, &sig)) {
33269781SMoriah.Waterland@Sun.COM 			pkgerr(a_err);
33279781SMoriah.Waterland@Sun.COM 			web_cleanup();
33289781SMoriah.Waterland@Sun.COM 			quit(1);
33299781SMoriah.Waterland@Sun.COM 			/* NOTREACHED */
33309781SMoriah.Waterland@Sun.COM 		}
33319781SMoriah.Waterland@Sun.COM 
33329781SMoriah.Waterland@Sun.COM 		if (sig != NULL) {
33339781SMoriah.Waterland@Sun.COM 			/* Found signature.  Verify. */
33349781SMoriah.Waterland@Sun.COM 			if (a_httpProxyName != NULL) {
33359781SMoriah.Waterland@Sun.COM 				/* Proxy will be needed for OCSP */
33369781SMoriah.Waterland@Sun.COM 				proxytmp = malloc(sizeof (url_hport_t));
33379781SMoriah.Waterland@Sun.COM 				if (url_parse_hostport(a_httpProxyName,
33389781SMoriah.Waterland@Sun.COM 					proxytmp, a_httpProxyPort)
33399781SMoriah.Waterland@Sun.COM 					!= URL_PARSE_SUCCESS) {
33409781SMoriah.Waterland@Sun.COM 					progerr(ERR_PROXY,
33419781SMoriah.Waterland@Sun.COM 						a_httpProxyName);
33429781SMoriah.Waterland@Sun.COM 					PKCS7_free(sig);
33439781SMoriah.Waterland@Sun.COM 					quit(99);
33449781SMoriah.Waterland@Sun.COM 					/* NOTREACHED */
33459781SMoriah.Waterland@Sun.COM 				}
33469781SMoriah.Waterland@Sun.COM 			}
33479781SMoriah.Waterland@Sun.COM 
33489781SMoriah.Waterland@Sun.COM 			/* Start with fresh error stack */
33499781SMoriah.Waterland@Sun.COM 			pkgerr_clear(a_err);
33509781SMoriah.Waterland@Sun.COM 
33519781SMoriah.Waterland@Sun.COM 			if (a_keystore == NULL) {
33529781SMoriah.Waterland@Sun.COM 				/* keystore not opened - open it */
33539781SMoriah.Waterland@Sun.COM 				if (open_keystore(a_err, a_keystoreFile,
33549781SMoriah.Waterland@Sun.COM 					get_prog_name(), pkg_passphrase_cb,
33559781SMoriah.Waterland@Sun.COM 					KEYSTORE_DFLT_FLAGS,
33569781SMoriah.Waterland@Sun.COM 					&a_keystore) != 0) {
33579781SMoriah.Waterland@Sun.COM 					pkgerr(a_err);
33589781SMoriah.Waterland@Sun.COM 					web_cleanup();
33599781SMoriah.Waterland@Sun.COM 					PKCS7_free(sig);
33609781SMoriah.Waterland@Sun.COM 					quit(1);
33619781SMoriah.Waterland@Sun.COM 					/* NOTREACHED */
33629781SMoriah.Waterland@Sun.COM 				}
33639781SMoriah.Waterland@Sun.COM 			}
33649781SMoriah.Waterland@Sun.COM 
33659781SMoriah.Waterland@Sun.COM 			/* get trusted CA certs */
33669781SMoriah.Waterland@Sun.COM 			if (find_ca_certs(a_err, a_keystore, &cas) != 0) {
33679781SMoriah.Waterland@Sun.COM 				pkgerr(a_err);
33689781SMoriah.Waterland@Sun.COM 				PKCS7_free(sig);
33699781SMoriah.Waterland@Sun.COM 				web_cleanup();
33709781SMoriah.Waterland@Sun.COM 				quit(1);
33719781SMoriah.Waterland@Sun.COM 				/* NOTREACHED */
33729781SMoriah.Waterland@Sun.COM 			}
33739781SMoriah.Waterland@Sun.COM 
33749781SMoriah.Waterland@Sun.COM 			/* Verify signature */
33759781SMoriah.Waterland@Sun.COM 			if (!ds_validate_signature(a_err, &pkgdev,
33769781SMoriah.Waterland@Sun.COM 				&a_argv[optind], a_idsName, sig,
33779781SMoriah.Waterland@Sun.COM 				cas, proxytmp, nointeract)) {
33789781SMoriah.Waterland@Sun.COM 				pkgerr(a_err);
33799781SMoriah.Waterland@Sun.COM 				quit(99);
33809781SMoriah.Waterland@Sun.COM 				/* NOTREACHED */
33819781SMoriah.Waterland@Sun.COM 			}
33829781SMoriah.Waterland@Sun.COM 
33839781SMoriah.Waterland@Sun.COM 			/* cleanup */
33849781SMoriah.Waterland@Sun.COM 			PKCS7_free(sig);
33859781SMoriah.Waterland@Sun.COM 			web_cleanup();
33869781SMoriah.Waterland@Sun.COM 			pkgerr_free(a_err);
33879781SMoriah.Waterland@Sun.COM 		}
33889781SMoriah.Waterland@Sun.COM 	}
33899781SMoriah.Waterland@Sun.COM 
33909781SMoriah.Waterland@Sun.COM 	/* order package list if input data stream specified */
33919781SMoriah.Waterland@Sun.COM 
33929781SMoriah.Waterland@Sun.COM 	if (a_idsName) {
33939781SMoriah.Waterland@Sun.COM 		ds_order(*r_pkgList);
33949781SMoriah.Waterland@Sun.COM 	}
33959781SMoriah.Waterland@Sun.COM 
33969781SMoriah.Waterland@Sun.COM 	return (B_TRUE);
33979781SMoriah.Waterland@Sun.COM }
33989781SMoriah.Waterland@Sun.COM 
33999781SMoriah.Waterland@Sun.COM /*
34009781SMoriah.Waterland@Sun.COM  * Name:	install_in_one_zone
34019781SMoriah.Waterland@Sun.COM  * Description:	Install a single package in a single zone
34029781SMoriah.Waterland@Sun.COM  * Arguments:	a_inheritedPkgDirs - pointer to array of strings, each one
34039781SMoriah.Waterland@Sun.COM  *			representing the non-global zones full path of a
34049781SMoriah.Waterland@Sun.COM  *			directory that is inherited from the global zone.
34059781SMoriah.Waterland@Sun.COM  *		a_zoneName - pointer to string representing the name of the
34069781SMoriah.Waterland@Sun.COM  *			zone to install the package into.
34079781SMoriah.Waterland@Sun.COM  *		a_idsName - pointer to string representing the data stream
34089781SMoriah.Waterland@Sun.COM  *			device (input data stream) containing the package to
34099781SMoriah.Waterland@Sun.COM  *			be installed.
34109781SMoriah.Waterland@Sun.COM  *			If this is == NULL the package is assumed to be
34119781SMoriah.Waterland@Sun.COM  *			spooled in the zone temporary directory.
34129781SMoriah.Waterland@Sun.COM  *		a_zoneAdminFile - pointer to string representing the admin
34139781SMoriah.Waterland@Sun.COM  *			file to pass to pkginstall when installing the package.
34149781SMoriah.Waterland@Sun.COM  *			If this is == NULL no admin file is given to pkginstall.
34159781SMoriah.Waterland@Sun.COM  *		a_zoneTempDir - pointer to string representing the temporary
34169781SMoriah.Waterland@Sun.COM  *			directory in which spooled packages can be found if
34179781SMoriah.Waterland@Sun.COM  *			a_idsName is == NULL.
34189781SMoriah.Waterland@Sun.COM  *		a_altBinDir - pointer to string representing an alternative
34199781SMoriah.Waterland@Sun.COM  *			binary location directory to pass to pkginstall.
34209781SMoriah.Waterland@Sun.COM  *			If this is == NULL no alternative binary location is
34219781SMoriah.Waterland@Sun.COM  *			passed to pkginstall.
34229781SMoriah.Waterland@Sun.COM  *		a_scratchName - pointer to string representing the name of the
34239781SMoriah.Waterland@Sun.COM  *			scratch zone to use for installation.
34249781SMoriah.Waterland@Sun.COM  *		a_zoneState - state of the zone; must be mounted or running.
3425*9869SCasper.Dik@Sun.COM  *		a_tmpzn - B_TRUE when this zone is booted by the package
3426*9869SCasper.Dik@Sun.COM  *			command or B_FALSE if it was running before.
34279781SMoriah.Waterland@Sun.COM  * Returns:	void
34289781SMoriah.Waterland@Sun.COM  * NOTE:	As a side effect, "ckreturn" is called on the result returned
34299781SMoriah.Waterland@Sun.COM  *		from running 'pkginstall' in the zone; this sets several global
34309781SMoriah.Waterland@Sun.COM  *		variables which allows the caller to determine the result of
34319781SMoriah.Waterland@Sun.COM  *		the installation operation.
34329781SMoriah.Waterland@Sun.COM  */
34339781SMoriah.Waterland@Sun.COM 
34349781SMoriah.Waterland@Sun.COM static void
34359781SMoriah.Waterland@Sun.COM install_in_one_zone(char **a_inheritedPkgDirs, char *a_zoneName,
34369781SMoriah.Waterland@Sun.COM 	char *a_idsName, char *a_zoneAdminFile, char *a_zoneTempDir,
3437*9869SCasper.Dik@Sun.COM 	char *a_altBinDir, zone_state_t a_zoneState, boolean_t a_tmpzn)
34389781SMoriah.Waterland@Sun.COM {
34399781SMoriah.Waterland@Sun.COM 	char	zoneStreamName[PATH_MAX] = {'\0'};
34409781SMoriah.Waterland@Sun.COM 	int	n;
34419781SMoriah.Waterland@Sun.COM 
34429781SMoriah.Waterland@Sun.COM 	/* entry assertions */
34439781SMoriah.Waterland@Sun.COM 
34449781SMoriah.Waterland@Sun.COM 	assert(a_zoneName != (char *)NULL);
34459781SMoriah.Waterland@Sun.COM 	assert(*a_zoneName != '\0');
34469781SMoriah.Waterland@Sun.COM 
34479781SMoriah.Waterland@Sun.COM 	/* entry debugging info */
34489781SMoriah.Waterland@Sun.COM 
34499781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_INSTINONEZONE_ENTRY);
34509781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_INSTINONEZONE_ARGS, a_zoneName, PSTR(a_idsName),
34519781SMoriah.Waterland@Sun.COM 			PSTR(a_zoneAdminFile), PSTR(a_zoneTempDir),
34529781SMoriah.Waterland@Sun.COM 			PSTR(a_altBinDir));
34539781SMoriah.Waterland@Sun.COM 
34549781SMoriah.Waterland@Sun.COM 	/* echo operation to perform to stdout */
34559781SMoriah.Waterland@Sun.COM 
34569781SMoriah.Waterland@Sun.COM 	echo(MSG_INSTALL_PKG_IN_ZONE, pkginst, a_zoneName);
34579781SMoriah.Waterland@Sun.COM 
34589781SMoriah.Waterland@Sun.COM 	/* determine path to the package stream */
34599781SMoriah.Waterland@Sun.COM 
34609781SMoriah.Waterland@Sun.COM 	if (a_idsName == (char *)NULL) {
34619781SMoriah.Waterland@Sun.COM 		/* locate temp stream created earlier */
34629781SMoriah.Waterland@Sun.COM 		(void) snprintf(zoneStreamName, sizeof (zoneStreamName),
34639781SMoriah.Waterland@Sun.COM 			"%s/%s.dstream", a_zoneTempDir, pkginst);
34649781SMoriah.Waterland@Sun.COM 	} else {
34659781SMoriah.Waterland@Sun.COM 		/* use stream passed in on command line */
34669781SMoriah.Waterland@Sun.COM 		(void) snprintf(zoneStreamName, sizeof (zoneStreamName),
34679781SMoriah.Waterland@Sun.COM 			"%s", a_idsName);
34689781SMoriah.Waterland@Sun.COM 	}
34699781SMoriah.Waterland@Sun.COM 
34709781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_INSTALL_IN_ZONE, pkginst, a_zoneName, zoneStreamName);
34719781SMoriah.Waterland@Sun.COM 
34729781SMoriah.Waterland@Sun.COM 	n = pkgZoneInstall(a_zoneName, a_inheritedPkgDirs, a_zoneState,
3473*9869SCasper.Dik@Sun.COM 		zoneStreamName, a_altBinDir, a_zoneAdminFile, a_tmpzn);
34749781SMoriah.Waterland@Sun.COM 
34759781SMoriah.Waterland@Sun.COM 	/* set success/fail condition variables */
34769781SMoriah.Waterland@Sun.COM 
34779781SMoriah.Waterland@Sun.COM 	ckreturn(n);
34789781SMoriah.Waterland@Sun.COM 
34799781SMoriah.Waterland@Sun.COM 	/* exit debugging info */
34809781SMoriah.Waterland@Sun.COM 
34819781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_INSTALL_FLAG_VALUES, "after install", admnflag, doreboot,
34829781SMoriah.Waterland@Sun.COM 		failflag, interrupted, intrflag, ireboot, needconsult,
34839781SMoriah.Waterland@Sun.COM 		nullflag, warnflag);
34849781SMoriah.Waterland@Sun.COM }
34859781SMoriah.Waterland@Sun.COM 
34869781SMoriah.Waterland@Sun.COM /*
34879781SMoriah.Waterland@Sun.COM  * Name:	install_in_zones
34889781SMoriah.Waterland@Sun.COM  * Description:	Install a single package in the zones that are running from
34899781SMoriah.Waterland@Sun.COM  *		a list of zones
34909781SMoriah.Waterland@Sun.COM  * Arguments:	a_zlst - list of zones to install the package into
34919781SMoriah.Waterland@Sun.COM  *		a_idsName - pointer to string representing the data stream
34929781SMoriah.Waterland@Sun.COM  *			device (input data stream) containing the package to
34939781SMoriah.Waterland@Sun.COM  *			be installed.
34949781SMoriah.Waterland@Sun.COM  *			If this is == NULL the package is assumed to be
34959781SMoriah.Waterland@Sun.COM  *			spooled in the zone temporary directory.
34969781SMoriah.Waterland@Sun.COM  *		a_altBinDir - pointer to string representing an alternative
34979781SMoriah.Waterland@Sun.COM  *			binary location directory to pass to pkginstall.
34989781SMoriah.Waterland@Sun.COM  *			If this is == NULL no alternative binary location is
34999781SMoriah.Waterland@Sun.COM  *			passed to pkginstall.
35009781SMoriah.Waterland@Sun.COM  *		a_zoneAdminFile - pointer to string representing the admin
35019781SMoriah.Waterland@Sun.COM  *			file to pass to pkginstall when installing the package.
35029781SMoriah.Waterland@Sun.COM  *			If this is == NULL no admin file is given to pkginstall.
35039781SMoriah.Waterland@Sun.COM  *		a_zoneTempDir - pointer to string representing the temporary
35049781SMoriah.Waterland@Sun.COM  *			directory in which spooled packages can be found if
35059781SMoriah.Waterland@Sun.COM  *			a_idsName is == NULL.
35069781SMoriah.Waterland@Sun.COM  */
35079781SMoriah.Waterland@Sun.COM 
35089781SMoriah.Waterland@Sun.COM static int
35099781SMoriah.Waterland@Sun.COM install_in_zones(zoneList_t a_zlst, char *a_idsName, char *a_altBinDir,
35109781SMoriah.Waterland@Sun.COM 	char *a_zoneAdminFile, char *a_zoneTempDir)
35119781SMoriah.Waterland@Sun.COM {
35129781SMoriah.Waterland@Sun.COM 	char		**inheritedPkgDirs;
35139781SMoriah.Waterland@Sun.COM 	char		*zoneName;
35149781SMoriah.Waterland@Sun.COM 	int		zoneIndex;
35159781SMoriah.Waterland@Sun.COM 	int		zonesSkipped = 0;
35169781SMoriah.Waterland@Sun.COM 	zone_state_t	zst;
35179781SMoriah.Waterland@Sun.COM 
35189781SMoriah.Waterland@Sun.COM 	/* entry assertions */
35199781SMoriah.Waterland@Sun.COM 
35209781SMoriah.Waterland@Sun.COM 	assert(a_zlst != (zoneList_t)NULL);
35219781SMoriah.Waterland@Sun.COM 
35229781SMoriah.Waterland@Sun.COM 	/* entry debugging info */
35239781SMoriah.Waterland@Sun.COM 
35249781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_INSTALLINZONES_ENTRY);
35259781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_INSTALLINZONES_ARGS, PSTR(a_idsName),
35269781SMoriah.Waterland@Sun.COM 			PSTR(a_zoneAdminFile), PSTR(a_zoneTempDir));
35279781SMoriah.Waterland@Sun.COM 
35289781SMoriah.Waterland@Sun.COM 	/* process each zone in the list */
35299781SMoriah.Waterland@Sun.COM 
35309781SMoriah.Waterland@Sun.COM 	for (zoneIndex = 0;
35319781SMoriah.Waterland@Sun.COM 		(zoneName = z_zlist_get_zonename(a_zlst, zoneIndex)) != NULL;
35329781SMoriah.Waterland@Sun.COM 		zoneIndex++) {
35339781SMoriah.Waterland@Sun.COM 
35349781SMoriah.Waterland@Sun.COM 		/* skip the zone if it is NOT running */
35359781SMoriah.Waterland@Sun.COM 
35369781SMoriah.Waterland@Sun.COM 		zst = z_zlist_get_current_state(a_zlst, zoneIndex);
35379781SMoriah.Waterland@Sun.COM 		if (zst != ZONE_STATE_RUNNING && zst != ZONE_STATE_MOUNTED) {
35389781SMoriah.Waterland@Sun.COM 			zonesSkipped++;
35399781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_SKIPPING_ZONE, zoneName);
35409781SMoriah.Waterland@Sun.COM 			continue;
35419781SMoriah.Waterland@Sun.COM 		}
35429781SMoriah.Waterland@Sun.COM 
35439781SMoriah.Waterland@Sun.COM 		/* determine list of directories inherited from global zone */
35449781SMoriah.Waterland@Sun.COM 
35459781SMoriah.Waterland@Sun.COM 		inheritedPkgDirs = z_zlist_get_inherited_pkg_dirs(a_zlst,
35469781SMoriah.Waterland@Sun.COM 					zoneIndex);
35479781SMoriah.Waterland@Sun.COM 
35489781SMoriah.Waterland@Sun.COM 		/* install the package in this zone */
35499781SMoriah.Waterland@Sun.COM 
35509781SMoriah.Waterland@Sun.COM 		install_in_one_zone(inheritedPkgDirs,
35519781SMoriah.Waterland@Sun.COM 		    z_zlist_get_scratch(a_zlst, zoneIndex), a_idsName,
3552*9869SCasper.Dik@Sun.COM 		    a_zoneAdminFile, a_zoneTempDir, a_altBinDir, zst, B_FALSE);
35539781SMoriah.Waterland@Sun.COM 	}
35549781SMoriah.Waterland@Sun.COM 
35559781SMoriah.Waterland@Sun.COM 	return (zonesSkipped);
35569781SMoriah.Waterland@Sun.COM }
35579781SMoriah.Waterland@Sun.COM 
35589781SMoriah.Waterland@Sun.COM /*
35599781SMoriah.Waterland@Sun.COM  * Name:	boot_and_install_in_zones
35609781SMoriah.Waterland@Sun.COM  * Description:	Install a single package in the zones that are NOT running from
35619781SMoriah.Waterland@Sun.COM  *		a list of zones - each zone is booted, the package installed,
35629781SMoriah.Waterland@Sun.COM  *		and the zone is halted
35639781SMoriah.Waterland@Sun.COM  * Arguments:	a_zlst - list of zones to install the package into
35649781SMoriah.Waterland@Sun.COM  *		a_idsName - pointer to string representing the data stream
35659781SMoriah.Waterland@Sun.COM  *			device (input data stream) containing the package to
35669781SMoriah.Waterland@Sun.COM  *			be installed.
35679781SMoriah.Waterland@Sun.COM  *			If this is == NULL the package is assumed to be
35689781SMoriah.Waterland@Sun.COM  *			spooled in the zone temporary directory.
35699781SMoriah.Waterland@Sun.COM  *		a_altBinDir - pointer to string representing an alternative
35709781SMoriah.Waterland@Sun.COM  *			binary location directory to pass to pkginstall.
35719781SMoriah.Waterland@Sun.COM  *			If this is == NULL no alternative binary location is
35729781SMoriah.Waterland@Sun.COM  *			passed to pkginstall.
35739781SMoriah.Waterland@Sun.COM  *		a_zoneAdminFile - pointer to string representing the admin
35749781SMoriah.Waterland@Sun.COM  *			file to pass to pkginstall when installing the package.
35759781SMoriah.Waterland@Sun.COM  *			If this is == NULL no admin file is given to pkginstall.
35769781SMoriah.Waterland@Sun.COM  *		a_zoneTempDir - pointer to string representing the temporary
35779781SMoriah.Waterland@Sun.COM  *			directory in which spooled packages can be found if
35789781SMoriah.Waterland@Sun.COM  *			a_idsName is == NULL.
35799781SMoriah.Waterland@Sun.COM  */
35809781SMoriah.Waterland@Sun.COM 
35819781SMoriah.Waterland@Sun.COM static int
35829781SMoriah.Waterland@Sun.COM boot_and_install_in_zones(zoneList_t a_zlst, char *a_idsName, char *a_altBinDir,
35839781SMoriah.Waterland@Sun.COM 	char *a_zoneAdminFile, char *a_zoneTempDir)
35849781SMoriah.Waterland@Sun.COM {
35859781SMoriah.Waterland@Sun.COM 	boolean_t	b;
35869781SMoriah.Waterland@Sun.COM 	char		**inheritedPkgDirs;
35879781SMoriah.Waterland@Sun.COM 	char		*zoneName;
35889781SMoriah.Waterland@Sun.COM 	int		zoneIndex;
35899781SMoriah.Waterland@Sun.COM 	int		zonesSkipped = 0;
35909781SMoriah.Waterland@Sun.COM 	zone_state_t	zst;
35919781SMoriah.Waterland@Sun.COM 
35929781SMoriah.Waterland@Sun.COM 	/* entry assertions */
35939781SMoriah.Waterland@Sun.COM 
35949781SMoriah.Waterland@Sun.COM 	assert(a_zlst != (zoneList_t)NULL);
35959781SMoriah.Waterland@Sun.COM 
35969781SMoriah.Waterland@Sun.COM 	/* entry debugging info */
35979781SMoriah.Waterland@Sun.COM 
35989781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_BOOTINSTALLINZONES_ENTRY);
35999781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_BOOTINSTALLINZONES_ARGS, PSTR(a_idsName),
36009781SMoriah.Waterland@Sun.COM 			PSTR(a_zoneAdminFile), PSTR(a_zoneTempDir));
36019781SMoriah.Waterland@Sun.COM 
36029781SMoriah.Waterland@Sun.COM 	/* process each zone in the list */
36039781SMoriah.Waterland@Sun.COM 
36049781SMoriah.Waterland@Sun.COM 	for (zoneIndex = 0;
36059781SMoriah.Waterland@Sun.COM 		(zoneName = z_zlist_get_zonename(a_zlst, zoneIndex)) != NULL;
36069781SMoriah.Waterland@Sun.COM 		zoneIndex++) {
36079781SMoriah.Waterland@Sun.COM 
36089781SMoriah.Waterland@Sun.COM 		/* skip the zone if it IS running */
36099781SMoriah.Waterland@Sun.COM 
36109781SMoriah.Waterland@Sun.COM 		zst = z_zlist_get_current_state(a_zlst, zoneIndex);
36119781SMoriah.Waterland@Sun.COM 		if (zst == ZONE_STATE_RUNNING || zst == ZONE_STATE_MOUNTED) {
36129781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_SKIPPING_ZONE_BOOT, zoneName);
36139781SMoriah.Waterland@Sun.COM 			continue;
36149781SMoriah.Waterland@Sun.COM 		}
36159781SMoriah.Waterland@Sun.COM 
36169781SMoriah.Waterland@Sun.COM 		/* skip the zone if it is NOT bootable */
36179781SMoriah.Waterland@Sun.COM 
36189781SMoriah.Waterland@Sun.COM 		if (z_zlist_is_zone_runnable(a_zlst, zoneIndex) == B_FALSE) {
36199781SMoriah.Waterland@Sun.COM 			echo(MSG_SKIPPING_ZONE_NOT_RUNNABLE, zoneName);
36209781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_SKIPPING_ZONE_NOT_RUNNABLE, zoneName);
36219781SMoriah.Waterland@Sun.COM 			continue;
36229781SMoriah.Waterland@Sun.COM 		}
36239781SMoriah.Waterland@Sun.COM 
36249781SMoriah.Waterland@Sun.COM 		/* mount up the zone */
36259781SMoriah.Waterland@Sun.COM 
36269781SMoriah.Waterland@Sun.COM 		echo(MSG_BOOTING_ZONE, zoneName);
36279781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_BOOTING_ZONE, zoneName);
36289781SMoriah.Waterland@Sun.COM 
36299781SMoriah.Waterland@Sun.COM 		b = z_zlist_change_zone_state(a_zlst, zoneIndex,
36309781SMoriah.Waterland@Sun.COM 					ZONE_STATE_MOUNTED);
36319781SMoriah.Waterland@Sun.COM 		if (b == B_FALSE) {
36329781SMoriah.Waterland@Sun.COM 			progerr(ERR_CANNOT_BOOT_ZONE, zoneName);
36339781SMoriah.Waterland@Sun.COM 			/* set fatal error return condition */
36349781SMoriah.Waterland@Sun.COM 			ckreturn(1);
36359781SMoriah.Waterland@Sun.COM 			zonesSkipped++;
36369781SMoriah.Waterland@Sun.COM 			continue;
36379781SMoriah.Waterland@Sun.COM 		}
36389781SMoriah.Waterland@Sun.COM 
36399781SMoriah.Waterland@Sun.COM 		/* determine list of directories inherited from global zone */
36409781SMoriah.Waterland@Sun.COM 
36419781SMoriah.Waterland@Sun.COM 		inheritedPkgDirs = z_zlist_get_inherited_pkg_dirs(a_zlst,
36429781SMoriah.Waterland@Sun.COM 					zoneIndex);
36439781SMoriah.Waterland@Sun.COM 
36449781SMoriah.Waterland@Sun.COM 		/* install the package in this zone */
36459781SMoriah.Waterland@Sun.COM 
36469781SMoriah.Waterland@Sun.COM 		install_in_one_zone(inheritedPkgDirs,
36479781SMoriah.Waterland@Sun.COM 		    z_zlist_get_scratch(a_zlst, zoneIndex), a_idsName,
36489781SMoriah.Waterland@Sun.COM 		    a_zoneAdminFile, a_zoneTempDir, a_altBinDir,
3649*9869SCasper.Dik@Sun.COM 		    ZONE_STATE_MOUNTED, B_TRUE);
36509781SMoriah.Waterland@Sun.COM 
36519781SMoriah.Waterland@Sun.COM 		/* restore original state of zone */
36529781SMoriah.Waterland@Sun.COM 
36539781SMoriah.Waterland@Sun.COM 		echo(MSG_RESTORE_ZONE_STATE, zoneName);
36549781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_RESTORE_ZONE_STATE, zoneName);
36559781SMoriah.Waterland@Sun.COM 
36569781SMoriah.Waterland@Sun.COM 		b = z_zlist_restore_zone_state(a_zlst, zoneIndex);
36579781SMoriah.Waterland@Sun.COM 	}
36589781SMoriah.Waterland@Sun.COM 
36599781SMoriah.Waterland@Sun.COM 	return (zonesSkipped);
36609781SMoriah.Waterland@Sun.COM }
36619781SMoriah.Waterland@Sun.COM 
36629781SMoriah.Waterland@Sun.COM /*
36639781SMoriah.Waterland@Sun.COM  * Name:	pkginstall_check_in_one_zone
36649781SMoriah.Waterland@Sun.COM  * Description:	Do a pre install check of a single package in a single zone
36659781SMoriah.Waterland@Sun.COM  * Arguments:	a_inheritedPkgDirs - pointer to array of strings, each one
36669781SMoriah.Waterland@Sun.COM  *			representing the non-global zones full path of a
36679781SMoriah.Waterland@Sun.COM  *			directory that is inherited from the global zone.
36689781SMoriah.Waterland@Sun.COM  *		a_zoneName - pointer to string representing the name of the
36699781SMoriah.Waterland@Sun.COM  *			zone to check install the package in.
36709781SMoriah.Waterland@Sun.COM  *		a_idsName - pointer to string representing the data stream
36719781SMoriah.Waterland@Sun.COM  *			device (input data stream) containing the package to
36729781SMoriah.Waterland@Sun.COM  *			be check installed.
36739781SMoriah.Waterland@Sun.COM  *			If this is == NULL the package is assumed to be
36749781SMoriah.Waterland@Sun.COM  *			spooled in the zone temporary directory.
36759781SMoriah.Waterland@Sun.COM  *		a_zoneAdminFile - pointer to string representing the admin
36769781SMoriah.Waterland@Sun.COM  *			file to pass to pkginstall when installing the package.
36779781SMoriah.Waterland@Sun.COM  *			If this is == NULL no admin file is given to pkginstall.
36789781SMoriah.Waterland@Sun.COM  *		a_zoneTempDir - pointer to string representing the temporary
36799781SMoriah.Waterland@Sun.COM  *			directory in which spooled packages can be found if
36809781SMoriah.Waterland@Sun.COM  *			a_idsName is == NULL.
36819781SMoriah.Waterland@Sun.COM  *		a_altBinDir - pointer to string representing an alternative
36829781SMoriah.Waterland@Sun.COM  *			binary location directory to pass to pkginstall.
36839781SMoriah.Waterland@Sun.COM  *			If this is == NULL no alternative binary location is
36849781SMoriah.Waterland@Sun.COM  *			passed to pkginstall.
36859781SMoriah.Waterland@Sun.COM  *		a_scratchName - pointer to string representing the name of the
36869781SMoriah.Waterland@Sun.COM  *			scratch zone to use for installation.
36879781SMoriah.Waterland@Sun.COM  *		a_zoneState - state of the zone; must be mounted or running.
3688*9869SCasper.Dik@Sun.COM  *		a_tmpzn - B_TRUE when this zone is booted by the package
3689*9869SCasper.Dik@Sun.COM  *			command or B_FALSE if it was running before.
36909781SMoriah.Waterland@Sun.COM  * Returns:	void
36919781SMoriah.Waterland@Sun.COM  * NOTE:	As a side effect, "ckreturn" is called on the result returned
36929781SMoriah.Waterland@Sun.COM  *		from running 'pkginstall' in the zone; this sets several global
36939781SMoriah.Waterland@Sun.COM  *		variables which allows the caller to determine the result of
36949781SMoriah.Waterland@Sun.COM  *		the pre installation check operation.
36959781SMoriah.Waterland@Sun.COM  */
36969781SMoriah.Waterland@Sun.COM 
36979781SMoriah.Waterland@Sun.COM static void
36989781SMoriah.Waterland@Sun.COM pkginstall_check_in_one_zone(char **a_inheritedPkgDirs, char *a_zoneName,
36999781SMoriah.Waterland@Sun.COM 	char *a_idsName, char *a_zoneAdminFile, char *a_zoneTempDir,
3700*9869SCasper.Dik@Sun.COM 	char *a_altBinDir, char *a_scratchName, zone_state_t a_zoneState,
3701*9869SCasper.Dik@Sun.COM 	boolean_t a_tmpzn)
37029781SMoriah.Waterland@Sun.COM {
37039781SMoriah.Waterland@Sun.COM 	char	preinstallcheckPath[PATH_MAX+1];
37049781SMoriah.Waterland@Sun.COM 	char	zoneStreamName[PATH_MAX] = {'\0'};
37059781SMoriah.Waterland@Sun.COM 	int	n;
37069781SMoriah.Waterland@Sun.COM 
37079781SMoriah.Waterland@Sun.COM 	echo(MSG_CHECKINSTALL_PKG_IN_ZONE, pkginst, a_zoneName);
37089781SMoriah.Waterland@Sun.COM 	echoDebug(MSG_CHECKINSTALL_PKG_IN_ZONE, pkginst, a_zoneName);
37099781SMoriah.Waterland@Sun.COM 
37109781SMoriah.Waterland@Sun.COM 	(void) snprintf(preinstallcheckPath, sizeof (preinstallcheckPath),
37119781SMoriah.Waterland@Sun.COM 		"%s/%s.%s.preinstallcheck.txt", a_zoneTempDir, pkginst,
37129781SMoriah.Waterland@Sun.COM 		a_zoneName);
37139781SMoriah.Waterland@Sun.COM 
37149781SMoriah.Waterland@Sun.COM 	if (a_idsName == (char *)NULL) {
37159781SMoriah.Waterland@Sun.COM 		/* locate temporary stream created earlier */
37169781SMoriah.Waterland@Sun.COM 		(void) snprintf(zoneStreamName, sizeof (zoneStreamName),
37179781SMoriah.Waterland@Sun.COM 			"%s/%s.dstream", a_zoneTempDir, pkginst);
37189781SMoriah.Waterland@Sun.COM 	} else {
37199781SMoriah.Waterland@Sun.COM 		(void) snprintf(zoneStreamName, sizeof (zoneStreamName),
37209781SMoriah.Waterland@Sun.COM 			"%s", a_idsName);
37219781SMoriah.Waterland@Sun.COM 	}
37229781SMoriah.Waterland@Sun.COM 
37239781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_CHECKINSTALL_IN_ZONE, pkginst, a_zoneName,
37249781SMoriah.Waterland@Sun.COM 						zoneStreamName);
37259781SMoriah.Waterland@Sun.COM 
37269781SMoriah.Waterland@Sun.COM 	n = pkgZoneCheckInstall(a_scratchName, a_inheritedPkgDirs,
37279781SMoriah.Waterland@Sun.COM 	    a_zoneState, zoneStreamName, a_altBinDir, a_zoneAdminFile,
3728*9869SCasper.Dik@Sun.COM 	    preinstallcheckPath, a_tmpzn);
37299781SMoriah.Waterland@Sun.COM 
37309781SMoriah.Waterland@Sun.COM 	/* set success/fail condition variables */
37319781SMoriah.Waterland@Sun.COM 
37329781SMoriah.Waterland@Sun.COM 	ckreturn(n);
37339781SMoriah.Waterland@Sun.COM 
37349781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_INSTALL_FLAG_VALUES, "after preinstall check",
37359781SMoriah.Waterland@Sun.COM 		admnflag, doreboot, failflag, interrupted, intrflag,
37369781SMoriah.Waterland@Sun.COM 		ireboot, needconsult, nullflag, warnflag);
37379781SMoriah.Waterland@Sun.COM }
37389781SMoriah.Waterland@Sun.COM 
37399781SMoriah.Waterland@Sun.COM /*
37409781SMoriah.Waterland@Sun.COM  * Name:	pkginstall_check_in_zones
37419781SMoriah.Waterland@Sun.COM  * Description:	Check installation of a single package in the zones that
37429781SMoriah.Waterland@Sun.COM  *		are running from a list of zones
37439781SMoriah.Waterland@Sun.COM  * Arguments:	a_zlst - list of zones to check install the package
37449781SMoriah.Waterland@Sun.COM  *		a_idsName - pointer to string representing the data stream
37459781SMoriah.Waterland@Sun.COM  *			device (input data stream) containing the package to
37469781SMoriah.Waterland@Sun.COM  *			be check installed.
37479781SMoriah.Waterland@Sun.COM  *			If this is == NULL the package is assumed to be
37489781SMoriah.Waterland@Sun.COM  *			spooled in the zone temporary directory.
37499781SMoriah.Waterland@Sun.COM  *		a_altBinDir - pointer to string representing an alternative
37509781SMoriah.Waterland@Sun.COM  *			binary location directory to pass to pkginstall.
37519781SMoriah.Waterland@Sun.COM  *			If this is == NULL no alternative binary location is
37529781SMoriah.Waterland@Sun.COM  *			passed to pkginstall.
37539781SMoriah.Waterland@Sun.COM  *		a_zoneAdminFile - pointer to string representing the admin
37549781SMoriah.Waterland@Sun.COM  *			file to pass to pkginstall when checking the installing
37559781SMoriah.Waterland@Sun.COM  *			of the package.
37569781SMoriah.Waterland@Sun.COM  *			If this is == NULL no admin file is given to pkginstall.
37579781SMoriah.Waterland@Sun.COM  *		a_zoneTempDir - pointer to string representing the temporary
37589781SMoriah.Waterland@Sun.COM  *			directory in which spooled packages can be found if
37599781SMoriah.Waterland@Sun.COM  *			a_idsName is == NULL.
37609781SMoriah.Waterland@Sun.COM  */
37619781SMoriah.Waterland@Sun.COM 
37629781SMoriah.Waterland@Sun.COM static int
37639781SMoriah.Waterland@Sun.COM pkginstall_check_in_zones(zoneList_t a_zlst, char *a_idsName, char *a_altBinDir,
37649781SMoriah.Waterland@Sun.COM 	char *a_zoneAdminFile, char *a_zoneTempDir)
37659781SMoriah.Waterland@Sun.COM {
37669781SMoriah.Waterland@Sun.COM 	char		**inheritedPkgDirs;
37679781SMoriah.Waterland@Sun.COM 	char		*zoneName;
37689781SMoriah.Waterland@Sun.COM 	int		zoneIndex;
37699781SMoriah.Waterland@Sun.COM 	int		zonesSkipped = 0;
37709781SMoriah.Waterland@Sun.COM 	zone_state_t	zst;
37719781SMoriah.Waterland@Sun.COM 
37729781SMoriah.Waterland@Sun.COM 	for (zoneIndex = 0;
37739781SMoriah.Waterland@Sun.COM 		(zoneName = z_zlist_get_zonename(a_zlst, zoneIndex)) != NULL;
37749781SMoriah.Waterland@Sun.COM 		zoneIndex++) {
37759781SMoriah.Waterland@Sun.COM 
37769781SMoriah.Waterland@Sun.COM 		zst = z_zlist_get_current_state(a_zlst, zoneIndex);
37779781SMoriah.Waterland@Sun.COM 		if (zst != ZONE_STATE_RUNNING && zst != ZONE_STATE_MOUNTED) {
37789781SMoriah.Waterland@Sun.COM 			zonesSkipped++;
37799781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_SKIPPING_ZONE, zoneName);
37809781SMoriah.Waterland@Sun.COM 			continue;
37819781SMoriah.Waterland@Sun.COM 		}
37829781SMoriah.Waterland@Sun.COM 
37839781SMoriah.Waterland@Sun.COM 		inheritedPkgDirs = z_zlist_get_inherited_pkg_dirs(a_zlst,
37849781SMoriah.Waterland@Sun.COM 					zoneIndex);
37859781SMoriah.Waterland@Sun.COM 
37869781SMoriah.Waterland@Sun.COM 		pkginstall_check_in_one_zone(inheritedPkgDirs, zoneName,
37879781SMoriah.Waterland@Sun.COM 		    a_idsName, a_zoneAdminFile, a_zoneTempDir, a_altBinDir,
3788*9869SCasper.Dik@Sun.COM 		    z_zlist_get_scratch(a_zlst, zoneIndex), zst, B_FALSE);
37899781SMoriah.Waterland@Sun.COM 	}
37909781SMoriah.Waterland@Sun.COM 
37919781SMoriah.Waterland@Sun.COM 	return (zonesSkipped);
37929781SMoriah.Waterland@Sun.COM }
37939781SMoriah.Waterland@Sun.COM 
37949781SMoriah.Waterland@Sun.COM /*
37959781SMoriah.Waterland@Sun.COM  * Name:	boot_and_pkginstall_check_in_zones
37969781SMoriah.Waterland@Sun.COM  * Description:	Check installation of a single package in the zones that
37979781SMoriah.Waterland@Sun.COM  *		are NOT running from a list of zones - each zone is booted,
37989781SMoriah.Waterland@Sun.COM  *		the package installation is checked, and the zone is halted.
37999781SMoriah.Waterland@Sun.COM  * Arguments:	a_zlst - list of zones to install the package into
38009781SMoriah.Waterland@Sun.COM  *		a_idsName - pointer to string representing the data stream
38019781SMoriah.Waterland@Sun.COM  *			device (input data stream) containing the package to
38029781SMoriah.Waterland@Sun.COM  *			be check installed.
38039781SMoriah.Waterland@Sun.COM  *			If this is == NULL the package is assumed to be
38049781SMoriah.Waterland@Sun.COM  *			spooled in the zone temporary directory.
38059781SMoriah.Waterland@Sun.COM  *		a_altBinDir - pointer to string representing an alternative
38069781SMoriah.Waterland@Sun.COM  *			binary location directory to pass to pkginstall.
38079781SMoriah.Waterland@Sun.COM  *			If this is == NULL no alternative binary location is
38089781SMoriah.Waterland@Sun.COM  *			passed to pkginstall.
38099781SMoriah.Waterland@Sun.COM  *		a_zoneAdminFile - pointer to string representing the admin
38109781SMoriah.Waterland@Sun.COM  *			file to pass to pkginstall when check installing the
38119781SMoriah.Waterland@Sun.COM  *			package.
38129781SMoriah.Waterland@Sun.COM  *			If this is == NULL no admin file is given to pkginstall.
38139781SMoriah.Waterland@Sun.COM  *		a_zoneTempDir - pointer to string representing the temporary
38149781SMoriah.Waterland@Sun.COM  *			directory in which spooled packages can be found if
38159781SMoriah.Waterland@Sun.COM  *			a_idsName is == NULL.
38169781SMoriah.Waterland@Sun.COM  */
38179781SMoriah.Waterland@Sun.COM 
38189781SMoriah.Waterland@Sun.COM static int
38199781SMoriah.Waterland@Sun.COM boot_and_pkginstall_check_in_zones(zoneList_t a_zlst, char *a_idsName,
38209781SMoriah.Waterland@Sun.COM 	char *a_altBinDir, char *a_zoneAdminFile, char *a_zoneTempDir)
38219781SMoriah.Waterland@Sun.COM {
38229781SMoriah.Waterland@Sun.COM 	int		zoneIndex;
38239781SMoriah.Waterland@Sun.COM 	int		zonesSkipped = 0;
38249781SMoriah.Waterland@Sun.COM 	char		*zoneName;
38259781SMoriah.Waterland@Sun.COM 	boolean_t	b;
38269781SMoriah.Waterland@Sun.COM 	char		**inheritedPkgDirs;
38279781SMoriah.Waterland@Sun.COM 	zone_state_t	zst;
38289781SMoriah.Waterland@Sun.COM 
38299781SMoriah.Waterland@Sun.COM 	/* entry assertions */
38309781SMoriah.Waterland@Sun.COM 
38319781SMoriah.Waterland@Sun.COM 	assert(a_zlst != (zoneList_t)NULL);
38329781SMoriah.Waterland@Sun.COM 
38339781SMoriah.Waterland@Sun.COM 	/* entry debugging info */
38349781SMoriah.Waterland@Sun.COM 
38359781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_BOOTCHECKINSTALLINZONES_ENTRY);
38369781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_BOOTCHECKINSTALLINZONES_ARGS, PSTR(a_idsName),
38379781SMoriah.Waterland@Sun.COM 			PSTR(a_zoneAdminFile), PSTR(a_zoneTempDir));
38389781SMoriah.Waterland@Sun.COM 
38399781SMoriah.Waterland@Sun.COM 	/* process each zone in the list */
38409781SMoriah.Waterland@Sun.COM 
38419781SMoriah.Waterland@Sun.COM 	for (zoneIndex = 0;
38429781SMoriah.Waterland@Sun.COM 		(zoneName = z_zlist_get_zonename(a_zlst, zoneIndex)) != NULL;
38439781SMoriah.Waterland@Sun.COM 		zoneIndex++) {
38449781SMoriah.Waterland@Sun.COM 
38459781SMoriah.Waterland@Sun.COM 		/* skip the zone if it IS running */
38469781SMoriah.Waterland@Sun.COM 
38479781SMoriah.Waterland@Sun.COM 		zst = z_zlist_get_current_state(a_zlst, zoneIndex);
38489781SMoriah.Waterland@Sun.COM 		if (zst == ZONE_STATE_RUNNING || zst == ZONE_STATE_MOUNTED) {
38499781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_SKIPPING_ZONE_BOOT, zoneName);
38509781SMoriah.Waterland@Sun.COM 			continue;
38519781SMoriah.Waterland@Sun.COM 		}
38529781SMoriah.Waterland@Sun.COM 
38539781SMoriah.Waterland@Sun.COM 		/* skip the zone if it is NOT bootable */
38549781SMoriah.Waterland@Sun.COM 
38559781SMoriah.Waterland@Sun.COM 		if (z_zlist_is_zone_runnable(a_zlst, zoneIndex) == B_FALSE) {
38569781SMoriah.Waterland@Sun.COM 			echo(MSG_SKIPPING_ZONE_NOT_RUNNABLE, zoneName);
38579781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_SKIPPING_ZONE_NOT_RUNNABLE, zoneName);
38589781SMoriah.Waterland@Sun.COM 			continue;
38599781SMoriah.Waterland@Sun.COM 		}
38609781SMoriah.Waterland@Sun.COM 
38619781SMoriah.Waterland@Sun.COM 		/* mount up the zone */
38629781SMoriah.Waterland@Sun.COM 
38639781SMoriah.Waterland@Sun.COM 		echo(MSG_BOOTING_ZONE, zoneName);
38649781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_BOOTING_ZONE, zoneName);
38659781SMoriah.Waterland@Sun.COM 
38669781SMoriah.Waterland@Sun.COM 		b = z_zlist_change_zone_state(a_zlst, zoneIndex,
38679781SMoriah.Waterland@Sun.COM 		    ZONE_STATE_MOUNTED);
38689781SMoriah.Waterland@Sun.COM 		if (b == B_FALSE) {
38699781SMoriah.Waterland@Sun.COM 			progerr(ERR_CANNOT_BOOT_ZONE, zoneName);
38709781SMoriah.Waterland@Sun.COM 			/* set fatal error return condition */
38719781SMoriah.Waterland@Sun.COM 			ckreturn(1);
38729781SMoriah.Waterland@Sun.COM 			zonesSkipped++;
38739781SMoriah.Waterland@Sun.COM 			continue;
38749781SMoriah.Waterland@Sun.COM 		}
38759781SMoriah.Waterland@Sun.COM 
38769781SMoriah.Waterland@Sun.COM 		/* determine list of directories inherited from global zone */
38779781SMoriah.Waterland@Sun.COM 
38789781SMoriah.Waterland@Sun.COM 		inheritedPkgDirs = z_zlist_get_inherited_pkg_dirs(a_zlst,
38799781SMoriah.Waterland@Sun.COM 					zoneIndex);
38809781SMoriah.Waterland@Sun.COM 
38819781SMoriah.Waterland@Sun.COM 		/* pre-installation check of the package in this zone */
38829781SMoriah.Waterland@Sun.COM 
38839781SMoriah.Waterland@Sun.COM 		pkginstall_check_in_one_zone(inheritedPkgDirs, zoneName,
38849781SMoriah.Waterland@Sun.COM 		    a_idsName, a_zoneAdminFile, a_zoneTempDir, a_altBinDir,
38859781SMoriah.Waterland@Sun.COM 		    z_zlist_get_scratch(a_zlst, zoneIndex),
3886*9869SCasper.Dik@Sun.COM 		    ZONE_STATE_MOUNTED, B_TRUE);
38879781SMoriah.Waterland@Sun.COM 
38889781SMoriah.Waterland@Sun.COM 		/* restore original state of zone */
38899781SMoriah.Waterland@Sun.COM 
38909781SMoriah.Waterland@Sun.COM 		echo(MSG_RESTORE_ZONE_STATE, zoneName);
38919781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_RESTORE_ZONE_STATE, zoneName);
38929781SMoriah.Waterland@Sun.COM 
38939781SMoriah.Waterland@Sun.COM 		b = z_zlist_restore_zone_state(a_zlst, zoneIndex);
38949781SMoriah.Waterland@Sun.COM 	}
38959781SMoriah.Waterland@Sun.COM 
38969781SMoriah.Waterland@Sun.COM 	return (zonesSkipped);
38979781SMoriah.Waterland@Sun.COM }
38989781SMoriah.Waterland@Sun.COM 
38999781SMoriah.Waterland@Sun.COM /*
39009781SMoriah.Waterland@Sun.COM  * Function:	add_packages_in_global_with_zones
39019781SMoriah.Waterland@Sun.COM  * Description: call this function to add a list of packages in the global zone
39029781SMoriah.Waterland@Sun.COM  *		when one or more non-global zones exist
39039781SMoriah.Waterland@Sun.COM  * returns:
39049781SMoriah.Waterland@Sun.COM  *	B_TRUE to process next data stream
39059781SMoriah.Waterland@Sun.COM  *	B_FALSE to exit
39069781SMoriah.Waterland@Sun.COM  */
39079781SMoriah.Waterland@Sun.COM 
39089781SMoriah.Waterland@Sun.COM static boolean_t
39099781SMoriah.Waterland@Sun.COM add_packages_in_global_with_zones(char **a_pkgList, char *a_uri,
39109781SMoriah.Waterland@Sun.COM 	char *a_idsName, int a_repeat, char *a_altBinDir,
39119781SMoriah.Waterland@Sun.COM 	char *a_device, zoneList_t a_zlst)
39129781SMoriah.Waterland@Sun.COM {
39139781SMoriah.Waterland@Sun.COM static	char		*zoneTempDir = (char *)NULL;
39149781SMoriah.Waterland@Sun.COM static	char		*zoneAdminFile = (char *)NULL;
39159781SMoriah.Waterland@Sun.COM 
39169781SMoriah.Waterland@Sun.COM 	boolean_t	b;
39179781SMoriah.Waterland@Sun.COM 	char		*packageDir;
39189781SMoriah.Waterland@Sun.COM 	char		instdir[PATH_MAX];
39199781SMoriah.Waterland@Sun.COM 	char		respfile_path[PATH_MAX];
39209781SMoriah.Waterland@Sun.COM 	char		zoneStreamName[PATH_MAX] = {'\0'};
39219781SMoriah.Waterland@Sun.COM 	int		i;
39229781SMoriah.Waterland@Sun.COM 	int		n;
39239781SMoriah.Waterland@Sun.COM 	int		savenpkgs = npkgs;
39249781SMoriah.Waterland@Sun.COM 	int		zonesSkipped;
39259781SMoriah.Waterland@Sun.COM 	boolean_t	globalPresent;
39269781SMoriah.Waterland@Sun.COM 
39279781SMoriah.Waterland@Sun.COM 	/* entry assertions */
39289781SMoriah.Waterland@Sun.COM 
39299781SMoriah.Waterland@Sun.COM 	assert(a_pkgList != (char **)NULL);
39309781SMoriah.Waterland@Sun.COM 	assert(a_zlst != (zoneList_t)NULL);
39319781SMoriah.Waterland@Sun.COM 
39329781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_ADDPACKAGES_GZ_W_LZ_ENTRY);
39339781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_ADDPACKAGES_GZ_W_LZ_ARGS, npkgs, PSTR(a_uri),
39349781SMoriah.Waterland@Sun.COM 			PSTR(a_idsName), a_repeat, PSTR(a_device));
39359781SMoriah.Waterland@Sun.COM 
39369781SMoriah.Waterland@Sun.COM 	/* create temporary directory for use by zone operations */
39379781SMoriah.Waterland@Sun.COM 
39389781SMoriah.Waterland@Sun.COM 	create_zone_tempdir(&zoneTempDir, tmpdir);
39399781SMoriah.Waterland@Sun.COM 
39409781SMoriah.Waterland@Sun.COM 	/* create hands off settings admin file for use in a non-global zone */
39419781SMoriah.Waterland@Sun.COM 
39429781SMoriah.Waterland@Sun.COM 	create_zone_adminfile(&zoneAdminFile, zoneTempDir, admnfile);
39439781SMoriah.Waterland@Sun.COM 
39449781SMoriah.Waterland@Sun.COM 	/* determine directory where packages can be found */
39459781SMoriah.Waterland@Sun.COM 
39469781SMoriah.Waterland@Sun.COM 	if (a_idsName == (char *)NULL) {
39479781SMoriah.Waterland@Sun.COM 		/* no stream - directory containing packages provided */
39489781SMoriah.Waterland@Sun.COM 		packageDir = pkgdev.dirname;
39499781SMoriah.Waterland@Sun.COM 	} else {
39509781SMoriah.Waterland@Sun.COM 		packageDir = zoneTempDir;
39519781SMoriah.Waterland@Sun.COM 	}
39529781SMoriah.Waterland@Sun.COM 
39539781SMoriah.Waterland@Sun.COM 	/* unpack and check all packages */
39549781SMoriah.Waterland@Sun.COM 
39559781SMoriah.Waterland@Sun.COM 	b = unpack_and_check_packages(a_pkgList, a_idsName, packageDir);
39569781SMoriah.Waterland@Sun.COM 	if (b != B_TRUE) {
39579781SMoriah.Waterland@Sun.COM 		quit(1);
39589781SMoriah.Waterland@Sun.COM 	}
39599781SMoriah.Waterland@Sun.COM 
39609781SMoriah.Waterland@Sun.COM 	/*
39619781SMoriah.Waterland@Sun.COM 	 * if the packages are contained in a directory, convert the
39629781SMoriah.Waterland@Sun.COM 	 * packages into individual streams because pkgZoneInstall is only able
39639781SMoriah.Waterland@Sun.COM 	 * to pass a stream to the non-global zone's pkginstall command.
39649781SMoriah.Waterland@Sun.COM 	 * After this code is executed:
39659781SMoriah.Waterland@Sun.COM 	 * if the original input was a datastream:
39669781SMoriah.Waterland@Sun.COM 	 * -> that datastream has been unpacked into "instdir"
39679781SMoriah.Waterland@Sun.COM 	 * if the original input was a directory with packages in it:
39689781SMoriah.Waterland@Sun.COM 	 * -> those packages have been placed into a single datastream
39699781SMoriah.Waterland@Sun.COM 	 */
39709781SMoriah.Waterland@Sun.COM 
39719781SMoriah.Waterland@Sun.COM 	if (a_idsName == (char *)NULL) {
39729781SMoriah.Waterland@Sun.COM 		for (i = 0; (pkginst = a_pkgList[i]) != NULL; i++) {
39739781SMoriah.Waterland@Sun.COM 			char	*pkgs[2];
39749781SMoriah.Waterland@Sun.COM 
39759781SMoriah.Waterland@Sun.COM 			/* package is not a stream - create one */
39769781SMoriah.Waterland@Sun.COM 
39779781SMoriah.Waterland@Sun.COM 			(void) snprintf(zoneStreamName, sizeof (zoneStreamName),
39789781SMoriah.Waterland@Sun.COM 				"%s/%s.dstream", zoneTempDir, pkginst);
39799781SMoriah.Waterland@Sun.COM 
39809781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_CONVERTING_PKG, packageDir, pkginst,
39819781SMoriah.Waterland@Sun.COM 				zoneStreamName);
39829781SMoriah.Waterland@Sun.COM 
39839781SMoriah.Waterland@Sun.COM 			/* set up list of packages to be this package only */
39849781SMoriah.Waterland@Sun.COM 
39859781SMoriah.Waterland@Sun.COM 			pkgs[0] = pkginst;
39869781SMoriah.Waterland@Sun.COM 			pkgs[1] = (char *)NULL;
39879781SMoriah.Waterland@Sun.COM 
39889781SMoriah.Waterland@Sun.COM 			n = pkgtrans(packageDir, zoneStreamName, pkgs,
39899781SMoriah.Waterland@Sun.COM 					PT_SILENT|PT_ODTSTREAM, NULL, NULL);
39909781SMoriah.Waterland@Sun.COM 			if (n != 0) {
39919781SMoriah.Waterland@Sun.COM 				progerr(ERR_CANNOT_CONVERT_PKGSTRM,
39929781SMoriah.Waterland@Sun.COM 					pkginst, packageDir, zoneStreamName);
39939781SMoriah.Waterland@Sun.COM 				quit(1);
39949781SMoriah.Waterland@Sun.COM 			}
39959781SMoriah.Waterland@Sun.COM 			npkgs--;
39969781SMoriah.Waterland@Sun.COM 		}
39979781SMoriah.Waterland@Sun.COM 		npkgs = savenpkgs;
39989781SMoriah.Waterland@Sun.COM 	}
39999781SMoriah.Waterland@Sun.COM 
40009781SMoriah.Waterland@Sun.COM 	/*
40019781SMoriah.Waterland@Sun.COM 	 * Phase I - run collect dependency information for all packages for all
40029781SMoriah.Waterland@Sun.COM 	 * zones - this involves running pkginstall with the "preinstallcheck"
40039781SMoriah.Waterland@Sun.COM 	 * option which causes all dependency checks to be performed without
40049781SMoriah.Waterland@Sun.COM 	 * actually doing the installation of the packages. This information is
40059781SMoriah.Waterland@Sun.COM 	 * gathered in the zone temporary directory and is used later to present
40069781SMoriah.Waterland@Sun.COM 	 * the dependency check results to the system administrator depending
40079781SMoriah.Waterland@Sun.COM 	 * on the administration settings.
40089781SMoriah.Waterland@Sun.COM 	 */
40099781SMoriah.Waterland@Sun.COM 
40109781SMoriah.Waterland@Sun.COM 	for (i = 0; (pkginst = a_pkgList[i]) != NULL; i++) {
40119781SMoriah.Waterland@Sun.COM 
40129781SMoriah.Waterland@Sun.COM 		/* reset interrupted flag before calling pkginstall */
40139781SMoriah.Waterland@Sun.COM 
40149781SMoriah.Waterland@Sun.COM 		interrupted = 0;	/* last action was NOT quit */
40159781SMoriah.Waterland@Sun.COM 
40169781SMoriah.Waterland@Sun.COM 		/*
40179781SMoriah.Waterland@Sun.COM 		 * if this package is marked "install in this zone only", then
40189781SMoriah.Waterland@Sun.COM 		 * do not check dependencies in any other zone
40199781SMoriah.Waterland@Sun.COM 		 */
40209781SMoriah.Waterland@Sun.COM 
40219781SMoriah.Waterland@Sun.COM 		if (pkgPackageIsThisZone(pkginst) == B_TRUE) {
40229781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_VERIFY_SKIP_THISZONE, pkginst);
40239781SMoriah.Waterland@Sun.COM 			npkgs--;
40249781SMoriah.Waterland@Sun.COM 			continue;
40259781SMoriah.Waterland@Sun.COM 		}
40269781SMoriah.Waterland@Sun.COM 
40279781SMoriah.Waterland@Sun.COM 		/*
40289781SMoriah.Waterland@Sun.COM 		 * if operation failed in global zone do not propagate
40299781SMoriah.Waterland@Sun.COM 		 * to any non-global zones
40309781SMoriah.Waterland@Sun.COM 		 */
40319781SMoriah.Waterland@Sun.COM 
40329781SMoriah.Waterland@Sun.COM 		if (interrupted != 0) {
40339781SMoriah.Waterland@Sun.COM 			echo(MSG_CHECKINSTALL_INTERRUPT_B4_Z, pkginst);
40349781SMoriah.Waterland@Sun.COM 			echoDebug(MSG_CHECKINSTALL_INTERRUPT_B4_Z, pkginst);
40359781SMoriah.Waterland@Sun.COM 			break;
40369781SMoriah.Waterland@Sun.COM 		}
40379781SMoriah.Waterland@Sun.COM 
40389781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_INSTALL_FLAG_VALUES, "after pkginstall",
40399781SMoriah.Waterland@Sun.COM 			admnflag, doreboot, failflag, interrupted, intrflag,
40409781SMoriah.Waterland@Sun.COM 			ireboot, needconsult, nullflag, warnflag);
40419781SMoriah.Waterland@Sun.COM 
40429781SMoriah.Waterland@Sun.COM 		/*
40439781SMoriah.Waterland@Sun.COM 		 * call pkginstall to verify this package for all non-global
40449781SMoriah.Waterland@Sun.COM 		 * zones that are currently booted
40459781SMoriah.Waterland@Sun.COM 		 */
40469781SMoriah.Waterland@Sun.COM 
40479781SMoriah.Waterland@Sun.COM 		zonesSkipped = pkginstall_check_in_zones(a_zlst, a_idsName,
40489781SMoriah.Waterland@Sun.COM 				a_altBinDir, admnfile, zoneTempDir);
40499781SMoriah.Waterland@Sun.COM 
40509781SMoriah.Waterland@Sun.COM 		/*
40519781SMoriah.Waterland@Sun.COM 		 * if any zones were skipped (becuase they are not currently
40529781SMoriah.Waterland@Sun.COM 		 * booted), boot each zone one at a time and call pkginstall
40539781SMoriah.Waterland@Sun.COM 		 * to verify this package for each such non-global zone
40549781SMoriah.Waterland@Sun.COM 		 */
40559781SMoriah.Waterland@Sun.COM 
40569781SMoriah.Waterland@Sun.COM 		if (zonesSkipped > 0) {
40579781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_ZONES_SKIPPED, zonesSkipped);
40589781SMoriah.Waterland@Sun.COM 
40599781SMoriah.Waterland@Sun.COM 			zonesSkipped =
40609781SMoriah.Waterland@Sun.COM 				boot_and_pkginstall_check_in_zones(a_zlst,
40619781SMoriah.Waterland@Sun.COM 				a_idsName, a_altBinDir, admnfile,
40629781SMoriah.Waterland@Sun.COM 				zoneTempDir);
40639781SMoriah.Waterland@Sun.COM 
40649781SMoriah.Waterland@Sun.COM 			if (zonesSkipped > 0) {
40659781SMoriah.Waterland@Sun.COM 				progerr(ERR_INSTALL_ZONES_SKIPPED,
40669781SMoriah.Waterland@Sun.COM 							zonesSkipped);
40679781SMoriah.Waterland@Sun.COM 			}
40689781SMoriah.Waterland@Sun.COM 		}
40699781SMoriah.Waterland@Sun.COM 
40709781SMoriah.Waterland@Sun.COM 		npkgs--;
40719781SMoriah.Waterland@Sun.COM 	}
40729781SMoriah.Waterland@Sun.COM 
40739781SMoriah.Waterland@Sun.COM 	/*
40749781SMoriah.Waterland@Sun.COM 	 * At this point, all of the dependency information has been gathered
40759781SMoriah.Waterland@Sun.COM 	 * and is ready to be analyzed. This function processes all of that
40769781SMoriah.Waterland@Sun.COM 	 * dependency information and presents the results to the system
40779781SMoriah.Waterland@Sun.COM 	 * administrator, depending on the current administration settings.
40789781SMoriah.Waterland@Sun.COM 	 */
40799781SMoriah.Waterland@Sun.COM 
40809781SMoriah.Waterland@Sun.COM 	i = preinstall_verify(a_pkgList, a_zlst, zoneTempDir);
40819781SMoriah.Waterland@Sun.COM 	if (i != 0) {
40829781SMoriah.Waterland@Sun.COM 		/* dependency checks failed - exit */
40839781SMoriah.Waterland@Sun.COM 		quit(i);
40849781SMoriah.Waterland@Sun.COM 	}
40859781SMoriah.Waterland@Sun.COM 
40869781SMoriah.Waterland@Sun.COM 	npkgs = savenpkgs;
40879781SMoriah.Waterland@Sun.COM 
40889781SMoriah.Waterland@Sun.COM 	/*
40899781SMoriah.Waterland@Sun.COM 	 * reset all error return condition variables that may have been
40909781SMoriah.Waterland@Sun.COM 	 * set during package installation dependency checking so that they
40919781SMoriah.Waterland@Sun.COM 	 * do not reflect on the success/failure of the actual package
40929781SMoriah.Waterland@Sun.COM 	 * installation operations
40939781SMoriah.Waterland@Sun.COM 	 */
40949781SMoriah.Waterland@Sun.COM 
40959781SMoriah.Waterland@Sun.COM 	resetreturn();
40969781SMoriah.Waterland@Sun.COM 
40979781SMoriah.Waterland@Sun.COM 	/*
40989781SMoriah.Waterland@Sun.COM 	 * At this point, all of the dependency checking is completed, and
40999781SMoriah.Waterland@Sun.COM 	 * the installation of the packages can proceed. Install each package
41009781SMoriah.Waterland@Sun.COM 	 * one at a time, starting with the global zone, and the for each
41019781SMoriah.Waterland@Sun.COM 	 * non-global zone that is booted, and then for each non-global zone
41029781SMoriah.Waterland@Sun.COM 	 * that is not currently booted.
41039781SMoriah.Waterland@Sun.COM 	 */
41049781SMoriah.Waterland@Sun.COM 
41059781SMoriah.Waterland@Sun.COM 	globalPresent = z_on_zone_spec(GLOBAL_ZONENAME);
41069781SMoriah.Waterland@Sun.COM 
41079781SMoriah.Waterland@Sun.COM 	for (i = 0; (pkginst = a_pkgList[i]) != NULL; i++) {
41089781SMoriah.Waterland@Sun.COM 		/*
41099781SMoriah.Waterland@Sun.COM 		 * if immediate reboot required from last package and this is
41109781SMoriah.Waterland@Sun.COM 		 * not 'pkgask' then suspend installation of remaining packages
41119781SMoriah.Waterland@Sun.COM 		 */
41129781SMoriah.Waterland@Sun.COM 
41139781SMoriah.Waterland@Sun.COM 		if ((ireboot != 0) && (askflag == 0)) {
41149781SMoriah.Waterland@Sun.COM 			ptext(stderr, MSG_SUSPEND_ADD, pkginst);
41159781SMoriah.Waterland@Sun.COM 				continue;
41169781SMoriah.Waterland@Sun.COM 		}
41179781SMoriah.Waterland@Sun.COM 
41189781SMoriah.Waterland@Sun.COM 		/*
41199781SMoriah.Waterland@Sun.COM 		 * handle interrupt if the previous pkginstall was interrupted
41209781SMoriah.Waterland@Sun.COM 		 */
41219781SMoriah.Waterland@Sun.COM 
41229781SMoriah.Waterland@Sun.COM 		if (continue_installation() == B_FALSE) {
41239781SMoriah.Waterland@Sun.COM 			return (B_FALSE);
41249781SMoriah.Waterland@Sun.COM 		}
41259781SMoriah.Waterland@Sun.COM 
41269781SMoriah.Waterland@Sun.COM 		/*
41279781SMoriah.Waterland@Sun.COM 		 * if pkgask, handle response file creation:
41289781SMoriah.Waterland@Sun.COM 		 * - if the response file is a directory, then create a path to
41299781SMoriah.Waterland@Sun.COM 		 * -- a package instance within the response file directory.
41309781SMoriah.Waterland@Sun.COM 		 * - If the response file is NOT a directory, if more than one
41319781SMoriah.Waterland@Sun.COM 		 * -- package is to be installed.
41329781SMoriah.Waterland@Sun.COM 		 */
41339781SMoriah.Waterland@Sun.COM 
41349781SMoriah.Waterland@Sun.COM 		if ((askflag != 0) && (respdir != (char *)NULL)) {
41359781SMoriah.Waterland@Sun.COM 			(void) snprintf(respfile_path, sizeof (respfile_path),
41369781SMoriah.Waterland@Sun.COM 					"%s/%s", respdir, pkginst);
41379781SMoriah.Waterland@Sun.COM 			respfile = respfile_path;
41389781SMoriah.Waterland@Sun.COM 		}
41399781SMoriah.Waterland@Sun.COM 
41409781SMoriah.Waterland@Sun.COM 		echo(MSG_PROC_INST, pkginst,
41419781SMoriah.Waterland@Sun.COM 			(a_uri && a_idsName) ? a_uri : a_device);
41429781SMoriah.Waterland@Sun.COM 
41439781SMoriah.Waterland@Sun.COM 		/*
41449781SMoriah.Waterland@Sun.COM 		 * If we're installing another package in the same
41459781SMoriah.Waterland@Sun.COM 		 * session, the second through nth pkginstall, must
41469781SMoriah.Waterland@Sun.COM 		 * continue from where the prior one left off. For this
41479781SMoriah.Waterland@Sun.COM 		 * reason, the continuation feature (implied by the
41489781SMoriah.Waterland@Sun.COM 		 * nature of the command) is used for the remaining
41499781SMoriah.Waterland@Sun.COM 		 * packages.
41509781SMoriah.Waterland@Sun.COM 		 */
41519781SMoriah.Waterland@Sun.COM 
41529781SMoriah.Waterland@Sun.COM 		if ((i == 1) && (pkgdrtarg != (char *)NULL)) {
41539781SMoriah.Waterland@Sun.COM 			pkgcontsrc = pkgdrtarg;
41549781SMoriah.Waterland@Sun.COM 		}
41559781SMoriah.Waterland@Sun.COM 
41569781SMoriah.Waterland@Sun.COM 		if (globalPresent) {
41579781SMoriah.Waterland@Sun.COM 			/*
41589781SMoriah.Waterland@Sun.COM 			 * call pkginstall for this package for the global zone
41599781SMoriah.Waterland@Sun.COM 			 */
41609781SMoriah.Waterland@Sun.COM 
41619781SMoriah.Waterland@Sun.COM 			echo(MSG_INSTALLING_PKG_IN_GZ, pkginst);
41629781SMoriah.Waterland@Sun.COM 
41639781SMoriah.Waterland@Sun.COM 			/* reset interrupted flag before calling pkginstall */
41649781SMoriah.Waterland@Sun.COM 
41659781SMoriah.Waterland@Sun.COM 			interrupted = 0;	/* last action was NOT quit */
41669781SMoriah.Waterland@Sun.COM 
41679781SMoriah.Waterland@Sun.COM 			n = pkgInstall(get_inst_root(), NULL, packageDir,
41689781SMoriah.Waterland@Sun.COM 			    a_altBinDir,  NULL);
41699781SMoriah.Waterland@Sun.COM 
41709781SMoriah.Waterland@Sun.COM 			/* set success/fail condition variables */
41719781SMoriah.Waterland@Sun.COM 
41729781SMoriah.Waterland@Sun.COM 			ckreturn(n);
41739781SMoriah.Waterland@Sun.COM 
41749781SMoriah.Waterland@Sun.COM 			/*
41759781SMoriah.Waterland@Sun.COM 			 * if operation failed in global zone do not propagate
41769781SMoriah.Waterland@Sun.COM 			 * to any non-global zones
41779781SMoriah.Waterland@Sun.COM 			 */
41789781SMoriah.Waterland@Sun.COM 
41799781SMoriah.Waterland@Sun.COM 			if (interrupted != 0) {
41809781SMoriah.Waterland@Sun.COM 				echo(MSG_INSTALL_INTERRUPT_B4_ZONES, pkginst);
41819781SMoriah.Waterland@Sun.COM 				echoDebug(MSG_INSTALL_INTERRUPT_B4_ZONES,
41829781SMoriah.Waterland@Sun.COM 				    pkginst);
41839781SMoriah.Waterland@Sun.COM 				break;
41849781SMoriah.Waterland@Sun.COM 			}
41859781SMoriah.Waterland@Sun.COM 		}
41869781SMoriah.Waterland@Sun.COM 
41879781SMoriah.Waterland@Sun.COM 		/*
41889781SMoriah.Waterland@Sun.COM 		 * if this package is marked "install in this zone only",
41899781SMoriah.Waterland@Sun.COM 		 * then only need to install the package in the global zone;
41909781SMoriah.Waterland@Sun.COM 		 * skip installation in any non-global zones.
41919781SMoriah.Waterland@Sun.COM 		 */
41929781SMoriah.Waterland@Sun.COM 
41939781SMoriah.Waterland@Sun.COM 		if (pkgPackageIsThisZone(pkginst) == B_TRUE) {
41949781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_INSTALL_SKIP_THISZONE, pkginst);
41959781SMoriah.Waterland@Sun.COM 			npkgs--;
41969781SMoriah.Waterland@Sun.COM 			continue;
41979781SMoriah.Waterland@Sun.COM 		}
41989781SMoriah.Waterland@Sun.COM 
41999781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_INSTALL_FLAG_VALUES, "install in running zones",
42009781SMoriah.Waterland@Sun.COM 			admnflag, doreboot, failflag, interrupted, intrflag,
42019781SMoriah.Waterland@Sun.COM 			ireboot, needconsult, nullflag, warnflag);
42029781SMoriah.Waterland@Sun.COM 
42039781SMoriah.Waterland@Sun.COM 		/* install package in currently booted zones */
42049781SMoriah.Waterland@Sun.COM 
42059781SMoriah.Waterland@Sun.COM 		zonesSkipped = install_in_zones(a_zlst, a_idsName, a_altBinDir,
42069781SMoriah.Waterland@Sun.COM 					zoneAdminFile, zoneTempDir);
42079781SMoriah.Waterland@Sun.COM 
42089781SMoriah.Waterland@Sun.COM 		/* install package in zones that are not currently booted */
42099781SMoriah.Waterland@Sun.COM 
42109781SMoriah.Waterland@Sun.COM 		if (zonesSkipped > 0) {
42119781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_ZONES_SKIPPED, zonesSkipped);
42129781SMoriah.Waterland@Sun.COM 
42139781SMoriah.Waterland@Sun.COM 			zonesSkipped = boot_and_install_in_zones(a_zlst,
42149781SMoriah.Waterland@Sun.COM 				a_idsName, a_altBinDir, zoneAdminFile,
42159781SMoriah.Waterland@Sun.COM 				zoneTempDir);
42169781SMoriah.Waterland@Sun.COM 
42179781SMoriah.Waterland@Sun.COM 			if (zonesSkipped > 0) {
42189781SMoriah.Waterland@Sun.COM 				progerr(ERR_INSTALL_ZONES_SKIPPED,
42199781SMoriah.Waterland@Sun.COM 							zonesSkipped);
42209781SMoriah.Waterland@Sun.COM 			}
42219781SMoriah.Waterland@Sun.COM 		}
42229781SMoriah.Waterland@Sun.COM 
42239781SMoriah.Waterland@Sun.COM 		/*
42249781SMoriah.Waterland@Sun.COM 		 * package completely installed - remove any temporary stream
42259781SMoriah.Waterland@Sun.COM 		 * of the package that might have been created
42269781SMoriah.Waterland@Sun.COM 		 */
42279781SMoriah.Waterland@Sun.COM 
42289781SMoriah.Waterland@Sun.COM 		if (a_idsName == (char *)NULL) {
42299781SMoriah.Waterland@Sun.COM 			/* locate temporary stream created earlier */
42309781SMoriah.Waterland@Sun.COM 			(void) snprintf(zoneStreamName, sizeof (zoneStreamName),
42319781SMoriah.Waterland@Sun.COM 				"%s/%s.dstream", zoneTempDir, pkginst);
42329781SMoriah.Waterland@Sun.COM 			/* remove stream - no longer needed */
42339781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_REMOVING_DSTREAM_PKGDIR, zoneStreamName,
42349781SMoriah.Waterland@Sun.COM 					pkginst);
42359781SMoriah.Waterland@Sun.COM 			(void) remove(zoneStreamName);
42369781SMoriah.Waterland@Sun.COM 		} else {
42379781SMoriah.Waterland@Sun.COM 			/* remove package - no longer needed */
42389781SMoriah.Waterland@Sun.COM 			if (snprintf(instdir, sizeof (instdir), "%s/%s",
42399781SMoriah.Waterland@Sun.COM 					zoneTempDir, pkginst) >= PATH_MAX) {
42409781SMoriah.Waterland@Sun.COM 				progerr(ERR_CANNOT_CREATE_PKGPATH, tmpdir);
42419781SMoriah.Waterland@Sun.COM 				quit(1);
42429781SMoriah.Waterland@Sun.COM 			}
42439781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_REMOVING_PKG_TMPDIR, instdir, pkginst);
42449781SMoriah.Waterland@Sun.COM 			(void) remove(instdir);
42459781SMoriah.Waterland@Sun.COM 		}
42469781SMoriah.Waterland@Sun.COM 
42479781SMoriah.Waterland@Sun.COM 		/* decrement number of packages left to install */
42489781SMoriah.Waterland@Sun.COM 
42499781SMoriah.Waterland@Sun.COM 		npkgs--;
42509781SMoriah.Waterland@Sun.COM 
42519781SMoriah.Waterland@Sun.COM 		/*
42529781SMoriah.Waterland@Sun.COM 		 * if no packages left to install, unmount package source
42539781SMoriah.Waterland@Sun.COM 		 * device if appropriate
42549781SMoriah.Waterland@Sun.COM 		 */
42559781SMoriah.Waterland@Sun.COM 
42569781SMoriah.Waterland@Sun.COM 		if ((npkgs <= 0) && (pkgdev.mount || a_idsName)) {
42579781SMoriah.Waterland@Sun.COM 			(void) chdir("/");
42589781SMoriah.Waterland@Sun.COM 			if (!a_idsName) {
42599781SMoriah.Waterland@Sun.COM 				echoDebug(DBG_UNMOUNTING_DEV,
42609781SMoriah.Waterland@Sun.COM 							PSTR(pkgdev.mount));
42619781SMoriah.Waterland@Sun.COM 				(void) pkgumount(&pkgdev);
42629781SMoriah.Waterland@Sun.COM 			}
42639781SMoriah.Waterland@Sun.COM 		}
42649781SMoriah.Waterland@Sun.COM 	}
42659781SMoriah.Waterland@Sun.COM 
42669781SMoriah.Waterland@Sun.COM 	/*
42679781SMoriah.Waterland@Sun.COM 	 * all packages in the package list have been installed.
42689781SMoriah.Waterland@Sun.COM 	 * Continue with installation if:
42699781SMoriah.Waterland@Sun.COM 	 * -- immediate reboot is NOT required
42709781SMoriah.Waterland@Sun.COM 	 * -- there are more packages to install
42719781SMoriah.Waterland@Sun.COM 	 * -- the package source is a path to a file
42729781SMoriah.Waterland@Sun.COM 	 * else return do NOT continue.
42739781SMoriah.Waterland@Sun.COM 	 */
42749781SMoriah.Waterland@Sun.COM 
42759781SMoriah.Waterland@Sun.COM 	if ((ireboot == 0) && (a_repeat != 0) &&
42769781SMoriah.Waterland@Sun.COM 		(pkgdev.pathname == (char *)NULL)) {
42779781SMoriah.Waterland@Sun.COM 		return (B_TRUE);
42789781SMoriah.Waterland@Sun.COM 	}
42799781SMoriah.Waterland@Sun.COM 
42809781SMoriah.Waterland@Sun.COM 	/* return 'dont continue' */
42819781SMoriah.Waterland@Sun.COM 
42829781SMoriah.Waterland@Sun.COM 	return (B_FALSE);
42839781SMoriah.Waterland@Sun.COM }
42849781SMoriah.Waterland@Sun.COM 
42859781SMoriah.Waterland@Sun.COM /*
42869781SMoriah.Waterland@Sun.COM  * Function:	add_packages_in_nonglobal_zone
42879781SMoriah.Waterland@Sun.COM  * Description: call this function to add a list of packages in a non-global
42889781SMoriah.Waterland@Sun.COM  *		zone
42899781SMoriah.Waterland@Sun.COM  * returns:
42909781SMoriah.Waterland@Sun.COM  *	B_TRUE to process next data stream
42919781SMoriah.Waterland@Sun.COM  *	B_FALSE to exit
42929781SMoriah.Waterland@Sun.COM  */
42939781SMoriah.Waterland@Sun.COM 
42949781SMoriah.Waterland@Sun.COM static boolean_t
42959781SMoriah.Waterland@Sun.COM add_packages_in_nonglobal_zone(char **a_pkgList, char *a_uri,
42969781SMoriah.Waterland@Sun.COM 	char *a_idsName, int a_repeat, char *a_altBinDir, char *a_device)
42979781SMoriah.Waterland@Sun.COM {
42989781SMoriah.Waterland@Sun.COM static	char		*zoneTempDir = (char *)NULL;
42999781SMoriah.Waterland@Sun.COM 
43009781SMoriah.Waterland@Sun.COM 	char		*packageDir;
43019781SMoriah.Waterland@Sun.COM 	char		respfile_path[PATH_MAX];
43029781SMoriah.Waterland@Sun.COM 	int		i;
43039781SMoriah.Waterland@Sun.COM 	int		n;
43049781SMoriah.Waterland@Sun.COM 	boolean_t	b;
43059781SMoriah.Waterland@Sun.COM 	int		savenpkgs = npkgs;
43069781SMoriah.Waterland@Sun.COM 
43079781SMoriah.Waterland@Sun.COM 	/* entry assertions */
43089781SMoriah.Waterland@Sun.COM 
43099781SMoriah.Waterland@Sun.COM 	assert(a_pkgList != (char **)NULL);
43109781SMoriah.Waterland@Sun.COM 
43119781SMoriah.Waterland@Sun.COM 	/* entry debugging info */
43129781SMoriah.Waterland@Sun.COM 
43139781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_ADDPACKAGES_LZ_ENTRY);
43149781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_ADDPACKAGES_LZ_ARGS, npkgs, PSTR(a_uri), PSTR(a_idsName),
43159781SMoriah.Waterland@Sun.COM 		a_repeat, PSTR(a_device));
43169781SMoriah.Waterland@Sun.COM 
43179781SMoriah.Waterland@Sun.COM 	/* create temporary directory for use by zone operations */
43189781SMoriah.Waterland@Sun.COM 
43199781SMoriah.Waterland@Sun.COM 	create_zone_tempdir(&zoneTempDir, tmpdir);
43209781SMoriah.Waterland@Sun.COM 
43219781SMoriah.Waterland@Sun.COM 	/*
43229781SMoriah.Waterland@Sun.COM 	 * package can be in a number of formats:
43239781SMoriah.Waterland@Sun.COM 	 * - file containing package stream (pkgadd -d file [pkgs])
43249781SMoriah.Waterland@Sun.COM 	 * - directory containing packages (pkgadd -d /dir [pkgs])
43259781SMoriah.Waterland@Sun.COM 	 * - device containing packages (pkgadd -d diskette1 [pkgs])
43269781SMoriah.Waterland@Sun.COM 	 * non-global zones can be passed open file drescriptors and
43279781SMoriah.Waterland@Sun.COM 	 * strings as arguments
43289781SMoriah.Waterland@Sun.COM 	 * - for file containing package stream
43299781SMoriah.Waterland@Sun.COM 	 * -- the stream can be passed directly to the non-global zone
43309781SMoriah.Waterland@Sun.COM 	 * - for directory
43319781SMoriah.Waterland@Sun.COM 	 * -- convert packages to datastream to pass to the non-global zone
43329781SMoriah.Waterland@Sun.COM 	 * - for device
43339781SMoriah.Waterland@Sun.COM 	 */
43349781SMoriah.Waterland@Sun.COM 
43359781SMoriah.Waterland@Sun.COM 	/* determine directory where packages can be found */
43369781SMoriah.Waterland@Sun.COM 
43379781SMoriah.Waterland@Sun.COM 	if (a_idsName == (char *)NULL) {
43389781SMoriah.Waterland@Sun.COM 		/* no stream - directory containing packages provided */
43399781SMoriah.Waterland@Sun.COM 		packageDir = pkgdev.dirname;
43409781SMoriah.Waterland@Sun.COM 	} else {
43419781SMoriah.Waterland@Sun.COM 		packageDir = zoneTempDir;
43429781SMoriah.Waterland@Sun.COM 	}
43439781SMoriah.Waterland@Sun.COM 
43449781SMoriah.Waterland@Sun.COM 	b = unpack_and_check_packages(a_pkgList, a_idsName, packageDir);
43459781SMoriah.Waterland@Sun.COM 	if (b != B_TRUE) {
43469781SMoriah.Waterland@Sun.COM 		quit(1);
43479781SMoriah.Waterland@Sun.COM 	}
43489781SMoriah.Waterland@Sun.COM 
43499781SMoriah.Waterland@Sun.COM 	/*
43509781SMoriah.Waterland@Sun.COM 	 * this is the main loop where all of the packages (as listed in the
43519781SMoriah.Waterland@Sun.COM 	 * package list) are added one at a time.
43529781SMoriah.Waterland@Sun.COM 	 */
43539781SMoriah.Waterland@Sun.COM 
43549781SMoriah.Waterland@Sun.COM 	for (i = 0; (pkginst = a_pkgList[i]) != NULL; i++) {
43559781SMoriah.Waterland@Sun.COM 		npkgs--;
43569781SMoriah.Waterland@Sun.COM 	}
43579781SMoriah.Waterland@Sun.COM 
43589781SMoriah.Waterland@Sun.COM 	npkgs = savenpkgs;
43599781SMoriah.Waterland@Sun.COM 
43609781SMoriah.Waterland@Sun.COM 	/*
43619781SMoriah.Waterland@Sun.COM 	 * this is the main loop where all of the packages (as listed in the
43629781SMoriah.Waterland@Sun.COM 	 * package list) are added one at a time.
43639781SMoriah.Waterland@Sun.COM 	 */
43649781SMoriah.Waterland@Sun.COM 
43659781SMoriah.Waterland@Sun.COM 	for (i = 0; (pkginst = a_pkgList[i]) != NULL; i++) {
43669781SMoriah.Waterland@Sun.COM 		/*
43679781SMoriah.Waterland@Sun.COM 		 * if immediate reboot required from last package and this is
43689781SMoriah.Waterland@Sun.COM 		 * not 'pkgask' then suspend installation of remaining packages
43699781SMoriah.Waterland@Sun.COM 		 */
43709781SMoriah.Waterland@Sun.COM 
43719781SMoriah.Waterland@Sun.COM 		if ((ireboot != 0) && (askflag == 0)) {
43729781SMoriah.Waterland@Sun.COM 			ptext(stderr, MSG_SUSPEND_ADD, pkginst);
43739781SMoriah.Waterland@Sun.COM 				continue;
43749781SMoriah.Waterland@Sun.COM 		}
43759781SMoriah.Waterland@Sun.COM 
43769781SMoriah.Waterland@Sun.COM 		/*
43779781SMoriah.Waterland@Sun.COM 		 * handle interrupt if the previous pkginstall was interrupted
43789781SMoriah.Waterland@Sun.COM 		 */
43799781SMoriah.Waterland@Sun.COM 
43809781SMoriah.Waterland@Sun.COM 		if (continue_installation() == B_FALSE) {
43819781SMoriah.Waterland@Sun.COM 			return (B_FALSE);
43829781SMoriah.Waterland@Sun.COM 		}
43839781SMoriah.Waterland@Sun.COM 
43849781SMoriah.Waterland@Sun.COM 		/*
43859781SMoriah.Waterland@Sun.COM 		 * if pkgask, handle response file creation:
43869781SMoriah.Waterland@Sun.COM 		 * - if the response file is a directory, then create a path to
43879781SMoriah.Waterland@Sun.COM 		 * -- a package instance within the response file directory.
43889781SMoriah.Waterland@Sun.COM 		 * - If the response file is NOT a directory, if more than one
43899781SMoriah.Waterland@Sun.COM 		 * -- package is to be installed.
43909781SMoriah.Waterland@Sun.COM 		 */
43919781SMoriah.Waterland@Sun.COM 
43929781SMoriah.Waterland@Sun.COM 		if ((askflag != 0) && (respdir != (char *)NULL)) {
43939781SMoriah.Waterland@Sun.COM 			(void) snprintf(respfile_path, sizeof (respfile_path),
43949781SMoriah.Waterland@Sun.COM 					"%s/%s", respdir, pkginst);
43959781SMoriah.Waterland@Sun.COM 			respfile = respfile_path;
43969781SMoriah.Waterland@Sun.COM 		}
43979781SMoriah.Waterland@Sun.COM 
43989781SMoriah.Waterland@Sun.COM 		echo(MSG_PROC_INST, pkginst,
43999781SMoriah.Waterland@Sun.COM 			(a_uri && a_idsName) ? a_uri : a_device);
44009781SMoriah.Waterland@Sun.COM 
44019781SMoriah.Waterland@Sun.COM 		/*
44029781SMoriah.Waterland@Sun.COM 		 * If we're installing another package in the same
44039781SMoriah.Waterland@Sun.COM 		 * session, the second through nth pkginstall, must
44049781SMoriah.Waterland@Sun.COM 		 * continue from where the prior one left off. For this
44059781SMoriah.Waterland@Sun.COM 		 * reason, the continuation feature (implied by the
44069781SMoriah.Waterland@Sun.COM 		 * nature of the command) is used for the remaining
44079781SMoriah.Waterland@Sun.COM 		 * packages.
44089781SMoriah.Waterland@Sun.COM 		 */
44099781SMoriah.Waterland@Sun.COM 
44109781SMoriah.Waterland@Sun.COM 		if ((i == 1) && (pkgdrtarg != (char *)NULL)) {
44119781SMoriah.Waterland@Sun.COM 			pkgcontsrc = pkgdrtarg;
44129781SMoriah.Waterland@Sun.COM 		}
44139781SMoriah.Waterland@Sun.COM 
44149781SMoriah.Waterland@Sun.COM 		/* reset interrupted flag before calling pkginstall */
44159781SMoriah.Waterland@Sun.COM 
44169781SMoriah.Waterland@Sun.COM 		interrupted = 0;	/* last action was NOT quit */
44179781SMoriah.Waterland@Sun.COM 
44189781SMoriah.Waterland@Sun.COM 		/* call pkginstall for this package */
44199781SMoriah.Waterland@Sun.COM 
44209781SMoriah.Waterland@Sun.COM 		n = pkgInstall(get_inst_root(), NULL,
44219781SMoriah.Waterland@Sun.COM 				packageDir, a_altBinDir,
44229781SMoriah.Waterland@Sun.COM 				(char **)NULL);
44239781SMoriah.Waterland@Sun.COM 
44249781SMoriah.Waterland@Sun.COM 		/* set success/fail condition variables */
44259781SMoriah.Waterland@Sun.COM 
44269781SMoriah.Waterland@Sun.COM 		ckreturn(n);
44279781SMoriah.Waterland@Sun.COM 
44289781SMoriah.Waterland@Sun.COM 		/* decrement number of packages left to install */
44299781SMoriah.Waterland@Sun.COM 
44309781SMoriah.Waterland@Sun.COM 		npkgs--;
44319781SMoriah.Waterland@Sun.COM 
44329781SMoriah.Waterland@Sun.COM 		/*
44339781SMoriah.Waterland@Sun.COM 		 * if no packages left to install, unmount package source
44349781SMoriah.Waterland@Sun.COM 		 * device if appropriate
44359781SMoriah.Waterland@Sun.COM 		 */
44369781SMoriah.Waterland@Sun.COM 
44379781SMoriah.Waterland@Sun.COM 		if ((npkgs <= 0) && (pkgdev.mount || a_idsName)) {
44389781SMoriah.Waterland@Sun.COM 			(void) chdir("/");
44399781SMoriah.Waterland@Sun.COM 			if (!a_idsName) {
44409781SMoriah.Waterland@Sun.COM 				(void) pkgumount(&pkgdev);
44419781SMoriah.Waterland@Sun.COM 			}
44429781SMoriah.Waterland@Sun.COM 		}
44439781SMoriah.Waterland@Sun.COM 	}
44449781SMoriah.Waterland@Sun.COM 
44459781SMoriah.Waterland@Sun.COM 	/*
44469781SMoriah.Waterland@Sun.COM 	 * all packages in the package list have been installed.
44479781SMoriah.Waterland@Sun.COM 	 * Continue with installation if:
44489781SMoriah.Waterland@Sun.COM 	 * -- immediate reboot is NOT required
44499781SMoriah.Waterland@Sun.COM 	 * -- there are more packages to install
44509781SMoriah.Waterland@Sun.COM 	 * -- the package source is a path to a file
44519781SMoriah.Waterland@Sun.COM 	 * else return do NOT continue.
44529781SMoriah.Waterland@Sun.COM 	 */
44539781SMoriah.Waterland@Sun.COM 
44549781SMoriah.Waterland@Sun.COM 	if ((ireboot == 0) && (a_repeat != 0) &&
44559781SMoriah.Waterland@Sun.COM 		(pkgdev.pathname == (char *)NULL)) {
44569781SMoriah.Waterland@Sun.COM 		return (B_TRUE);
44579781SMoriah.Waterland@Sun.COM 	}
44589781SMoriah.Waterland@Sun.COM 
44599781SMoriah.Waterland@Sun.COM 	/* return 'dont continue' */
44609781SMoriah.Waterland@Sun.COM 
44619781SMoriah.Waterland@Sun.COM 	return (B_FALSE);
44629781SMoriah.Waterland@Sun.COM }
44639781SMoriah.Waterland@Sun.COM 
44649781SMoriah.Waterland@Sun.COM /*
44659781SMoriah.Waterland@Sun.COM  * Function:	add_packages_in_global_no_zones
44669781SMoriah.Waterland@Sun.COM  * Description: call this function to add a list of packages in the global zone
44679781SMoriah.Waterland@Sun.COM  *		when no non-global zones exist
44689781SMoriah.Waterland@Sun.COM  * returns:
44699781SMoriah.Waterland@Sun.COM  *	B_TRUE to process next data stream
44709781SMoriah.Waterland@Sun.COM  *	B_FALSE to exit
44719781SMoriah.Waterland@Sun.COM  */
44729781SMoriah.Waterland@Sun.COM 
44739781SMoriah.Waterland@Sun.COM static boolean_t
44749781SMoriah.Waterland@Sun.COM add_packages_in_global_no_zones(char **a_pkgList, char *a_uri,
44759781SMoriah.Waterland@Sun.COM 	char *a_idsName, int a_repeat, char *a_altBinDir, char *a_device)
44769781SMoriah.Waterland@Sun.COM {
44779781SMoriah.Waterland@Sun.COM 	int		n;
44789781SMoriah.Waterland@Sun.COM 	int		i;
44799781SMoriah.Waterland@Sun.COM 	char		respfile_path[PATH_MAX];
44809781SMoriah.Waterland@Sun.COM 	CAF_T		flags = 0;
44819781SMoriah.Waterland@Sun.COM 
44829781SMoriah.Waterland@Sun.COM 	/* entry assertions */
44839781SMoriah.Waterland@Sun.COM 
44849781SMoriah.Waterland@Sun.COM 	assert(a_pkgList != (char **)NULL);
44859781SMoriah.Waterland@Sun.COM 
44869781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_ADDPACKAGES_GZ_NO_LZ_ENTRY);
44879781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_ADDPACKAGES_GZ_NO_LZ_ARGS, npkgs, PSTR(a_uri),
44889781SMoriah.Waterland@Sun.COM 		PSTR(a_idsName), a_repeat, PSTR(a_device));
44899781SMoriah.Waterland@Sun.COM 
44909781SMoriah.Waterland@Sun.COM 	/*
44919781SMoriah.Waterland@Sun.COM 	 * set flags for applicability check
44929781SMoriah.Waterland@Sun.COM 	 */
44939781SMoriah.Waterland@Sun.COM 
44949781SMoriah.Waterland@Sun.COM 	/* in the global zone */
44959781SMoriah.Waterland@Sun.COM 
44969781SMoriah.Waterland@Sun.COM 	flags |= CAF_IN_GLOBAL_ZONE;
44979781SMoriah.Waterland@Sun.COM 
44989781SMoriah.Waterland@Sun.COM 	/* set -G flag */
44999781SMoriah.Waterland@Sun.COM 
45009781SMoriah.Waterland@Sun.COM 	if (globalZoneOnly == B_TRUE) {
45019781SMoriah.Waterland@Sun.COM 		flags |= CAF_SCOPE_GLOBAL;
45029781SMoriah.Waterland@Sun.COM 	}
45039781SMoriah.Waterland@Sun.COM 
45049781SMoriah.Waterland@Sun.COM 	/*
45059781SMoriah.Waterland@Sun.COM 	 * this is the main loop where all of the packages (as listed in the
45069781SMoriah.Waterland@Sun.COM 	 * package list) are added one at a time.
45079781SMoriah.Waterland@Sun.COM 	 */
45089781SMoriah.Waterland@Sun.COM 
45099781SMoriah.Waterland@Sun.COM 	for (i = 0; (pkginst = a_pkgList[i]) != NULL; i++) {
45109781SMoriah.Waterland@Sun.COM 		/*
45119781SMoriah.Waterland@Sun.COM 		 * if immediate reboot required from last package and this is
45129781SMoriah.Waterland@Sun.COM 		 * not 'pkgask' then suspend installation of remaining packages
45139781SMoriah.Waterland@Sun.COM 		 */
45149781SMoriah.Waterland@Sun.COM 
45159781SMoriah.Waterland@Sun.COM 		if ((ireboot != 0) && (askflag == 0)) {
45169781SMoriah.Waterland@Sun.COM 			ptext(stderr, MSG_SUSPEND_ADD, pkginst);
45179781SMoriah.Waterland@Sun.COM 				continue;
45189781SMoriah.Waterland@Sun.COM 		}
45199781SMoriah.Waterland@Sun.COM 
45209781SMoriah.Waterland@Sun.COM 		/*
45219781SMoriah.Waterland@Sun.COM 		 * handle interrupt if the previous pkginstall was interrupted
45229781SMoriah.Waterland@Sun.COM 		 */
45239781SMoriah.Waterland@Sun.COM 
45249781SMoriah.Waterland@Sun.COM 		if (continue_installation() == B_FALSE) {
45259781SMoriah.Waterland@Sun.COM 			return (B_FALSE);
45269781SMoriah.Waterland@Sun.COM 		}
45279781SMoriah.Waterland@Sun.COM 
45289781SMoriah.Waterland@Sun.COM 		/*
45299781SMoriah.Waterland@Sun.COM 		 * check package applicability to install in this context
45309781SMoriah.Waterland@Sun.COM 		 */
45319781SMoriah.Waterland@Sun.COM 
45329781SMoriah.Waterland@Sun.COM 		if (check_applicability(pkgdev.dirname,
45339781SMoriah.Waterland@Sun.COM 			pkginst, get_inst_root(), flags) == B_FALSE) {
45349781SMoriah.Waterland@Sun.COM 			progerr(ERR_PKG_NOT_APPLICABLE, pkginst);
45359781SMoriah.Waterland@Sun.COM 			quit(1);
45369781SMoriah.Waterland@Sun.COM 		}
45379781SMoriah.Waterland@Sun.COM 
45389781SMoriah.Waterland@Sun.COM 		/*
45399781SMoriah.Waterland@Sun.COM 		 * if pkgask, handle response file creation:
45409781SMoriah.Waterland@Sun.COM 		 * - if the response file is a directory, then create a path to
45419781SMoriah.Waterland@Sun.COM 		 * -- a package instance within the response file directory.
45429781SMoriah.Waterland@Sun.COM 		 * - If the response file is NOT a directory, if more than one
45439781SMoriah.Waterland@Sun.COM 		 * -- package is to be installed.
45449781SMoriah.Waterland@Sun.COM 		 */
45459781SMoriah.Waterland@Sun.COM 
45469781SMoriah.Waterland@Sun.COM 		if ((askflag != 0) && (respdir != (char *)NULL)) {
45479781SMoriah.Waterland@Sun.COM 			(void) snprintf(respfile_path, sizeof (respfile_path),
45489781SMoriah.Waterland@Sun.COM 					"%s/%s", respdir, pkginst);
45499781SMoriah.Waterland@Sun.COM 			respfile = respfile_path;
45509781SMoriah.Waterland@Sun.COM 		}
45519781SMoriah.Waterland@Sun.COM 
45529781SMoriah.Waterland@Sun.COM 		echo(MSG_PROC_INST, pkginst,
45539781SMoriah.Waterland@Sun.COM 			(a_uri && a_idsName) ? a_uri : a_device);
45549781SMoriah.Waterland@Sun.COM 
45559781SMoriah.Waterland@Sun.COM 		/*
45569781SMoriah.Waterland@Sun.COM 		 * If we're installing another package in the same
45579781SMoriah.Waterland@Sun.COM 		 * session, the second through nth pkginstall, must
45589781SMoriah.Waterland@Sun.COM 		 * continue from where the prior one left off. For this
45599781SMoriah.Waterland@Sun.COM 		 * reason, the continuation feature (implied by the
45609781SMoriah.Waterland@Sun.COM 		 * nature of the command) is used for the remaining
45619781SMoriah.Waterland@Sun.COM 		 * packages.
45629781SMoriah.Waterland@Sun.COM 		 */
45639781SMoriah.Waterland@Sun.COM 
45649781SMoriah.Waterland@Sun.COM 		if ((i == 1) && (pkgdrtarg != (char *)NULL)) {
45659781SMoriah.Waterland@Sun.COM 			pkgcontsrc = pkgdrtarg;
45669781SMoriah.Waterland@Sun.COM 		}
45679781SMoriah.Waterland@Sun.COM 
45689781SMoriah.Waterland@Sun.COM 		/* reset interrupted flag before calling pkginstall */
45699781SMoriah.Waterland@Sun.COM 
45709781SMoriah.Waterland@Sun.COM 		interrupted = 0;	/* last action was NOT quit */
45719781SMoriah.Waterland@Sun.COM 
45729781SMoriah.Waterland@Sun.COM 		/* call pkginstall for this package */
45739781SMoriah.Waterland@Sun.COM 
45749781SMoriah.Waterland@Sun.COM 		n = pkgInstall(get_inst_root(), a_idsName,
45759781SMoriah.Waterland@Sun.COM 				pkgdev.dirname, a_altBinDir,
45769781SMoriah.Waterland@Sun.COM 				z_get_inherited_file_systems());
45779781SMoriah.Waterland@Sun.COM 
45789781SMoriah.Waterland@Sun.COM 		/* set success/fail condition variables */
45799781SMoriah.Waterland@Sun.COM 
45809781SMoriah.Waterland@Sun.COM 		ckreturn(n);
45819781SMoriah.Waterland@Sun.COM 
45829781SMoriah.Waterland@Sun.COM 		/* decrement number of packages left to install */
45839781SMoriah.Waterland@Sun.COM 
45849781SMoriah.Waterland@Sun.COM 		npkgs--;
45859781SMoriah.Waterland@Sun.COM 
45869781SMoriah.Waterland@Sun.COM 		/*
45879781SMoriah.Waterland@Sun.COM 		 * if no packages left to install, unmount package source
45889781SMoriah.Waterland@Sun.COM 		 * device if appropriate
45899781SMoriah.Waterland@Sun.COM 		 */
45909781SMoriah.Waterland@Sun.COM 
45919781SMoriah.Waterland@Sun.COM 		if ((npkgs <= 0) && (pkgdev.mount || a_idsName)) {
45929781SMoriah.Waterland@Sun.COM 			(void) chdir("/");
45939781SMoriah.Waterland@Sun.COM 			if (!a_idsName) {
45949781SMoriah.Waterland@Sun.COM 				(void) pkgumount(&pkgdev);
45959781SMoriah.Waterland@Sun.COM 			}
45969781SMoriah.Waterland@Sun.COM 		}
45979781SMoriah.Waterland@Sun.COM 	}
45989781SMoriah.Waterland@Sun.COM 
45999781SMoriah.Waterland@Sun.COM 	/*
46009781SMoriah.Waterland@Sun.COM 	 * all packages in the package list have been installed.
46019781SMoriah.Waterland@Sun.COM 	 * Continue with installation if:
46029781SMoriah.Waterland@Sun.COM 	 * -- immediate reboot is NOT required
46039781SMoriah.Waterland@Sun.COM 	 * -- there are more packages to install
46049781SMoriah.Waterland@Sun.COM 	 * -- the package source is a path to a file
46059781SMoriah.Waterland@Sun.COM 	 * else return do NOT continue.
46069781SMoriah.Waterland@Sun.COM 	 */
46079781SMoriah.Waterland@Sun.COM 
46089781SMoriah.Waterland@Sun.COM 	if ((ireboot == 0) && (a_repeat != 0) &&
46099781SMoriah.Waterland@Sun.COM 		(pkgdev.pathname == (char *)NULL)) {
46109781SMoriah.Waterland@Sun.COM 		return (B_TRUE);
46119781SMoriah.Waterland@Sun.COM 	}
46129781SMoriah.Waterland@Sun.COM 
46139781SMoriah.Waterland@Sun.COM 	/* return 'dont continue' */
46149781SMoriah.Waterland@Sun.COM 
46159781SMoriah.Waterland@Sun.COM 	return (B_FALSE);
46169781SMoriah.Waterland@Sun.COM }
46179781SMoriah.Waterland@Sun.COM 
46189781SMoriah.Waterland@Sun.COM /*
46199781SMoriah.Waterland@Sun.COM  * returns:
46209781SMoriah.Waterland@Sun.COM  *	B_TRUE to process next data stream
46219781SMoriah.Waterland@Sun.COM  *	B_FALSE to exit
46229781SMoriah.Waterland@Sun.COM  */
46239781SMoriah.Waterland@Sun.COM 
46249781SMoriah.Waterland@Sun.COM static boolean_t
46259781SMoriah.Waterland@Sun.COM add_packages(char **a_pkgList, char *a_uri,
46269781SMoriah.Waterland@Sun.COM 	char *a_idsName, int a_repeat, char *a_altBinDir, char *a_device,
46279781SMoriah.Waterland@Sun.COM 	boolean_t a_noZones)
46289781SMoriah.Waterland@Sun.COM {
46299781SMoriah.Waterland@Sun.COM 	zoneList_t	zlst;
46309781SMoriah.Waterland@Sun.COM 	boolean_t	b;
46319781SMoriah.Waterland@Sun.COM 
46329781SMoriah.Waterland@Sun.COM 	/* entry assertions */
46339781SMoriah.Waterland@Sun.COM 
46349781SMoriah.Waterland@Sun.COM 	assert(a_pkgList != (char **)NULL);
46359781SMoriah.Waterland@Sun.COM 
46369781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_ADDPACKAGES_ENTRY);
46379781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_ADDPACKAGES_ARGS, npkgs, PSTR(a_uri), PSTR(a_idsName),
46389781SMoriah.Waterland@Sun.COM 		a_repeat, PSTR(a_altBinDir), PSTR(a_device));
46399781SMoriah.Waterland@Sun.COM 
46409781SMoriah.Waterland@Sun.COM 	/*
46419781SMoriah.Waterland@Sun.COM 	 * if running in the global zone AND one or more non-global
46429781SMoriah.Waterland@Sun.COM 	 * zones exist, add packages in a 'zones aware' manner, else
46439781SMoriah.Waterland@Sun.COM 	 * add packages in the standard 'non-zones aware' manner.
46449781SMoriah.Waterland@Sun.COM 	 */
46459781SMoriah.Waterland@Sun.COM 
46469781SMoriah.Waterland@Sun.COM 	if ((a_noZones == B_FALSE) && (z_running_in_global_zone() == B_FALSE)) {
46479781SMoriah.Waterland@Sun.COM 		/* in non-global zone */
46489781SMoriah.Waterland@Sun.COM 
46499781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_IN_LZ);
46509781SMoriah.Waterland@Sun.COM 
46519781SMoriah.Waterland@Sun.COM 		b = z_lock_this_zone(ZLOCKS_PKG_ADMIN);
46529781SMoriah.Waterland@Sun.COM 		if (b != B_TRUE) {
46539781SMoriah.Waterland@Sun.COM 			progerr(ERR_CANNOT_LOCK_THIS_ZONE);
46549781SMoriah.Waterland@Sun.COM 			/* set fatal error return condition */
46559781SMoriah.Waterland@Sun.COM 			ckreturn(1);
46569781SMoriah.Waterland@Sun.COM 			return (B_FALSE);
46579781SMoriah.Waterland@Sun.COM 		}
46589781SMoriah.Waterland@Sun.COM 
46599781SMoriah.Waterland@Sun.COM 		b = add_packages_in_nonglobal_zone(a_pkgList, a_uri, a_idsName,
46609781SMoriah.Waterland@Sun.COM 			a_repeat, a_altBinDir, a_device);
46619781SMoriah.Waterland@Sun.COM 
46629781SMoriah.Waterland@Sun.COM 		(void) z_unlock_this_zone(ZLOCKS_ALL);
46639781SMoriah.Waterland@Sun.COM 
46649781SMoriah.Waterland@Sun.COM 		return (B_FALSE);
46659781SMoriah.Waterland@Sun.COM 	}
46669781SMoriah.Waterland@Sun.COM 
46679781SMoriah.Waterland@Sun.COM 	/* running in the global zone */
46689781SMoriah.Waterland@Sun.COM 
46699781SMoriah.Waterland@Sun.COM 	b = z_non_global_zones_exist();
46709781SMoriah.Waterland@Sun.COM 	if ((a_noZones == B_FALSE) && (b == B_TRUE) &&
46719781SMoriah.Waterland@Sun.COM 					(globalZoneOnly == B_FALSE)) {
46729781SMoriah.Waterland@Sun.COM 
46739781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_IN_GZ_WITH_LZ);
46749781SMoriah.Waterland@Sun.COM 
46759781SMoriah.Waterland@Sun.COM 		/* error if -V specified - what to use in non-global zone? */
46769781SMoriah.Waterland@Sun.COM 
46779781SMoriah.Waterland@Sun.COM 		if (vfstab_file) {
46789781SMoriah.Waterland@Sun.COM 			progerr(ERR_V_USED_WITH_GZS);
46799781SMoriah.Waterland@Sun.COM 			quit(1);
46809781SMoriah.Waterland@Sun.COM 		}
46819781SMoriah.Waterland@Sun.COM 
46829781SMoriah.Waterland@Sun.COM 		/* get a list of all non-global zones */
46839781SMoriah.Waterland@Sun.COM 		zlst = z_get_nonglobal_zone_list();
46849781SMoriah.Waterland@Sun.COM 		if (zlst == (zoneList_t)NULL) {
46859781SMoriah.Waterland@Sun.COM 			progerr(ERR_CANNOT_GET_ZONE_LIST);
46869781SMoriah.Waterland@Sun.COM 			quit(1);
46879781SMoriah.Waterland@Sun.COM 		}
46889781SMoriah.Waterland@Sun.COM 
46899781SMoriah.Waterland@Sun.COM 		/* need to lock all of the zones */
46909781SMoriah.Waterland@Sun.COM 
46919781SMoriah.Waterland@Sun.COM 		quitSetZonelist(zlst);
46929781SMoriah.Waterland@Sun.COM 		b = z_lock_zones(zlst, ZLOCKS_PKG_ADMIN);
46939781SMoriah.Waterland@Sun.COM 		if (b == B_FALSE) {
46949781SMoriah.Waterland@Sun.COM 			z_free_zone_list(zlst);
46959781SMoriah.Waterland@Sun.COM 			progerr(ERR_CANNOT_LOCK_ZONES);
46969781SMoriah.Waterland@Sun.COM 			/* set fatal error return condition */
46979781SMoriah.Waterland@Sun.COM 			ckreturn(1);
46989781SMoriah.Waterland@Sun.COM 			return (B_FALSE);
46999781SMoriah.Waterland@Sun.COM 		}
47009781SMoriah.Waterland@Sun.COM 
47019781SMoriah.Waterland@Sun.COM 		/* add packages to all zones */
47029781SMoriah.Waterland@Sun.COM 
47039781SMoriah.Waterland@Sun.COM 		b = add_packages_in_global_with_zones(a_pkgList, a_uri,
47049781SMoriah.Waterland@Sun.COM 			a_idsName, a_repeat, a_altBinDir, a_device, zlst);
47059781SMoriah.Waterland@Sun.COM 
47069781SMoriah.Waterland@Sun.COM 		/* unlock all zones */
47079781SMoriah.Waterland@Sun.COM 
47089781SMoriah.Waterland@Sun.COM 		(void) z_unlock_zones(zlst, ZLOCKS_ALL);
47099781SMoriah.Waterland@Sun.COM 		quitSetZonelist((zoneList_t)NULL);
47109781SMoriah.Waterland@Sun.COM 
47119781SMoriah.Waterland@Sun.COM 		/* free list of all non-global zones */
47129781SMoriah.Waterland@Sun.COM 
47139781SMoriah.Waterland@Sun.COM 		z_free_zone_list(zlst);
47149781SMoriah.Waterland@Sun.COM 
47159781SMoriah.Waterland@Sun.COM 		return (B_FALSE);
47169781SMoriah.Waterland@Sun.COM 	}
47179781SMoriah.Waterland@Sun.COM 
47189781SMoriah.Waterland@Sun.COM 	/* in global zone no non-global zones */
47199781SMoriah.Waterland@Sun.COM 
47209781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_IN_GZ_NO_LZ);
47219781SMoriah.Waterland@Sun.COM 
47229781SMoriah.Waterland@Sun.COM 	b = z_lock_this_zone(ZLOCKS_PKG_ADMIN);
47239781SMoriah.Waterland@Sun.COM 	if (b != B_TRUE) {
47249781SMoriah.Waterland@Sun.COM 		progerr(ERR_CANNOT_LOCK_THIS_ZONE);
47259781SMoriah.Waterland@Sun.COM 		/* set fatal error return condition */
47269781SMoriah.Waterland@Sun.COM 		ckreturn(1);
47279781SMoriah.Waterland@Sun.COM 		return (B_FALSE);
47289781SMoriah.Waterland@Sun.COM 	}
47299781SMoriah.Waterland@Sun.COM 
47309781SMoriah.Waterland@Sun.COM 	b = add_packages_in_global_no_zones(a_pkgList, a_uri, a_idsName,
47319781SMoriah.Waterland@Sun.COM 		a_repeat, a_altBinDir, a_device);
47329781SMoriah.Waterland@Sun.COM 
47339781SMoriah.Waterland@Sun.COM 	(void) z_unlock_this_zone(ZLOCKS_ALL);
47349781SMoriah.Waterland@Sun.COM 
47359781SMoriah.Waterland@Sun.COM 	return (B_FALSE);
47369781SMoriah.Waterland@Sun.COM }
4737