xref: /titanic_52/usr/src/cmd/svr4pkg/pkgadd/main.c (revision 62224350e5355e6834f7deb9d8a7d062a50cb7c2)
15c51f124SMoriah Waterland /*
25c51f124SMoriah Waterland  * CDDL HEADER START
35c51f124SMoriah Waterland  *
45c51f124SMoriah Waterland  * The contents of this file are subject to the terms of the
55c51f124SMoriah Waterland  * Common Development and Distribution License (the "License").
65c51f124SMoriah Waterland  * You may not use this file except in compliance with the License.
75c51f124SMoriah Waterland  *
85c51f124SMoriah Waterland  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
95c51f124SMoriah Waterland  * or http://www.opensolaris.org/os/licensing.
105c51f124SMoriah Waterland  * See the License for the specific language governing permissions
115c51f124SMoriah Waterland  * and limitations under the License.
125c51f124SMoriah Waterland  *
135c51f124SMoriah Waterland  * When distributing Covered Code, include this CDDL HEADER in each
145c51f124SMoriah Waterland  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
155c51f124SMoriah Waterland  * If applicable, add the following below this CDDL HEADER, with the
165c51f124SMoriah Waterland  * fields enclosed by brackets "[]" replaced with your own identifying
175c51f124SMoriah Waterland  * information: Portions Copyright [yyyy] [name of copyright owner]
185c51f124SMoriah Waterland  *
195c51f124SMoriah Waterland  * CDDL HEADER END
205c51f124SMoriah Waterland  */
215c51f124SMoriah Waterland 
225c51f124SMoriah Waterland /*
235c51f124SMoriah Waterland  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
245c51f124SMoriah Waterland  * Use is subject to license terms.
255c51f124SMoriah Waterland  */
265c51f124SMoriah Waterland 
275c51f124SMoriah Waterland /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
285c51f124SMoriah Waterland /* All Rights Reserved */
295c51f124SMoriah Waterland 
305c51f124SMoriah Waterland 
315c51f124SMoriah Waterland /*
325c51f124SMoriah Waterland  * Program:	pkgadd / pkgask
335c51f124SMoriah Waterland  *
345c51f124SMoriah Waterland  * Function:	public command and private utility functions that
355c51f124SMoriah Waterland  *		implement the package add and package ask operations.
365c51f124SMoriah Waterland  *
375c51f124SMoriah Waterland  */
385c51f124SMoriah Waterland 
395c51f124SMoriah Waterland /*
405c51f124SMoriah Waterland  * System includes
415c51f124SMoriah Waterland  */
425c51f124SMoriah Waterland 
435c51f124SMoriah Waterland #include <stdio.h>
445c51f124SMoriah Waterland #include <limits.h>
455c51f124SMoriah Waterland #include <stdlib.h>
465c51f124SMoriah Waterland #include <unistd.h>
475c51f124SMoriah Waterland #include <string.h>
485c51f124SMoriah Waterland #include <fcntl.h>
495c51f124SMoriah Waterland #include <sys/types.h>
505c51f124SMoriah Waterland #include <sys/stat.h>
515c51f124SMoriah Waterland #include <signal.h>
525c51f124SMoriah Waterland #include <errno.h>
535c51f124SMoriah Waterland #include <pkgdev.h>
545c51f124SMoriah Waterland #include <pkginfo.h>
555c51f124SMoriah Waterland #include <pkglocs.h>
565c51f124SMoriah Waterland #include <locale.h>
575c51f124SMoriah Waterland #include <libintl.h>
585c51f124SMoriah Waterland #include <pkgtrans.h>
595c51f124SMoriah Waterland #include <boot_http.h>
605c51f124SMoriah Waterland #include <assert.h>
615c51f124SMoriah Waterland 
625c51f124SMoriah Waterland /*
635c51f124SMoriah Waterland  * consolidation pkg command library includes
645c51f124SMoriah Waterland  */
655c51f124SMoriah Waterland #include <pkglib.h>
665c51f124SMoriah Waterland #include <pkgerr.h>
675c51f124SMoriah Waterland #include <pkgweb.h>
685c51f124SMoriah Waterland 
695c51f124SMoriah Waterland #include <instzones_api.h>
705c51f124SMoriah Waterland 
715c51f124SMoriah Waterland /*
725c51f124SMoriah Waterland  * local pkg command library includes
735c51f124SMoriah Waterland  */
745c51f124SMoriah Waterland #include <install.h>
755c51f124SMoriah Waterland #include <libinst.h>
765c51f124SMoriah Waterland #include <libadm.h>
775c51f124SMoriah Waterland #include <messages.h>
785c51f124SMoriah Waterland 
795c51f124SMoriah Waterland 
805c51f124SMoriah Waterland /*
815c51f124SMoriah Waterland  * pkgadd local includes
825c51f124SMoriah Waterland  */
835c51f124SMoriah Waterland 
845c51f124SMoriah Waterland #include "quit.h"
855c51f124SMoriah Waterland 
865c51f124SMoriah Waterland /*
875c51f124SMoriah Waterland  * imported global variables/functions
885c51f124SMoriah Waterland  */
895c51f124SMoriah Waterland 
905c51f124SMoriah Waterland /* presvr4.c */
915c51f124SMoriah Waterland extern int	presvr4(char **ppkg, int a_nointeract);
925c51f124SMoriah Waterland 
935c51f124SMoriah Waterland /* check.c */
945c51f124SMoriah Waterland extern int	preinstall_verify(char **a_pkgList, zoneList_t a_zlst,
955c51f124SMoriah Waterland 			char *a_zoneTempDir);
965c51f124SMoriah Waterland 
975c51f124SMoriah Waterland /*
985c51f124SMoriah Waterland  * ckquit is a global that controls 'ckyorn' (defined in libadm)
995c51f124SMoriah Waterland  * If ckquit is non-zero, then "quit" is allowed as an answer when
1005c51f124SMoriah Waterland  * ckyorn is called. If is it zero, then "quit" is not an allowed answer.
1015c51f124SMoriah Waterland  */
1025c51f124SMoriah Waterland extern int	ckquit;
1035c51f124SMoriah Waterland 
1045c51f124SMoriah Waterland /*
1055c51f124SMoriah Waterland  * exported global variables
1065c51f124SMoriah Waterland  */
1075c51f124SMoriah Waterland 
1085c51f124SMoriah Waterland /* these globals are set by ckreturn and used by quit.c */
1095c51f124SMoriah Waterland 
1105c51f124SMoriah Waterland int	admnflag = 0;	/* != 0 if any pkg op admin setting failure (4) */
1115c51f124SMoriah Waterland int	doreboot = 0;	/* != 0 if reboot required after installation */
1125c51f124SMoriah Waterland int	failflag = 0;	/* != 0 if fatal error has occurred (1) */
1135c51f124SMoriah Waterland int	intrflag = 0;	/* != 0 if user selected quit (3) */
1145c51f124SMoriah Waterland int	ireboot = 0;	/* != 0 if immediate reboot required */
1155c51f124SMoriah Waterland int	nullflag = 0;	/* != 0 if admin interaction required (5) */
1165c51f124SMoriah Waterland int	warnflag = 0;	/* != 0 if non-fatal error has occurred (2) */
1175c51f124SMoriah Waterland 
1185c51f124SMoriah Waterland /* imported by quit.c */
1195c51f124SMoriah Waterland int	npkgs = 0;	/* the number of packages yet to be installed */
1205c51f124SMoriah Waterland 
1215c51f124SMoriah Waterland /* imported by various (many) */
1225c51f124SMoriah Waterland char	*respfile = NULL;	/* response pathname (or NULL) */
1235c51f124SMoriah Waterland char	*tmpdir = NULL;		/* location to place temporary files */
1245c51f124SMoriah Waterland 
1255c51f124SMoriah Waterland struct admin	adm;		/* holds info about installation admin */
1265c51f124SMoriah Waterland struct pkgdev	pkgdev;		/* holds info about the installation device */
1275c51f124SMoriah Waterland 
1285c51f124SMoriah Waterland /*
1295c51f124SMoriah Waterland  * internal global variables
1305c51f124SMoriah Waterland  */
1315c51f124SMoriah Waterland 
1325c51f124SMoriah Waterland static char	*admnfile = NULL;	/* file to use for installation admin */
1335c51f124SMoriah Waterland static char	*ids_name = NULL;	/* name of data stream device */
1345c51f124SMoriah Waterland static char	*pkgcontsrc = NULL;	/* continuation file (-c option) */
1355c51f124SMoriah Waterland static char	*pkgdrtarg = NULL;	/* dry run file (-D option) */
1365c51f124SMoriah Waterland static char	*pkginst = NULL;	/* current pkg/src instance 2 process */
1375c51f124SMoriah Waterland static char	*respdir = NULL;	/* respfile is a directory spec */
1385c51f124SMoriah Waterland static char	*rw_block_size = NULL;
1395c51f124SMoriah Waterland static char	*vfstab_file = NULL;
1405c51f124SMoriah Waterland static int	askflag = 0;		/* non-zero if invoked as "pkgask" */
1415c51f124SMoriah Waterland static int	disableAttributes = 0;	/* Disabling attribute checking */
1425c51f124SMoriah Waterland static int	disableChecksum = 0;	/* Disable checksumming */
1435c51f124SMoriah Waterland static int	disableSaveSpool = 0;	/* Disable partial spool dir create */
1445c51f124SMoriah Waterland static int	init_install = 0;	/* inform scripts initial install */
1455c51f124SMoriah Waterland static int	no_map_client = 0;	/* do not map from vfstab file */
1465c51f124SMoriah Waterland static int	nointeract = 0;		/* non-zero - no user interaction */
1475c51f124SMoriah Waterland static int	pkgverbose = 0;		/* non-zero if verbose mode selected */
1485c51f124SMoriah Waterland static int	saveSpoolInstall = 0;	/* installing from save spool dir */
1495c51f124SMoriah Waterland static int	suppressCopyright = 0;	/* suppress copyright notices */
1505c51f124SMoriah Waterland 
1515c51f124SMoriah Waterland /* set by ckreturn() */
1525c51f124SMoriah Waterland 
1535c51f124SMoriah Waterland static int	interrupted = 0;	/* last pkg op was quit (1,2,3,4,5) */
1545c51f124SMoriah Waterland static int	needconsult = 0;	/* essential ask admin now (1,2,3,5) */
1555c51f124SMoriah Waterland 
1565c51f124SMoriah Waterland /* Set by -O nozones: do not process any zones */
1575c51f124SMoriah Waterland 
1585c51f124SMoriah Waterland static boolean_t	noZones = B_FALSE;
1595c51f124SMoriah Waterland 
1605c51f124SMoriah Waterland /* Set by -O zonelist=<names...>: process only named zones */
1615c51f124SMoriah Waterland 
1625c51f124SMoriah Waterland static boolean_t	usedZoneList = B_FALSE;
1635c51f124SMoriah Waterland 
1645c51f124SMoriah Waterland /* Set by -O debug: debug output is enabled? */
1655c51f124SMoriah Waterland 
1665c51f124SMoriah Waterland static boolean_t	debugFlag = B_FALSE;
1675c51f124SMoriah Waterland 
1685c51f124SMoriah Waterland /* Set by the -G option: install packages in global zone only */
1695c51f124SMoriah Waterland 
1705c51f124SMoriah Waterland static boolean_t	globalZoneOnly = B_FALSE;
1715c51f124SMoriah Waterland 
1725c51f124SMoriah Waterland /* Set by -O patchPkgRemoval */
1735c51f124SMoriah Waterland 
1745c51f124SMoriah Waterland static boolean_t	patchPkgRemoval = B_FALSE;
1755c51f124SMoriah Waterland 
1765c51f124SMoriah Waterland /*
1775c51f124SMoriah Waterland  * Assume the package is ABI and POSIX compliant as regards user
1785c51f124SMoriah Waterland  * interactiion during procedure scripts.
1795c51f124SMoriah Waterland  */
1805c51f124SMoriah Waterland 
1815c51f124SMoriah Waterland static int	old_pkg = 0;
1825c51f124SMoriah Waterland 
1835c51f124SMoriah Waterland /* Assume pkg should be installed according to the ABI */
1845c51f124SMoriah Waterland 
1855c51f124SMoriah Waterland static int	old_symlinks = 0;
1865c51f124SMoriah Waterland 
1875c51f124SMoriah Waterland /*
1885c51f124SMoriah Waterland  * Default name length will be 32 chars - if this is set,
1895c51f124SMoriah Waterland  * disable the 32 char name limit extension
1905c51f124SMoriah Waterland  */
1915c51f124SMoriah Waterland 
1925c51f124SMoriah Waterland static int	ABI_namelength = 0;
1935c51f124SMoriah Waterland 
1945c51f124SMoriah Waterland #if	!defined(TEXT_DOMAIN)	/* Should be defined by cc -D */
1955c51f124SMoriah Waterland #define	TEXT_DOMAIN	"SYS_TEST"
1965c51f124SMoriah Waterland #endif
1975c51f124SMoriah Waterland 
1985c51f124SMoriah Waterland /* printable string - if string is null results in ??? */
1995c51f124SMoriah Waterland 
2005c51f124SMoriah Waterland #define	PSTR(STR) (((STR) == (char *)NULL) ? "???" : (STR))
2015c51f124SMoriah Waterland 
2025c51f124SMoriah Waterland #define	MAX_FDS	20
2035c51f124SMoriah Waterland 
2045c51f124SMoriah Waterland #define	INHERITFS	"inherited-filesystem="
2055c51f124SMoriah Waterland #define	INHERITFS_LEN	((sizeof (INHERITFS))-1)
2065c51f124SMoriah Waterland 
2075c51f124SMoriah Waterland /*
2085c51f124SMoriah Waterland  * forward declarations
2095c51f124SMoriah Waterland  */
2105c51f124SMoriah Waterland 
2115c51f124SMoriah Waterland static int		boot_and_pkginstall_check_in_zones(zoneList_t a_zlst,
2125c51f124SMoriah Waterland 				char *a_idsName, char *a_altBinDir,
2135c51f124SMoriah Waterland 				char *a_zoneAdminFile, char *a_zoneTempDir);
2145c51f124SMoriah Waterland static int		boot_and_install_in_zones(zoneList_t a_zlst,
2155c51f124SMoriah Waterland 				char *a_idsName, char *a_altBinDir,
2165c51f124SMoriah Waterland 				char *a_zoneAdminFile, char *a_zoneTempDir);
2175c51f124SMoriah Waterland static void		pkginstall_check_in_one_zone(char **a_inheritedPkgDirs,
2185c51f124SMoriah Waterland 				char *a_zoneName, char *a_idsName,
2195c51f124SMoriah Waterland 				char *a_zoneAdminFile, char *a_zoneTempDir,
2205c51f124SMoriah Waterland 				char *a_altBinDir, char *a_scratchName,
221*62224350SCasper H.S. Dik 				zone_state_t a_zoneState, boolean_t a_tmpzn);
2225c51f124SMoriah Waterland static void		ckreturn(int retcode);
2235c51f124SMoriah Waterland static void		create_zone_adminfile(char **r_zoneAdminFile,
2245c51f124SMoriah Waterland 				char *a_zoneTempDir, char *a_admnfile);
2255c51f124SMoriah Waterland static void		create_zone_tempdir(char **r_zoneTempDir,
2265c51f124SMoriah Waterland 				char *a_tmpdir);
2275c51f124SMoriah Waterland static void		install_in_one_zone(char **a_inheritedPkgDirs,
2285c51f124SMoriah Waterland 				char *a_zoneName, char *a_idsName,
2295c51f124SMoriah Waterland 				char *a_zoneAdminFile, char *a_zoneTempDir,
230*62224350SCasper H.S. Dik 				char *a_altBinDir, zone_state_t a_zoneState,
231*62224350SCasper H.S. Dik 				boolean_t a_tmpzn);
2325c51f124SMoriah Waterland static int		pkginstall_check_in_zones(zoneList_t a_zlst,
2335c51f124SMoriah Waterland 				char *a_idsName, char *a_altBinDir,
2345c51f124SMoriah Waterland 				char *a_zoneAdminFile, char *a_zoneTempDir);
2355c51f124SMoriah Waterland static int		install_in_zones(zoneList_t a_zlst, char *a_idsName,
2365c51f124SMoriah Waterland 				char *a_altBinDir, char *a_zoneAdminFile,
2375c51f124SMoriah Waterland 				char *a_zoneTempDir);
2385c51f124SMoriah Waterland static int		pkgInstall(char *ir, char *a_idsName, char *a_pkgDir,
2395c51f124SMoriah Waterland 				char *a_altBinDir, char **a_inheritedPkgDirs);
2405c51f124SMoriah Waterland static int		pkgZoneCheckInstall(char *a_zoneName,
2415c51f124SMoriah Waterland 				char **a_inheritedPkgDirs,
2425c51f124SMoriah Waterland 				zone_state_t a_zoneState,
2435c51f124SMoriah Waterland 				char *a_idsName, char *a_altBinDir,
244*62224350SCasper H.S. Dik 				char *a_adminFile, char *a_stdoutPath,
245*62224350SCasper H.S. Dik 				boolean_t a_tmpzn);
2465c51f124SMoriah Waterland static int		pkgZoneInstall(char *a_zoneName,
2475c51f124SMoriah Waterland 				char **a_inheritedPkgDirs,
2485c51f124SMoriah Waterland 				zone_state_t a_zoneState,
2495c51f124SMoriah Waterland 				char *a_idsName, char *a_altBinDir,
250*62224350SCasper H.S. Dik 				char *a_adminFile, boolean_t a_tmpzn);
2515c51f124SMoriah Waterland static void		resetreturn();
2525c51f124SMoriah Waterland static void		usage(void);
2535c51f124SMoriah Waterland static boolean_t	add_packages(char **a_pkgList, char *a_uri,
2545c51f124SMoriah Waterland 				char *a_idsName, int a_repeat,
2555c51f124SMoriah Waterland 				char *a_altBinDir, char *a_device,
2565c51f124SMoriah Waterland 				boolean_t a_noZones);
2575c51f124SMoriah Waterland static boolean_t	add_packages_in_global_no_zones(char **a_pkgList,
2585c51f124SMoriah Waterland 				char *a_uri, char *a_idsName, int a_repeat,
2595c51f124SMoriah Waterland 				char *a_altBinDir, char *a_device);
2605c51f124SMoriah Waterland static boolean_t	add_packages_in_global_with_zones(char **a_pkgList,
2615c51f124SMoriah Waterland 				char *a_uri, char *a_idsName, int a_repeat,
2625c51f124SMoriah Waterland 				char *a_altBinDir, char *a_device,
2635c51f124SMoriah Waterland 				zoneList_t a_zlst);
2645c51f124SMoriah Waterland static boolean_t	add_packages_in_nonglobal_zone(char **a_pkgList,
2655c51f124SMoriah Waterland 				char *a_uri, char *a_idsName, int a_repeat,
2665c51f124SMoriah Waterland 				char *a_altBinDir, char *a_device);
2675c51f124SMoriah Waterland static boolean_t	check_applicability(char *a_packageDir,
2685c51f124SMoriah Waterland 				char *a_pkgInst, char *a_rootPath,
2695c51f124SMoriah Waterland 				CAF_T a_flags);
2705c51f124SMoriah Waterland static boolean_t	get_package_list(char ***r_pkgList, char **a_argv,
2715c51f124SMoriah Waterland 				char *a_categories, char **a_categoryList,
2725c51f124SMoriah Waterland 				int a_ignoreSignatures, PKG_ERR *a_err,
2735c51f124SMoriah Waterland 				ushort_t a_httpProxyPort, char *a_httpProxyName,
2745c51f124SMoriah Waterland 				keystore_handle_t a_keystore,
2755c51f124SMoriah Waterland 				char *a_keystoreFile, char *a_idsName,
2765c51f124SMoriah Waterland 				int *r_repeat);
2775c51f124SMoriah Waterland static boolean_t	continue_installation(void);
2785c51f124SMoriah Waterland static boolean_t	unpack_and_check_packages(char **a_pkgList,
2795c51f124SMoriah Waterland 				char *a_idsName, char *a_packageDir);
2805c51f124SMoriah Waterland /*
2815c51f124SMoriah Waterland  * *****************************************************************************
2825c51f124SMoriah Waterland  * global external (public) functions
2835c51f124SMoriah Waterland  * *****************************************************************************
2845c51f124SMoriah Waterland  */
2855c51f124SMoriah Waterland 
2865c51f124SMoriah Waterland /*
2875c51f124SMoriah Waterland  * Name:	main
2885c51f124SMoriah Waterland  * Description:	main entry point for pkgadd/pkgask
2895c51f124SMoriah Waterland  * Returns:	int
2905c51f124SMoriah Waterland  *   0        Successful completion
2915c51f124SMoriah Waterland  *   1        Fatal error.
2925c51f124SMoriah Waterland  *   2        Warning.
2935c51f124SMoriah Waterland  *   3        Interruption.
2945c51f124SMoriah Waterland  *   4        Administration.
2955c51f124SMoriah Waterland  *   5        Administration. Interaction is required. Do not use pkgadd -n.
2965c51f124SMoriah Waterland  * In addition, one of the following values may be added to the previous value
2975c51f124SMoriah Waterland  * as appropriate:
2985c51f124SMoriah Waterland  *  10       Reboot after installation of all packages.
2995c51f124SMoriah Waterland  *  20       Reboot after installation of this package.
3005c51f124SMoriah Waterland  * For example, "14" would indicate both "administration" and "reboot after
3015c51f124SMoriah Waterland  * installation of all packages".
3025c51f124SMoriah Waterland  */
3035c51f124SMoriah Waterland 
3045c51f124SMoriah Waterland int
3055c51f124SMoriah Waterland main(int argc, char **argv)
3065c51f124SMoriah Waterland {
3075c51f124SMoriah Waterland 	PKG_ERR			*err = NULL;
3085c51f124SMoriah Waterland 	WebScheme		scheme = none;
3095c51f124SMoriah Waterland 	char			**category = NULL;
3105c51f124SMoriah Waterland 	char			*abiPtr;
3115c51f124SMoriah Waterland 	char			*altBinDir = (char *)NULL;
3125c51f124SMoriah Waterland 	char			*catg_arg = NULL;
3135c51f124SMoriah Waterland 	char			*device = NULL;		/* dev pkg stored on */
3145c51f124SMoriah Waterland 	char			*dwnld_dir = NULL;
3155c51f124SMoriah Waterland 	char			*keystore_file = NULL;
3165c51f124SMoriah Waterland 	char			*p;
3175c51f124SMoriah Waterland 	char			*q;
3185c51f124SMoriah Waterland 	char			*prog;
3195c51f124SMoriah Waterland 	char			*prog_full_name = NULL;
3205c51f124SMoriah Waterland 	char			*proxy = NULL;
3215c51f124SMoriah Waterland 	char			*spoolDir = NULL;	/* specified with -s */
3225c51f124SMoriah Waterland 	char			*uri = NULL;
3235c51f124SMoriah Waterland 	char			Rpath[PATH_MAX+1] = {'\0'};
3245c51f124SMoriah Waterland 	int			c;
3255c51f124SMoriah Waterland 	int			ignore_sig = 0;
3265c51f124SMoriah Waterland 	int			n;
3275c51f124SMoriah Waterland 	int			repeat;
3285c51f124SMoriah Waterland 	int			retries = NET_RETRIES_DEFAULT;
3295c51f124SMoriah Waterland 	int			timeout = NET_TIMEOUT_DEFAULT;
3305c51f124SMoriah Waterland 	keystore_handle_t	keystore = NULL;
3315c51f124SMoriah Waterland 	struct sigaction	nact;
3325c51f124SMoriah Waterland 	struct sigaction	oact;
3335c51f124SMoriah Waterland 	ushort_t		proxy_port = 0;
3345c51f124SMoriah Waterland 
3355c51f124SMoriah Waterland 	/* initialize locale environment */
3365c51f124SMoriah Waterland 
3375c51f124SMoriah Waterland 	(void) setlocale(LC_ALL, "");
3385c51f124SMoriah Waterland 	(void) textdomain(TEXT_DOMAIN);
3395c51f124SMoriah Waterland 
3405c51f124SMoriah Waterland 	/* initialize program name */
3415c51f124SMoriah Waterland 
3425c51f124SMoriah Waterland 	prog_full_name = argv[0];
3435c51f124SMoriah Waterland 	prog = set_prog_name(argv[0]);
3445c51f124SMoriah Waterland 
3455c51f124SMoriah Waterland 	/* tell spmi zones interface how to access package output functions */
3465c51f124SMoriah Waterland 
3475c51f124SMoriah Waterland 	z_set_output_functions(echo, echoDebug, progerr);
3485c51f124SMoriah Waterland 
3495c51f124SMoriah Waterland 	askflag = (strcmp(prog, "pkgask") == 0);
3505c51f124SMoriah Waterland 
3515c51f124SMoriah Waterland 	/* set sane umask */
3525c51f124SMoriah Waterland 
3535c51f124SMoriah Waterland 	(void) umask(0022);
3545c51f124SMoriah Waterland 
3555c51f124SMoriah Waterland 	/* tell quit which ckreturn function to call */
3565c51f124SMoriah Waterland 
3575c51f124SMoriah Waterland 	quitSetCkreturnFunc(&ckreturn);
3585c51f124SMoriah Waterland 
3595c51f124SMoriah Waterland 	/* initially no source "device" */
3605c51f124SMoriah Waterland 
3615c51f124SMoriah Waterland 	device = NULL;
3625c51f124SMoriah Waterland 
3635c51f124SMoriah Waterland 	/* reset npkgs (used as pkg remaining count in quit.c) */
3645c51f124SMoriah Waterland 
3655c51f124SMoriah Waterland 	npkgs = 0;
3665c51f124SMoriah Waterland 
3675c51f124SMoriah Waterland 	/* set default password prompt for encrypted packages */
3685c51f124SMoriah Waterland 
3695c51f124SMoriah Waterland 	set_passphrase_prompt(MSG_PASSPROMPT);
3705c51f124SMoriah Waterland 
3715c51f124SMoriah Waterland 	/* initialize security operations structures and libraries */
3725c51f124SMoriah Waterland 
3735c51f124SMoriah Waterland 	sec_init();
3745c51f124SMoriah Waterland 
3755c51f124SMoriah Waterland 	if (z_running_in_global_zone() && !enable_local_fs()) {
3765c51f124SMoriah Waterland 		progerr(ERR_CANNOT_ENABLE_LOCAL_FS);
3775c51f124SMoriah Waterland 	}
3785c51f124SMoriah Waterland 
379*62224350SCasper H.S. Dik 	pkgserversetmode(DEFAULTMODE);
380*62224350SCasper H.S. Dik 
3815c51f124SMoriah Waterland 	/*
3825c51f124SMoriah Waterland 	 * ********************************************************************
3835c51f124SMoriah Waterland 	 * parse command line options
3845c51f124SMoriah Waterland 	 * ********************************************************************
3855c51f124SMoriah Waterland 	 */
3865c51f124SMoriah Waterland 
3875c51f124SMoriah Waterland 	while ((c = getopt(argc, argv,
3885c51f124SMoriah Waterland 		"?Aa:b:B:Cc:D:d:GhIik:MnO:P:R:r:Ss:tV:vx:Y:zZ")) != EOF) {
3895c51f124SMoriah Waterland 		switch (c) {
3905c51f124SMoriah Waterland 
3915c51f124SMoriah Waterland 		/*
3925c51f124SMoriah Waterland 		 * Not a public interface: This disables attribute checking.
3935c51f124SMoriah Waterland 		 * It speeds up installation a little bit.
3945c51f124SMoriah Waterland 		 */
3955c51f124SMoriah Waterland 		case 'A':
3965c51f124SMoriah Waterland 			disableAttributes++;
3975c51f124SMoriah Waterland 			break;
3985c51f124SMoriah Waterland 
3995c51f124SMoriah Waterland 		/*
4005c51f124SMoriah Waterland 		 * Public interface: Define an installation administration
4015c51f124SMoriah Waterland 		 * file, admin, to be used in place of the default
4025c51f124SMoriah Waterland 		 * administration file.	 The token none overrides the use
4035c51f124SMoriah Waterland 		 * of any admin file, and thus forces interaction with the
4045c51f124SMoriah Waterland 		 * user. Unless a full path name is given, pkgadd first
4055c51f124SMoriah Waterland 		 * looks in the current working directory for the
4065c51f124SMoriah Waterland 		 * administration file.	 If the specified administration
4075c51f124SMoriah Waterland 		 * file is not in the current working directory, pkgadd
4085c51f124SMoriah Waterland 		 * looks in the /var/sadm/install/admin directory for the
4095c51f124SMoriah Waterland 		 * administration file.
4105c51f124SMoriah Waterland 		 */
4115c51f124SMoriah Waterland 		case 'a':
4125c51f124SMoriah Waterland 			admnfile = flex_device(optarg, 0);
4135c51f124SMoriah Waterland 			break;
4145c51f124SMoriah Waterland 
4155c51f124SMoriah Waterland 		/*
4165c51f124SMoriah Waterland 		 * Not a public interface: control block size given to
4175c51f124SMoriah Waterland 		 * pkginstall - block size used in read()/write() loop;
4185c51f124SMoriah Waterland 		 * default is st_blksize from stat() of source file.
4195c51f124SMoriah Waterland 		 */
4205c51f124SMoriah Waterland 		case 'B':
4215c51f124SMoriah Waterland 			if (optarg[0] == '-') {
4225c51f124SMoriah Waterland 				usage();
4235c51f124SMoriah Waterland 				quit(1);
4245c51f124SMoriah Waterland 			}
4255c51f124SMoriah Waterland 			rw_block_size = optarg;
4265c51f124SMoriah Waterland 			break;
4275c51f124SMoriah Waterland 
4285c51f124SMoriah Waterland 		/*
4295c51f124SMoriah Waterland 		 * Not a public interface:  location where package executables
4305c51f124SMoriah Waterland 		 * can be found - default is /usr/sadm/install/bin.
4315c51f124SMoriah Waterland 		 */
4325c51f124SMoriah Waterland 		case 'b':
4335c51f124SMoriah Waterland 			if (optarg[0] == '-') {
4345c51f124SMoriah Waterland 				usage();
4355c51f124SMoriah Waterland 				quit(1);
4365c51f124SMoriah Waterland 			}
4375c51f124SMoriah Waterland 			if (!path_valid(optarg)) {
4385c51f124SMoriah Waterland 				progerr(ERR_PATH, optarg);
4395c51f124SMoriah Waterland 				quit(1);
4405c51f124SMoriah Waterland 			}
4415c51f124SMoriah Waterland 			if (isdir(optarg) != 0) {
4425c51f124SMoriah Waterland 				p = strerror(errno);
4435c51f124SMoriah Waterland 				progerr(ERR_CANNOT_USE_DIR, optarg, p);
4445c51f124SMoriah Waterland 				quit(1);
4455c51f124SMoriah Waterland 			}
4465c51f124SMoriah Waterland 			altBinDir = optarg;
4475c51f124SMoriah Waterland 			break;
4485c51f124SMoriah Waterland 
4495c51f124SMoriah Waterland 		/*
4505c51f124SMoriah Waterland 		 * Not a public interface: This disables checksum tests on
4515c51f124SMoriah Waterland 		 * the source files. It speeds up installation a little bit.
4525c51f124SMoriah Waterland 		 */
4535c51f124SMoriah Waterland 		case 'C':
4545c51f124SMoriah Waterland 			disableChecksum++;
4555c51f124SMoriah Waterland 			break;
4565c51f124SMoriah Waterland 
4575c51f124SMoriah Waterland 		/*
4585c51f124SMoriah Waterland 		 * Not a public interface: This allows designation of a
4595c51f124SMoriah Waterland 		 * continuation file. It is the same format as a dryrun file
4605c51f124SMoriah Waterland 		 * but it is used to take up where the dryrun left off.
4615c51f124SMoriah Waterland 		 */
4625c51f124SMoriah Waterland 		case 'c':
4635c51f124SMoriah Waterland 			pkgcontsrc = flex_device(optarg, 0);
4645c51f124SMoriah Waterland 			break;
4655c51f124SMoriah Waterland 
4665c51f124SMoriah Waterland 		/*
4675c51f124SMoriah Waterland 		 * Not a public interface: This allows designation of a
4685c51f124SMoriah Waterland 		 * dryrun file. This pkgadd will create dryrun files
4695c51f124SMoriah Waterland 		 * in the directory provided.
4705c51f124SMoriah Waterland 		 */
4715c51f124SMoriah Waterland 		case 'D':
4725c51f124SMoriah Waterland 			if (optarg[0] == '-') {
4735c51f124SMoriah Waterland 				usage();
4745c51f124SMoriah Waterland 				quit(1);
4755c51f124SMoriah Waterland 			}
4765c51f124SMoriah Waterland 			pkgdrtarg = flex_device(optarg, 0);
4775c51f124SMoriah Waterland 			break;
4785c51f124SMoriah Waterland 
4795c51f124SMoriah Waterland 		/*
4805c51f124SMoriah Waterland 		 * Public interface: Install or copy a package from
4815c51f124SMoriah Waterland 		 * device. device can be a full path name to a directory
4825c51f124SMoriah Waterland 		 * or the identifiers for tape, floppy disk, or removable
4835c51f124SMoriah Waterland 		 * disk - for example, /var/tmp or /floppy/floppy_name.
4845c51f124SMoriah Waterland 		 * It can also be a device alias - for example,
4855c51f124SMoriah Waterland 		 * /floppy/floppy0, or a datastream created by pkgtrans.
4865c51f124SMoriah Waterland 		 */
4875c51f124SMoriah Waterland 		case 'd':
4885c51f124SMoriah Waterland 			if (optarg[0] == '-') {
4895c51f124SMoriah Waterland 				usage();
4905c51f124SMoriah Waterland 				quit(1);
4915c51f124SMoriah Waterland 			}
4925c51f124SMoriah Waterland 			if (!path_valid(optarg)) {
4935c51f124SMoriah Waterland 				progerr(ERR_PATH, optarg);
4945c51f124SMoriah Waterland 				quit(1);
4955c51f124SMoriah Waterland 				/* NOTREACHED */
4965c51f124SMoriah Waterland 			}
4975c51f124SMoriah Waterland 
4985c51f124SMoriah Waterland 			if (strncmp(optarg, HTTP, 7) == 0) {
4995c51f124SMoriah Waterland 				scheme = web_http;
5005c51f124SMoriah Waterland 			} else if (strncmp(optarg, HTTPS, 8) == 0) {
5015c51f124SMoriah Waterland 				scheme = web_https;
5025c51f124SMoriah Waterland 			}
5035c51f124SMoriah Waterland 
5045c51f124SMoriah Waterland 			if (scheme == web_https || scheme == web_http) {
5055c51f124SMoriah Waterland 				uri = optarg;
5065c51f124SMoriah Waterland 				if ((device = malloc(PATH_MAX)) == NULL) {
5075c51f124SMoriah Waterland 					progerr(ERR_MEM);
5085c51f124SMoriah Waterland 					exit(1);
5095c51f124SMoriah Waterland 				}
5105c51f124SMoriah Waterland 				(void) memset(device, '\0', PATH_MAX);
5115c51f124SMoriah Waterland 			} else {
5125c51f124SMoriah Waterland 				device = flex_device(optarg, 1);
5135c51f124SMoriah Waterland 			}
5145c51f124SMoriah Waterland 			break;
5155c51f124SMoriah Waterland 
5165c51f124SMoriah Waterland 		/*
5175c51f124SMoriah Waterland 		 * Public interface: install package in global zone only.
5185c51f124SMoriah Waterland 		 */
5195c51f124SMoriah Waterland 		case 'G':
5205c51f124SMoriah Waterland 			globalZoneOnly = B_TRUE;
5215c51f124SMoriah Waterland 			break;
5225c51f124SMoriah Waterland 
5235c51f124SMoriah Waterland 		/*
5245c51f124SMoriah Waterland 		 * Not a public interface: Enable hollow package support. When
5255c51f124SMoriah Waterland 		 * specified, for any package that has SUNW_PKG_HOLLOW=true:
5265c51f124SMoriah Waterland 		 *  Do not calculate and verify package size against target.
5275c51f124SMoriah Waterland 		 *  Do not run any package procedure or class action scripts.
5285c51f124SMoriah Waterland 		 *  Do not create any target directories.
5295c51f124SMoriah Waterland 		 *  Do not perform any script locking.
5305c51f124SMoriah Waterland 		 *  Do not install any components of any package.
5315c51f124SMoriah Waterland 		 *  Do not output any status or database update messages.
5325c51f124SMoriah Waterland 		 */
5335c51f124SMoriah Waterland 		case 'h':
5345c51f124SMoriah Waterland 			set_depend_pkginfo_DB(B_TRUE);
5355c51f124SMoriah Waterland 			break;
5365c51f124SMoriah Waterland 
5375c51f124SMoriah Waterland 		/*
5385c51f124SMoriah Waterland 		 * Not a public interface: Informs scripts that this is
5395c51f124SMoriah Waterland 		 * an initial install by setting the environment parameter
5405c51f124SMoriah Waterland 		 * PKG_INIT_INSTALL=TRUE for all scripts. They may use it as
5415c51f124SMoriah Waterland 		 * they see fit, safe in the knowledge that the target
5425c51f124SMoriah Waterland 		 * filesystem is tabula rasa.
5435c51f124SMoriah Waterland 		 */
5445c51f124SMoriah Waterland 		case 'I':
5455c51f124SMoriah Waterland 			init_install++;
5465c51f124SMoriah Waterland 			break;
5475c51f124SMoriah Waterland 
5485c51f124SMoriah Waterland 		/*
5495c51f124SMoriah Waterland 		 * Not a public interface: ignore signatures.
5505c51f124SMoriah Waterland 		 */
5515c51f124SMoriah Waterland 		case 'i':
5525c51f124SMoriah Waterland 			ignore_sig++;
5535c51f124SMoriah Waterland 			break;
5545c51f124SMoriah Waterland 
5555c51f124SMoriah Waterland 		/*
5565c51f124SMoriah Waterland 		 * Public interface: Use keystore as the location from which to
5575c51f124SMoriah Waterland 		 * get trusted certificate authority certificates when verifying
5585c51f124SMoriah Waterland 		 * digital signatures found in packages. If no keystore is
5595c51f124SMoriah Waterland 		 * specified, then the default keystore locations are searched
5605c51f124SMoriah Waterland 		 * for valid trusted certificates.
5615c51f124SMoriah Waterland 		 */
5625c51f124SMoriah Waterland 		case 'k':
5635c51f124SMoriah Waterland 			if (!path_valid(optarg)) {
5645c51f124SMoriah Waterland 				progerr(ERR_PATH, optarg);
5655c51f124SMoriah Waterland 				quit(1);
5665c51f124SMoriah Waterland 				/* NOTREACHED */
5675c51f124SMoriah Waterland 			}
5685c51f124SMoriah Waterland 			keystore_file = optarg;
5695c51f124SMoriah Waterland 			break;
5705c51f124SMoriah Waterland 
5715c51f124SMoriah Waterland 		/*
5725c51f124SMoriah Waterland 		 * Public interface: Instruct pkgadd not to use the
5735c51f124SMoriah Waterland 		 * $root_path/etc/vfstab file for determining the client's
5745c51f124SMoriah Waterland 		 * mount points. This option assumes the mount points are
5755c51f124SMoriah Waterland 		 * correct on the server and it behaves consistently with
5765c51f124SMoriah Waterland 		 * Solaris 2.5 and earlier releases.
5775c51f124SMoriah Waterland 		 */
5785c51f124SMoriah Waterland 		case 'M':
5795c51f124SMoriah Waterland 			no_map_client = 1;
5805c51f124SMoriah Waterland 			break;
5815c51f124SMoriah Waterland 
5825c51f124SMoriah Waterland 		/*
5835c51f124SMoriah Waterland 		 * Not a public interface: the -O option allows the behavior
5845c51f124SMoriah Waterland 		 * of the package tools to be modified. Recognized options:
5855c51f124SMoriah Waterland 		 * -> debug
5865c51f124SMoriah Waterland 		 * ---> enable debugging output
5875c51f124SMoriah Waterland 		 * -> addzonename
5885c51f124SMoriah Waterland 		 * ---> add zone name to appropriate messages
5895c51f124SMoriah Waterland 		 * -> nozones
5905c51f124SMoriah Waterland 		 * ---> act as though in global zone with no non-global zones
5915c51f124SMoriah Waterland 		 * -> inherited-filesystems
5925c51f124SMoriah Waterland 		 * ---> add specified file system to list of file systems
5935c51f124SMoriah Waterland 		 * ---> that are inherited from the global zone
5945c51f124SMoriah Waterland 		 * -> enable-hollow-package-support
5955c51f124SMoriah Waterland 		 * ---> Enable hollow package support. When specified, for any
5965c51f124SMoriah Waterland 		 * ---> package that has SUNW_PKG_HOLLOW=true:
5975c51f124SMoriah Waterland 		 * ---> Do not calculate and verify package size against target
5985c51f124SMoriah Waterland 		 * ---> Do not run any package procedure or class action scripts
5995c51f124SMoriah Waterland 		 * ---> Do not create any target directories
6005c51f124SMoriah Waterland 		 * ---> Do not perform any script locking
6015c51f124SMoriah Waterland 		 * ---> Do not install any components of any package
6025c51f124SMoriah Waterland 		 * ---> Do not output any status or database update messages
6035c51f124SMoriah Waterland 		 * -> zonelist="<names...>"
6045c51f124SMoriah Waterland 		 * ---> add package to space/colon separated list of zones only
6055c51f124SMoriah Waterland 		 */
6065c51f124SMoriah Waterland 
6075c51f124SMoriah Waterland 		case 'O':
6085c51f124SMoriah Waterland 			for (p = strtok(optarg, ","); p != (char *)NULL;
6095c51f124SMoriah Waterland 				p = strtok(NULL, ",")) {
6105c51f124SMoriah Waterland 
6115c51f124SMoriah Waterland 				if (strcmp(p, "debug") == 0) {
6125c51f124SMoriah Waterland 					/* set debug flag/enable debug output */
6135c51f124SMoriah Waterland 					debugFlag = B_TRUE;
6145c51f124SMoriah Waterland 					(void) echoDebugSetFlag(debugFlag);
6155c51f124SMoriah Waterland 
6165c51f124SMoriah Waterland 					/* debug info on arguments to pkgadd */
6175c51f124SMoriah Waterland 					for (n = 0; n < argc && argv[n]; n++) {
6185c51f124SMoriah Waterland 						echoDebug(DBG_ARG, n, argv[n]);
6195c51f124SMoriah Waterland 					}
6205c51f124SMoriah Waterland 
6215c51f124SMoriah Waterland 					continue;
6225c51f124SMoriah Waterland 				}
6235c51f124SMoriah Waterland 
6245c51f124SMoriah Waterland 				if (strcmp(p,
6255c51f124SMoriah Waterland 					"enable-hollow-package-support") == 0) {
6265c51f124SMoriah Waterland 					set_depend_pkginfo_DB(B_TRUE);
6275c51f124SMoriah Waterland 					continue;
6285c51f124SMoriah Waterland 				}
6295c51f124SMoriah Waterland 
6305c51f124SMoriah Waterland 				if (strncmp(p, INHERITFS, INHERITFS_LEN) == 0) {
6315c51f124SMoriah Waterland 					if (z_add_inherited_file_system(
6325c51f124SMoriah Waterland 						p+INHERITFS_LEN) == B_FALSE) {
6335c51f124SMoriah Waterland 						progerr(ERR_NOSUCH_INHERITED,
6345c51f124SMoriah Waterland 							p+INHERITFS_LEN);
6355c51f124SMoriah Waterland 						quit(1);
6365c51f124SMoriah Waterland 						/* NOTREACHED */
6375c51f124SMoriah Waterland 					}
6385c51f124SMoriah Waterland 					continue;
6395c51f124SMoriah Waterland 				}
6405c51f124SMoriah Waterland 
6415c51f124SMoriah Waterland 				if (strcmp(p, "addzonename") == 0) {
6425c51f124SMoriah Waterland 					quitSetZoneName(z_get_zonename());
6435c51f124SMoriah Waterland 					continue;
6445c51f124SMoriah Waterland 				}
6455c51f124SMoriah Waterland 
6465c51f124SMoriah Waterland 				if (strcmp(p, "nozones") == 0) {
6475c51f124SMoriah Waterland 					noZones = B_TRUE;
6485c51f124SMoriah Waterland 					continue;
6495c51f124SMoriah Waterland 				}
6505c51f124SMoriah Waterland 
6515c51f124SMoriah Waterland 				/*
6525c51f124SMoriah Waterland 				 * Private interface: package is being
6535c51f124SMoriah Waterland 				 * installed as a patch package.
6545c51f124SMoriah Waterland 				 */
6555c51f124SMoriah Waterland 
6565c51f124SMoriah Waterland 				if (strcmp(p, "patchPkgInstall") == 0) {
6575c51f124SMoriah Waterland 					setPatchUpdate();
6585c51f124SMoriah Waterland 					continue;
6595c51f124SMoriah Waterland 				}
6605c51f124SMoriah Waterland 
6615c51f124SMoriah Waterland 				/*
6625c51f124SMoriah Waterland 				 * If this is a patch removal
6635c51f124SMoriah Waterland 				 * then call setPatchUpdate() and set
6645c51f124SMoriah Waterland 				 * patchPkgRemoval flag.
6655c51f124SMoriah Waterland 				 */
6665c51f124SMoriah Waterland 				if (strcmp(p, "patchPkgRemoval") == 0) {
6675c51f124SMoriah Waterland 					setPatchUpdate();
6685c51f124SMoriah Waterland 					patchPkgRemoval = B_TRUE;
6695c51f124SMoriah Waterland 					continue;
6705c51f124SMoriah Waterland 				}
6715c51f124SMoriah Waterland 
6725c51f124SMoriah Waterland 				if (strncmp(p, "zonelist=", 9) == 0) {
6735c51f124SMoriah Waterland 					/*
6745c51f124SMoriah Waterland 					 * If colons used as separators,
6755c51f124SMoriah Waterland 					 * convert to spaces.
6765c51f124SMoriah Waterland 					 */
6775c51f124SMoriah Waterland 					q = p + 9;
6785c51f124SMoriah Waterland 					while (*q != '\0') {
6795c51f124SMoriah Waterland 						if (*q == ':') {
6805c51f124SMoriah Waterland 							*q = ' ';
6815c51f124SMoriah Waterland 						}
6825c51f124SMoriah Waterland 						q++;
6835c51f124SMoriah Waterland 					}
6845c51f124SMoriah Waterland 
6855c51f124SMoriah Waterland 					if (z_set_zone_spec(p + 9) == -1)
6865c51f124SMoriah Waterland 						quit(1);
6875c51f124SMoriah Waterland 					usedZoneList = B_TRUE;
6885c51f124SMoriah Waterland 					continue;
6895c51f124SMoriah Waterland 				}
6905c51f124SMoriah Waterland 
6915c51f124SMoriah Waterland 				progerr(ERR_INVALID_O_OPTION, p);
6925c51f124SMoriah Waterland 				continue;
6935c51f124SMoriah Waterland 			}
6945c51f124SMoriah Waterland 			break;
6955c51f124SMoriah Waterland 
6965c51f124SMoriah Waterland 		/*
6975c51f124SMoriah Waterland 		 * Public interface: installation occurs in
6985c51f124SMoriah Waterland 		 * non-interactive mode.  Suppress output of the list of
6995c51f124SMoriah Waterland 		 * installed files. The default mode is interactive.
7005c51f124SMoriah Waterland 		 */
7015c51f124SMoriah Waterland 		case 'n':
7025c51f124SMoriah Waterland 			nointeract++;
7035c51f124SMoriah Waterland 			(void) echoSetFlag(B_FALSE);
7045c51f124SMoriah Waterland 			break;
7055c51f124SMoriah Waterland 
7065c51f124SMoriah Waterland 		/*
7075c51f124SMoriah Waterland 		 * Public interface: Password to use to decrypt keystore
7085c51f124SMoriah Waterland 		 * specified with -k, if required. See PASS PHRASE
7095c51f124SMoriah Waterland 		 * ARGUMENTS for more information about the format of this
7105c51f124SMoriah Waterland 		 * option's argument.
7115c51f124SMoriah Waterland 		 */
7125c51f124SMoriah Waterland 		case 'P':
7135c51f124SMoriah Waterland 			if (optarg[0] == '-') {
7145c51f124SMoriah Waterland 				usage();
7155c51f124SMoriah Waterland 				quit(1);
7165c51f124SMoriah Waterland 			}
7175c51f124SMoriah Waterland 			set_passphrase_passarg(optarg);
7185c51f124SMoriah Waterland 			if (ci_strneq(optarg, "pass:", 5)) {
7195c51f124SMoriah Waterland 				/*
7205c51f124SMoriah Waterland 				 * passwords on the command line are highly
7215c51f124SMoriah Waterland 				 * insecure.  complain.
7225c51f124SMoriah Waterland 				 */
7235c51f124SMoriah Waterland 				logerr(PASSWD_CMDLINE, "pass:<pass>");
7245c51f124SMoriah Waterland 			}
7255c51f124SMoriah Waterland 			break;
7265c51f124SMoriah Waterland 
7275c51f124SMoriah Waterland 		/*
7285c51f124SMoriah Waterland 		 * Public interface: Define the full path name of a
7295c51f124SMoriah Waterland 		 * directory to use as the root_path.  All files,
7305c51f124SMoriah Waterland 		 * including package system information files, are
7315c51f124SMoriah Waterland 		 * relocated to a directory tree starting in the specified
7325c51f124SMoriah Waterland 		 * root_path. The root_path may be specified when
7335c51f124SMoriah Waterland 		 * installing to a client from a server (for example,
7345c51f124SMoriah Waterland 		 * /export/root/client1).
7355c51f124SMoriah Waterland 		 */
7365c51f124SMoriah Waterland 		case 'R':
7375c51f124SMoriah Waterland 			if (optarg[0] == '-') {
7385c51f124SMoriah Waterland 				usage();
7395c51f124SMoriah Waterland 				quit(1);
7405c51f124SMoriah Waterland 			}
7415c51f124SMoriah Waterland 			/* determine the real path specified */
7425c51f124SMoriah Waterland 
7435c51f124SMoriah Waterland 			n = resolvepath(optarg, Rpath, sizeof (Rpath)-1);
7445c51f124SMoriah Waterland 
7455c51f124SMoriah Waterland 			/* use supplied path if not resolvable */
7465c51f124SMoriah Waterland 
7475c51f124SMoriah Waterland 			if (n == -1) {
7485c51f124SMoriah Waterland 				(void) strlcpy(Rpath, optarg, sizeof (Rpath));
7495c51f124SMoriah Waterland 			} else {
7505c51f124SMoriah Waterland 				/* null terminate string */
7515c51f124SMoriah Waterland 				Rpath[n] = '\0';
7525c51f124SMoriah Waterland 			}
7535c51f124SMoriah Waterland 
7545c51f124SMoriah Waterland 			/* set the alternative root path */
7555c51f124SMoriah Waterland 
7565c51f124SMoriah Waterland 			if (!set_inst_root(Rpath)) {
7575c51f124SMoriah Waterland 				progerr(ERR_ROOT_CMD);
7585c51f124SMoriah Waterland 				exit(1);
7595c51f124SMoriah Waterland 			}
7605c51f124SMoriah Waterland 			break;
7615c51f124SMoriah Waterland 
7625c51f124SMoriah Waterland 		/*
7635c51f124SMoriah Waterland 		 * Public interface: Identify a file or directory which
7645c51f124SMoriah Waterland 		 * contains output from a previous pkgask(1M)
7655c51f124SMoriah Waterland 		 * session. This file supplies the interaction responses
7665c51f124SMoriah Waterland 		 * that would be requested by the package in interactive
7675c51f124SMoriah Waterland 		 * mode. response must be a full pathname.
7685c51f124SMoriah Waterland 		 */
7695c51f124SMoriah Waterland 		case 'r':
7705c51f124SMoriah Waterland 			if (optarg[0] == '-') {
7715c51f124SMoriah Waterland 				usage();
7725c51f124SMoriah Waterland 				quit(1);
7735c51f124SMoriah Waterland 			}
7745c51f124SMoriah Waterland 			respfile = flex_device(optarg, 2);
7755c51f124SMoriah Waterland 			if (isdir(respfile) == 0)
7765c51f124SMoriah Waterland 				respdir = respfile;
7775c51f124SMoriah Waterland 			break;
7785c51f124SMoriah Waterland 
7795c51f124SMoriah Waterland 		/*
7805c51f124SMoriah Waterland 		 * Not a public interface: suppress copyright notice being
7815c51f124SMoriah Waterland 		 * output during installation.
7825c51f124SMoriah Waterland 		 */
7835c51f124SMoriah Waterland 		case 'S':
7845c51f124SMoriah Waterland 			suppressCopyright++;
7855c51f124SMoriah Waterland 			break;
7865c51f124SMoriah Waterland 
7875c51f124SMoriah Waterland 		/*
7885c51f124SMoriah Waterland 		 * Public interface: Write the package into the directory
7895c51f124SMoriah Waterland 		 * spool instead of installing it. The default directory
7905c51f124SMoriah Waterland 		 * for spooled packages is /var/sadm/pkg.
7915c51f124SMoriah Waterland 		 */
7925c51f124SMoriah Waterland 		case 's':
7935c51f124SMoriah Waterland 			spoolDir = flex_device(optarg, 1);
7945c51f124SMoriah Waterland 			break;
7955c51f124SMoriah Waterland 
7965c51f124SMoriah Waterland 		/*
7975c51f124SMoriah Waterland 		 * Not a public interface: disable save spool area creation;
7985c51f124SMoriah Waterland 		 * suppress the creation and population of the package save
7995c51f124SMoriah Waterland 		 * spool area (var/sadm/pkg/PKG/save/pspool/PKG).
8005c51f124SMoriah Waterland 		 */
8015c51f124SMoriah Waterland 		case 't':
8025c51f124SMoriah Waterland 			disableSaveSpool++;
8035c51f124SMoriah Waterland 			break;
8045c51f124SMoriah Waterland 
8055c51f124SMoriah Waterland 		/*
8065c51f124SMoriah Waterland 		 * Public interface: Specify an alternative fs_file to map
8075c51f124SMoriah Waterland 		 * the client's file systems.  For example, used in
8085c51f124SMoriah Waterland 		 * situations where the $root_path/etc/vfstab file is
8095c51f124SMoriah Waterland 		 * non-existent or unreliable. Informs the pkginstall
8105c51f124SMoriah Waterland 		 * portion to mount up a client filesystem based upon the
8115c51f124SMoriah Waterland 		 * supplied vfstab-like file of stable format.
8125c51f124SMoriah Waterland 		 */
8135c51f124SMoriah Waterland 		case 'V':
8145c51f124SMoriah Waterland 			vfstab_file = flex_device(optarg, 2);
8155c51f124SMoriah Waterland 			no_map_client = 0;
8165c51f124SMoriah Waterland 			break;
8175c51f124SMoriah Waterland 
8185c51f124SMoriah Waterland 		/*
8195c51f124SMoriah Waterland 		 * Public interface: Trace all of the scripts that get
8205c51f124SMoriah Waterland 		 * executed by pkgadd, located in the pkginst/install
8215c51f124SMoriah Waterland 		 * directory. This option is used for debugging the
8225c51f124SMoriah Waterland 		 * procedural and non-procedural scripts
8235c51f124SMoriah Waterland 		 */
8245c51f124SMoriah Waterland 		case 'v':
8255c51f124SMoriah Waterland 			pkgverbose++;
8265c51f124SMoriah Waterland 			break;
8275c51f124SMoriah Waterland 
8285c51f124SMoriah Waterland 		/*
8295c51f124SMoriah Waterland 		 * Public interface: Specify a HTTP[S] proxy to use when
8305c51f124SMoriah Waterland 		 * downloading packages The format of proxy is host:port,
8315c51f124SMoriah Waterland 		 * where host is the hostname of the HTTP[S] proxy, and
8325c51f124SMoriah Waterland 		 * port is the port number associated with the proxy. This
8335c51f124SMoriah Waterland 		 * switch overrides all other methods of specifying a
8345c51f124SMoriah Waterland 		 * proxy. See ENVIRONMENT VARIABLES for more information
8355c51f124SMoriah Waterland 		 * on alternate methods of specifying a default proxy.
8365c51f124SMoriah Waterland 		 */
8375c51f124SMoriah Waterland 		case 'x':
8385c51f124SMoriah Waterland 			if (!path_valid(optarg)) {
8395c51f124SMoriah Waterland 				progerr(ERR_PATH, optarg);
8405c51f124SMoriah Waterland 				quit(1);
8415c51f124SMoriah Waterland 				/* NOTREACHED */
8425c51f124SMoriah Waterland 			}
8435c51f124SMoriah Waterland 			proxy = optarg;
8445c51f124SMoriah Waterland 			break;
8455c51f124SMoriah Waterland 
8465c51f124SMoriah Waterland 		/*
8475c51f124SMoriah Waterland 		 * Public interface: Install packages based on the value
8485c51f124SMoriah Waterland 		 * of the CATEGORY parameter stored in the package's
8495c51f124SMoriah Waterland 		 * pkginfo(4) file. All packages on the source medium
8505c51f124SMoriah Waterland 		 * whose CATEGORY matches one of the specified categories
8515c51f124SMoriah Waterland 		 * will be selected for installation or spooling. Install
8525c51f124SMoriah Waterland 		 * packages that contain the same CATEGORY as the one
8535c51f124SMoriah Waterland 		 * provided on the command line.
8545c51f124SMoriah Waterland 		 */
8555c51f124SMoriah Waterland 		case 'Y':
8565c51f124SMoriah Waterland 			if (optarg[0] == '-') {
8575c51f124SMoriah Waterland 				usage();
8585c51f124SMoriah Waterland 				quit(1);
8595c51f124SMoriah Waterland 			}
8605c51f124SMoriah Waterland 			catg_arg = strdup(optarg);
8615c51f124SMoriah Waterland 
8625c51f124SMoriah Waterland 			if ((category = get_categories(catg_arg)) == NULL) {
8635c51f124SMoriah Waterland 				progerr(ERR_CAT_INV, catg_arg);
8645c51f124SMoriah Waterland 				exit(1);
8655c51f124SMoriah Waterland 			} else if (is_not_valid_length(category)) {
8665c51f124SMoriah Waterland 				progerr(ERR_CAT_LNGTH);
8675c51f124SMoriah Waterland 				exit(1);
8685c51f124SMoriah Waterland 			}
8695c51f124SMoriah Waterland 			break;
8705c51f124SMoriah Waterland 
8715c51f124SMoriah Waterland 		/*
8725c51f124SMoriah Waterland 		 * Not a public interface: perform fresh install from
8735c51f124SMoriah Waterland 		 * package save spool area. When set, the package contents
8745c51f124SMoriah Waterland 		 * are installed from the package spool save area instead
8755c51f124SMoriah Waterland 		 * of from the package root area, so that the original
8765c51f124SMoriah Waterland 		 * source packages are not required to install the
8775c51f124SMoriah Waterland 		 * package. If the -h option is also specified and the
8785c51f124SMoriah Waterland 		 * package is hollow, then this option is ignored. When -z
8795c51f124SMoriah Waterland 		 * is specified:
8805c51f124SMoriah Waterland 		 *  - Editable files are installed from the package instance
8815c51f124SMoriah Waterland 		 *    save area.
8825c51f124SMoriah Waterland 		 *  - Volatile files are installed from the package instance
8835c51f124SMoriah Waterland 		 *    save area.
8845c51f124SMoriah Waterland 		 *  - Executable and data files are installed from the final
8855c51f124SMoriah Waterland 		 *    installed location as specified in the pkgmap file.
8865c51f124SMoriah Waterland 		 *  - Installation scripts are run from the package spool
8875c51f124SMoriah Waterland 		 *    save area.
8885c51f124SMoriah Waterland 		 */
8895c51f124SMoriah Waterland 		case 'z':
8905c51f124SMoriah Waterland 			saveSpoolInstall++;
8915c51f124SMoriah Waterland 			break;
8925c51f124SMoriah Waterland 
8935c51f124SMoriah Waterland 		/*
8945c51f124SMoriah Waterland 		 * unrecognized option
8955c51f124SMoriah Waterland 		 */
8965c51f124SMoriah Waterland 
8975c51f124SMoriah Waterland 		default:
8985c51f124SMoriah Waterland 			usage();
8995c51f124SMoriah Waterland 			return (1);
9005c51f124SMoriah Waterland 		}
9015c51f124SMoriah Waterland 	}
9025c51f124SMoriah Waterland 
9035c51f124SMoriah Waterland 	/*
9045c51f124SMoriah Waterland 	 * ********************************************************************
9055c51f124SMoriah Waterland 	 * validate command line options
9065c51f124SMoriah Waterland 	 * ********************************************************************
9075c51f124SMoriah Waterland 	 */
9085c51f124SMoriah Waterland 
9095c51f124SMoriah Waterland 	/* set "debug echo" flag according to setting of "-O debug" option */
9105c51f124SMoriah Waterland 
9115c51f124SMoriah Waterland 	(void) echoDebugSetFlag(debugFlag);
9125c51f124SMoriah Waterland 
9135c51f124SMoriah Waterland 	/* output entry debugging information */
9145c51f124SMoriah Waterland 
9155c51f124SMoriah Waterland 	if (z_running_in_global_zone()) {
9165c51f124SMoriah Waterland 		echoDebug(DBG_ENTRY_IN_GZ, prog_full_name);
9175c51f124SMoriah Waterland 	} else {
9185c51f124SMoriah Waterland 		echoDebug(DBG_ENTRY_IN_LZ, prog_full_name, getzoneid(),
9195c51f124SMoriah Waterland 			z_get_zonename());
9205c51f124SMoriah Waterland 	}
9215c51f124SMoriah Waterland 
9225c51f124SMoriah Waterland 	/*
9235c51f124SMoriah Waterland 	 * Later, it may be decided to pursue this ability to continue to an
9245c51f124SMoriah Waterland 	 * actual installation based only on the dryrun data. At this time,
9255c51f124SMoriah Waterland 	 * it is too risky.
9265c51f124SMoriah Waterland 	 */
9275c51f124SMoriah Waterland 
9285c51f124SMoriah Waterland 	if (pkgcontsrc && !pkgdrtarg) {
9295c51f124SMoriah Waterland 		progerr(ERR_NO_LIVE_MODE);
9305c51f124SMoriah Waterland 		usage();
9315c51f124SMoriah Waterland 		return (1);
9325c51f124SMoriah Waterland 	}
9335c51f124SMoriah Waterland 
9345c51f124SMoriah Waterland 	/* ignore -G option if not used in the global zone */
9355c51f124SMoriah Waterland 
9365c51f124SMoriah Waterland 	if (!z_running_in_global_zone()) {
9375c51f124SMoriah Waterland 		globalZoneOnly = B_FALSE;
9385c51f124SMoriah Waterland 	}
9395c51f124SMoriah Waterland 
9405c51f124SMoriah Waterland 	/* if zonelist used, must be in global zone */
9415c51f124SMoriah Waterland 
9425c51f124SMoriah Waterland 	if (usedZoneList && !z_running_in_global_zone()) {
9435c51f124SMoriah Waterland 		progerr(ERR_Z_USED_IN_NONGLOBAL_ZONE);
9445c51f124SMoriah Waterland 		return (1);
9455c51f124SMoriah Waterland 	}
9465c51f124SMoriah Waterland 
9475c51f124SMoriah Waterland 	/* -G and zonelist cannot be used together */
9485c51f124SMoriah Waterland 
9495c51f124SMoriah Waterland 	if (globalZoneOnly && usedZoneList) {
9505c51f124SMoriah Waterland 		progerr(ERR_GZ_USED_TOGETHER);
9515c51f124SMoriah Waterland 		usage();
9525c51f124SMoriah Waterland 		return (1);
9535c51f124SMoriah Waterland 	}
9545c51f124SMoriah Waterland 
9555c51f124SMoriah Waterland 	/* -s cannot be used with either -G or zonelist */
9565c51f124SMoriah Waterland 
9575c51f124SMoriah Waterland 	if (spoolDir != NULL) {
9585c51f124SMoriah Waterland 		if (globalZoneOnly) {
9595c51f124SMoriah Waterland 			progerr(ERR_SPOOLDIR_USED_WITH_G);
9605c51f124SMoriah Waterland 			usage();
9615c51f124SMoriah Waterland 			return (1);
9625c51f124SMoriah Waterland 		}
9635c51f124SMoriah Waterland 		if (usedZoneList) {
9645c51f124SMoriah Waterland 			progerr(ERR_SPOOLDIR_USED_WITH_Z);
9655c51f124SMoriah Waterland 			usage();
9665c51f124SMoriah Waterland 			return (1);
9675c51f124SMoriah Waterland 		}
9685c51f124SMoriah Waterland 		if (strcmp(spoolDir, "/var/sadm/pkg") == 0) {
9695c51f124SMoriah Waterland 			progerr(ERR_SPOOLDIR_CANNOT_BE_SYS, "/var/sadm/pkg");
9705c51f124SMoriah Waterland 			usage();
9715c51f124SMoriah Waterland 			return (1);
9725c51f124SMoriah Waterland 		}
9735c51f124SMoriah Waterland 	}
9745c51f124SMoriah Waterland 
9755c51f124SMoriah Waterland 	/* pkgask does not support the same options as pkgadd */
9765c51f124SMoriah Waterland 
9775c51f124SMoriah Waterland 	if (askflag && proxy) {
9785c51f124SMoriah Waterland 		progerr(ERR_PKGASK_AND_PROXY);
9795c51f124SMoriah Waterland 		usage();
9805c51f124SMoriah Waterland 		return (1);
9815c51f124SMoriah Waterland 	}
9825c51f124SMoriah Waterland 
9835c51f124SMoriah Waterland 	if (askflag && uri) {
9845c51f124SMoriah Waterland 		progerr(ERR_PKGASK_AND_URI);
9855c51f124SMoriah Waterland 		usage();
9865c51f124SMoriah Waterland 		return (1);
9875c51f124SMoriah Waterland 	}
9885c51f124SMoriah Waterland 
9895c51f124SMoriah Waterland 	if (askflag && keystore_file) {
9905c51f124SMoriah Waterland 		progerr(ERR_PKGASK_AND_KEYSTORE_FILE);
9915c51f124SMoriah Waterland 		usage();
9925c51f124SMoriah Waterland 		return (1);
9935c51f124SMoriah Waterland 	}
9945c51f124SMoriah Waterland 
9955c51f124SMoriah Waterland 	if (askflag && ignore_sig) {
9965c51f124SMoriah Waterland 		progerr(ERR_PKGASK_AND_IGNORE_SIG);
9975c51f124SMoriah Waterland 		usage();
9985c51f124SMoriah Waterland 		return (1);
9995c51f124SMoriah Waterland 	}
10005c51f124SMoriah Waterland 
10015c51f124SMoriah Waterland 	if (askflag && spoolDir) {
10025c51f124SMoriah Waterland 		progerr(ERR_PKGASK_AND_SPOOLDIR);
10035c51f124SMoriah Waterland 		usage();
10045c51f124SMoriah Waterland 		return (1);
10055c51f124SMoriah Waterland 	}
10065c51f124SMoriah Waterland 
10075c51f124SMoriah Waterland 	if (askflag && nointeract) {
10085c51f124SMoriah Waterland 		progerr(ERR_PKGASK_AND_NOINTERACT);
10095c51f124SMoriah Waterland 		usage();
10105c51f124SMoriah Waterland 		return (1);
10115c51f124SMoriah Waterland 	}
10125c51f124SMoriah Waterland 
10135c51f124SMoriah Waterland 	/* cannot use response file and web address together */
10145c51f124SMoriah Waterland 
10155c51f124SMoriah Waterland 	if (respfile && uri) {
10165c51f124SMoriah Waterland 		progerr(ERR_RESPFILE_AND_URI);
10175c51f124SMoriah Waterland 		usage();
10185c51f124SMoriah Waterland 		return (1);
10195c51f124SMoriah Waterland 	}
10205c51f124SMoriah Waterland 
10215c51f124SMoriah Waterland 	/* cannot use response file/not-interactive and spool-to directory */
10225c51f124SMoriah Waterland 
10235c51f124SMoriah Waterland 	if (spoolDir && nointeract) {
10245c51f124SMoriah Waterland 		progerr(ERR_SPOOLDIR_AND_NOINTERACT);
10255c51f124SMoriah Waterland 		usage();
10265c51f124SMoriah Waterland 		return (1);
10275c51f124SMoriah Waterland 	}
10285c51f124SMoriah Waterland 
10295c51f124SMoriah Waterland 	if (spoolDir && respfile) {
10305c51f124SMoriah Waterland 		progerr(ERR_SPOOLDIR_AND_RESPFILE);
10315c51f124SMoriah Waterland 		usage();
10325c51f124SMoriah Waterland 		return (1);
10335c51f124SMoriah Waterland 	}
10345c51f124SMoriah Waterland 
10355c51f124SMoriah Waterland 	if (usedZoneList) {
10365c51f124SMoriah Waterland 		/* Verify supplied zone list valid for the target */
10375c51f124SMoriah Waterland 		if (z_verify_zone_spec() == -1)
10385c51f124SMoriah Waterland 			return (1);
10395c51f124SMoriah Waterland 
10405c51f124SMoriah Waterland 		/* -z zonelist=global is logically the same as -G */
10415c51f124SMoriah Waterland 		if (z_global_only() && z_running_in_global_zone())
10425c51f124SMoriah Waterland 			globalZoneOnly = B_TRUE;
10435c51f124SMoriah Waterland 	}
10445c51f124SMoriah Waterland 
10455c51f124SMoriah Waterland 	/*
10465c51f124SMoriah Waterland 	 * hook SIGINT and SIGHUP interrupts into quit.c's trap handler
10475c51f124SMoriah Waterland 	 */
10485c51f124SMoriah Waterland 
10495c51f124SMoriah Waterland 	/* hold SIGINT/SIGHUP interrupts */
10505c51f124SMoriah Waterland 
10515c51f124SMoriah Waterland 	(void) sighold(SIGHUP);
10525c51f124SMoriah Waterland 	(void) sighold(SIGINT);
10535c51f124SMoriah Waterland 
10545c51f124SMoriah Waterland 	/* connect quit.c:trap() to SIGINT */
10555c51f124SMoriah Waterland 
10565c51f124SMoriah Waterland 	nact.sa_handler = quitGetTrapHandler();
10575c51f124SMoriah Waterland 	nact.sa_flags = SA_RESTART;
10585c51f124SMoriah Waterland 	(void) sigemptyset(&nact.sa_mask);
10595c51f124SMoriah Waterland 
10605c51f124SMoriah Waterland 	(void) sigaction(SIGINT, &nact, &oact);
10615c51f124SMoriah Waterland 
10625c51f124SMoriah Waterland 	/* connect quit.c:trap() to SIGHUP */
10635c51f124SMoriah Waterland 
10645c51f124SMoriah Waterland 	nact.sa_handler = quitGetTrapHandler();
10655c51f124SMoriah Waterland 	nact.sa_flags = SA_RESTART;
10665c51f124SMoriah Waterland 	(void) sigemptyset(&nact.sa_mask);
10675c51f124SMoriah Waterland 
10685c51f124SMoriah Waterland 	(void) sigaction(SIGHUP, &nact, &oact);
10695c51f124SMoriah Waterland 
10705c51f124SMoriah Waterland 	/* release hold on signals */
10715c51f124SMoriah Waterland 
10725c51f124SMoriah Waterland 	(void) sigrelse(SIGHUP);
10735c51f124SMoriah Waterland 	(void) sigrelse(SIGINT);
10745c51f124SMoriah Waterland 
10755c51f124SMoriah Waterland 	/*
10765c51f124SMoriah Waterland 	 * This function is in the libadm library; it sets:
10775c51f124SMoriah Waterland 	 * -> get_PKGLOC() = <install_root>/var/sadm/pkg
10785c51f124SMoriah Waterland 	 * -> get_PKGOLD() = <install_root>/usr/options
10795c51f124SMoriah Waterland 	 * -> get_PKGADM() = <install_root>/var/sadm/install
10805c51f124SMoriah Waterland 	 * -> pkgdir = <install_root>/var/sadm/pkg
10815c51f124SMoriah Waterland 	 * -> pkg_install_root = <install_root>
10825c51f124SMoriah Waterland 	 * This controls operations of libadm functions such as:
10835c51f124SMoriah Waterland 	 * -> pkginfofind, pkginfopen, fpkgparam, pkgparam, get_PKGLOC,
10845c51f124SMoriah Waterland 	 * -> get_PKGOLD, get_PKGADM, get_install_root
10855c51f124SMoriah Waterland 	 */
10865c51f124SMoriah Waterland 
10875c51f124SMoriah Waterland 	set_PKGpaths(get_inst_root());
10885c51f124SMoriah Waterland 	echoDebug(DBG_PKGADD_PKGPATHS,
10895c51f124SMoriah Waterland 		get_PKGLOC() ? get_PKGLOC() : "",
10905c51f124SMoriah Waterland 		get_PKGADM() ? get_PKGADM() : "");
10915c51f124SMoriah Waterland 
10925c51f124SMoriah Waterland 	/*
10935c51f124SMoriah Waterland 	 * This function is in the libinst library; it reads the specified
10945c51f124SMoriah Waterland 	 * admin(4) file and, using fpkgparam(), sets the global "adm" structure
10955c51f124SMoriah Waterland 	 * values to match what is in the specified admin file.
10965c51f124SMoriah Waterland 	 */
10975c51f124SMoriah Waterland 
10985c51f124SMoriah Waterland 	echoDebug(DBG_PKGADD_ADMINFILE, admnfile ? admnfile : "");
10995c51f124SMoriah Waterland 	setadminFile(admnfile);
11005c51f124SMoriah Waterland 
11015c51f124SMoriah Waterland 	/*
11025c51f124SMoriah Waterland 	 * if running in the global zone, and non-global zones exist, then
11035c51f124SMoriah Waterland 	 * enable hollow package support so that any packages that are marked
11045c51f124SMoriah Waterland 	 * SUNW_PKG_HOLLOW=true will be correctly installed in non-global zones
11055c51f124SMoriah Waterland 	 * when added directly in the global zone by the global zone admin.
11065c51f124SMoriah Waterland 	 */
11075c51f124SMoriah Waterland 
11085c51f124SMoriah Waterland 	if (is_depend_pkginfo_DB()) {
11095c51f124SMoriah Waterland 		echoDebug(DBG_PKGADD_HOLLOW_ENABLED);
11105c51f124SMoriah Waterland 	} else if ((z_running_in_global_zone() == B_TRUE) &&
11115c51f124SMoriah Waterland 		(z_non_global_zones_exist() == B_TRUE)) {
11125c51f124SMoriah Waterland 		echoDebug(DBG_PKGADD_ENABLING_HOLLOW);
11135c51f124SMoriah Waterland 		set_depend_pkginfo_DB(B_TRUE);
11145c51f124SMoriah Waterland 	}
11155c51f124SMoriah Waterland 
11165c51f124SMoriah Waterland 	/* if no device and no url, get and validate default device */
11175c51f124SMoriah Waterland 
11185c51f124SMoriah Waterland 	if ((device == NULL) && (uri == NULL)) {
11195c51f124SMoriah Waterland 		device = devattr("spool", "pathname");
11205c51f124SMoriah Waterland 		if (device == NULL) {
11215c51f124SMoriah Waterland 			progerr(ERR_NODEVICE);
11225c51f124SMoriah Waterland 			quit(1);
11235c51f124SMoriah Waterland 			/* NOTREACHED */
11245c51f124SMoriah Waterland 		}
11255c51f124SMoriah Waterland 	}
11265c51f124SMoriah Waterland 
11275c51f124SMoriah Waterland 	/* must be root if not directing results to spool directory */
11285c51f124SMoriah Waterland 
11295c51f124SMoriah Waterland 	if ((getuid() != 0) && (spoolDir == NULL)) {
11305c51f124SMoriah Waterland 		progerr(ERR_NOT_ROOT, prog);
11315c51f124SMoriah Waterland 		exit(1);
11325c51f124SMoriah Waterland 	}
11335c51f124SMoriah Waterland 
11345c51f124SMoriah Waterland 	/*
11355c51f124SMoriah Waterland 	 * process response file argument
11365c51f124SMoriah Waterland 	 */
11375c51f124SMoriah Waterland 
11385c51f124SMoriah Waterland 	if (respfile) {
11395c51f124SMoriah Waterland 		echoDebug(DBG_PKGADD_RESPFILE,
11405c51f124SMoriah Waterland 			respfile, respdir ? respdir : "");
11415c51f124SMoriah Waterland 
11425c51f124SMoriah Waterland 		if (respfile[0] != '/') {
11435c51f124SMoriah Waterland 			progerr(ERR_RSP_FILE_NOTFULLPATH, respfile);
11445c51f124SMoriah Waterland 			quit(1);
11455c51f124SMoriah Waterland 			/* NOTREACHED */
11465c51f124SMoriah Waterland 		}
11475c51f124SMoriah Waterland 		if (respdir == NULL) {
11485c51f124SMoriah Waterland 			if (askflag) {
11495c51f124SMoriah Waterland 				if (access(respfile, F_OK) == 0) {
11505c51f124SMoriah Waterland 					progerr(ERR_NORESP, respfile);
11515c51f124SMoriah Waterland 					quit(1);
11525c51f124SMoriah Waterland 					/* NOTREACHED */
11535c51f124SMoriah Waterland 				}
11545c51f124SMoriah Waterland 			} else if (access(respfile, F_OK) != 0) {
11555c51f124SMoriah Waterland 				progerr(ERR_ACCRESP, respfile);
11565c51f124SMoriah Waterland 				quit(1);
11575c51f124SMoriah Waterland 				/* NOTREACHED */
11585c51f124SMoriah Waterland 			}
11595c51f124SMoriah Waterland 		}
11605c51f124SMoriah Waterland 	} else if (askflag) {
11615c51f124SMoriah Waterland 		progerr(ERR_RSP_FILE_NOT_GIVEN);
11625c51f124SMoriah Waterland 		usage();
11635c51f124SMoriah Waterland 		quit(1);
11645c51f124SMoriah Waterland 		/* NOTREACHED */
11655c51f124SMoriah Waterland 	}
11665c51f124SMoriah Waterland 
11675c51f124SMoriah Waterland 	/* establish temporary directory to use */
11685c51f124SMoriah Waterland 
11695c51f124SMoriah Waterland 	if ((tmpdir = getenv("TMPDIR")) == NULL) {
11705c51f124SMoriah Waterland 		/* use default - no override specified */
11715c51f124SMoriah Waterland 		tmpdir = P_tmpdir;
11725c51f124SMoriah Waterland 	}
11735c51f124SMoriah Waterland 
11745c51f124SMoriah Waterland 	echoDebug(DBG_PKGADD_TMPDIR, tmpdir);
11755c51f124SMoriah Waterland 
11765c51f124SMoriah Waterland 	/*
11775c51f124SMoriah Waterland 	 * setup and prepare secure package operations
11785c51f124SMoriah Waterland 	 */
11795c51f124SMoriah Waterland 
11805c51f124SMoriah Waterland 	/* initialize error object used by security functions */
11815c51f124SMoriah Waterland 
11825c51f124SMoriah Waterland 	err = pkgerr_new();
11835c51f124SMoriah Waterland 
11845c51f124SMoriah Waterland 	/* validate keystore file */
11855c51f124SMoriah Waterland 
11865c51f124SMoriah Waterland 	if (!check_keystore_admin(&keystore_file)) {
11875c51f124SMoriah Waterland 		progerr(ERR_ADM_KEYSTORE);
11885c51f124SMoriah Waterland 		quit(1);
11895c51f124SMoriah Waterland 		/* NOTREACHED */
11905c51f124SMoriah Waterland 	}
11915c51f124SMoriah Waterland 
11925c51f124SMoriah Waterland 	/* if uri provided, establish session */
11935c51f124SMoriah Waterland 
11945c51f124SMoriah Waterland 	if (uri != NULL) {
11955c51f124SMoriah Waterland 		boolean_t	b;
11965c51f124SMoriah Waterland 		int		len;
11975c51f124SMoriah Waterland 		char		*bname = (char *)NULL;
11985c51f124SMoriah Waterland 
11995c51f124SMoriah Waterland 		set_web_install();
12005c51f124SMoriah Waterland 
12015c51f124SMoriah Waterland 		if (!get_proxy_port(err, &proxy, &proxy_port)) {
12025c51f124SMoriah Waterland 			pkgerr(err);
12035c51f124SMoriah Waterland 			quit(1);
12045c51f124SMoriah Waterland 			/* NOTREACHED */
12055c51f124SMoriah Waterland 		}
12065c51f124SMoriah Waterland 
12075c51f124SMoriah Waterland 		if (proxy == NULL) {
12085c51f124SMoriah Waterland 			if (!get_proxy_port_admin(&proxy, &proxy_port)) {
12095c51f124SMoriah Waterland 				progerr(ERR_ADM_PROXY);
12105c51f124SMoriah Waterland 				quit(1);
12115c51f124SMoriah Waterland 				/* NOTREACHED */
12125c51f124SMoriah Waterland 			}
12135c51f124SMoriah Waterland 		}
12145c51f124SMoriah Waterland 
12155c51f124SMoriah Waterland 		if ((retries = web_ck_retries()) == 0) {
12165c51f124SMoriah Waterland 			pkgerr(err);
12175c51f124SMoriah Waterland 			quit(1);
12185c51f124SMoriah Waterland 			/* NOTREACHED */
12195c51f124SMoriah Waterland 		}
12205c51f124SMoriah Waterland 
12215c51f124SMoriah Waterland 		if ((timeout = web_ck_timeout()) == 0) {
12225c51f124SMoriah Waterland 			pkgerr(err);
12235c51f124SMoriah Waterland 			quit(1);
12245c51f124SMoriah Waterland 			/* NOTREACHED */
12255c51f124SMoriah Waterland 		}
12265c51f124SMoriah Waterland 
12275c51f124SMoriah Waterland 		/* create temporary directory */
12285c51f124SMoriah Waterland 
12295c51f124SMoriah Waterland 		b = setup_temporary_directory(&dwnld_dir, tmpdir, "dwnld");
12305c51f124SMoriah Waterland 		if (b != B_TRUE) {
12315c51f124SMoriah Waterland 			progerr(ERR_DWNLDTEMPDIR, tmpdir, strerror(errno));
12325c51f124SMoriah Waterland 			quit(1);
12335c51f124SMoriah Waterland 			/* NOTREACHED */
12345c51f124SMoriah Waterland 		}
12355c51f124SMoriah Waterland 		canonize_slashes(dwnld_dir);
12365c51f124SMoriah Waterland 
12375c51f124SMoriah Waterland 		/* register with quit() so directory is removed on exit */
12385c51f124SMoriah Waterland 
12395c51f124SMoriah Waterland 		quitSetDwnldTmpdir(dwnld_dir);	/* DO NOT FREE() */
12405c51f124SMoriah Waterland 
12415c51f124SMoriah Waterland 		/* open keystore if this is a secure download */
12425c51f124SMoriah Waterland 		if (scheme == web_https) {
12435c51f124SMoriah Waterland 			if (open_keystore(err, keystore_file,
12445c51f124SMoriah Waterland 			    get_prog_name(),  pkg_passphrase_cb,
12455c51f124SMoriah Waterland 			    KEYSTORE_DFLT_FLAGS, &keystore) != 0) {
12465c51f124SMoriah Waterland 				pkgerr(err);
12475c51f124SMoriah Waterland 				web_cleanup();
12485c51f124SMoriah Waterland 				quit(1);
12495c51f124SMoriah Waterland 				/* NOTREACHED */
12505c51f124SMoriah Waterland 			}
12515c51f124SMoriah Waterland 		}
12525c51f124SMoriah Waterland 
12535c51f124SMoriah Waterland 		if (!web_session_control(err, uri, dwnld_dir, keystore, proxy,
12545c51f124SMoriah Waterland 			proxy_port, retries, timeout, nointeract, &bname)) {
12555c51f124SMoriah Waterland 			pkgerr(err);
12565c51f124SMoriah Waterland 			web_cleanup();
12575c51f124SMoriah Waterland 			quit(1);
12585c51f124SMoriah Waterland 			/* NOTREACHED */
12595c51f124SMoriah Waterland 		}
12605c51f124SMoriah Waterland 
12615c51f124SMoriah Waterland 		/*
12625c51f124SMoriah Waterland 		 * reset device to point to newly-downloaded file; note
12635c51f124SMoriah Waterland 		 * when (scheme == web_https || scheme == web_http) that
12645c51f124SMoriah Waterland 		 * device gets preloaded with a pointer to PATH_MAX bytes
12655c51f124SMoriah Waterland 		 * allocated via malloc().
12665c51f124SMoriah Waterland 		 */
12675c51f124SMoriah Waterland 
12685c51f124SMoriah Waterland 		len = snprintf(device, PATH_MAX, "%s/%s", dwnld_dir, bname);
12695c51f124SMoriah Waterland 		if ((len < 0) || (len >= PATH_MAX)) {
12705c51f124SMoriah Waterland 			progerr(ERR_DIR_CONST, tmpdir);
12715c51f124SMoriah Waterland 			quit(1);
12725c51f124SMoriah Waterland 			/* NOTREACHED */
12735c51f124SMoriah Waterland 		}
12745c51f124SMoriah Waterland 	}
12755c51f124SMoriah Waterland 
12765c51f124SMoriah Waterland 	/*
12775c51f124SMoriah Waterland 	 * See if user wants this to be handled as an old style pkg.
12785c51f124SMoriah Waterland 	 * NOTE : the ``exception_pkg()'' stuff is to be used only
12795c51f124SMoriah Waterland 	 * through on495. This function comes out for on1095. See
12805c51f124SMoriah Waterland 	 * PSARC 1993-546. -- JST
12815c51f124SMoriah Waterland 	 */
12825c51f124SMoriah Waterland 
12835c51f124SMoriah Waterland 	if (getenv("NONABI_SCRIPTS") != NULL) {
12845c51f124SMoriah Waterland 		old_pkg = 1;
12855c51f124SMoriah Waterland 	}
12865c51f124SMoriah Waterland 
12875c51f124SMoriah Waterland 	/*
12885c51f124SMoriah Waterland 	 * See if the user wants to process symlinks consistent with
12895c51f124SMoriah Waterland 	 * the old behavior.
12905c51f124SMoriah Waterland 	 */
12915c51f124SMoriah Waterland 
12925c51f124SMoriah Waterland 	if (getenv("PKG_NONABI_SYMLINKS") != NULL) {
12935c51f124SMoriah Waterland 		old_symlinks = 1;
12945c51f124SMoriah Waterland 	}
12955c51f124SMoriah Waterland 
12965c51f124SMoriah Waterland 	/*
12975c51f124SMoriah Waterland 	 * See if the user wants the package name length restricted.
12985c51f124SMoriah Waterland 	 */
12995c51f124SMoriah Waterland 
13005c51f124SMoriah Waterland 	abiPtr = getenv("PKG_ABI_NAMELENGTH");
13015c51f124SMoriah Waterland 	if (abiPtr && strncasecmp(abiPtr, "TRUE", 4) == 0) {
13025c51f124SMoriah Waterland 		ABI_namelength = 1;
13035c51f124SMoriah Waterland 	}
13045c51f124SMoriah Waterland 
13055c51f124SMoriah Waterland 	/*
13065c51f124SMoriah Waterland 	 * validate the package source device - return pkgdev info that
13075c51f124SMoriah Waterland 	 * describes the package source device.
13085c51f124SMoriah Waterland 	 */
13095c51f124SMoriah Waterland 
13105c51f124SMoriah Waterland 	if (devtype(device, &pkgdev)) {
13115c51f124SMoriah Waterland 		progerr(ERR_BAD_DEVICE, device);
13125c51f124SMoriah Waterland 		quit(1);
13135c51f124SMoriah Waterland 		/* NOTREACHED */
13145c51f124SMoriah Waterland 	}
13155c51f124SMoriah Waterland 
13165c51f124SMoriah Waterland 	/*
13175c51f124SMoriah Waterland 	 * If writing the packages into a spool directory instead of
13185c51f124SMoriah Waterland 	 * installing the packages, open the package datastream and
13195c51f124SMoriah Waterland 	 * invoke pkgtrans to perform the conversion and exit.
13205c51f124SMoriah Waterland 	 */
13215c51f124SMoriah Waterland 
13225c51f124SMoriah Waterland 	if (spoolDir != (char *)NULL) {
13235c51f124SMoriah Waterland 		boolean_t	b;
13245c51f124SMoriah Waterland 		int		n;
13255c51f124SMoriah Waterland 
13265c51f124SMoriah Waterland 		echoDebug(DBG_INSTALLING_TO_SPOOL, spoolDir);
13275c51f124SMoriah Waterland 
13285c51f124SMoriah Waterland 		b = open_package_datastream(argc, argv, spoolDir, device,
13295c51f124SMoriah Waterland 						&repeat, &ids_name, tmpdir,
13305c51f124SMoriah Waterland 						&pkgdev, optind);
13315c51f124SMoriah Waterland 
13325c51f124SMoriah Waterland 		quitSetIdsName(ids_name);
13335c51f124SMoriah Waterland 
13345c51f124SMoriah Waterland 		if (b != B_TRUE) {
13355c51f124SMoriah Waterland 			progerr(ERR_CANNOT_OPEN_PKG_STREAM, PSTR(device));
13365c51f124SMoriah Waterland 			quit(1);
13375c51f124SMoriah Waterland 		}
13385c51f124SMoriah Waterland 
13395c51f124SMoriah Waterland 		n = pkgtrans(device, spoolDir, &argv[optind],
13405c51f124SMoriah Waterland 				0, NULL, NULL);
13415c51f124SMoriah Waterland 		quit(n);
13425c51f124SMoriah Waterland 		/* NOTREACHED */
13435c51f124SMoriah Waterland 	}
13445c51f124SMoriah Waterland 
13455c51f124SMoriah Waterland 	/*
13465c51f124SMoriah Waterland 	 * error if there are packages on the command line and a category
13475c51f124SMoriah Waterland 	 * was specified
13485c51f124SMoriah Waterland 	 */
13495c51f124SMoriah Waterland 
13505c51f124SMoriah Waterland 	if ((optind < argc) && (catg_arg != NULL)) {
13515c51f124SMoriah Waterland 		progerr(ERR_PKGS_AND_CAT_PKGADD);
13525c51f124SMoriah Waterland 		usage();
13535c51f124SMoriah Waterland 		quit(1);
13545c51f124SMoriah Waterland 		/* NOTREACHED */
13555c51f124SMoriah Waterland 	}
13565c51f124SMoriah Waterland 
13575c51f124SMoriah Waterland 	/*
13585c51f124SMoriah Waterland 	 * ********************************************************************
13595c51f124SMoriah Waterland 	 * main package processing "loop"
13605c51f124SMoriah Waterland 	 * ********************************************************************
13615c51f124SMoriah Waterland 	 */
13625c51f124SMoriah Waterland 
13635c51f124SMoriah Waterland 	ids_name = NULL;
13645c51f124SMoriah Waterland 	quitSetIdsName(ids_name);
13655c51f124SMoriah Waterland 
13665c51f124SMoriah Waterland 	for (;;) {
13675c51f124SMoriah Waterland 		boolean_t	b;
13685c51f124SMoriah Waterland 		char		**pkglist;	/* points to array of pkgs */
13695c51f124SMoriah Waterland 
13705c51f124SMoriah Waterland 		/*
13715c51f124SMoriah Waterland 		 * open next package data stream
13725c51f124SMoriah Waterland 		 */
13735c51f124SMoriah Waterland 
13745c51f124SMoriah Waterland 		b = open_package_datastream(argc, argv, spoolDir, device,
13755c51f124SMoriah Waterland 						&repeat, &ids_name, tmpdir,
13765c51f124SMoriah Waterland 						&pkgdev, optind);
13775c51f124SMoriah Waterland 
13785c51f124SMoriah Waterland 		quitSetIdsName(ids_name);
13795c51f124SMoriah Waterland 
13805c51f124SMoriah Waterland 		if (b == B_FALSE) {
13815c51f124SMoriah Waterland 			echoDebug(ERR_CANNOT_OPEN_PKG_STREAM, PSTR(device));
13825c51f124SMoriah Waterland 			continue;
13835c51f124SMoriah Waterland 		}
13845c51f124SMoriah Waterland 
13855c51f124SMoriah Waterland 		/*
13865c51f124SMoriah Waterland 		 * package source data stream open - get the package list
13875c51f124SMoriah Waterland 		 */
13885c51f124SMoriah Waterland 
13895c51f124SMoriah Waterland 		b = get_package_list(&pkglist, argv, catg_arg, category,
13905c51f124SMoriah Waterland 			ignore_sig, err, proxy_port, proxy, keystore,
13915c51f124SMoriah Waterland 			keystore_file, ids_name, &repeat);
13925c51f124SMoriah Waterland 
13935c51f124SMoriah Waterland 		if (b == B_FALSE) {
13945c51f124SMoriah Waterland 			char	path[PATH_MAX];
13955c51f124SMoriah Waterland 
13965c51f124SMoriah Waterland 			echoDebug(DBG_CANNOT_GET_PKGLIST);
13975c51f124SMoriah Waterland 
13985c51f124SMoriah Waterland 			/* check for existence of pre-SVR4 package */
13995c51f124SMoriah Waterland 			(void) snprintf(path, sizeof (path),
14005c51f124SMoriah Waterland 				"%s/install/INSTALL", pkgdev.dirname);
14015c51f124SMoriah Waterland 			if (access(path, F_OK) == 0) {
14025c51f124SMoriah Waterland 				pkginst = ((optind < argc) ?
14035c51f124SMoriah Waterland 					argv[optind++] : NULL);
14045c51f124SMoriah Waterland 				ckreturn(presvr4(&pkginst, nointeract));
14055c51f124SMoriah Waterland 				if (repeat || (optind < argc)) {
14065c51f124SMoriah Waterland 					continue;
14075c51f124SMoriah Waterland 				}
14085c51f124SMoriah Waterland 				quit(0);
14095c51f124SMoriah Waterland 			}
14105c51f124SMoriah Waterland 			progerr(ERR_NOPKGS, pkgdev.dirname);
14115c51f124SMoriah Waterland 			quit(1);
14125c51f124SMoriah Waterland 			/* NOTREACHED */
14135c51f124SMoriah Waterland 		}
14145c51f124SMoriah Waterland 
14155c51f124SMoriah Waterland 		/*
14165c51f124SMoriah Waterland 		 * count the number of packages to install
14175c51f124SMoriah Waterland 		 * NOTE: npkgs is a global variable that is referenced by quit.c
14185c51f124SMoriah Waterland 		 * when error messages are generated - it is referenced directly
14195c51f124SMoriah Waterland 		 * by the other functions called below...
14205c51f124SMoriah Waterland 		 */
14215c51f124SMoriah Waterland 
14225c51f124SMoriah Waterland 		for (npkgs = 0; pkglist[npkgs] != (char *)NULL; /* void */) {
14235c51f124SMoriah Waterland 			echoDebug(DBG_PKG_SELECTED, npkgs, pkglist[npkgs]);
14245c51f124SMoriah Waterland 			npkgs++;
14255c51f124SMoriah Waterland 		}
14265c51f124SMoriah Waterland 
14275c51f124SMoriah Waterland 		/* output number of packages to be added */
14285c51f124SMoriah Waterland 
14295c51f124SMoriah Waterland 		echoDebug(DBG_NUM_PKGS_TO_ADD, npkgs);
14305c51f124SMoriah Waterland 
14315c51f124SMoriah Waterland 		/*
14325c51f124SMoriah Waterland 		 * if pkgask and response container is a file (not a directory),
14335c51f124SMoriah Waterland 		 * and there is more than one package to install, then it is an
14345c51f124SMoriah Waterland 		 * error - too many packages to install when response container
14355c51f124SMoriah Waterland 		 * is a file.
14365c51f124SMoriah Waterland 		 */
14375c51f124SMoriah Waterland 
14385c51f124SMoriah Waterland 		if ((askflag != 0) && (respdir == (char *)NULL) &&
14395c51f124SMoriah Waterland 			(npkgs > 1)) {
14405c51f124SMoriah Waterland 			progerr(ERR_TOO_MANY_PKGS);
14415c51f124SMoriah Waterland 			quit(1);
14425c51f124SMoriah Waterland 			/* NOTREACHED */
14435c51f124SMoriah Waterland 		}
14445c51f124SMoriah Waterland 
14455c51f124SMoriah Waterland 		/*
14465c51f124SMoriah Waterland 		 * package list generated - add packages
14475c51f124SMoriah Waterland 		 */
14485c51f124SMoriah Waterland 
14495c51f124SMoriah Waterland 		b = add_packages(pkglist, uri, ids_name, repeat,
14505c51f124SMoriah Waterland 					altBinDir, device, noZones);
14515c51f124SMoriah Waterland 
14525c51f124SMoriah Waterland 		/*
14535c51f124SMoriah Waterland 		 * close open input data stream (source package) if left open.
14545c51f124SMoriah Waterland 		 */
14555c51f124SMoriah Waterland 
14565c51f124SMoriah Waterland 		if (ids_name) {
14575c51f124SMoriah Waterland 			echoDebug(DBG_CLOSING_STREAM, ids_name,
14585c51f124SMoriah Waterland 					PSTR(pkgdev.dirname));
14595c51f124SMoriah Waterland 			(void) ds_close(1);
14605c51f124SMoriah Waterland 			rrmdir(pkgdev.dirname);
14615c51f124SMoriah Waterland 			ids_name = NULL;
14625c51f124SMoriah Waterland 			quitSetIdsName(ids_name);
14635c51f124SMoriah Waterland 		}
14645c51f124SMoriah Waterland 
14655c51f124SMoriah Waterland 		/*
14665c51f124SMoriah Waterland 		 * continue with next sequence of packages if continue set
14675c51f124SMoriah Waterland 		 */
14685c51f124SMoriah Waterland 
14695c51f124SMoriah Waterland 		if (b == B_TRUE) {
14705c51f124SMoriah Waterland 			continue;
14715c51f124SMoriah Waterland 		}
14725c51f124SMoriah Waterland 
14735c51f124SMoriah Waterland 		/*
14745c51f124SMoriah Waterland 		 * not continuing - quit with 0 exit code
14755c51f124SMoriah Waterland 		 */
14765c51f124SMoriah Waterland 
14775c51f124SMoriah Waterland 		quit(0);
14785c51f124SMoriah Waterland 		/* NOTREACHED */
14795c51f124SMoriah Waterland 	}
14805c51f124SMoriah Waterland 
14815c51f124SMoriah Waterland 	/* NOTREACHED */
14825c51f124SMoriah Waterland }
14835c51f124SMoriah Waterland 
14845c51f124SMoriah Waterland /*
14855c51f124SMoriah Waterland  * *****************************************************************************
14865c51f124SMoriah Waterland  * static internal (private) functions
14875c51f124SMoriah Waterland  * *****************************************************************************
14885c51f124SMoriah Waterland  */
14895c51f124SMoriah Waterland 
14905c51f124SMoriah Waterland /*
14915c51f124SMoriah Waterland  * Name:	pkgZoneCheckInstall
14925c51f124SMoriah Waterland  * Description:	Invoke pkginstall in a specified zone to perform a preinstall
14935c51f124SMoriah Waterland  *		check of the a single package in the specified zone
14945c51f124SMoriah Waterland  * Arguments:	a_zoneName - pointer to string representing the name of the
14955c51f124SMoriah Waterland  *			zone to check install the package in.
14965c51f124SMoriah Waterland  *		a_inheritedPkgDirs - pointer to array of strings, each one
14975c51f124SMoriah Waterland  *			representing the non-global zones full path of a
14985c51f124SMoriah Waterland  *			directory that is inherited from the global zone.
14995c51f124SMoriah Waterland  *		a_zoneState - current state of the zone; must be mounted or
15005c51f124SMoriah Waterland  *			running.
15015c51f124SMoriah Waterland  *		a_idsName - pointer to string representing the data stream
15025c51f124SMoriah Waterland  *			device (input data stream) containing the package to
15035c51f124SMoriah Waterland  *			be check installed.
15045c51f124SMoriah Waterland  *		a_altBinDir - pointer to string representing an alternative
15055c51f124SMoriah Waterland  *			binary location directory to pass to pkginstall.
15065c51f124SMoriah Waterland  *			If this is == NULL no alternative binary location is
15075c51f124SMoriah Waterland  *			passed to pkginstall.
15085c51f124SMoriah Waterland  *		a_adminFile - pointer to string representing the admin
15095c51f124SMoriah Waterland  *			file to pass to pkginstall when installing the package.
15105c51f124SMoriah Waterland  *			If this is == NULL no admin file is given to pkginstall.
15115c51f124SMoriah Waterland  *		a_stdoutPath - pointer to string representing the local path
15125c51f124SMoriah Waterland  *			into which all output written by pkginstall to stdout
15135c51f124SMoriah Waterland  *			is stored.
15145c51f124SMoriah Waterland  *			If this is == NULL stdout is redirected to /dev/null
1515*62224350SCasper H.S. Dik  *		a_tmpzn - B_TRUE when this zone is booted by the package
1516*62224350SCasper H.S. Dik  *			command or B_FALSE if it was running before.
15175c51f124SMoriah Waterland  * Returns:	int	(see ckreturn() function for details)
15185c51f124SMoriah Waterland  *		0 - success
15195c51f124SMoriah Waterland  *		1 - package operation failed (fatal error)
15205c51f124SMoriah Waterland  *		2 - non-fatal error (warning)
15215c51f124SMoriah Waterland  *		3 - user selected quit (operation interrupted)
15225c51f124SMoriah Waterland  *		4 - admin settings prevented operation
15235c51f124SMoriah Waterland  *		5 - interaction required and -n (non-interactive) specified
15245c51f124SMoriah Waterland  *		"10" will be added to indicate "immediate reboot required"
15255c51f124SMoriah Waterland  *		"20" will be added to indicate "reboot after install required"
15265c51f124SMoriah Waterland  */
15275c51f124SMoriah Waterland 
15285c51f124SMoriah Waterland static int
15295c51f124SMoriah Waterland pkgZoneCheckInstall(char *a_zoneName, char **a_inheritedPkgDirs,
15305c51f124SMoriah Waterland 	zone_state_t a_zoneState, char *a_idsName, char *a_altBinDir,
1531*62224350SCasper H.S. Dik 	char *a_adminFile, char *a_stdoutPath, boolean_t a_tmpzn)
15325c51f124SMoriah Waterland {
15335c51f124SMoriah Waterland 	char	*arg[MAXARGS];
15345c51f124SMoriah Waterland 	char	*p;
15355c51f124SMoriah Waterland 	char	adminfd_path[PATH_MAX];
15365c51f124SMoriah Waterland 	char	path[PATH_MAX];
15375c51f124SMoriah Waterland 	char	pkgstreamfd_path[PATH_MAX];
15385c51f124SMoriah Waterland 	int	fds[MAX_FDS];
15395c51f124SMoriah Waterland 	int	maxfds;
15405c51f124SMoriah Waterland 	int	n;
15415c51f124SMoriah Waterland 	int	nargs;
15425c51f124SMoriah Waterland 
15435c51f124SMoriah Waterland 	/* entry assertions */
15445c51f124SMoriah Waterland 
15455c51f124SMoriah Waterland 	assert(a_zoneName != (char *)NULL);
15465c51f124SMoriah Waterland 	assert(*a_zoneName != '\0');
15475c51f124SMoriah Waterland 
15485c51f124SMoriah Waterland 	/* entry debugging info */
15495c51f124SMoriah Waterland 
15505c51f124SMoriah Waterland 	echoDebug(DBG_PKGZONECHECKINSTALL_ENTRY);
15515c51f124SMoriah Waterland 	echoDebug(DBG_PKGZONECHECKINSTALL_ARGS, a_zoneName, PSTR(pkginst),
15525c51f124SMoriah Waterland 		PSTR(pkgdev.dirname), PSTR(pkgdev.mount), PSTR(pkgdev.bdevice),
15535c51f124SMoriah Waterland 		a_zoneState == ZONE_STATE_MOUNTED ? "/a" : "/",
15545c51f124SMoriah Waterland 		PSTR(a_idsName), PSTR(a_adminFile), PSTR(a_stdoutPath));
15555c51f124SMoriah Waterland 
15565c51f124SMoriah Waterland 	/* generate full path to 'phatinstall' to run in zone */
15575c51f124SMoriah Waterland 
15585c51f124SMoriah Waterland 	(void) snprintf(path, sizeof (path), "%s/pkginstall",
15595c51f124SMoriah Waterland 			"/usr/sadm/install/bin");
15605c51f124SMoriah Waterland 
15615c51f124SMoriah Waterland 	/* start at first file descriptor */
15625c51f124SMoriah Waterland 
15635c51f124SMoriah Waterland 	maxfds = 0;
15645c51f124SMoriah Waterland 
15655c51f124SMoriah Waterland 	/*
15665c51f124SMoriah Waterland 	 * generate argument list for call to pkginstall
15675c51f124SMoriah Waterland 	 */
15685c51f124SMoriah Waterland 
15695c51f124SMoriah Waterland 	/* start at argument 0 */
15705c51f124SMoriah Waterland 
15715c51f124SMoriah Waterland 	nargs = 0;
15725c51f124SMoriah Waterland 
15735c51f124SMoriah Waterland 	/* first argument is always: full path to executable */
15745c51f124SMoriah Waterland 
15755c51f124SMoriah Waterland 	arg[nargs++] = path;
15765c51f124SMoriah Waterland 
15775c51f124SMoriah Waterland 	/*
15785c51f124SMoriah Waterland 	 * second argument is always: pass -O debug to pkginstall: debug mode
15795c51f124SMoriah Waterland 	 */
15805c51f124SMoriah Waterland 	if (debugFlag == B_TRUE) {
15815c51f124SMoriah Waterland 		arg[nargs++] = "-O";
15825c51f124SMoriah Waterland 		arg[nargs++] = "debug";
15835c51f124SMoriah Waterland 	}
15845c51f124SMoriah Waterland 
15855c51f124SMoriah Waterland 	/* pkgadd -G: pass -G to pkginstall */
15865c51f124SMoriah Waterland 
15875c51f124SMoriah Waterland 	if (globalZoneOnly == B_TRUE) {
15885c51f124SMoriah Waterland 		arg[nargs++] = "-G";
15895c51f124SMoriah Waterland 	}
15905c51f124SMoriah Waterland 
15915c51f124SMoriah Waterland 	/* pkgadd -b dir: pass -b to pkginstall */
15925c51f124SMoriah Waterland 
15935c51f124SMoriah Waterland 	if (a_altBinDir != (char *)NULL) {
15945c51f124SMoriah Waterland 		arg[nargs++] = "-b";
15955c51f124SMoriah Waterland 		arg[nargs++] = a_altBinDir;
15965c51f124SMoriah Waterland 	}
15975c51f124SMoriah Waterland 
15985c51f124SMoriah Waterland 	/* pkgadd -C: pass -C to pkginstall: disable checksum */
15995c51f124SMoriah Waterland 
16005c51f124SMoriah Waterland 	if (disableChecksum) {
16015c51f124SMoriah Waterland 		arg[nargs++] = "-C";
16025c51f124SMoriah Waterland 	}
16035c51f124SMoriah Waterland 
16045c51f124SMoriah Waterland 	/* pkgadd -A: pass -A to pkginstall: disable attribute checking */
16055c51f124SMoriah Waterland 
16065c51f124SMoriah Waterland 	if (disableAttributes) {
16075c51f124SMoriah Waterland 		arg[nargs++] = "-A";
16085c51f124SMoriah Waterland 	}
16095c51f124SMoriah Waterland 
16105c51f124SMoriah Waterland 	/*
16115c51f124SMoriah Waterland 	 * NONABI_SCRIPTS defined: pass -o to pkginstall; refers to a
16125c51f124SMoriah Waterland 	 * pkg requiring operator interaction during a procedure script
16135c51f124SMoriah Waterland 	 * (common before on1093)
16145c51f124SMoriah Waterland 	 */
16155c51f124SMoriah Waterland 
16165c51f124SMoriah Waterland 	if (old_pkg) {
16175c51f124SMoriah Waterland 		arg[nargs++] = "-o";
16185c51f124SMoriah Waterland 	}
16195c51f124SMoriah Waterland 
16205c51f124SMoriah Waterland 	/*
16215c51f124SMoriah Waterland 	 * PKG_NONABI_SYMLINKS defined: pass -y to pkginstall; process
16225c51f124SMoriah Waterland 	 * symlinks consistent with old behavior
16235c51f124SMoriah Waterland 	 */
16245c51f124SMoriah Waterland 
16255c51f124SMoriah Waterland 	if (old_symlinks) {
16265c51f124SMoriah Waterland 		arg[nargs++] = "-y";
16275c51f124SMoriah Waterland 	}
16285c51f124SMoriah Waterland 
16295c51f124SMoriah Waterland 	/*
16305c51f124SMoriah Waterland 	 * PKG_ABI_NAMELENGTH defined: pass -e to pkginstall; causes
16315c51f124SMoriah Waterland 	 * package name length to be restricted
16325c51f124SMoriah Waterland 	 */
16335c51f124SMoriah Waterland 
16345c51f124SMoriah Waterland 	if (ABI_namelength) {
16355c51f124SMoriah Waterland 		arg[nargs++] = "-e";
16365c51f124SMoriah Waterland 	}
16375c51f124SMoriah Waterland 
16385c51f124SMoriah Waterland 	/* pkgadd -S: pass -S to pkginstall: suppress copyright notices */
16395c51f124SMoriah Waterland 
16405c51f124SMoriah Waterland 	arg[nargs++] = "-S";
16415c51f124SMoriah Waterland 
16425c51f124SMoriah Waterland 	/* pkgadd -M: pass -M to pkginstall: dont mount client file systems */
16435c51f124SMoriah Waterland 
16445c51f124SMoriah Waterland 	arg[nargs++] = "-M";
16455c51f124SMoriah Waterland 
16465c51f124SMoriah Waterland 	/* pkgadd -v: pass -v to pkginstall: never trace scripts */
16475c51f124SMoriah Waterland 
16485c51f124SMoriah Waterland 	/* if running pkgask, pass -i to pkginstall: running pkgask */
16495c51f124SMoriah Waterland 
16505c51f124SMoriah Waterland 	if (askflag) {
16515c51f124SMoriah Waterland 		return (0);
16525c51f124SMoriah Waterland 	}
16535c51f124SMoriah Waterland 
16545c51f124SMoriah Waterland 	/* pass "-O enable-hollow-package-support" */
16555c51f124SMoriah Waterland 
16565c51f124SMoriah Waterland 	if (is_depend_pkginfo_DB()) {
16575c51f124SMoriah Waterland 		arg[nargs++] = "-O";
16585c51f124SMoriah Waterland 		arg[nargs++] = "enable-hollow-package-support";
16595c51f124SMoriah Waterland 	}
16605c51f124SMoriah Waterland 
16615c51f124SMoriah Waterland 	/* check is always in non-interactive mode */
16625c51f124SMoriah Waterland 
16635c51f124SMoriah Waterland 	arg[nargs++] = "-n";
16645c51f124SMoriah Waterland 
16655c51f124SMoriah Waterland 	/* pkgadd -a admin: pass -a admin to pkginstall in zone: admin file */
16665c51f124SMoriah Waterland 
16675c51f124SMoriah Waterland 	if (a_adminFile) {
16685c51f124SMoriah Waterland 		int fd;
16695c51f124SMoriah Waterland 		fd = openLocal(a_adminFile, O_RDONLY, tmpdir);
16705c51f124SMoriah Waterland 		if (fd < 0) {
16715c51f124SMoriah Waterland 			progerr(ERR_CANNOT_COPY_LOCAL, a_adminFile,
16725c51f124SMoriah Waterland 				errno, strerror(errno));
16735c51f124SMoriah Waterland 			return (1);
16745c51f124SMoriah Waterland 		}
16755c51f124SMoriah Waterland 		(void) snprintf(adminfd_path, sizeof (adminfd_path),
16765c51f124SMoriah Waterland 			"/proc/self/fd/%d", fd);
16775c51f124SMoriah Waterland 		fds[maxfds++] = fd;
16785c51f124SMoriah Waterland 		arg[nargs++] = "-a";
16795c51f124SMoriah Waterland 		arg[nargs++] = adminfd_path;
16805c51f124SMoriah Waterland 	}
16815c51f124SMoriah Waterland 
16825c51f124SMoriah Waterland 	/* pkgadd -R root: pass -R /a to pkginstall when zone is mounted */
16835c51f124SMoriah Waterland 
16845c51f124SMoriah Waterland 	if (a_zoneState == ZONE_STATE_MOUNTED) {
16855c51f124SMoriah Waterland 		arg[nargs++] = "-R";
16865c51f124SMoriah Waterland 		arg[nargs++] = "/a";
16875c51f124SMoriah Waterland 	}
16885c51f124SMoriah Waterland 
16895c51f124SMoriah Waterland 	/* pass -N to pkginstall: program name to report */
16905c51f124SMoriah Waterland 
16915c51f124SMoriah Waterland 	arg[nargs++] = "-N";
16925c51f124SMoriah Waterland 	arg[nargs++] = get_prog_name();
16935c51f124SMoriah Waterland 
16945c51f124SMoriah Waterland 	/* pass "-O preinstallcheck" */
16955c51f124SMoriah Waterland 
16965c51f124SMoriah Waterland 	arg[nargs++] = "-O";
16975c51f124SMoriah Waterland 	arg[nargs++] = "preinstallcheck";
16985c51f124SMoriah Waterland 
16995c51f124SMoriah Waterland 	/* add "-O addzonename" */
17005c51f124SMoriah Waterland 
17015c51f124SMoriah Waterland 	arg[nargs++] = "-O";
17025c51f124SMoriah Waterland 	arg[nargs++] = "addzonename";
17035c51f124SMoriah Waterland 
17045c51f124SMoriah Waterland 	if (isPatchUpdate()) {
17055c51f124SMoriah Waterland 		if (patchPkgRemoval == B_TRUE) {
17065c51f124SMoriah Waterland 			arg[nargs++] = "-O";
17075c51f124SMoriah Waterland 			arg[nargs++] = "patchPkgRemoval";
17085c51f124SMoriah Waterland 		} else {
17095c51f124SMoriah Waterland 			arg[nargs++] = "-O";
17105c51f124SMoriah Waterland 			arg[nargs++] = "patchPkgInstall";
17115c51f124SMoriah Waterland 		}
17125c51f124SMoriah Waterland 	}
17135c51f124SMoriah Waterland 
17145c51f124SMoriah Waterland 	/* add all inherited file systems */
17155c51f124SMoriah Waterland 
17165c51f124SMoriah Waterland 	if (a_inheritedPkgDirs != (char **)NULL) {
17175c51f124SMoriah Waterland 		for (n = 0; a_inheritedPkgDirs[n] != (char *)NULL; n++) {
17185c51f124SMoriah Waterland 			char	ifs[MAXPATHLEN+22];
17195c51f124SMoriah Waterland 			(void) snprintf(ifs, sizeof (ifs),
17205c51f124SMoriah Waterland 				"inherited-filesystem=%s",
17215c51f124SMoriah Waterland 				a_inheritedPkgDirs[n]);
17225c51f124SMoriah Waterland 			arg[nargs++] = "-O";
17235c51f124SMoriah Waterland 			arg[nargs++] = strdup(ifs);
17245c51f124SMoriah Waterland 		}
17255c51f124SMoriah Waterland 	}
17265c51f124SMoriah Waterland 
17275c51f124SMoriah Waterland 	/*
17285c51f124SMoriah Waterland 	 * add parent zone info/type
17295c51f124SMoriah Waterland 	 */
17305c51f124SMoriah Waterland 
17315c51f124SMoriah Waterland 	p = z_get_zonename();
17325c51f124SMoriah Waterland 	if ((p != NULL) && (*p != '\0')) {
17335c51f124SMoriah Waterland 			char	zn[MAXPATHLEN];
17345c51f124SMoriah Waterland 			(void) snprintf(zn, sizeof (zn),
17355c51f124SMoriah Waterland 				"parent-zone-name=%s", p);
17365c51f124SMoriah Waterland 			arg[nargs++] = "-O";
17375c51f124SMoriah Waterland 			arg[nargs++] = strdup(zn);
17385c51f124SMoriah Waterland 	}
17395c51f124SMoriah Waterland 
17405c51f124SMoriah Waterland 	/* current zone type */
17415c51f124SMoriah Waterland 
17425c51f124SMoriah Waterland 	arg[nargs++] = "-O";
17435c51f124SMoriah Waterland 	if (z_running_in_global_zone() == B_TRUE) {
17445c51f124SMoriah Waterland 			char	zn[MAXPATHLEN];
17455c51f124SMoriah Waterland 			(void) snprintf(zn, sizeof (zn),
17465c51f124SMoriah Waterland 				"parent-zone-type=%s",
17475c51f124SMoriah Waterland 				TAG_VALUE_GLOBAL_ZONE);
17485c51f124SMoriah Waterland 			arg[nargs++] = strdup(zn);
17495c51f124SMoriah Waterland 	} else {
17505c51f124SMoriah Waterland 			char	zn[MAXPATHLEN];
17515c51f124SMoriah Waterland 			(void) snprintf(zn, sizeof (zn),
17525c51f124SMoriah Waterland 				"parent-zone-type=%s",
17535c51f124SMoriah Waterland 				TAG_VALUE_NONGLOBAL_ZONE);
17545c51f124SMoriah Waterland 			arg[nargs++] = strdup(zn);
17555c51f124SMoriah Waterland 	}
17565c51f124SMoriah Waterland 
1757*62224350SCasper H.S. Dik 	/* Add the pkgserv options */
1758*62224350SCasper H.S. Dik 	arg[nargs++] = "-O";
1759*62224350SCasper H.S. Dik 	arg[nargs++] = pkgmodeargument(a_tmpzn ? RUN_ONCE : pkgservergetmode());
1760*62224350SCasper H.S. Dik 
17615c51f124SMoriah Waterland 	/* add in the package stream file */
17625c51f124SMoriah Waterland 
17635c51f124SMoriah Waterland 	if (a_idsName != NULL) {
17645c51f124SMoriah Waterland 		int fd;
17655c51f124SMoriah Waterland 		fd = openLocal(a_idsName, O_RDONLY, tmpdir);
17665c51f124SMoriah Waterland 		if (fd < 0) {
17675c51f124SMoriah Waterland 			progerr(ERR_STREAM_UNAVAILABLE, a_idsName,
17685c51f124SMoriah Waterland 				pkginst, strerror(errno));
17695c51f124SMoriah Waterland 			quit(1);
17705c51f124SMoriah Waterland 		}
17715c51f124SMoriah Waterland 		(void) snprintf(pkgstreamfd_path, sizeof (pkgstreamfd_path),
17725c51f124SMoriah Waterland 			"/proc/self/fd/%d", fd);
17735c51f124SMoriah Waterland 		fds[maxfds++] = fd;
17745c51f124SMoriah Waterland 		arg[nargs++] = pkgstreamfd_path;
17755c51f124SMoriah Waterland 	} else {
17765c51f124SMoriah Waterland 		progerr(ERR_PKGZONEINSTALL_NO_STREAM);
17775c51f124SMoriah Waterland 		quit(1);
17785c51f124SMoriah Waterland 	}
17795c51f124SMoriah Waterland 
17805c51f124SMoriah Waterland 	/* add package instance name */
17815c51f124SMoriah Waterland 
17825c51f124SMoriah Waterland 	arg[nargs++] = pkginst;
17835c51f124SMoriah Waterland 
17845c51f124SMoriah Waterland 	/* terminate the argument list */
17855c51f124SMoriah Waterland 
17865c51f124SMoriah Waterland 	arg[nargs++] = NULL;
17875c51f124SMoriah Waterland 
17885c51f124SMoriah Waterland 	/*
17895c51f124SMoriah Waterland 	 * run the appropriate pkginstall command in the specified zone
17905c51f124SMoriah Waterland 	 */
17915c51f124SMoriah Waterland 
17925c51f124SMoriah Waterland 	if (debugFlag == B_TRUE) {
17935c51f124SMoriah Waterland 		echoDebug(DBG_ZONE_EXEC_ENTER, a_zoneName, arg[0]);
17945c51f124SMoriah Waterland 		for (n = 0; arg[n]; n++) {
17955c51f124SMoriah Waterland 			echoDebug(DBG_ARG, n, arg[n]);
17965c51f124SMoriah Waterland 		}
17975c51f124SMoriah Waterland 	}
17985c51f124SMoriah Waterland 
17995c51f124SMoriah Waterland 	/* terminate file descriptor list */
18005c51f124SMoriah Waterland 
18015c51f124SMoriah Waterland 	fds[maxfds] = -1;
18025c51f124SMoriah Waterland 
18035c51f124SMoriah Waterland 	/* exec command in zone */
18045c51f124SMoriah Waterland 
18055c51f124SMoriah Waterland 	n = z_zone_exec(a_zoneName, path, arg, a_stdoutPath, (char *)NULL, fds);
18065c51f124SMoriah Waterland 
18075c51f124SMoriah Waterland 	echoDebug(DBG_ZONE_EXEC_EXIT, a_zoneName, arg[0], n,
18085c51f124SMoriah Waterland 			PSTR(a_stdoutPath));
18095c51f124SMoriah Waterland 
18105c51f124SMoriah Waterland 	/*
18115c51f124SMoriah Waterland 	 * close any files that were opened for use by the
18125c51f124SMoriah Waterland 	 * /proc/self/fd interface so they could be passed to programs
18135c51f124SMoriah Waterland 	 * via the z_zone_exec() interface
18145c51f124SMoriah Waterland 	 */
18155c51f124SMoriah Waterland 
18165c51f124SMoriah Waterland 	for (; maxfds > 0; maxfds--) {
18175c51f124SMoriah Waterland 		(void) close(fds[maxfds-1]);
18185c51f124SMoriah Waterland 	}
18195c51f124SMoriah Waterland 
18205c51f124SMoriah Waterland 	/* return results of pkginstall in zone execution */
18215c51f124SMoriah Waterland 
18225c51f124SMoriah Waterland 	return (n);
18235c51f124SMoriah Waterland }
18245c51f124SMoriah Waterland 
18255c51f124SMoriah Waterland /*
18265c51f124SMoriah Waterland  * Name:	pkgZoneInstall
18275c51f124SMoriah Waterland  * Description:	Invoke pkginstall in a specified zone to perform an install
18285c51f124SMoriah Waterland  *		of a single package in the specified zone
18295c51f124SMoriah Waterland  * Arguments:	a_zoneName - pointer to string representing the name of the
18305c51f124SMoriah Waterland  *			zone to install the package in.
18315c51f124SMoriah Waterland  *		a_inheritedPkgDirs - pointer to array of strings, each one
18325c51f124SMoriah Waterland  *			representing the non-global zones full path of a
18335c51f124SMoriah Waterland  *			directory that is inherited from the global zone.
18345c51f124SMoriah Waterland  *		a_zoneState - current state of the zone; must be mounted or
18355c51f124SMoriah Waterland  *			running.
18365c51f124SMoriah Waterland  *		a_idsName - pointer to string representing the data stream
18375c51f124SMoriah Waterland  *			device (input data stream) containing the package to
18385c51f124SMoriah Waterland  *			be installed.
18395c51f124SMoriah Waterland  *		a_altBinDir - pointer to string representing an alternative
18405c51f124SMoriah Waterland  *			binary location directory to pass to pkginstall.
18415c51f124SMoriah Waterland  *			If this is == NULL no alternative binary location is
18425c51f124SMoriah Waterland  *			passed to pkginstall.
18435c51f124SMoriah Waterland  *		a_adminFile - pointer to string representing the admin
18445c51f124SMoriah Waterland  *			file to pass to pkginstall when installing the package.
18455c51f124SMoriah Waterland  *			If this is == NULL no admin file is given to pkginstall.
18465c51f124SMoriah Waterland  *		a_stdoutPath - pointer to string representing the local path
18475c51f124SMoriah Waterland  *			into which all output written by pkginstall to stdout
18485c51f124SMoriah Waterland  *			is stored.
18495c51f124SMoriah Waterland  *			If this is == NULL stdout is redirected to /dev/null
1850*62224350SCasper H.S. Dik  *		a_tmpzn - B_TRUE when this zone is booted by the package
1851*62224350SCasper H.S. Dik  *			command or B_FALSE if it was running before.
18525c51f124SMoriah Waterland  * Returns:	int	(see ckreturn() function for details)
18535c51f124SMoriah Waterland  *		0 - success
18545c51f124SMoriah Waterland  *		1 - package operation failed (fatal error)
18555c51f124SMoriah Waterland  *		2 - non-fatal error (warning)
18565c51f124SMoriah Waterland  *		3 - user selected quit (operation interrupted)
18575c51f124SMoriah Waterland  *		4 - admin settings prevented operation
18585c51f124SMoriah Waterland  *		5 - interaction required and -n (non-interactive) specified
18595c51f124SMoriah Waterland  *		"10" will be added to indicate "immediate reboot required"
18605c51f124SMoriah Waterland  *		"20" will be added to indicate "reboot after install required"
18615c51f124SMoriah Waterland  */
18625c51f124SMoriah Waterland 
18635c51f124SMoriah Waterland static int
18645c51f124SMoriah Waterland pkgZoneInstall(char *a_zoneName, char **a_inheritedPkgDirs,
18655c51f124SMoriah Waterland     zone_state_t a_zoneState, char *a_idsName, char *a_altBinDir,
1866*62224350SCasper H.S. Dik     char *a_adminFile, boolean_t a_tmpzn)
18675c51f124SMoriah Waterland {
18685c51f124SMoriah Waterland 	char	*arg[MAXARGS];
18695c51f124SMoriah Waterland 	char	*p;
18705c51f124SMoriah Waterland 	char	adminfd_path[PATH_MAX];
18715c51f124SMoriah Waterland 	char	path[PATH_MAX];
18725c51f124SMoriah Waterland 	char	pkgstreamfd_path[PATH_MAX];
18735c51f124SMoriah Waterland 	char	respfilefd_path[PATH_MAX];
18745c51f124SMoriah Waterland 	int	fds[MAX_FDS];
18755c51f124SMoriah Waterland 	int	maxfds;
18765c51f124SMoriah Waterland 	int	n;
18775c51f124SMoriah Waterland 	int	nargs;
18785c51f124SMoriah Waterland 
18795c51f124SMoriah Waterland 	/* entry assertions */
18805c51f124SMoriah Waterland 
18815c51f124SMoriah Waterland 	assert(a_zoneName != (char *)NULL);
18825c51f124SMoriah Waterland 	assert(*a_zoneName != '\0');
18835c51f124SMoriah Waterland 
18845c51f124SMoriah Waterland 	/* entry debugging info */
18855c51f124SMoriah Waterland 
18865c51f124SMoriah Waterland 	echoDebug(DBG_PKGZONEINSTALL_ENTRY);
18875c51f124SMoriah Waterland 	echoDebug(DBG_PKGZONEINSTALL_ARGS, a_zoneName, PSTR(pkginst),
18885c51f124SMoriah Waterland 		PSTR(pkgdev.dirname), PSTR(pkgdev.mount), PSTR(pkgdev.bdevice),
18895c51f124SMoriah Waterland 		a_zoneState == ZONE_STATE_MOUNTED ? "/a" : "", PSTR(a_idsName),
18905c51f124SMoriah Waterland 		a_adminFile);
18915c51f124SMoriah Waterland 
18925c51f124SMoriah Waterland 	/* generate path to pkginstall */
18935c51f124SMoriah Waterland 
18945c51f124SMoriah Waterland 	(void) snprintf(path, sizeof (path), "%s/pkginstall", PKGBIN);
18955c51f124SMoriah Waterland 
18965c51f124SMoriah Waterland 	/* start at first file descriptor */
18975c51f124SMoriah Waterland 
18985c51f124SMoriah Waterland 	maxfds = 0;
18995c51f124SMoriah Waterland 
19005c51f124SMoriah Waterland 	/*
19015c51f124SMoriah Waterland 	 * generate argument list for call to pkginstall
19025c51f124SMoriah Waterland 	 */
19035c51f124SMoriah Waterland 
19045c51f124SMoriah Waterland 	/* start at argument 0 */
19055c51f124SMoriah Waterland 
19065c51f124SMoriah Waterland 	nargs = 0;
19075c51f124SMoriah Waterland 
19085c51f124SMoriah Waterland 	/* first argument is path to executable */
19095c51f124SMoriah Waterland 
19105c51f124SMoriah Waterland 	arg[nargs++] = path;
19115c51f124SMoriah Waterland 
19125c51f124SMoriah Waterland 	/*
19135c51f124SMoriah Waterland 	 * second argument is always: pass -O debug to pkginstall: debug mode
19145c51f124SMoriah Waterland 	 */
19155c51f124SMoriah Waterland 	if (debugFlag == B_TRUE) {
19165c51f124SMoriah Waterland 		arg[nargs++] = "-O";
19175c51f124SMoriah Waterland 		arg[nargs++] = "debug";
19185c51f124SMoriah Waterland 	}
19195c51f124SMoriah Waterland 
19205c51f124SMoriah Waterland 	/* pkgadd -G: pass -G to pkginstall */
19215c51f124SMoriah Waterland 
19225c51f124SMoriah Waterland 	if (globalZoneOnly == B_TRUE) {
19235c51f124SMoriah Waterland 		arg[nargs++] = "-G";
19245c51f124SMoriah Waterland 	}
19255c51f124SMoriah Waterland 
19265c51f124SMoriah Waterland 	/* pkgadd -b dir: pass -b to pkginstall in zone */
19275c51f124SMoriah Waterland 
19285c51f124SMoriah Waterland 	if (a_altBinDir != (char *)NULL) {
19295c51f124SMoriah Waterland 		arg[nargs++] = "-b";
19305c51f124SMoriah Waterland 		arg[nargs++] = a_altBinDir;
19315c51f124SMoriah Waterland 	}
19325c51f124SMoriah Waterland 
19335c51f124SMoriah Waterland 	/* pkgadd -B blocksize: pass -B to pkginstall in zone */
19345c51f124SMoriah Waterland 
19355c51f124SMoriah Waterland 	if (rw_block_size != NULL) {
19365c51f124SMoriah Waterland 		arg[nargs++] = "-B";
19375c51f124SMoriah Waterland 		arg[nargs++] = rw_block_size;
19385c51f124SMoriah Waterland 	}
19395c51f124SMoriah Waterland 
19405c51f124SMoriah Waterland 	/* pkgadd -C: pass -C to pkgadd in zone: disable checksum */
19415c51f124SMoriah Waterland 
19425c51f124SMoriah Waterland 	if (disableChecksum) {
19435c51f124SMoriah Waterland 		arg[nargs++] = "-C";
19445c51f124SMoriah Waterland 	}
19455c51f124SMoriah Waterland 
19465c51f124SMoriah Waterland 	/* pkgadd -A: pass -A to pkgadd in zone: disable attribute checking */
19475c51f124SMoriah Waterland 
19485c51f124SMoriah Waterland 	if (disableAttributes) {
19495c51f124SMoriah Waterland 		arg[nargs++] = "-A";
19505c51f124SMoriah Waterland 	}
19515c51f124SMoriah Waterland 
19525c51f124SMoriah Waterland 	/* pkgadd -S: pass -S to pkgadd in zone: suppress copyright notices */
19535c51f124SMoriah Waterland 
19545c51f124SMoriah Waterland 	arg[nargs++] = "-S";
19555c51f124SMoriah Waterland 
19565c51f124SMoriah Waterland 	/* pkgadd -I: pass -I to pkgadd in zone: initial install */
19575c51f124SMoriah Waterland 
19585c51f124SMoriah Waterland 	if (init_install) {
19595c51f124SMoriah Waterland 		arg[nargs++] = "-I";
19605c51f124SMoriah Waterland 	}
19615c51f124SMoriah Waterland 
19625c51f124SMoriah Waterland 	/* pkgadd -M: pass -M to pkgadd in zone: dont mount client file sys */
19635c51f124SMoriah Waterland 
19645c51f124SMoriah Waterland 	arg[nargs++] = "-M";
19655c51f124SMoriah Waterland 
19665c51f124SMoriah Waterland 	/* pkgadd -v: pass -v to pkgadd in zone: trace scripts */
19675c51f124SMoriah Waterland 
19685c51f124SMoriah Waterland 	if (pkgverbose) {
19695c51f124SMoriah Waterland 		arg[nargs++] = "-v";
19705c51f124SMoriah Waterland 	}
19715c51f124SMoriah Waterland 
19725c51f124SMoriah Waterland 	/* pkgadd -z: pass -z to pkgadd in zone fresh inst from pkg save area */
19735c51f124SMoriah Waterland 
19745c51f124SMoriah Waterland 	if (saveSpoolInstall) {
19755c51f124SMoriah Waterland 		arg[nargs++] = "-z";
19765c51f124SMoriah Waterland 	}
19775c51f124SMoriah Waterland 
19785c51f124SMoriah Waterland 	/* pass "-O enable-hollow-package-support" */
19795c51f124SMoriah Waterland 
19805c51f124SMoriah Waterland 	if (is_depend_pkginfo_DB()) {
19815c51f124SMoriah Waterland 		arg[nargs++] = "-O";
19825c51f124SMoriah Waterland 		arg[nargs++] = "enable-hollow-package-support";
19835c51f124SMoriah Waterland 	}
19845c51f124SMoriah Waterland 
19855c51f124SMoriah Waterland 	/* pkgadd -t pass -t to pkgadd in zone disable save spool area create */
19865c51f124SMoriah Waterland 
19875c51f124SMoriah Waterland 	if (disableSaveSpool) {
19885c51f124SMoriah Waterland 		arg[nargs++] = "-t";
19895c51f124SMoriah Waterland 	}
19905c51f124SMoriah Waterland 
19915c51f124SMoriah Waterland 	/* if running pkgask, pass -i to pkgadd in zone: running pkgask */
19925c51f124SMoriah Waterland 
19935c51f124SMoriah Waterland 	if (askflag) {
19945c51f124SMoriah Waterland 		echo(MSG_BYPASSING_ZONE, a_zoneName);
19955c51f124SMoriah Waterland 		return (0);
19965c51f124SMoriah Waterland 	}
19975c51f124SMoriah Waterland 
19985c51f124SMoriah Waterland 	/*
19995c51f124SMoriah Waterland 	 * pkgadd -n (not pkgask): pass -n to pkginstall: noninteractive mode
20005c51f124SMoriah Waterland 	 */
20015c51f124SMoriah Waterland 	if (nointeract && !askflag) {
20025c51f124SMoriah Waterland 		arg[nargs++] = "-n";
20035c51f124SMoriah Waterland 	}
20045c51f124SMoriah Waterland 
20055c51f124SMoriah Waterland 	/* pkgadd -a admin: pass -a admin to pkginstall in zone: admin file */
20065c51f124SMoriah Waterland 
20075c51f124SMoriah Waterland 	if (a_adminFile) {
20085c51f124SMoriah Waterland 		int fd;
20095c51f124SMoriah Waterland 		fd = openLocal(a_adminFile, O_RDONLY, tmpdir);
20105c51f124SMoriah Waterland 		if (fd < 0) {
20115c51f124SMoriah Waterland 			progerr(ERR_CANNOT_COPY_LOCAL, a_adminFile,
20125c51f124SMoriah Waterland 				errno, strerror(errno));
20135c51f124SMoriah Waterland 			return (1);
20145c51f124SMoriah Waterland 		}
20155c51f124SMoriah Waterland 		(void) snprintf(adminfd_path, sizeof (adminfd_path),
20165c51f124SMoriah Waterland 			"/proc/self/fd/%d", fd);
20175c51f124SMoriah Waterland 		fds[maxfds++] = fd;
20185c51f124SMoriah Waterland 		arg[nargs++] = "-a";
20195c51f124SMoriah Waterland 		arg[nargs++] = adminfd_path;
20205c51f124SMoriah Waterland 	}
20215c51f124SMoriah Waterland 
20225c51f124SMoriah Waterland 	/* pkgadd -R root: pass -R /a to pkginstall when zone is mounted */
20235c51f124SMoriah Waterland 	if (a_zoneState == ZONE_STATE_MOUNTED) {
20245c51f124SMoriah Waterland 		arg[nargs++] = "-R";
20255c51f124SMoriah Waterland 		arg[nargs++] = "/a";
20265c51f124SMoriah Waterland 	}
20275c51f124SMoriah Waterland 
20285c51f124SMoriah Waterland 	/*
20295c51f124SMoriah Waterland 	 * pkgadd -D arg: pass -D dryrun to pkginstall in zone: dryrun
20305c51f124SMoriah Waterland 	 * mode/file
20315c51f124SMoriah Waterland 	 */
20325c51f124SMoriah Waterland 	if (pkgdrtarg) {
20335c51f124SMoriah Waterland 		arg[nargs++] = "-D";
20345c51f124SMoriah Waterland 		arg[nargs++] = pkgdrtarg;
20355c51f124SMoriah Waterland 	}
20365c51f124SMoriah Waterland 
20375c51f124SMoriah Waterland 	/*
20385c51f124SMoriah Waterland 	 * pkgadd -c cont: pass -c cont to pkginstall in zone: continuation
20395c51f124SMoriah Waterland 	 * file
20405c51f124SMoriah Waterland 	 */
20415c51f124SMoriah Waterland 	if (pkgcontsrc) {
20425c51f124SMoriah Waterland 		arg[nargs++] = "-c";
20435c51f124SMoriah Waterland 		arg[nargs++] = pkgcontsrc;
20445c51f124SMoriah Waterland 	}
20455c51f124SMoriah Waterland 
20465c51f124SMoriah Waterland 	/* pkgadd -r resp: pass -r resp to pkginstall in zone: response file */
20475c51f124SMoriah Waterland 
20485c51f124SMoriah Waterland 	if (respfile) {
20495c51f124SMoriah Waterland 		int fd;
20505c51f124SMoriah Waterland 		fd = openLocal(respfile, O_RDONLY, tmpdir);
20515c51f124SMoriah Waterland 		if (fd < 0) {
20525c51f124SMoriah Waterland 			progerr(ERR_CANNOT_COPY_LOCAL, a_adminFile,
20535c51f124SMoriah Waterland 				errno, strerror(errno));
20545c51f124SMoriah Waterland 			return (1);
20555c51f124SMoriah Waterland 		}
20565c51f124SMoriah Waterland 		(void) snprintf(respfilefd_path,
20575c51f124SMoriah Waterland 			sizeof (respfilefd_path),
20585c51f124SMoriah Waterland 			"/proc/self/fd/%d", fd);
20595c51f124SMoriah Waterland 		fds[maxfds++] = fd;
20605c51f124SMoriah Waterland 		arg[nargs++] = "-r";
20615c51f124SMoriah Waterland 		arg[nargs++] = respfilefd_path;
20625c51f124SMoriah Waterland 	}
20635c51f124SMoriah Waterland 
20645c51f124SMoriah Waterland 	/* add "-O addzonename" */
20655c51f124SMoriah Waterland 
20665c51f124SMoriah Waterland 	arg[nargs++] = "-O";
20675c51f124SMoriah Waterland 	arg[nargs++] = "addzonename";
20685c51f124SMoriah Waterland 
20695c51f124SMoriah Waterland 	if (isPatchUpdate()) {
20705c51f124SMoriah Waterland 		if (patchPkgRemoval == B_TRUE) {
20715c51f124SMoriah Waterland 			arg[nargs++] = "-O";
20725c51f124SMoriah Waterland 			arg[nargs++] = "patchPkgRemoval";
20735c51f124SMoriah Waterland 		} else {
20745c51f124SMoriah Waterland 			arg[nargs++] = "-O";
20755c51f124SMoriah Waterland 			arg[nargs++] = "patchPkgInstall";
20765c51f124SMoriah Waterland 		}
20775c51f124SMoriah Waterland 	}
20785c51f124SMoriah Waterland 
20795c51f124SMoriah Waterland 	/* add all inherited file systems */
20805c51f124SMoriah Waterland 
20815c51f124SMoriah Waterland 	if (a_inheritedPkgDirs != (char **)NULL) {
20825c51f124SMoriah Waterland 		for (n = 0; a_inheritedPkgDirs[n] != (char *)NULL; n++) {
20835c51f124SMoriah Waterland 			char	ifs[MAXPATHLEN+22];
20845c51f124SMoriah Waterland 			(void) snprintf(ifs, sizeof (ifs),
20855c51f124SMoriah Waterland 				"inherited-filesystem=%s",
20865c51f124SMoriah Waterland 				a_inheritedPkgDirs[n]);
20875c51f124SMoriah Waterland 			arg[nargs++] = "-O";
20885c51f124SMoriah Waterland 			arg[nargs++] = strdup(ifs);
20895c51f124SMoriah Waterland 		}
20905c51f124SMoriah Waterland 	}
20915c51f124SMoriah Waterland 
20925c51f124SMoriah Waterland 	/*
20935c51f124SMoriah Waterland 	 * add parent zone info/type
20945c51f124SMoriah Waterland 	 */
20955c51f124SMoriah Waterland 
20965c51f124SMoriah Waterland 	p = z_get_zonename();
20975c51f124SMoriah Waterland 	if ((p != NULL) && (*p != '\0')) {
20985c51f124SMoriah Waterland 			char	zn[MAXPATHLEN];
20995c51f124SMoriah Waterland 			(void) snprintf(zn, sizeof (zn),
21005c51f124SMoriah Waterland 				"parent-zone-name=%s", p);
21015c51f124SMoriah Waterland 			arg[nargs++] = "-O";
21025c51f124SMoriah Waterland 			arg[nargs++] = strdup(zn);
21035c51f124SMoriah Waterland 	}
21045c51f124SMoriah Waterland 
21055c51f124SMoriah Waterland 	/* current zone type */
21065c51f124SMoriah Waterland 
21075c51f124SMoriah Waterland 	arg[nargs++] = "-O";
21085c51f124SMoriah Waterland 	if (z_running_in_global_zone() == B_TRUE) {
21095c51f124SMoriah Waterland 			char	zn[MAXPATHLEN];
21105c51f124SMoriah Waterland 			(void) snprintf(zn, sizeof (zn),
21115c51f124SMoriah Waterland 				"parent-zone-type=%s",
21125c51f124SMoriah Waterland 				TAG_VALUE_GLOBAL_ZONE);
21135c51f124SMoriah Waterland 			arg[nargs++] = strdup(zn);
21145c51f124SMoriah Waterland 	} else {
21155c51f124SMoriah Waterland 			char	zn[MAXPATHLEN];
21165c51f124SMoriah Waterland 			(void) snprintf(zn, sizeof (zn),
21175c51f124SMoriah Waterland 				"parent-zone-type=%s",
21185c51f124SMoriah Waterland 				TAG_VALUE_NONGLOBAL_ZONE);
21195c51f124SMoriah Waterland 			arg[nargs++] = strdup(zn);
21205c51f124SMoriah Waterland 	}
21215c51f124SMoriah Waterland 
2122*62224350SCasper H.S. Dik 	/* Add the pkgserv options */
2123*62224350SCasper H.S. Dik 	arg[nargs++] = "-O";
2124*62224350SCasper H.S. Dik 	arg[nargs++] = pkgmodeargument(a_tmpzn ? RUN_ONCE : pkgservergetmode());
2125*62224350SCasper H.S. Dik 
21265c51f124SMoriah Waterland 	/* add in the package stream file */
21275c51f124SMoriah Waterland 
21285c51f124SMoriah Waterland 	if (a_idsName != NULL) {
21295c51f124SMoriah Waterland 		int fd;
21305c51f124SMoriah Waterland 		fd = openLocal(a_idsName, O_RDONLY, tmpdir);
21315c51f124SMoriah Waterland 		if (fd < 0) {
21325c51f124SMoriah Waterland 			progerr(ERR_STREAM_UNAVAILABLE, a_idsName,
21335c51f124SMoriah Waterland 				pkginst, strerror(errno));
21345c51f124SMoriah Waterland 			quit(1);
21355c51f124SMoriah Waterland 		}
21365c51f124SMoriah Waterland 		(void) snprintf(pkgstreamfd_path, sizeof (pkgstreamfd_path),
21375c51f124SMoriah Waterland 			"/proc/self/fd/%d", fd);
21385c51f124SMoriah Waterland 		fds[maxfds++] = fd;
21395c51f124SMoriah Waterland 		arg[nargs++] = pkgstreamfd_path;
21405c51f124SMoriah Waterland 	} else {
21415c51f124SMoriah Waterland 		progerr(ERR_PKGZONEINSTALL_NO_STREAM);
21425c51f124SMoriah Waterland 		quit(1);
21435c51f124SMoriah Waterland 	}
21445c51f124SMoriah Waterland 
21455c51f124SMoriah Waterland 	/* add package instance name */
21465c51f124SMoriah Waterland 
21475c51f124SMoriah Waterland 	arg[nargs++] = pkginst;
21485c51f124SMoriah Waterland 
21495c51f124SMoriah Waterland 	/* terminate the argument list */
21505c51f124SMoriah Waterland 
21515c51f124SMoriah Waterland 	arg[nargs++] = NULL;
21525c51f124SMoriah Waterland 
21535c51f124SMoriah Waterland 	/*
21545c51f124SMoriah Waterland 	 * run the appropriate pkginstall command in the specified zone
21555c51f124SMoriah Waterland 	 */
21565c51f124SMoriah Waterland 
21575c51f124SMoriah Waterland 	if (debugFlag == B_TRUE) {
21585c51f124SMoriah Waterland 		echoDebug(DBG_ZONE_EXEC_ENTER, a_zoneName, arg[0]);
21595c51f124SMoriah Waterland 		for (n = 0; arg[n]; n++) {
21605c51f124SMoriah Waterland 			echoDebug(DBG_ARG, n, arg[n]);
21615c51f124SMoriah Waterland 		}
21625c51f124SMoriah Waterland 	}
21635c51f124SMoriah Waterland 
21645c51f124SMoriah Waterland 	/* terminate file descriptor list */
21655c51f124SMoriah Waterland 
21665c51f124SMoriah Waterland 	fds[maxfds] = -1;
21675c51f124SMoriah Waterland 
21685c51f124SMoriah Waterland 	/* exec command in zone */
21695c51f124SMoriah Waterland 
21705c51f124SMoriah Waterland 	n = z_zone_exec(a_zoneName, path, arg, (char *)NULL, (char *)NULL, fds);
21715c51f124SMoriah Waterland 
21725c51f124SMoriah Waterland 	echoDebug(DBG_ZONE_EXEC_EXIT, a_zoneName, arg[0], n, "");
21735c51f124SMoriah Waterland 
21745c51f124SMoriah Waterland 	/*
21755c51f124SMoriah Waterland 	 * close any files that were opened for use by the
21765c51f124SMoriah Waterland 	 * /proc/self/fd interface so they could be passed to programs
21775c51f124SMoriah Waterland 	 * via the z_zone_exec() interface
21785c51f124SMoriah Waterland 	 */
21795c51f124SMoriah Waterland 
21805c51f124SMoriah Waterland 	for (; maxfds > 0; maxfds--) {
21815c51f124SMoriah Waterland 		(void) close(fds[maxfds-1]);
21825c51f124SMoriah Waterland 	}
21835c51f124SMoriah Waterland 
21845c51f124SMoriah Waterland 	/* return results of pkginstall in zone execution */
21855c51f124SMoriah Waterland 
21865c51f124SMoriah Waterland 	return (n);
21875c51f124SMoriah Waterland }
21885c51f124SMoriah Waterland 
21895c51f124SMoriah Waterland /*
21905c51f124SMoriah Waterland  * Name:	pkgInstall
21915c51f124SMoriah Waterland  * Description:	Invoke pkginstall in the current zone to perform an install
21925c51f124SMoriah Waterland  *		of a single package to the current zone or standalone system
21935c51f124SMoriah Waterland  * Arguments:	a_altRoot - pointer to string representing the alternative
21945c51f124SMoriah Waterland  *			root to use for the install
21955c51f124SMoriah Waterland  *		a_idsName - pointer to string representing the data stream
21965c51f124SMoriah Waterland  *			device (input data stream) containing the package to
21975c51f124SMoriah Waterland  *			be installed.
21985c51f124SMoriah Waterland  *		a_pkgDir - pointer to string representing the path to the
21995c51f124SMoriah Waterland  *			directory containing the package
22005c51f124SMoriah Waterland  *		a_altBinDir - pointer to string representing location of the
22015c51f124SMoriah Waterland  *			pkginstall executable to run. If not NULL, then pass
22025c51f124SMoriah Waterland  *			the path specified to the -b option to pkginstall.
22035c51f124SMoriah Waterland  *		a_inheritedPkgDirs - pointer to array of strings, each one
22045c51f124SMoriah Waterland  *			representing the non-global zones full path of a
22055c51f124SMoriah Waterland  *			directory that is inherited from the global zone.
22065c51f124SMoriah Waterland  * Returns:	int	(see ckreturn() function for details)
22075c51f124SMoriah Waterland  *		0 - success
22085c51f124SMoriah Waterland  *		1 - package operation failed (fatal error)
22095c51f124SMoriah Waterland  *		2 - non-fatal error (warning)
22105c51f124SMoriah Waterland  *		3 - user selected quit (operation interrupted)
22115c51f124SMoriah Waterland  *		4 - admin settings prevented operation
22125c51f124SMoriah Waterland  *		5 - interaction required and -n (non-interactive) specified
22135c51f124SMoriah Waterland  *		"10" will be added to indicate "immediate reboot required"
22145c51f124SMoriah Waterland  *		"20" will be added to indicate "reboot after install required"
22155c51f124SMoriah Waterland  * NOTE:	Both a_idsName and a_pkgDir are used to determine where the
22165c51f124SMoriah Waterland  *		package to be installed is located. If a_idsName is != NULL
22175c51f124SMoriah Waterland  *		then it must be the path to a device containing a package
22185c51f124SMoriah Waterland  *		stream that contains the package to be installed. If a_idsName
22195c51f124SMoriah Waterland  *		is == NULL then a_pkgDir must contain a full path to a directory
22205c51f124SMoriah Waterland  *		that contains the package to be installed.
22215c51f124SMoriah Waterland  */
22225c51f124SMoriah Waterland 
22235c51f124SMoriah Waterland static int
22245c51f124SMoriah Waterland pkgInstall(char *a_altRoot, char *a_idsName, char *a_pkgDir, char *a_altBinDir,
22255c51f124SMoriah Waterland 	char **a_inheritedPkgDirs)
22265c51f124SMoriah Waterland {
22275c51f124SMoriah Waterland 	char	*arg[MAXARGS];
22285c51f124SMoriah Waterland 	char	*p;
22295c51f124SMoriah Waterland 	char	path[PATH_MAX];
22305c51f124SMoriah Waterland 	char	buffer[256];
22315c51f124SMoriah Waterland 	int	n, nargs;
22325c51f124SMoriah Waterland 
22335c51f124SMoriah Waterland 	/* entry debugging info */
22345c51f124SMoriah Waterland 
22355c51f124SMoriah Waterland 	echoDebug(DBG_PKGINSTALL_ENTRY);
22365c51f124SMoriah Waterland 	echoDebug(DBG_PKGINSTALL_ARGS, PSTR(pkginst), PSTR(pkgdev.dirname),
22375c51f124SMoriah Waterland 		PSTR(pkgdev.mount), PSTR(pkgdev.bdevice), PSTR(a_altRoot),
22385c51f124SMoriah Waterland 		PSTR(a_idsName), PSTR(a_pkgDir));
22395c51f124SMoriah Waterland 
22405c51f124SMoriah Waterland 	/* generate full path to 'pkginstall' to run in zone */
22415c51f124SMoriah Waterland 
22425c51f124SMoriah Waterland 	(void) snprintf(path, sizeof (path), "%s/pkginstall",
22435c51f124SMoriah Waterland 		a_altBinDir == (char *)NULL ? PKGBIN : a_altBinDir);
22445c51f124SMoriah Waterland 	/*
22455c51f124SMoriah Waterland 	 * generate argument list for call to pkginstall
22465c51f124SMoriah Waterland 	 */
22475c51f124SMoriah Waterland 
22485c51f124SMoriah Waterland 	/* start at argument 0 */
22495c51f124SMoriah Waterland 
22505c51f124SMoriah Waterland 	nargs = 0;
22515c51f124SMoriah Waterland 
22525c51f124SMoriah Waterland 	/* first argument is path to executable */
22535c51f124SMoriah Waterland 
22545c51f124SMoriah Waterland 	arg[nargs++] = path;
22555c51f124SMoriah Waterland 
22565c51f124SMoriah Waterland 	/*
22575c51f124SMoriah Waterland 	 * second argument is always: pass -O debug to pkginstall: debug mode
22585c51f124SMoriah Waterland 	 */
22595c51f124SMoriah Waterland 	if (debugFlag == B_TRUE) {
22605c51f124SMoriah Waterland 		arg[nargs++] = "-O";
22615c51f124SMoriah Waterland 		arg[nargs++] = "debug";
22625c51f124SMoriah Waterland 	}
22635c51f124SMoriah Waterland 
22645c51f124SMoriah Waterland 	/* Installation is from a patch package. */
22655c51f124SMoriah Waterland 
22665c51f124SMoriah Waterland 	if (isPatchUpdate()) {
22675c51f124SMoriah Waterland 		if (patchPkgRemoval == B_TRUE) {
22685c51f124SMoriah Waterland 			arg[nargs++] = "-O";
22695c51f124SMoriah Waterland 			arg[nargs++] = "patchPkgRemoval";
22705c51f124SMoriah Waterland 		} else {
22715c51f124SMoriah Waterland 			arg[nargs++] = "-O";
22725c51f124SMoriah Waterland 			arg[nargs++] = "patchPkgInstall";
22735c51f124SMoriah Waterland 		}
22745c51f124SMoriah Waterland 	}
22755c51f124SMoriah Waterland 
2276*62224350SCasper H.S. Dik 	arg[nargs++] = "-O";
2277*62224350SCasper H.S. Dik 	arg[nargs++] = pkgmodeargument(pkgservergetmode());
2278*62224350SCasper H.S. Dik 
22795c51f124SMoriah Waterland 	/*
22805c51f124SMoriah Waterland 	 * pkgadd -G: pass -G to pkginstall if:
22815c51f124SMoriah Waterland 	 *  - the -G option is specified on the pkgadd command line
22825c51f124SMoriah Waterland 	 *  - this package is marked 'this zone only':
22835c51f124SMoriah Waterland 	 *  -- package has SUNW_PKG_THISZONE=true, or
22845c51f124SMoriah Waterland 	 *  -- package has a request script
22855c51f124SMoriah Waterland 	 * Setting -G for pkginstall causes pkginstall to install the package
22865c51f124SMoriah Waterland 	 * in the target zone. If running in the global zone, will install the
22875c51f124SMoriah Waterland 	 * package and mark the package as installed "in the global zone only".
22885c51f124SMoriah Waterland 	 * If running in a non-global zone, will just install the package.
22895c51f124SMoriah Waterland 	 */
22905c51f124SMoriah Waterland 
22915c51f124SMoriah Waterland 	if (globalZoneOnly == B_TRUE) {
22925c51f124SMoriah Waterland 		arg[nargs++] = "-G";
22935c51f124SMoriah Waterland 	} else if (pkgPackageIsThisZone(pkginst) == B_TRUE) {
22945c51f124SMoriah Waterland 		arg[nargs++] = "-G";
22955c51f124SMoriah Waterland 	}
22965c51f124SMoriah Waterland 
22975c51f124SMoriah Waterland 	/* pkgadd -b dir: pass -b to pkginstall */
22985c51f124SMoriah Waterland 
22995c51f124SMoriah Waterland 	if (a_altBinDir != (char *)NULL) {
23005c51f124SMoriah Waterland 		arg[nargs++] = "-b";
23015c51f124SMoriah Waterland 		arg[nargs++] = a_altBinDir;
23025c51f124SMoriah Waterland 	}
23035c51f124SMoriah Waterland 
23045c51f124SMoriah Waterland 	/* pkgadd -B blocksize: pass -B to pkginstall */
23055c51f124SMoriah Waterland 
23065c51f124SMoriah Waterland 	if (rw_block_size != NULL) {
23075c51f124SMoriah Waterland 		arg[nargs++] = "-B";
23085c51f124SMoriah Waterland 		arg[nargs++] = rw_block_size;
23095c51f124SMoriah Waterland 	}
23105c51f124SMoriah Waterland 
23115c51f124SMoriah Waterland 	/* pkgadd -C: pass -C to pkginstall: disable checksum */
23125c51f124SMoriah Waterland 
23135c51f124SMoriah Waterland 	if (disableChecksum) {
23145c51f124SMoriah Waterland 		arg[nargs++] = "-C";
23155c51f124SMoriah Waterland 	}
23165c51f124SMoriah Waterland 
23175c51f124SMoriah Waterland 	/* pkgadd -A: pass -A to pkginstall: disable attribute checking */
23185c51f124SMoriah Waterland 
23195c51f124SMoriah Waterland 	if (disableAttributes) {
23205c51f124SMoriah Waterland 		arg[nargs++] = "-A";
23215c51f124SMoriah Waterland 	}
23225c51f124SMoriah Waterland 
23235c51f124SMoriah Waterland 	/*
23245c51f124SMoriah Waterland 	 * NONABI_SCRIPTS defined: pass -o to pkginstall; refers to a
23255c51f124SMoriah Waterland 	 * pkg requiring operator interaction during a procedure script
23265c51f124SMoriah Waterland 	 * (common before on1093)
23275c51f124SMoriah Waterland 	 */
23285c51f124SMoriah Waterland 
23295c51f124SMoriah Waterland 	if (old_pkg) {
23305c51f124SMoriah Waterland 		arg[nargs++] = "-o";
23315c51f124SMoriah Waterland 	}
23325c51f124SMoriah Waterland 
23335c51f124SMoriah Waterland 	/*
23345c51f124SMoriah Waterland 	 * PKG_NONABI_SYMLINKS defined: pass -y to pkginstall; process
23355c51f124SMoriah Waterland 	 * symlinks consistent with old behavior
23365c51f124SMoriah Waterland 	 */
23375c51f124SMoriah Waterland 
23385c51f124SMoriah Waterland 	if (old_symlinks) {
23395c51f124SMoriah Waterland 		arg[nargs++] = "-y";
23405c51f124SMoriah Waterland 	}
23415c51f124SMoriah Waterland 
23425c51f124SMoriah Waterland 	/*
23435c51f124SMoriah Waterland 	 * PKG_ABI_NAMELENGTH defined: pass -e to pkginstall; causes
23445c51f124SMoriah Waterland 	 * package name length to be restricted
23455c51f124SMoriah Waterland 	 */
23465c51f124SMoriah Waterland 
23475c51f124SMoriah Waterland 	if (ABI_namelength) {
23485c51f124SMoriah Waterland 		arg[nargs++] = "-e";
23495c51f124SMoriah Waterland 	}
23505c51f124SMoriah Waterland 
23515c51f124SMoriah Waterland 	/* pkgadd -S: pass -S to pkginstall: suppress copyright notices */
23525c51f124SMoriah Waterland 
23535c51f124SMoriah Waterland 	if (suppressCopyright) {
23545c51f124SMoriah Waterland 		arg[nargs++] = "-S";
23555c51f124SMoriah Waterland 	}
23565c51f124SMoriah Waterland 
23575c51f124SMoriah Waterland 	/* pkgadd -I: pass -I to pkginstall: initial install being performed */
23585c51f124SMoriah Waterland 
23595c51f124SMoriah Waterland 	if (init_install) {
23605c51f124SMoriah Waterland 		arg[nargs++] = "-I";
23615c51f124SMoriah Waterland 	}
23625c51f124SMoriah Waterland 
23635c51f124SMoriah Waterland 	/* pkgadd -M: pass -M to pkginstall: dont mount client file systems */
23645c51f124SMoriah Waterland 
23655c51f124SMoriah Waterland 	if (no_map_client) {
23665c51f124SMoriah Waterland 		arg[nargs++] = "-M";
23675c51f124SMoriah Waterland 	}
23685c51f124SMoriah Waterland 
23695c51f124SMoriah Waterland 	/* pkgadd -v: pass -v to pkginstall: trace scripts */
23705c51f124SMoriah Waterland 
23715c51f124SMoriah Waterland 	if (pkgverbose) {
23725c51f124SMoriah Waterland 		arg[nargs++] = "-v";
23735c51f124SMoriah Waterland 	}
23745c51f124SMoriah Waterland 
23755c51f124SMoriah Waterland 	/* pkgadd -z: pass -z to pkginstall: fresh install from pkg save area */
23765c51f124SMoriah Waterland 
23775c51f124SMoriah Waterland 	if (saveSpoolInstall) {
23785c51f124SMoriah Waterland 		arg[nargs++] = "-z";
23795c51f124SMoriah Waterland 	}
23805c51f124SMoriah Waterland 
23815c51f124SMoriah Waterland 	/*
23825c51f124SMoriah Waterland 	 * if running in a non-global zone and the 'hollow' attribute is
23835c51f124SMoriah Waterland 	 * passed in, then pass -h to pkginstall so that it knows how to
23845c51f124SMoriah Waterland 	 * handle hollow packages for this local zone.
23855c51f124SMoriah Waterland 	 */
23865c51f124SMoriah Waterland 
23875c51f124SMoriah Waterland 	if (!z_running_in_global_zone() && is_depend_pkginfo_DB()) {
23885c51f124SMoriah Waterland 		arg[nargs++] = "-h";
23895c51f124SMoriah Waterland 	}
23905c51f124SMoriah Waterland 
23915c51f124SMoriah Waterland 	/* pkgadd -t: pass -t to pkginstall: disable save spool area creation */
23925c51f124SMoriah Waterland 
23935c51f124SMoriah Waterland 	if (disableSaveSpool) {
23945c51f124SMoriah Waterland 		arg[nargs++] = "-t";
23955c51f124SMoriah Waterland 	}
23965c51f124SMoriah Waterland 
23975c51f124SMoriah Waterland 	/* if running pkgask, pass -i to pkginstall: running pkgask */
23985c51f124SMoriah Waterland 
23995c51f124SMoriah Waterland 	if (askflag) {
24005c51f124SMoriah Waterland 		arg[nargs++] = "-i";
24015c51f124SMoriah Waterland 	}
24025c51f124SMoriah Waterland 
24035c51f124SMoriah Waterland 	/* pkgadd -n (not pkgask): pass -n to pkginstall: noninteractive mode */
24045c51f124SMoriah Waterland 
24055c51f124SMoriah Waterland 	if (nointeract && !askflag) {
24065c51f124SMoriah Waterland 		arg[nargs++] = "-n";
24075c51f124SMoriah Waterland 	}
24085c51f124SMoriah Waterland 
24095c51f124SMoriah Waterland 	/* pkgadd -a admin: pass -a admin to pkginstall: admin file */
24105c51f124SMoriah Waterland 
24115c51f124SMoriah Waterland 	if (admnfile) {
24125c51f124SMoriah Waterland 		arg[nargs++] = "-a";
24135c51f124SMoriah Waterland 		arg[nargs++] = admnfile;
24145c51f124SMoriah Waterland 	}
24155c51f124SMoriah Waterland 
24165c51f124SMoriah Waterland 	/* pkgadd -D dryrun: pass -D dryrun to pkginstall: dryrun mode/file */
24175c51f124SMoriah Waterland 
24185c51f124SMoriah Waterland 	if (pkgdrtarg) {
24195c51f124SMoriah Waterland 		arg[nargs++] = "-D";
24205c51f124SMoriah Waterland 		arg[nargs++] = pkgdrtarg;
24215c51f124SMoriah Waterland 	}
24225c51f124SMoriah Waterland 
24235c51f124SMoriah Waterland 	/* pkgadd -c cont: pass -c cont to pkginstall: continuation file */
24245c51f124SMoriah Waterland 
24255c51f124SMoriah Waterland 	if (pkgcontsrc) {
24265c51f124SMoriah Waterland 		arg[nargs++] = "-c";
24275c51f124SMoriah Waterland 		arg[nargs++] = pkgcontsrc;
24285c51f124SMoriah Waterland 	}
24295c51f124SMoriah Waterland 
24305c51f124SMoriah Waterland 	/* pkgadd -V vfstab: pass -V vfstab to pkginstall: alternate vfstab */
24315c51f124SMoriah Waterland 
24325c51f124SMoriah Waterland 	if (vfstab_file) {
24335c51f124SMoriah Waterland 		arg[nargs++] = "-V";
24345c51f124SMoriah Waterland 		arg[nargs++] = vfstab_file;
24355c51f124SMoriah Waterland 	}
24365c51f124SMoriah Waterland 
24375c51f124SMoriah Waterland 	/* pkgadd -r resp: pass -r resp to pkginstall: response file */
24385c51f124SMoriah Waterland 
24395c51f124SMoriah Waterland 	if (respfile) {
24405c51f124SMoriah Waterland 		arg[nargs++] = "-r";
24415c51f124SMoriah Waterland 		arg[nargs++] = respfile;
24425c51f124SMoriah Waterland 	}
24435c51f124SMoriah Waterland 
24445c51f124SMoriah Waterland 	/* pkgadd -R root: pass -R root to pkginstall: alternative root */
24455c51f124SMoriah Waterland 
24465c51f124SMoriah Waterland 	if (a_altRoot && *a_altRoot) {
24475c51f124SMoriah Waterland 		arg[nargs++] = "-R";
24485c51f124SMoriah Waterland 		arg[nargs++] = a_altRoot;
24495c51f124SMoriah Waterland 	}
24505c51f124SMoriah Waterland 
24515c51f124SMoriah Waterland 	/*
24525c51f124SMoriah Waterland 	 * If input data stream is available,
24535c51f124SMoriah Waterland 	 * - add: -d ids_name -p number_of_parts
24545c51f124SMoriah Waterland 	 * else,
24555c51f124SMoriah Waterland 	 * - add: -d device -m mount [-f type]
24565c51f124SMoriah Waterland 	 */
24575c51f124SMoriah Waterland 
24585c51f124SMoriah Waterland 	if (a_idsName != NULL) {
24595c51f124SMoriah Waterland 		arg[nargs++] = "-d";
24605c51f124SMoriah Waterland 		arg[nargs++] = a_idsName;
24615c51f124SMoriah Waterland 		arg[nargs++] = "-p";
24625c51f124SMoriah Waterland 		ds_close(1);
24635c51f124SMoriah Waterland 		ds_putinfo(buffer);
24645c51f124SMoriah Waterland 		arg[nargs++] = buffer;
24655c51f124SMoriah Waterland 	} else if (pkgdev.mount != NULL) {
24665c51f124SMoriah Waterland 		arg[nargs++] = "-d";
24675c51f124SMoriah Waterland 		arg[nargs++] = pkgdev.bdevice;
24685c51f124SMoriah Waterland 		arg[nargs++] = "-m";
24695c51f124SMoriah Waterland 		arg[nargs++] = pkgdev.mount;
24705c51f124SMoriah Waterland 		if (pkgdev.fstyp != NULL) {
24715c51f124SMoriah Waterland 			arg[nargs++] = "-f";
24725c51f124SMoriah Waterland 			arg[nargs++] = pkgdev.fstyp;
24735c51f124SMoriah Waterland 		}
24745c51f124SMoriah Waterland 	}
24755c51f124SMoriah Waterland 
24765c51f124SMoriah Waterland 	/* add all inherited file systems */
24775c51f124SMoriah Waterland 
24785c51f124SMoriah Waterland 	if (a_inheritedPkgDirs != (char **)NULL) {
24795c51f124SMoriah Waterland 		for (n = 0; a_inheritedPkgDirs[n] != (char *)NULL; n++) {
24805c51f124SMoriah Waterland 			char	ifs[MAXPATHLEN+22];
24815c51f124SMoriah Waterland 			(void) snprintf(ifs, sizeof (ifs),
24825c51f124SMoriah Waterland 				"inherited-filesystem=%s",
24835c51f124SMoriah Waterland 				a_inheritedPkgDirs[n]);
24845c51f124SMoriah Waterland 			arg[nargs++] = "-O";
24855c51f124SMoriah Waterland 			arg[nargs++] = strdup(ifs);
24865c51f124SMoriah Waterland 		}
24875c51f124SMoriah Waterland 	}
24885c51f124SMoriah Waterland 
24895c51f124SMoriah Waterland 	/*
24905c51f124SMoriah Waterland 	 * add parent zone info/type
24915c51f124SMoriah Waterland 	 */
24925c51f124SMoriah Waterland 
24935c51f124SMoriah Waterland 	p = z_get_zonename();
24945c51f124SMoriah Waterland 	if ((p != NULL) && (*p != '\0')) {
24955c51f124SMoriah Waterland 			char	zn[MAXPATHLEN];
24965c51f124SMoriah Waterland 			(void) snprintf(zn, sizeof (zn),
24975c51f124SMoriah Waterland 				"parent-zone-name=%s", p);
24985c51f124SMoriah Waterland 			arg[nargs++] = "-O";
24995c51f124SMoriah Waterland 			arg[nargs++] = strdup(zn);
25005c51f124SMoriah Waterland 	}
25015c51f124SMoriah Waterland 
25025c51f124SMoriah Waterland 	/* current zone type */
25035c51f124SMoriah Waterland 
25045c51f124SMoriah Waterland 	arg[nargs++] = "-O";
25055c51f124SMoriah Waterland 	if (z_running_in_global_zone() == B_TRUE) {
25065c51f124SMoriah Waterland 			char	zn[MAXPATHLEN];
25075c51f124SMoriah Waterland 			(void) snprintf(zn, sizeof (zn),
25085c51f124SMoriah Waterland 				"parent-zone-type=%s",
25095c51f124SMoriah Waterland 				TAG_VALUE_GLOBAL_ZONE);
25105c51f124SMoriah Waterland 			arg[nargs++] = strdup(zn);
25115c51f124SMoriah Waterland 	} else {
25125c51f124SMoriah Waterland 			char	zn[MAXPATHLEN];
25135c51f124SMoriah Waterland 			(void) snprintf(zn, sizeof (zn),
25145c51f124SMoriah Waterland 				"parent-zone-type=%s",
25155c51f124SMoriah Waterland 				TAG_VALUE_NONGLOBAL_ZONE);
25165c51f124SMoriah Waterland 			arg[nargs++] = strdup(zn);
25175c51f124SMoriah Waterland 	}
25185c51f124SMoriah Waterland 
25195c51f124SMoriah Waterland 	/* pass -N to pkginstall: program name to report */
25205c51f124SMoriah Waterland 
25215c51f124SMoriah Waterland 	arg[nargs++] = "-N";
25225c51f124SMoriah Waterland 	arg[nargs++] = get_prog_name();
25235c51f124SMoriah Waterland 
25245c51f124SMoriah Waterland 	/* add package directory name */
25255c51f124SMoriah Waterland 
25265c51f124SMoriah Waterland 	arg[nargs++] = a_pkgDir;
25275c51f124SMoriah Waterland 
25285c51f124SMoriah Waterland 	/* add package instance name */
25295c51f124SMoriah Waterland 
25305c51f124SMoriah Waterland 	arg[nargs++] = pkginst;
25315c51f124SMoriah Waterland 
25325c51f124SMoriah Waterland 	/* terminate the argument list */
25335c51f124SMoriah Waterland 
25345c51f124SMoriah Waterland 	arg[nargs++] = NULL;
25355c51f124SMoriah Waterland 
25365c51f124SMoriah Waterland 	/*
25375c51f124SMoriah Waterland 	 * run the appropriate pkginstall command in the specified zone
25385c51f124SMoriah Waterland 	 */
25395c51f124SMoriah Waterland 
25405c51f124SMoriah Waterland 	if (debugFlag == B_TRUE) {
25415c51f124SMoriah Waterland 		echoDebug(DBG_ZONE_EXEC_ENTER, "global", arg[0]);
25425c51f124SMoriah Waterland 		for (n = 0; arg[n]; n++) {
25435c51f124SMoriah Waterland 			echoDebug(DBG_ARG, n, arg[n]);
25445c51f124SMoriah Waterland 		}
25455c51f124SMoriah Waterland 	}
25465c51f124SMoriah Waterland 
25475c51f124SMoriah Waterland 	/* execute pkginstall command */
25485c51f124SMoriah Waterland 
25495c51f124SMoriah Waterland 	n = pkgexecv(NULL, NULL, NULL, NULL, arg);
25505c51f124SMoriah Waterland 
25515c51f124SMoriah Waterland 	/* return results of pkginstall execution */
25525c51f124SMoriah Waterland 
25535c51f124SMoriah Waterland 	return (n);
25545c51f124SMoriah Waterland }
25555c51f124SMoriah Waterland 
25565c51f124SMoriah Waterland /*
25575c51f124SMoriah Waterland  *  function to clear out any exisiting error return conditions that may have
25585c51f124SMoriah Waterland  *  been set by previous calls to ckreturn()
25595c51f124SMoriah Waterland  */
25605c51f124SMoriah Waterland static void
25615c51f124SMoriah Waterland resetreturn()
25625c51f124SMoriah Waterland {
25635c51f124SMoriah Waterland 	admnflag = 0;	/* != 0 if any pkg op admin setting failure (4) */
25645c51f124SMoriah Waterland 	doreboot = 0;	/* != 0 if reboot required after installation (>= 10) */
25655c51f124SMoriah Waterland 	failflag = 0;	/* != 0 if fatal error has occurred (1) */
25665c51f124SMoriah Waterland 	intrflag = 0;	/* != 0 if user selected quit (3) */
25675c51f124SMoriah Waterland 	ireboot = 0;	/* != 0 if immediate reboot required (>= 20) */
25685c51f124SMoriah Waterland 	nullflag = 0;	/* != 0 if admin interaction required (5) */
25695c51f124SMoriah Waterland 	warnflag = 0;	/* != 0 if non-fatal error has occurred (2) */
25705c51f124SMoriah Waterland 	interrupted = 0;	/* last pkg op was quit (1,2,3,4,5) */
25715c51f124SMoriah Waterland 	needconsult = 0;	/* essential ask admin now (1,2,3,5) */
25725c51f124SMoriah Waterland }
25735c51f124SMoriah Waterland 
25745c51f124SMoriah Waterland /*
25755c51f124SMoriah Waterland  *  function which checks the indicated return value
25765c51f124SMoriah Waterland  *  and indicates disposition of installation
25775c51f124SMoriah Waterland  */
25785c51f124SMoriah Waterland static void
25795c51f124SMoriah Waterland ckreturn(int retcode)
25805c51f124SMoriah Waterland {
25815c51f124SMoriah Waterland 	/*
25825c51f124SMoriah Waterland 	 * entry debugging info
25835c51f124SMoriah Waterland 	 */
25845c51f124SMoriah Waterland 
25855c51f124SMoriah Waterland 	echoDebug(DBG_PKGADD_CKRETURN, retcode, PSTR(pkginst));
25865c51f124SMoriah Waterland 
25875c51f124SMoriah Waterland 	/* reset needconsult so it only reflects this call to ckreturn */
25885c51f124SMoriah Waterland 	needconsult = 0;
25895c51f124SMoriah Waterland 
25905c51f124SMoriah Waterland 	switch (retcode) {
25915c51f124SMoriah Waterland 	    case  0:		/* successful */
25925c51f124SMoriah Waterland 	    case 10:
25935c51f124SMoriah Waterland 	    case 20:
25945c51f124SMoriah Waterland 		break; /* empty case */
25955c51f124SMoriah Waterland 
25965c51f124SMoriah Waterland 	    case  1:		/* package operation failed (fatal error) */
25975c51f124SMoriah Waterland 	    case 11:
25985c51f124SMoriah Waterland 	    case 21:
25995c51f124SMoriah Waterland 		failflag++;
26005c51f124SMoriah Waterland 		interrupted++;
26015c51f124SMoriah Waterland 		needconsult++;
26025c51f124SMoriah Waterland 		break;
26035c51f124SMoriah Waterland 
26045c51f124SMoriah Waterland 	    case  2:		/* non-fatal error (warning) */
26055c51f124SMoriah Waterland 	    case 12:
26065c51f124SMoriah Waterland 	    case 22:
26075c51f124SMoriah Waterland 		warnflag++;
26085c51f124SMoriah Waterland 		interrupted++;
26095c51f124SMoriah Waterland 		needconsult++;
26105c51f124SMoriah Waterland 		break;
26115c51f124SMoriah Waterland 
26125c51f124SMoriah Waterland 	    case  3:		/* user selected quit; operation interrupted */
26135c51f124SMoriah Waterland 	    case 13:
26145c51f124SMoriah Waterland 	    case 23:
26155c51f124SMoriah Waterland 		intrflag++;
26165c51f124SMoriah Waterland 		interrupted++;
26175c51f124SMoriah Waterland 		needconsult++;
26185c51f124SMoriah Waterland 		break;
26195c51f124SMoriah Waterland 
26205c51f124SMoriah Waterland 	    case  4:		/* admin settings prevented operation */
26215c51f124SMoriah Waterland 	    case 14:
26225c51f124SMoriah Waterland 	    case 24:
26235c51f124SMoriah Waterland 		admnflag++;
26245c51f124SMoriah Waterland 		interrupted++;
26255c51f124SMoriah Waterland 		break;
26265c51f124SMoriah Waterland 
26275c51f124SMoriah Waterland 	    case  5:		/* administration: interaction req (no -n) */
26285c51f124SMoriah Waterland 	    case 15:
26295c51f124SMoriah Waterland 	    case 25:
26305c51f124SMoriah Waterland 		nullflag++;
26315c51f124SMoriah Waterland 		interrupted++;
26325c51f124SMoriah Waterland 		needconsult++;
26335c51f124SMoriah Waterland 		break;
26345c51f124SMoriah Waterland 
26355c51f124SMoriah Waterland 	    default:
26365c51f124SMoriah Waterland 		failflag++;
26375c51f124SMoriah Waterland 		interrupted++;
26385c51f124SMoriah Waterland 		needconsult++;
26395c51f124SMoriah Waterland 		return;
26405c51f124SMoriah Waterland 	}
26415c51f124SMoriah Waterland 
26425c51f124SMoriah Waterland 	if (retcode >= 20) {
26435c51f124SMoriah Waterland 		ireboot++;
26445c51f124SMoriah Waterland 	} else if (retcode >= 10) {
26455c51f124SMoriah Waterland 		doreboot++;
26465c51f124SMoriah Waterland 	}
26475c51f124SMoriah Waterland }
26485c51f124SMoriah Waterland 
26495c51f124SMoriah Waterland static void
26505c51f124SMoriah Waterland usage(void)
26515c51f124SMoriah Waterland {
26525c51f124SMoriah Waterland 	char *prog = get_prog_name();
26535c51f124SMoriah Waterland 
26545c51f124SMoriah Waterland 	if (askflag) {
26555c51f124SMoriah Waterland 		(void) fprintf(stderr, ERR_USAGE_PKGASK, prog);
26565c51f124SMoriah Waterland 	} else if (z_running_in_global_zone() == B_FALSE) {
26575c51f124SMoriah Waterland 		(void) fprintf(stderr, ERR_USAGE_PKGADD_NONGLOBALZONE,
26585c51f124SMoriah Waterland 			prog, prog);
26595c51f124SMoriah Waterland 	} else {
26605c51f124SMoriah Waterland 		(void) fprintf(stderr, ERR_USAGE_PKGADD_GLOBALZONE,
26615c51f124SMoriah Waterland 			prog, prog);
26625c51f124SMoriah Waterland 	}
26635c51f124SMoriah Waterland }
26645c51f124SMoriah Waterland 
26655c51f124SMoriah Waterland /*
26665c51f124SMoriah Waterland  * Name:	check_applicability
26675c51f124SMoriah Waterland  * Description:	determine if a package is installable in this zone; that is,
26685c51f124SMoriah Waterland  *		does the scope of install conflict with existing installation
26695c51f124SMoriah Waterland  *		or can the package be installed
26705c51f124SMoriah Waterland  * Arguments:	a_packageDir - [RO, *RO] - (char *)
26715c51f124SMoriah Waterland  *			Pointer to string representing the directory where the
26725c51f124SMoriah Waterland  *			package is located
26735c51f124SMoriah Waterland  *		a_pkgInst - [RO, *RO] - (char *)
26745c51f124SMoriah Waterland  *			Pointer to string representing the name of the package
26755c51f124SMoriah Waterland  *			to check
26765c51f124SMoriah Waterland  *		a_rootPath - [RO, *RO] - (char *)
26775c51f124SMoriah Waterland  *			Pointer to string representing path to the root of the
26785c51f124SMoriah Waterland  *			file system where the package is to be installed - this
26795c51f124SMoriah Waterland  *			is usually the same as the "-R" argument to pkgadd
26805c51f124SMoriah Waterland  *		a_flags - [RO, *RO] - (CAF_T)
26815c51f124SMoriah Waterland  *			Flags set by the caller to indicate the conditions
26825c51f124SMoriah Waterland  *			under which the package is to be installed:
26835c51f124SMoriah Waterland  *				CAF_IN_GLOBAL_ZONE - in global zone
26845c51f124SMoriah Waterland  *				CAF_SCOPE_GLOBAL - -G specified
26855c51f124SMoriah Waterland  *				CAF_SCOPE_NONGLOBAL - -Z specified
26865c51f124SMoriah Waterland  * Returns:	boolean_t
26875c51f124SMoriah Waterland  *			B_TRUE - the package can be installed
26885c51f124SMoriah Waterland  *			B_FALSE - the package can not be installed
26895c51f124SMoriah Waterland  */
26905c51f124SMoriah Waterland 
26915c51f124SMoriah Waterland static boolean_t
26925c51f124SMoriah Waterland check_applicability(char *a_packageDir, char *a_pkgInst, char *a_rootPath,
26935c51f124SMoriah Waterland 	CAF_T a_flags)
26945c51f124SMoriah Waterland {
26955c51f124SMoriah Waterland 	FILE		*pkginfoFP;
26965c51f124SMoriah Waterland 	FILE		*pkgmapFP;
26975c51f124SMoriah Waterland 	boolean_t	all_zones;	/* pkg is "all zones" only */
26985c51f124SMoriah Waterland 	boolean_t	in_gz_only;	/* pkg installed in global zone only */
26995c51f124SMoriah Waterland 	boolean_t	is_hollow;	/* pkg is "hollow" */
27005c51f124SMoriah Waterland 	boolean_t	pkg_installed;	/* pkg is installed */
27015c51f124SMoriah Waterland 	boolean_t	this_zone;	/* pkg is "this zone" only */
27025c51f124SMoriah Waterland 	boolean_t	reqfile_found = B_FALSE;
27035c51f124SMoriah Waterland 	char		instPkg[PKGSIZ+1];	/* installed pkg instance nam */
27045c51f124SMoriah Waterland 	char		instPkgPath[PATH_MAX];	/* installed pkg toplevel dir */
27055c51f124SMoriah Waterland 	char		pkginfoPath[PATH_MAX];	/* pkg 2 install pkginfo file */
27065c51f124SMoriah Waterland 	char		pkgmapPath[PATH_MAX];	/* pkg 2 install pkgmap file */
27075c51f124SMoriah Waterland 	char		pkgpath[PATH_MAX];	/* pkg 2 install toplevel dir */
27085c51f124SMoriah Waterland 	int		len;
27095c51f124SMoriah Waterland 	char		line[LINE_MAX];
27105c51f124SMoriah Waterland 
27115c51f124SMoriah Waterland 	/* entry assertions */
27125c51f124SMoriah Waterland 
27135c51f124SMoriah Waterland 	assert(a_packageDir != (char *)NULL);
27145c51f124SMoriah Waterland 	assert(*a_packageDir != '\0');
27155c51f124SMoriah Waterland 	assert(a_pkgInst != (char *)NULL);
27165c51f124SMoriah Waterland 	assert(*a_pkgInst != '\0');
27175c51f124SMoriah Waterland 
27185c51f124SMoriah Waterland 	/* normalize root path */
27195c51f124SMoriah Waterland 
27205c51f124SMoriah Waterland 	if (a_rootPath == (char *)NULL) {
27215c51f124SMoriah Waterland 		a_rootPath = "";
27225c51f124SMoriah Waterland 	}
27235c51f124SMoriah Waterland 
27245c51f124SMoriah Waterland 	/* entry debugging info */
27255c51f124SMoriah Waterland 
27265c51f124SMoriah Waterland 	echoDebug(DBG_CHECKAPP_ENTRY);
27275c51f124SMoriah Waterland 	echoDebug(DBG_CHECKAPP_ARGS, a_pkgInst, a_packageDir, a_rootPath);
27285c51f124SMoriah Waterland 
27295c51f124SMoriah Waterland 	/*
27305c51f124SMoriah Waterland 	 * calculate paths to various objects
27315c51f124SMoriah Waterland 	 */
27325c51f124SMoriah Waterland 
27335c51f124SMoriah Waterland 	/* path to package to be installed top level (main) directory */
27345c51f124SMoriah Waterland 
27355c51f124SMoriah Waterland 	len = snprintf(pkgpath, sizeof (pkgpath), "%s/%s", a_packageDir,
27365c51f124SMoriah Waterland 			a_pkgInst);
27375c51f124SMoriah Waterland 	if (len > sizeof (pkgpath)) {
27385c51f124SMoriah Waterland 		progerr(ERR_CREATE_PATH_2, a_packageDir, a_pkgInst);
27395c51f124SMoriah Waterland 		return (B_FALSE);
27405c51f124SMoriah Waterland 	}
27415c51f124SMoriah Waterland 
27425c51f124SMoriah Waterland 	/* error if package top level directory does not exist */
27435c51f124SMoriah Waterland 
27445c51f124SMoriah Waterland 	if (isdir(pkgpath) != 0) {
27455c51f124SMoriah Waterland 		progerr(ERR_NO_PKGDIR, pkgpath, a_pkgInst, strerror(errno));
27465c51f124SMoriah Waterland 		return (B_FALSE);
27475c51f124SMoriah Waterland 	}
27485c51f124SMoriah Waterland 
27495c51f124SMoriah Waterland 	/* path to pkginfo file within the package to be installed */
27505c51f124SMoriah Waterland 
27515c51f124SMoriah Waterland 	len = snprintf(pkginfoPath, sizeof (pkginfoPath), "%s/pkginfo",
27525c51f124SMoriah Waterland 			pkgpath);
27535c51f124SMoriah Waterland 	if (len > sizeof (pkginfoPath)) {
27545c51f124SMoriah Waterland 		progerr(ERR_CREATE_PATH_2, pkgpath, "pkginfo");
27555c51f124SMoriah Waterland 		return (B_FALSE);
27565c51f124SMoriah Waterland 	}
27575c51f124SMoriah Waterland 
27585c51f124SMoriah Waterland 	/* path to highest instance of package currently installed */
27595c51f124SMoriah Waterland 
27605c51f124SMoriah Waterland 	pkgLocateHighestInst(instPkgPath, sizeof (instPkgPath),
27615c51f124SMoriah Waterland 		instPkg, sizeof (instPkg), a_rootPath, a_pkgInst);
27625c51f124SMoriah Waterland 
27635c51f124SMoriah Waterland 	/*
27645c51f124SMoriah Waterland 	 * gather information from this package's pkginfo file
27655c51f124SMoriah Waterland 	 */
27665c51f124SMoriah Waterland 
27675c51f124SMoriah Waterland 	pkginfoFP = fopen(pkginfoPath, "r");
27685c51f124SMoriah Waterland 
27695c51f124SMoriah Waterland 	if (pkginfoFP == (FILE *)NULL) {
27705c51f124SMoriah Waterland 		progerr(ERR_NO_PKG_INFOFILE, a_pkgInst, pkginfoPath,
27715c51f124SMoriah Waterland 							strerror(errno));
27725c51f124SMoriah Waterland 		return (B_FALSE);
27735c51f124SMoriah Waterland 	}
27745c51f124SMoriah Waterland 
27755c51f124SMoriah Waterland 	/* determine "HOLLOW" setting for this package */
27765c51f124SMoriah Waterland 
27775c51f124SMoriah Waterland 	is_hollow = pkginfoParamTruth(pkginfoFP, PKG_HOLLOW_VARIABLE,
27785c51f124SMoriah Waterland 			"true", B_FALSE);
27795c51f124SMoriah Waterland 
27805c51f124SMoriah Waterland 	/* determine "ALLZONES" setting for this package */
27815c51f124SMoriah Waterland 
27825c51f124SMoriah Waterland 	all_zones = pkginfoParamTruth(pkginfoFP, PKG_ALLZONES_VARIABLE,
27835c51f124SMoriah Waterland 			"true", B_FALSE);
27845c51f124SMoriah Waterland 
27855c51f124SMoriah Waterland 	/* determine "THISZONE" setting for this package */
27865c51f124SMoriah Waterland 
27875c51f124SMoriah Waterland 	this_zone = pkginfoParamTruth(pkginfoFP, PKG_THISZONE_VARIABLE,
27885c51f124SMoriah Waterland 			"true", B_FALSE);
27895c51f124SMoriah Waterland 
27905c51f124SMoriah Waterland 	/* close pkginfo file */
27915c51f124SMoriah Waterland 
27925c51f124SMoriah Waterland 	(void) fclose(pkginfoFP);
27935c51f124SMoriah Waterland 
27945c51f124SMoriah Waterland 	/*
27955c51f124SMoriah Waterland 	 * If request file is not found, it may be in the datastream which
27965c51f124SMoriah Waterland 	 * is not yet unpacked. Check in the pkgmap file.
27975c51f124SMoriah Waterland 	 */
27985c51f124SMoriah Waterland 	if (isfile(pkgpath, REQUEST_FILE) != 0) {
27995c51f124SMoriah Waterland 
28005c51f124SMoriah Waterland 		/* path to pkgmap file within the package to be installed */
28015c51f124SMoriah Waterland 		(void) snprintf(pkgmapPath, sizeof (pkgmapPath), "%s/pkgmap",
28025c51f124SMoriah Waterland 		    pkgpath);
28035c51f124SMoriah Waterland 
28045c51f124SMoriah Waterland 		pkgmapFP = fopen(pkgmapPath, "r");
28055c51f124SMoriah Waterland 
28065c51f124SMoriah Waterland 		if (pkgmapFP == NULL) {
28075c51f124SMoriah Waterland 			progerr(ERR_NO_PKG_MAPFILE, a_pkgInst,
28085c51f124SMoriah Waterland 			    pkgmapPath, strerror(errno));
28095c51f124SMoriah Waterland 			return (B_FALSE);
28105c51f124SMoriah Waterland 		}
28115c51f124SMoriah Waterland 
28125c51f124SMoriah Waterland 		while (fgets(line, LINE_MAX, pkgmapFP) != NULL) {
28135c51f124SMoriah Waterland 			if (strstr(line, " i request") != NULL) {
28145c51f124SMoriah Waterland 				reqfile_found = B_TRUE;
28155c51f124SMoriah Waterland 				break;
28165c51f124SMoriah Waterland 			}
28175c51f124SMoriah Waterland 		}
28185c51f124SMoriah Waterland 		(void) fclose(pkgmapFP);
28195c51f124SMoriah Waterland 	} else {
28205c51f124SMoriah Waterland 		reqfile_found = B_TRUE;
28215c51f124SMoriah Waterland 	}
28225c51f124SMoriah Waterland 
28235c51f124SMoriah Waterland 	/*
28245c51f124SMoriah Waterland 	 * If this package is not marked for installation in this zone only,
28255c51f124SMoriah Waterland 	 * check to see if this package has a request script. If this package
28265c51f124SMoriah Waterland 	 * does have a request script, then mark the package for installation
28275c51f124SMoriah Waterland 	 * in this zone only. Any package with a request script cannot be
28285c51f124SMoriah Waterland 	 * installed outside of the zone the pkgadd command is being run in,
28295c51f124SMoriah Waterland 	 * nor can such a package be installed as part of a new zone install.
28305c51f124SMoriah Waterland 	 * A new zone install must be non-interactive, which is required
28315c51f124SMoriah Waterland 	 * by all packages integrated into the Solaris WOS.
28325c51f124SMoriah Waterland 	 */
28335c51f124SMoriah Waterland 
28345c51f124SMoriah Waterland 	if ((!this_zone) && (reqfile_found)) {
28355c51f124SMoriah Waterland 		if (a_flags & CAF_IN_GLOBAL_ZONE) {
28365c51f124SMoriah Waterland 			echoDebug(DBG_CHECKAPP_THISZONE_REQUEST, a_pkgInst);
28375c51f124SMoriah Waterland 		}
28385c51f124SMoriah Waterland 		this_zone = B_TRUE;
28395c51f124SMoriah Waterland 	}
28405c51f124SMoriah Waterland 
28415c51f124SMoriah Waterland 	/*
28425c51f124SMoriah Waterland 	 * If this package is already installed, see if the current installation
28435c51f124SMoriah Waterland 	 * of the package has a request file - if it does, then act as though
28445c51f124SMoriah Waterland 	 * the current package to be added has a request file - install the
28455c51f124SMoriah Waterland 	 * package in the current zone only.
28465c51f124SMoriah Waterland 	 */
28475c51f124SMoriah Waterland 
28485c51f124SMoriah Waterland 	if ((!this_zone) && (instPkgPath[0] != '\0') &&
28495c51f124SMoriah Waterland 		(isfile(instPkgPath, REQUEST_FILE) == 0)) {
28505c51f124SMoriah Waterland 		if (a_flags & CAF_IN_GLOBAL_ZONE) {
28515c51f124SMoriah Waterland 			echoDebug(DBG_CHECKAPP_THISZONE_INSTREQ,
28525c51f124SMoriah Waterland 				a_pkgInst, instPkg);
28535c51f124SMoriah Waterland 		}
28545c51f124SMoriah Waterland 		this_zone = B_TRUE;
28555c51f124SMoriah Waterland 	}
28565c51f124SMoriah Waterland 
28575c51f124SMoriah Waterland 	/* gather information from the global zone only file */
28585c51f124SMoriah Waterland 
28595c51f124SMoriah Waterland 	in_gz_only = B_FALSE;
28605c51f124SMoriah Waterland 	if (a_flags & CAF_IN_GLOBAL_ZONE) {
28615c51f124SMoriah Waterland 		in_gz_only = pkgIsPkgInGzOnly(a_rootPath, a_pkgInst);
28625c51f124SMoriah Waterland 	}
28635c51f124SMoriah Waterland 
28645c51f124SMoriah Waterland 	/* determine if this package is currently installed */
28655c51f124SMoriah Waterland 
28665c51f124SMoriah Waterland 	pkg_installed = pkginfoIsPkgInstalled((struct pkginfo **)NULL,
28675c51f124SMoriah Waterland 								a_pkgInst);
28685c51f124SMoriah Waterland 
28695c51f124SMoriah Waterland 	/*
28705c51f124SMoriah Waterland 	 * verify package applicability based on information gathered,
28715c51f124SMoriah Waterland 	 * and validate the three SUNW_PKG_ options:
28725c51f124SMoriah Waterland 	 *
28735c51f124SMoriah Waterland 	 * -----------|--------------|-------------|-------------|-----------
28745c51f124SMoriah Waterland 	 * - - - - - -| GLOBAL ZONE -| GLOBAL ZONE | LOCAL ZONE	 | LOCAL ZONE
28755c51f124SMoriah Waterland 	 * - - - - - -|	- - pkgadd - | pkgadd -G   | pkgadd	 | pkgadd -G
28765c51f124SMoriah Waterland 	 * ----1------|--------------|-------------|-------------|------------
28775c51f124SMoriah Waterland 	 * ALLZONES f | add to gz    | add to gz   | add to ls	 | add to ls
28785c51f124SMoriah Waterland 	 * HOLLOW   f | current lz   | not to curr | only - - - -| only - - -
28795c51f124SMoriah Waterland 	 * THISZONE f | futr lz - - -| or futr lz  | - - - - - - | - - - - - -
28805c51f124SMoriah Waterland 	 * ----2------|--------------|-------------|-------------|------------
28815c51f124SMoriah Waterland 	 * ALLZONES T | add to gz    | operation   | operation	 | operation
28825c51f124SMoriah Waterland 	 * HOLLOW   f | current lz   | not allowed | not allowed | not allowed
28835c51f124SMoriah Waterland 	 * THISZONE f | future lz    | - - - - - - | - - - - - - | - - - - - -
28845c51f124SMoriah Waterland 	 * ----3------|--------------|-------------|-------------|------------
28855c51f124SMoriah Waterland 	 * ALLZONES T | add to gz    | operation   | operation	 | operation
28865c51f124SMoriah Waterland 	 * HOLLOW   T | pkg db only  | not allowed | not allowed | not allowed
28875c51f124SMoriah Waterland 	 * THISZONE f | curr/futr lz | - - - - - - | - - - - - - | - - - - - -
28885c51f124SMoriah Waterland 	 * ----4------|--------------|-------------|-------------|------------
28895c51f124SMoriah Waterland 	 * ALLZONES T | bad option   | bad option  | bad option	 | bad option
28905c51f124SMoriah Waterland 	 * HOLLOW   * | combo - - - -| combo - - - | combo - - - | combo - -
28915c51f124SMoriah Waterland 	 * THISZONE T |	- - - - - - -|- - - - - - -|- - - - - - -|- - - - - -
28925c51f124SMoriah Waterland 	 * ----5------|--------------|-------------|-------------|------------
28935c51f124SMoriah Waterland 	 * ALLZONES f | bad option   | bad option  | bad option	 | bad option
28945c51f124SMoriah Waterland 	 * HOLLOW   T | combo - - - -| combo - - - | combo - - - | combo - - -
28955c51f124SMoriah Waterland 	 * THISZONE * | - - - - - - -| - - - - - - | - - - - - - | - - - - - -
28965c51f124SMoriah Waterland 	 * ----6------|--------------|-------------|-------------|------------
28975c51f124SMoriah Waterland 	 * ALLZONES f | add to gz    | add to gz   | add to lz	 | add to lz
28985c51f124SMoriah Waterland 	 * HOLLOW   f | not current  | not current | only - - -	 | only - - -
28995c51f124SMoriah Waterland 	 * THISZONE T | or future lz | or futr lz  | - - - - - - | - - - - - -
29005c51f124SMoriah Waterland 	 * -----------|--------------|-------------|-------------|-----------
29015c51f124SMoriah Waterland 	 */
29025c51f124SMoriah Waterland 
29035c51f124SMoriah Waterland 	/* pkg "all zones" && "this zone" (#4) */
29045c51f124SMoriah Waterland 
29055c51f124SMoriah Waterland 	if (all_zones && this_zone) {
29065c51f124SMoriah Waterland 		progerr(ERR_ALLZONES_AND_THISZONE, a_pkgInst,
29075c51f124SMoriah Waterland 			PKG_ALLZONES_VARIABLE, PKG_THISZONE_VARIABLE);
29085c51f124SMoriah Waterland 		return (B_FALSE);
29095c51f124SMoriah Waterland 	}
29105c51f124SMoriah Waterland 
29115c51f124SMoriah Waterland 	/* pkg "!all zones" && "hollow" (#5) */
29125c51f124SMoriah Waterland 
29135c51f124SMoriah Waterland 	if ((!all_zones) && is_hollow) {
29145c51f124SMoriah Waterland 		progerr(ERR_NOW_ALLZONES_AND_HOLLOW, a_pkgInst,
29155c51f124SMoriah Waterland 			PKG_ALLZONES_VARIABLE, PKG_HOLLOW_VARIABLE);
29165c51f124SMoriah Waterland 		return (B_FALSE);
29175c51f124SMoriah Waterland 	}
29185c51f124SMoriah Waterland 
29195c51f124SMoriah Waterland 	/* pkg ALLZONES=true && -Z specified */
29205c51f124SMoriah Waterland 
29215c51f124SMoriah Waterland 	if (all_zones && (a_flags & CAF_SCOPE_NONGLOBAL)) {
29225c51f124SMoriah Waterland 		progerr(ERR_ALLZONES_AND_Z_USED, a_pkgInst);
29235c51f124SMoriah Waterland 		return (B_FALSE);
29245c51f124SMoriah Waterland 	}
29255c51f124SMoriah Waterland 
29265c51f124SMoriah Waterland 	/* pkg ALLZONES=true & not running in global zone (#2/#3) */
29275c51f124SMoriah Waterland 
29285c51f124SMoriah Waterland 	if (all_zones && (!(a_flags & CAF_IN_GLOBAL_ZONE))) {
29295c51f124SMoriah Waterland 		progerr(ERR_ALLZONES_AND_IN_LZ, a_pkgInst);
29305c51f124SMoriah Waterland 		return (B_FALSE);
29315c51f124SMoriah Waterland 	}
29325c51f124SMoriah Waterland 
29335c51f124SMoriah Waterland 	/* pkg "in gz only" & pkg "NOT installed" */
29345c51f124SMoriah Waterland 
29355c51f124SMoriah Waterland 	if (in_gz_only && (!pkg_installed)) {
29365c51f124SMoriah Waterland 		/* MAKE A WARNING */
29375c51f124SMoriah Waterland 		echo(ERR_IN_GZ_AND_NOT_INSTALLED, a_pkgInst,
29385c51f124SMoriah Waterland 			pkgGetGzOnlyPath());
29395c51f124SMoriah Waterland 	}
29405c51f124SMoriah Waterland 
29415c51f124SMoriah Waterland 	/* pkg ALLZONES=true & pkg "in gz only" & pkg "is installed" */
29425c51f124SMoriah Waterland 
29435c51f124SMoriah Waterland 	if (all_zones && in_gz_only && pkg_installed) {
29445c51f124SMoriah Waterland 		progerr(ERR_IN_GZ_AND_ALLZONES_AND_INSTALLED, a_pkgInst);
29455c51f124SMoriah Waterland 		return (B_FALSE);
29465c51f124SMoriah Waterland 	}
29475c51f124SMoriah Waterland 
29485c51f124SMoriah Waterland 	/* pkg ALLZONES=true && -G specified (#2/#3) */
29495c51f124SMoriah Waterland 
29505c51f124SMoriah Waterland 	if (all_zones && (a_flags & CAF_SCOPE_GLOBAL)) {
29515c51f124SMoriah Waterland 		progerr(ERR_ALLZONES_AND_G_USED, a_pkgInst);
29525c51f124SMoriah Waterland 		return (B_FALSE);
29535c51f124SMoriah Waterland 	}
29545c51f124SMoriah Waterland 
29555c51f124SMoriah Waterland 	/* pkg "!this zone" && "in gz only" & -G not specified */
29565c51f124SMoriah Waterland 
29575c51f124SMoriah Waterland 	if ((!this_zone) && in_gz_only && (!(a_flags & CAF_SCOPE_GLOBAL))) {
29585c51f124SMoriah Waterland 		progerr(ERR_IN_GZ_AND_NO_G_USED, a_pkgInst);
29595c51f124SMoriah Waterland 		return (B_FALSE);
29605c51f124SMoriah Waterland 	}
29615c51f124SMoriah Waterland 
29625c51f124SMoriah Waterland 	/* pkg "NOT in gz only" & -Z specified */
29635c51f124SMoriah Waterland 
29645c51f124SMoriah Waterland 	if ((!in_gz_only) && (a_flags & CAF_SCOPE_NONGLOBAL)) {
29655c51f124SMoriah Waterland 		progerr(ERR_NOT_IN_GZ_AND_Z_USED, a_pkgInst);
29665c51f124SMoriah Waterland 		return (B_FALSE);
29675c51f124SMoriah Waterland 	}
29685c51f124SMoriah Waterland 
29695c51f124SMoriah Waterland 	/* pkg "this zone" && -Z specified */
29705c51f124SMoriah Waterland 
29715c51f124SMoriah Waterland 	if (this_zone && (a_flags & CAF_SCOPE_NONGLOBAL)) {
29725c51f124SMoriah Waterland 		progerr(ERR_THISZONE_AND_Z_USED, PKG_THISZONE_VARIABLE,
29735c51f124SMoriah Waterland 			a_pkgInst);
29745c51f124SMoriah Waterland 		return (B_FALSE);
29755c51f124SMoriah Waterland 	}
29765c51f124SMoriah Waterland 
29775c51f124SMoriah Waterland 	/*
29785c51f124SMoriah Waterland 	 * If this package is marked 'this zone only', then mark the package
29795c51f124SMoriah Waterland 	 * as "add to this zone only". This is referenced by the various
29805c51f124SMoriah Waterland 	 * add_package_... functions to determine if the package should be
29815c51f124SMoriah Waterland 	 * added to the current zone, or to all zones, depending on the
29825c51f124SMoriah Waterland 	 * zone in which the command is being run.
29835c51f124SMoriah Waterland 	 */
29845c51f124SMoriah Waterland 
29855c51f124SMoriah Waterland 	if (this_zone) {
29865c51f124SMoriah Waterland 		pkgAddThisZonePackage(a_pkgInst);
29875c51f124SMoriah Waterland 	}
29885c51f124SMoriah Waterland 
29895c51f124SMoriah Waterland 	return (B_TRUE);
29905c51f124SMoriah Waterland }
29915c51f124SMoriah Waterland 
29925c51f124SMoriah Waterland /*
29935c51f124SMoriah Waterland  * Name:	create_zone_adminfile
29945c51f124SMoriah Waterland  * Description: Given a zone temporary directory and optionally an existing
29955c51f124SMoriah Waterland  *		administration file, generate an administration file that
29965c51f124SMoriah Waterland  *		can be used to perform "non-interactive" operations in a
29975c51f124SMoriah Waterland  *		non-global zone.
29985c51f124SMoriah Waterland  * Arguments:	r_zoneAdminFile - pointer to handle that will contain a
29995c51f124SMoriah Waterland  *			string representing the path to the temporary
30005c51f124SMoriah Waterland  *			administration file created - this must be NULL
30015c51f124SMoriah Waterland  *			before the first call to this function - on
30025c51f124SMoriah Waterland  *			subsequent calls if the pointer is NOT null then
30035c51f124SMoriah Waterland  *			the existing string will NOT be overwritten.
30045c51f124SMoriah Waterland  *		a_zoneTempDir - pointer to string representing the path
30055c51f124SMoriah Waterland  *			to the zone temporary directory to create the
30065c51f124SMoriah Waterland  *			temporary administration file in
30075c51f124SMoriah Waterland  *		a_admnfile - pointer to string representing the path to
30085c51f124SMoriah Waterland  *			an existing "user" administration file - the
30095c51f124SMoriah Waterland  *			administration file created will contain the
30105c51f124SMoriah Waterland  *			settings contained in this file, modified as
30115c51f124SMoriah Waterland  *			appropriate to supress any interaction;
30125c51f124SMoriah Waterland  *			If this is == NULL then the administration file
30135c51f124SMoriah Waterland  *			created will not contain any extra settings
30145c51f124SMoriah Waterland  * Returns:	void
30155c51f124SMoriah Waterland  * NOTE:	Any string returned is placed in new storage for the
30165c51f124SMoriah Waterland  *		calling method. The caller must use 'free' to dispose
30175c51f124SMoriah Waterland  *		of the storage once the string is no longer needed.
30185c51f124SMoriah Waterland  * NOTE:	On any error this function will call 'quit(1)'
30195c51f124SMoriah Waterland  */
30205c51f124SMoriah Waterland 
30215c51f124SMoriah Waterland static void
30225c51f124SMoriah Waterland create_zone_adminfile(char **r_zoneAdminFile, char *a_zoneTempDir,
30235c51f124SMoriah Waterland 	char *a_admnfile)
30245c51f124SMoriah Waterland {
30255c51f124SMoriah Waterland 	boolean_t	b;
30265c51f124SMoriah Waterland 
30275c51f124SMoriah Waterland 	/* entry assertions */
30285c51f124SMoriah Waterland 
30295c51f124SMoriah Waterland 	assert(r_zoneAdminFile != (char **)NULL);
30305c51f124SMoriah Waterland 	assert(a_zoneTempDir != (char *)NULL);
30315c51f124SMoriah Waterland 	assert(*a_zoneTempDir != '\0');
30325c51f124SMoriah Waterland 
30335c51f124SMoriah Waterland 	/* entry debugging info */
30345c51f124SMoriah Waterland 
30355c51f124SMoriah Waterland 	echoDebug(DBG_CREATE_ZONE_ADMINFILE, a_zoneTempDir, PSTR(a_admnfile));
30365c51f124SMoriah Waterland 
30375c51f124SMoriah Waterland 	/* if temporary name already exists, do not overwrite */
30385c51f124SMoriah Waterland 
30395c51f124SMoriah Waterland 	if (*r_zoneAdminFile != (char *)NULL) {
30405c51f124SMoriah Waterland 		return;
30415c51f124SMoriah Waterland 	}
30425c51f124SMoriah Waterland 
30435c51f124SMoriah Waterland 	/* create temporary name */
30445c51f124SMoriah Waterland 
30455c51f124SMoriah Waterland 	*r_zoneAdminFile = tempnam(a_zoneTempDir, "zadmn");
30465c51f124SMoriah Waterland 	b = z_create_zone_admin_file(*r_zoneAdminFile, a_admnfile);
30475c51f124SMoriah Waterland 	if (b == B_FALSE) {
30485c51f124SMoriah Waterland 		progerr(ERR_CREATE_TMPADMIN, *r_zoneAdminFile,
30495c51f124SMoriah Waterland 			strerror(errno));
30505c51f124SMoriah Waterland 		quit(1);
30515c51f124SMoriah Waterland 		/* NOTREACHED */
30525c51f124SMoriah Waterland 	}
30535c51f124SMoriah Waterland 
30545c51f124SMoriah Waterland 	echoDebug(DBG_CREATED_ZONE_ADMINFILE, *r_zoneAdminFile);
30555c51f124SMoriah Waterland }
30565c51f124SMoriah Waterland 
30575c51f124SMoriah Waterland /*
30585c51f124SMoriah Waterland  * Name:	create_zone_tempdir
30595c51f124SMoriah Waterland  * Description: Given a system temporary directory, create a "zone" specific
30605c51f124SMoriah Waterland  *		temporary directory and return the path to the directory
30615c51f124SMoriah Waterland  *		created.
30625c51f124SMoriah Waterland  * Arguments:	r_zoneTempDir - pointer to handle that will contain a
30635c51f124SMoriah Waterland  *			string representing the path to the temporary
30645c51f124SMoriah Waterland  *			directory created - this must be NULL before the
30655c51f124SMoriah Waterland  *			first call to this function - on subsequent calls
30665c51f124SMoriah Waterland  *			if the pointer is NOT null then the existing string
30675c51f124SMoriah Waterland  *			will NOT be overwritten.
30685c51f124SMoriah Waterland  *		a_zoneTempDir - pointer to string representing the path
30695c51f124SMoriah Waterland  *			to the system temporary directory to create the
30705c51f124SMoriah Waterland  *			temporary zone directory in
30715c51f124SMoriah Waterland  * Returns:	void
30725c51f124SMoriah Waterland  * NOTE:	Any string returned is placed in new storage for the
30735c51f124SMoriah Waterland  *		calling method. The caller must use 'free' to dispose
30745c51f124SMoriah Waterland  *		of the storage once the string is no longer needed.
30755c51f124SMoriah Waterland  * NOTE:	On any error this function will call 'quit(1)'
30765c51f124SMoriah Waterland  * NOTE:	This function calls "quitSetZoneTmpdir" on success to
30775c51f124SMoriah Waterland  *		register the directory created with quit() so that the
30785c51f124SMoriah Waterland  *		directory will be automatically deleted on exit.
30795c51f124SMoriah Waterland  */
30805c51f124SMoriah Waterland 
30815c51f124SMoriah Waterland static void
30825c51f124SMoriah Waterland create_zone_tempdir(char **r_zoneTempDir, char *a_tmpdir)
30835c51f124SMoriah Waterland {
30845c51f124SMoriah Waterland 	boolean_t	b;
30855c51f124SMoriah Waterland 
30865c51f124SMoriah Waterland 	/* entry assertions */
30875c51f124SMoriah Waterland 
30885c51f124SMoriah Waterland 	assert(r_zoneTempDir != (char **)NULL);
30895c51f124SMoriah Waterland 	assert(a_tmpdir != (char *)NULL);
30905c51f124SMoriah Waterland 	assert(*a_tmpdir != '\0');
30915c51f124SMoriah Waterland 
30925c51f124SMoriah Waterland 	/* entry debugging info */
30935c51f124SMoriah Waterland 
30945c51f124SMoriah Waterland 	echoDebug(DBG_CREATE_ZONE_TEMPDIR, a_tmpdir);
30955c51f124SMoriah Waterland 
30965c51f124SMoriah Waterland 	/* if temporary directory already exists, do not overwrite */
30975c51f124SMoriah Waterland 
30985c51f124SMoriah Waterland 	if (*r_zoneTempDir != (char *)NULL) {
30995c51f124SMoriah Waterland 		return;
31005c51f124SMoriah Waterland 	}
31015c51f124SMoriah Waterland 
31025c51f124SMoriah Waterland 	/* create temporary directory */
31035c51f124SMoriah Waterland 
31045c51f124SMoriah Waterland 	b = setup_temporary_directory(r_zoneTempDir, a_tmpdir, "ztemp");
31055c51f124SMoriah Waterland 	if (b == B_FALSE) {
31065c51f124SMoriah Waterland 		progerr(ERR_ZONETEMPDIR, a_tmpdir, strerror(errno));
31075c51f124SMoriah Waterland 		quit(1);
31085c51f124SMoriah Waterland 		/* NOTREACHED */
31095c51f124SMoriah Waterland 	}
31105c51f124SMoriah Waterland 
31115c51f124SMoriah Waterland 	/* register with quit() so directory is removed on exit */
31125c51f124SMoriah Waterland 
31135c51f124SMoriah Waterland 	quitSetZoneTmpdir(*r_zoneTempDir);
31145c51f124SMoriah Waterland 
31155c51f124SMoriah Waterland 	/* exit debugging info */
31165c51f124SMoriah Waterland 
31175c51f124SMoriah Waterland 	echoDebug(DBG_CREATED_ZONE_TEMPDIR, *r_zoneTempDir);
31185c51f124SMoriah Waterland }
31195c51f124SMoriah Waterland 
31205c51f124SMoriah Waterland /*
31215c51f124SMoriah Waterland  * Name:	continue_installation
31225c51f124SMoriah Waterland  * Description: Called from within a loop that is installing packages,
31235c51f124SMoriah Waterland  *		this function examines various global variables and decides
31245c51f124SMoriah Waterland  *		whether or not to ask an appropriate question, and wait for
31255c51f124SMoriah Waterland  *		and appropriate reply.
31265c51f124SMoriah Waterland  * Arguments:	<<global variables>>
31275c51f124SMoriah Waterland  * Returns:	B_TRUE - continue processing with next package
31285c51f124SMoriah Waterland  *		B_FALSE - do not continue processing with next package
31295c51f124SMoriah Waterland  */
31305c51f124SMoriah Waterland 
31315c51f124SMoriah Waterland static boolean_t
31325c51f124SMoriah Waterland continue_installation(void)
31335c51f124SMoriah Waterland {
31345c51f124SMoriah Waterland 	char	ans[MAX_INPUT];
31355c51f124SMoriah Waterland 	int	n;
31365c51f124SMoriah Waterland 
31375c51f124SMoriah Waterland 	/* return TRUE if not interrupted */
31385c51f124SMoriah Waterland 
31395c51f124SMoriah Waterland 	if (!interrupted) {
31405c51f124SMoriah Waterland 		return (B_TRUE);
31415c51f124SMoriah Waterland 	}
31425c51f124SMoriah Waterland 
31435c51f124SMoriah Waterland 	/*
31445c51f124SMoriah Waterland 	 * process interrupted - determine whether or not to continue
31455c51f124SMoriah Waterland 	 */
31465c51f124SMoriah Waterland 
31475c51f124SMoriah Waterland 	/* output appropriate interrupted message */
31485c51f124SMoriah Waterland 
31495c51f124SMoriah Waterland 	if (askflag) {
31505c51f124SMoriah Waterland 		echo(npkgs == 1 ? MSG_1MORE_PROC : MSG_MORE_PROC, npkgs);
31515c51f124SMoriah Waterland 	} else {
31525c51f124SMoriah Waterland 		echo(npkgs == 1 ? MSG_1MORE_INST : MSG_MORE_INST, npkgs);
31535c51f124SMoriah Waterland 	}
31545c51f124SMoriah Waterland 
31555c51f124SMoriah Waterland 	/* if running with no interaction (-n) do not ask question */
31565c51f124SMoriah Waterland 
31575c51f124SMoriah Waterland 	if (nointeract) {
31585c51f124SMoriah Waterland 		/* if admin required return 'dont continue' */
31595c51f124SMoriah Waterland 		if (needconsult) {
31605c51f124SMoriah Waterland 			return (B_FALSE);
31615c51f124SMoriah Waterland 		}
31625c51f124SMoriah Waterland 		ckquit = 1;
31635c51f124SMoriah Waterland 		return (B_TRUE);
31645c51f124SMoriah Waterland 	}
31655c51f124SMoriah Waterland 
31665c51f124SMoriah Waterland 	/* interaction possible: ask question */
31675c51f124SMoriah Waterland 
31685c51f124SMoriah Waterland 	ckquit = 0;
31695c51f124SMoriah Waterland 	n = ckyorn(ans, NULL, NULL, NULL, ASK_CONTINUE_ADD);
31705c51f124SMoriah Waterland 	if (n != 0) {
31715c51f124SMoriah Waterland 		quit(n);
31725c51f124SMoriah Waterland 		/* NOTREACHED */
31735c51f124SMoriah Waterland 	}
31745c51f124SMoriah Waterland 	ckquit = 1;
31755c51f124SMoriah Waterland 	if (strchr("yY", *ans) == NULL) {
31765c51f124SMoriah Waterland 		return (B_FALSE);
31775c51f124SMoriah Waterland 	}
31785c51f124SMoriah Waterland 	return (B_TRUE);
31795c51f124SMoriah Waterland }
31805c51f124SMoriah Waterland 
31815c51f124SMoriah Waterland /*
31825c51f124SMoriah Waterland  * package can be in a number of formats:
31835c51f124SMoriah Waterland  * - file containing package stream (pkgadd -d file [pkgs])
31845c51f124SMoriah Waterland  * - directory containing packages (pkgadd -d /dir [pkgs])
31855c51f124SMoriah Waterland  * - device containing packages (pkgadd -d diskette1 [pkgs])
31865c51f124SMoriah Waterland  * non-global zones can be passed open files and strings as arguments
31875c51f124SMoriah Waterland  * - for file containing package stream
31885c51f124SMoriah Waterland  * -- the stream can be passed directly to the non-global zone
31895c51f124SMoriah Waterland  * - for directory
31905c51f124SMoriah Waterland  * -- convert packages to datastream to pass to the non-global zone
31915c51f124SMoriah Waterland  * - for device
31925c51f124SMoriah Waterland  * -- ?
31935c51f124SMoriah Waterland  */
31945c51f124SMoriah Waterland 
31955c51f124SMoriah Waterland static boolean_t
31965c51f124SMoriah Waterland unpack_and_check_packages(char **a_pkgList, char *a_idsName, char *a_packageDir)
31975c51f124SMoriah Waterland {
31985c51f124SMoriah Waterland 	int	savenpkgs = npkgs;
31995c51f124SMoriah Waterland 	int	i;
32005c51f124SMoriah Waterland 	CAF_T	flags = 0;
32015c51f124SMoriah Waterland 
32025c51f124SMoriah Waterland 	/* entry assertions */
32035c51f124SMoriah Waterland 
32045c51f124SMoriah Waterland 	assert(a_pkgList != (char **)NULL);
32055c51f124SMoriah Waterland 
32065c51f124SMoriah Waterland 	/* entry debugging info */
32075c51f124SMoriah Waterland 
32085c51f124SMoriah Waterland 	echoDebug(DBG_UNPACKCHECK_ENTRY);
32095c51f124SMoriah Waterland 	echoDebug(DBG_UNPACKCHECK_ARGS, PSTR(a_idsName), PSTR(a_packageDir));
32105c51f124SMoriah Waterland 
32115c51f124SMoriah Waterland 	/*
32125c51f124SMoriah Waterland 	 * set flags for applicability check
32135c51f124SMoriah Waterland 	 */
32145c51f124SMoriah Waterland 
32155c51f124SMoriah Waterland 	/* determine if running in the global zone */
32165c51f124SMoriah Waterland 
32175c51f124SMoriah Waterland 	if (z_running_in_global_zone() == B_TRUE) {
32185c51f124SMoriah Waterland 		flags |= CAF_IN_GLOBAL_ZONE;
32195c51f124SMoriah Waterland 	}
32205c51f124SMoriah Waterland 
32215c51f124SMoriah Waterland 	/* set -G flag */
32225c51f124SMoriah Waterland 
32235c51f124SMoriah Waterland 	if (globalZoneOnly == B_TRUE) {
32245c51f124SMoriah Waterland 		flags |= CAF_SCOPE_GLOBAL;
32255c51f124SMoriah Waterland 	}
32265c51f124SMoriah Waterland 
32275c51f124SMoriah Waterland 	/*
32285c51f124SMoriah Waterland 	 * for each package to install:
32295c51f124SMoriah Waterland 	 * - if packages from datastream, unpack package into package dir
32305c51f124SMoriah Waterland 	 * - check applicability of installing package on this system/zone
32315c51f124SMoriah Waterland 	 */
32325c51f124SMoriah Waterland 
32335c51f124SMoriah Waterland 	for (i = 0; (pkginst = a_pkgList[i]) != NULL; i++) {
32345c51f124SMoriah Waterland 		if (a_idsName != (char *)NULL) {
32355c51f124SMoriah Waterland 			/* create stream out of package if not already one */
32365c51f124SMoriah Waterland 			if (unpack_package_from_stream(a_idsName, pkginst,
32375c51f124SMoriah Waterland 				a_packageDir) == B_FALSE) {
32385c51f124SMoriah Waterland 				progerr(ERR_CANNOT_UNPACK_PKGSTRM,
32395c51f124SMoriah Waterland 					PSTR(pkginst), PSTR(a_idsName),
32405c51f124SMoriah Waterland 					PSTR(a_packageDir));
32415c51f124SMoriah Waterland 
32425c51f124SMoriah Waterland 				npkgs = savenpkgs;
32435c51f124SMoriah Waterland 				return (B_FALSE);
32445c51f124SMoriah Waterland 			}
32455c51f124SMoriah Waterland 		} else {
32465c51f124SMoriah Waterland 			echoDebug(DBG_PKG_IN_DIR, pkginst, a_packageDir);
32475c51f124SMoriah Waterland 		}
32485c51f124SMoriah Waterland 
32495c51f124SMoriah Waterland 		/* check package applicability */
32505c51f124SMoriah Waterland 		if (check_applicability(a_packageDir,
32515c51f124SMoriah Waterland 			pkginst, get_inst_root(), flags) == B_FALSE) {
32525c51f124SMoriah Waterland 			progerr(ERR_PKG_NOT_INSTALLABLE, pkginst);
32535c51f124SMoriah Waterland 			npkgs = savenpkgs;
32545c51f124SMoriah Waterland 			return (B_FALSE);
32555c51f124SMoriah Waterland 		}
32565c51f124SMoriah Waterland 		npkgs--;
32575c51f124SMoriah Waterland 	}
32585c51f124SMoriah Waterland 
32595c51f124SMoriah Waterland 	npkgs = savenpkgs;
32605c51f124SMoriah Waterland 	return (B_TRUE);
32615c51f124SMoriah Waterland }
32625c51f124SMoriah Waterland 
32635c51f124SMoriah Waterland /*
32645c51f124SMoriah Waterland  * returns:
32655c51f124SMoriah Waterland  *	B_TRUE - package list generated
32665c51f124SMoriah Waterland  *	B_FALSE - failed to generate package list
32675c51f124SMoriah Waterland  *	Will call quit(n) on fatal error.
32685c51f124SMoriah Waterland  */
32695c51f124SMoriah Waterland 
32705c51f124SMoriah Waterland static boolean_t
32715c51f124SMoriah Waterland get_package_list(char ***r_pkgList, char **a_argv, char *a_categories,
32725c51f124SMoriah Waterland 	char **a_categoryList, int a_ignoreSignatures, PKG_ERR *a_err,
32735c51f124SMoriah Waterland 	ushort_t a_httpProxyPort, char *a_httpProxyName,
32745c51f124SMoriah Waterland 	keystore_handle_t a_keystore, char *a_keystoreFile,
32755c51f124SMoriah Waterland 	char *a_idsName, int *r_repeat)
32765c51f124SMoriah Waterland {
32775c51f124SMoriah Waterland 	int		n;
32785c51f124SMoriah Waterland 	url_hport_t	*proxytmp = NULL;
32795c51f124SMoriah Waterland 
32805c51f124SMoriah Waterland 	/* entry assertions */
32815c51f124SMoriah Waterland 
32825c51f124SMoriah Waterland 	assert(r_repeat != (int *)NULL);
32835c51f124SMoriah Waterland 
32845c51f124SMoriah Waterland 	/* entry debugging info */
32855c51f124SMoriah Waterland 
32865c51f124SMoriah Waterland 	echoDebug(DBG_GETPKGLIST_ENTRY);
32875c51f124SMoriah Waterland 	echoDebug(DBG_GETPKGLIST_ARGS, PSTR(a_idsName), PSTR(pkgdev.dirname),
32885c51f124SMoriah Waterland 			*r_repeat);
32895c51f124SMoriah Waterland 
32905c51f124SMoriah Waterland 	/*
32915c51f124SMoriah Waterland 	 * get the list of the packages to add
32925c51f124SMoriah Waterland 	 */
32935c51f124SMoriah Waterland 
32945c51f124SMoriah Waterland 	n = pkgGetPackageList(r_pkgList, a_argv, optind, a_categories,
32955c51f124SMoriah Waterland 				a_categoryList, &pkgdev);
32965c51f124SMoriah Waterland 
32975c51f124SMoriah Waterland 	switch (n) {
32985c51f124SMoriah Waterland 		case -1:	/* no packages found */
32995c51f124SMoriah Waterland 			echoDebug(DBG_PKGLIST_NONFOUND, PSTR(a_idsName),
33005c51f124SMoriah Waterland 					pkgdev.dirname);
33015c51f124SMoriah Waterland 			return (B_FALSE);
33025c51f124SMoriah Waterland 
33035c51f124SMoriah Waterland 		case 0:		/* packages found */
33045c51f124SMoriah Waterland 			break;
33055c51f124SMoriah Waterland 
33065c51f124SMoriah Waterland 		default:	/* "quit" error */
33075c51f124SMoriah Waterland 			echoDebug(DBG_PKGLIST_ERROR, PSTR(a_idsName),
33085c51f124SMoriah Waterland 				pkgdev.dirname, n);
33095c51f124SMoriah Waterland 			quit(n);
33105c51f124SMoriah Waterland 			/* NOTREACHED */
33115c51f124SMoriah Waterland 	}
33125c51f124SMoriah Waterland 
33135c51f124SMoriah Waterland 	/*
33145c51f124SMoriah Waterland 	 * If we are not ignoring signatures, check the package's
33155c51f124SMoriah Waterland 	 * signature if one exists.  pkgask doesn't care about
33165c51f124SMoriah Waterland 	 * signatures though.
33175c51f124SMoriah Waterland 	 */
33185c51f124SMoriah Waterland 	if (!askflag && !a_ignoreSignatures && a_idsName &&
33195c51f124SMoriah Waterland 		(web_ck_authentication() == AUTH_QUIT)) {
33205c51f124SMoriah Waterland 
33215c51f124SMoriah Waterland 		PKCS7		*sig = NULL;
33225c51f124SMoriah Waterland 		STACK_OF(X509)	*cas = NULL;
33235c51f124SMoriah Waterland 
33245c51f124SMoriah Waterland 		/* Retrieve signature */
33255c51f124SMoriah Waterland 		if (!get_signature(a_err, a_idsName, &pkgdev, &sig)) {
33265c51f124SMoriah Waterland 			pkgerr(a_err);
33275c51f124SMoriah Waterland 			web_cleanup();
33285c51f124SMoriah Waterland 			quit(1);
33295c51f124SMoriah Waterland 			/* NOTREACHED */
33305c51f124SMoriah Waterland 		}
33315c51f124SMoriah Waterland 
33325c51f124SMoriah Waterland 		if (sig != NULL) {
33335c51f124SMoriah Waterland 			/* Found signature.  Verify. */
33345c51f124SMoriah Waterland 			if (a_httpProxyName != NULL) {
33355c51f124SMoriah Waterland 				/* Proxy will be needed for OCSP */
33365c51f124SMoriah Waterland 				proxytmp = malloc(sizeof (url_hport_t));
33375c51f124SMoriah Waterland 				if (url_parse_hostport(a_httpProxyName,
33385c51f124SMoriah Waterland 					proxytmp, a_httpProxyPort)
33395c51f124SMoriah Waterland 					!= URL_PARSE_SUCCESS) {
33405c51f124SMoriah Waterland 					progerr(ERR_PROXY,
33415c51f124SMoriah Waterland 						a_httpProxyName);
33425c51f124SMoriah Waterland 					PKCS7_free(sig);
33435c51f124SMoriah Waterland 					quit(99);
33445c51f124SMoriah Waterland 					/* NOTREACHED */
33455c51f124SMoriah Waterland 				}
33465c51f124SMoriah Waterland 			}
33475c51f124SMoriah Waterland 
33485c51f124SMoriah Waterland 			/* Start with fresh error stack */
33495c51f124SMoriah Waterland 			pkgerr_clear(a_err);
33505c51f124SMoriah Waterland 
33515c51f124SMoriah Waterland 			if (a_keystore == NULL) {
33525c51f124SMoriah Waterland 				/* keystore not opened - open it */
33535c51f124SMoriah Waterland 				if (open_keystore(a_err, a_keystoreFile,
33545c51f124SMoriah Waterland 					get_prog_name(), pkg_passphrase_cb,
33555c51f124SMoriah Waterland 					KEYSTORE_DFLT_FLAGS,
33565c51f124SMoriah Waterland 					&a_keystore) != 0) {
33575c51f124SMoriah Waterland 					pkgerr(a_err);
33585c51f124SMoriah Waterland 					web_cleanup();
33595c51f124SMoriah Waterland 					PKCS7_free(sig);
33605c51f124SMoriah Waterland 					quit(1);
33615c51f124SMoriah Waterland 					/* NOTREACHED */
33625c51f124SMoriah Waterland 				}
33635c51f124SMoriah Waterland 			}
33645c51f124SMoriah Waterland 
33655c51f124SMoriah Waterland 			/* get trusted CA certs */
33665c51f124SMoriah Waterland 			if (find_ca_certs(a_err, a_keystore, &cas) != 0) {
33675c51f124SMoriah Waterland 				pkgerr(a_err);
33685c51f124SMoriah Waterland 				PKCS7_free(sig);
33695c51f124SMoriah Waterland 				web_cleanup();
33705c51f124SMoriah Waterland 				quit(1);
33715c51f124SMoriah Waterland 				/* NOTREACHED */
33725c51f124SMoriah Waterland 			}
33735c51f124SMoriah Waterland 
33745c51f124SMoriah Waterland 			/* Verify signature */
33755c51f124SMoriah Waterland 			if (!ds_validate_signature(a_err, &pkgdev,
33765c51f124SMoriah Waterland 				&a_argv[optind], a_idsName, sig,
33775c51f124SMoriah Waterland 				cas, proxytmp, nointeract)) {
33785c51f124SMoriah Waterland 				pkgerr(a_err);
33795c51f124SMoriah Waterland 				quit(99);
33805c51f124SMoriah Waterland 				/* NOTREACHED */
33815c51f124SMoriah Waterland 			}
33825c51f124SMoriah Waterland 
33835c51f124SMoriah Waterland 			/* cleanup */
33845c51f124SMoriah Waterland 			PKCS7_free(sig);
33855c51f124SMoriah Waterland 			web_cleanup();
33865c51f124SMoriah Waterland 			pkgerr_free(a_err);
33875c51f124SMoriah Waterland 		}
33885c51f124SMoriah Waterland 	}
33895c51f124SMoriah Waterland 
33905c51f124SMoriah Waterland 	/* order package list if input data stream specified */
33915c51f124SMoriah Waterland 
33925c51f124SMoriah Waterland 	if (a_idsName) {
33935c51f124SMoriah Waterland 		ds_order(*r_pkgList);
33945c51f124SMoriah Waterland 	}
33955c51f124SMoriah Waterland 
33965c51f124SMoriah Waterland 	return (B_TRUE);
33975c51f124SMoriah Waterland }
33985c51f124SMoriah Waterland 
33995c51f124SMoriah Waterland /*
34005c51f124SMoriah Waterland  * Name:	install_in_one_zone
34015c51f124SMoriah Waterland  * Description:	Install a single package in a single zone
34025c51f124SMoriah Waterland  * Arguments:	a_inheritedPkgDirs - pointer to array of strings, each one
34035c51f124SMoriah Waterland  *			representing the non-global zones full path of a
34045c51f124SMoriah Waterland  *			directory that is inherited from the global zone.
34055c51f124SMoriah Waterland  *		a_zoneName - pointer to string representing the name of the
34065c51f124SMoriah Waterland  *			zone to install the package into.
34075c51f124SMoriah Waterland  *		a_idsName - pointer to string representing the data stream
34085c51f124SMoriah Waterland  *			device (input data stream) containing the package to
34095c51f124SMoriah Waterland  *			be installed.
34105c51f124SMoriah Waterland  *			If this is == NULL the package is assumed to be
34115c51f124SMoriah Waterland  *			spooled in the zone temporary directory.
34125c51f124SMoriah Waterland  *		a_zoneAdminFile - pointer to string representing the admin
34135c51f124SMoriah Waterland  *			file to pass to pkginstall when installing the package.
34145c51f124SMoriah Waterland  *			If this is == NULL no admin file is given to pkginstall.
34155c51f124SMoriah Waterland  *		a_zoneTempDir - pointer to string representing the temporary
34165c51f124SMoriah Waterland  *			directory in which spooled packages can be found if
34175c51f124SMoriah Waterland  *			a_idsName is == NULL.
34185c51f124SMoriah Waterland  *		a_altBinDir - pointer to string representing an alternative
34195c51f124SMoriah Waterland  *			binary location directory to pass to pkginstall.
34205c51f124SMoriah Waterland  *			If this is == NULL no alternative binary location is
34215c51f124SMoriah Waterland  *			passed to pkginstall.
34225c51f124SMoriah Waterland  *		a_scratchName - pointer to string representing the name of the
34235c51f124SMoriah Waterland  *			scratch zone to use for installation.
34245c51f124SMoriah Waterland  *		a_zoneState - state of the zone; must be mounted or running.
3425*62224350SCasper H.S. Dik  *		a_tmpzn - B_TRUE when this zone is booted by the package
3426*62224350SCasper H.S. Dik  *			command or B_FALSE if it was running before.
34275c51f124SMoriah Waterland  * Returns:	void
34285c51f124SMoriah Waterland  * NOTE:	As a side effect, "ckreturn" is called on the result returned
34295c51f124SMoriah Waterland  *		from running 'pkginstall' in the zone; this sets several global
34305c51f124SMoriah Waterland  *		variables which allows the caller to determine the result of
34315c51f124SMoriah Waterland  *		the installation operation.
34325c51f124SMoriah Waterland  */
34335c51f124SMoriah Waterland 
34345c51f124SMoriah Waterland static void
34355c51f124SMoriah Waterland install_in_one_zone(char **a_inheritedPkgDirs, char *a_zoneName,
34365c51f124SMoriah Waterland 	char *a_idsName, char *a_zoneAdminFile, char *a_zoneTempDir,
3437*62224350SCasper H.S. Dik 	char *a_altBinDir, zone_state_t a_zoneState, boolean_t a_tmpzn)
34385c51f124SMoriah Waterland {
34395c51f124SMoriah Waterland 	char	zoneStreamName[PATH_MAX] = {'\0'};
34405c51f124SMoriah Waterland 	int	n;
34415c51f124SMoriah Waterland 
34425c51f124SMoriah Waterland 	/* entry assertions */
34435c51f124SMoriah Waterland 
34445c51f124SMoriah Waterland 	assert(a_zoneName != (char *)NULL);
34455c51f124SMoriah Waterland 	assert(*a_zoneName != '\0');
34465c51f124SMoriah Waterland 
34475c51f124SMoriah Waterland 	/* entry debugging info */
34485c51f124SMoriah Waterland 
34495c51f124SMoriah Waterland 	echoDebug(DBG_INSTINONEZONE_ENTRY);
34505c51f124SMoriah Waterland 	echoDebug(DBG_INSTINONEZONE_ARGS, a_zoneName, PSTR(a_idsName),
34515c51f124SMoriah Waterland 			PSTR(a_zoneAdminFile), PSTR(a_zoneTempDir),
34525c51f124SMoriah Waterland 			PSTR(a_altBinDir));
34535c51f124SMoriah Waterland 
34545c51f124SMoriah Waterland 	/* echo operation to perform to stdout */
34555c51f124SMoriah Waterland 
34565c51f124SMoriah Waterland 	echo(MSG_INSTALL_PKG_IN_ZONE, pkginst, a_zoneName);
34575c51f124SMoriah Waterland 
34585c51f124SMoriah Waterland 	/* determine path to the package stream */
34595c51f124SMoriah Waterland 
34605c51f124SMoriah Waterland 	if (a_idsName == (char *)NULL) {
34615c51f124SMoriah Waterland 		/* locate temp stream created earlier */
34625c51f124SMoriah Waterland 		(void) snprintf(zoneStreamName, sizeof (zoneStreamName),
34635c51f124SMoriah Waterland 			"%s/%s.dstream", a_zoneTempDir, pkginst);
34645c51f124SMoriah Waterland 	} else {
34655c51f124SMoriah Waterland 		/* use stream passed in on command line */
34665c51f124SMoriah Waterland 		(void) snprintf(zoneStreamName, sizeof (zoneStreamName),
34675c51f124SMoriah Waterland 			"%s", a_idsName);
34685c51f124SMoriah Waterland 	}
34695c51f124SMoriah Waterland 
34705c51f124SMoriah Waterland 	echoDebug(DBG_INSTALL_IN_ZONE, pkginst, a_zoneName, zoneStreamName);
34715c51f124SMoriah Waterland 
34725c51f124SMoriah Waterland 	n = pkgZoneInstall(a_zoneName, a_inheritedPkgDirs, a_zoneState,
3473*62224350SCasper H.S. Dik 		zoneStreamName, a_altBinDir, a_zoneAdminFile, a_tmpzn);
34745c51f124SMoriah Waterland 
34755c51f124SMoriah Waterland 	/* set success/fail condition variables */
34765c51f124SMoriah Waterland 
34775c51f124SMoriah Waterland 	ckreturn(n);
34785c51f124SMoriah Waterland 
34795c51f124SMoriah Waterland 	/* exit debugging info */
34805c51f124SMoriah Waterland 
34815c51f124SMoriah Waterland 	echoDebug(DBG_INSTALL_FLAG_VALUES, "after install", admnflag, doreboot,
34825c51f124SMoriah Waterland 		failflag, interrupted, intrflag, ireboot, needconsult,
34835c51f124SMoriah Waterland 		nullflag, warnflag);
34845c51f124SMoriah Waterland }
34855c51f124SMoriah Waterland 
34865c51f124SMoriah Waterland /*
34875c51f124SMoriah Waterland  * Name:	install_in_zones
34885c51f124SMoriah Waterland  * Description:	Install a single package in the zones that are running from
34895c51f124SMoriah Waterland  *		a list of zones
34905c51f124SMoriah Waterland  * Arguments:	a_zlst - list of zones to install the package into
34915c51f124SMoriah Waterland  *		a_idsName - pointer to string representing the data stream
34925c51f124SMoriah Waterland  *			device (input data stream) containing the package to
34935c51f124SMoriah Waterland  *			be installed.
34945c51f124SMoriah Waterland  *			If this is == NULL the package is assumed to be
34955c51f124SMoriah Waterland  *			spooled in the zone temporary directory.
34965c51f124SMoriah Waterland  *		a_altBinDir - pointer to string representing an alternative
34975c51f124SMoriah Waterland  *			binary location directory to pass to pkginstall.
34985c51f124SMoriah Waterland  *			If this is == NULL no alternative binary location is
34995c51f124SMoriah Waterland  *			passed to pkginstall.
35005c51f124SMoriah Waterland  *		a_zoneAdminFile - pointer to string representing the admin
35015c51f124SMoriah Waterland  *			file to pass to pkginstall when installing the package.
35025c51f124SMoriah Waterland  *			If this is == NULL no admin file is given to pkginstall.
35035c51f124SMoriah Waterland  *		a_zoneTempDir - pointer to string representing the temporary
35045c51f124SMoriah Waterland  *			directory in which spooled packages can be found if
35055c51f124SMoriah Waterland  *			a_idsName is == NULL.
35065c51f124SMoriah Waterland  */
35075c51f124SMoriah Waterland 
35085c51f124SMoriah Waterland static int
35095c51f124SMoriah Waterland install_in_zones(zoneList_t a_zlst, char *a_idsName, char *a_altBinDir,
35105c51f124SMoriah Waterland 	char *a_zoneAdminFile, char *a_zoneTempDir)
35115c51f124SMoriah Waterland {
35125c51f124SMoriah Waterland 	char		**inheritedPkgDirs;
35135c51f124SMoriah Waterland 	char		*zoneName;
35145c51f124SMoriah Waterland 	int		zoneIndex;
35155c51f124SMoriah Waterland 	int		zonesSkipped = 0;
35165c51f124SMoriah Waterland 	zone_state_t	zst;
35175c51f124SMoriah Waterland 
35185c51f124SMoriah Waterland 	/* entry assertions */
35195c51f124SMoriah Waterland 
35205c51f124SMoriah Waterland 	assert(a_zlst != (zoneList_t)NULL);
35215c51f124SMoriah Waterland 
35225c51f124SMoriah Waterland 	/* entry debugging info */
35235c51f124SMoriah Waterland 
35245c51f124SMoriah Waterland 	echoDebug(DBG_INSTALLINZONES_ENTRY);
35255c51f124SMoriah Waterland 	echoDebug(DBG_INSTALLINZONES_ARGS, PSTR(a_idsName),
35265c51f124SMoriah Waterland 			PSTR(a_zoneAdminFile), PSTR(a_zoneTempDir));
35275c51f124SMoriah Waterland 
35285c51f124SMoriah Waterland 	/* process each zone in the list */
35295c51f124SMoriah Waterland 
35305c51f124SMoriah Waterland 	for (zoneIndex = 0;
35315c51f124SMoriah Waterland 		(zoneName = z_zlist_get_zonename(a_zlst, zoneIndex)) != NULL;
35325c51f124SMoriah Waterland 		zoneIndex++) {
35335c51f124SMoriah Waterland 
35345c51f124SMoriah Waterland 		/* skip the zone if it is NOT running */
35355c51f124SMoriah Waterland 
35365c51f124SMoriah Waterland 		zst = z_zlist_get_current_state(a_zlst, zoneIndex);
35375c51f124SMoriah Waterland 		if (zst != ZONE_STATE_RUNNING && zst != ZONE_STATE_MOUNTED) {
35385c51f124SMoriah Waterland 			zonesSkipped++;
35395c51f124SMoriah Waterland 			echoDebug(DBG_SKIPPING_ZONE, zoneName);
35405c51f124SMoriah Waterland 			continue;
35415c51f124SMoriah Waterland 		}
35425c51f124SMoriah Waterland 
35435c51f124SMoriah Waterland 		/* determine list of directories inherited from global zone */
35445c51f124SMoriah Waterland 
35455c51f124SMoriah Waterland 		inheritedPkgDirs = z_zlist_get_inherited_pkg_dirs(a_zlst,
35465c51f124SMoriah Waterland 					zoneIndex);
35475c51f124SMoriah Waterland 
35485c51f124SMoriah Waterland 		/* install the package in this zone */
35495c51f124SMoriah Waterland 
35505c51f124SMoriah Waterland 		install_in_one_zone(inheritedPkgDirs,
35515c51f124SMoriah Waterland 		    z_zlist_get_scratch(a_zlst, zoneIndex), a_idsName,
3552*62224350SCasper H.S. Dik 		    a_zoneAdminFile, a_zoneTempDir, a_altBinDir, zst, B_FALSE);
35535c51f124SMoriah Waterland 	}
35545c51f124SMoriah Waterland 
35555c51f124SMoriah Waterland 	return (zonesSkipped);
35565c51f124SMoriah Waterland }
35575c51f124SMoriah Waterland 
35585c51f124SMoriah Waterland /*
35595c51f124SMoriah Waterland  * Name:	boot_and_install_in_zones
35605c51f124SMoriah Waterland  * Description:	Install a single package in the zones that are NOT running from
35615c51f124SMoriah Waterland  *		a list of zones - each zone is booted, the package installed,
35625c51f124SMoriah Waterland  *		and the zone is halted
35635c51f124SMoriah Waterland  * Arguments:	a_zlst - list of zones to install the package into
35645c51f124SMoriah Waterland  *		a_idsName - pointer to string representing the data stream
35655c51f124SMoriah Waterland  *			device (input data stream) containing the package to
35665c51f124SMoriah Waterland  *			be installed.
35675c51f124SMoriah Waterland  *			If this is == NULL the package is assumed to be
35685c51f124SMoriah Waterland  *			spooled in the zone temporary directory.
35695c51f124SMoriah Waterland  *		a_altBinDir - pointer to string representing an alternative
35705c51f124SMoriah Waterland  *			binary location directory to pass to pkginstall.
35715c51f124SMoriah Waterland  *			If this is == NULL no alternative binary location is
35725c51f124SMoriah Waterland  *			passed to pkginstall.
35735c51f124SMoriah Waterland  *		a_zoneAdminFile - pointer to string representing the admin
35745c51f124SMoriah Waterland  *			file to pass to pkginstall when installing the package.
35755c51f124SMoriah Waterland  *			If this is == NULL no admin file is given to pkginstall.
35765c51f124SMoriah Waterland  *		a_zoneTempDir - pointer to string representing the temporary
35775c51f124SMoriah Waterland  *			directory in which spooled packages can be found if
35785c51f124SMoriah Waterland  *			a_idsName is == NULL.
35795c51f124SMoriah Waterland  */
35805c51f124SMoriah Waterland 
35815c51f124SMoriah Waterland static int
35825c51f124SMoriah Waterland boot_and_install_in_zones(zoneList_t a_zlst, char *a_idsName, char *a_altBinDir,
35835c51f124SMoriah Waterland 	char *a_zoneAdminFile, char *a_zoneTempDir)
35845c51f124SMoriah Waterland {
35855c51f124SMoriah Waterland 	boolean_t	b;
35865c51f124SMoriah Waterland 	char		**inheritedPkgDirs;
35875c51f124SMoriah Waterland 	char		*zoneName;
35885c51f124SMoriah Waterland 	int		zoneIndex;
35895c51f124SMoriah Waterland 	int		zonesSkipped = 0;
35905c51f124SMoriah Waterland 	zone_state_t	zst;
35915c51f124SMoriah Waterland 
35925c51f124SMoriah Waterland 	/* entry assertions */
35935c51f124SMoriah Waterland 
35945c51f124SMoriah Waterland 	assert(a_zlst != (zoneList_t)NULL);
35955c51f124SMoriah Waterland 
35965c51f124SMoriah Waterland 	/* entry debugging info */
35975c51f124SMoriah Waterland 
35985c51f124SMoriah Waterland 	echoDebug(DBG_BOOTINSTALLINZONES_ENTRY);
35995c51f124SMoriah Waterland 	echoDebug(DBG_BOOTINSTALLINZONES_ARGS, PSTR(a_idsName),
36005c51f124SMoriah Waterland 			PSTR(a_zoneAdminFile), PSTR(a_zoneTempDir));
36015c51f124SMoriah Waterland 
36025c51f124SMoriah Waterland 	/* process each zone in the list */
36035c51f124SMoriah Waterland 
36045c51f124SMoriah Waterland 	for (zoneIndex = 0;
36055c51f124SMoriah Waterland 		(zoneName = z_zlist_get_zonename(a_zlst, zoneIndex)) != NULL;
36065c51f124SMoriah Waterland 		zoneIndex++) {
36075c51f124SMoriah Waterland 
36085c51f124SMoriah Waterland 		/* skip the zone if it IS running */
36095c51f124SMoriah Waterland 
36105c51f124SMoriah Waterland 		zst = z_zlist_get_current_state(a_zlst, zoneIndex);
36115c51f124SMoriah Waterland 		if (zst == ZONE_STATE_RUNNING || zst == ZONE_STATE_MOUNTED) {
36125c51f124SMoriah Waterland 			echoDebug(DBG_SKIPPING_ZONE_BOOT, zoneName);
36135c51f124SMoriah Waterland 			continue;
36145c51f124SMoriah Waterland 		}
36155c51f124SMoriah Waterland 
36165c51f124SMoriah Waterland 		/* skip the zone if it is NOT bootable */
36175c51f124SMoriah Waterland 
36185c51f124SMoriah Waterland 		if (z_zlist_is_zone_runnable(a_zlst, zoneIndex) == B_FALSE) {
36195c51f124SMoriah Waterland 			echo(MSG_SKIPPING_ZONE_NOT_RUNNABLE, zoneName);
36205c51f124SMoriah Waterland 			echoDebug(DBG_SKIPPING_ZONE_NOT_RUNNABLE, zoneName);
36215c51f124SMoriah Waterland 			continue;
36225c51f124SMoriah Waterland 		}
36235c51f124SMoriah Waterland 
36245c51f124SMoriah Waterland 		/* mount up the zone */
36255c51f124SMoriah Waterland 
36265c51f124SMoriah Waterland 		echo(MSG_BOOTING_ZONE, zoneName);
36275c51f124SMoriah Waterland 		echoDebug(DBG_BOOTING_ZONE, zoneName);
36285c51f124SMoriah Waterland 
36295c51f124SMoriah Waterland 		b = z_zlist_change_zone_state(a_zlst, zoneIndex,
36305c51f124SMoriah Waterland 					ZONE_STATE_MOUNTED);
36315c51f124SMoriah Waterland 		if (b == B_FALSE) {
36325c51f124SMoriah Waterland 			progerr(ERR_CANNOT_BOOT_ZONE, zoneName);
36335c51f124SMoriah Waterland 			/* set fatal error return condition */
36345c51f124SMoriah Waterland 			ckreturn(1);
36355c51f124SMoriah Waterland 			zonesSkipped++;
36365c51f124SMoriah Waterland 			continue;
36375c51f124SMoriah Waterland 		}
36385c51f124SMoriah Waterland 
36395c51f124SMoriah Waterland 		/* determine list of directories inherited from global zone */
36405c51f124SMoriah Waterland 
36415c51f124SMoriah Waterland 		inheritedPkgDirs = z_zlist_get_inherited_pkg_dirs(a_zlst,
36425c51f124SMoriah Waterland 					zoneIndex);
36435c51f124SMoriah Waterland 
36445c51f124SMoriah Waterland 		/* install the package in this zone */
36455c51f124SMoriah Waterland 
36465c51f124SMoriah Waterland 		install_in_one_zone(inheritedPkgDirs,
36475c51f124SMoriah Waterland 		    z_zlist_get_scratch(a_zlst, zoneIndex), a_idsName,
36485c51f124SMoriah Waterland 		    a_zoneAdminFile, a_zoneTempDir, a_altBinDir,
3649*62224350SCasper H.S. Dik 		    ZONE_STATE_MOUNTED, B_TRUE);
36505c51f124SMoriah Waterland 
36515c51f124SMoriah Waterland 		/* restore original state of zone */
36525c51f124SMoriah Waterland 
36535c51f124SMoriah Waterland 		echo(MSG_RESTORE_ZONE_STATE, zoneName);
36545c51f124SMoriah Waterland 		echoDebug(DBG_RESTORE_ZONE_STATE, zoneName);
36555c51f124SMoriah Waterland 
36565c51f124SMoriah Waterland 		b = z_zlist_restore_zone_state(a_zlst, zoneIndex);
36575c51f124SMoriah Waterland 	}
36585c51f124SMoriah Waterland 
36595c51f124SMoriah Waterland 	return (zonesSkipped);
36605c51f124SMoriah Waterland }
36615c51f124SMoriah Waterland 
36625c51f124SMoriah Waterland /*
36635c51f124SMoriah Waterland  * Name:	pkginstall_check_in_one_zone
36645c51f124SMoriah Waterland  * Description:	Do a pre install check of a single package in a single zone
36655c51f124SMoriah Waterland  * Arguments:	a_inheritedPkgDirs - pointer to array of strings, each one
36665c51f124SMoriah Waterland  *			representing the non-global zones full path of a
36675c51f124SMoriah Waterland  *			directory that is inherited from the global zone.
36685c51f124SMoriah Waterland  *		a_zoneName - pointer to string representing the name of the
36695c51f124SMoriah Waterland  *			zone to check install the package in.
36705c51f124SMoriah Waterland  *		a_idsName - pointer to string representing the data stream
36715c51f124SMoriah Waterland  *			device (input data stream) containing the package to
36725c51f124SMoriah Waterland  *			be check installed.
36735c51f124SMoriah Waterland  *			If this is == NULL the package is assumed to be
36745c51f124SMoriah Waterland  *			spooled in the zone temporary directory.
36755c51f124SMoriah Waterland  *		a_zoneAdminFile - pointer to string representing the admin
36765c51f124SMoriah Waterland  *			file to pass to pkginstall when installing the package.
36775c51f124SMoriah Waterland  *			If this is == NULL no admin file is given to pkginstall.
36785c51f124SMoriah Waterland  *		a_zoneTempDir - pointer to string representing the temporary
36795c51f124SMoriah Waterland  *			directory in which spooled packages can be found if
36805c51f124SMoriah Waterland  *			a_idsName is == NULL.
36815c51f124SMoriah Waterland  *		a_altBinDir - pointer to string representing an alternative
36825c51f124SMoriah Waterland  *			binary location directory to pass to pkginstall.
36835c51f124SMoriah Waterland  *			If this is == NULL no alternative binary location is
36845c51f124SMoriah Waterland  *			passed to pkginstall.
36855c51f124SMoriah Waterland  *		a_scratchName - pointer to string representing the name of the
36865c51f124SMoriah Waterland  *			scratch zone to use for installation.
36875c51f124SMoriah Waterland  *		a_zoneState - state of the zone; must be mounted or running.
3688*62224350SCasper H.S. Dik  *		a_tmpzn - B_TRUE when this zone is booted by the package
3689*62224350SCasper H.S. Dik  *			command or B_FALSE if it was running before.
36905c51f124SMoriah Waterland  * Returns:	void
36915c51f124SMoriah Waterland  * NOTE:	As a side effect, "ckreturn" is called on the result returned
36925c51f124SMoriah Waterland  *		from running 'pkginstall' in the zone; this sets several global
36935c51f124SMoriah Waterland  *		variables which allows the caller to determine the result of
36945c51f124SMoriah Waterland  *		the pre installation check operation.
36955c51f124SMoriah Waterland  */
36965c51f124SMoriah Waterland 
36975c51f124SMoriah Waterland static void
36985c51f124SMoriah Waterland pkginstall_check_in_one_zone(char **a_inheritedPkgDirs, char *a_zoneName,
36995c51f124SMoriah Waterland 	char *a_idsName, char *a_zoneAdminFile, char *a_zoneTempDir,
3700*62224350SCasper H.S. Dik 	char *a_altBinDir, char *a_scratchName, zone_state_t a_zoneState,
3701*62224350SCasper H.S. Dik 	boolean_t a_tmpzn)
37025c51f124SMoriah Waterland {
37035c51f124SMoriah Waterland 	char	preinstallcheckPath[PATH_MAX+1];
37045c51f124SMoriah Waterland 	char	zoneStreamName[PATH_MAX] = {'\0'};
37055c51f124SMoriah Waterland 	int	n;
37065c51f124SMoriah Waterland 
37075c51f124SMoriah Waterland 	echo(MSG_CHECKINSTALL_PKG_IN_ZONE, pkginst, a_zoneName);
37085c51f124SMoriah Waterland 	echoDebug(MSG_CHECKINSTALL_PKG_IN_ZONE, pkginst, a_zoneName);
37095c51f124SMoriah Waterland 
37105c51f124SMoriah Waterland 	(void) snprintf(preinstallcheckPath, sizeof (preinstallcheckPath),
37115c51f124SMoriah Waterland 		"%s/%s.%s.preinstallcheck.txt", a_zoneTempDir, pkginst,
37125c51f124SMoriah Waterland 		a_zoneName);
37135c51f124SMoriah Waterland 
37145c51f124SMoriah Waterland 	if (a_idsName == (char *)NULL) {
37155c51f124SMoriah Waterland 		/* locate temporary stream created earlier */
37165c51f124SMoriah Waterland 		(void) snprintf(zoneStreamName, sizeof (zoneStreamName),
37175c51f124SMoriah Waterland 			"%s/%s.dstream", a_zoneTempDir, pkginst);
37185c51f124SMoriah Waterland 	} else {
37195c51f124SMoriah Waterland 		(void) snprintf(zoneStreamName, sizeof (zoneStreamName),
37205c51f124SMoriah Waterland 			"%s", a_idsName);
37215c51f124SMoriah Waterland 	}
37225c51f124SMoriah Waterland 
37235c51f124SMoriah Waterland 	echoDebug(DBG_CHECKINSTALL_IN_ZONE, pkginst, a_zoneName,
37245c51f124SMoriah Waterland 						zoneStreamName);
37255c51f124SMoriah Waterland 
37265c51f124SMoriah Waterland 	n = pkgZoneCheckInstall(a_scratchName, a_inheritedPkgDirs,
37275c51f124SMoriah Waterland 	    a_zoneState, zoneStreamName, a_altBinDir, a_zoneAdminFile,
3728*62224350SCasper H.S. Dik 	    preinstallcheckPath, a_tmpzn);
37295c51f124SMoriah Waterland 
37305c51f124SMoriah Waterland 	/* set success/fail condition variables */
37315c51f124SMoriah Waterland 
37325c51f124SMoriah Waterland 	ckreturn(n);
37335c51f124SMoriah Waterland 
37345c51f124SMoriah Waterland 	echoDebug(DBG_INSTALL_FLAG_VALUES, "after preinstall check",
37355c51f124SMoriah Waterland 		admnflag, doreboot, failflag, interrupted, intrflag,
37365c51f124SMoriah Waterland 		ireboot, needconsult, nullflag, warnflag);
37375c51f124SMoriah Waterland }
37385c51f124SMoriah Waterland 
37395c51f124SMoriah Waterland /*
37405c51f124SMoriah Waterland  * Name:	pkginstall_check_in_zones
37415c51f124SMoriah Waterland  * Description:	Check installation of a single package in the zones that
37425c51f124SMoriah Waterland  *		are running from a list of zones
37435c51f124SMoriah Waterland  * Arguments:	a_zlst - list of zones to check install the package
37445c51f124SMoriah Waterland  *		a_idsName - pointer to string representing the data stream
37455c51f124SMoriah Waterland  *			device (input data stream) containing the package to
37465c51f124SMoriah Waterland  *			be check installed.
37475c51f124SMoriah Waterland  *			If this is == NULL the package is assumed to be
37485c51f124SMoriah Waterland  *			spooled in the zone temporary directory.
37495c51f124SMoriah Waterland  *		a_altBinDir - pointer to string representing an alternative
37505c51f124SMoriah Waterland  *			binary location directory to pass to pkginstall.
37515c51f124SMoriah Waterland  *			If this is == NULL no alternative binary location is
37525c51f124SMoriah Waterland  *			passed to pkginstall.
37535c51f124SMoriah Waterland  *		a_zoneAdminFile - pointer to string representing the admin
37545c51f124SMoriah Waterland  *			file to pass to pkginstall when checking the installing
37555c51f124SMoriah Waterland  *			of the package.
37565c51f124SMoriah Waterland  *			If this is == NULL no admin file is given to pkginstall.
37575c51f124SMoriah Waterland  *		a_zoneTempDir - pointer to string representing the temporary
37585c51f124SMoriah Waterland  *			directory in which spooled packages can be found if
37595c51f124SMoriah Waterland  *			a_idsName is == NULL.
37605c51f124SMoriah Waterland  */
37615c51f124SMoriah Waterland 
37625c51f124SMoriah Waterland static int
37635c51f124SMoriah Waterland pkginstall_check_in_zones(zoneList_t a_zlst, char *a_idsName, char *a_altBinDir,
37645c51f124SMoriah Waterland 	char *a_zoneAdminFile, char *a_zoneTempDir)
37655c51f124SMoriah Waterland {
37665c51f124SMoriah Waterland 	char		**inheritedPkgDirs;
37675c51f124SMoriah Waterland 	char		*zoneName;
37685c51f124SMoriah Waterland 	int		zoneIndex;
37695c51f124SMoriah Waterland 	int		zonesSkipped = 0;
37705c51f124SMoriah Waterland 	zone_state_t	zst;
37715c51f124SMoriah Waterland 
37725c51f124SMoriah Waterland 	for (zoneIndex = 0;
37735c51f124SMoriah Waterland 		(zoneName = z_zlist_get_zonename(a_zlst, zoneIndex)) != NULL;
37745c51f124SMoriah Waterland 		zoneIndex++) {
37755c51f124SMoriah Waterland 
37765c51f124SMoriah Waterland 		zst = z_zlist_get_current_state(a_zlst, zoneIndex);
37775c51f124SMoriah Waterland 		if (zst != ZONE_STATE_RUNNING && zst != ZONE_STATE_MOUNTED) {
37785c51f124SMoriah Waterland 			zonesSkipped++;
37795c51f124SMoriah Waterland 			echoDebug(DBG_SKIPPING_ZONE, zoneName);
37805c51f124SMoriah Waterland 			continue;
37815c51f124SMoriah Waterland 		}
37825c51f124SMoriah Waterland 
37835c51f124SMoriah Waterland 		inheritedPkgDirs = z_zlist_get_inherited_pkg_dirs(a_zlst,
37845c51f124SMoriah Waterland 					zoneIndex);
37855c51f124SMoriah Waterland 
37865c51f124SMoriah Waterland 		pkginstall_check_in_one_zone(inheritedPkgDirs, zoneName,
37875c51f124SMoriah Waterland 		    a_idsName, a_zoneAdminFile, a_zoneTempDir, a_altBinDir,
3788*62224350SCasper H.S. Dik 		    z_zlist_get_scratch(a_zlst, zoneIndex), zst, B_FALSE);
37895c51f124SMoriah Waterland 	}
37905c51f124SMoriah Waterland 
37915c51f124SMoriah Waterland 	return (zonesSkipped);
37925c51f124SMoriah Waterland }
37935c51f124SMoriah Waterland 
37945c51f124SMoriah Waterland /*
37955c51f124SMoriah Waterland  * Name:	boot_and_pkginstall_check_in_zones
37965c51f124SMoriah Waterland  * Description:	Check installation of a single package in the zones that
37975c51f124SMoriah Waterland  *		are NOT running from a list of zones - each zone is booted,
37985c51f124SMoriah Waterland  *		the package installation is checked, and the zone is halted.
37995c51f124SMoriah Waterland  * Arguments:	a_zlst - list of zones to install the package into
38005c51f124SMoriah Waterland  *		a_idsName - pointer to string representing the data stream
38015c51f124SMoriah Waterland  *			device (input data stream) containing the package to
38025c51f124SMoriah Waterland  *			be check installed.
38035c51f124SMoriah Waterland  *			If this is == NULL the package is assumed to be
38045c51f124SMoriah Waterland  *			spooled in the zone temporary directory.
38055c51f124SMoriah Waterland  *		a_altBinDir - pointer to string representing an alternative
38065c51f124SMoriah Waterland  *			binary location directory to pass to pkginstall.
38075c51f124SMoriah Waterland  *			If this is == NULL no alternative binary location is
38085c51f124SMoriah Waterland  *			passed to pkginstall.
38095c51f124SMoriah Waterland  *		a_zoneAdminFile - pointer to string representing the admin
38105c51f124SMoriah Waterland  *			file to pass to pkginstall when check installing the
38115c51f124SMoriah Waterland  *			package.
38125c51f124SMoriah Waterland  *			If this is == NULL no admin file is given to pkginstall.
38135c51f124SMoriah Waterland  *		a_zoneTempDir - pointer to string representing the temporary
38145c51f124SMoriah Waterland  *			directory in which spooled packages can be found if
38155c51f124SMoriah Waterland  *			a_idsName is == NULL.
38165c51f124SMoriah Waterland  */
38175c51f124SMoriah Waterland 
38185c51f124SMoriah Waterland static int
38195c51f124SMoriah Waterland boot_and_pkginstall_check_in_zones(zoneList_t a_zlst, char *a_idsName,
38205c51f124SMoriah Waterland 	char *a_altBinDir, char *a_zoneAdminFile, char *a_zoneTempDir)
38215c51f124SMoriah Waterland {
38225c51f124SMoriah Waterland 	int		zoneIndex;
38235c51f124SMoriah Waterland 	int		zonesSkipped = 0;
38245c51f124SMoriah Waterland 	char		*zoneName;
38255c51f124SMoriah Waterland 	boolean_t	b;
38265c51f124SMoriah Waterland 	char		**inheritedPkgDirs;
38275c51f124SMoriah Waterland 	zone_state_t	zst;
38285c51f124SMoriah Waterland 
38295c51f124SMoriah Waterland 	/* entry assertions */
38305c51f124SMoriah Waterland 
38315c51f124SMoriah Waterland 	assert(a_zlst != (zoneList_t)NULL);
38325c51f124SMoriah Waterland 
38335c51f124SMoriah Waterland 	/* entry debugging info */
38345c51f124SMoriah Waterland 
38355c51f124SMoriah Waterland 	echoDebug(DBG_BOOTCHECKINSTALLINZONES_ENTRY);
38365c51f124SMoriah Waterland 	echoDebug(DBG_BOOTCHECKINSTALLINZONES_ARGS, PSTR(a_idsName),
38375c51f124SMoriah Waterland 			PSTR(a_zoneAdminFile), PSTR(a_zoneTempDir));
38385c51f124SMoriah Waterland 
38395c51f124SMoriah Waterland 	/* process each zone in the list */
38405c51f124SMoriah Waterland 
38415c51f124SMoriah Waterland 	for (zoneIndex = 0;
38425c51f124SMoriah Waterland 		(zoneName = z_zlist_get_zonename(a_zlst, zoneIndex)) != NULL;
38435c51f124SMoriah Waterland 		zoneIndex++) {
38445c51f124SMoriah Waterland 
38455c51f124SMoriah Waterland 		/* skip the zone if it IS running */
38465c51f124SMoriah Waterland 
38475c51f124SMoriah Waterland 		zst = z_zlist_get_current_state(a_zlst, zoneIndex);
38485c51f124SMoriah Waterland 		if (zst == ZONE_STATE_RUNNING || zst == ZONE_STATE_MOUNTED) {
38495c51f124SMoriah Waterland 			echoDebug(DBG_SKIPPING_ZONE_BOOT, zoneName);
38505c51f124SMoriah Waterland 			continue;
38515c51f124SMoriah Waterland 		}
38525c51f124SMoriah Waterland 
38535c51f124SMoriah Waterland 		/* skip the zone if it is NOT bootable */
38545c51f124SMoriah Waterland 
38555c51f124SMoriah Waterland 		if (z_zlist_is_zone_runnable(a_zlst, zoneIndex) == B_FALSE) {
38565c51f124SMoriah Waterland 			echo(MSG_SKIPPING_ZONE_NOT_RUNNABLE, zoneName);
38575c51f124SMoriah Waterland 			echoDebug(DBG_SKIPPING_ZONE_NOT_RUNNABLE, zoneName);
38585c51f124SMoriah Waterland 			continue;
38595c51f124SMoriah Waterland 		}
38605c51f124SMoriah Waterland 
38615c51f124SMoriah Waterland 		/* mount up the zone */
38625c51f124SMoriah Waterland 
38635c51f124SMoriah Waterland 		echo(MSG_BOOTING_ZONE, zoneName);
38645c51f124SMoriah Waterland 		echoDebug(DBG_BOOTING_ZONE, zoneName);
38655c51f124SMoriah Waterland 
38665c51f124SMoriah Waterland 		b = z_zlist_change_zone_state(a_zlst, zoneIndex,
38675c51f124SMoriah Waterland 		    ZONE_STATE_MOUNTED);
38685c51f124SMoriah Waterland 		if (b == B_FALSE) {
38695c51f124SMoriah Waterland 			progerr(ERR_CANNOT_BOOT_ZONE, zoneName);
38705c51f124SMoriah Waterland 			/* set fatal error return condition */
38715c51f124SMoriah Waterland 			ckreturn(1);
38725c51f124SMoriah Waterland 			zonesSkipped++;
38735c51f124SMoriah Waterland 			continue;
38745c51f124SMoriah Waterland 		}
38755c51f124SMoriah Waterland 
38765c51f124SMoriah Waterland 		/* determine list of directories inherited from global zone */
38775c51f124SMoriah Waterland 
38785c51f124SMoriah Waterland 		inheritedPkgDirs = z_zlist_get_inherited_pkg_dirs(a_zlst,
38795c51f124SMoriah Waterland 					zoneIndex);
38805c51f124SMoriah Waterland 
38815c51f124SMoriah Waterland 		/* pre-installation check of the package in this zone */
38825c51f124SMoriah Waterland 
38835c51f124SMoriah Waterland 		pkginstall_check_in_one_zone(inheritedPkgDirs, zoneName,
38845c51f124SMoriah Waterland 		    a_idsName, a_zoneAdminFile, a_zoneTempDir, a_altBinDir,
38855c51f124SMoriah Waterland 		    z_zlist_get_scratch(a_zlst, zoneIndex),
3886*62224350SCasper H.S. Dik 		    ZONE_STATE_MOUNTED, B_TRUE);
38875c51f124SMoriah Waterland 
38885c51f124SMoriah Waterland 		/* restore original state of zone */
38895c51f124SMoriah Waterland 
38905c51f124SMoriah Waterland 		echo(MSG_RESTORE_ZONE_STATE, zoneName);
38915c51f124SMoriah Waterland 		echoDebug(DBG_RESTORE_ZONE_STATE, zoneName);
38925c51f124SMoriah Waterland 
38935c51f124SMoriah Waterland 		b = z_zlist_restore_zone_state(a_zlst, zoneIndex);
38945c51f124SMoriah Waterland 	}
38955c51f124SMoriah Waterland 
38965c51f124SMoriah Waterland 	return (zonesSkipped);
38975c51f124SMoriah Waterland }
38985c51f124SMoriah Waterland 
38995c51f124SMoriah Waterland /*
39005c51f124SMoriah Waterland  * Function:	add_packages_in_global_with_zones
39015c51f124SMoriah Waterland  * Description: call this function to add a list of packages in the global zone
39025c51f124SMoriah Waterland  *		when one or more non-global zones exist
39035c51f124SMoriah Waterland  * returns:
39045c51f124SMoriah Waterland  *	B_TRUE to process next data stream
39055c51f124SMoriah Waterland  *	B_FALSE to exit
39065c51f124SMoriah Waterland  */
39075c51f124SMoriah Waterland 
39085c51f124SMoriah Waterland static boolean_t
39095c51f124SMoriah Waterland add_packages_in_global_with_zones(char **a_pkgList, char *a_uri,
39105c51f124SMoriah Waterland 	char *a_idsName, int a_repeat, char *a_altBinDir,
39115c51f124SMoriah Waterland 	char *a_device, zoneList_t a_zlst)
39125c51f124SMoriah Waterland {
39135c51f124SMoriah Waterland static	char		*zoneTempDir = (char *)NULL;
39145c51f124SMoriah Waterland static	char		*zoneAdminFile = (char *)NULL;
39155c51f124SMoriah Waterland 
39165c51f124SMoriah Waterland 	boolean_t	b;
39175c51f124SMoriah Waterland 	char		*packageDir;
39185c51f124SMoriah Waterland 	char		instdir[PATH_MAX];
39195c51f124SMoriah Waterland 	char		respfile_path[PATH_MAX];
39205c51f124SMoriah Waterland 	char		zoneStreamName[PATH_MAX] = {'\0'};
39215c51f124SMoriah Waterland 	int		i;
39225c51f124SMoriah Waterland 	int		n;
39235c51f124SMoriah Waterland 	int		savenpkgs = npkgs;
39245c51f124SMoriah Waterland 	int		zonesSkipped;
39255c51f124SMoriah Waterland 	boolean_t	globalPresent;
39265c51f124SMoriah Waterland 
39275c51f124SMoriah Waterland 	/* entry assertions */
39285c51f124SMoriah Waterland 
39295c51f124SMoriah Waterland 	assert(a_pkgList != (char **)NULL);
39305c51f124SMoriah Waterland 	assert(a_zlst != (zoneList_t)NULL);
39315c51f124SMoriah Waterland 
39325c51f124SMoriah Waterland 	echoDebug(DBG_ADDPACKAGES_GZ_W_LZ_ENTRY);
39335c51f124SMoriah Waterland 	echoDebug(DBG_ADDPACKAGES_GZ_W_LZ_ARGS, npkgs, PSTR(a_uri),
39345c51f124SMoriah Waterland 			PSTR(a_idsName), a_repeat, PSTR(a_device));
39355c51f124SMoriah Waterland 
39365c51f124SMoriah Waterland 	/* create temporary directory for use by zone operations */
39375c51f124SMoriah Waterland 
39385c51f124SMoriah Waterland 	create_zone_tempdir(&zoneTempDir, tmpdir);
39395c51f124SMoriah Waterland 
39405c51f124SMoriah Waterland 	/* create hands off settings admin file for use in a non-global zone */
39415c51f124SMoriah Waterland 
39425c51f124SMoriah Waterland 	create_zone_adminfile(&zoneAdminFile, zoneTempDir, admnfile);
39435c51f124SMoriah Waterland 
39445c51f124SMoriah Waterland 	/* determine directory where packages can be found */
39455c51f124SMoriah Waterland 
39465c51f124SMoriah Waterland 	if (a_idsName == (char *)NULL) {
39475c51f124SMoriah Waterland 		/* no stream - directory containing packages provided */
39485c51f124SMoriah Waterland 		packageDir = pkgdev.dirname;
39495c51f124SMoriah Waterland 	} else {
39505c51f124SMoriah Waterland 		packageDir = zoneTempDir;
39515c51f124SMoriah Waterland 	}
39525c51f124SMoriah Waterland 
39535c51f124SMoriah Waterland 	/* unpack and check all packages */
39545c51f124SMoriah Waterland 
39555c51f124SMoriah Waterland 	b = unpack_and_check_packages(a_pkgList, a_idsName, packageDir);
39565c51f124SMoriah Waterland 	if (b != B_TRUE) {
39575c51f124SMoriah Waterland 		quit(1);
39585c51f124SMoriah Waterland 	}
39595c51f124SMoriah Waterland 
39605c51f124SMoriah Waterland 	/*
39615c51f124SMoriah Waterland 	 * if the packages are contained in a directory, convert the
39625c51f124SMoriah Waterland 	 * packages into individual streams because pkgZoneInstall is only able
39635c51f124SMoriah Waterland 	 * to pass a stream to the non-global zone's pkginstall command.
39645c51f124SMoriah Waterland 	 * After this code is executed:
39655c51f124SMoriah Waterland 	 * if the original input was a datastream:
39665c51f124SMoriah Waterland 	 * -> that datastream has been unpacked into "instdir"
39675c51f124SMoriah Waterland 	 * if the original input was a directory with packages in it:
39685c51f124SMoriah Waterland 	 * -> those packages have been placed into a single datastream
39695c51f124SMoriah Waterland 	 */
39705c51f124SMoriah Waterland 
39715c51f124SMoriah Waterland 	if (a_idsName == (char *)NULL) {
39725c51f124SMoriah Waterland 		for (i = 0; (pkginst = a_pkgList[i]) != NULL; i++) {
39735c51f124SMoriah Waterland 			char	*pkgs[2];
39745c51f124SMoriah Waterland 
39755c51f124SMoriah Waterland 			/* package is not a stream - create one */
39765c51f124SMoriah Waterland 
39775c51f124SMoriah Waterland 			(void) snprintf(zoneStreamName, sizeof (zoneStreamName),
39785c51f124SMoriah Waterland 				"%s/%s.dstream", zoneTempDir, pkginst);
39795c51f124SMoriah Waterland 
39805c51f124SMoriah Waterland 			echoDebug(DBG_CONVERTING_PKG, packageDir, pkginst,
39815c51f124SMoriah Waterland 				zoneStreamName);
39825c51f124SMoriah Waterland 
39835c51f124SMoriah Waterland 			/* set up list of packages to be this package only */
39845c51f124SMoriah Waterland 
39855c51f124SMoriah Waterland 			pkgs[0] = pkginst;
39865c51f124SMoriah Waterland 			pkgs[1] = (char *)NULL;
39875c51f124SMoriah Waterland 
39885c51f124SMoriah Waterland 			n = pkgtrans(packageDir, zoneStreamName, pkgs,
39895c51f124SMoriah Waterland 					PT_SILENT|PT_ODTSTREAM, NULL, NULL);
39905c51f124SMoriah Waterland 			if (n != 0) {
39915c51f124SMoriah Waterland 				progerr(ERR_CANNOT_CONVERT_PKGSTRM,
39925c51f124SMoriah Waterland 					pkginst, packageDir, zoneStreamName);
39935c51f124SMoriah Waterland 				quit(1);
39945c51f124SMoriah Waterland 			}
39955c51f124SMoriah Waterland 			npkgs--;
39965c51f124SMoriah Waterland 		}
39975c51f124SMoriah Waterland 		npkgs = savenpkgs;
39985c51f124SMoriah Waterland 	}
39995c51f124SMoriah Waterland 
40005c51f124SMoriah Waterland 	/*
40015c51f124SMoriah Waterland 	 * Phase I - run collect dependency information for all packages for all
40025c51f124SMoriah Waterland 	 * zones - this involves running pkginstall with the "preinstallcheck"
40035c51f124SMoriah Waterland 	 * option which causes all dependency checks to be performed without
40045c51f124SMoriah Waterland 	 * actually doing the installation of the packages. This information is
40055c51f124SMoriah Waterland 	 * gathered in the zone temporary directory and is used later to present
40065c51f124SMoriah Waterland 	 * the dependency check results to the system administrator depending
40075c51f124SMoriah Waterland 	 * on the administration settings.
40085c51f124SMoriah Waterland 	 */
40095c51f124SMoriah Waterland 
40105c51f124SMoriah Waterland 	for (i = 0; (pkginst = a_pkgList[i]) != NULL; i++) {
40115c51f124SMoriah Waterland 
40125c51f124SMoriah Waterland 		/* reset interrupted flag before calling pkginstall */
40135c51f124SMoriah Waterland 
40145c51f124SMoriah Waterland 		interrupted = 0;	/* last action was NOT quit */
40155c51f124SMoriah Waterland 
40165c51f124SMoriah Waterland 		/*
40175c51f124SMoriah Waterland 		 * if this package is marked "install in this zone only", then
40185c51f124SMoriah Waterland 		 * do not check dependencies in any other zone
40195c51f124SMoriah Waterland 		 */
40205c51f124SMoriah Waterland 
40215c51f124SMoriah Waterland 		if (pkgPackageIsThisZone(pkginst) == B_TRUE) {
40225c51f124SMoriah Waterland 			echoDebug(DBG_VERIFY_SKIP_THISZONE, pkginst);
40235c51f124SMoriah Waterland 			npkgs--;
40245c51f124SMoriah Waterland 			continue;
40255c51f124SMoriah Waterland 		}
40265c51f124SMoriah Waterland 
40275c51f124SMoriah Waterland 		/*
40285c51f124SMoriah Waterland 		 * if operation failed in global zone do not propagate
40295c51f124SMoriah Waterland 		 * to any non-global zones
40305c51f124SMoriah Waterland 		 */
40315c51f124SMoriah Waterland 
40325c51f124SMoriah Waterland 		if (interrupted != 0) {
40335c51f124SMoriah Waterland 			echo(MSG_CHECKINSTALL_INTERRUPT_B4_Z, pkginst);
40345c51f124SMoriah Waterland 			echoDebug(MSG_CHECKINSTALL_INTERRUPT_B4_Z, pkginst);
40355c51f124SMoriah Waterland 			break;
40365c51f124SMoriah Waterland 		}
40375c51f124SMoriah Waterland 
40385c51f124SMoriah Waterland 		echoDebug(DBG_INSTALL_FLAG_VALUES, "after pkginstall",
40395c51f124SMoriah Waterland 			admnflag, doreboot, failflag, interrupted, intrflag,
40405c51f124SMoriah Waterland 			ireboot, needconsult, nullflag, warnflag);
40415c51f124SMoriah Waterland 
40425c51f124SMoriah Waterland 		/*
40435c51f124SMoriah Waterland 		 * call pkginstall to verify this package for all non-global
40445c51f124SMoriah Waterland 		 * zones that are currently booted
40455c51f124SMoriah Waterland 		 */
40465c51f124SMoriah Waterland 
40475c51f124SMoriah Waterland 		zonesSkipped = pkginstall_check_in_zones(a_zlst, a_idsName,
40485c51f124SMoriah Waterland 				a_altBinDir, admnfile, zoneTempDir);
40495c51f124SMoriah Waterland 
40505c51f124SMoriah Waterland 		/*
40515c51f124SMoriah Waterland 		 * if any zones were skipped (becuase they are not currently
40525c51f124SMoriah Waterland 		 * booted), boot each zone one at a time and call pkginstall
40535c51f124SMoriah Waterland 		 * to verify this package for each such non-global zone
40545c51f124SMoriah Waterland 		 */
40555c51f124SMoriah Waterland 
40565c51f124SMoriah Waterland 		if (zonesSkipped > 0) {
40575c51f124SMoriah Waterland 			echoDebug(DBG_ZONES_SKIPPED, zonesSkipped);
40585c51f124SMoriah Waterland 
40595c51f124SMoriah Waterland 			zonesSkipped =
40605c51f124SMoriah Waterland 				boot_and_pkginstall_check_in_zones(a_zlst,
40615c51f124SMoriah Waterland 				a_idsName, a_altBinDir, admnfile,
40625c51f124SMoriah Waterland 				zoneTempDir);
40635c51f124SMoriah Waterland 
40645c51f124SMoriah Waterland 			if (zonesSkipped > 0) {
40655c51f124SMoriah Waterland 				progerr(ERR_INSTALL_ZONES_SKIPPED,
40665c51f124SMoriah Waterland 							zonesSkipped);
40675c51f124SMoriah Waterland 			}
40685c51f124SMoriah Waterland 		}
40695c51f124SMoriah Waterland 
40705c51f124SMoriah Waterland 		npkgs--;
40715c51f124SMoriah Waterland 	}
40725c51f124SMoriah Waterland 
40735c51f124SMoriah Waterland 	/*
40745c51f124SMoriah Waterland 	 * At this point, all of the dependency information has been gathered
40755c51f124SMoriah Waterland 	 * and is ready to be analyzed. This function processes all of that
40765c51f124SMoriah Waterland 	 * dependency information and presents the results to the system
40775c51f124SMoriah Waterland 	 * administrator, depending on the current administration settings.
40785c51f124SMoriah Waterland 	 */
40795c51f124SMoriah Waterland 
40805c51f124SMoriah Waterland 	i = preinstall_verify(a_pkgList, a_zlst, zoneTempDir);
40815c51f124SMoriah Waterland 	if (i != 0) {
40825c51f124SMoriah Waterland 		/* dependency checks failed - exit */
40835c51f124SMoriah Waterland 		quit(i);
40845c51f124SMoriah Waterland 	}
40855c51f124SMoriah Waterland 
40865c51f124SMoriah Waterland 	npkgs = savenpkgs;
40875c51f124SMoriah Waterland 
40885c51f124SMoriah Waterland 	/*
40895c51f124SMoriah Waterland 	 * reset all error return condition variables that may have been
40905c51f124SMoriah Waterland 	 * set during package installation dependency checking so that they
40915c51f124SMoriah Waterland 	 * do not reflect on the success/failure of the actual package
40925c51f124SMoriah Waterland 	 * installation operations
40935c51f124SMoriah Waterland 	 */
40945c51f124SMoriah Waterland 
40955c51f124SMoriah Waterland 	resetreturn();
40965c51f124SMoriah Waterland 
40975c51f124SMoriah Waterland 	/*
40985c51f124SMoriah Waterland 	 * At this point, all of the dependency checking is completed, and
40995c51f124SMoriah Waterland 	 * the installation of the packages can proceed. Install each package
41005c51f124SMoriah Waterland 	 * one at a time, starting with the global zone, and the for each
41015c51f124SMoriah Waterland 	 * non-global zone that is booted, and then for each non-global zone
41025c51f124SMoriah Waterland 	 * that is not currently booted.
41035c51f124SMoriah Waterland 	 */
41045c51f124SMoriah Waterland 
41055c51f124SMoriah Waterland 	globalPresent = z_on_zone_spec(GLOBAL_ZONENAME);
41065c51f124SMoriah Waterland 
41075c51f124SMoriah Waterland 	for (i = 0; (pkginst = a_pkgList[i]) != NULL; i++) {
41085c51f124SMoriah Waterland 		/*
41095c51f124SMoriah Waterland 		 * if immediate reboot required from last package and this is
41105c51f124SMoriah Waterland 		 * not 'pkgask' then suspend installation of remaining packages
41115c51f124SMoriah Waterland 		 */
41125c51f124SMoriah Waterland 
41135c51f124SMoriah Waterland 		if ((ireboot != 0) && (askflag == 0)) {
41145c51f124SMoriah Waterland 			ptext(stderr, MSG_SUSPEND_ADD, pkginst);
41155c51f124SMoriah Waterland 				continue;
41165c51f124SMoriah Waterland 		}
41175c51f124SMoriah Waterland 
41185c51f124SMoriah Waterland 		/*
41195c51f124SMoriah Waterland 		 * handle interrupt if the previous pkginstall was interrupted
41205c51f124SMoriah Waterland 		 */
41215c51f124SMoriah Waterland 
41225c51f124SMoriah Waterland 		if (continue_installation() == B_FALSE) {
41235c51f124SMoriah Waterland 			return (B_FALSE);
41245c51f124SMoriah Waterland 		}
41255c51f124SMoriah Waterland 
41265c51f124SMoriah Waterland 		/*
41275c51f124SMoriah Waterland 		 * if pkgask, handle response file creation:
41285c51f124SMoriah Waterland 		 * - if the response file is a directory, then create a path to
41295c51f124SMoriah Waterland 		 * -- a package instance within the response file directory.
41305c51f124SMoriah Waterland 		 * - If the response file is NOT a directory, if more than one
41315c51f124SMoriah Waterland 		 * -- package is to be installed.
41325c51f124SMoriah Waterland 		 */
41335c51f124SMoriah Waterland 
41345c51f124SMoriah Waterland 		if ((askflag != 0) && (respdir != (char *)NULL)) {
41355c51f124SMoriah Waterland 			(void) snprintf(respfile_path, sizeof (respfile_path),
41365c51f124SMoriah Waterland 					"%s/%s", respdir, pkginst);
41375c51f124SMoriah Waterland 			respfile = respfile_path;
41385c51f124SMoriah Waterland 		}
41395c51f124SMoriah Waterland 
41405c51f124SMoriah Waterland 		echo(MSG_PROC_INST, pkginst,
41415c51f124SMoriah Waterland 			(a_uri && a_idsName) ? a_uri : a_device);
41425c51f124SMoriah Waterland 
41435c51f124SMoriah Waterland 		/*
41445c51f124SMoriah Waterland 		 * If we're installing another package in the same
41455c51f124SMoriah Waterland 		 * session, the second through nth pkginstall, must
41465c51f124SMoriah Waterland 		 * continue from where the prior one left off. For this
41475c51f124SMoriah Waterland 		 * reason, the continuation feature (implied by the
41485c51f124SMoriah Waterland 		 * nature of the command) is used for the remaining
41495c51f124SMoriah Waterland 		 * packages.
41505c51f124SMoriah Waterland 		 */
41515c51f124SMoriah Waterland 
41525c51f124SMoriah Waterland 		if ((i == 1) && (pkgdrtarg != (char *)NULL)) {
41535c51f124SMoriah Waterland 			pkgcontsrc = pkgdrtarg;
41545c51f124SMoriah Waterland 		}
41555c51f124SMoriah Waterland 
41565c51f124SMoriah Waterland 		if (globalPresent) {
41575c51f124SMoriah Waterland 			/*
41585c51f124SMoriah Waterland 			 * call pkginstall for this package for the global zone
41595c51f124SMoriah Waterland 			 */
41605c51f124SMoriah Waterland 
41615c51f124SMoriah Waterland 			echo(MSG_INSTALLING_PKG_IN_GZ, pkginst);
41625c51f124SMoriah Waterland 
41635c51f124SMoriah Waterland 			/* reset interrupted flag before calling pkginstall */
41645c51f124SMoriah Waterland 
41655c51f124SMoriah Waterland 			interrupted = 0;	/* last action was NOT quit */
41665c51f124SMoriah Waterland 
41675c51f124SMoriah Waterland 			n = pkgInstall(get_inst_root(), NULL, packageDir,
41685c51f124SMoriah Waterland 			    a_altBinDir,  NULL);
41695c51f124SMoriah Waterland 
41705c51f124SMoriah Waterland 			/* set success/fail condition variables */
41715c51f124SMoriah Waterland 
41725c51f124SMoriah Waterland 			ckreturn(n);
41735c51f124SMoriah Waterland 
41745c51f124SMoriah Waterland 			/*
41755c51f124SMoriah Waterland 			 * if operation failed in global zone do not propagate
41765c51f124SMoriah Waterland 			 * to any non-global zones
41775c51f124SMoriah Waterland 			 */
41785c51f124SMoriah Waterland 
41795c51f124SMoriah Waterland 			if (interrupted != 0) {
41805c51f124SMoriah Waterland 				echo(MSG_INSTALL_INTERRUPT_B4_ZONES, pkginst);
41815c51f124SMoriah Waterland 				echoDebug(MSG_INSTALL_INTERRUPT_B4_ZONES,
41825c51f124SMoriah Waterland 				    pkginst);
41835c51f124SMoriah Waterland 				break;
41845c51f124SMoriah Waterland 			}
41855c51f124SMoriah Waterland 		}
41865c51f124SMoriah Waterland 
41875c51f124SMoriah Waterland 		/*
41885c51f124SMoriah Waterland 		 * if this package is marked "install in this zone only",
41895c51f124SMoriah Waterland 		 * then only need to install the package in the global zone;
41905c51f124SMoriah Waterland 		 * skip installation in any non-global zones.
41915c51f124SMoriah Waterland 		 */
41925c51f124SMoriah Waterland 
41935c51f124SMoriah Waterland 		if (pkgPackageIsThisZone(pkginst) == B_TRUE) {
41945c51f124SMoriah Waterland 			echoDebug(DBG_INSTALL_SKIP_THISZONE, pkginst);
41955c51f124SMoriah Waterland 			npkgs--;
41965c51f124SMoriah Waterland 			continue;
41975c51f124SMoriah Waterland 		}
41985c51f124SMoriah Waterland 
41995c51f124SMoriah Waterland 		echoDebug(DBG_INSTALL_FLAG_VALUES, "install in running zones",
42005c51f124SMoriah Waterland 			admnflag, doreboot, failflag, interrupted, intrflag,
42015c51f124SMoriah Waterland 			ireboot, needconsult, nullflag, warnflag);
42025c51f124SMoriah Waterland 
42035c51f124SMoriah Waterland 		/* install package in currently booted zones */
42045c51f124SMoriah Waterland 
42055c51f124SMoriah Waterland 		zonesSkipped = install_in_zones(a_zlst, a_idsName, a_altBinDir,
42065c51f124SMoriah Waterland 					zoneAdminFile, zoneTempDir);
42075c51f124SMoriah Waterland 
42085c51f124SMoriah Waterland 		/* install package in zones that are not currently booted */
42095c51f124SMoriah Waterland 
42105c51f124SMoriah Waterland 		if (zonesSkipped > 0) {
42115c51f124SMoriah Waterland 			echoDebug(DBG_ZONES_SKIPPED, zonesSkipped);
42125c51f124SMoriah Waterland 
42135c51f124SMoriah Waterland 			zonesSkipped = boot_and_install_in_zones(a_zlst,
42145c51f124SMoriah Waterland 				a_idsName, a_altBinDir, zoneAdminFile,
42155c51f124SMoriah Waterland 				zoneTempDir);
42165c51f124SMoriah Waterland 
42175c51f124SMoriah Waterland 			if (zonesSkipped > 0) {
42185c51f124SMoriah Waterland 				progerr(ERR_INSTALL_ZONES_SKIPPED,
42195c51f124SMoriah Waterland 							zonesSkipped);
42205c51f124SMoriah Waterland 			}
42215c51f124SMoriah Waterland 		}
42225c51f124SMoriah Waterland 
42235c51f124SMoriah Waterland 		/*
42245c51f124SMoriah Waterland 		 * package completely installed - remove any temporary stream
42255c51f124SMoriah Waterland 		 * of the package that might have been created
42265c51f124SMoriah Waterland 		 */
42275c51f124SMoriah Waterland 
42285c51f124SMoriah Waterland 		if (a_idsName == (char *)NULL) {
42295c51f124SMoriah Waterland 			/* locate temporary stream created earlier */
42305c51f124SMoriah Waterland 			(void) snprintf(zoneStreamName, sizeof (zoneStreamName),
42315c51f124SMoriah Waterland 				"%s/%s.dstream", zoneTempDir, pkginst);
42325c51f124SMoriah Waterland 			/* remove stream - no longer needed */
42335c51f124SMoriah Waterland 			echoDebug(DBG_REMOVING_DSTREAM_PKGDIR, zoneStreamName,
42345c51f124SMoriah Waterland 					pkginst);
42355c51f124SMoriah Waterland 			(void) remove(zoneStreamName);
42365c51f124SMoriah Waterland 		} else {
42375c51f124SMoriah Waterland 			/* remove package - no longer needed */
42385c51f124SMoriah Waterland 			if (snprintf(instdir, sizeof (instdir), "%s/%s",
42395c51f124SMoriah Waterland 					zoneTempDir, pkginst) >= PATH_MAX) {
42405c51f124SMoriah Waterland 				progerr(ERR_CANNOT_CREATE_PKGPATH, tmpdir);
42415c51f124SMoriah Waterland 				quit(1);
42425c51f124SMoriah Waterland 			}
42435c51f124SMoriah Waterland 			echoDebug(DBG_REMOVING_PKG_TMPDIR, instdir, pkginst);
42445c51f124SMoriah Waterland 			(void) remove(instdir);
42455c51f124SMoriah Waterland 		}
42465c51f124SMoriah Waterland 
42475c51f124SMoriah Waterland 		/* decrement number of packages left to install */
42485c51f124SMoriah Waterland 
42495c51f124SMoriah Waterland 		npkgs--;
42505c51f124SMoriah Waterland 
42515c51f124SMoriah Waterland 		/*
42525c51f124SMoriah Waterland 		 * if no packages left to install, unmount package source
42535c51f124SMoriah Waterland 		 * device if appropriate
42545c51f124SMoriah Waterland 		 */
42555c51f124SMoriah Waterland 
42565c51f124SMoriah Waterland 		if ((npkgs <= 0) && (pkgdev.mount || a_idsName)) {
42575c51f124SMoriah Waterland 			(void) chdir("/");
42585c51f124SMoriah Waterland 			if (!a_idsName) {
42595c51f124SMoriah Waterland 				echoDebug(DBG_UNMOUNTING_DEV,
42605c51f124SMoriah Waterland 							PSTR(pkgdev.mount));
42615c51f124SMoriah Waterland 				(void) pkgumount(&pkgdev);
42625c51f124SMoriah Waterland 			}
42635c51f124SMoriah Waterland 		}
42645c51f124SMoriah Waterland 	}
42655c51f124SMoriah Waterland 
42665c51f124SMoriah Waterland 	/*
42675c51f124SMoriah Waterland 	 * all packages in the package list have been installed.
42685c51f124SMoriah Waterland 	 * Continue with installation if:
42695c51f124SMoriah Waterland 	 * -- immediate reboot is NOT required
42705c51f124SMoriah Waterland 	 * -- there are more packages to install
42715c51f124SMoriah Waterland 	 * -- the package source is a path to a file
42725c51f124SMoriah Waterland 	 * else return do NOT continue.
42735c51f124SMoriah Waterland 	 */
42745c51f124SMoriah Waterland 
42755c51f124SMoriah Waterland 	if ((ireboot == 0) && (a_repeat != 0) &&
42765c51f124SMoriah Waterland 		(pkgdev.pathname == (char *)NULL)) {
42775c51f124SMoriah Waterland 		return (B_TRUE);
42785c51f124SMoriah Waterland 	}
42795c51f124SMoriah Waterland 
42805c51f124SMoriah Waterland 	/* return 'dont continue' */
42815c51f124SMoriah Waterland 
42825c51f124SMoriah Waterland 	return (B_FALSE);
42835c51f124SMoriah Waterland }
42845c51f124SMoriah Waterland 
42855c51f124SMoriah Waterland /*
42865c51f124SMoriah Waterland  * Function:	add_packages_in_nonglobal_zone
42875c51f124SMoriah Waterland  * Description: call this function to add a list of packages in a non-global
42885c51f124SMoriah Waterland  *		zone
42895c51f124SMoriah Waterland  * returns:
42905c51f124SMoriah Waterland  *	B_TRUE to process next data stream
42915c51f124SMoriah Waterland  *	B_FALSE to exit
42925c51f124SMoriah Waterland  */
42935c51f124SMoriah Waterland 
42945c51f124SMoriah Waterland static boolean_t
42955c51f124SMoriah Waterland add_packages_in_nonglobal_zone(char **a_pkgList, char *a_uri,
42965c51f124SMoriah Waterland 	char *a_idsName, int a_repeat, char *a_altBinDir, char *a_device)
42975c51f124SMoriah Waterland {
42985c51f124SMoriah Waterland static	char		*zoneTempDir = (char *)NULL;
42995c51f124SMoriah Waterland 
43005c51f124SMoriah Waterland 	char		*packageDir;
43015c51f124SMoriah Waterland 	char		respfile_path[PATH_MAX];
43025c51f124SMoriah Waterland 	int		i;
43035c51f124SMoriah Waterland 	int		n;
43045c51f124SMoriah Waterland 	boolean_t	b;
43055c51f124SMoriah Waterland 	int		savenpkgs = npkgs;
43065c51f124SMoriah Waterland 
43075c51f124SMoriah Waterland 	/* entry assertions */
43085c51f124SMoriah Waterland 
43095c51f124SMoriah Waterland 	assert(a_pkgList != (char **)NULL);
43105c51f124SMoriah Waterland 
43115c51f124SMoriah Waterland 	/* entry debugging info */
43125c51f124SMoriah Waterland 
43135c51f124SMoriah Waterland 	echoDebug(DBG_ADDPACKAGES_LZ_ENTRY);
43145c51f124SMoriah Waterland 	echoDebug(DBG_ADDPACKAGES_LZ_ARGS, npkgs, PSTR(a_uri), PSTR(a_idsName),
43155c51f124SMoriah Waterland 		a_repeat, PSTR(a_device));
43165c51f124SMoriah Waterland 
43175c51f124SMoriah Waterland 	/* create temporary directory for use by zone operations */
43185c51f124SMoriah Waterland 
43195c51f124SMoriah Waterland 	create_zone_tempdir(&zoneTempDir, tmpdir);
43205c51f124SMoriah Waterland 
43215c51f124SMoriah Waterland 	/*
43225c51f124SMoriah Waterland 	 * package can be in a number of formats:
43235c51f124SMoriah Waterland 	 * - file containing package stream (pkgadd -d file [pkgs])
43245c51f124SMoriah Waterland 	 * - directory containing packages (pkgadd -d /dir [pkgs])
43255c51f124SMoriah Waterland 	 * - device containing packages (pkgadd -d diskette1 [pkgs])
43265c51f124SMoriah Waterland 	 * non-global zones can be passed open file drescriptors and
43275c51f124SMoriah Waterland 	 * strings as arguments
43285c51f124SMoriah Waterland 	 * - for file containing package stream
43295c51f124SMoriah Waterland 	 * -- the stream can be passed directly to the non-global zone
43305c51f124SMoriah Waterland 	 * - for directory
43315c51f124SMoriah Waterland 	 * -- convert packages to datastream to pass to the non-global zone
43325c51f124SMoriah Waterland 	 * - for device
43335c51f124SMoriah Waterland 	 */
43345c51f124SMoriah Waterland 
43355c51f124SMoriah Waterland 	/* determine directory where packages can be found */
43365c51f124SMoriah Waterland 
43375c51f124SMoriah Waterland 	if (a_idsName == (char *)NULL) {
43385c51f124SMoriah Waterland 		/* no stream - directory containing packages provided */
43395c51f124SMoriah Waterland 		packageDir = pkgdev.dirname;
43405c51f124SMoriah Waterland 	} else {
43415c51f124SMoriah Waterland 		packageDir = zoneTempDir;
43425c51f124SMoriah Waterland 	}
43435c51f124SMoriah Waterland 
43445c51f124SMoriah Waterland 	b = unpack_and_check_packages(a_pkgList, a_idsName, packageDir);
43455c51f124SMoriah Waterland 	if (b != B_TRUE) {
43465c51f124SMoriah Waterland 		quit(1);
43475c51f124SMoriah Waterland 	}
43485c51f124SMoriah Waterland 
43495c51f124SMoriah Waterland 	/*
43505c51f124SMoriah Waterland 	 * this is the main loop where all of the packages (as listed in the
43515c51f124SMoriah Waterland 	 * package list) are added one at a time.
43525c51f124SMoriah Waterland 	 */
43535c51f124SMoriah Waterland 
43545c51f124SMoriah Waterland 	for (i = 0; (pkginst = a_pkgList[i]) != NULL; i++) {
43555c51f124SMoriah Waterland 		npkgs--;
43565c51f124SMoriah Waterland 	}
43575c51f124SMoriah Waterland 
43585c51f124SMoriah Waterland 	npkgs = savenpkgs;
43595c51f124SMoriah Waterland 
43605c51f124SMoriah Waterland 	/*
43615c51f124SMoriah Waterland 	 * this is the main loop where all of the packages (as listed in the
43625c51f124SMoriah Waterland 	 * package list) are added one at a time.
43635c51f124SMoriah Waterland 	 */
43645c51f124SMoriah Waterland 
43655c51f124SMoriah Waterland 	for (i = 0; (pkginst = a_pkgList[i]) != NULL; i++) {
43665c51f124SMoriah Waterland 		/*
43675c51f124SMoriah Waterland 		 * if immediate reboot required from last package and this is
43685c51f124SMoriah Waterland 		 * not 'pkgask' then suspend installation of remaining packages
43695c51f124SMoriah Waterland 		 */
43705c51f124SMoriah Waterland 
43715c51f124SMoriah Waterland 		if ((ireboot != 0) && (askflag == 0)) {
43725c51f124SMoriah Waterland 			ptext(stderr, MSG_SUSPEND_ADD, pkginst);
43735c51f124SMoriah Waterland 				continue;
43745c51f124SMoriah Waterland 		}
43755c51f124SMoriah Waterland 
43765c51f124SMoriah Waterland 		/*
43775c51f124SMoriah Waterland 		 * handle interrupt if the previous pkginstall was interrupted
43785c51f124SMoriah Waterland 		 */
43795c51f124SMoriah Waterland 
43805c51f124SMoriah Waterland 		if (continue_installation() == B_FALSE) {
43815c51f124SMoriah Waterland 			return (B_FALSE);
43825c51f124SMoriah Waterland 		}
43835c51f124SMoriah Waterland 
43845c51f124SMoriah Waterland 		/*
43855c51f124SMoriah Waterland 		 * if pkgask, handle response file creation:
43865c51f124SMoriah Waterland 		 * - if the response file is a directory, then create a path to
43875c51f124SMoriah Waterland 		 * -- a package instance within the response file directory.
43885c51f124SMoriah Waterland 		 * - If the response file is NOT a directory, if more than one
43895c51f124SMoriah Waterland 		 * -- package is to be installed.
43905c51f124SMoriah Waterland 		 */
43915c51f124SMoriah Waterland 
43925c51f124SMoriah Waterland 		if ((askflag != 0) && (respdir != (char *)NULL)) {
43935c51f124SMoriah Waterland 			(void) snprintf(respfile_path, sizeof (respfile_path),
43945c51f124SMoriah Waterland 					"%s/%s", respdir, pkginst);
43955c51f124SMoriah Waterland 			respfile = respfile_path;
43965c51f124SMoriah Waterland 		}
43975c51f124SMoriah Waterland 
43985c51f124SMoriah Waterland 		echo(MSG_PROC_INST, pkginst,
43995c51f124SMoriah Waterland 			(a_uri && a_idsName) ? a_uri : a_device);
44005c51f124SMoriah Waterland 
44015c51f124SMoriah Waterland 		/*
44025c51f124SMoriah Waterland 		 * If we're installing another package in the same
44035c51f124SMoriah Waterland 		 * session, the second through nth pkginstall, must
44045c51f124SMoriah Waterland 		 * continue from where the prior one left off. For this
44055c51f124SMoriah Waterland 		 * reason, the continuation feature (implied by the
44065c51f124SMoriah Waterland 		 * nature of the command) is used for the remaining
44075c51f124SMoriah Waterland 		 * packages.
44085c51f124SMoriah Waterland 		 */
44095c51f124SMoriah Waterland 
44105c51f124SMoriah Waterland 		if ((i == 1) && (pkgdrtarg != (char *)NULL)) {
44115c51f124SMoriah Waterland 			pkgcontsrc = pkgdrtarg;
44125c51f124SMoriah Waterland 		}
44135c51f124SMoriah Waterland 
44145c51f124SMoriah Waterland 		/* reset interrupted flag before calling pkginstall */
44155c51f124SMoriah Waterland 
44165c51f124SMoriah Waterland 		interrupted = 0;	/* last action was NOT quit */
44175c51f124SMoriah Waterland 
44185c51f124SMoriah Waterland 		/* call pkginstall for this package */
44195c51f124SMoriah Waterland 
44205c51f124SMoriah Waterland 		n = pkgInstall(get_inst_root(), NULL,
44215c51f124SMoriah Waterland 				packageDir, a_altBinDir,
44225c51f124SMoriah Waterland 				(char **)NULL);
44235c51f124SMoriah Waterland 
44245c51f124SMoriah Waterland 		/* set success/fail condition variables */
44255c51f124SMoriah Waterland 
44265c51f124SMoriah Waterland 		ckreturn(n);
44275c51f124SMoriah Waterland 
44285c51f124SMoriah Waterland 		/* decrement number of packages left to install */
44295c51f124SMoriah Waterland 
44305c51f124SMoriah Waterland 		npkgs--;
44315c51f124SMoriah Waterland 
44325c51f124SMoriah Waterland 		/*
44335c51f124SMoriah Waterland 		 * if no packages left to install, unmount package source
44345c51f124SMoriah Waterland 		 * device if appropriate
44355c51f124SMoriah Waterland 		 */
44365c51f124SMoriah Waterland 
44375c51f124SMoriah Waterland 		if ((npkgs <= 0) && (pkgdev.mount || a_idsName)) {
44385c51f124SMoriah Waterland 			(void) chdir("/");
44395c51f124SMoriah Waterland 			if (!a_idsName) {
44405c51f124SMoriah Waterland 				(void) pkgumount(&pkgdev);
44415c51f124SMoriah Waterland 			}
44425c51f124SMoriah Waterland 		}
44435c51f124SMoriah Waterland 	}
44445c51f124SMoriah Waterland 
44455c51f124SMoriah Waterland 	/*
44465c51f124SMoriah Waterland 	 * all packages in the package list have been installed.
44475c51f124SMoriah Waterland 	 * Continue with installation if:
44485c51f124SMoriah Waterland 	 * -- immediate reboot is NOT required
44495c51f124SMoriah Waterland 	 * -- there are more packages to install
44505c51f124SMoriah Waterland 	 * -- the package source is a path to a file
44515c51f124SMoriah Waterland 	 * else return do NOT continue.
44525c51f124SMoriah Waterland 	 */
44535c51f124SMoriah Waterland 
44545c51f124SMoriah Waterland 	if ((ireboot == 0) && (a_repeat != 0) &&
44555c51f124SMoriah Waterland 		(pkgdev.pathname == (char *)NULL)) {
44565c51f124SMoriah Waterland 		return (B_TRUE);
44575c51f124SMoriah Waterland 	}
44585c51f124SMoriah Waterland 
44595c51f124SMoriah Waterland 	/* return 'dont continue' */
44605c51f124SMoriah Waterland 
44615c51f124SMoriah Waterland 	return (B_FALSE);
44625c51f124SMoriah Waterland }
44635c51f124SMoriah Waterland 
44645c51f124SMoriah Waterland /*
44655c51f124SMoriah Waterland  * Function:	add_packages_in_global_no_zones
44665c51f124SMoriah Waterland  * Description: call this function to add a list of packages in the global zone
44675c51f124SMoriah Waterland  *		when no non-global zones exist
44685c51f124SMoriah Waterland  * returns:
44695c51f124SMoriah Waterland  *	B_TRUE to process next data stream
44705c51f124SMoriah Waterland  *	B_FALSE to exit
44715c51f124SMoriah Waterland  */
44725c51f124SMoriah Waterland 
44735c51f124SMoriah Waterland static boolean_t
44745c51f124SMoriah Waterland add_packages_in_global_no_zones(char **a_pkgList, char *a_uri,
44755c51f124SMoriah Waterland 	char *a_idsName, int a_repeat, char *a_altBinDir, char *a_device)
44765c51f124SMoriah Waterland {
44775c51f124SMoriah Waterland 	int		n;
44785c51f124SMoriah Waterland 	int		i;
44795c51f124SMoriah Waterland 	char		respfile_path[PATH_MAX];
44805c51f124SMoriah Waterland 	CAF_T		flags = 0;
44815c51f124SMoriah Waterland 
44825c51f124SMoriah Waterland 	/* entry assertions */
44835c51f124SMoriah Waterland 
44845c51f124SMoriah Waterland 	assert(a_pkgList != (char **)NULL);
44855c51f124SMoriah Waterland 
44865c51f124SMoriah Waterland 	echoDebug(DBG_ADDPACKAGES_GZ_NO_LZ_ENTRY);
44875c51f124SMoriah Waterland 	echoDebug(DBG_ADDPACKAGES_GZ_NO_LZ_ARGS, npkgs, PSTR(a_uri),
44885c51f124SMoriah Waterland 		PSTR(a_idsName), a_repeat, PSTR(a_device));
44895c51f124SMoriah Waterland 
44905c51f124SMoriah Waterland 	/*
44915c51f124SMoriah Waterland 	 * set flags for applicability check
44925c51f124SMoriah Waterland 	 */
44935c51f124SMoriah Waterland 
44945c51f124SMoriah Waterland 	/* in the global zone */
44955c51f124SMoriah Waterland 
44965c51f124SMoriah Waterland 	flags |= CAF_IN_GLOBAL_ZONE;
44975c51f124SMoriah Waterland 
44985c51f124SMoriah Waterland 	/* set -G flag */
44995c51f124SMoriah Waterland 
45005c51f124SMoriah Waterland 	if (globalZoneOnly == B_TRUE) {
45015c51f124SMoriah Waterland 		flags |= CAF_SCOPE_GLOBAL;
45025c51f124SMoriah Waterland 	}
45035c51f124SMoriah Waterland 
45045c51f124SMoriah Waterland 	/*
45055c51f124SMoriah Waterland 	 * this is the main loop where all of the packages (as listed in the
45065c51f124SMoriah Waterland 	 * package list) are added one at a time.
45075c51f124SMoriah Waterland 	 */
45085c51f124SMoriah Waterland 
45095c51f124SMoriah Waterland 	for (i = 0; (pkginst = a_pkgList[i]) != NULL; i++) {
45105c51f124SMoriah Waterland 		/*
45115c51f124SMoriah Waterland 		 * if immediate reboot required from last package and this is
45125c51f124SMoriah Waterland 		 * not 'pkgask' then suspend installation of remaining packages
45135c51f124SMoriah Waterland 		 */
45145c51f124SMoriah Waterland 
45155c51f124SMoriah Waterland 		if ((ireboot != 0) && (askflag == 0)) {
45165c51f124SMoriah Waterland 			ptext(stderr, MSG_SUSPEND_ADD, pkginst);
45175c51f124SMoriah Waterland 				continue;
45185c51f124SMoriah Waterland 		}
45195c51f124SMoriah Waterland 
45205c51f124SMoriah Waterland 		/*
45215c51f124SMoriah Waterland 		 * handle interrupt if the previous pkginstall was interrupted
45225c51f124SMoriah Waterland 		 */
45235c51f124SMoriah Waterland 
45245c51f124SMoriah Waterland 		if (continue_installation() == B_FALSE) {
45255c51f124SMoriah Waterland 			return (B_FALSE);
45265c51f124SMoriah Waterland 		}
45275c51f124SMoriah Waterland 
45285c51f124SMoriah Waterland 		/*
45295c51f124SMoriah Waterland 		 * check package applicability to install in this context
45305c51f124SMoriah Waterland 		 */
45315c51f124SMoriah Waterland 
45325c51f124SMoriah Waterland 		if (check_applicability(pkgdev.dirname,
45335c51f124SMoriah Waterland 			pkginst, get_inst_root(), flags) == B_FALSE) {
45345c51f124SMoriah Waterland 			progerr(ERR_PKG_NOT_APPLICABLE, pkginst);
45355c51f124SMoriah Waterland 			quit(1);
45365c51f124SMoriah Waterland 		}
45375c51f124SMoriah Waterland 
45385c51f124SMoriah Waterland 		/*
45395c51f124SMoriah Waterland 		 * if pkgask, handle response file creation:
45405c51f124SMoriah Waterland 		 * - if the response file is a directory, then create a path to
45415c51f124SMoriah Waterland 		 * -- a package instance within the response file directory.
45425c51f124SMoriah Waterland 		 * - If the response file is NOT a directory, if more than one
45435c51f124SMoriah Waterland 		 * -- package is to be installed.
45445c51f124SMoriah Waterland 		 */
45455c51f124SMoriah Waterland 
45465c51f124SMoriah Waterland 		if ((askflag != 0) && (respdir != (char *)NULL)) {
45475c51f124SMoriah Waterland 			(void) snprintf(respfile_path, sizeof (respfile_path),
45485c51f124SMoriah Waterland 					"%s/%s", respdir, pkginst);
45495c51f124SMoriah Waterland 			respfile = respfile_path;
45505c51f124SMoriah Waterland 		}
45515c51f124SMoriah Waterland 
45525c51f124SMoriah Waterland 		echo(MSG_PROC_INST, pkginst,
45535c51f124SMoriah Waterland 			(a_uri && a_idsName) ? a_uri : a_device);
45545c51f124SMoriah Waterland 
45555c51f124SMoriah Waterland 		/*
45565c51f124SMoriah Waterland 		 * If we're installing another package in the same
45575c51f124SMoriah Waterland 		 * session, the second through nth pkginstall, must
45585c51f124SMoriah Waterland 		 * continue from where the prior one left off. For this
45595c51f124SMoriah Waterland 		 * reason, the continuation feature (implied by the
45605c51f124SMoriah Waterland 		 * nature of the command) is used for the remaining
45615c51f124SMoriah Waterland 		 * packages.
45625c51f124SMoriah Waterland 		 */
45635c51f124SMoriah Waterland 
45645c51f124SMoriah Waterland 		if ((i == 1) && (pkgdrtarg != (char *)NULL)) {
45655c51f124SMoriah Waterland 			pkgcontsrc = pkgdrtarg;
45665c51f124SMoriah Waterland 		}
45675c51f124SMoriah Waterland 
45685c51f124SMoriah Waterland 		/* reset interrupted flag before calling pkginstall */
45695c51f124SMoriah Waterland 
45705c51f124SMoriah Waterland 		interrupted = 0;	/* last action was NOT quit */
45715c51f124SMoriah Waterland 
45725c51f124SMoriah Waterland 		/* call pkginstall for this package */
45735c51f124SMoriah Waterland 
45745c51f124SMoriah Waterland 		n = pkgInstall(get_inst_root(), a_idsName,
45755c51f124SMoriah Waterland 				pkgdev.dirname, a_altBinDir,
45765c51f124SMoriah Waterland 				z_get_inherited_file_systems());
45775c51f124SMoriah Waterland 
45785c51f124SMoriah Waterland 		/* set success/fail condition variables */
45795c51f124SMoriah Waterland 
45805c51f124SMoriah Waterland 		ckreturn(n);
45815c51f124SMoriah Waterland 
45825c51f124SMoriah Waterland 		/* decrement number of packages left to install */
45835c51f124SMoriah Waterland 
45845c51f124SMoriah Waterland 		npkgs--;
45855c51f124SMoriah Waterland 
45865c51f124SMoriah Waterland 		/*
45875c51f124SMoriah Waterland 		 * if no packages left to install, unmount package source
45885c51f124SMoriah Waterland 		 * device if appropriate
45895c51f124SMoriah Waterland 		 */
45905c51f124SMoriah Waterland 
45915c51f124SMoriah Waterland 		if ((npkgs <= 0) && (pkgdev.mount || a_idsName)) {
45925c51f124SMoriah Waterland 			(void) chdir("/");
45935c51f124SMoriah Waterland 			if (!a_idsName) {
45945c51f124SMoriah Waterland 				(void) pkgumount(&pkgdev);
45955c51f124SMoriah Waterland 			}
45965c51f124SMoriah Waterland 		}
45975c51f124SMoriah Waterland 	}
45985c51f124SMoriah Waterland 
45995c51f124SMoriah Waterland 	/*
46005c51f124SMoriah Waterland 	 * all packages in the package list have been installed.
46015c51f124SMoriah Waterland 	 * Continue with installation if:
46025c51f124SMoriah Waterland 	 * -- immediate reboot is NOT required
46035c51f124SMoriah Waterland 	 * -- there are more packages to install
46045c51f124SMoriah Waterland 	 * -- the package source is a path to a file
46055c51f124SMoriah Waterland 	 * else return do NOT continue.
46065c51f124SMoriah Waterland 	 */
46075c51f124SMoriah Waterland 
46085c51f124SMoriah Waterland 	if ((ireboot == 0) && (a_repeat != 0) &&
46095c51f124SMoriah Waterland 		(pkgdev.pathname == (char *)NULL)) {
46105c51f124SMoriah Waterland 		return (B_TRUE);
46115c51f124SMoriah Waterland 	}
46125c51f124SMoriah Waterland 
46135c51f124SMoriah Waterland 	/* return 'dont continue' */
46145c51f124SMoriah Waterland 
46155c51f124SMoriah Waterland 	return (B_FALSE);
46165c51f124SMoriah Waterland }
46175c51f124SMoriah Waterland 
46185c51f124SMoriah Waterland /*
46195c51f124SMoriah Waterland  * returns:
46205c51f124SMoriah Waterland  *	B_TRUE to process next data stream
46215c51f124SMoriah Waterland  *	B_FALSE to exit
46225c51f124SMoriah Waterland  */
46235c51f124SMoriah Waterland 
46245c51f124SMoriah Waterland static boolean_t
46255c51f124SMoriah Waterland add_packages(char **a_pkgList, char *a_uri,
46265c51f124SMoriah Waterland 	char *a_idsName, int a_repeat, char *a_altBinDir, char *a_device,
46275c51f124SMoriah Waterland 	boolean_t a_noZones)
46285c51f124SMoriah Waterland {
46295c51f124SMoriah Waterland 	zoneList_t	zlst;
46305c51f124SMoriah Waterland 	boolean_t	b;
46315c51f124SMoriah Waterland 
46325c51f124SMoriah Waterland 	/* entry assertions */
46335c51f124SMoriah Waterland 
46345c51f124SMoriah Waterland 	assert(a_pkgList != (char **)NULL);
46355c51f124SMoriah Waterland 
46365c51f124SMoriah Waterland 	echoDebug(DBG_ADDPACKAGES_ENTRY);
46375c51f124SMoriah Waterland 	echoDebug(DBG_ADDPACKAGES_ARGS, npkgs, PSTR(a_uri), PSTR(a_idsName),
46385c51f124SMoriah Waterland 		a_repeat, PSTR(a_altBinDir), PSTR(a_device));
46395c51f124SMoriah Waterland 
46405c51f124SMoriah Waterland 	/*
46415c51f124SMoriah Waterland 	 * if running in the global zone AND one or more non-global
46425c51f124SMoriah Waterland 	 * zones exist, add packages in a 'zones aware' manner, else
46435c51f124SMoriah Waterland 	 * add packages in the standard 'non-zones aware' manner.
46445c51f124SMoriah Waterland 	 */
46455c51f124SMoriah Waterland 
46465c51f124SMoriah Waterland 	if ((a_noZones == B_FALSE) && (z_running_in_global_zone() == B_FALSE)) {
46475c51f124SMoriah Waterland 		/* in non-global zone */
46485c51f124SMoriah Waterland 
46495c51f124SMoriah Waterland 		echoDebug(DBG_IN_LZ);
46505c51f124SMoriah Waterland 
46515c51f124SMoriah Waterland 		b = z_lock_this_zone(ZLOCKS_PKG_ADMIN);
46525c51f124SMoriah Waterland 		if (b != B_TRUE) {
46535c51f124SMoriah Waterland 			progerr(ERR_CANNOT_LOCK_THIS_ZONE);
46545c51f124SMoriah Waterland 			/* set fatal error return condition */
46555c51f124SMoriah Waterland 			ckreturn(1);
46565c51f124SMoriah Waterland 			return (B_FALSE);
46575c51f124SMoriah Waterland 		}
46585c51f124SMoriah Waterland 
46595c51f124SMoriah Waterland 		b = add_packages_in_nonglobal_zone(a_pkgList, a_uri, a_idsName,
46605c51f124SMoriah Waterland 			a_repeat, a_altBinDir, a_device);
46615c51f124SMoriah Waterland 
46625c51f124SMoriah Waterland 		(void) z_unlock_this_zone(ZLOCKS_ALL);
46635c51f124SMoriah Waterland 
46645c51f124SMoriah Waterland 		return (B_FALSE);
46655c51f124SMoriah Waterland 	}
46665c51f124SMoriah Waterland 
46675c51f124SMoriah Waterland 	/* running in the global zone */
46685c51f124SMoriah Waterland 
46695c51f124SMoriah Waterland 	b = z_non_global_zones_exist();
46705c51f124SMoriah Waterland 	if ((a_noZones == B_FALSE) && (b == B_TRUE) &&
46715c51f124SMoriah Waterland 					(globalZoneOnly == B_FALSE)) {
46725c51f124SMoriah Waterland 
46735c51f124SMoriah Waterland 		echoDebug(DBG_IN_GZ_WITH_LZ);
46745c51f124SMoriah Waterland 
46755c51f124SMoriah Waterland 		/* error if -V specified - what to use in non-global zone? */
46765c51f124SMoriah Waterland 
46775c51f124SMoriah Waterland 		if (vfstab_file) {
46785c51f124SMoriah Waterland 			progerr(ERR_V_USED_WITH_GZS);
46795c51f124SMoriah Waterland 			quit(1);
46805c51f124SMoriah Waterland 		}
46815c51f124SMoriah Waterland 
46825c51f124SMoriah Waterland 		/* get a list of all non-global zones */
46835c51f124SMoriah Waterland 		zlst = z_get_nonglobal_zone_list();
46845c51f124SMoriah Waterland 		if (zlst == (zoneList_t)NULL) {
46855c51f124SMoriah Waterland 			progerr(ERR_CANNOT_GET_ZONE_LIST);
46865c51f124SMoriah Waterland 			quit(1);
46875c51f124SMoriah Waterland 		}
46885c51f124SMoriah Waterland 
46895c51f124SMoriah Waterland 		/* need to lock all of the zones */
46905c51f124SMoriah Waterland 
46915c51f124SMoriah Waterland 		quitSetZonelist(zlst);
46925c51f124SMoriah Waterland 		b = z_lock_zones(zlst, ZLOCKS_PKG_ADMIN);
46935c51f124SMoriah Waterland 		if (b == B_FALSE) {
46945c51f124SMoriah Waterland 			z_free_zone_list(zlst);
46955c51f124SMoriah Waterland 			progerr(ERR_CANNOT_LOCK_ZONES);
46965c51f124SMoriah Waterland 			/* set fatal error return condition */
46975c51f124SMoriah Waterland 			ckreturn(1);
46985c51f124SMoriah Waterland 			return (B_FALSE);
46995c51f124SMoriah Waterland 		}
47005c51f124SMoriah Waterland 
47015c51f124SMoriah Waterland 		/* add packages to all zones */
47025c51f124SMoriah Waterland 
47035c51f124SMoriah Waterland 		b = add_packages_in_global_with_zones(a_pkgList, a_uri,
47045c51f124SMoriah Waterland 			a_idsName, a_repeat, a_altBinDir, a_device, zlst);
47055c51f124SMoriah Waterland 
47065c51f124SMoriah Waterland 		/* unlock all zones */
47075c51f124SMoriah Waterland 
47085c51f124SMoriah Waterland 		(void) z_unlock_zones(zlst, ZLOCKS_ALL);
47095c51f124SMoriah Waterland 		quitSetZonelist((zoneList_t)NULL);
47105c51f124SMoriah Waterland 
47115c51f124SMoriah Waterland 		/* free list of all non-global zones */
47125c51f124SMoriah Waterland 
47135c51f124SMoriah Waterland 		z_free_zone_list(zlst);
47145c51f124SMoriah Waterland 
47155c51f124SMoriah Waterland 		return (B_FALSE);
47165c51f124SMoriah Waterland 	}
47175c51f124SMoriah Waterland 
47185c51f124SMoriah Waterland 	/* in global zone no non-global zones */
47195c51f124SMoriah Waterland 
47205c51f124SMoriah Waterland 	echoDebug(DBG_IN_GZ_NO_LZ);
47215c51f124SMoriah Waterland 
47225c51f124SMoriah Waterland 	b = z_lock_this_zone(ZLOCKS_PKG_ADMIN);
47235c51f124SMoriah Waterland 	if (b != B_TRUE) {
47245c51f124SMoriah Waterland 		progerr(ERR_CANNOT_LOCK_THIS_ZONE);
47255c51f124SMoriah Waterland 		/* set fatal error return condition */
47265c51f124SMoriah Waterland 		ckreturn(1);
47275c51f124SMoriah Waterland 		return (B_FALSE);
47285c51f124SMoriah Waterland 	}
47295c51f124SMoriah Waterland 
47305c51f124SMoriah Waterland 	b = add_packages_in_global_no_zones(a_pkgList, a_uri, a_idsName,
47315c51f124SMoriah Waterland 		a_repeat, a_altBinDir, a_device);
47325c51f124SMoriah Waterland 
47335c51f124SMoriah Waterland 	(void) z_unlock_this_zone(ZLOCKS_ALL);
47345c51f124SMoriah Waterland 
47355c51f124SMoriah Waterland 	return (B_FALSE);
47365c51f124SMoriah Waterland }
4737