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