xref: /titanic_52/usr/src/cmd/svr4pkg/pkgrm/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  * System includes
335c51f124SMoriah Waterland  */
345c51f124SMoriah Waterland 
355c51f124SMoriah Waterland #include <stdio.h>
365c51f124SMoriah Waterland #include <stdlib.h>
375c51f124SMoriah Waterland #include <unistd.h>
385c51f124SMoriah Waterland #include <string.h>
395c51f124SMoriah Waterland #include <signal.h>
405c51f124SMoriah Waterland #include <errno.h>
415c51f124SMoriah Waterland #include <locale.h>
425c51f124SMoriah Waterland #include <libintl.h>
435c51f124SMoriah Waterland #include <pkgstrct.h>
445c51f124SMoriah Waterland #include <pkgdev.h>
455c51f124SMoriah Waterland #include <pkginfo.h>
465c51f124SMoriah Waterland #include <pkglocs.h>
475c51f124SMoriah Waterland #include <pkglib.h>
485c51f124SMoriah Waterland #include <assert.h>
495c51f124SMoriah Waterland 
505c51f124SMoriah Waterland /*
515c51f124SMoriah Waterland  * libinstzones includes
525c51f124SMoriah Waterland  */
535c51f124SMoriah Waterland 
545c51f124SMoriah Waterland #include <instzones_api.h>
555c51f124SMoriah Waterland 
565c51f124SMoriah Waterland /*
575c51f124SMoriah Waterland  * consolidation pkg command library includes
585c51f124SMoriah Waterland  */
595c51f124SMoriah Waterland 
605c51f124SMoriah Waterland #include <pkglib.h>
615c51f124SMoriah Waterland 
625c51f124SMoriah Waterland /*
635c51f124SMoriah Waterland  * local pkg command library includes
645c51f124SMoriah Waterland  */
655c51f124SMoriah Waterland 
665c51f124SMoriah Waterland #include "install.h"
675c51f124SMoriah Waterland #include "libinst.h"
685c51f124SMoriah Waterland #include "libadm.h"
695c51f124SMoriah Waterland #include "messages.h"
705c51f124SMoriah Waterland 
715c51f124SMoriah Waterland /*
725c51f124SMoriah Waterland  * pkgrm local includes
735c51f124SMoriah Waterland  */
745c51f124SMoriah Waterland 
755c51f124SMoriah Waterland #include "quit.h"
765c51f124SMoriah Waterland 
775c51f124SMoriah Waterland /*
785c51f124SMoriah Waterland  * exported global variables
795c51f124SMoriah Waterland  */
805c51f124SMoriah Waterland 
815c51f124SMoriah Waterland /* these globals are set by ckreturn and used by quit.c */
825c51f124SMoriah Waterland 
835c51f124SMoriah Waterland int	admnflag = 0;	/* != 0 if any pkg op admin setting failure (4) */
845c51f124SMoriah Waterland int	doreboot = 0;	/* != 0 if reboot required after installation */
855c51f124SMoriah Waterland int	failflag = 0;	/* != 0 if fatal error has occurred (1) */
865c51f124SMoriah Waterland int	intrflag = 0;	/* != 0 if user selected quit (3) */
875c51f124SMoriah Waterland int	ireboot = 0;	/* != 0 if immediate reboot required */
885c51f124SMoriah Waterland int	nullflag = 0;	/* != 0 if admin interaction required (5) */
895c51f124SMoriah Waterland int	warnflag = 0;	/* != 0 if non-fatal error has occurred (2) */
905c51f124SMoriah Waterland 
915c51f124SMoriah Waterland /* imported by quit.c */
925c51f124SMoriah Waterland int	npkgs = 0;	/* the number of packages yet to be installed */
935c51f124SMoriah Waterland 
945c51f124SMoriah Waterland /* imported by presvr4.c */
955c51f124SMoriah Waterland int	started = 0;
965c51f124SMoriah Waterland char	*tmpdir = NULL;	/* location to place temporary files */
975c51f124SMoriah Waterland 
985c51f124SMoriah Waterland /* imported by various (many) */
995c51f124SMoriah Waterland struct admin	adm;	/* holds info about installation admin */
1005c51f124SMoriah Waterland struct pkgdev	pkgdev;	/* holds info about the installation device */
1015c51f124SMoriah Waterland 
1025c51f124SMoriah Waterland /*
1035c51f124SMoriah Waterland  * internal global variables
1045c51f124SMoriah Waterland  */
1055c51f124SMoriah Waterland 
1065c51f124SMoriah Waterland static char	*admnfile = NULL;	/* file to use for installation admin */
1075c51f124SMoriah Waterland static char	*pkginst = NULL;	/* current pkg/src instance 2 process */
1085c51f124SMoriah Waterland static char	*vfstab_file = NULL;
1095c51f124SMoriah Waterland static char	*zoneTempDir = (char *)NULL;
1105c51f124SMoriah Waterland 
1115c51f124SMoriah Waterland /* set by ckreturn() */
1125c51f124SMoriah Waterland 
1135c51f124SMoriah Waterland static int	interrupted = 0;	/* last pkg op was quit (1,2,3,4,5) */
1145c51f124SMoriah Waterland 
1155c51f124SMoriah Waterland static int	nointeract = 0;		/* non-zero - no user interaction */
1165c51f124SMoriah Waterland static int	pkgrmremote = 0;	/* remove pkg objs stored remotely  */
1175c51f124SMoriah Waterland static int	pkgverbose = 0;		/* non-zero if verbose mode selected */
1185c51f124SMoriah Waterland 
1195c51f124SMoriah Waterland /*
1205c51f124SMoriah Waterland  * Assume the package complies with the standards as regards user
1215c51f124SMoriah Waterland  * interaction during procedure scripts.
1225c51f124SMoriah Waterland  */
1235c51f124SMoriah Waterland 
1245c51f124SMoriah Waterland static int	old_pkg = 0;
1255c51f124SMoriah Waterland static int	old_symlinks = 0;
1265c51f124SMoriah Waterland static int	no_map_client = 0;
1275c51f124SMoriah Waterland 
1285c51f124SMoriah Waterland /* Set by -O nozones: do not process any zones */
1295c51f124SMoriah Waterland 
1305c51f124SMoriah Waterland static boolean_t	noZones = B_FALSE;
1315c51f124SMoriah Waterland 
1325c51f124SMoriah Waterland /* Set by -O zonelist=<names...>: process only named zones */
1335c51f124SMoriah Waterland 
1345c51f124SMoriah Waterland static boolean_t	usedZoneList = B_FALSE;
1355c51f124SMoriah Waterland 
1365c51f124SMoriah Waterland /* Set by -O debug: debug output is enabled? */
1375c51f124SMoriah Waterland 
1385c51f124SMoriah Waterland static boolean_t	debugFlag = B_FALSE;
1395c51f124SMoriah Waterland 
1405c51f124SMoriah Waterland /*
1415c51f124SMoriah Waterland  * imported (external) functions
1425c51f124SMoriah Waterland  */
1435c51f124SMoriah Waterland 
1445c51f124SMoriah Waterland /* presvr4.c */
1455c51f124SMoriah Waterland 
1465c51f124SMoriah Waterland extern int	presvr4(char *pkg, int a_nointeract);
1475c51f124SMoriah Waterland 
1485c51f124SMoriah Waterland /* check.c */
1495c51f124SMoriah Waterland 
1505c51f124SMoriah Waterland extern int	preremove_verify(char **a_pkgList, zoneList_t a_zlst,
1515c51f124SMoriah Waterland 			char *a_zoneTempDir);
1525c51f124SMoriah Waterland /* quit.c */
1535c51f124SMoriah Waterland 
1545c51f124SMoriah Waterland extern void	quitSetZonelist(zoneList_t a_zlst);
1555c51f124SMoriah Waterland 
1565c51f124SMoriah Waterland /*
1575c51f124SMoriah Waterland  * imported (external) variables
1585c51f124SMoriah Waterland  */
1595c51f124SMoriah Waterland 
1605c51f124SMoriah Waterland extern char	*pkgdir;
1615c51f124SMoriah Waterland 
1625c51f124SMoriah Waterland /* printable string - if string is null results in ??? */
1635c51f124SMoriah Waterland 
1645c51f124SMoriah Waterland #define	PSTR(STR) (((STR) == (char *)NULL) ? "???" : (STR))
1655c51f124SMoriah Waterland 
1665c51f124SMoriah Waterland #define	MAX_FDS	20
1675c51f124SMoriah Waterland 
1685c51f124SMoriah Waterland #if !defined(TEXT_DOMAIN)	/* Should be defined by cc -D */
1695c51f124SMoriah Waterland #define	TEXT_DOMAIN "SYS_TEST"
1705c51f124SMoriah Waterland #endif
1715c51f124SMoriah Waterland 
1725c51f124SMoriah Waterland #define	INHERITFS	"inherited-filesystem="
1735c51f124SMoriah Waterland #define	INHERITFS_LEN	((sizeof (INHERITFS))-1)
1745c51f124SMoriah Waterland 
1755c51f124SMoriah Waterland /*
1765c51f124SMoriah Waterland  * forward declarations
1775c51f124SMoriah Waterland  */
1785c51f124SMoriah Waterland 
1795c51f124SMoriah Waterland static void		ckreturn(int retcode);
1805c51f124SMoriah Waterland static void		create_zone_adminfile(char **r_zoneAdminFile,
1815c51f124SMoriah Waterland 				char *a_zoneTempDir, char *a_admnfile);
1825c51f124SMoriah Waterland static void		create_zone_tempdir(char **r_zoneTempDir,
1835c51f124SMoriah Waterland 				char *a_tmpdir);
1845c51f124SMoriah Waterland static int		doRemove(int a_nodelete, char *a_altBinDir,
1855c51f124SMoriah Waterland 				int a_longestPkg, char *a_adminFile,
1865c51f124SMoriah Waterland 				char *a_zoneAdminFile, zoneList_t zlst);
1875c51f124SMoriah Waterland static int		pkgRemove(int a_nodelete, char *a_altBinDir,
1885c51f124SMoriah Waterland 				char *a_adminFile, char **a_inheritedPkgDirs);
1895c51f124SMoriah Waterland static int		pkgZoneCheckRemove(char *a_zoneName,
1905c51f124SMoriah Waterland 				char **a_inheritedPkgDirs, char *a_altBinDir,
1915c51f124SMoriah Waterland 				char *a_adminFile, char *a_stdoutPath,
192*62224350SCasper H.S. Dik 				zone_state_t a_zoneState, boolean_t tmpzone);
1935c51f124SMoriah Waterland static int		pkgZoneRemove(char *a_zoneName,
1945c51f124SMoriah Waterland 				char **a_inheritedPkgDirs, int a_nodelete,
1955c51f124SMoriah Waterland 				char *a_altBinDir, char *a_adminFile,
196*62224350SCasper H.S. Dik 				zone_state_t a_zoneState, boolean_t tmpzone);
1975c51f124SMoriah Waterland static void		resetreturn();
1985c51f124SMoriah Waterland static void		usage(void);
1995c51f124SMoriah Waterland static boolean_t	check_applicability(char *a_packageDir,
2005c51f124SMoriah Waterland 				char *a_pkgInst, char *a_rootPath,
2015c51f124SMoriah Waterland 				CAF_T a_flags);
2025c51f124SMoriah Waterland static boolean_t	check_packages(char **a_pkgList, char *a_packageDir);
2035c51f124SMoriah Waterland static boolean_t	path_valid(char *path);
2045c51f124SMoriah Waterland static boolean_t	remove_packages(char **a_pkgList, int a_nodelete,
2055c51f124SMoriah Waterland 				int a_longestPkg, int a_repeat,
2065c51f124SMoriah Waterland 				char *a_altBinDir, char *a_pkgdir,
2075c51f124SMoriah Waterland 				char *a_spoolDir, boolean_t a_noZones);
2085c51f124SMoriah Waterland static boolean_t	remove_packages_from_spool_directory(char **a_pkgList,
2095c51f124SMoriah Waterland 				int a_nodelete, int a_longestPkg, int a_repeat,
2105c51f124SMoriah Waterland 				char *a_altBinDir);
2115c51f124SMoriah Waterland static boolean_t	remove_packages_in_global_no_zones(char **a_pkgList,
2125c51f124SMoriah Waterland 				int a_nodelete, int a_longestPkg, int a_repeat,
2135c51f124SMoriah Waterland 				char *a_altBinDir);
2145c51f124SMoriah Waterland static boolean_t	remove_packages_in_global_with_zones(char **a_pkgList,
2155c51f124SMoriah Waterland 				int a_nodelete, int a_longestPkg, int a_repeat,
2165c51f124SMoriah Waterland 				char *a_altBinDir, char *a_pkgdir,
2175c51f124SMoriah Waterland 				zoneList_t a_zlst);
2185c51f124SMoriah Waterland static boolean_t	remove_packages_in_nonglobal_zone(char **a_pkgList,
2195c51f124SMoriah Waterland 				int a_nodelete, int a_longestPkg, int a_repeat,
2205c51f124SMoriah Waterland 				char *a_altBinDir, char *a_pkgdir);
2215c51f124SMoriah Waterland static boolean_t	shall_we_continue(char *a_pkgInst, int a_npkgs);
2225c51f124SMoriah Waterland 
2235c51f124SMoriah Waterland /*
2245c51f124SMoriah Waterland  * *****************************************************************************
2255c51f124SMoriah Waterland  * global external (public) functions
2265c51f124SMoriah Waterland  * *****************************************************************************
2275c51f124SMoriah Waterland  */
2285c51f124SMoriah Waterland 
2295c51f124SMoriah Waterland /*
2305c51f124SMoriah Waterland  * Name:	main
2315c51f124SMoriah Waterland  * Description:	main entry point for pkgrm
2325c51f124SMoriah Waterland  * Returns:	int
2335c51f124SMoriah Waterland  *   0        Successful completion
2345c51f124SMoriah Waterland  *   1        Fatal error.
2355c51f124SMoriah Waterland  *   2        Warning.
2365c51f124SMoriah Waterland  *   3        Interruption.
2375c51f124SMoriah Waterland  *   4        Administration.
2385c51f124SMoriah Waterland  *   5        Administration. Interaction is required. Do not use pkgrm -n.
2395c51f124SMoriah Waterland  *  10       Reboot after removal of all packages.
2405c51f124SMoriah Waterland  *  20       Reboot after removal of this package.
2415c51f124SMoriah Waterland  */
2425c51f124SMoriah Waterland 
2435c51f124SMoriah Waterland int
2445c51f124SMoriah Waterland main(int argc, char **argv)
2455c51f124SMoriah Waterland {
2465c51f124SMoriah Waterland 	char			**category = NULL;
2475c51f124SMoriah Waterland 	char			*altBinDir = (char *)NULL;
2485c51f124SMoriah Waterland 	char			*catg_arg = NULL;
2495c51f124SMoriah Waterland 	char			*p;
2505c51f124SMoriah Waterland 	char			*prog_full_name = NULL;
2515c51f124SMoriah Waterland 	char			*spoolDir = 0;
2525c51f124SMoriah Waterland 	int			c;
2535c51f124SMoriah Waterland 	int			longestPkg = 0;
2545c51f124SMoriah Waterland 	int			n;
2555c51f124SMoriah Waterland 	int			nodelete = 0;	/* dont rm files/run scripts */
2565c51f124SMoriah Waterland 	int			pkgLgth = 0;
2575c51f124SMoriah Waterland 	int			repeat;
2585c51f124SMoriah Waterland 	struct sigaction	nact;
2595c51f124SMoriah Waterland 	struct sigaction	oact;
2605c51f124SMoriah Waterland 
2615c51f124SMoriah Waterland 	/* initialize locale environment */
2625c51f124SMoriah Waterland 
2635c51f124SMoriah Waterland 	(void) setlocale(LC_ALL, "");
2645c51f124SMoriah Waterland 	(void) textdomain(TEXT_DOMAIN);
2655c51f124SMoriah Waterland 
2665c51f124SMoriah Waterland 	/* initialize program name */
2675c51f124SMoriah Waterland 
2685c51f124SMoriah Waterland 	prog_full_name = argv[0];
2695c51f124SMoriah Waterland 	(void) set_prog_name(argv[0]);
2705c51f124SMoriah Waterland 
2715c51f124SMoriah Waterland 	/* tell spmi zones interface how to access package output functions */
2725c51f124SMoriah Waterland 
2735c51f124SMoriah Waterland 	z_set_output_functions(echo, echoDebug, progerr);
2745c51f124SMoriah Waterland 
2755c51f124SMoriah Waterland 	/* tell quit which ckreturn function to call */
2765c51f124SMoriah Waterland 
2775c51f124SMoriah Waterland 	quitSetCkreturnFunc(&ckreturn);
2785c51f124SMoriah Waterland 
2795c51f124SMoriah Waterland 	/* Read PKG_INSTALL_ROOT from the environment, if it's there. */
2805c51f124SMoriah Waterland 
2815c51f124SMoriah Waterland 	if (!set_inst_root(getenv("PKG_INSTALL_ROOT"))) {
2825c51f124SMoriah Waterland 		progerr(ERR_ROOT_SET);
2835c51f124SMoriah Waterland 		exit(1);
2845c51f124SMoriah Waterland 	}
2855c51f124SMoriah Waterland 
2865c51f124SMoriah Waterland 	if (z_running_in_global_zone() && !enable_local_fs()) {
2875c51f124SMoriah Waterland 		progerr(ERR_CANNOT_ENABLE_LOCAL_FS);
2885c51f124SMoriah Waterland 	}
2895c51f124SMoriah Waterland 
290*62224350SCasper H.S. Dik 	pkgserversetmode(DEFAULTMODE);
291*62224350SCasper H.S. Dik 
2925c51f124SMoriah Waterland 	/*
2935c51f124SMoriah Waterland 	 * ********************************************************************
2945c51f124SMoriah Waterland 	 * parse command line options
2955c51f124SMoriah Waterland 	 * ********************************************************************
2965c51f124SMoriah Waterland 	 */
2975c51f124SMoriah Waterland 
2985c51f124SMoriah Waterland 	while ((c = getopt(argc, argv, "?Aa:b:FMnO:R:s:V:vY:Z")) != EOF) {
2995c51f124SMoriah Waterland 		switch (c) {
3005c51f124SMoriah Waterland 		/*
3015c51f124SMoriah Waterland 		 * Public interface: Allow admin to remove objects
3025c51f124SMoriah Waterland 		 * from a service area via a reference client.
3035c51f124SMoriah Waterland 		 * Remove the package files from the client's file
3045c51f124SMoriah Waterland 		 * system, absolutely. If a file is shared with other
3055c51f124SMoriah Waterland 		 * packages, the default behavior is to not remove
3065c51f124SMoriah Waterland 		 * the file from the client's file system.
3075c51f124SMoriah Waterland 		 */
3085c51f124SMoriah Waterland 		case 'A':
3095c51f124SMoriah Waterland 		    pkgrmremote++;
3105c51f124SMoriah Waterland 		    break;
3115c51f124SMoriah Waterland 
3125c51f124SMoriah Waterland 		/*
3135c51f124SMoriah Waterland 		 * Public interface: Use the installation
3145c51f124SMoriah Waterland 		 * administration file, admin, in place of the
3155c51f124SMoriah Waterland 		 * default admin file. pkgrm first looks in the
3165c51f124SMoriah Waterland 		 * current working directory for the administration
3175c51f124SMoriah Waterland 		 * file.  If the specified administration file is not
3185c51f124SMoriah Waterland 		 * in the current working directory, pkgrm looks in
3195c51f124SMoriah Waterland 		 * the /var/sadm/install/admin directory for the
3205c51f124SMoriah Waterland 		 * administra- tion file.
3215c51f124SMoriah Waterland 		 */
3225c51f124SMoriah Waterland 		case 'a':
3235c51f124SMoriah Waterland 		    admnfile = flex_device(optarg, 0);
3245c51f124SMoriah Waterland 		    break;
3255c51f124SMoriah Waterland 
3265c51f124SMoriah Waterland 		/*
3275c51f124SMoriah Waterland 		 * Not a public interface:  location where package executables
3285c51f124SMoriah Waterland 		 * can be found - default is /usr/sadm/install/bin.
3295c51f124SMoriah Waterland 		 */
3305c51f124SMoriah Waterland 		case 'b':
3315c51f124SMoriah Waterland 			if (!path_valid(optarg)) {
3325c51f124SMoriah Waterland 				progerr(ERR_PATH, optarg);
3335c51f124SMoriah Waterland 				quit(1);
3345c51f124SMoriah Waterland 			}
3355c51f124SMoriah Waterland 			if (isdir(optarg) != 0) {
3365c51f124SMoriah Waterland 				p = strerror(errno);
3375c51f124SMoriah Waterland 				progerr(ERR_CANNOT_USE_DIR, optarg, p);
3385c51f124SMoriah Waterland 				quit(1);
3395c51f124SMoriah Waterland 			}
3405c51f124SMoriah Waterland 			altBinDir = optarg;
3415c51f124SMoriah Waterland 			break;
3425c51f124SMoriah Waterland 
3435c51f124SMoriah Waterland 		/*
3445c51f124SMoriah Waterland 		 * Not a public interface: pass -F option to
3455c51f124SMoriah Waterland 		 * pkgremove which suppresses the removal of any
3465c51f124SMoriah Waterland 		 * files and any class action scripts, and suppresses
3475c51f124SMoriah Waterland 		 * the running of any class action scripts.  The
3485c51f124SMoriah Waterland 		 * package files remain but the package looks like it
3495c51f124SMoriah Waterland 		 * is not installed. This is mainly for use by the
3505c51f124SMoriah Waterland 		 * upgrade process.
3515c51f124SMoriah Waterland 		 */
3525c51f124SMoriah Waterland 		case 'F':
3535c51f124SMoriah Waterland 		    nodelete++;
3545c51f124SMoriah Waterland 		    break;
3555c51f124SMoriah Waterland 
3565c51f124SMoriah Waterland 		/*
3575c51f124SMoriah Waterland 		 * Public interface: Instruct pkgrm not to use the
3585c51f124SMoriah Waterland 		 * $root_path/etc/vfstab file for determining the
3595c51f124SMoriah Waterland 		 * client's mount points. This option assumes the
3605c51f124SMoriah Waterland 		 * mount points are correct on the server and it
3615c51f124SMoriah Waterland 		 * behaves consistently with Solaris 2.5 and earlier
3625c51f124SMoriah Waterland 		 * releases.
3635c51f124SMoriah Waterland 		 */
3645c51f124SMoriah Waterland 		case 'M':
3655c51f124SMoriah Waterland 		    no_map_client = 1;
3665c51f124SMoriah Waterland 		    break;
3675c51f124SMoriah Waterland 
3685c51f124SMoriah Waterland 		/*
3695c51f124SMoriah Waterland 		 * Public interface: package removal occurs in
3705c51f124SMoriah Waterland 		 * non-interactive mode.  Suppress output of the list of
3715c51f124SMoriah Waterland 		 * removed files. The default mode is interactive.
3725c51f124SMoriah Waterland 		 */
3735c51f124SMoriah Waterland 		case 'n':
3745c51f124SMoriah Waterland 		    nointeract++;
3755c51f124SMoriah Waterland 		    (void) echoSetFlag(B_FALSE);
3765c51f124SMoriah Waterland 		    break;
3775c51f124SMoriah Waterland 
3785c51f124SMoriah Waterland 		/*
3795c51f124SMoriah Waterland 		 * Not a public interface: the -O option allows the behavior
3805c51f124SMoriah Waterland 		 * of the package tools to be modified. Recognized options:
3815c51f124SMoriah Waterland 		 * -> debug
3825c51f124SMoriah Waterland 		 * ---> enable debugging output
3835c51f124SMoriah Waterland 		 * -> nozones
3845c51f124SMoriah Waterland 		 * ---> act as though in global zone with no non-global zones
3855c51f124SMoriah Waterland 		 * -> inherited-filesystems
3865c51f124SMoriah Waterland 		 * ---> add specified file system to list of file systems
3875c51f124SMoriah Waterland 		 * ---> that are inherited from the global zone
3885c51f124SMoriah Waterland 		 * -> enable-hollow-package-support
3895c51f124SMoriah Waterland 		 * --> Enable hollow package support. When specified, for any
3905c51f124SMoriah Waterland 		 * --> package that has SUNW_PKG_HOLLOW=true:
3915c51f124SMoriah Waterland 		 * --> Do not calculate and verify package size against target
3925c51f124SMoriah Waterland 		 * --> Do not run any package procedure or class action scripts
3935c51f124SMoriah Waterland 		 * --> Do not create or remove any target directories
3945c51f124SMoriah Waterland 		 * --> Do not perform any script locking
3955c51f124SMoriah Waterland 		 * --> Do not install or uninstall any components of any package
3965c51f124SMoriah Waterland 		 * --> Do not output any status or database update messages
3975c51f124SMoriah Waterland 		 * -> zonelist="<names...>"
3985c51f124SMoriah Waterland 		 * ---> add package to space-separated list of zones only
3995c51f124SMoriah Waterland 		 */
4005c51f124SMoriah Waterland 
4015c51f124SMoriah Waterland 		case 'O':
4025c51f124SMoriah Waterland 			for (p = strtok(optarg, ","); p != (char *)NULL;
4035c51f124SMoriah Waterland 				p = strtok(NULL, ",")) {
4045c51f124SMoriah Waterland 
4055c51f124SMoriah Waterland 				if (strcmp(p, "nozones") == 0) {
4065c51f124SMoriah Waterland 					noZones = B_TRUE;
4075c51f124SMoriah Waterland 					continue;
4085c51f124SMoriah Waterland 				}
4095c51f124SMoriah Waterland 
4105c51f124SMoriah Waterland 				if (strncmp(p, INHERITFS, INHERITFS_LEN) == 0) {
4115c51f124SMoriah Waterland 					if (z_add_inherited_file_system(
4125c51f124SMoriah Waterland 						p+INHERITFS_LEN) == B_FALSE) {
4135c51f124SMoriah Waterland 						progerr(ERR_NOSUCH_INHERITED,
4145c51f124SMoriah Waterland 							p+INHERITFS_LEN);
4155c51f124SMoriah Waterland 						quit(1);
4165c51f124SMoriah Waterland 						/* NOTREACHED */
4175c51f124SMoriah Waterland 					}
4185c51f124SMoriah Waterland 					continue;
4195c51f124SMoriah Waterland 				}
4205c51f124SMoriah Waterland 
4215c51f124SMoriah Waterland 				if (strcmp(p,
4225c51f124SMoriah Waterland 					"enable-hollow-package-support") == 0) {
4235c51f124SMoriah Waterland 					set_depend_pkginfo_DB(B_TRUE);
4245c51f124SMoriah Waterland 					continue;
4255c51f124SMoriah Waterland 				}
4265c51f124SMoriah Waterland 
4275c51f124SMoriah Waterland 				if (strcmp(p, "debug") == 0) {
4285c51f124SMoriah Waterland 					/* set debug flag/enable debug output */
4295c51f124SMoriah Waterland 					debugFlag = B_TRUE;
4305c51f124SMoriah Waterland 					(void) echoDebugSetFlag(debugFlag);
4315c51f124SMoriah Waterland 
4325c51f124SMoriah Waterland 					/* debug info on arguments to pkgadd */
4335c51f124SMoriah Waterland 					for (n = 0; n < argc && argv[n]; n++) {
4345c51f124SMoriah Waterland 						echoDebug(DBG_ARG, n, argv[n]);
4355c51f124SMoriah Waterland 					}
4365c51f124SMoriah Waterland 
4375c51f124SMoriah Waterland 					continue;
4385c51f124SMoriah Waterland 				}
4395c51f124SMoriah Waterland 
4405c51f124SMoriah Waterland 				if (strncmp(p, "zonelist=", 9) == 0) {
4415c51f124SMoriah Waterland 					if (z_set_zone_spec(p + 9) == -1)
4425c51f124SMoriah Waterland 						quit(1);
4435c51f124SMoriah Waterland 					usedZoneList = B_TRUE;
4445c51f124SMoriah Waterland 					continue;
4455c51f124SMoriah Waterland 				}
4465c51f124SMoriah Waterland 
4475c51f124SMoriah Waterland 				/* -O option not recognized - issue warning */
4485c51f124SMoriah Waterland 
4495c51f124SMoriah Waterland 				progerr(ERR_INVALID_O_OPTION, p);
4505c51f124SMoriah Waterland 				continue;
4515c51f124SMoriah Waterland 			}
4525c51f124SMoriah Waterland 			break;
4535c51f124SMoriah Waterland 
4545c51f124SMoriah Waterland 		/*
4555c51f124SMoriah Waterland 		 * Public interface: defines the full path name of a
4565c51f124SMoriah Waterland 		 * directory to use as the root_path.  All files,
4575c51f124SMoriah Waterland 		 * including package system information files, are
4585c51f124SMoriah Waterland 		 * relocated to a directory tree starting in the
4595c51f124SMoriah Waterland 		 * specified root_path.
4605c51f124SMoriah Waterland 		 */
4615c51f124SMoriah Waterland 		case 'R':
4625c51f124SMoriah Waterland 		    if (!set_inst_root(optarg)) {
4635c51f124SMoriah Waterland 			    progerr(ERR_ROOT_CMD);
4645c51f124SMoriah Waterland 			    exit(1);
4655c51f124SMoriah Waterland 		    }
4665c51f124SMoriah Waterland 		    break;
4675c51f124SMoriah Waterland 
4685c51f124SMoriah Waterland 		/*
4695c51f124SMoriah Waterland 		 * Public interface: remove the specified package(s)
4705c51f124SMoriah Waterland 		 * from the directory spool.  The default directory
4715c51f124SMoriah Waterland 		 * for spooled packages is /var/sadm/pkg.
4725c51f124SMoriah Waterland 		 */
4735c51f124SMoriah Waterland 		case 's':
4745c51f124SMoriah Waterland 		    spoolDir = flex_device(optarg, 1);
4755c51f124SMoriah Waterland 		    break;
4765c51f124SMoriah Waterland 
4775c51f124SMoriah Waterland 		/*
4785c51f124SMoriah Waterland 		 * Public interface: Allow admin to establish the client
4795c51f124SMoriah Waterland 		 * filesystem using a vfstab-like file of stable format.
4805c51f124SMoriah Waterland 		 */
4815c51f124SMoriah Waterland 		case 'V':
4825c51f124SMoriah Waterland 		    vfstab_file = flex_device(optarg, 2);
4835c51f124SMoriah Waterland 		    no_map_client = 0;
4845c51f124SMoriah Waterland 		    break;
4855c51f124SMoriah Waterland 
4865c51f124SMoriah Waterland 		/*
4875c51f124SMoriah Waterland 		 * Public interface: trace all of the scripts that
4885c51f124SMoriah Waterland 		 * get executed by pkgrm, located in the
4895c51f124SMoriah Waterland 		 * pkginst/install directory. This option is used for
4905c51f124SMoriah Waterland 		 * debugging the procedural and non- procedural
4915c51f124SMoriah Waterland 		 * scripts.
4925c51f124SMoriah Waterland 		 */
4935c51f124SMoriah Waterland 		case 'v':
4945c51f124SMoriah Waterland 		    pkgverbose++;
4955c51f124SMoriah Waterland 		    break;
4965c51f124SMoriah Waterland 
4975c51f124SMoriah Waterland 		/*
4985c51f124SMoriah Waterland 		 * Public interface: remove packages based on the
4995c51f124SMoriah Waterland 		 * CATEGORY variable from the installed/spooled
5005c51f124SMoriah Waterland 		 * pkginfo file
5015c51f124SMoriah Waterland 		 */
5025c51f124SMoriah Waterland 		case 'Y':
5035c51f124SMoriah Waterland 		    catg_arg = strdup(optarg);
5045c51f124SMoriah Waterland 
5055c51f124SMoriah Waterland 		    if ((category = get_categories(catg_arg)) == NULL) {
5065c51f124SMoriah Waterland 			    progerr(ERR_CAT_INV, catg_arg);
5075c51f124SMoriah Waterland 			    exit(1);
5085c51f124SMoriah Waterland 		    } else if (is_not_valid_category(category,
5095c51f124SMoriah Waterland 				    get_prog_name())) {
5105c51f124SMoriah Waterland 			    progerr(ERR_CAT_SYS);
5115c51f124SMoriah Waterland 			    exit(1);
5125c51f124SMoriah Waterland 		    } else if (is_not_valid_length(category)) {
5135c51f124SMoriah Waterland 			    progerr(ERR_CAT_LNGTH);
5145c51f124SMoriah Waterland 			    exit(1);
5155c51f124SMoriah Waterland 		    }
5165c51f124SMoriah Waterland 
5175c51f124SMoriah Waterland 		    break;
5185c51f124SMoriah Waterland 
5195c51f124SMoriah Waterland 		/*
5205c51f124SMoriah Waterland 		 * unrecognized option
5215c51f124SMoriah Waterland 		 */
5225c51f124SMoriah Waterland 		default:
5235c51f124SMoriah Waterland 		    usage();
5245c51f124SMoriah Waterland 		    /* NOTREACHED */
5255c51f124SMoriah Waterland 		}
5265c51f124SMoriah Waterland 	}
5275c51f124SMoriah Waterland 
5285c51f124SMoriah Waterland 	/*
5295c51f124SMoriah Waterland 	 * ********************************************************************
5305c51f124SMoriah Waterland 	 * validate command line options
5315c51f124SMoriah Waterland 	 * ********************************************************************
5325c51f124SMoriah Waterland 	 */
5335c51f124SMoriah Waterland 
5345c51f124SMoriah Waterland 	/* set "debug echo" flag according to setting of "-O debug" option */
5355c51f124SMoriah Waterland 
5365c51f124SMoriah Waterland 	(void) echoDebugSetFlag(debugFlag);
5375c51f124SMoriah Waterland 
5385c51f124SMoriah Waterland 	/* output entry debugging information */
5395c51f124SMoriah Waterland 
5405c51f124SMoriah Waterland 	if (z_running_in_global_zone()) {
5415c51f124SMoriah Waterland 		echoDebug(DBG_ENTRY_IN_GZ, prog_full_name);
5425c51f124SMoriah Waterland 	} else {
5435c51f124SMoriah Waterland 		echoDebug(DBG_ENTRY_IN_LZ, prog_full_name, getzoneid(),
5445c51f124SMoriah Waterland 			z_get_zonename());
5455c51f124SMoriah Waterland 	}
5465c51f124SMoriah Waterland 
5475c51f124SMoriah Waterland 	/* -s cannot be used with several */
5485c51f124SMoriah Waterland 
5495c51f124SMoriah Waterland 	if (spoolDir != (char *)NULL) {
5505c51f124SMoriah Waterland 		if (admnfile != (char *)NULL) {
5515c51f124SMoriah Waterland 			progerr(ERR_SPOOLDIR_AND_ADMNFILE);
5525c51f124SMoriah Waterland 			usage();
5535c51f124SMoriah Waterland 			/* NOTREACHED */
5545c51f124SMoriah Waterland 		}
5555c51f124SMoriah Waterland 
5565c51f124SMoriah Waterland 		if (pkgrmremote != 0) {
5575c51f124SMoriah Waterland 			progerr(ERR_SPOOLDIR_AND_PKGRMREMOTE);
5585c51f124SMoriah Waterland 			usage();
5595c51f124SMoriah Waterland 			/* NOTREACHED */
5605c51f124SMoriah Waterland 		}
5615c51f124SMoriah Waterland 
5625c51f124SMoriah Waterland 		if (pkgverbose != 0) {
5635c51f124SMoriah Waterland 			progerr(ERR_SPOOLDIR_AND_PKGVERBOSE);
5645c51f124SMoriah Waterland 			usage();
5655c51f124SMoriah Waterland 			/* NOTREACHED */
5665c51f124SMoriah Waterland 		}
5675c51f124SMoriah Waterland 
5685c51f124SMoriah Waterland 		if (is_an_inst_root() != 0) {
5695c51f124SMoriah Waterland 			progerr(ERR_SPOOLDIR_AND_INST_ROOT);
5705c51f124SMoriah Waterland 			usage();
5715c51f124SMoriah Waterland 			/* NOTREACHED */
5725c51f124SMoriah Waterland 		}
5735c51f124SMoriah Waterland 	}
5745c51f124SMoriah Waterland 
5755c51f124SMoriah Waterland 	/* -V cannot be used with -A */
5765c51f124SMoriah Waterland 
5775c51f124SMoriah Waterland 	if (no_map_client && pkgrmremote) {
5785c51f124SMoriah Waterland 		progerr(ERR_V_USED_AND_PKGRMREMOTE);
5795c51f124SMoriah Waterland 		usage();
5805c51f124SMoriah Waterland 		/* NOTREACHED */
5815c51f124SMoriah Waterland 	}
5825c51f124SMoriah Waterland 
5835c51f124SMoriah Waterland 	/* -n used without pkg names or category */
5845c51f124SMoriah Waterland 
5855c51f124SMoriah Waterland 	if (nointeract && (optind == argc) && (catg_arg == NULL)) {
5865c51f124SMoriah Waterland 		progerr(ERR_BAD_N_PKGRM);
5875c51f124SMoriah Waterland 		usage();
5885c51f124SMoriah Waterland 		/* NOTREACHED */
5895c51f124SMoriah Waterland 	}
5905c51f124SMoriah Waterland 
5915c51f124SMoriah Waterland 	/* Error if specified zone list isn't valid on target */
5925c51f124SMoriah Waterland 	if (usedZoneList && z_verify_zone_spec() == -1)
5935c51f124SMoriah Waterland 		usage();
5945c51f124SMoriah Waterland 
5955c51f124SMoriah Waterland 	/*
5965c51f124SMoriah Waterland 	 * hook SIGINT and SIGHUP interrupts into quit.c's trap handler
5975c51f124SMoriah Waterland 	 */
5985c51f124SMoriah Waterland 
5995c51f124SMoriah Waterland 	/* hold SIGINT/SIGHUP interrupts */
6005c51f124SMoriah Waterland 
6015c51f124SMoriah Waterland 	(void) sighold(SIGHUP);
6025c51f124SMoriah Waterland 	(void) sighold(SIGINT);
6035c51f124SMoriah Waterland 
6045c51f124SMoriah Waterland 	/* connect quit.c:trap() to SIGINT */
6055c51f124SMoriah Waterland 
6065c51f124SMoriah Waterland 	nact.sa_handler = quitGetTrapHandler();
6075c51f124SMoriah Waterland 	nact.sa_flags = SA_RESTART;
6085c51f124SMoriah Waterland 	(void) sigemptyset(&nact.sa_mask);
6095c51f124SMoriah Waterland 
6105c51f124SMoriah Waterland 	(void) sigaction(SIGINT, &nact, &oact);
6115c51f124SMoriah Waterland 
6125c51f124SMoriah Waterland 	/* connect quit.c:trap() to SIGHUP */
6135c51f124SMoriah Waterland 
6145c51f124SMoriah Waterland 	nact.sa_handler = quitGetTrapHandler();
6155c51f124SMoriah Waterland 	nact.sa_flags = SA_RESTART;
6165c51f124SMoriah Waterland 	(void) sigemptyset(&nact.sa_mask);
6175c51f124SMoriah Waterland 
6185c51f124SMoriah Waterland 	(void) sigaction(SIGHUP, &nact, &oact);
6195c51f124SMoriah Waterland 
6205c51f124SMoriah Waterland 	/* release hold on signals */
6215c51f124SMoriah Waterland 
6225c51f124SMoriah Waterland 	(void) sigrelse(SIGHUP);
6235c51f124SMoriah Waterland 	(void) sigrelse(SIGINT);
6245c51f124SMoriah Waterland 
6255c51f124SMoriah Waterland 	/* establish temporary directory to use */
6265c51f124SMoriah Waterland 
6275c51f124SMoriah Waterland 	tmpdir = getenv("TMPDIR");
6285c51f124SMoriah Waterland 	if (tmpdir == NULL) {
6295c51f124SMoriah Waterland 		tmpdir = P_tmpdir;
6305c51f124SMoriah Waterland 	}
6315c51f124SMoriah Waterland 
6325c51f124SMoriah Waterland 	echoDebug(DBG_PKGRM_TMPDIR, tmpdir);
6335c51f124SMoriah Waterland 
6345c51f124SMoriah Waterland 	/* initialize path parameters */
6355c51f124SMoriah Waterland 
6365c51f124SMoriah Waterland 	set_PKGpaths(get_inst_root());
6375c51f124SMoriah Waterland 
6385c51f124SMoriah Waterland 	/*
6395c51f124SMoriah Waterland 	 * initialize installation admin parameters - if removing from a spool
6405c51f124SMoriah Waterland 	 * directory then the admin file is ignore.
6415c51f124SMoriah Waterland 	 */
6425c51f124SMoriah Waterland 
6435c51f124SMoriah Waterland 	if (spoolDir == NULL) {
6445c51f124SMoriah Waterland 		echoDebug(DBG_PKGRM_ADMINFILE, admnfile ? admnfile : "");
6455c51f124SMoriah Waterland 		setadminFile(admnfile);
6465c51f124SMoriah Waterland 	}
6475c51f124SMoriah Waterland 
6485c51f124SMoriah Waterland 	/*
6495c51f124SMoriah Waterland 	 * if running in the global zone, and non-global zones exist, then
6505c51f124SMoriah Waterland 	 * enable hollow package support so that any packages that are marked
6515c51f124SMoriah Waterland 	 * SUNW_PKG_HOLLOW=true will be correctly removed in non-global zones
6525c51f124SMoriah Waterland 	 * when removed directly in the global zone by the global zone admin.
6535c51f124SMoriah Waterland 	 */
6545c51f124SMoriah Waterland 
6555c51f124SMoriah Waterland 	if (is_depend_pkginfo_DB()) {
6565c51f124SMoriah Waterland 		echoDebug(DBG_PKGRM_HOLLOW_ENABLED);
6575c51f124SMoriah Waterland 	} else if ((z_running_in_global_zone() == B_TRUE) &&
6585c51f124SMoriah Waterland 		(z_non_global_zones_exist() == B_TRUE)) {
6595c51f124SMoriah Waterland 		echoDebug(DBG_PKGRM_ENABLING_HOLLOW);
6605c51f124SMoriah Waterland 		set_depend_pkginfo_DB(B_TRUE);
6615c51f124SMoriah Waterland 	}
6625c51f124SMoriah Waterland 
6635c51f124SMoriah Waterland 	/*
6645c51f124SMoriah Waterland 	 * See if user wants this to be handled as an old style pkg.
6655c51f124SMoriah Waterland 	 * NOTE : the ``exception_pkg()'' stuff is to be used only
6665c51f124SMoriah Waterland 	 * through on495. This function comes out for on1095. See
6675c51f124SMoriah Waterland 	 * PSARC 1993-546. -- JST
6685c51f124SMoriah Waterland 	 */
6695c51f124SMoriah Waterland 	if (getenv("NONABI_SCRIPTS") != NULL) {
6705c51f124SMoriah Waterland 		old_pkg = 1;
6715c51f124SMoriah Waterland 	}
6725c51f124SMoriah Waterland 
6735c51f124SMoriah Waterland 	/*
6745c51f124SMoriah Waterland 	 * See if the user wants to process symlinks consistent with
6755c51f124SMoriah Waterland 	 * the old behavior.
6765c51f124SMoriah Waterland 	 */
6775c51f124SMoriah Waterland 
6785c51f124SMoriah Waterland 	if (getenv("PKG_NONABI_SYMLINKS") != NULL) {
6795c51f124SMoriah Waterland 		old_symlinks = 1;
6805c51f124SMoriah Waterland 	}
6815c51f124SMoriah Waterland 
6825c51f124SMoriah Waterland 	if (devtype((spoolDir ? spoolDir : get_PKGLOC()), &pkgdev) ||
6835c51f124SMoriah Waterland 	    pkgdev.dirname == NULL) {
6845c51f124SMoriah Waterland 		progerr(ERR_BAD_DEVICE, spoolDir ? spoolDir : get_PKGLOC());
6855c51f124SMoriah Waterland 		quit(1);
6865c51f124SMoriah Waterland 		/* NOTREACHED */
6875c51f124SMoriah Waterland 	}
6885c51f124SMoriah Waterland 
6895c51f124SMoriah Waterland 	pkgdir = pkgdev.dirname;
6905c51f124SMoriah Waterland 	repeat = ((optind >= argc) && pkgdev.mount);
6915c51f124SMoriah Waterland 
6925c51f124SMoriah Waterland 	/*
6935c51f124SMoriah Waterland 	 * error if there are packages on the command line and a category
6945c51f124SMoriah Waterland 	 * was specified
6955c51f124SMoriah Waterland 	 */
6965c51f124SMoriah Waterland 
6975c51f124SMoriah Waterland 	if (optind < argc && catg_arg != NULL) {
6985c51f124SMoriah Waterland 		progerr(ERR_PKGS_AND_CAT_PKGRM);
6995c51f124SMoriah Waterland 		usage();
7005c51f124SMoriah Waterland 		/* NOTREACHED */
7015c51f124SMoriah Waterland 	}
7025c51f124SMoriah Waterland 
7035c51f124SMoriah Waterland 	/*
7045c51f124SMoriah Waterland 	 * ********************************************************************
7055c51f124SMoriah Waterland 	 * main package processing "loop"
7065c51f124SMoriah Waterland 	 * ********************************************************************
7075c51f124SMoriah Waterland 	 */
7085c51f124SMoriah Waterland 
7095c51f124SMoriah Waterland 	for (;;) {
7105c51f124SMoriah Waterland 		boolean_t	b;
7115c51f124SMoriah Waterland 		char		**pkglist;	/* points to array of pkgs */
7125c51f124SMoriah Waterland 
7135c51f124SMoriah Waterland 		/*
7145c51f124SMoriah Waterland 		 * mount the spool device if required
7155c51f124SMoriah Waterland 		 */
7165c51f124SMoriah Waterland 
7175c51f124SMoriah Waterland 		if (pkgdev.mount) {
7185c51f124SMoriah Waterland 			if (n = pkgmount(&pkgdev, NULL, 0, 0, 1)) {
7195c51f124SMoriah Waterland 				quit(n);
7205c51f124SMoriah Waterland 				/* NOTREACHED */
7215c51f124SMoriah Waterland 			}
7225c51f124SMoriah Waterland 		}
7235c51f124SMoriah Waterland 
7245c51f124SMoriah Waterland 		if (chdir(pkgdev.dirname)) {
7255c51f124SMoriah Waterland 			progerr(ERR_CHDIR, pkgdev.dirname);
7265c51f124SMoriah Waterland 			quit(1);
7275c51f124SMoriah Waterland 			/* NOTREACHED */
7285c51f124SMoriah Waterland 		}
7295c51f124SMoriah Waterland 
7305c51f124SMoriah Waterland 		/*
7315c51f124SMoriah Waterland 		 * spool device mounted/available - get the list of the
7325c51f124SMoriah Waterland 		 * packages to remove
7335c51f124SMoriah Waterland 		 */
7345c51f124SMoriah Waterland 
7355c51f124SMoriah Waterland 		n = pkgGetPackageList(&pkglist, argv, optind,
7365c51f124SMoriah Waterland 			catg_arg, category, &pkgdev);
7375c51f124SMoriah Waterland 
7385c51f124SMoriah Waterland 		switch (n) {
7395c51f124SMoriah Waterland 			case -1:	/* no packages found */
7405c51f124SMoriah Waterland 				echoDebug(DBG_PKGLIST_RM_NONFOUND,
7415c51f124SMoriah Waterland 					PSTR(pkgdev.dirname));
7425c51f124SMoriah Waterland 				progerr(ERR_NOPKGS, pkgdev.dirname);
7435c51f124SMoriah Waterland 				quit(1);
7445c51f124SMoriah Waterland 				/* NOTREACHED */
7455c51f124SMoriah Waterland 
7465c51f124SMoriah Waterland 			case 0:		/* packages found */
7475c51f124SMoriah Waterland 				break;
7485c51f124SMoriah Waterland 
7495c51f124SMoriah Waterland 			default:	/* "quit" error */
7505c51f124SMoriah Waterland 				echoDebug(DBG_PKGLIST_RM_ERROR,
7515c51f124SMoriah Waterland 					pkgdev.dirname, n);
7525c51f124SMoriah Waterland 				quit(n);
7535c51f124SMoriah Waterland 				/* NOTREACHED */
7545c51f124SMoriah Waterland 		}
7555c51f124SMoriah Waterland 
7565c51f124SMoriah Waterland 		/*
7575c51f124SMoriah Waterland 		 * count the number of packages to remove
7585c51f124SMoriah Waterland 		 * NOTE: npkgs is a global variable that is referenced by quit.c
7595c51f124SMoriah Waterland 		 * when error messages are generated - it is referenced directly
7605c51f124SMoriah Waterland 		 * by the other functions called below...
7615c51f124SMoriah Waterland 		 */
7625c51f124SMoriah Waterland 
7635c51f124SMoriah Waterland 		for (npkgs = 0; pkglist[npkgs] != (char *)NULL; /* void */) {
7645c51f124SMoriah Waterland 			pkgLgth = strlen(pkglist[npkgs]);
7655c51f124SMoriah Waterland 			if (pkgLgth > longestPkg) {
7665c51f124SMoriah Waterland 				longestPkg = pkgLgth;
7675c51f124SMoriah Waterland 			}
7685c51f124SMoriah Waterland 			echoDebug(DBG_PKG_SELECTED, npkgs, pkglist[npkgs]);
7695c51f124SMoriah Waterland 			npkgs++;
7705c51f124SMoriah Waterland 		}
7715c51f124SMoriah Waterland 
7725c51f124SMoriah Waterland 		/* output number of packages to be removed */
7735c51f124SMoriah Waterland 
7745c51f124SMoriah Waterland 		echoDebug(DBG_NUM_PKGS_TO_REMOVE, npkgs, longestPkg);
7755c51f124SMoriah Waterland 
7765c51f124SMoriah Waterland 		/*
7775c51f124SMoriah Waterland 		 * package list generated - remove packages
7785c51f124SMoriah Waterland 		 */
7795c51f124SMoriah Waterland 
7805c51f124SMoriah Waterland 		b = remove_packages(pkglist, nodelete, longestPkg, repeat,
7815c51f124SMoriah Waterland 			altBinDir, pkgdev.dirname, spoolDir, noZones);
7825c51f124SMoriah Waterland 
7835c51f124SMoriah Waterland 		/*
7845c51f124SMoriah Waterland 		 * unmount the spool directory if necessary
7855c51f124SMoriah Waterland 		 */
7865c51f124SMoriah Waterland 
7875c51f124SMoriah Waterland 		if (pkgdev.mount) {
7885c51f124SMoriah Waterland 			(void) chdir("/");
7895c51f124SMoriah Waterland 			if (pkgumount(&pkgdev)) {
7905c51f124SMoriah Waterland 				progerr(ERR_PKGUNMOUNT, pkgdev.bdevice);
7915c51f124SMoriah Waterland 				quit(99);
7925c51f124SMoriah Waterland 				/* NOTREACHED */
7935c51f124SMoriah Waterland 
7945c51f124SMoriah Waterland 			}
7955c51f124SMoriah Waterland 		}
7965c51f124SMoriah Waterland 
7975c51f124SMoriah Waterland 		/*
7985c51f124SMoriah Waterland 		 * continue with next sequence of packages if continue set
7995c51f124SMoriah Waterland 		 */
8005c51f124SMoriah Waterland 
8015c51f124SMoriah Waterland 		if (b == B_TRUE) {
8025c51f124SMoriah Waterland 			continue;
8035c51f124SMoriah Waterland 		}
8045c51f124SMoriah Waterland 
8055c51f124SMoriah Waterland 		/*
8065c51f124SMoriah Waterland 		 * not continuing - quit with 0 exit code
8075c51f124SMoriah Waterland 		 */
8085c51f124SMoriah Waterland 
8095c51f124SMoriah Waterland 		quit(0);
8105c51f124SMoriah Waterland 		/* NOTREACHED */
8115c51f124SMoriah Waterland #ifdef lint
8125c51f124SMoriah Waterland 		return (0);
8135c51f124SMoriah Waterland #endif	/* lint */
8145c51f124SMoriah Waterland 	}
8155c51f124SMoriah Waterland }
8165c51f124SMoriah Waterland 
8175c51f124SMoriah Waterland /*
8185c51f124SMoriah Waterland  * *****************************************************************************
8195c51f124SMoriah Waterland  * static internal (private) functions
8205c51f124SMoriah Waterland  * *****************************************************************************
8215c51f124SMoriah Waterland  */
8225c51f124SMoriah Waterland 
8235c51f124SMoriah Waterland /*
8245c51f124SMoriah Waterland  * Name:	doRemove
8255c51f124SMoriah Waterland  * Description:	Remove a package from the global zone, and optionally from one
8265c51f124SMoriah Waterland  *		or more non-global zones.
8275c51f124SMoriah Waterland  * Arguments:	a_nodelete: should the files and scripts remain installed?
8285c51f124SMoriah Waterland  *			- if != 0 pass -F flag to pkgremove - suppress
8295c51f124SMoriah Waterland  *			the removal of any files and any class action scripts
8305c51f124SMoriah Waterland  *			and suppress the running of any class action scripts.
8315c51f124SMoriah Waterland  *			The package files remain but the package looks like it
8325c51f124SMoriah Waterland  *			is not installed. This is mainly for use by upgrade.
8335c51f124SMoriah Waterland  *			- if == 0 do not pass -F flag to pkgremove - all
8345c51f124SMoriah Waterland  *			files and class action scripts are removed, and any
8355c51f124SMoriah Waterland  *			appropriate class action scripts are run.
8365c51f124SMoriah Waterland  *		a_altBinDir - pointer to string representing location of the
8375c51f124SMoriah Waterland  *			pkgremove executable to run. If not NULL, then pass
8385c51f124SMoriah Waterland  *			the path specified to the -b option to pkgremove.
8395c51f124SMoriah Waterland  *		a_longestPkg - length of the longest package "name" (for
8405c51f124SMoriah Waterland  *			output format alignment)
8415c51f124SMoriah Waterland  *		a_adminFile - pointer to string representing the admin
8425c51f124SMoriah Waterland  *			file to pass to pkgremove when removing a package from
8435c51f124SMoriah Waterland  *			the global zone only. Typically the admin file used for
8445c51f124SMoriah Waterland  *			the global zone is the admin file passed in by the user.
8455c51f124SMoriah Waterland  *			If this is == NULL no admin file is given to pkgremove.
8465c51f124SMoriah Waterland  *		a_zoneAdminFile - pointer to string representing the admin
8475c51f124SMoriah Waterland  *			file to pass to pkgremove when removing the package
8485c51f124SMoriah Waterland  *			from a non-global zone only. Typically the admin file
8495c51f124SMoriah Waterland  *			used for non-global zones supresses all checks since
8505c51f124SMoriah Waterland  *			the dependency checking is done for all zones first
8515c51f124SMoriah Waterland  *			before proceeding.
8525c51f124SMoriah Waterland  *			A zoneAdminFile MUST be specified if a_zlst != NULL.
8535c51f124SMoriah Waterland  *			A zoneAdminFile must NOT be specified if a_zlst == NULL.
8545c51f124SMoriah Waterland  *		a_zlst - list of zones to process; NULL if no zones to process.
8555c51f124SMoriah Waterland  * Returns:	int	(see ckreturn() function for details)
8565c51f124SMoriah Waterland  *		0 - success
8575c51f124SMoriah Waterland  *		1 - package operation failed (fatal error)
8585c51f124SMoriah Waterland  *		2 - non-fatal error (warning)
8595c51f124SMoriah Waterland  *		3 - user selected quit (operation interrupted)
8605c51f124SMoriah Waterland  *		4 - admin settings prevented operation
8615c51f124SMoriah Waterland  *		5 - interaction required and -n (non-interactive) specified
8625c51f124SMoriah Waterland  *		"10" will be added to indicate "immediate reboot required"
8635c51f124SMoriah Waterland  *		"20" will be added to indicate "reboot after install required"
8645c51f124SMoriah Waterland  */
8655c51f124SMoriah Waterland 
8665c51f124SMoriah Waterland static int
8675c51f124SMoriah Waterland doRemove(int a_nodelete, char *a_altBinDir, int a_longestPkg, char *a_adminFile,
8685c51f124SMoriah Waterland 	char *a_zoneAdminFile, zoneList_t a_zlst)
8695c51f124SMoriah Waterland {
8705c51f124SMoriah Waterland 	boolean_t	b;
8715c51f124SMoriah Waterland 	char		**inheritedPkgDirs;
8725c51f124SMoriah Waterland 	char		*zoneName;
8735c51f124SMoriah Waterland 	char		ans[MAX_INPUT];
8745c51f124SMoriah Waterland 	int		n;
8755c51f124SMoriah Waterland 	int		zoneIndex;
8765c51f124SMoriah Waterland 	int		zonesSkipped;
8775c51f124SMoriah Waterland 	struct pkginfo	*pinfo = (struct pkginfo *)NULL;
8785c51f124SMoriah Waterland 	zone_state_t	zst;
8795c51f124SMoriah Waterland 
8805c51f124SMoriah Waterland 	/* entry assertions */
8815c51f124SMoriah Waterland 
8825c51f124SMoriah Waterland 	if (a_zlst != (zoneList_t)NULL) {
8835c51f124SMoriah Waterland 		/* zone list specified - zone admin file required */
8845c51f124SMoriah Waterland 		assert(a_zoneAdminFile != (char *)NULL);
8855c51f124SMoriah Waterland 		assert(*a_zoneAdminFile != '\0');
8865c51f124SMoriah Waterland 	} else {
8875c51f124SMoriah Waterland 		/* no zone list specified - no zone admin file needed */
8885c51f124SMoriah Waterland 		assert(a_zoneAdminFile == (char *)NULL);
8895c51f124SMoriah Waterland 	}
8905c51f124SMoriah Waterland 
8915c51f124SMoriah Waterland 	/* NOTE: required 'pkgdir' set to spool directory or NULL */
8925c51f124SMoriah Waterland 	b = pkginfoIsPkgInstalled(&pinfo, pkginst);
8935c51f124SMoriah Waterland 	if (b == B_FALSE) {
8945c51f124SMoriah Waterland 		progerr(ERR_NO_SUCH_INSTANCE, pkginst);
8955c51f124SMoriah Waterland 		pkginfoFree(&pinfo);
8965c51f124SMoriah Waterland 		return (2);
8975c51f124SMoriah Waterland 	}
8985c51f124SMoriah Waterland 
8995c51f124SMoriah Waterland 	/* entry debugging info */
9005c51f124SMoriah Waterland 
9015c51f124SMoriah Waterland 	echoDebug(DBG_DOREMOVE_ENTRY);
9025c51f124SMoriah Waterland 	echoDebug(DBG_DOREMOVE_ARGS, PSTR(pinfo->pkginst), PSTR(pinfo->name),
9035c51f124SMoriah Waterland 		PSTR(pinfo->arch), PSTR(pinfo->version), PSTR(pinfo->basedir),
9045c51f124SMoriah Waterland 		PSTR(pinfo->catg), pinfo->status);
9055c51f124SMoriah Waterland 
9065c51f124SMoriah Waterland 	if (!nointeract) {
9075c51f124SMoriah Waterland 		char	fmt1[100];
9085c51f124SMoriah Waterland 
9095c51f124SMoriah Waterland 		/* create format based on max pkg name length */
9105c51f124SMoriah Waterland 
9115c51f124SMoriah Waterland 		(void) snprintf(fmt1, sizeof (fmt1), "   %%-%d.%ds  %%s",
9125c51f124SMoriah Waterland 				a_longestPkg, a_longestPkg);
9135c51f124SMoriah Waterland 
9145c51f124SMoriah Waterland 		if (pinfo->status == PI_SPOOLED) {
9155c51f124SMoriah Waterland 			echo(INFO_SPOOLED);
9165c51f124SMoriah Waterland 		} else {
9175c51f124SMoriah Waterland 			if (getuid()) {
9185c51f124SMoriah Waterland 				progerr(ERR_NOT_ROOT, get_prog_name());
9195c51f124SMoriah Waterland 				exit(1);
9205c51f124SMoriah Waterland 			}
9215c51f124SMoriah Waterland 			echo(INFO_INSTALL);
9225c51f124SMoriah Waterland 		}
9235c51f124SMoriah Waterland 
9245c51f124SMoriah Waterland 		echo(fmt1, pinfo->pkginst, pinfo->name);
9255c51f124SMoriah Waterland 
9265c51f124SMoriah Waterland 		if (pinfo->arch || pinfo->version) {
9275c51f124SMoriah Waterland 			char	fmt2[100];
9285c51f124SMoriah Waterland 
9295c51f124SMoriah Waterland 			/* create format based on max pkg name length */
9305c51f124SMoriah Waterland 
9315c51f124SMoriah Waterland 			(void) snprintf(fmt2, sizeof (fmt2), "   %%%d.%ds  ",
9325c51f124SMoriah Waterland 					a_longestPkg, a_longestPkg);
9335c51f124SMoriah Waterland 
9345c51f124SMoriah Waterland 			/* LINTED variable format specifier to fprintf() */
9355c51f124SMoriah Waterland 			(void) fprintf(stderr, fmt2, "");
9365c51f124SMoriah Waterland 
9375c51f124SMoriah Waterland 			if (pinfo->arch) {
9385c51f124SMoriah Waterland 				(void) fprintf(stderr, "(%s) ", pinfo->arch);
9395c51f124SMoriah Waterland 			}
9405c51f124SMoriah Waterland 
9415c51f124SMoriah Waterland 			if (pinfo->version) {
9425c51f124SMoriah Waterland 				(void) fprintf(stderr, "%s", pinfo->version);
9435c51f124SMoriah Waterland 			}
9445c51f124SMoriah Waterland 
9455c51f124SMoriah Waterland 			(void) fprintf(stderr, "\n");
9465c51f124SMoriah Waterland 		}
9475c51f124SMoriah Waterland 
9485c51f124SMoriah Waterland 		n = ckyorn(ans, NULL, NULL, NULL, ASK_CONFIRM);
9495c51f124SMoriah Waterland 		if (n != 0) {
9505c51f124SMoriah Waterland 			quit(n);
9515c51f124SMoriah Waterland 			/* NOTREACHED */
9525c51f124SMoriah Waterland 		}
9535c51f124SMoriah Waterland 
9545c51f124SMoriah Waterland 		if (strchr("yY", *ans) == NULL) {
9555c51f124SMoriah Waterland 			pkginfoFree(&pinfo);
9565c51f124SMoriah Waterland 			return (0);
9575c51f124SMoriah Waterland 		}
9585c51f124SMoriah Waterland 	}
9595c51f124SMoriah Waterland 
9605c51f124SMoriah Waterland 	if (pinfo->status == PI_PRESVR4) {
9615c51f124SMoriah Waterland 		pkginfoFree(&pinfo);
9625c51f124SMoriah Waterland 		return (presvr4(pkginst, nointeract));
9635c51f124SMoriah Waterland 	}
9645c51f124SMoriah Waterland 
9655c51f124SMoriah Waterland 	if (pinfo->status == PI_SPOOLED) {
9665c51f124SMoriah Waterland 		/* removal from a directory */
9675c51f124SMoriah Waterland 		echo(INFO_RMSPOOL, pkginst);
9685c51f124SMoriah Waterland 		pkginfoFree(&pinfo);
9695c51f124SMoriah Waterland 		return (rrmdir(pkginst));
9705c51f124SMoriah Waterland 	}
9715c51f124SMoriah Waterland 
9725c51f124SMoriah Waterland 	/* exit if not root */
9735c51f124SMoriah Waterland 
9745c51f124SMoriah Waterland 	if (getuid()) {
9755c51f124SMoriah Waterland 		progerr(ERR_NOT_ROOT, get_prog_name());
9765c51f124SMoriah Waterland 		exit(1);
9775c51f124SMoriah Waterland 	}
9785c51f124SMoriah Waterland 
9795c51f124SMoriah Waterland 	pkginfoFree(&pinfo);
9805c51f124SMoriah Waterland 
9815c51f124SMoriah Waterland 	zonesSkipped = 0;
9825c51f124SMoriah Waterland 
9835c51f124SMoriah Waterland 	if (interrupted != 0) {
9845c51f124SMoriah Waterland 		echo(MSG_DOREMOVE_INTERRUPTED_B4_Z, pkginst);
9855c51f124SMoriah Waterland 		echoDebug(MSG_DOREMOVE_INTERRUPTED_B4_Z, pkginst);
9865c51f124SMoriah Waterland 		return (n);
9875c51f124SMoriah Waterland 	}
9885c51f124SMoriah Waterland 
9895c51f124SMoriah Waterland 	echoDebug(DBG_REMOVE_FLAG_VALUES, "before pkgZoneRemove",
9905c51f124SMoriah Waterland 		admnflag, doreboot, failflag, interrupted,
9915c51f124SMoriah Waterland 		intrflag, ireboot, nullflag, warnflag);
9925c51f124SMoriah Waterland 
9935c51f124SMoriah Waterland 	for (zoneIndex = 0;
9945c51f124SMoriah Waterland 	    a_zlst != NULL &&
9955c51f124SMoriah Waterland 	    (zoneName = z_zlist_get_zonename(a_zlst, zoneIndex)) != NULL;
9965c51f124SMoriah Waterland 	    zoneIndex++) {
9975c51f124SMoriah Waterland 
9985c51f124SMoriah Waterland 		/* skip the zone if it is NOT running */
9995c51f124SMoriah Waterland 
10005c51f124SMoriah Waterland 		zst = z_zlist_get_current_state(a_zlst, zoneIndex);
10015c51f124SMoriah Waterland 		if (zst != ZONE_STATE_RUNNING && zst != ZONE_STATE_MOUNTED) {
10025c51f124SMoriah Waterland 			zonesSkipped++;
10035c51f124SMoriah Waterland 			echoDebug(DBG_SKIPPING_ZONE, zoneName);
10045c51f124SMoriah Waterland 			continue;
10055c51f124SMoriah Waterland 		}
10065c51f124SMoriah Waterland 
10075c51f124SMoriah Waterland 		echo(MSG_REMOVE_PKG_FROM_ZONE, pkginst, zoneName);
10085c51f124SMoriah Waterland 		echoDebug(DBG_REMOVE_PKG_FROM_ZONE, pkginst, zoneName);
10095c51f124SMoriah Waterland 
10105c51f124SMoriah Waterland 		/* determine list of directories inherited from global zone */
10115c51f124SMoriah Waterland 
10125c51f124SMoriah Waterland 		inheritedPkgDirs = z_zlist_get_inherited_pkg_dirs(a_zlst,
10135c51f124SMoriah Waterland 					zoneIndex);
10145c51f124SMoriah Waterland 
10155c51f124SMoriah Waterland 		/*
10165c51f124SMoriah Waterland 		 * remove package from zone; use the zone admin file which
10175c51f124SMoriah Waterland 		 * suppresses all checks.
10185c51f124SMoriah Waterland 		 */
10195c51f124SMoriah Waterland 
10205c51f124SMoriah Waterland 		n = pkgZoneRemove(z_zlist_get_scratch(a_zlst, zoneIndex),
10215c51f124SMoriah Waterland 			inheritedPkgDirs, a_nodelete, a_altBinDir,
1022*62224350SCasper H.S. Dik 			a_zoneAdminFile, zst, B_FALSE);
10235c51f124SMoriah Waterland 
10245c51f124SMoriah Waterland 		/* set success/fail condition variables */
10255c51f124SMoriah Waterland 
10265c51f124SMoriah Waterland 		ckreturn(n);
10275c51f124SMoriah Waterland 
10285c51f124SMoriah Waterland 		echoDebug(DBG_REMOVE_FLAG_VALUES, "after pkgZoneRemove",
10295c51f124SMoriah Waterland 			admnflag, doreboot, failflag, interrupted, intrflag,
10305c51f124SMoriah Waterland 			ireboot, nullflag, warnflag);
10315c51f124SMoriah Waterland 	}
10325c51f124SMoriah Waterland 
10335c51f124SMoriah Waterland 	if (zonesSkipped > 0) {
10345c51f124SMoriah Waterland 		echoDebug(DBG_ZONES_SKIPPED, zonesSkipped);
10355c51f124SMoriah Waterland 
10365c51f124SMoriah Waterland 		for (zoneIndex = 0;
10375c51f124SMoriah Waterland 			(zoneName = z_zlist_get_zonename(a_zlst, zoneIndex)) !=
10385c51f124SMoriah Waterland 				(char *)NULL; zoneIndex++) {
10395c51f124SMoriah Waterland 
10405c51f124SMoriah Waterland 			/* skip the zone if it IS running */
10415c51f124SMoriah Waterland 
10425c51f124SMoriah Waterland 			zst = z_zlist_get_current_state(a_zlst, zoneIndex);
10435c51f124SMoriah Waterland 			if (zst == ZONE_STATE_RUNNING ||
10445c51f124SMoriah Waterland 			    zst == ZONE_STATE_MOUNTED) {
10455c51f124SMoriah Waterland 				zonesSkipped++;
10465c51f124SMoriah Waterland 				echoDebug(DBG_SKIPPING_ZONE_BOOT, zoneName);
10475c51f124SMoriah Waterland 				continue;
10485c51f124SMoriah Waterland 			}
10495c51f124SMoriah Waterland 
10505c51f124SMoriah Waterland 			/* skip the zone if it is NOT bootable */
10515c51f124SMoriah Waterland 
10525c51f124SMoriah Waterland 			if (z_zlist_is_zone_runnable(a_zlst,
10535c51f124SMoriah Waterland 						zoneIndex) == B_FALSE) {
10545c51f124SMoriah Waterland 				echo(MSG_SKIPPING_ZONE_NOT_RUNNABLE, zoneName);
10555c51f124SMoriah Waterland 				echoDebug(DBG_SKIPPING_ZONE_NOT_RUNNABLE,
10565c51f124SMoriah Waterland 					zoneName);
10575c51f124SMoriah Waterland 				continue;
10585c51f124SMoriah Waterland 			}
10595c51f124SMoriah Waterland 
10605c51f124SMoriah Waterland 			/* mount up the zone */
10615c51f124SMoriah Waterland 
10625c51f124SMoriah Waterland 			echo(MSG_BOOTING_ZONE, zoneName);
10635c51f124SMoriah Waterland 			echoDebug(DBG_BOOTING_ZONE, zoneName);
10645c51f124SMoriah Waterland 
10655c51f124SMoriah Waterland 			b = z_zlist_change_zone_state(a_zlst, zoneIndex,
10665c51f124SMoriah Waterland 				ZONE_STATE_MOUNTED);
10675c51f124SMoriah Waterland 			if (b == B_FALSE) {
10685c51f124SMoriah Waterland 				progerr(ERR_CANNOT_BOOT_ZONE, zoneName);
10695c51f124SMoriah Waterland 				/* set fatal error return condition */
10705c51f124SMoriah Waterland 				ckreturn(1);
10715c51f124SMoriah Waterland 				continue;
10725c51f124SMoriah Waterland 			}
10735c51f124SMoriah Waterland 
10745c51f124SMoriah Waterland 			echo(MSG_REMOVE_PKG_FROM_ZONE, pkginst, zoneName);
10755c51f124SMoriah Waterland 
10765c51f124SMoriah Waterland 			/* determine list of dirs inherited from global zone */
10775c51f124SMoriah Waterland 
10785c51f124SMoriah Waterland 			inheritedPkgDirs =
10795c51f124SMoriah Waterland 				z_zlist_get_inherited_pkg_dirs(a_zlst,
10805c51f124SMoriah Waterland 						zoneIndex);
10815c51f124SMoriah Waterland 
10825c51f124SMoriah Waterland 			/*
10835c51f124SMoriah Waterland 			 * remove package from zone; use the zone admin file
10845c51f124SMoriah Waterland 			 * which suppresses all checks.
10855c51f124SMoriah Waterland 			 */
10865c51f124SMoriah Waterland 
10875c51f124SMoriah Waterland 			n = pkgZoneRemove(z_zlist_get_scratch(a_zlst,
10885c51f124SMoriah Waterland 				zoneIndex), inheritedPkgDirs,
10895c51f124SMoriah Waterland 				a_nodelete, a_altBinDir, a_zoneAdminFile,
1090*62224350SCasper H.S. Dik 				ZONE_STATE_MOUNTED, B_TRUE);
10915c51f124SMoriah Waterland 
10925c51f124SMoriah Waterland 			/* set success/fail condition variables */
10935c51f124SMoriah Waterland 
10945c51f124SMoriah Waterland 			ckreturn(n);
10955c51f124SMoriah Waterland 
10965c51f124SMoriah Waterland 			echoDebug(DBG_REMOVE_FLAG_VALUES, "after pkgZoneRemove",
10975c51f124SMoriah Waterland 				admnflag, doreboot, failflag, interrupted,
10985c51f124SMoriah Waterland 				intrflag, ireboot, nullflag, warnflag);
10995c51f124SMoriah Waterland 
11005c51f124SMoriah Waterland 			/* restore original state of zone */
11015c51f124SMoriah Waterland 
11025c51f124SMoriah Waterland 			echo(MSG_RESTORE_ZONE_STATE, zoneName);
11035c51f124SMoriah Waterland 			echoDebug(DBG_RESTORE_ZONE_STATE, zoneName);
11045c51f124SMoriah Waterland 
11055c51f124SMoriah Waterland 			b = z_zlist_restore_zone_state(a_zlst, zoneIndex);
11065c51f124SMoriah Waterland 		}
11075c51f124SMoriah Waterland 	}
11085c51f124SMoriah Waterland 
11095c51f124SMoriah Waterland 	/*
11105c51f124SMoriah Waterland 	 * Process global zone if it was either the only possible
11115c51f124SMoriah Waterland 	 * target (no list of zones specified) or it appears in the list
11125c51f124SMoriah Waterland 	 */
11135c51f124SMoriah Waterland 	if (a_zlst == NULL || z_on_zone_spec(GLOBAL_ZONENAME)) {
11145c51f124SMoriah Waterland 		/* reset interrupted flag before calling pkgremove */
11155c51f124SMoriah Waterland 		interrupted = 0;	/* last action was NOT quit */
11165c51f124SMoriah Waterland 
11175c51f124SMoriah Waterland 		/*
11185c51f124SMoriah Waterland 		 * call pkgremove for this package for the global zone;
11195c51f124SMoriah Waterland 		 * use the admin file passed in by the user via -a.
11205c51f124SMoriah Waterland 		 */
11215c51f124SMoriah Waterland 		n = pkgRemove(a_nodelete, a_altBinDir, a_adminFile,
11225c51f124SMoriah Waterland 		    z_get_inherited_file_systems());
11235c51f124SMoriah Waterland 
11245c51f124SMoriah Waterland 		/* set success/fail condition variables */
11255c51f124SMoriah Waterland 		ckreturn(n);
11265c51f124SMoriah Waterland 	}
11275c51f124SMoriah Waterland 
11285c51f124SMoriah Waterland 	return (n);
11295c51f124SMoriah Waterland }
11305c51f124SMoriah Waterland 
11315c51f124SMoriah Waterland /*
11325c51f124SMoriah Waterland  *  function to clear out any exisiting error return conditions that may have
11335c51f124SMoriah Waterland  *  been set by previous calls to ckreturn()
11345c51f124SMoriah Waterland  */
11355c51f124SMoriah Waterland static void
11365c51f124SMoriah Waterland resetreturn()
11375c51f124SMoriah Waterland {
11385c51f124SMoriah Waterland 	admnflag = 0;	/* != 0 if any pkg op admin setting failure (4) */
11395c51f124SMoriah Waterland 	doreboot = 0;	/* != 0 if reboot required after installation (>= 10) */
11405c51f124SMoriah Waterland 	failflag = 0;	/* != 0 if fatal error has occurred (1) */
11415c51f124SMoriah Waterland 	intrflag = 0;	/* != 0 if user selected quit (3) */
11425c51f124SMoriah Waterland 	ireboot = 0;	/* != 0 if immediate reboot required (>= 20) */
11435c51f124SMoriah Waterland 	nullflag = 0;	/* != 0 if admin interaction required (5) */
11445c51f124SMoriah Waterland 	warnflag = 0;	/* != 0 if non-fatal error has occurred (2) */
11455c51f124SMoriah Waterland 	interrupted = 0;	/* last pkg op was quit (1,2,3,4,5) */
11465c51f124SMoriah Waterland }
11475c51f124SMoriah Waterland 
11485c51f124SMoriah Waterland /*
11495c51f124SMoriah Waterland  *  function which checks the indicated return value
11505c51f124SMoriah Waterland  *  and indicates disposition of installation
11515c51f124SMoriah Waterland  */
11525c51f124SMoriah Waterland static void
11535c51f124SMoriah Waterland ckreturn(int retcode)
11545c51f124SMoriah Waterland {
11555c51f124SMoriah Waterland 	/*
11565c51f124SMoriah Waterland 	 * entry debugging info
11575c51f124SMoriah Waterland 	 */
11585c51f124SMoriah Waterland 
11595c51f124SMoriah Waterland 	echoDebug(DBG_PKGRM_CKRETURN, retcode, PSTR(pkginst));
11605c51f124SMoriah Waterland 
11615c51f124SMoriah Waterland 	switch (retcode) {
11625c51f124SMoriah Waterland 	    case  0:		/* successful */
11635c51f124SMoriah Waterland 	    case 10:
11645c51f124SMoriah Waterland 	    case 20:
11655c51f124SMoriah Waterland 		break; /* empty case */
11665c51f124SMoriah Waterland 
11675c51f124SMoriah Waterland 	    case  1:		/* package operation failed (fatal error) */
11685c51f124SMoriah Waterland 	    case 11:
11695c51f124SMoriah Waterland 	    case 21:
11705c51f124SMoriah Waterland 		failflag++;
11715c51f124SMoriah Waterland 		interrupted++;
11725c51f124SMoriah Waterland 		break;
11735c51f124SMoriah Waterland 
11745c51f124SMoriah Waterland 	    case  2:		/* non-fatal error (warning) */
11755c51f124SMoriah Waterland 	    case 12:
11765c51f124SMoriah Waterland 	    case 22:
11775c51f124SMoriah Waterland 		warnflag++;
11785c51f124SMoriah Waterland 		interrupted++;
11795c51f124SMoriah Waterland 		break;
11805c51f124SMoriah Waterland 
11815c51f124SMoriah Waterland 	    case  3:		/* user selected quit; operation interrupted */
11825c51f124SMoriah Waterland 	    case 13:
11835c51f124SMoriah Waterland 	    case 23:
11845c51f124SMoriah Waterland 		intrflag++;
11855c51f124SMoriah Waterland 		interrupted++;
11865c51f124SMoriah Waterland 		break;
11875c51f124SMoriah Waterland 
11885c51f124SMoriah Waterland 	    case  4:		/* admin settings prevented operation */
11895c51f124SMoriah Waterland 	    case 14:
11905c51f124SMoriah Waterland 	    case 24:
11915c51f124SMoriah Waterland 		admnflag++;
11925c51f124SMoriah Waterland 		interrupted++;
11935c51f124SMoriah Waterland 		break;
11945c51f124SMoriah Waterland 
11955c51f124SMoriah Waterland 	    case  5:		/* administration: interaction req (no -n) */
11965c51f124SMoriah Waterland 	    case 15:
11975c51f124SMoriah Waterland 	    case 25:
11985c51f124SMoriah Waterland 		nullflag++;
11995c51f124SMoriah Waterland 		interrupted++;
12005c51f124SMoriah Waterland 		break;
12015c51f124SMoriah Waterland 
12025c51f124SMoriah Waterland 	    default:
12035c51f124SMoriah Waterland 		failflag++;
12045c51f124SMoriah Waterland 		interrupted++;
12055c51f124SMoriah Waterland 		return;
12065c51f124SMoriah Waterland 	}
12075c51f124SMoriah Waterland 
12085c51f124SMoriah Waterland 	if (retcode >= 20) {
12095c51f124SMoriah Waterland 		ireboot++;
12105c51f124SMoriah Waterland 	} else if (retcode >= 10) {
12115c51f124SMoriah Waterland 		doreboot++;
12125c51f124SMoriah Waterland 	}
12135c51f124SMoriah Waterland }
12145c51f124SMoriah Waterland 
12155c51f124SMoriah Waterland static int
12165c51f124SMoriah Waterland pkgZoneCheckRemove(char *a_zoneName, char **a_inheritedPkgDirs,
12175c51f124SMoriah Waterland 	char *a_altBinDir, char *a_adminFile, char *a_stdoutPath,
1218*62224350SCasper H.S. Dik 	zone_state_t a_zoneState, boolean_t tmpzone)
12195c51f124SMoriah Waterland {
12205c51f124SMoriah Waterland 	char	*arg[MAXARGS];
12215c51f124SMoriah Waterland 	char	*p;
12225c51f124SMoriah Waterland 	char	adminfd_path[PATH_MAX];
12235c51f124SMoriah Waterland 	char	path[PATH_MAX];
12245c51f124SMoriah Waterland 	int	fds[MAX_FDS];
12255c51f124SMoriah Waterland 	int	maxfds;
12265c51f124SMoriah Waterland 	int	n;
12275c51f124SMoriah Waterland 	int	nargs;
12285c51f124SMoriah Waterland 
12295c51f124SMoriah Waterland 	/* entry assertions */
12305c51f124SMoriah Waterland 
12315c51f124SMoriah Waterland 	assert(a_zoneName != (char *)NULL);
12325c51f124SMoriah Waterland 	assert(*a_zoneName != '\0');
12335c51f124SMoriah Waterland 
12345c51f124SMoriah Waterland 	/* entry debugging info */
12355c51f124SMoriah Waterland 
12365c51f124SMoriah Waterland 	echoDebug(DBG_PKGZONECHECKREMOVE_ENTRY);
12375c51f124SMoriah Waterland 	echoDebug(DBG_PKGZONECHECKREMOVE_ARGS, a_zoneName, PSTR(pkginst),
12385c51f124SMoriah Waterland 		PSTR(pkgdev.dirname), PSTR(a_adminFile), PSTR(a_stdoutPath));
12395c51f124SMoriah Waterland 
12405c51f124SMoriah Waterland 	/* generate path to pkgremove */
12415c51f124SMoriah Waterland 
12425c51f124SMoriah Waterland 	(void) snprintf(path, sizeof (path), "%s/pkgremove",
12435c51f124SMoriah Waterland 		a_altBinDir == (char *)NULL ? PKGBIN : a_altBinDir);
12445c51f124SMoriah Waterland 
12455c51f124SMoriah Waterland 	/* start at first file descriptor */
12465c51f124SMoriah Waterland 
12475c51f124SMoriah Waterland 	maxfds = 0;
12485c51f124SMoriah Waterland 
12495c51f124SMoriah Waterland 	/*
12505c51f124SMoriah Waterland 	 * generate argument list for call to pkgremove
12515c51f124SMoriah Waterland 	 */
12525c51f124SMoriah Waterland 
12535c51f124SMoriah Waterland 	/* start at argument 0 */
12545c51f124SMoriah Waterland 
12555c51f124SMoriah Waterland 	nargs = 0;
12565c51f124SMoriah Waterland 
12575c51f124SMoriah Waterland 	/* first argument is path to executable */
12585c51f124SMoriah Waterland 
12595c51f124SMoriah Waterland 	arg[nargs++] = strdup(path);
12605c51f124SMoriah Waterland 
12615c51f124SMoriah Waterland 	/* second argument is always: pass -O debug to pkgremove: debug mode */
12625c51f124SMoriah Waterland 
12635c51f124SMoriah Waterland 	if (debugFlag == B_TRUE) {
12645c51f124SMoriah Waterland 		arg[nargs++] = "-O";
12655c51f124SMoriah Waterland 		arg[nargs++] = "debug";
12665c51f124SMoriah Waterland 	}
12675c51f124SMoriah Waterland 
12685c51f124SMoriah Waterland 	/* pkgrm -b dir: pass -b to pkgremove */
12695c51f124SMoriah Waterland 
12705c51f124SMoriah Waterland 	if (a_altBinDir != (char *)NULL) {
12715c51f124SMoriah Waterland 		arg[nargs++] = "-b";
12725c51f124SMoriah Waterland 		arg[nargs++] = a_altBinDir;
12735c51f124SMoriah Waterland 	}
12745c51f124SMoriah Waterland 
12755c51f124SMoriah Waterland 	/*
12765c51f124SMoriah Waterland 	 * NONABI_SCRIPTS defined: pass -o to pkgremove; refers to a
12775c51f124SMoriah Waterland 	 * pkg requiring operator interaction during a procedure script
12785c51f124SMoriah Waterland 	 * (common before on1093)
12795c51f124SMoriah Waterland 	 */
12805c51f124SMoriah Waterland 
12815c51f124SMoriah Waterland 	if (old_pkg) {
12825c51f124SMoriah Waterland 		arg[nargs++] = "-o";
12835c51f124SMoriah Waterland 	}
12845c51f124SMoriah Waterland 
12855c51f124SMoriah Waterland 	/*
12865c51f124SMoriah Waterland 	 * PKG_NONABI_SYMLINKS defined: pass -y to pkgremove; process
12875c51f124SMoriah Waterland 	 * symlinks consistent with old behavior
12885c51f124SMoriah Waterland 	 */
12895c51f124SMoriah Waterland 
12905c51f124SMoriah Waterland 	if (old_symlinks) {
12915c51f124SMoriah Waterland 		arg[nargs++] = "-y";
12925c51f124SMoriah Waterland 	}
12935c51f124SMoriah Waterland 
12945c51f124SMoriah Waterland 	/* pkgrm -M: pass -M to pkgremove: don't mount client file systems */
12955c51f124SMoriah Waterland 
12965c51f124SMoriah Waterland 	arg[nargs++] = "-M";
12975c51f124SMoriah Waterland 
12985c51f124SMoriah Waterland 	/* pkgrm -A: pass -A to pkgremove */
12995c51f124SMoriah Waterland 
13005c51f124SMoriah Waterland 	if (pkgrmremote) {
13015c51f124SMoriah Waterland 		arg[nargs++] = "-A";
13025c51f124SMoriah Waterland 	}
13035c51f124SMoriah Waterland 
13045c51f124SMoriah Waterland 	/* pkgrm -v: pass -v to pkgremove: never trace scripts */
13055c51f124SMoriah Waterland 
13065c51f124SMoriah Waterland 	/* pass "-O enable-hollow-package-support" */
13075c51f124SMoriah Waterland 
13085c51f124SMoriah Waterland 	if (is_depend_pkginfo_DB()) {
13095c51f124SMoriah Waterland 		arg[nargs++] = "-O";
13105c51f124SMoriah Waterland 		arg[nargs++] = "enable-hollow-package-support";
13115c51f124SMoriah Waterland 	}
13125c51f124SMoriah Waterland 
13135c51f124SMoriah Waterland 	/* pass -n to pkgremove: always in noninteractive mode */
13145c51f124SMoriah Waterland 
13155c51f124SMoriah Waterland 	arg[nargs++] = "-n";
13165c51f124SMoriah Waterland 
13175c51f124SMoriah Waterland 	/* pkgrm -a admin: pass -a admin to pkgremove: admin file */
13185c51f124SMoriah Waterland 
13195c51f124SMoriah Waterland 	if (a_adminFile) {
13205c51f124SMoriah Waterland 		int fd;
13215c51f124SMoriah Waterland 		fd = openLocal(a_adminFile, O_RDONLY, tmpdir);
13225c51f124SMoriah Waterland 		if (fd < 0) {
13235c51f124SMoriah Waterland 			progerr(ERR_CANNOT_COPY_LOCAL, a_adminFile,
13245c51f124SMoriah Waterland 				errno, strerror(errno));
13255c51f124SMoriah Waterland 			return (1);
13265c51f124SMoriah Waterland 		}
13275c51f124SMoriah Waterland 		(void) snprintf(adminfd_path, sizeof (adminfd_path),
13285c51f124SMoriah Waterland 			"/proc/self/fd/%d", fd);
13295c51f124SMoriah Waterland 		fds[maxfds++] = fd;
13305c51f124SMoriah Waterland 		arg[nargs++] = "-a";
13315c51f124SMoriah Waterland 		arg[nargs++] = strdup(adminfd_path);
13325c51f124SMoriah Waterland 	}
13335c51f124SMoriah Waterland 
13345c51f124SMoriah Waterland 	/*
13355c51f124SMoriah Waterland 	 * pkgadd -R root: pass -R /a to pkgremove in mounted zone
13365c51f124SMoriah Waterland 	 */
13375c51f124SMoriah Waterland 	if (a_zoneState == ZONE_STATE_MOUNTED) {
13385c51f124SMoriah Waterland 		arg[nargs++] = "-R";
13395c51f124SMoriah Waterland 		arg[nargs++] = "/a";
13405c51f124SMoriah Waterland 	}
13415c51f124SMoriah Waterland 
13425c51f124SMoriah Waterland 	/* pkgrm -F: pass -F to pkgremove: always update DB only */
13435c51f124SMoriah Waterland 
13445c51f124SMoriah Waterland 	arg[nargs++] = "-F";
13455c51f124SMoriah Waterland 
13465c51f124SMoriah Waterland 	/* pass "-O preremovecheck" */
13475c51f124SMoriah Waterland 
13485c51f124SMoriah Waterland 	arg[nargs++] = "-O";
13495c51f124SMoriah Waterland 	arg[nargs++] = "preremovecheck";
13505c51f124SMoriah Waterland 
13515c51f124SMoriah Waterland 	/* add "-O addzonename" */
13525c51f124SMoriah Waterland 
13535c51f124SMoriah Waterland 	arg[nargs++] = "-O";
13545c51f124SMoriah Waterland 	arg[nargs++] = "addzonename";
13555c51f124SMoriah Waterland 
13565c51f124SMoriah Waterland 	/* add all inherited file systems */
13575c51f124SMoriah Waterland 
13585c51f124SMoriah Waterland 	if (a_inheritedPkgDirs != (char **)NULL) {
13595c51f124SMoriah Waterland 		for (n = 0; a_inheritedPkgDirs[n] != (char *)NULL; n++) {
13605c51f124SMoriah Waterland 			char	ifs[MAXPATHLEN+22];
13615c51f124SMoriah Waterland 			(void) snprintf(ifs, sizeof (ifs),
13625c51f124SMoriah Waterland 				"inherited-filesystem=%s",
13635c51f124SMoriah Waterland 				a_inheritedPkgDirs[n]);
13645c51f124SMoriah Waterland 			arg[nargs++] = "-O";
13655c51f124SMoriah Waterland 			arg[nargs++] = strdup(ifs);
13665c51f124SMoriah Waterland 		}
13675c51f124SMoriah Waterland 	}
13685c51f124SMoriah Waterland 
13695c51f124SMoriah Waterland 	/*
13705c51f124SMoriah Waterland 	 * add parent zone info/type
13715c51f124SMoriah Waterland 	 */
13725c51f124SMoriah Waterland 
13735c51f124SMoriah Waterland 	p = z_get_zonename();
13745c51f124SMoriah Waterland 	if ((p != NULL) && (*p != '\0')) {
13755c51f124SMoriah Waterland 			char	zn[MAXPATHLEN];
13765c51f124SMoriah Waterland 			(void) snprintf(zn, sizeof (zn),
13775c51f124SMoriah Waterland 				"parent-zone-name=%s", p);
13785c51f124SMoriah Waterland 			arg[nargs++] = "-O";
13795c51f124SMoriah Waterland 			arg[nargs++] = strdup(zn);
13805c51f124SMoriah Waterland 	}
13815c51f124SMoriah Waterland 
13825c51f124SMoriah Waterland 	/* current zone type */
13835c51f124SMoriah Waterland 
13845c51f124SMoriah Waterland 	arg[nargs++] = "-O";
13855c51f124SMoriah Waterland 	if (z_running_in_global_zone() == B_TRUE) {
13865c51f124SMoriah Waterland 			char	zn[MAXPATHLEN];
13875c51f124SMoriah Waterland 			(void) snprintf(zn, sizeof (zn),
13885c51f124SMoriah Waterland 				"parent-zone-type=%s",
13895c51f124SMoriah Waterland 				TAG_VALUE_GLOBAL_ZONE);
13905c51f124SMoriah Waterland 			arg[nargs++] = strdup(zn);
13915c51f124SMoriah Waterland 	} else {
13925c51f124SMoriah Waterland 			char	zn[MAXPATHLEN];
13935c51f124SMoriah Waterland 			(void) snprintf(zn, sizeof (zn),
13945c51f124SMoriah Waterland 				"parent-zone-type=%s",
13955c51f124SMoriah Waterland 				TAG_VALUE_NONGLOBAL_ZONE);
13965c51f124SMoriah Waterland 			arg[nargs++] = strdup(zn);
13975c51f124SMoriah Waterland 	}
13985c51f124SMoriah Waterland 
1399*62224350SCasper H.S. Dik 	/* Add arguments how to start the pkgserv */
1400*62224350SCasper H.S. Dik 
1401*62224350SCasper H.S. Dik 	arg[nargs++] = "-O";
1402*62224350SCasper H.S. Dik 	arg[nargs++] = pkgmodeargument(tmpzone ? RUN_ONCE : pkgservergetmode());
1403*62224350SCasper H.S. Dik 
14045c51f124SMoriah Waterland 	/* pass -N to pkgremove: program name to report */
14055c51f124SMoriah Waterland 
14065c51f124SMoriah Waterland 	arg[nargs++] = "-N";
14075c51f124SMoriah Waterland 	arg[nargs++] = get_prog_name();
14085c51f124SMoriah Waterland 
14095c51f124SMoriah Waterland 	/* add package instance name */
14105c51f124SMoriah Waterland 
14115c51f124SMoriah Waterland 	arg[nargs++] = pkginst;
14125c51f124SMoriah Waterland 
14135c51f124SMoriah Waterland 	/* terminate argument list */
14145c51f124SMoriah Waterland 
14155c51f124SMoriah Waterland 	arg[nargs++] = NULL;
14165c51f124SMoriah Waterland 
14175c51f124SMoriah Waterland 	/* execute pkgremove command */
14185c51f124SMoriah Waterland 
14195c51f124SMoriah Waterland 	if (debugFlag == B_TRUE) {
14205c51f124SMoriah Waterland 		echoDebug(DBG_ZONE_EXEC_ENTER, a_zoneName, arg[0]);
14215c51f124SMoriah Waterland 		for (n = 0; arg[n]; n++) {
14225c51f124SMoriah Waterland 			echoDebug(DBG_ARG, n, arg[n]);
14235c51f124SMoriah Waterland 		}
14245c51f124SMoriah Waterland 	}
14255c51f124SMoriah Waterland 
14265c51f124SMoriah Waterland 	/* terminate file descriptor list */
14275c51f124SMoriah Waterland 
14285c51f124SMoriah Waterland 	fds[maxfds] = -1;
14295c51f124SMoriah Waterland 
14305c51f124SMoriah Waterland 	/* exec command in zone */
14315c51f124SMoriah Waterland 
14325c51f124SMoriah Waterland 	n = z_zone_exec(a_zoneName, path, arg, a_stdoutPath, (char *)NULL, fds);
14335c51f124SMoriah Waterland 
14345c51f124SMoriah Waterland 	echoDebug(DBG_ZONE_EXEC_EXIT, a_zoneName, arg[0], n,
14355c51f124SMoriah Waterland 			PSTR(a_stdoutPath));
14365c51f124SMoriah Waterland 
14375c51f124SMoriah Waterland 	/*
14385c51f124SMoriah Waterland 	 * close any files that were opened for use by the
14395c51f124SMoriah Waterland 	 * /proc/self/fd interface so they could be passed to programs
14405c51f124SMoriah Waterland 	 * via the z_zone_exec() interface
14415c51f124SMoriah Waterland 	 */
14425c51f124SMoriah Waterland 
14435c51f124SMoriah Waterland 	for (; maxfds > 0; maxfds--) {
14445c51f124SMoriah Waterland 		(void) close(fds[maxfds-1]);
14455c51f124SMoriah Waterland 	}
14465c51f124SMoriah Waterland 
14475c51f124SMoriah Waterland 	/* return results of pkgremove in zone execution */
14485c51f124SMoriah Waterland 
14495c51f124SMoriah Waterland 	return (n);
14505c51f124SMoriah Waterland }
14515c51f124SMoriah Waterland 
14525c51f124SMoriah Waterland static int
14535c51f124SMoriah Waterland pkgZoneRemove(char *a_zoneName, char **a_inheritedPkgDirs,
14545c51f124SMoriah Waterland 	int a_nodelete, char *a_altBinDir, char *a_adminFile,
1455*62224350SCasper H.S. Dik 	zone_state_t a_zoneState, boolean_t tmpzone)
14565c51f124SMoriah Waterland {
14575c51f124SMoriah Waterland 	char	*arg[MAXARGS];
14585c51f124SMoriah Waterland 	char	*p;
14595c51f124SMoriah Waterland 	char	adminfd_path[PATH_MAX];
14605c51f124SMoriah Waterland 	char	path[PATH_MAX];
14615c51f124SMoriah Waterland 	int	fds[MAX_FDS];
14625c51f124SMoriah Waterland 	int	maxfds;
14635c51f124SMoriah Waterland 	int	n;
14645c51f124SMoriah Waterland 	int	nargs;
14655c51f124SMoriah Waterland 
14665c51f124SMoriah Waterland 	/* entry assertions */
14675c51f124SMoriah Waterland 
14685c51f124SMoriah Waterland 	assert(a_zoneName != (char *)NULL);
14695c51f124SMoriah Waterland 	assert(*a_zoneName != '\0');
14705c51f124SMoriah Waterland 
14715c51f124SMoriah Waterland 	/* entry debugging info */
14725c51f124SMoriah Waterland 
14735c51f124SMoriah Waterland 	echoDebug(DBG_PKGZONEREMOVE_ENTRY);
14745c51f124SMoriah Waterland 	echoDebug(DBG_PKGZONEREMOVE_ARGS, a_zoneName, PSTR(pkginst),
14755c51f124SMoriah Waterland 		PSTR(pkgdev.dirname), a_nodelete, PSTR(a_adminFile));
14765c51f124SMoriah Waterland 
14775c51f124SMoriah Waterland 	/* generate path to pkgremove */
14785c51f124SMoriah Waterland 
14795c51f124SMoriah Waterland 	(void) snprintf(path, sizeof (path), "%s/pkgremove",
14805c51f124SMoriah Waterland 		a_altBinDir == (char *)NULL ? PKGBIN : a_altBinDir);
14815c51f124SMoriah Waterland 
14825c51f124SMoriah Waterland 	/* start at first file descriptor */
14835c51f124SMoriah Waterland 
14845c51f124SMoriah Waterland 	maxfds = 0;
14855c51f124SMoriah Waterland 
14865c51f124SMoriah Waterland 	/*
14875c51f124SMoriah Waterland 	 * generate argument list for call to pkgremove
14885c51f124SMoriah Waterland 	 */
14895c51f124SMoriah Waterland 
14905c51f124SMoriah Waterland 	/* start at argument 0 */
14915c51f124SMoriah Waterland 
14925c51f124SMoriah Waterland 	nargs = 0;
14935c51f124SMoriah Waterland 
14945c51f124SMoriah Waterland 	/* first argument is path to executable */
14955c51f124SMoriah Waterland 
14965c51f124SMoriah Waterland 	arg[nargs++] = strdup(path);
14975c51f124SMoriah Waterland 
14985c51f124SMoriah Waterland 	/* second argument is always: pass -O debug to pkgremove: debug mode */
14995c51f124SMoriah Waterland 
15005c51f124SMoriah Waterland 	if (debugFlag == B_TRUE) {
15015c51f124SMoriah Waterland 		arg[nargs++] = "-O";
15025c51f124SMoriah Waterland 		arg[nargs++] = "debug";
15035c51f124SMoriah Waterland 	}
15045c51f124SMoriah Waterland 
15055c51f124SMoriah Waterland 	/* pkgrm -b dir: pass -b to pkgremove */
15065c51f124SMoriah Waterland 
15075c51f124SMoriah Waterland 	if (a_altBinDir != (char *)NULL) {
15085c51f124SMoriah Waterland 		arg[nargs++] = "-b";
15095c51f124SMoriah Waterland 		arg[nargs++] = a_altBinDir;
15105c51f124SMoriah Waterland 	}
15115c51f124SMoriah Waterland 
15125c51f124SMoriah Waterland 	/*
15135c51f124SMoriah Waterland 	 * NONABI_SCRIPTS defined: pass -o to pkgremove; refers to a
15145c51f124SMoriah Waterland 	 * pkg requiring operator interaction during a procedure script
15155c51f124SMoriah Waterland 	 * (common before on1093)
15165c51f124SMoriah Waterland 	 */
15175c51f124SMoriah Waterland 
15185c51f124SMoriah Waterland 	if (old_pkg) {
15195c51f124SMoriah Waterland 		arg[nargs++] = "-o";
15205c51f124SMoriah Waterland 	}
15215c51f124SMoriah Waterland 
15225c51f124SMoriah Waterland 	/*
15235c51f124SMoriah Waterland 	 * PKG_NONABI_SYMLINKS defined: pass -y to pkgremove; process
15245c51f124SMoriah Waterland 	 * symlinks consistent with old behavior
15255c51f124SMoriah Waterland 	 */
15265c51f124SMoriah Waterland 
15275c51f124SMoriah Waterland 	if (old_symlinks) {
15285c51f124SMoriah Waterland 		arg[nargs++] = "-y";
15295c51f124SMoriah Waterland 	}
15305c51f124SMoriah Waterland 
15315c51f124SMoriah Waterland 	/* pkgrm -M: pass -M to pkgremove: don't mount client file systems */
15325c51f124SMoriah Waterland 
15335c51f124SMoriah Waterland 	arg[nargs++] = "-M";
15345c51f124SMoriah Waterland 
15355c51f124SMoriah Waterland 	/* pkgrm -A: pass -A to pkgremove */
15365c51f124SMoriah Waterland 
15375c51f124SMoriah Waterland 	if (pkgrmremote) {
15385c51f124SMoriah Waterland 		arg[nargs++] = "-A";
15395c51f124SMoriah Waterland 	}
15405c51f124SMoriah Waterland 
15415c51f124SMoriah Waterland 	/* pkgrm -v: pass -v to pkgremove: trace scripts */
15425c51f124SMoriah Waterland 
15435c51f124SMoriah Waterland 	if (pkgverbose) {
15445c51f124SMoriah Waterland 		arg[nargs++] = "-v";
15455c51f124SMoriah Waterland 	}
15465c51f124SMoriah Waterland 
15475c51f124SMoriah Waterland 	/* pass "-O enable-hollow-package-support" */
15485c51f124SMoriah Waterland 
15495c51f124SMoriah Waterland 	if (is_depend_pkginfo_DB()) {
15505c51f124SMoriah Waterland 		arg[nargs++] = "-O";
15515c51f124SMoriah Waterland 		arg[nargs++] = "enable-hollow-package-support";
15525c51f124SMoriah Waterland 	}
15535c51f124SMoriah Waterland 
15545c51f124SMoriah Waterland 	/* pkgrm -n: pass -n to pkgremove: noninteractive mode */
15555c51f124SMoriah Waterland 
15565c51f124SMoriah Waterland 	if (nointeract) {
15575c51f124SMoriah Waterland 		arg[nargs++] = "-n";
15585c51f124SMoriah Waterland 	}
15595c51f124SMoriah Waterland 
15605c51f124SMoriah Waterland 	/* pkgrm -a admin: pass -a admin to pkgremove: admin file */
15615c51f124SMoriah Waterland 
15625c51f124SMoriah Waterland 	if (a_adminFile) {
15635c51f124SMoriah Waterland 		int fd;
15645c51f124SMoriah Waterland 		fd = openLocal(a_adminFile, O_RDONLY, tmpdir);
15655c51f124SMoriah Waterland 		if (fd < 0) {
15665c51f124SMoriah Waterland 			progerr(ERR_CANNOT_COPY_LOCAL, a_adminFile,
15675c51f124SMoriah Waterland 				errno, strerror(errno));
15685c51f124SMoriah Waterland 			return (1);
15695c51f124SMoriah Waterland 		}
15705c51f124SMoriah Waterland 		(void) snprintf(adminfd_path, sizeof (adminfd_path),
15715c51f124SMoriah Waterland 			"/proc/self/fd/%d", fd);
15725c51f124SMoriah Waterland 		fds[maxfds++] = fd;
15735c51f124SMoriah Waterland 		arg[nargs++] = "-a";
15745c51f124SMoriah Waterland 		arg[nargs++] = adminfd_path;
15755c51f124SMoriah Waterland 	}
15765c51f124SMoriah Waterland 
15775c51f124SMoriah Waterland 	/*
15785c51f124SMoriah Waterland 	 * pkgadd -R root: pass -R /a to pkgremove in mounted zone
15795c51f124SMoriah Waterland 	 */
15805c51f124SMoriah Waterland 	if (a_zoneState == ZONE_STATE_MOUNTED) {
15815c51f124SMoriah Waterland 		arg[nargs++] = "-R";
15825c51f124SMoriah Waterland 		arg[nargs++] = "/a";
15835c51f124SMoriah Waterland 	}
15845c51f124SMoriah Waterland 
15855c51f124SMoriah Waterland 	/* pkgrm -F: pass -F to pkgremove: update DB only */
15865c51f124SMoriah Waterland 
15875c51f124SMoriah Waterland 	if (a_nodelete) {
15885c51f124SMoriah Waterland 		arg[nargs++] = "-F";
15895c51f124SMoriah Waterland 	}
15905c51f124SMoriah Waterland 
15915c51f124SMoriah Waterland 	/* add "-O addzonename" */
15925c51f124SMoriah Waterland 
15935c51f124SMoriah Waterland 	arg[nargs++] = "-O";
15945c51f124SMoriah Waterland 	arg[nargs++] = "addzonename";
15955c51f124SMoriah Waterland 
15965c51f124SMoriah Waterland 	/* add all inherited file systems */
15975c51f124SMoriah Waterland 
15985c51f124SMoriah Waterland 	if (a_inheritedPkgDirs != (char **)NULL) {
15995c51f124SMoriah Waterland 		for (n = 0; a_inheritedPkgDirs[n] != (char *)NULL; n++) {
16005c51f124SMoriah Waterland 			char	ifs[MAXPATHLEN+22];
16015c51f124SMoriah Waterland 
16025c51f124SMoriah Waterland 			(void) snprintf(ifs, sizeof (ifs),
16035c51f124SMoriah Waterland 				"inherited-filesystem=%s",
16045c51f124SMoriah Waterland 				a_inheritedPkgDirs[n]);
16055c51f124SMoriah Waterland 			arg[nargs++] = "-O";
16065c51f124SMoriah Waterland 			arg[nargs++] = strdup(ifs);
16075c51f124SMoriah Waterland 		}
16085c51f124SMoriah Waterland 	}
16095c51f124SMoriah Waterland 
16105c51f124SMoriah Waterland 	/*
16115c51f124SMoriah Waterland 	 * add parent zone info/type
16125c51f124SMoriah Waterland 	 */
16135c51f124SMoriah Waterland 
16145c51f124SMoriah Waterland 	p = z_get_zonename();
16155c51f124SMoriah Waterland 	if ((p != NULL) && (*p != '\0')) {
16165c51f124SMoriah Waterland 			char	zn[MAXPATHLEN];
16175c51f124SMoriah Waterland 			(void) snprintf(zn, sizeof (zn),
16185c51f124SMoriah Waterland 				"parent-zone-name=%s", p);
16195c51f124SMoriah Waterland 			arg[nargs++] = "-O";
16205c51f124SMoriah Waterland 			arg[nargs++] = strdup(zn);
16215c51f124SMoriah Waterland 	}
16225c51f124SMoriah Waterland 
16235c51f124SMoriah Waterland 	/* current zone type */
16245c51f124SMoriah Waterland 
16255c51f124SMoriah Waterland 	arg[nargs++] = "-O";
16265c51f124SMoriah Waterland 	if (z_running_in_global_zone() == B_TRUE) {
16275c51f124SMoriah Waterland 			char	zn[MAXPATHLEN];
16285c51f124SMoriah Waterland 			(void) snprintf(zn, sizeof (zn),
16295c51f124SMoriah Waterland 				"parent-zone-type=%s",
16305c51f124SMoriah Waterland 				TAG_VALUE_GLOBAL_ZONE);
16315c51f124SMoriah Waterland 			arg[nargs++] = strdup(zn);
16325c51f124SMoriah Waterland 	} else {
16335c51f124SMoriah Waterland 			char	zn[MAXPATHLEN];
16345c51f124SMoriah Waterland 			(void) snprintf(zn, sizeof (zn),
16355c51f124SMoriah Waterland 				"parent-zone-type=%s",
16365c51f124SMoriah Waterland 				TAG_VALUE_NONGLOBAL_ZONE);
16375c51f124SMoriah Waterland 			arg[nargs++] = strdup(zn);
16385c51f124SMoriah Waterland 	}
16395c51f124SMoriah Waterland 
1640*62224350SCasper H.S. Dik 	/* Add arguments how to start the pkgserv */
1641*62224350SCasper H.S. Dik 
1642*62224350SCasper H.S. Dik 	arg[nargs++] = "-O";
1643*62224350SCasper H.S. Dik 	arg[nargs++] = pkgmodeargument(tmpzone ? RUN_ONCE : pkgservergetmode());
1644*62224350SCasper H.S. Dik 
16455c51f124SMoriah Waterland 	/* pass -N to pkgremove: program name to report */
16465c51f124SMoriah Waterland 
16475c51f124SMoriah Waterland 	arg[nargs++] = "-N";
16485c51f124SMoriah Waterland 	arg[nargs++] = get_prog_name();
16495c51f124SMoriah Waterland 
16505c51f124SMoriah Waterland 	/* add package instance name */
16515c51f124SMoriah Waterland 
16525c51f124SMoriah Waterland 	arg[nargs++] = pkginst;
16535c51f124SMoriah Waterland 
16545c51f124SMoriah Waterland 	/* terminate argument list */
16555c51f124SMoriah Waterland 
16565c51f124SMoriah Waterland 	arg[nargs++] = NULL;
16575c51f124SMoriah Waterland 
16585c51f124SMoriah Waterland 	/* execute pkgremove command */
16595c51f124SMoriah Waterland 
16605c51f124SMoriah Waterland 	if (debugFlag == B_TRUE) {
16615c51f124SMoriah Waterland 		echoDebug(DBG_ZONE_EXEC_ENTER, a_zoneName, arg[0]);
16625c51f124SMoriah Waterland 		for (n = 0; arg[n]; n++) {
16635c51f124SMoriah Waterland 			echoDebug(DBG_ARG, n, arg[n]);
16645c51f124SMoriah Waterland 		}
16655c51f124SMoriah Waterland 	}
16665c51f124SMoriah Waterland 
16675c51f124SMoriah Waterland 	/* terminate file descriptor list */
16685c51f124SMoriah Waterland 
16695c51f124SMoriah Waterland 	fds[maxfds] = -1;
16705c51f124SMoriah Waterland 
16715c51f124SMoriah Waterland 	/* exec command in zone */
16725c51f124SMoriah Waterland 
16735c51f124SMoriah Waterland 	n = z_zone_exec(a_zoneName, path, arg, (char *)NULL, (char *)NULL, fds);
16745c51f124SMoriah Waterland 
16755c51f124SMoriah Waterland 	/*
16765c51f124SMoriah Waterland 	 * close any files that were opened for use by the
16775c51f124SMoriah Waterland 	 * /proc/self/fd interface so they could be passed to programs
16785c51f124SMoriah Waterland 	 * via the z_zone_exec() interface
16795c51f124SMoriah Waterland 	 */
16805c51f124SMoriah Waterland 
16815c51f124SMoriah Waterland 	for (; maxfds > 0; maxfds--) {
16825c51f124SMoriah Waterland 		(void) close(fds[maxfds-1]);
16835c51f124SMoriah Waterland 	}
16845c51f124SMoriah Waterland 
16855c51f124SMoriah Waterland 	return (n);
16865c51f124SMoriah Waterland }
16875c51f124SMoriah Waterland 
16885c51f124SMoriah Waterland /*
16895c51f124SMoriah Waterland  * Name:	pkgRemove
16905c51f124SMoriah Waterland  * Description:	Invoke pkgremove in the current zone to perform a remove
16915c51f124SMoriah Waterland  *		of a single package from the current zone or standalone system
16925c51f124SMoriah Waterland  * Arguments:	a_nodelete: should the files and scripts remain installed?
16935c51f124SMoriah Waterland  *			- if != 0 pass -F flag to pkgremove - suppress
16945c51f124SMoriah Waterland  *			the removal of any files and any class action scripts
16955c51f124SMoriah Waterland  *			and suppress the running of any class action scripts.
16965c51f124SMoriah Waterland  *			The package files remain but the package looks like it
16975c51f124SMoriah Waterland  *			is not installed. This is mainly for use by upgrade.
16985c51f124SMoriah Waterland  *			- if == 0 do not pass -F flag to pkgremove - all
16995c51f124SMoriah Waterland  *			files and class action scripts are removed, and any
17005c51f124SMoriah Waterland  *			appropriate class action scripts are run.
17015c51f124SMoriah Waterland  *		a_altBinDir - pointer to string representing location of the
17025c51f124SMoriah Waterland  *			pkgremove executable to run. If not NULL, then pass
17035c51f124SMoriah Waterland  *			the path specified to the -b option to pkgremove.
17045c51f124SMoriah Waterland  *		a_adminFile - pointer to string representing the admin
17055c51f124SMoriah Waterland  *			file to pass to pkgremove when removing the package.
17065c51f124SMoriah Waterland  *			If this is == NULL no admin file is given to pkgremove.
17075c51f124SMoriah Waterland  *		a_inheritedPkgDirs - pointer to array of strings, each one
17085c51f124SMoriah Waterland  *			representing the non-global zones full path of a
17095c51f124SMoriah Waterland  *			directory that is inherited from the global zone.
17105c51f124SMoriah Waterland  * Returns:	int	(see ckreturn() function for details)
17115c51f124SMoriah Waterland  *		0 - success
17125c51f124SMoriah Waterland  *		1 - package operation failed (fatal error)
17135c51f124SMoriah Waterland  *		2 - non-fatal error (warning)
17145c51f124SMoriah Waterland  *		3 - user selected quit (operation interrupted)
17155c51f124SMoriah Waterland  *		4 - admin settings prevented operation
17165c51f124SMoriah Waterland  *		5 - interaction required and -n (non-interactive) specified
17175c51f124SMoriah Waterland  *		"10" will be added to indicate "immediate reboot required"
17185c51f124SMoriah Waterland  *		"20" will be added to indicate "reboot after install required"
17195c51f124SMoriah Waterland  */
17205c51f124SMoriah Waterland 
17215c51f124SMoriah Waterland static int
17225c51f124SMoriah Waterland pkgRemove(int a_nodelete, char *a_altBinDir, char *a_adminFile,
17235c51f124SMoriah Waterland 	char **a_inheritedPkgDirs)
17245c51f124SMoriah Waterland {
17255c51f124SMoriah Waterland 	char	*arg[MAXARGS];
17265c51f124SMoriah Waterland 	char	*p;
17275c51f124SMoriah Waterland 	char	path[PATH_MAX];
17285c51f124SMoriah Waterland 	int	n;
17295c51f124SMoriah Waterland 	int	nargs;
17305c51f124SMoriah Waterland 
17315c51f124SMoriah Waterland 	/* entry debugging info */
17325c51f124SMoriah Waterland 
17335c51f124SMoriah Waterland 	echoDebug(DBG_PKGREMOVE_ENTRY);
17345c51f124SMoriah Waterland 	echoDebug(DBG_PKGREMOVE_ARGS, PSTR(pkginst), PSTR(pkgdev.dirname),
17355c51f124SMoriah Waterland 		a_nodelete, PSTR(a_adminFile));
17365c51f124SMoriah Waterland 
17375c51f124SMoriah Waterland 	(void) snprintf(path, sizeof (path), "%s/pkgremove",
17385c51f124SMoriah Waterland 		a_altBinDir == (char *)NULL ? PKGBIN : a_altBinDir);
17395c51f124SMoriah Waterland 
17405c51f124SMoriah Waterland 	nargs = 0;
17415c51f124SMoriah Waterland 
17425c51f124SMoriah Waterland 	/* first argument is path to executable */
17435c51f124SMoriah Waterland 
17445c51f124SMoriah Waterland 	arg[nargs++] = strdup(path);
17455c51f124SMoriah Waterland 
17465c51f124SMoriah Waterland 	/* second argument is always: pass -O debug to pkgremove: debug mode */
17475c51f124SMoriah Waterland 
17485c51f124SMoriah Waterland 	if (debugFlag == B_TRUE) {
17495c51f124SMoriah Waterland 		arg[nargs++] = "-O";
17505c51f124SMoriah Waterland 		arg[nargs++] = "debug";
17515c51f124SMoriah Waterland 	}
17525c51f124SMoriah Waterland 
1753*62224350SCasper H.S. Dik 	/* Add arguments how to start the pkgserv */
1754*62224350SCasper H.S. Dik 
1755*62224350SCasper H.S. Dik 	arg[nargs++] = "-O";
1756*62224350SCasper H.S. Dik 	arg[nargs++] = pkgmodeargument(pkgservergetmode());
1757*62224350SCasper H.S. Dik 
17585c51f124SMoriah Waterland 	/* pkgrm -b dir: pass -b to pkgremove */
17595c51f124SMoriah Waterland 
17605c51f124SMoriah Waterland 	if (a_altBinDir != (char *)NULL) {
17615c51f124SMoriah Waterland 		arg[nargs++] = "-b";
17625c51f124SMoriah Waterland 		arg[nargs++] = a_altBinDir;
17635c51f124SMoriah Waterland 	}
17645c51f124SMoriah Waterland 
17655c51f124SMoriah Waterland 	/*
17665c51f124SMoriah Waterland 	 * NONABI_SCRIPTS defined: pass -o to pkgremove; refers to a
17675c51f124SMoriah Waterland 	 * pkg requiring operator interaction during a procedure script
17685c51f124SMoriah Waterland 	 * (common before on1093)
17695c51f124SMoriah Waterland 	 */
17705c51f124SMoriah Waterland 
17715c51f124SMoriah Waterland 	if (old_pkg) {
17725c51f124SMoriah Waterland 		arg[nargs++] = "-o";
17735c51f124SMoriah Waterland 	}
17745c51f124SMoriah Waterland 
17755c51f124SMoriah Waterland 	/*
17765c51f124SMoriah Waterland 	 * PKG_NONABI_SYMLINKS defined: pass -y to pkgremove; process
17775c51f124SMoriah Waterland 	 * symlinks consistent with old behavior
17785c51f124SMoriah Waterland 	 */
17795c51f124SMoriah Waterland 
17805c51f124SMoriah Waterland 	if (old_symlinks) {
17815c51f124SMoriah Waterland 		arg[nargs++] = "-y";
17825c51f124SMoriah Waterland 	}
17835c51f124SMoriah Waterland 
17845c51f124SMoriah Waterland 	/* pkgrm -M: pass -M to pkgrm: dont mount client file systems */
17855c51f124SMoriah Waterland 
17865c51f124SMoriah Waterland 	if (no_map_client) {
17875c51f124SMoriah Waterland 		arg[nargs++] = "-M";
17885c51f124SMoriah Waterland 	}
17895c51f124SMoriah Waterland 
17905c51f124SMoriah Waterland 	/* pkgrm -A: pass -A to pkgrm */
17915c51f124SMoriah Waterland 
17925c51f124SMoriah Waterland 	if (pkgrmremote) {
17935c51f124SMoriah Waterland 		arg[nargs++] = "-A";
17945c51f124SMoriah Waterland 	}
17955c51f124SMoriah Waterland 
17965c51f124SMoriah Waterland 	/* pkgrm -v: pass -v to pkgremove: trace scripts */
17975c51f124SMoriah Waterland 
17985c51f124SMoriah Waterland 	if (pkgverbose) {
17995c51f124SMoriah Waterland 		arg[nargs++] = "-v";
18005c51f124SMoriah Waterland 	}
18015c51f124SMoriah Waterland 
18025c51f124SMoriah Waterland 	/* pkgrm -n: pass -n to pkgremove: noninteractive mode */
18035c51f124SMoriah Waterland 
18045c51f124SMoriah Waterland 	if (nointeract) {
18055c51f124SMoriah Waterland 		arg[nargs++] = "-n";
18065c51f124SMoriah Waterland 	}
18075c51f124SMoriah Waterland 
18085c51f124SMoriah Waterland 	/* pkgrm -a admin: pass -a admin to pkgremove: admin file */
18095c51f124SMoriah Waterland 
18105c51f124SMoriah Waterland 	if (a_adminFile) {
18115c51f124SMoriah Waterland 		arg[nargs++] = "-a";
18125c51f124SMoriah Waterland 		arg[nargs++] = strdup(a_adminFile);
18135c51f124SMoriah Waterland 	}
18145c51f124SMoriah Waterland 
18155c51f124SMoriah Waterland 	/* pkgrm -V vfstab: pass -V vfstab to pkgremove: alternate vfstab */
18165c51f124SMoriah Waterland 
18175c51f124SMoriah Waterland 	if (vfstab_file) {
18185c51f124SMoriah Waterland 		arg[nargs++] = "-V";
18195c51f124SMoriah Waterland 		arg[nargs++] = vfstab_file;
18205c51f124SMoriah Waterland 	}
18215c51f124SMoriah Waterland 
18225c51f124SMoriah Waterland 	/* pkgrm -R root: pass -R root to pkgremove: alternative root */
18235c51f124SMoriah Waterland 
18245c51f124SMoriah Waterland 	if (is_an_inst_root()) {
18255c51f124SMoriah Waterland 		arg[nargs++] = "-R";
18265c51f124SMoriah Waterland 		arg[nargs++] = get_inst_root();
18275c51f124SMoriah Waterland 	}
18285c51f124SMoriah Waterland 
18295c51f124SMoriah Waterland 	/* pkgrm -F: pass -F to pkgremove: update DB only */
18305c51f124SMoriah Waterland 
18315c51f124SMoriah Waterland 	if (a_nodelete) {
18325c51f124SMoriah Waterland 		arg[nargs++] = "-F";
18335c51f124SMoriah Waterland 	}
18345c51f124SMoriah Waterland 
18355c51f124SMoriah Waterland 	/* add all inherited file systems */
18365c51f124SMoriah Waterland 
18375c51f124SMoriah Waterland 	if (a_inheritedPkgDirs != (char **)NULL) {
18385c51f124SMoriah Waterland 		for (n = 0; a_inheritedPkgDirs[n] != (char *)NULL; n++) {
18395c51f124SMoriah Waterland 			char	ifs[MAXPATHLEN+22];
18405c51f124SMoriah Waterland 			(void) snprintf(ifs, sizeof (ifs),
18415c51f124SMoriah Waterland 				"inherited-filesystem=%s",
18425c51f124SMoriah Waterland 				a_inheritedPkgDirs[n]);
18435c51f124SMoriah Waterland 			arg[nargs++] = "-O";
18445c51f124SMoriah Waterland 			arg[nargs++] = strdup(ifs);
18455c51f124SMoriah Waterland 		}
18465c51f124SMoriah Waterland 	}
18475c51f124SMoriah Waterland 
18485c51f124SMoriah Waterland 	/*
18495c51f124SMoriah Waterland 	 * add parent zone info/type
18505c51f124SMoriah Waterland 	 */
18515c51f124SMoriah Waterland 
18525c51f124SMoriah Waterland 	p = z_get_zonename();
18535c51f124SMoriah Waterland 	if ((p != NULL) && (*p != '\0')) {
18545c51f124SMoriah Waterland 			char	zn[MAXPATHLEN];
18555c51f124SMoriah Waterland 			(void) snprintf(zn, sizeof (zn),
18565c51f124SMoriah Waterland 				"parent-zone-name=%s", p);
18575c51f124SMoriah Waterland 			arg[nargs++] = "-O";
18585c51f124SMoriah Waterland 			arg[nargs++] = strdup(zn);
18595c51f124SMoriah Waterland 	}
18605c51f124SMoriah Waterland 
18615c51f124SMoriah Waterland 	/* current zone type */
18625c51f124SMoriah Waterland 
18635c51f124SMoriah Waterland 	arg[nargs++] = "-O";
18645c51f124SMoriah Waterland 	if (z_running_in_global_zone() == B_TRUE) {
18655c51f124SMoriah Waterland 			char	zn[MAXPATHLEN];
18665c51f124SMoriah Waterland 			(void) snprintf(zn, sizeof (zn),
18675c51f124SMoriah Waterland 				"parent-zone-type=%s",
18685c51f124SMoriah Waterland 				TAG_VALUE_GLOBAL_ZONE);
18695c51f124SMoriah Waterland 			arg[nargs++] = strdup(zn);
18705c51f124SMoriah Waterland 	} else {
18715c51f124SMoriah Waterland 			char	zn[MAXPATHLEN];
18725c51f124SMoriah Waterland 			(void) snprintf(zn, sizeof (zn),
18735c51f124SMoriah Waterland 				"parent-zone-type=%s",
18745c51f124SMoriah Waterland 				TAG_VALUE_NONGLOBAL_ZONE);
18755c51f124SMoriah Waterland 			arg[nargs++] = strdup(zn);
18765c51f124SMoriah Waterland 	}
18775c51f124SMoriah Waterland 
18785c51f124SMoriah Waterland 	/* pass -N to pkgremove: program name to report */
18795c51f124SMoriah Waterland 
18805c51f124SMoriah Waterland 	arg[nargs++] = "-N";
18815c51f124SMoriah Waterland 	arg[nargs++] = get_prog_name();
18825c51f124SMoriah Waterland 
18835c51f124SMoriah Waterland 	/* add package instance name */
18845c51f124SMoriah Waterland 
18855c51f124SMoriah Waterland 	arg[nargs++] = pkginst;
18865c51f124SMoriah Waterland 
18875c51f124SMoriah Waterland 	/* terminate argument list */
18885c51f124SMoriah Waterland 
18895c51f124SMoriah Waterland 	arg[nargs++] = NULL;
18905c51f124SMoriah Waterland 
18915c51f124SMoriah Waterland 	/*
18925c51f124SMoriah Waterland 	 * run the appropriate pkgremove command in the specified zone
18935c51f124SMoriah Waterland 	 */
18945c51f124SMoriah Waterland 
18955c51f124SMoriah Waterland 	if (debugFlag == B_TRUE) {
18965c51f124SMoriah Waterland 		echoDebug(DBG_ZONE_EXEC_ENTER, "global", arg[0]);
18975c51f124SMoriah Waterland 		for (n = 0; arg[n]; n++) {
18985c51f124SMoriah Waterland 			echoDebug(DBG_ARG, n, arg[n]);
18995c51f124SMoriah Waterland 		}
19005c51f124SMoriah Waterland 	}
19015c51f124SMoriah Waterland 
19025c51f124SMoriah Waterland 	/* execute pkgremove command */
19035c51f124SMoriah Waterland 
19045c51f124SMoriah Waterland 	n = pkgexecv(NULL, NULL, NULL, NULL, arg);
19055c51f124SMoriah Waterland 
19065c51f124SMoriah Waterland 	/* return results of pkgrm in this zone */
19075c51f124SMoriah Waterland 
19085c51f124SMoriah Waterland 	return (n);
19095c51f124SMoriah Waterland }
19105c51f124SMoriah Waterland 
19115c51f124SMoriah Waterland static void
19125c51f124SMoriah Waterland usage(void)
19135c51f124SMoriah Waterland {
19145c51f124SMoriah Waterland 	char	*prog = get_prog_name();
19155c51f124SMoriah Waterland 
19165c51f124SMoriah Waterland 	(void) fprintf(stderr, ERR_USAGE_PKGRM, prog, prog);
19175c51f124SMoriah Waterland 	exit(1);
19185c51f124SMoriah Waterland }
19195c51f124SMoriah Waterland 
19205c51f124SMoriah Waterland /*
19215c51f124SMoriah Waterland  * Name:	remove_packages_in_global_with_zones
19225c51f124SMoriah Waterland  * Description:	Remove packages from the global zone and from non-global zones
19235c51f124SMoriah Waterland  *		when run from the global zone and when non-global zones are
19245c51f124SMoriah Waterland  *		present.
19255c51f124SMoriah Waterland  * Arguments:	a_pkgList - pointer to array of strings, each string specifying
19265c51f124SMoriah Waterland  *			the name of one package to be removed.
19275c51f124SMoriah Waterland  *		a_nodelete: should the files and scripts remain installed?
19285c51f124SMoriah Waterland  *			- if != 0 pass -F flag to pkgremove - suppress
19295c51f124SMoriah Waterland  *			the removal of any files and any class action scripts
19305c51f124SMoriah Waterland  *			and suppress the running of any class action scripts.
19315c51f124SMoriah Waterland  *			The package files remain but the package looks like it
19325c51f124SMoriah Waterland  *			is not installed. This is mainly for use by upgrade.
19335c51f124SMoriah Waterland  *			- if == 0 do not pass -F flag to pkgremove - all
19345c51f124SMoriah Waterland  *			files and class action scripts are removed, and any
19355c51f124SMoriah Waterland  *			appropriate class action scripts are run.
19365c51f124SMoriah Waterland  *		a_longestPkg - length of the longest package "name" (for
19375c51f124SMoriah Waterland  *			output format alignment)
19385c51f124SMoriah Waterland  *		a_repeat - are there more packages avialable in "optind"
19395c51f124SMoriah Waterland  *			- B_TRUE - process packages from optind
19405c51f124SMoriah Waterland  *			- B_FALSE - do not process packages from optind
19415c51f124SMoriah Waterland  *		a_altBinDir - pointer to string representing location of the
19425c51f124SMoriah Waterland  *			pkgremove executable to run. If not NULL, then pass
19435c51f124SMoriah Waterland  *			the path specified to the -b option to pkgremove.
19445c51f124SMoriah Waterland  *		a_pkgdir - pointer to string representing the directory
19455c51f124SMoriah Waterland  *			where the packages to be removed are located.
19465c51f124SMoriah Waterland  *		a_zlst - list of zones to process; NULL if no zones to process.
19475c51f124SMoriah Waterland  * Returns:	int	(see ckreturn() function for details)
19485c51f124SMoriah Waterland  *		0 - success
19495c51f124SMoriah Waterland  *		1 - package operation failed (fatal error)
19505c51f124SMoriah Waterland  *		2 - non-fatal error (warning)
19515c51f124SMoriah Waterland  *		3 - user selected quit (operation interrupted)
19525c51f124SMoriah Waterland  *		4 - admin settings prevented operation
19535c51f124SMoriah Waterland  *		5 - interaction required and -n (non-interactive) specified
19545c51f124SMoriah Waterland  *		"10" will be added to indicate "immediate reboot required"
19555c51f124SMoriah Waterland  *		"20" will be added to indicate "reboot after install required"
19565c51f124SMoriah Waterland  */
19575c51f124SMoriah Waterland 
19585c51f124SMoriah Waterland static boolean_t
19595c51f124SMoriah Waterland remove_packages_in_global_with_zones(char **a_pkgList, int a_nodelete,
19605c51f124SMoriah Waterland 	int a_longestPkg, int a_repeat, char *a_altBinDir, char *a_pkgdir,
19615c51f124SMoriah Waterland 	zoneList_t a_zlst)
19625c51f124SMoriah Waterland {
19635c51f124SMoriah Waterland static	char		*zoneAdminFile = (char *)NULL;
19645c51f124SMoriah Waterland 
19655c51f124SMoriah Waterland 	boolean_t	b;
19665c51f124SMoriah Waterland 	char		**inheritedPkgDirs;
19675c51f124SMoriah Waterland 	char		*zoneName;
19685c51f124SMoriah Waterland 	char		*scratchName;
19695c51f124SMoriah Waterland 	char		preremovecheckPath[PATH_MAX+1];
19705c51f124SMoriah Waterland 	int		i;
19715c51f124SMoriah Waterland 	int		n;
19725c51f124SMoriah Waterland 	int		savenpkgs = npkgs;
19735c51f124SMoriah Waterland 	int		zoneIndex;
19745c51f124SMoriah Waterland 	int		zonesSkipped;
19755c51f124SMoriah Waterland 	zone_state_t	zst;
19765c51f124SMoriah Waterland 
19775c51f124SMoriah Waterland 	/* entry assertions */
19785c51f124SMoriah Waterland 
19795c51f124SMoriah Waterland 	assert(a_zlst != (zoneList_t)NULL);
19805c51f124SMoriah Waterland 	assert(a_pkgList != (char **)NULL);
19815c51f124SMoriah Waterland 	assert(a_longestPkg > 0);
19825c51f124SMoriah Waterland 	assert(a_pkgdir != (char *)NULL);
19835c51f124SMoriah Waterland 	assert(*a_pkgdir != '\0');
19845c51f124SMoriah Waterland 
19855c51f124SMoriah Waterland 	/* entry debugging info */
19865c51f124SMoriah Waterland 
19875c51f124SMoriah Waterland 	echoDebug(DBG_PKGREMPKGSGZWNGZ_ENTRY);
19885c51f124SMoriah Waterland 	echoDebug(DBG_PKGREMPKGSGZWNGZ_ARGS, a_nodelete, a_longestPkg,
19895c51f124SMoriah Waterland 		a_repeat, PSTR(a_altBinDir), PSTR(a_pkgdir));
19905c51f124SMoriah Waterland 
19915c51f124SMoriah Waterland 	/* check all packages */
19925c51f124SMoriah Waterland 
19935c51f124SMoriah Waterland 	if (check_packages(a_pkgList, a_pkgdir) != B_TRUE) {
19945c51f124SMoriah Waterland 		quit(1);
19955c51f124SMoriah Waterland 	}
19965c51f124SMoriah Waterland 
19975c51f124SMoriah Waterland 	/* create temporary directory for use by zone operations */
19985c51f124SMoriah Waterland 
19995c51f124SMoriah Waterland 	create_zone_tempdir(&zoneTempDir, tmpdir);
20005c51f124SMoriah Waterland 
20015c51f124SMoriah Waterland 	/* create hands off settings admin file for use in a non-global zone */
20025c51f124SMoriah Waterland 
20035c51f124SMoriah Waterland 	create_zone_adminfile(&zoneAdminFile, zoneTempDir, admnfile);
20045c51f124SMoriah Waterland 
20055c51f124SMoriah Waterland 	/*
20065c51f124SMoriah Waterland 	 * all of the packages (as listed in the package list) are
20075c51f124SMoriah Waterland 	 * removed one at a time from all non-global zones and then
20085c51f124SMoriah Waterland 	 * from the global zone.
20095c51f124SMoriah Waterland 	 */
20105c51f124SMoriah Waterland 
20115c51f124SMoriah Waterland 	for (i = 0; (pkginst = a_pkgList[i]) != NULL; i++) {
20125c51f124SMoriah Waterland 		/* reset interrupted flag before calling pkgremove */
20135c51f124SMoriah Waterland 
20145c51f124SMoriah Waterland 		interrupted = 0;	/* last action was NOT quit */
20155c51f124SMoriah Waterland 
20165c51f124SMoriah Waterland 		/* skip package if it is "in the global zone only" */
20175c51f124SMoriah Waterland 
20185c51f124SMoriah Waterland 		if (pkgIsPkgInGzOnly(get_inst_root(), pkginst) == B_TRUE) {
20195c51f124SMoriah Waterland 			continue;
20205c51f124SMoriah Waterland 		}
20215c51f124SMoriah Waterland 
20225c51f124SMoriah Waterland 		/*
20235c51f124SMoriah Waterland 		 * if operation failed in global zone do not propagate to
20245c51f124SMoriah Waterland 		 * non-global zones
20255c51f124SMoriah Waterland 		 */
20265c51f124SMoriah Waterland 
20275c51f124SMoriah Waterland 		zonesSkipped = 0;
20285c51f124SMoriah Waterland 
20295c51f124SMoriah Waterland 		if (interrupted != 0) {
20305c51f124SMoriah Waterland 			echo(MSG_DOREMOVE_INTERRUPTED, pkginst);
20315c51f124SMoriah Waterland 			echoDebug(DBG_DOREMOVE_INTERRUPTED, pkginst);
20325c51f124SMoriah Waterland 			break;
20335c51f124SMoriah Waterland 		}
20345c51f124SMoriah Waterland 
20355c51f124SMoriah Waterland 		echoDebug(DBG_REMOVE_FLAG_VALUES, "before loop",
20365c51f124SMoriah Waterland 			admnflag, doreboot, failflag, interrupted,
20375c51f124SMoriah Waterland 			intrflag, ireboot, nullflag, warnflag);
20385c51f124SMoriah Waterland 
20395c51f124SMoriah Waterland 		for (zoneIndex = 0;
20405c51f124SMoriah Waterland 			(zoneName = z_zlist_get_zonename(a_zlst, zoneIndex)) !=
20415c51f124SMoriah Waterland 				(char *)NULL; zoneIndex++) {
20425c51f124SMoriah Waterland 
20435c51f124SMoriah Waterland 			/* skip the zone if it is NOT running */
20445c51f124SMoriah Waterland 
20455c51f124SMoriah Waterland 			zst = z_zlist_get_current_state(a_zlst, zoneIndex);
20465c51f124SMoriah Waterland 			if (zst != ZONE_STATE_RUNNING &&
20475c51f124SMoriah Waterland 			    zst != ZONE_STATE_MOUNTED) {
20485c51f124SMoriah Waterland 				zonesSkipped++;
20495c51f124SMoriah Waterland 				echoDebug(DBG_SKIPPING_ZONE, zoneName);
20505c51f124SMoriah Waterland 				continue;
20515c51f124SMoriah Waterland 			}
20525c51f124SMoriah Waterland 
20535c51f124SMoriah Waterland 			echo(MSG_CHECKREMOVE_PKG_IN_ZONE, pkginst, zoneName);
20545c51f124SMoriah Waterland 			echoDebug(DBG_CHECKREMOVE_PKG_IN_ZONE, pkginst,
20555c51f124SMoriah Waterland 				zoneName);
20565c51f124SMoriah Waterland 
20575c51f124SMoriah Waterland 			scratchName = z_zlist_get_scratch(a_zlst, zoneIndex);
20585c51f124SMoriah Waterland 
20595c51f124SMoriah Waterland 			(void) snprintf(preremovecheckPath,
20605c51f124SMoriah Waterland 				sizeof (preremovecheckPath),
20615c51f124SMoriah Waterland 				"%s/%s.%s.preremovecheck.txt",
20625c51f124SMoriah Waterland 				zoneTempDir, pkginst, scratchName);
20635c51f124SMoriah Waterland 
20645c51f124SMoriah Waterland 			/* determine list of dirs inherited from global zone */
20655c51f124SMoriah Waterland 
20665c51f124SMoriah Waterland 			inheritedPkgDirs =
20675c51f124SMoriah Waterland 				z_zlist_get_inherited_pkg_dirs(a_zlst,
20685c51f124SMoriah Waterland 					zoneIndex);
20695c51f124SMoriah Waterland 
20705c51f124SMoriah Waterland 			/*
20715c51f124SMoriah Waterland 			 * dependency check this package this zone; use the
20725c51f124SMoriah Waterland 			 * user supplied admin file so that the appropriate
20735c51f124SMoriah Waterland 			 * level of dependency checking is (or is not) done.
20745c51f124SMoriah Waterland 			 */
20755c51f124SMoriah Waterland 
20765c51f124SMoriah Waterland 			n = pkgZoneCheckRemove(scratchName, inheritedPkgDirs,
20775c51f124SMoriah Waterland 				a_altBinDir, admnfile, preremovecheckPath,
2078*62224350SCasper H.S. Dik 				zst, B_FALSE);
20795c51f124SMoriah Waterland 
20805c51f124SMoriah Waterland 			/* set success/fail condition variables */
20815c51f124SMoriah Waterland 
20825c51f124SMoriah Waterland 			ckreturn(n);
20835c51f124SMoriah Waterland 
20845c51f124SMoriah Waterland 			echoDebug(DBG_REMOVE_FLAG_VALUES,
20855c51f124SMoriah Waterland 				"after pkgzonecheckremove",
20865c51f124SMoriah Waterland 				admnflag, doreboot, failflag, interrupted,
20875c51f124SMoriah Waterland 				intrflag, ireboot, nullflag, warnflag);
20885c51f124SMoriah Waterland 		}
20895c51f124SMoriah Waterland 
20905c51f124SMoriah Waterland 		if (zonesSkipped == 0) {
20915c51f124SMoriah Waterland 			continue;
20925c51f124SMoriah Waterland 		}
20935c51f124SMoriah Waterland 
20945c51f124SMoriah Waterland 		echoDebug(DBG_ZONES_SKIPPED, zonesSkipped);
20955c51f124SMoriah Waterland 
20965c51f124SMoriah Waterland 		for (zoneIndex = 0;
20975c51f124SMoriah Waterland 			(zoneName = z_zlist_get_zonename(a_zlst, zoneIndex)) !=
20985c51f124SMoriah Waterland 				(char *)NULL; zoneIndex++) {
20995c51f124SMoriah Waterland 
21005c51f124SMoriah Waterland 			/* skip the zone if it IS running */
21015c51f124SMoriah Waterland 
21025c51f124SMoriah Waterland 			zst = z_zlist_get_current_state(a_zlst, zoneIndex);
21035c51f124SMoriah Waterland 			if (zst == ZONE_STATE_RUNNING ||
21045c51f124SMoriah Waterland 			    zst == ZONE_STATE_MOUNTED) {
21055c51f124SMoriah Waterland 				zonesSkipped++;
21065c51f124SMoriah Waterland 				echoDebug(DBG_SKIPPING_ZONE_BOOT, zoneName);
21075c51f124SMoriah Waterland 				continue;
21085c51f124SMoriah Waterland 			}
21095c51f124SMoriah Waterland 
21105c51f124SMoriah Waterland 			/* skip the zone if it is NOT bootable */
21115c51f124SMoriah Waterland 
21125c51f124SMoriah Waterland 			if (z_zlist_is_zone_runnable(a_zlst,
21135c51f124SMoriah Waterland 						zoneIndex) == B_FALSE) {
21145c51f124SMoriah Waterland 				echo(MSG_SKIPPING_ZONE_NOT_RUNNABLE, zoneName);
21155c51f124SMoriah Waterland 				echoDebug(DBG_SKIPPING_ZONE_NOT_RUNNABLE,
21165c51f124SMoriah Waterland 					zoneName);
21175c51f124SMoriah Waterland 				continue;
21185c51f124SMoriah Waterland 			}
21195c51f124SMoriah Waterland 
21205c51f124SMoriah Waterland 			/* mount up the zone */
21215c51f124SMoriah Waterland 
21225c51f124SMoriah Waterland 			echo(MSG_BOOTING_ZONE, zoneName);
21235c51f124SMoriah Waterland 			echoDebug(DBG_BOOTING_ZONE, zoneName);
21245c51f124SMoriah Waterland 
21255c51f124SMoriah Waterland 			b = z_zlist_change_zone_state(a_zlst, zoneIndex,
21265c51f124SMoriah Waterland 				ZONE_STATE_MOUNTED);
21275c51f124SMoriah Waterland 			if (b == B_FALSE) {
21285c51f124SMoriah Waterland 				progerr(ERR_CANNOT_BOOT_ZONE, zoneName);
21295c51f124SMoriah Waterland 				/* set fatal error return condition */
21305c51f124SMoriah Waterland 				ckreturn(1);
21315c51f124SMoriah Waterland 				continue;
21325c51f124SMoriah Waterland 			}
21335c51f124SMoriah Waterland 
21345c51f124SMoriah Waterland 			echo(MSG_CHECKREMOVE_PKG_IN_ZONE, pkginst, zoneName);
21355c51f124SMoriah Waterland 			echoDebug(DBG_CHECKREMOVE_PKG_IN_ZONE, pkginst,
21365c51f124SMoriah Waterland 					zoneName);
21375c51f124SMoriah Waterland 
21385c51f124SMoriah Waterland 			scratchName = z_zlist_get_scratch(a_zlst, zoneIndex);
21395c51f124SMoriah Waterland 
21405c51f124SMoriah Waterland 			(void) snprintf(preremovecheckPath,
21415c51f124SMoriah Waterland 				sizeof (preremovecheckPath),
21425c51f124SMoriah Waterland 				"%s/%s.%s.preremovecheck.txt",
21435c51f124SMoriah Waterland 				zoneTempDir, pkginst, scratchName);
21445c51f124SMoriah Waterland 
21455c51f124SMoriah Waterland 			/* determine list of dirs inherited from global zone */
21465c51f124SMoriah Waterland 
21475c51f124SMoriah Waterland 			inheritedPkgDirs =
21485c51f124SMoriah Waterland 				z_zlist_get_inherited_pkg_dirs(a_zlst,
21495c51f124SMoriah Waterland 					zoneIndex);
21505c51f124SMoriah Waterland 
21515c51f124SMoriah Waterland 			/*
21525c51f124SMoriah Waterland 			 * dependency check this package this zone; use the
21535c51f124SMoriah Waterland 			 * user supplied admin file so that the appropriate
21545c51f124SMoriah Waterland 			 * level of dependency checking is (or is not) done.
21555c51f124SMoriah Waterland 			 */
21565c51f124SMoriah Waterland 
21575c51f124SMoriah Waterland 			n = pkgZoneCheckRemove(scratchName, inheritedPkgDirs,
21585c51f124SMoriah Waterland 				a_altBinDir, admnfile, preremovecheckPath,
2159*62224350SCasper H.S. Dik 				ZONE_STATE_MOUNTED, B_TRUE);
21605c51f124SMoriah Waterland 
21615c51f124SMoriah Waterland 			/* set success/fail condition variables */
21625c51f124SMoriah Waterland 
21635c51f124SMoriah Waterland 			ckreturn(n);
21645c51f124SMoriah Waterland 
21655c51f124SMoriah Waterland 			echoDebug(DBG_REMOVE_FLAG_VALUES,
21665c51f124SMoriah Waterland 				"after pkgzonecheckremove",
21675c51f124SMoriah Waterland 				admnflag, doreboot, failflag, interrupted,
21685c51f124SMoriah Waterland 				intrflag, ireboot, nullflag, warnflag);
21695c51f124SMoriah Waterland 
21705c51f124SMoriah Waterland 			/* restore original state of zone */
21715c51f124SMoriah Waterland 
21725c51f124SMoriah Waterland 			echo(MSG_RESTORE_ZONE_STATE, zoneName);
21735c51f124SMoriah Waterland 			echoDebug(DBG_RESTORE_ZONE_STATE, zoneName);
21745c51f124SMoriah Waterland 
21755c51f124SMoriah Waterland 			b = z_zlist_restore_zone_state(a_zlst, zoneIndex);
21765c51f124SMoriah Waterland 		}
21775c51f124SMoriah Waterland 		npkgs--;
21785c51f124SMoriah Waterland 	}
21795c51f124SMoriah Waterland 
21805c51f124SMoriah Waterland 	/*
21815c51f124SMoriah Waterland 	 * look at all pre-remove check files
21825c51f124SMoriah Waterland 	 */
21835c51f124SMoriah Waterland 
21845c51f124SMoriah Waterland 	i = preremove_verify(a_pkgList, a_zlst, zoneTempDir);
21855c51f124SMoriah Waterland 	if (i != 0) {
21865c51f124SMoriah Waterland 		quit(i);
21875c51f124SMoriah Waterland 	}
21885c51f124SMoriah Waterland 
21895c51f124SMoriah Waterland 	npkgs = savenpkgs;
21905c51f124SMoriah Waterland 
21915c51f124SMoriah Waterland 	/*
21925c51f124SMoriah Waterland 	 * reset all error return condition variables that may have been
21935c51f124SMoriah Waterland 	 * set during package removal dependency checking so that they
21945c51f124SMoriah Waterland 	 * do not reflect on the success/failure of the actual package
21955c51f124SMoriah Waterland 	 * removal operations
21965c51f124SMoriah Waterland 	 */
21975c51f124SMoriah Waterland 
21985c51f124SMoriah Waterland 	resetreturn();
21995c51f124SMoriah Waterland 
22005c51f124SMoriah Waterland 	/*
22015c51f124SMoriah Waterland 	 * all of the packages (as listed in the package list) are
22025c51f124SMoriah Waterland 	 * removed one at a time.
22035c51f124SMoriah Waterland 	 */
22045c51f124SMoriah Waterland 
22055c51f124SMoriah Waterland 	interrupted = 0;
22065c51f124SMoriah Waterland 	for (i = 0; (pkginst = a_pkgList[i]) != NULL; i++) {
22075c51f124SMoriah Waterland 		boolean_t	in_gz_only;
22085c51f124SMoriah Waterland 		started = 0;
22095c51f124SMoriah Waterland 
22105c51f124SMoriah Waterland 		if (shall_we_continue(pkginst, npkgs) == B_FALSE) {
22115c51f124SMoriah Waterland 			continue;
22125c51f124SMoriah Waterland 		}
22135c51f124SMoriah Waterland 
22145c51f124SMoriah Waterland 		in_gz_only = pkgIsPkgInGzOnly(get_inst_root(), pkginst);
22155c51f124SMoriah Waterland 
22165c51f124SMoriah Waterland 		/* reset interrupted flag before calling pkgremove */
22175c51f124SMoriah Waterland 
22185c51f124SMoriah Waterland 		interrupted = 0;
22195c51f124SMoriah Waterland 
22205c51f124SMoriah Waterland 		/*
22215c51f124SMoriah Waterland 		 * pkgrm invoked from within the global zone and there are
22225c51f124SMoriah Waterland 		 * non-global zones configured:
22235c51f124SMoriah Waterland 		 * Remove the package from the global zone.
22245c51f124SMoriah Waterland 		 * If not removing the package from the global zone only,
22255c51f124SMoriah Waterland 		 * then remove the package from the list of zones specified.
22265c51f124SMoriah Waterland 		 */
22275c51f124SMoriah Waterland 
22285c51f124SMoriah Waterland 		if (in_gz_only) {
22295c51f124SMoriah Waterland 			/* global zone only */
22305c51f124SMoriah Waterland 			n = doRemove(a_nodelete, a_altBinDir, a_longestPkg,
22315c51f124SMoriah Waterland 				admnfile, (char *)NULL, (zoneList_t)NULL);
22325c51f124SMoriah Waterland 		} else {
22335c51f124SMoriah Waterland 			/* global zone and non-global zones */
22345c51f124SMoriah Waterland 			n = doRemove(a_nodelete, a_altBinDir, a_longestPkg,
22355c51f124SMoriah Waterland 				zoneAdminFile, zoneAdminFile, a_zlst);
22365c51f124SMoriah Waterland 		}
22375c51f124SMoriah Waterland 
22385c51f124SMoriah Waterland 		/* set success/fail condition variables */
22395c51f124SMoriah Waterland 
22405c51f124SMoriah Waterland 		ckreturn(n);
22415c51f124SMoriah Waterland 
22425c51f124SMoriah Waterland 		npkgs--;
22435c51f124SMoriah Waterland 	}
22445c51f124SMoriah Waterland 
22455c51f124SMoriah Waterland 	/*
22465c51f124SMoriah Waterland 	 * all packages in the package list have been removed.
22475c51f124SMoriah Waterland 	 * Continue with removal if:
22485c51f124SMoriah Waterland 	 * -- immediate reboot is NOT required
22495c51f124SMoriah Waterland 	 * -- there are more packages to remove
22505c51f124SMoriah Waterland 	 * else return do NOT continue.
22515c51f124SMoriah Waterland 	 */
22525c51f124SMoriah Waterland 
22535c51f124SMoriah Waterland 	if ((ireboot == 0) && (a_repeat != 0)) {
22545c51f124SMoriah Waterland 		return (B_TRUE);
22555c51f124SMoriah Waterland 	}
22565c51f124SMoriah Waterland 
22575c51f124SMoriah Waterland 	/* return 'dont continue' */
22585c51f124SMoriah Waterland 
22595c51f124SMoriah Waterland 	return (B_FALSE);
22605c51f124SMoriah Waterland }
22615c51f124SMoriah Waterland 
22625c51f124SMoriah Waterland /*
22635c51f124SMoriah Waterland  * Name:	remove_packages_in_nonglobal_zone
22645c51f124SMoriah Waterland  * Description:	Remove packages in a non-global zone when run from a
22655c51f124SMoriah Waterland  *		non-global zone.
22665c51f124SMoriah Waterland  * Arguments:	a_pkgList - pointer to array of strings, each string specifying
22675c51f124SMoriah Waterland  *			the name of one package to be removed.
22685c51f124SMoriah Waterland  *		a_nodelete: should the files and scripts remain installed?
22695c51f124SMoriah Waterland  *			- if != 0 pass -F flag to pkgremove - suppress
22705c51f124SMoriah Waterland  *			the removal of any files and any class action scripts
22715c51f124SMoriah Waterland  *			and suppress the running of any class action scripts.
22725c51f124SMoriah Waterland  *			The package files remain but the package looks like it
22735c51f124SMoriah Waterland  *			is not installed. This is mainly for use by upgrade.
22745c51f124SMoriah Waterland  *			- if == 0 do not pass -F flag to pkgremove - all
22755c51f124SMoriah Waterland  *			files and class action scripts are removed, and any
22765c51f124SMoriah Waterland  *			appropriate class action scripts are run.
22775c51f124SMoriah Waterland  *		a_longestPkg - length of the longest package "name" (for
22785c51f124SMoriah Waterland  *			output format alignment)
22795c51f124SMoriah Waterland  *		a_repeat - are there more packages avialable in "optind"
22805c51f124SMoriah Waterland  *			- B_TRUE - process packages from optind
22815c51f124SMoriah Waterland  *			- B_FALSE - do not process packages from optind
22825c51f124SMoriah Waterland  *		a_altBinDir - pointer to string representing location of the
22835c51f124SMoriah Waterland  *			pkgremove executable to run. If not NULL, then pass
22845c51f124SMoriah Waterland  *			the path specified to the -b option to pkgremove.
22855c51f124SMoriah Waterland  *		a_pkgdir - pointer to string representing the directory
22865c51f124SMoriah Waterland  *			where the packages to be removed are located.
22875c51f124SMoriah Waterland  * Returns:	int	(see ckreturn() function for details)
22885c51f124SMoriah Waterland  *		0 - success
22895c51f124SMoriah Waterland  *		1 - package operation failed (fatal error)
22905c51f124SMoriah Waterland  *		2 - non-fatal error (warning)
22915c51f124SMoriah Waterland  *		3 - user selected quit (operation interrupted)
22925c51f124SMoriah Waterland  *		4 - admin settings prevented operation
22935c51f124SMoriah Waterland  *		5 - interaction required and -n (non-interactive) specified
22945c51f124SMoriah Waterland  *		"10" will be added to indicate "immediate reboot required"
22955c51f124SMoriah Waterland  *		"20" will be added to indicate "reboot after install required"
22965c51f124SMoriah Waterland  */
22975c51f124SMoriah Waterland 
22985c51f124SMoriah Waterland static boolean_t
22995c51f124SMoriah Waterland remove_packages_in_nonglobal_zone(char **a_pkgList, int a_nodelete,
23005c51f124SMoriah Waterland 	int a_longestPkg, int a_repeat, char *a_altBinDir, char *a_pkgdir)
23015c51f124SMoriah Waterland {
23025c51f124SMoriah Waterland static	char		*zoneAdminFile = (char *)NULL;
23035c51f124SMoriah Waterland 
23045c51f124SMoriah Waterland 	int		n;
23055c51f124SMoriah Waterland 	int		i;
23065c51f124SMoriah Waterland 
23075c51f124SMoriah Waterland 	/* entry assertions */
23085c51f124SMoriah Waterland 
23095c51f124SMoriah Waterland 	assert(a_pkgList != (char **)NULL);
23105c51f124SMoriah Waterland 	assert(a_longestPkg > 0);
23115c51f124SMoriah Waterland 	assert(a_pkgdir != (char *)NULL);
23125c51f124SMoriah Waterland 	assert(*a_pkgdir != '\0');
23135c51f124SMoriah Waterland 
23145c51f124SMoriah Waterland 	/* entry debugging info */
23155c51f124SMoriah Waterland 
23165c51f124SMoriah Waterland 	echoDebug(DBG_PKGREMPKGSNGZ_ENTRY);
23175c51f124SMoriah Waterland 	echoDebug(DBG_PKGREMPKGSNGZ_ARGS, a_nodelete, a_longestPkg,
23185c51f124SMoriah Waterland 		a_repeat, PSTR(a_altBinDir), PSTR(a_pkgdir));
23195c51f124SMoriah Waterland 
23205c51f124SMoriah Waterland 	/* check all package */
23215c51f124SMoriah Waterland 
23225c51f124SMoriah Waterland 	if (check_packages(a_pkgList, a_pkgdir) != B_TRUE) {
23235c51f124SMoriah Waterland 		quit(1);
23245c51f124SMoriah Waterland 	}
23255c51f124SMoriah Waterland 
23265c51f124SMoriah Waterland 	/* create temporary directory for use by zone operations */
23275c51f124SMoriah Waterland 
23285c51f124SMoriah Waterland 	create_zone_tempdir(&zoneTempDir, tmpdir);
23295c51f124SMoriah Waterland 
23305c51f124SMoriah Waterland 	/* create hands off settings admin file for use in a non-global zone */
23315c51f124SMoriah Waterland 
23325c51f124SMoriah Waterland 	create_zone_adminfile(&zoneAdminFile, zoneTempDir, admnfile);
23335c51f124SMoriah Waterland 
23345c51f124SMoriah Waterland 	/*
23355c51f124SMoriah Waterland 	 * all of the packages (as listed in the package list) are
23365c51f124SMoriah Waterland 	 * removed one at a time.
23375c51f124SMoriah Waterland 	 */
23385c51f124SMoriah Waterland 
23395c51f124SMoriah Waterland 	interrupted = 0;
23405c51f124SMoriah Waterland 	for (i = 0; (pkginst = a_pkgList[i]) != NULL; i++) {
23415c51f124SMoriah Waterland 		started = 0;
23425c51f124SMoriah Waterland 
23435c51f124SMoriah Waterland 		if (shall_we_continue(pkginst, npkgs) == B_FALSE) {
23445c51f124SMoriah Waterland 			continue;
23455c51f124SMoriah Waterland 		}
23465c51f124SMoriah Waterland 
23475c51f124SMoriah Waterland 		interrupted = 0;
23485c51f124SMoriah Waterland 
23495c51f124SMoriah Waterland 		/*
23505c51f124SMoriah Waterland 		 * pkgrm invoked from within a non-global zone: remove
23515c51f124SMoriah Waterland 		 * the package from the current zone only - no non-global
23525c51f124SMoriah Waterland 		 * zones are possible.
23535c51f124SMoriah Waterland 		 */
23545c51f124SMoriah Waterland 
23555c51f124SMoriah Waterland 		n = doRemove(a_nodelete, a_altBinDir, a_longestPkg,
23565c51f124SMoriah Waterland 			admnfile, (char *)NULL, (zoneList_t)NULL);
23575c51f124SMoriah Waterland 
23585c51f124SMoriah Waterland 		/* set success/fail condition variables */
23595c51f124SMoriah Waterland 
23605c51f124SMoriah Waterland 		ckreturn(n);
23615c51f124SMoriah Waterland 
23625c51f124SMoriah Waterland 		npkgs--;
23635c51f124SMoriah Waterland 	}
23645c51f124SMoriah Waterland 
23655c51f124SMoriah Waterland 	/*
23665c51f124SMoriah Waterland 	 * all packages in the package list have been removed.
23675c51f124SMoriah Waterland 	 * Continue with removal if:
23685c51f124SMoriah Waterland 	 * -- immediate reboot is NOT required
23695c51f124SMoriah Waterland 	 * -- there are more packages to remove
23705c51f124SMoriah Waterland 	 * else return do NOT continue.
23715c51f124SMoriah Waterland 	 */
23725c51f124SMoriah Waterland 
23735c51f124SMoriah Waterland 	if ((ireboot == 0) && (a_repeat != 0)) {
23745c51f124SMoriah Waterland 		return (B_TRUE);
23755c51f124SMoriah Waterland 	}
23765c51f124SMoriah Waterland 
23775c51f124SMoriah Waterland 	/* return 'dont continue' */
23785c51f124SMoriah Waterland 
23795c51f124SMoriah Waterland 	return (B_FALSE);
23805c51f124SMoriah Waterland }
23815c51f124SMoriah Waterland 
23825c51f124SMoriah Waterland /*
23835c51f124SMoriah Waterland  * Name:	remove_packages_in_global_no_zones
23845c51f124SMoriah Waterland  * Description:	Remove packages from the global zone only when run in the
23855c51f124SMoriah Waterland  *		global zone and no non-global zones are installed.
23865c51f124SMoriah Waterland  * Arguments:	a_pkgList - pointer to array of strings, each string specifying
23875c51f124SMoriah Waterland  *			the name of one package to be removed.
23885c51f124SMoriah Waterland  *		a_nodelete: should the files and scripts remain installed?
23895c51f124SMoriah Waterland  *			- if != 0 pass -F flag to pkgremove - suppress
23905c51f124SMoriah Waterland  *			the removal of any files and any class action scripts
23915c51f124SMoriah Waterland  *			and suppress the running of any class action scripts.
23925c51f124SMoriah Waterland  *			The package files remain but the package looks like it
23935c51f124SMoriah Waterland  *			is not installed. This is mainly for use by upgrade.
23945c51f124SMoriah Waterland  *			- if == 0 do not pass -F flag to pkgremove - all
23955c51f124SMoriah Waterland  *			files and class action scripts are removed, and any
23965c51f124SMoriah Waterland  *			appropriate class action scripts are run.
23975c51f124SMoriah Waterland  *		a_longestPkg - length of the longest package "name" (for
23985c51f124SMoriah Waterland  *			output format alignment)
23995c51f124SMoriah Waterland  *		a_repeat - are there more packages avialable in "optind"
24005c51f124SMoriah Waterland  *			- B_TRUE - process packages from optind
24015c51f124SMoriah Waterland  *			- B_FALSE - do not process packages from optind
24025c51f124SMoriah Waterland  *		a_altBinDir - pointer to string representing location of the
24035c51f124SMoriah Waterland  *			pkgremove executable to run. If not NULL, then pass
24045c51f124SMoriah Waterland  *			the path specified to the -b option to pkgremove.
24055c51f124SMoriah Waterland  * Returns:	int	(see ckreturn() function for details)
24065c51f124SMoriah Waterland  *		0 - success
24075c51f124SMoriah Waterland  *		1 - package operation failed (fatal error)
24085c51f124SMoriah Waterland  *		2 - non-fatal error (warning)
24095c51f124SMoriah Waterland  *		3 - user selected quit (operation interrupted)
24105c51f124SMoriah Waterland  *		4 - admin settings prevented operation
24115c51f124SMoriah Waterland  *		5 - interaction required and -n (non-interactive) specified
24125c51f124SMoriah Waterland  *		"10" will be added to indicate "immediate reboot required"
24135c51f124SMoriah Waterland  *		"20" will be added to indicate "reboot after install required"
24145c51f124SMoriah Waterland  */
24155c51f124SMoriah Waterland 
24165c51f124SMoriah Waterland static boolean_t
24175c51f124SMoriah Waterland remove_packages_in_global_no_zones(char **a_pkgList, int a_nodelete,
24185c51f124SMoriah Waterland 	int a_longestPkg, int a_repeat, char *a_altBinDir)
24195c51f124SMoriah Waterland {
24205c51f124SMoriah Waterland 	int	n;
24215c51f124SMoriah Waterland 	int	i;
24225c51f124SMoriah Waterland 
24235c51f124SMoriah Waterland 	/* entry assertions */
24245c51f124SMoriah Waterland 
24255c51f124SMoriah Waterland 	assert(a_pkgList != (char **)NULL);
24265c51f124SMoriah Waterland 	assert(a_longestPkg > 0);
24275c51f124SMoriah Waterland 
24285c51f124SMoriah Waterland 	/* entry debugging info */
24295c51f124SMoriah Waterland 
24305c51f124SMoriah Waterland 	echoDebug(DBG_PKGREMPKGSGZNNGZ_ENTRY);
24315c51f124SMoriah Waterland 	echoDebug(DBG_PKGREMPKGSGZNNGZ_ARGS, a_nodelete, a_longestPkg,
24325c51f124SMoriah Waterland 		a_repeat, PSTR(a_altBinDir));
24335c51f124SMoriah Waterland 
24345c51f124SMoriah Waterland 	/*
24355c51f124SMoriah Waterland 	 * all of the packages (as listed in the package list) are
24365c51f124SMoriah Waterland 	 * removed one at a time.
24375c51f124SMoriah Waterland 	 */
24385c51f124SMoriah Waterland 
24395c51f124SMoriah Waterland 	interrupted = 0;
24405c51f124SMoriah Waterland 	for (i = 0; (pkginst = a_pkgList[i]) != NULL; i++) {
24415c51f124SMoriah Waterland 		started = 0;
24425c51f124SMoriah Waterland 
24435c51f124SMoriah Waterland 		if (shall_we_continue(pkginst, npkgs) == B_FALSE) {
24445c51f124SMoriah Waterland 			continue;
24455c51f124SMoriah Waterland 		}
24465c51f124SMoriah Waterland 
24475c51f124SMoriah Waterland 		interrupted = 0;
24485c51f124SMoriah Waterland 
24495c51f124SMoriah Waterland 		/*
24505c51f124SMoriah Waterland 		 * pkgrm invoked from within the global zone and there are
24515c51f124SMoriah Waterland 		 * NO non-global zones configured:
24525c51f124SMoriah Waterland 		 * Remove the package from the global zone only.
24535c51f124SMoriah Waterland 		 */
24545c51f124SMoriah Waterland 
24555c51f124SMoriah Waterland 		n = doRemove(a_nodelete, a_altBinDir, a_longestPkg,
24565c51f124SMoriah Waterland 				admnfile, (char *)NULL, (zoneList_t)NULL);
24575c51f124SMoriah Waterland 
24585c51f124SMoriah Waterland 		/* set success/fail condition variables */
24595c51f124SMoriah Waterland 
24605c51f124SMoriah Waterland 		ckreturn(n);
24615c51f124SMoriah Waterland 
24625c51f124SMoriah Waterland 		npkgs--;
24635c51f124SMoriah Waterland 	}
24645c51f124SMoriah Waterland 
24655c51f124SMoriah Waterland 	/*
24665c51f124SMoriah Waterland 	 * all packages in the package list have been removed.
24675c51f124SMoriah Waterland 	 * Continue with removal if:
24685c51f124SMoriah Waterland 	 * -- immediate reboot is NOT required
24695c51f124SMoriah Waterland 	 * -- there are more packages to remove
24705c51f124SMoriah Waterland 	 * else return do NOT continue.
24715c51f124SMoriah Waterland 	 */
24725c51f124SMoriah Waterland 
24735c51f124SMoriah Waterland 	if ((ireboot == 0) && (a_repeat != 0)) {
24745c51f124SMoriah Waterland 		return (B_TRUE);
24755c51f124SMoriah Waterland 	}
24765c51f124SMoriah Waterland 
24775c51f124SMoriah Waterland 	/* return 'dont continue' */
24785c51f124SMoriah Waterland 
24795c51f124SMoriah Waterland 	return (B_FALSE);
24805c51f124SMoriah Waterland }
24815c51f124SMoriah Waterland 
24825c51f124SMoriah Waterland /*
24835c51f124SMoriah Waterland  * Name:	remove_packages_from_spool_directory
24845c51f124SMoriah Waterland  * Description:	Remove packages from a spool directory only.
24855c51f124SMoriah Waterland  * Arguments:	a_pkgList - pointer to array of strings, each string specifying
24865c51f124SMoriah Waterland  *			the name of one package to be removed.
24875c51f124SMoriah Waterland  *		a_nodelete: should the files and scripts remain installed?
24885c51f124SMoriah Waterland  *			- if != 0 pass -F flag to pkgremove - suppress
24895c51f124SMoriah Waterland  *			the removal of any files and any class action scripts
24905c51f124SMoriah Waterland  *			and suppress the running of any class action scripts.
24915c51f124SMoriah Waterland  *			The package files remain but the package looks like it
24925c51f124SMoriah Waterland  *			is not installed. This is mainly for use by upgrade.
24935c51f124SMoriah Waterland  *			- if == 0 do not pass -F flag to pkgremove - all
24945c51f124SMoriah Waterland  *			files and class action scripts are removed, and any
24955c51f124SMoriah Waterland  *			appropriate class action scripts are run.
24965c51f124SMoriah Waterland  *		a_longestPkg - length of the longest package "name" (for
24975c51f124SMoriah Waterland  *			output format alignment)
24985c51f124SMoriah Waterland  *		a_repeat - are there more packages avialable in "optind"
24995c51f124SMoriah Waterland  *			- B_TRUE - process packages from optind
25005c51f124SMoriah Waterland  *			- B_FALSE - do not process packages from optind
25015c51f124SMoriah Waterland  *		a_altBinDir - pointer to string representing location of the
25025c51f124SMoriah Waterland  *			pkgremove executable to run. If not NULL, then pass
25035c51f124SMoriah Waterland  *			the path specified to the -b option to pkgremove.
25045c51f124SMoriah Waterland  * Returns:	int	(see ckreturn() function for details)
25055c51f124SMoriah Waterland  *		0 - success
25065c51f124SMoriah Waterland  *		1 - package operation failed (fatal error)
25075c51f124SMoriah Waterland  *		2 - non-fatal error (warning)
25085c51f124SMoriah Waterland  *		3 - user selected quit (operation interrupted)
25095c51f124SMoriah Waterland  *		4 - admin settings prevented operation
25105c51f124SMoriah Waterland  *		5 - interaction required and -n (non-interactive) specified
25115c51f124SMoriah Waterland  *		"10" will be added to indicate "immediate reboot required"
25125c51f124SMoriah Waterland  *		"20" will be added to indicate "reboot after install required"
25135c51f124SMoriah Waterland  */
25145c51f124SMoriah Waterland 
25155c51f124SMoriah Waterland static boolean_t
25165c51f124SMoriah Waterland remove_packages_from_spool_directory(char **a_pkgList, int a_nodelete,
25175c51f124SMoriah Waterland 	int a_longestPkg, int a_repeat, char *a_altBinDir)
25185c51f124SMoriah Waterland {
25195c51f124SMoriah Waterland 	int	n;
25205c51f124SMoriah Waterland 	int	i;
25215c51f124SMoriah Waterland 
25225c51f124SMoriah Waterland 	/* entry assertions */
25235c51f124SMoriah Waterland 
25245c51f124SMoriah Waterland 	assert(a_pkgList != (char **)NULL);
25255c51f124SMoriah Waterland 	assert(a_longestPkg > 0);
25265c51f124SMoriah Waterland 
25275c51f124SMoriah Waterland 	/*
25285c51f124SMoriah Waterland 	 * all of the packages (as listed in the package list) are
25295c51f124SMoriah Waterland 	 * removed one at a time.
25305c51f124SMoriah Waterland 	 */
25315c51f124SMoriah Waterland 
25325c51f124SMoriah Waterland 	interrupted = 0;
25335c51f124SMoriah Waterland 	for (i = 0; (pkginst = a_pkgList[i]) != NULL; i++) {
25345c51f124SMoriah Waterland 		started = 0;
25355c51f124SMoriah Waterland 
25365c51f124SMoriah Waterland 		if (shall_we_continue(pkginst, npkgs) == B_FALSE) {
25375c51f124SMoriah Waterland 			continue;
25385c51f124SMoriah Waterland 		}
25395c51f124SMoriah Waterland 
25405c51f124SMoriah Waterland 		interrupted = 0;
25415c51f124SMoriah Waterland 
25425c51f124SMoriah Waterland 		/*
25435c51f124SMoriah Waterland 		 * pkgrm invoked from any type of zone BUT the target
25445c51f124SMoriah Waterland 		 * to be removed is a local spool directory: remove the
25455c51f124SMoriah Waterland 		 * packages from the spool directory only.
25465c51f124SMoriah Waterland 		 */
25475c51f124SMoriah Waterland 
25485c51f124SMoriah Waterland 		n = doRemove(a_nodelete, a_altBinDir, a_longestPkg,
25495c51f124SMoriah Waterland 			admnfile, (char *)NULL, (zoneList_t)NULL);
25505c51f124SMoriah Waterland 
25515c51f124SMoriah Waterland 		/* set success/fail condition variables */
25525c51f124SMoriah Waterland 
25535c51f124SMoriah Waterland 		ckreturn(n);
25545c51f124SMoriah Waterland 
25555c51f124SMoriah Waterland 		npkgs--;
25565c51f124SMoriah Waterland 	}
25575c51f124SMoriah Waterland 
25585c51f124SMoriah Waterland 	/*
25595c51f124SMoriah Waterland 	 * all packages in the package list have been removed.
25605c51f124SMoriah Waterland 	 * Continue with removal if:
25615c51f124SMoriah Waterland 	 * -- immediate reboot is NOT required
25625c51f124SMoriah Waterland 	 * -- there are more packages to remove
25635c51f124SMoriah Waterland 	 * else return do NOT continue.
25645c51f124SMoriah Waterland 	 */
25655c51f124SMoriah Waterland 
25665c51f124SMoriah Waterland 	if ((ireboot == 0) && (a_repeat != 0)) {
25675c51f124SMoriah Waterland 		return (B_TRUE);
25685c51f124SMoriah Waterland 	}
25695c51f124SMoriah Waterland 
25705c51f124SMoriah Waterland 	/* return 'dont continue' */
25715c51f124SMoriah Waterland 
25725c51f124SMoriah Waterland 	return (B_FALSE);
25735c51f124SMoriah Waterland }
25745c51f124SMoriah Waterland 
25755c51f124SMoriah Waterland /*
25765c51f124SMoriah Waterland  * Name:	remove_packages
25775c51f124SMoriah Waterland  * Description:	Remove packages from the global zone, and optionally from one
25785c51f124SMoriah Waterland  *		or more non-global zones, or from a specified spool directory.
25795c51f124SMoriah Waterland  * Arguments:	a_pkgList - pointer to array of strings, each string specifying
25805c51f124SMoriah Waterland  *			the name of one package to be removed.
25815c51f124SMoriah Waterland  *		a_nodelete: should the files and scripts remain installed?
25825c51f124SMoriah Waterland  *			- if != 0 pass -F flag to pkgremove - suppress
25835c51f124SMoriah Waterland  *			the removal of any files and any class action scripts
25845c51f124SMoriah Waterland  *			and suppress the running of any class action scripts.
25855c51f124SMoriah Waterland  *			The package files remain but the package looks like it
25865c51f124SMoriah Waterland  *			is not installed. This is mainly for use by upgrade.
25875c51f124SMoriah Waterland  *			- if == 0 do not pass -F flag to pkgremove - all
25885c51f124SMoriah Waterland  *			files and class action scripts are removed, and any
25895c51f124SMoriah Waterland  *			appropriate class action scripts are run.
25905c51f124SMoriah Waterland  *		a_longestPkg - length of the longest package "name" (for
25915c51f124SMoriah Waterland  *			output format alignment)
25925c51f124SMoriah Waterland  *		a_repeat - are there more packages avialable in "optind"
25935c51f124SMoriah Waterland  *			- B_TRUE - process packages from optind
25945c51f124SMoriah Waterland  *			- B_FALSE - do not process packages from optind
25955c51f124SMoriah Waterland  *		a_altBinDir - pointer to string representing location of the
25965c51f124SMoriah Waterland  *			pkgremove executable to run. If not NULL, then pass
25975c51f124SMoriah Waterland  *			the path specified to the -b option to pkgremove.
25985c51f124SMoriah Waterland  *		a_pkgdir - pointer to string representing the directory
25995c51f124SMoriah Waterland  *			where the packages to be removed are located.
26005c51f124SMoriah Waterland  *		a_spoolDir - pointer to string specifying spool directory
26015c51f124SMoriah Waterland  *			to remove packages from. If != NULL then all zones
26025c51f124SMoriah Waterland  *			processing is bypassed and the packages are removed
26035c51f124SMoriah Waterland  *			from the specified spool directory only.
26045c51f124SMoriah Waterland  *		a_noZones - if non-global zones are configured, should the
26055c51f124SMoriah Waterland  *			packages be removed from the non-global zones?
26065c51f124SMoriah Waterland  *			- B_TRUE - do NOT remove packages from non-global zones
26075c51f124SMoriah Waterland  *			- B_FALSE - remove packages from non-global zones
26085c51f124SMoriah Waterland  * Returns:	int	(see ckreturn() function for details)
26095c51f124SMoriah Waterland  *		0 - success
26105c51f124SMoriah Waterland  *		1 - package operation failed (fatal error)
26115c51f124SMoriah Waterland  *		2 - non-fatal error (warning)
26125c51f124SMoriah Waterland  *		3 - user selected quit (operation interrupted)
26135c51f124SMoriah Waterland  *		4 - admin settings prevented operation
26145c51f124SMoriah Waterland  *		5 - interaction required and -n (non-interactive) specified
26155c51f124SMoriah Waterland  *		"10" will be added to indicate "immediate reboot required"
26165c51f124SMoriah Waterland  *		"20" will be added to indicate "reboot after install required"
26175c51f124SMoriah Waterland  */
26185c51f124SMoriah Waterland 
26195c51f124SMoriah Waterland static boolean_t
26205c51f124SMoriah Waterland remove_packages(char **a_pkgList, int a_nodelete, int a_longestPkg,
26215c51f124SMoriah Waterland 	int a_repeat, char *a_altBinDir, char *a_pkgdir, char *a_spoolDir,
26225c51f124SMoriah Waterland 	boolean_t a_noZones)
26235c51f124SMoriah Waterland {
26245c51f124SMoriah Waterland 	zoneList_t	zlst;
26255c51f124SMoriah Waterland 	boolean_t	b;
26265c51f124SMoriah Waterland 
26275c51f124SMoriah Waterland 	/* entry assertions */
26285c51f124SMoriah Waterland 
26295c51f124SMoriah Waterland 	assert(a_pkgList != (char **)NULL);
26305c51f124SMoriah Waterland 
26315c51f124SMoriah Waterland 	echoDebug(DBG_REMOVEPKGS_ENTRY);
26325c51f124SMoriah Waterland 	echoDebug(DBG_REMOVEPKGS_ARGS, npkgs, a_nodelete, a_longestPkg,
26335c51f124SMoriah Waterland 		a_repeat, PSTR(a_pkgdir), PSTR(a_spoolDir));
26345c51f124SMoriah Waterland 
26355c51f124SMoriah Waterland 	/*
26365c51f124SMoriah Waterland 	 * if removing from spool directory, bypass all zones checks
26375c51f124SMoriah Waterland 	 */
26385c51f124SMoriah Waterland 
26395c51f124SMoriah Waterland 	if (a_spoolDir != (char *)NULL) {
26405c51f124SMoriah Waterland 		/* in non-global zone */
26415c51f124SMoriah Waterland 
26425c51f124SMoriah Waterland 		echoDebug(DBG_REMOVE_PKGS_FROM_SPOOL, a_spoolDir);
26435c51f124SMoriah Waterland 
26445c51f124SMoriah Waterland 		b = remove_packages_from_spool_directory(a_pkgList, a_nodelete,
26455c51f124SMoriah Waterland 			a_longestPkg, a_repeat, a_altBinDir);
26465c51f124SMoriah Waterland 
26475c51f124SMoriah Waterland 		return (B_FALSE);
26485c51f124SMoriah Waterland 	}
26495c51f124SMoriah Waterland 
26505c51f124SMoriah Waterland 	/* exit if not root */
26515c51f124SMoriah Waterland 
26525c51f124SMoriah Waterland 	if (getuid()) {
26535c51f124SMoriah Waterland 		progerr(ERR_NOT_ROOT, get_prog_name());
26545c51f124SMoriah Waterland 		exit(1);
26555c51f124SMoriah Waterland 	}
26565c51f124SMoriah Waterland 
26575c51f124SMoriah Waterland 	/*
26585c51f124SMoriah Waterland 	 * if running in the global zone AND one or more non-global
26595c51f124SMoriah Waterland 	 * zones exist, add packages in a 'zones aware' manner, else
26605c51f124SMoriah Waterland 	 * add packages in the standard 'non-zones aware' manner.
26615c51f124SMoriah Waterland 	 */
26625c51f124SMoriah Waterland 
26635c51f124SMoriah Waterland 	if ((a_noZones == B_FALSE) && (z_running_in_global_zone() == B_FALSE)) {
26645c51f124SMoriah Waterland 		/* in non-global zone */
26655c51f124SMoriah Waterland 
26665c51f124SMoriah Waterland 		echoDebug(DBG_IN_LZ);
26675c51f124SMoriah Waterland 
26685c51f124SMoriah Waterland 		b = z_lock_this_zone(ZLOCKS_PKG_ADMIN);
26695c51f124SMoriah Waterland 		if (b != B_TRUE) {
26705c51f124SMoriah Waterland 			progerr(ERR_CANNOT_LOCK_THIS_ZONE);
26715c51f124SMoriah Waterland 			/* set fatal error return condition */
26725c51f124SMoriah Waterland 			ckreturn(1);
26735c51f124SMoriah Waterland 			return (B_FALSE);
26745c51f124SMoriah Waterland 		}
26755c51f124SMoriah Waterland 
26765c51f124SMoriah Waterland 		b = remove_packages_in_nonglobal_zone(a_pkgList, a_nodelete,
26775c51f124SMoriah Waterland 			a_longestPkg, a_repeat, a_altBinDir, a_pkgdir);
26785c51f124SMoriah Waterland 
26795c51f124SMoriah Waterland 		(void) z_unlock_this_zone(ZLOCKS_ALL);
26805c51f124SMoriah Waterland 
26815c51f124SMoriah Waterland 		return (B_FALSE);
26825c51f124SMoriah Waterland 	}
26835c51f124SMoriah Waterland 
26845c51f124SMoriah Waterland 	/* running in the global zone */
26855c51f124SMoriah Waterland 
26865c51f124SMoriah Waterland 	b = z_non_global_zones_exist();
26875c51f124SMoriah Waterland 	if ((a_noZones == B_FALSE) && (b == B_TRUE)) {
26885c51f124SMoriah Waterland 
26895c51f124SMoriah Waterland 		echoDebug(DBG_IN_GZ_WITH_LZ);
26905c51f124SMoriah Waterland 
26915c51f124SMoriah Waterland 		/* get a list of all non-global zones */
26925c51f124SMoriah Waterland 		zlst = z_get_nonglobal_zone_list();
26935c51f124SMoriah Waterland 		if (zlst == (zoneList_t)NULL) {
26945c51f124SMoriah Waterland 			progerr(ERR_CANNOT_GET_ZONE_LIST);
26955c51f124SMoriah Waterland 			quit(1);
26965c51f124SMoriah Waterland 		}
26975c51f124SMoriah Waterland 
26985c51f124SMoriah Waterland 		/* need to lock all of the zones */
26995c51f124SMoriah Waterland 
27005c51f124SMoriah Waterland 		quitSetZonelist(zlst);
27015c51f124SMoriah Waterland 		b = z_lock_zones(zlst, ZLOCKS_PKG_ADMIN);
27025c51f124SMoriah Waterland 		if (b == B_FALSE) {
27035c51f124SMoriah Waterland 			z_free_zone_list(zlst);
27045c51f124SMoriah Waterland 			progerr(ERR_CANNOT_LOCK_ZONES);
27055c51f124SMoriah Waterland 			/* set fatal error return condition */
27065c51f124SMoriah Waterland 			ckreturn(1);
27075c51f124SMoriah Waterland 			return (B_FALSE);
27085c51f124SMoriah Waterland 		}
27095c51f124SMoriah Waterland 
27105c51f124SMoriah Waterland 		/* add packages to all zones */
27115c51f124SMoriah Waterland 
27125c51f124SMoriah Waterland 		b = remove_packages_in_global_with_zones(a_pkgList, a_nodelete,
27135c51f124SMoriah Waterland 			a_longestPkg, a_repeat, a_altBinDir, a_pkgdir, zlst);
27145c51f124SMoriah Waterland 
27155c51f124SMoriah Waterland 		/* unlock all zones */
27165c51f124SMoriah Waterland 
27175c51f124SMoriah Waterland 		(void) z_unlock_zones(zlst, ZLOCKS_ALL);
27185c51f124SMoriah Waterland 		quitSetZonelist((zoneList_t)NULL);
27195c51f124SMoriah Waterland 
27205c51f124SMoriah Waterland 		/* free list of all non-global zones */
27215c51f124SMoriah Waterland 
27225c51f124SMoriah Waterland 		z_free_zone_list(zlst);
27235c51f124SMoriah Waterland 
27245c51f124SMoriah Waterland 		return (B_FALSE);
27255c51f124SMoriah Waterland 	}
27265c51f124SMoriah Waterland 
27275c51f124SMoriah Waterland 	/* in global zone no non-global zones */
27285c51f124SMoriah Waterland 
27295c51f124SMoriah Waterland 	echoDebug(DBG_IN_GZ_NO_LZ);
27305c51f124SMoriah Waterland 
27315c51f124SMoriah Waterland 	b = z_lock_this_zone(ZLOCKS_PKG_ADMIN);
27325c51f124SMoriah Waterland 	if (b != B_TRUE) {
27335c51f124SMoriah Waterland 		progerr(ERR_CANNOT_LOCK_THIS_ZONE);
27345c51f124SMoriah Waterland 		/* set fatal error return condition */
27355c51f124SMoriah Waterland 		ckreturn(1);
27365c51f124SMoriah Waterland 		return (B_FALSE);
27375c51f124SMoriah Waterland 	}
27385c51f124SMoriah Waterland 
27395c51f124SMoriah Waterland 	b = remove_packages_in_global_no_zones(a_pkgList, a_nodelete,
27405c51f124SMoriah Waterland 			a_longestPkg, a_repeat, a_altBinDir);
27415c51f124SMoriah Waterland 
27425c51f124SMoriah Waterland 	(void) z_unlock_this_zone(ZLOCKS_ALL);
27435c51f124SMoriah Waterland 
27445c51f124SMoriah Waterland 	return (B_FALSE);
27455c51f124SMoriah Waterland }
27465c51f124SMoriah Waterland 
27475c51f124SMoriah Waterland /*
27485c51f124SMoriah Waterland  * Name:		path_valid
27495c51f124SMoriah Waterland  * Description:	Checks a string for being a valid path
27505c51f124SMoriah Waterland  *
27515c51f124SMoriah Waterland  * Arguments:	path - path to validate
27525c51f124SMoriah Waterland  *
27535c51f124SMoriah Waterland  * Returns :	B_TRUE - success, B_FALSE otherwise.
27545c51f124SMoriah Waterland  *		B_FALSE means path was null, too long (>PATH_MAX),
27555c51f124SMoriah Waterland  *		or too short (<1)
27565c51f124SMoriah Waterland  */
27575c51f124SMoriah Waterland static boolean_t
27585c51f124SMoriah Waterland path_valid(char *path)
27595c51f124SMoriah Waterland {
27605c51f124SMoriah Waterland 	if (path == NULL) {
27615c51f124SMoriah Waterland 		return (B_FALSE);
27625c51f124SMoriah Waterland 	} else if (strlen(path) > PATH_MAX) {
27635c51f124SMoriah Waterland 		return (B_FALSE);
27645c51f124SMoriah Waterland 	} else if (strlen(path) >= 1) {
27655c51f124SMoriah Waterland 		return (B_TRUE);
27665c51f124SMoriah Waterland 	} else {
27675c51f124SMoriah Waterland 		/* path < 1 */
27685c51f124SMoriah Waterland 		return (B_FALSE);
27695c51f124SMoriah Waterland 	}
27705c51f124SMoriah Waterland }
27715c51f124SMoriah Waterland 
27725c51f124SMoriah Waterland /*
27735c51f124SMoriah Waterland  */
27745c51f124SMoriah Waterland 
27755c51f124SMoriah Waterland static boolean_t
27765c51f124SMoriah Waterland check_packages(char **a_pkgList, char *a_packageDir)
27775c51f124SMoriah Waterland {
27785c51f124SMoriah Waterland 	int	savenpkgs = npkgs;
27795c51f124SMoriah Waterland 	int	i;
27805c51f124SMoriah Waterland 	CAF_T	flags = 0;
27815c51f124SMoriah Waterland 
27825c51f124SMoriah Waterland 	/* set flags for applicability check */
27835c51f124SMoriah Waterland 
27845c51f124SMoriah Waterland 	if (z_running_in_global_zone() == B_TRUE) {
27855c51f124SMoriah Waterland 		flags |= CAF_IN_GLOBAL_ZONE;
27865c51f124SMoriah Waterland 	}
27875c51f124SMoriah Waterland 
27885c51f124SMoriah Waterland 	/*
27895c51f124SMoriah Waterland 	 * for each package to remove, verify that the package is installed
27905c51f124SMoriah Waterland 	 * and is removable.
27915c51f124SMoriah Waterland 	 */
27925c51f124SMoriah Waterland 
27935c51f124SMoriah Waterland 	for (i = 0; (pkginst = a_pkgList[i]) != NULL; i++) {
27945c51f124SMoriah Waterland 		/* check package applicability */
27955c51f124SMoriah Waterland 		if (check_applicability(a_packageDir, pkginst, get_inst_root(),
27965c51f124SMoriah Waterland 			flags) == B_FALSE) {
27975c51f124SMoriah Waterland 			progerr(ERR_PKG_NOT_REMOVABLE, pkginst);
27985c51f124SMoriah Waterland 			npkgs = savenpkgs;
27995c51f124SMoriah Waterland 			return (B_FALSE);
28005c51f124SMoriah Waterland 		}
28015c51f124SMoriah Waterland 		npkgs--;
28025c51f124SMoriah Waterland 	}
28035c51f124SMoriah Waterland 
28045c51f124SMoriah Waterland 	npkgs = savenpkgs;
28055c51f124SMoriah Waterland 	return (B_TRUE);
28065c51f124SMoriah Waterland }
28075c51f124SMoriah Waterland 
28085c51f124SMoriah Waterland /*
28095c51f124SMoriah Waterland  * - is this package removable from this zone?
28105c51f124SMoriah Waterland  * - does the scope of remove conflict with existing installation
28115c51f124SMoriah Waterland  */
28125c51f124SMoriah Waterland 
28135c51f124SMoriah Waterland static boolean_t
28145c51f124SMoriah Waterland check_applicability(char *a_packageDir, char *a_pkgInst,
28155c51f124SMoriah Waterland 	char *a_rootPath, CAF_T a_flags)
28165c51f124SMoriah Waterland {
28175c51f124SMoriah Waterland 	FILE		*pkginfoFP;
28185c51f124SMoriah Waterland 	boolean_t	all_zones;	/* pkg is "all zones" only */
28195c51f124SMoriah Waterland 	char		pkginfoPath[PATH_MAX];
28205c51f124SMoriah Waterland 	char		pkgpath[PATH_MAX];
28215c51f124SMoriah Waterland 	int		len;
28225c51f124SMoriah Waterland 
28235c51f124SMoriah Waterland 	/* entry assertions */
28245c51f124SMoriah Waterland 
28255c51f124SMoriah Waterland 	assert(a_packageDir != (char *)NULL);
28265c51f124SMoriah Waterland 	assert(*a_packageDir != '\0');
28275c51f124SMoriah Waterland 	assert(a_pkgInst != (char *)NULL);
28285c51f124SMoriah Waterland 	assert(*a_pkgInst != '\0');
28295c51f124SMoriah Waterland 
28305c51f124SMoriah Waterland 	/* normalize root path */
28315c51f124SMoriah Waterland 
28325c51f124SMoriah Waterland 	if (a_rootPath == (char *)NULL) {
28335c51f124SMoriah Waterland 		a_rootPath = "";
28345c51f124SMoriah Waterland 	}
28355c51f124SMoriah Waterland 
28365c51f124SMoriah Waterland 	/*
28375c51f124SMoriah Waterland 	 * determine if this package is currently installed
28385c51f124SMoriah Waterland 	 * if not installed return success - operation will fail
28395c51f124SMoriah Waterland 	 * when the removal is attempted
28405c51f124SMoriah Waterland 	 */
28415c51f124SMoriah Waterland 
28425c51f124SMoriah Waterland 	if (pkginfoIsPkgInstalled((struct pkginfo **)NULL, a_pkgInst) !=
28435c51f124SMoriah Waterland 		B_TRUE) {
28445c51f124SMoriah Waterland 		return (B_TRUE);
28455c51f124SMoriah Waterland 	}
28465c51f124SMoriah Waterland 
28475c51f124SMoriah Waterland 	/*
28485c51f124SMoriah Waterland 	 * calculate paths to various objects
28495c51f124SMoriah Waterland 	 */
28505c51f124SMoriah Waterland 
28515c51f124SMoriah Waterland 	len = snprintf(pkgpath, sizeof (pkgpath), "%s/%s", a_packageDir,
28525c51f124SMoriah Waterland 			a_pkgInst);
28535c51f124SMoriah Waterland 	if (len > sizeof (pkgpath)) {
28545c51f124SMoriah Waterland 		progerr(ERR_CREATE_PATH_2, a_packageDir, a_pkgInst);
28555c51f124SMoriah Waterland 		return (B_FALSE);
28565c51f124SMoriah Waterland 	}
28575c51f124SMoriah Waterland 
28585c51f124SMoriah Waterland 	/* if not installed then just return */
28595c51f124SMoriah Waterland 
28605c51f124SMoriah Waterland 	if (isdir(pkgpath) != 0) {
28615c51f124SMoriah Waterland 		progerr(ERR_NO_PKGDIR, pkgpath, a_pkgInst, strerror(errno));
28625c51f124SMoriah Waterland 		return (B_TRUE);
28635c51f124SMoriah Waterland 	}
28645c51f124SMoriah Waterland 
28655c51f124SMoriah Waterland 	len = snprintf(pkginfoPath, sizeof (pkginfoPath),
28665c51f124SMoriah Waterland 			"%s/pkginfo", pkgpath);
28675c51f124SMoriah Waterland 	if (len > sizeof (pkgpath)) {
28685c51f124SMoriah Waterland 		progerr(ERR_CREATE_PATH_2, pkgpath, "pkginfo");
28695c51f124SMoriah Waterland 		return (B_FALSE);
28705c51f124SMoriah Waterland 	}
28715c51f124SMoriah Waterland 
28725c51f124SMoriah Waterland 	/*
28735c51f124SMoriah Waterland 	 * gather information from this packages pkginfo file
28745c51f124SMoriah Waterland 	 */
28755c51f124SMoriah Waterland 
28765c51f124SMoriah Waterland 	pkginfoFP = fopen(pkginfoPath, "r");
28775c51f124SMoriah Waterland 
28785c51f124SMoriah Waterland 	if (pkginfoFP == (FILE *)NULL) {
28795c51f124SMoriah Waterland 		progerr(ERR_NO_PKG_INFOFILE, a_pkgInst, pkginfoPath,
28805c51f124SMoriah Waterland 							strerror(errno));
28815c51f124SMoriah Waterland 		return (B_FALSE);
28825c51f124SMoriah Waterland 	}
28835c51f124SMoriah Waterland 
28845c51f124SMoriah Waterland 	/* determine "ALLZONES" setting for this package */
28855c51f124SMoriah Waterland 
28865c51f124SMoriah Waterland 	all_zones = pkginfoParamTruth(pkginfoFP, PKG_ALLZONES_VARIABLE,
28875c51f124SMoriah Waterland 			"true", B_FALSE);
28885c51f124SMoriah Waterland 
28895c51f124SMoriah Waterland 	/* close pkginfo file */
28905c51f124SMoriah Waterland 
28915c51f124SMoriah Waterland 	(void) fclose(pkginfoFP);
28925c51f124SMoriah Waterland 
28935c51f124SMoriah Waterland 	/* gather information from the global zone only file */
28945c51f124SMoriah Waterland 
28955c51f124SMoriah Waterland 	/*
28965c51f124SMoriah Waterland 	 * verify package applicability based on information gathered;
28975c51f124SMoriah Waterland 	 * the package IS currently installed....
28985c51f124SMoriah Waterland 	 */
28995c51f124SMoriah Waterland 
29005c51f124SMoriah Waterland 	/* pkg ALLZONES=true & not running in global zone */
29015c51f124SMoriah Waterland 
29025c51f124SMoriah Waterland 	if ((all_zones == B_TRUE) && (!(a_flags & CAF_IN_GLOBAL_ZONE))) {
29035c51f124SMoriah Waterland 		progerr(ERR_ALLZONES_AND_IN_LZ_PKGRM, a_pkgInst);
29045c51f124SMoriah Waterland 		return (B_FALSE);
29055c51f124SMoriah Waterland 	}
29065c51f124SMoriah Waterland 
29075c51f124SMoriah Waterland 	return (B_TRUE);
29085c51f124SMoriah Waterland }
29095c51f124SMoriah Waterland 
29105c51f124SMoriah Waterland /*
29115c51f124SMoriah Waterland  * Name:	shall_we_continue
29125c51f124SMoriah Waterland  * Description: Called from within a loop that is installing packages,
29135c51f124SMoriah Waterland  *		this function examines various global variables and decides
29145c51f124SMoriah Waterland  *		whether or not to ask an appropriate question, and wait for
29155c51f124SMoriah Waterland  *		and appropriate reply.
29165c51f124SMoriah Waterland  * Arguments:	<<global variables>>
29175c51f124SMoriah Waterland  * Returns:	B_TRUE - continue processing with next package
29185c51f124SMoriah Waterland  *		B_FALSE - do not continue processing with next package
29195c51f124SMoriah Waterland  */
29205c51f124SMoriah Waterland 
29215c51f124SMoriah Waterland static boolean_t
29225c51f124SMoriah Waterland shall_we_continue(char *a_pkgInst, int a_npkgs)
29235c51f124SMoriah Waterland {
29245c51f124SMoriah Waterland 	char	ans[MAX_INPUT];
29255c51f124SMoriah Waterland 	int	n;
29265c51f124SMoriah Waterland 
29275c51f124SMoriah Waterland 	/* return FALSE if immediate reboot required */
29285c51f124SMoriah Waterland 
29295c51f124SMoriah Waterland 	if (ireboot) {
29305c51f124SMoriah Waterland 		ptext(stderr, MSG_SUSPEND_RM, a_pkgInst);
29315c51f124SMoriah Waterland 		return (B_FALSE);
29325c51f124SMoriah Waterland 	}
29335c51f124SMoriah Waterland 
29345c51f124SMoriah Waterland 	/* return TRUE if not interrupted */
29355c51f124SMoriah Waterland 
29365c51f124SMoriah Waterland 	if (!interrupted) {
29375c51f124SMoriah Waterland 		return (B_TRUE);
29385c51f124SMoriah Waterland 	}
29395c51f124SMoriah Waterland 
29405c51f124SMoriah Waterland 	/* output appropriate interrupt message */
29415c51f124SMoriah Waterland 
29425c51f124SMoriah Waterland 	echo(a_npkgs == 1 ? MSG_1MORETODO : MSG_MORETODO, a_npkgs);
29435c51f124SMoriah Waterland 
29445c51f124SMoriah Waterland 	/* if running with no interaction (-n) do not ask question */
29455c51f124SMoriah Waterland 
29465c51f124SMoriah Waterland 	if (nointeract) {
29475c51f124SMoriah Waterland 		quit(0);
29485c51f124SMoriah Waterland 		/* NOTREACHED */
29495c51f124SMoriah Waterland 	}
29505c51f124SMoriah Waterland 
29515c51f124SMoriah Waterland 	/* interaction possible: ask question */
29525c51f124SMoriah Waterland 
29535c51f124SMoriah Waterland 	n = ckyorn(ans, NULL, NULL, NULL, ASK_CONTINUE_RM);
29545c51f124SMoriah Waterland 	if (n != 0) {
29555c51f124SMoriah Waterland 		quit(n);
29565c51f124SMoriah Waterland 		/* NOTREACHED */
29575c51f124SMoriah Waterland 	}
29585c51f124SMoriah Waterland 
29595c51f124SMoriah Waterland 	if (strchr("yY", *ans) == NULL) {
29605c51f124SMoriah Waterland 		quit(0);
29615c51f124SMoriah Waterland 		/* NOTREACHED */
29625c51f124SMoriah Waterland 	}
29635c51f124SMoriah Waterland 	return (B_TRUE);
29645c51f124SMoriah Waterland }
29655c51f124SMoriah Waterland 
29665c51f124SMoriah Waterland /*
29675c51f124SMoriah Waterland  * Name:	create_zone_adminfile
29685c51f124SMoriah Waterland  * Description: Given a zone temporary directory and optionally an existing
29695c51f124SMoriah Waterland  *		administration file, generate an administration file that
29705c51f124SMoriah Waterland  *		can be used to perform "non-interactive" operations in a
29715c51f124SMoriah Waterland  *		non-global zone.
29725c51f124SMoriah Waterland  * Arguments:	r_zoneAdminFile - pointer to handle that will contain a
29735c51f124SMoriah Waterland  *			string representing the path to the temporary
29745c51f124SMoriah Waterland  *			administration file created - this must be NULL
29755c51f124SMoriah Waterland  *			before the first call to this function - on
29765c51f124SMoriah Waterland  *			subsequent calls if the pointer is NOT null then
29775c51f124SMoriah Waterland  *			the existing string will NOT be overwritten.
29785c51f124SMoriah Waterland  *		a_zoneTempDir - pointer to string representing the path
29795c51f124SMoriah Waterland  *			to the zone temporary directory to create the
29805c51f124SMoriah Waterland  *			temporary administration file in
29815c51f124SMoriah Waterland  *		a_admnfile - pointer to string representing the path to
29825c51f124SMoriah Waterland  *			an existing "user" administration file - the
29835c51f124SMoriah Waterland  *			administration file created will contain the
29845c51f124SMoriah Waterland  *			settings contained in this file, modified as
29855c51f124SMoriah Waterland  *			appropriate to supress any interaction;
29865c51f124SMoriah Waterland  *			If this is == NULL then the administration file
29875c51f124SMoriah Waterland  *			created will not contain any extra settings
29885c51f124SMoriah Waterland  * Returns:	void
29895c51f124SMoriah Waterland  * NOTE:	Any string returned is placed in new storage for the
29905c51f124SMoriah Waterland  *		calling method. The caller must use 'free' to dispose
29915c51f124SMoriah Waterland  *		of the storage once the string is no longer needed.
29925c51f124SMoriah Waterland  * NOTE:	On any error this function will call 'quit(1)'
29935c51f124SMoriah Waterland  */
29945c51f124SMoriah Waterland 
29955c51f124SMoriah Waterland static void
29965c51f124SMoriah Waterland create_zone_adminfile(char **r_zoneAdminFile, char *a_zoneTempDir,
29975c51f124SMoriah Waterland 	char *a_admnfile)
29985c51f124SMoriah Waterland {
29995c51f124SMoriah Waterland 	boolean_t	b;
30005c51f124SMoriah Waterland 
30015c51f124SMoriah Waterland 	/* entry assertions */
30025c51f124SMoriah Waterland 
30035c51f124SMoriah Waterland 	assert(r_zoneAdminFile != (char **)NULL);
30045c51f124SMoriah Waterland 	assert(a_zoneTempDir != (char *)NULL);
30055c51f124SMoriah Waterland 	assert(*a_zoneTempDir != '\0');
30065c51f124SMoriah Waterland 
30075c51f124SMoriah Waterland 	/* entry debugging info */
30085c51f124SMoriah Waterland 
30095c51f124SMoriah Waterland 	echoDebug(DBG_CREATE_ZONE_ADMINFILE, a_zoneTempDir, PSTR(a_admnfile));
30105c51f124SMoriah Waterland 
30115c51f124SMoriah Waterland 	/* if temporary name already exists, do not overwrite */
30125c51f124SMoriah Waterland 
30135c51f124SMoriah Waterland 	if (*r_zoneAdminFile != (char *)NULL) {
30145c51f124SMoriah Waterland 		return;
30155c51f124SMoriah Waterland 	}
30165c51f124SMoriah Waterland 
30175c51f124SMoriah Waterland 	/* create temporary name */
30185c51f124SMoriah Waterland 
30195c51f124SMoriah Waterland 	*r_zoneAdminFile = tempnam(a_zoneTempDir, "zadmn");
30205c51f124SMoriah Waterland 	b = z_create_zone_admin_file(*r_zoneAdminFile, a_admnfile);
30215c51f124SMoriah Waterland 	if (b == B_FALSE) {
30225c51f124SMoriah Waterland 		progerr(ERR_CREATE_TMPADMIN, *r_zoneAdminFile,
30235c51f124SMoriah Waterland 			strerror(errno));
30245c51f124SMoriah Waterland 		quit(1);
30255c51f124SMoriah Waterland 		/* NOTREACHED */
30265c51f124SMoriah Waterland 	}
30275c51f124SMoriah Waterland 
30285c51f124SMoriah Waterland 	echoDebug(DBG_CREATED_ZONE_ADMINFILE, *r_zoneAdminFile);
30295c51f124SMoriah Waterland }
30305c51f124SMoriah Waterland 
30315c51f124SMoriah Waterland /*
30325c51f124SMoriah Waterland  * Name:	create_zone_tempdir
30335c51f124SMoriah Waterland  * Description: Given a system temporary directory, create a "zone" specific
30345c51f124SMoriah Waterland  *		temporary directory and return the path to the directory
30355c51f124SMoriah Waterland  *		created.
30365c51f124SMoriah Waterland  * Arguments:	r_zoneTempDir - pointer to handle that will contain a
30375c51f124SMoriah Waterland  *			string representing the path to the temporary
30385c51f124SMoriah Waterland  *			directory created - this must be NULL before the
30395c51f124SMoriah Waterland  *			first call to this function - on subsequent calls
30405c51f124SMoriah Waterland  *			if the pointer is NOT null then the existing string
30415c51f124SMoriah Waterland  *			will NOT be overwritten.
30425c51f124SMoriah Waterland  *		a_zoneTempDir - pointer to string representing the path
30435c51f124SMoriah Waterland  *			to the system temporary directory to create the
30445c51f124SMoriah Waterland  *			temporary zone directory in
30455c51f124SMoriah Waterland  * Returns:	void
30465c51f124SMoriah Waterland  * NOTE:	Any string returned is placed in new storage for the
30475c51f124SMoriah Waterland  *		calling method. The caller must use 'free' to dispose
30485c51f124SMoriah Waterland  *		of the storage once the string is no longer needed.
30495c51f124SMoriah Waterland  * NOTE:	On any error this function will call 'quit(1)'
30505c51f124SMoriah Waterland  * NOTE:	This function calls "quitSetZoneTmpdir" on success to
30515c51f124SMoriah Waterland  *		register the directory created with quit() so that the
30525c51f124SMoriah Waterland  *		directory will be automatically deleted on exit.
30535c51f124SMoriah Waterland  */
30545c51f124SMoriah Waterland 
30555c51f124SMoriah Waterland static void
30565c51f124SMoriah Waterland create_zone_tempdir(char **r_zoneTempDir, char *a_tmpdir)
30575c51f124SMoriah Waterland {
30585c51f124SMoriah Waterland 	boolean_t	b;
30595c51f124SMoriah Waterland 
30605c51f124SMoriah Waterland 	/* entry assertions */
30615c51f124SMoriah Waterland 
30625c51f124SMoriah Waterland 	assert(r_zoneTempDir != (char **)NULL);
30635c51f124SMoriah Waterland 	assert(a_tmpdir != (char *)NULL);
30645c51f124SMoriah Waterland 	assert(*a_tmpdir != '\0');
30655c51f124SMoriah Waterland 
30665c51f124SMoriah Waterland 	/* entry debugging info */
30675c51f124SMoriah Waterland 
30685c51f124SMoriah Waterland 	echoDebug(DBG_CREATE_ZONE_TEMPDIR, a_tmpdir);
30695c51f124SMoriah Waterland 
30705c51f124SMoriah Waterland 	/* if temporary directory already exists, do not overwrite */
30715c51f124SMoriah Waterland 
30725c51f124SMoriah Waterland 	if (*r_zoneTempDir != (char *)NULL) {
30735c51f124SMoriah Waterland 		return;
30745c51f124SMoriah Waterland 	}
30755c51f124SMoriah Waterland 
30765c51f124SMoriah Waterland 	/* create temporary directory */
30775c51f124SMoriah Waterland 
30785c51f124SMoriah Waterland 	b = setup_temporary_directory(r_zoneTempDir, a_tmpdir, "ztemp");
30795c51f124SMoriah Waterland 	if (b == B_FALSE) {
30805c51f124SMoriah Waterland 		progerr(ERR_ZONETEMPDIR, a_tmpdir, strerror(errno));
30815c51f124SMoriah Waterland 		quit(1);
30825c51f124SMoriah Waterland 		/* NOTREACHED */
30835c51f124SMoriah Waterland 	}
30845c51f124SMoriah Waterland 
30855c51f124SMoriah Waterland 	/* register with quit() to directory is removed on exit */
30865c51f124SMoriah Waterland 
30875c51f124SMoriah Waterland 	quitSetZoneTmpdir(*r_zoneTempDir);
30885c51f124SMoriah Waterland 
30895c51f124SMoriah Waterland 	/* exit debugging info */
30905c51f124SMoriah Waterland 
30915c51f124SMoriah Waterland 	echoDebug(DBG_CREATED_ZONE_TEMPDIR, *r_zoneTempDir);
30925c51f124SMoriah Waterland }
3093