xref: /onnv-gate/usr/src/cmd/svr4pkg/pkgrm/main.c (revision 9869)
19781SMoriah.Waterland@Sun.COM /*
29781SMoriah.Waterland@Sun.COM  * CDDL HEADER START
39781SMoriah.Waterland@Sun.COM  *
49781SMoriah.Waterland@Sun.COM  * The contents of this file are subject to the terms of the
59781SMoriah.Waterland@Sun.COM  * Common Development and Distribution License (the "License").
69781SMoriah.Waterland@Sun.COM  * You may not use this file except in compliance with the License.
79781SMoriah.Waterland@Sun.COM  *
89781SMoriah.Waterland@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
99781SMoriah.Waterland@Sun.COM  * or http://www.opensolaris.org/os/licensing.
109781SMoriah.Waterland@Sun.COM  * See the License for the specific language governing permissions
119781SMoriah.Waterland@Sun.COM  * and limitations under the License.
129781SMoriah.Waterland@Sun.COM  *
139781SMoriah.Waterland@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
149781SMoriah.Waterland@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
159781SMoriah.Waterland@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
169781SMoriah.Waterland@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
179781SMoriah.Waterland@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
189781SMoriah.Waterland@Sun.COM  *
199781SMoriah.Waterland@Sun.COM  * CDDL HEADER END
209781SMoriah.Waterland@Sun.COM  */
219781SMoriah.Waterland@Sun.COM 
229781SMoriah.Waterland@Sun.COM /*
239781SMoriah.Waterland@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
249781SMoriah.Waterland@Sun.COM  * Use is subject to license terms.
259781SMoriah.Waterland@Sun.COM  */
269781SMoriah.Waterland@Sun.COM 
279781SMoriah.Waterland@Sun.COM /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
289781SMoriah.Waterland@Sun.COM /* All Rights Reserved */
299781SMoriah.Waterland@Sun.COM 
309781SMoriah.Waterland@Sun.COM 
319781SMoriah.Waterland@Sun.COM /*
329781SMoriah.Waterland@Sun.COM  * System includes
339781SMoriah.Waterland@Sun.COM  */
349781SMoriah.Waterland@Sun.COM 
359781SMoriah.Waterland@Sun.COM #include <stdio.h>
369781SMoriah.Waterland@Sun.COM #include <stdlib.h>
379781SMoriah.Waterland@Sun.COM #include <unistd.h>
389781SMoriah.Waterland@Sun.COM #include <string.h>
399781SMoriah.Waterland@Sun.COM #include <signal.h>
409781SMoriah.Waterland@Sun.COM #include <errno.h>
419781SMoriah.Waterland@Sun.COM #include <locale.h>
429781SMoriah.Waterland@Sun.COM #include <libintl.h>
439781SMoriah.Waterland@Sun.COM #include <pkgstrct.h>
449781SMoriah.Waterland@Sun.COM #include <pkgdev.h>
459781SMoriah.Waterland@Sun.COM #include <pkginfo.h>
469781SMoriah.Waterland@Sun.COM #include <pkglocs.h>
479781SMoriah.Waterland@Sun.COM #include <pkglib.h>
489781SMoriah.Waterland@Sun.COM #include <assert.h>
499781SMoriah.Waterland@Sun.COM 
509781SMoriah.Waterland@Sun.COM /*
519781SMoriah.Waterland@Sun.COM  * libinstzones includes
529781SMoriah.Waterland@Sun.COM  */
539781SMoriah.Waterland@Sun.COM 
549781SMoriah.Waterland@Sun.COM #include <instzones_api.h>
559781SMoriah.Waterland@Sun.COM 
569781SMoriah.Waterland@Sun.COM /*
579781SMoriah.Waterland@Sun.COM  * consolidation pkg command library includes
589781SMoriah.Waterland@Sun.COM  */
599781SMoriah.Waterland@Sun.COM 
609781SMoriah.Waterland@Sun.COM #include <pkglib.h>
619781SMoriah.Waterland@Sun.COM 
629781SMoriah.Waterland@Sun.COM /*
639781SMoriah.Waterland@Sun.COM  * local pkg command library includes
649781SMoriah.Waterland@Sun.COM  */
659781SMoriah.Waterland@Sun.COM 
669781SMoriah.Waterland@Sun.COM #include "install.h"
679781SMoriah.Waterland@Sun.COM #include "libinst.h"
689781SMoriah.Waterland@Sun.COM #include "libadm.h"
699781SMoriah.Waterland@Sun.COM #include "messages.h"
709781SMoriah.Waterland@Sun.COM 
719781SMoriah.Waterland@Sun.COM /*
729781SMoriah.Waterland@Sun.COM  * pkgrm local includes
739781SMoriah.Waterland@Sun.COM  */
749781SMoriah.Waterland@Sun.COM 
759781SMoriah.Waterland@Sun.COM #include "quit.h"
769781SMoriah.Waterland@Sun.COM 
779781SMoriah.Waterland@Sun.COM /*
789781SMoriah.Waterland@Sun.COM  * exported global variables
799781SMoriah.Waterland@Sun.COM  */
809781SMoriah.Waterland@Sun.COM 
819781SMoriah.Waterland@Sun.COM /* these globals are set by ckreturn and used by quit.c */
829781SMoriah.Waterland@Sun.COM 
839781SMoriah.Waterland@Sun.COM int	admnflag = 0;	/* != 0 if any pkg op admin setting failure (4) */
849781SMoriah.Waterland@Sun.COM int	doreboot = 0;	/* != 0 if reboot required after installation */
859781SMoriah.Waterland@Sun.COM int	failflag = 0;	/* != 0 if fatal error has occurred (1) */
869781SMoriah.Waterland@Sun.COM int	intrflag = 0;	/* != 0 if user selected quit (3) */
879781SMoriah.Waterland@Sun.COM int	ireboot = 0;	/* != 0 if immediate reboot required */
889781SMoriah.Waterland@Sun.COM int	nullflag = 0;	/* != 0 if admin interaction required (5) */
899781SMoriah.Waterland@Sun.COM int	warnflag = 0;	/* != 0 if non-fatal error has occurred (2) */
909781SMoriah.Waterland@Sun.COM 
919781SMoriah.Waterland@Sun.COM /* imported by quit.c */
929781SMoriah.Waterland@Sun.COM int	npkgs = 0;	/* the number of packages yet to be installed */
939781SMoriah.Waterland@Sun.COM 
949781SMoriah.Waterland@Sun.COM /* imported by presvr4.c */
959781SMoriah.Waterland@Sun.COM int	started = 0;
969781SMoriah.Waterland@Sun.COM char	*tmpdir = NULL;	/* location to place temporary files */
979781SMoriah.Waterland@Sun.COM 
989781SMoriah.Waterland@Sun.COM /* imported by various (many) */
999781SMoriah.Waterland@Sun.COM struct admin	adm;	/* holds info about installation admin */
1009781SMoriah.Waterland@Sun.COM struct pkgdev	pkgdev;	/* holds info about the installation device */
1019781SMoriah.Waterland@Sun.COM 
1029781SMoriah.Waterland@Sun.COM /*
1039781SMoriah.Waterland@Sun.COM  * internal global variables
1049781SMoriah.Waterland@Sun.COM  */
1059781SMoriah.Waterland@Sun.COM 
1069781SMoriah.Waterland@Sun.COM static char	*admnfile = NULL;	/* file to use for installation admin */
1079781SMoriah.Waterland@Sun.COM static char	*pkginst = NULL;	/* current pkg/src instance 2 process */
1089781SMoriah.Waterland@Sun.COM static char	*vfstab_file = NULL;
1099781SMoriah.Waterland@Sun.COM static char	*zoneTempDir = (char *)NULL;
1109781SMoriah.Waterland@Sun.COM 
1119781SMoriah.Waterland@Sun.COM /* set by ckreturn() */
1129781SMoriah.Waterland@Sun.COM 
1139781SMoriah.Waterland@Sun.COM static int	interrupted = 0;	/* last pkg op was quit (1,2,3,4,5) */
1149781SMoriah.Waterland@Sun.COM 
1159781SMoriah.Waterland@Sun.COM static int	nointeract = 0;		/* non-zero - no user interaction */
1169781SMoriah.Waterland@Sun.COM static int	pkgrmremote = 0;	/* remove pkg objs stored remotely  */
1179781SMoriah.Waterland@Sun.COM static int	pkgverbose = 0;		/* non-zero if verbose mode selected */
1189781SMoriah.Waterland@Sun.COM 
1199781SMoriah.Waterland@Sun.COM /*
1209781SMoriah.Waterland@Sun.COM  * Assume the package complies with the standards as regards user
1219781SMoriah.Waterland@Sun.COM  * interaction during procedure scripts.
1229781SMoriah.Waterland@Sun.COM  */
1239781SMoriah.Waterland@Sun.COM 
1249781SMoriah.Waterland@Sun.COM static int	old_pkg = 0;
1259781SMoriah.Waterland@Sun.COM static int	old_symlinks = 0;
1269781SMoriah.Waterland@Sun.COM static int	no_map_client = 0;
1279781SMoriah.Waterland@Sun.COM 
1289781SMoriah.Waterland@Sun.COM /* Set by -O nozones: do not process any zones */
1299781SMoriah.Waterland@Sun.COM 
1309781SMoriah.Waterland@Sun.COM static boolean_t	noZones = B_FALSE;
1319781SMoriah.Waterland@Sun.COM 
1329781SMoriah.Waterland@Sun.COM /* Set by -O zonelist=<names...>: process only named zones */
1339781SMoriah.Waterland@Sun.COM 
1349781SMoriah.Waterland@Sun.COM static boolean_t	usedZoneList = B_FALSE;
1359781SMoriah.Waterland@Sun.COM 
1369781SMoriah.Waterland@Sun.COM /* Set by -O debug: debug output is enabled? */
1379781SMoriah.Waterland@Sun.COM 
1389781SMoriah.Waterland@Sun.COM static boolean_t	debugFlag = B_FALSE;
1399781SMoriah.Waterland@Sun.COM 
1409781SMoriah.Waterland@Sun.COM /*
1419781SMoriah.Waterland@Sun.COM  * imported (external) functions
1429781SMoriah.Waterland@Sun.COM  */
1439781SMoriah.Waterland@Sun.COM 
1449781SMoriah.Waterland@Sun.COM /* presvr4.c */
1459781SMoriah.Waterland@Sun.COM 
1469781SMoriah.Waterland@Sun.COM extern int	presvr4(char *pkg, int a_nointeract);
1479781SMoriah.Waterland@Sun.COM 
1489781SMoriah.Waterland@Sun.COM /* check.c */
1499781SMoriah.Waterland@Sun.COM 
1509781SMoriah.Waterland@Sun.COM extern int	preremove_verify(char **a_pkgList, zoneList_t a_zlst,
1519781SMoriah.Waterland@Sun.COM 			char *a_zoneTempDir);
1529781SMoriah.Waterland@Sun.COM /* quit.c */
1539781SMoriah.Waterland@Sun.COM 
1549781SMoriah.Waterland@Sun.COM extern void	quitSetZonelist(zoneList_t a_zlst);
1559781SMoriah.Waterland@Sun.COM 
1569781SMoriah.Waterland@Sun.COM /*
1579781SMoriah.Waterland@Sun.COM  * imported (external) variables
1589781SMoriah.Waterland@Sun.COM  */
1599781SMoriah.Waterland@Sun.COM 
1609781SMoriah.Waterland@Sun.COM extern char	*pkgdir;
1619781SMoriah.Waterland@Sun.COM 
1629781SMoriah.Waterland@Sun.COM /* printable string - if string is null results in ??? */
1639781SMoriah.Waterland@Sun.COM 
1649781SMoriah.Waterland@Sun.COM #define	PSTR(STR) (((STR) == (char *)NULL) ? "???" : (STR))
1659781SMoriah.Waterland@Sun.COM 
1669781SMoriah.Waterland@Sun.COM #define	MAX_FDS	20
1679781SMoriah.Waterland@Sun.COM 
1689781SMoriah.Waterland@Sun.COM #if !defined(TEXT_DOMAIN)	/* Should be defined by cc -D */
1699781SMoriah.Waterland@Sun.COM #define	TEXT_DOMAIN "SYS_TEST"
1709781SMoriah.Waterland@Sun.COM #endif
1719781SMoriah.Waterland@Sun.COM 
1729781SMoriah.Waterland@Sun.COM #define	INHERITFS	"inherited-filesystem="
1739781SMoriah.Waterland@Sun.COM #define	INHERITFS_LEN	((sizeof (INHERITFS))-1)
1749781SMoriah.Waterland@Sun.COM 
1759781SMoriah.Waterland@Sun.COM /*
1769781SMoriah.Waterland@Sun.COM  * forward declarations
1779781SMoriah.Waterland@Sun.COM  */
1789781SMoriah.Waterland@Sun.COM 
1799781SMoriah.Waterland@Sun.COM static void		ckreturn(int retcode);
1809781SMoriah.Waterland@Sun.COM static void		create_zone_adminfile(char **r_zoneAdminFile,
1819781SMoriah.Waterland@Sun.COM 				char *a_zoneTempDir, char *a_admnfile);
1829781SMoriah.Waterland@Sun.COM static void		create_zone_tempdir(char **r_zoneTempDir,
1839781SMoriah.Waterland@Sun.COM 				char *a_tmpdir);
1849781SMoriah.Waterland@Sun.COM static int		doRemove(int a_nodelete, char *a_altBinDir,
1859781SMoriah.Waterland@Sun.COM 				int a_longestPkg, char *a_adminFile,
1869781SMoriah.Waterland@Sun.COM 				char *a_zoneAdminFile, zoneList_t zlst);
1879781SMoriah.Waterland@Sun.COM static int		pkgRemove(int a_nodelete, char *a_altBinDir,
1889781SMoriah.Waterland@Sun.COM 				char *a_adminFile, char **a_inheritedPkgDirs);
1899781SMoriah.Waterland@Sun.COM static int		pkgZoneCheckRemove(char *a_zoneName,
1909781SMoriah.Waterland@Sun.COM 				char **a_inheritedPkgDirs, char *a_altBinDir,
1919781SMoriah.Waterland@Sun.COM 				char *a_adminFile, char *a_stdoutPath,
192*9869SCasper.Dik@Sun.COM 				zone_state_t a_zoneState, boolean_t tmpzone);
1939781SMoriah.Waterland@Sun.COM static int		pkgZoneRemove(char *a_zoneName,
1949781SMoriah.Waterland@Sun.COM 				char **a_inheritedPkgDirs, int a_nodelete,
1959781SMoriah.Waterland@Sun.COM 				char *a_altBinDir, char *a_adminFile,
196*9869SCasper.Dik@Sun.COM 				zone_state_t a_zoneState, boolean_t tmpzone);
1979781SMoriah.Waterland@Sun.COM static void		resetreturn();
1989781SMoriah.Waterland@Sun.COM static void		usage(void);
1999781SMoriah.Waterland@Sun.COM static boolean_t	check_applicability(char *a_packageDir,
2009781SMoriah.Waterland@Sun.COM 				char *a_pkgInst, char *a_rootPath,
2019781SMoriah.Waterland@Sun.COM 				CAF_T a_flags);
2029781SMoriah.Waterland@Sun.COM static boolean_t	check_packages(char **a_pkgList, char *a_packageDir);
2039781SMoriah.Waterland@Sun.COM static boolean_t	path_valid(char *path);
2049781SMoriah.Waterland@Sun.COM static boolean_t	remove_packages(char **a_pkgList, int a_nodelete,
2059781SMoriah.Waterland@Sun.COM 				int a_longestPkg, int a_repeat,
2069781SMoriah.Waterland@Sun.COM 				char *a_altBinDir, char *a_pkgdir,
2079781SMoriah.Waterland@Sun.COM 				char *a_spoolDir, boolean_t a_noZones);
2089781SMoriah.Waterland@Sun.COM static boolean_t	remove_packages_from_spool_directory(char **a_pkgList,
2099781SMoriah.Waterland@Sun.COM 				int a_nodelete, int a_longestPkg, int a_repeat,
2109781SMoriah.Waterland@Sun.COM 				char *a_altBinDir);
2119781SMoriah.Waterland@Sun.COM static boolean_t	remove_packages_in_global_no_zones(char **a_pkgList,
2129781SMoriah.Waterland@Sun.COM 				int a_nodelete, int a_longestPkg, int a_repeat,
2139781SMoriah.Waterland@Sun.COM 				char *a_altBinDir);
2149781SMoriah.Waterland@Sun.COM static boolean_t	remove_packages_in_global_with_zones(char **a_pkgList,
2159781SMoriah.Waterland@Sun.COM 				int a_nodelete, int a_longestPkg, int a_repeat,
2169781SMoriah.Waterland@Sun.COM 				char *a_altBinDir, char *a_pkgdir,
2179781SMoriah.Waterland@Sun.COM 				zoneList_t a_zlst);
2189781SMoriah.Waterland@Sun.COM static boolean_t	remove_packages_in_nonglobal_zone(char **a_pkgList,
2199781SMoriah.Waterland@Sun.COM 				int a_nodelete, int a_longestPkg, int a_repeat,
2209781SMoriah.Waterland@Sun.COM 				char *a_altBinDir, char *a_pkgdir);
2219781SMoriah.Waterland@Sun.COM static boolean_t	shall_we_continue(char *a_pkgInst, int a_npkgs);
2229781SMoriah.Waterland@Sun.COM 
2239781SMoriah.Waterland@Sun.COM /*
2249781SMoriah.Waterland@Sun.COM  * *****************************************************************************
2259781SMoriah.Waterland@Sun.COM  * global external (public) functions
2269781SMoriah.Waterland@Sun.COM  * *****************************************************************************
2279781SMoriah.Waterland@Sun.COM  */
2289781SMoriah.Waterland@Sun.COM 
2299781SMoriah.Waterland@Sun.COM /*
2309781SMoriah.Waterland@Sun.COM  * Name:	main
2319781SMoriah.Waterland@Sun.COM  * Description:	main entry point for pkgrm
2329781SMoriah.Waterland@Sun.COM  * Returns:	int
2339781SMoriah.Waterland@Sun.COM  *   0        Successful completion
2349781SMoriah.Waterland@Sun.COM  *   1        Fatal error.
2359781SMoriah.Waterland@Sun.COM  *   2        Warning.
2369781SMoriah.Waterland@Sun.COM  *   3        Interruption.
2379781SMoriah.Waterland@Sun.COM  *   4        Administration.
2389781SMoriah.Waterland@Sun.COM  *   5        Administration. Interaction is required. Do not use pkgrm -n.
2399781SMoriah.Waterland@Sun.COM  *  10       Reboot after removal of all packages.
2409781SMoriah.Waterland@Sun.COM  *  20       Reboot after removal of this package.
2419781SMoriah.Waterland@Sun.COM  */
2429781SMoriah.Waterland@Sun.COM 
2439781SMoriah.Waterland@Sun.COM int
2449781SMoriah.Waterland@Sun.COM main(int argc, char **argv)
2459781SMoriah.Waterland@Sun.COM {
2469781SMoriah.Waterland@Sun.COM 	char			**category = NULL;
2479781SMoriah.Waterland@Sun.COM 	char			*altBinDir = (char *)NULL;
2489781SMoriah.Waterland@Sun.COM 	char			*catg_arg = NULL;
2499781SMoriah.Waterland@Sun.COM 	char			*p;
2509781SMoriah.Waterland@Sun.COM 	char			*prog_full_name = NULL;
2519781SMoriah.Waterland@Sun.COM 	char			*spoolDir = 0;
2529781SMoriah.Waterland@Sun.COM 	int			c;
2539781SMoriah.Waterland@Sun.COM 	int			longestPkg = 0;
2549781SMoriah.Waterland@Sun.COM 	int			n;
2559781SMoriah.Waterland@Sun.COM 	int			nodelete = 0;	/* dont rm files/run scripts */
2569781SMoriah.Waterland@Sun.COM 	int			pkgLgth = 0;
2579781SMoriah.Waterland@Sun.COM 	int			repeat;
2589781SMoriah.Waterland@Sun.COM 	struct sigaction	nact;
2599781SMoriah.Waterland@Sun.COM 	struct sigaction	oact;
2609781SMoriah.Waterland@Sun.COM 
2619781SMoriah.Waterland@Sun.COM 	/* initialize locale environment */
2629781SMoriah.Waterland@Sun.COM 
2639781SMoriah.Waterland@Sun.COM 	(void) setlocale(LC_ALL, "");
2649781SMoriah.Waterland@Sun.COM 	(void) textdomain(TEXT_DOMAIN);
2659781SMoriah.Waterland@Sun.COM 
2669781SMoriah.Waterland@Sun.COM 	/* initialize program name */
2679781SMoriah.Waterland@Sun.COM 
2689781SMoriah.Waterland@Sun.COM 	prog_full_name = argv[0];
2699781SMoriah.Waterland@Sun.COM 	(void) set_prog_name(argv[0]);
2709781SMoriah.Waterland@Sun.COM 
2719781SMoriah.Waterland@Sun.COM 	/* tell spmi zones interface how to access package output functions */
2729781SMoriah.Waterland@Sun.COM 
2739781SMoriah.Waterland@Sun.COM 	z_set_output_functions(echo, echoDebug, progerr);
2749781SMoriah.Waterland@Sun.COM 
2759781SMoriah.Waterland@Sun.COM 	/* tell quit which ckreturn function to call */
2769781SMoriah.Waterland@Sun.COM 
2779781SMoriah.Waterland@Sun.COM 	quitSetCkreturnFunc(&ckreturn);
2789781SMoriah.Waterland@Sun.COM 
2799781SMoriah.Waterland@Sun.COM 	/* Read PKG_INSTALL_ROOT from the environment, if it's there. */
2809781SMoriah.Waterland@Sun.COM 
2819781SMoriah.Waterland@Sun.COM 	if (!set_inst_root(getenv("PKG_INSTALL_ROOT"))) {
2829781SMoriah.Waterland@Sun.COM 		progerr(ERR_ROOT_SET);
2839781SMoriah.Waterland@Sun.COM 		exit(1);
2849781SMoriah.Waterland@Sun.COM 	}
2859781SMoriah.Waterland@Sun.COM 
2869781SMoriah.Waterland@Sun.COM 	if (z_running_in_global_zone() && !enable_local_fs()) {
2879781SMoriah.Waterland@Sun.COM 		progerr(ERR_CANNOT_ENABLE_LOCAL_FS);
2889781SMoriah.Waterland@Sun.COM 	}
2899781SMoriah.Waterland@Sun.COM 
290*9869SCasper.Dik@Sun.COM 	pkgserversetmode(DEFAULTMODE);
291*9869SCasper.Dik@Sun.COM 
2929781SMoriah.Waterland@Sun.COM 	/*
2939781SMoriah.Waterland@Sun.COM 	 * ********************************************************************
2949781SMoriah.Waterland@Sun.COM 	 * parse command line options
2959781SMoriah.Waterland@Sun.COM 	 * ********************************************************************
2969781SMoriah.Waterland@Sun.COM 	 */
2979781SMoriah.Waterland@Sun.COM 
2989781SMoriah.Waterland@Sun.COM 	while ((c = getopt(argc, argv, "?Aa:b:FMnO:R:s:V:vY:Z")) != EOF) {
2999781SMoriah.Waterland@Sun.COM 		switch (c) {
3009781SMoriah.Waterland@Sun.COM 		/*
3019781SMoriah.Waterland@Sun.COM 		 * Public interface: Allow admin to remove objects
3029781SMoriah.Waterland@Sun.COM 		 * from a service area via a reference client.
3039781SMoriah.Waterland@Sun.COM 		 * Remove the package files from the client's file
3049781SMoriah.Waterland@Sun.COM 		 * system, absolutely. If a file is shared with other
3059781SMoriah.Waterland@Sun.COM 		 * packages, the default behavior is to not remove
3069781SMoriah.Waterland@Sun.COM 		 * the file from the client's file system.
3079781SMoriah.Waterland@Sun.COM 		 */
3089781SMoriah.Waterland@Sun.COM 		case 'A':
3099781SMoriah.Waterland@Sun.COM 		    pkgrmremote++;
3109781SMoriah.Waterland@Sun.COM 		    break;
3119781SMoriah.Waterland@Sun.COM 
3129781SMoriah.Waterland@Sun.COM 		/*
3139781SMoriah.Waterland@Sun.COM 		 * Public interface: Use the installation
3149781SMoriah.Waterland@Sun.COM 		 * administration file, admin, in place of the
3159781SMoriah.Waterland@Sun.COM 		 * default admin file. pkgrm first looks in the
3169781SMoriah.Waterland@Sun.COM 		 * current working directory for the administration
3179781SMoriah.Waterland@Sun.COM 		 * file.  If the specified administration file is not
3189781SMoriah.Waterland@Sun.COM 		 * in the current working directory, pkgrm looks in
3199781SMoriah.Waterland@Sun.COM 		 * the /var/sadm/install/admin directory for the
3209781SMoriah.Waterland@Sun.COM 		 * administra- tion file.
3219781SMoriah.Waterland@Sun.COM 		 */
3229781SMoriah.Waterland@Sun.COM 		case 'a':
3239781SMoriah.Waterland@Sun.COM 		    admnfile = flex_device(optarg, 0);
3249781SMoriah.Waterland@Sun.COM 		    break;
3259781SMoriah.Waterland@Sun.COM 
3269781SMoriah.Waterland@Sun.COM 		/*
3279781SMoriah.Waterland@Sun.COM 		 * Not a public interface:  location where package executables
3289781SMoriah.Waterland@Sun.COM 		 * can be found - default is /usr/sadm/install/bin.
3299781SMoriah.Waterland@Sun.COM 		 */
3309781SMoriah.Waterland@Sun.COM 		case 'b':
3319781SMoriah.Waterland@Sun.COM 			if (!path_valid(optarg)) {
3329781SMoriah.Waterland@Sun.COM 				progerr(ERR_PATH, optarg);
3339781SMoriah.Waterland@Sun.COM 				quit(1);
3349781SMoriah.Waterland@Sun.COM 			}
3359781SMoriah.Waterland@Sun.COM 			if (isdir(optarg) != 0) {
3369781SMoriah.Waterland@Sun.COM 				p = strerror(errno);
3379781SMoriah.Waterland@Sun.COM 				progerr(ERR_CANNOT_USE_DIR, optarg, p);
3389781SMoriah.Waterland@Sun.COM 				quit(1);
3399781SMoriah.Waterland@Sun.COM 			}
3409781SMoriah.Waterland@Sun.COM 			altBinDir = optarg;
3419781SMoriah.Waterland@Sun.COM 			break;
3429781SMoriah.Waterland@Sun.COM 
3439781SMoriah.Waterland@Sun.COM 		/*
3449781SMoriah.Waterland@Sun.COM 		 * Not a public interface: pass -F option to
3459781SMoriah.Waterland@Sun.COM 		 * pkgremove which suppresses the removal of any
3469781SMoriah.Waterland@Sun.COM 		 * files and any class action scripts, and suppresses
3479781SMoriah.Waterland@Sun.COM 		 * the running of any class action scripts.  The
3489781SMoriah.Waterland@Sun.COM 		 * package files remain but the package looks like it
3499781SMoriah.Waterland@Sun.COM 		 * is not installed. This is mainly for use by the
3509781SMoriah.Waterland@Sun.COM 		 * upgrade process.
3519781SMoriah.Waterland@Sun.COM 		 */
3529781SMoriah.Waterland@Sun.COM 		case 'F':
3539781SMoriah.Waterland@Sun.COM 		    nodelete++;
3549781SMoriah.Waterland@Sun.COM 		    break;
3559781SMoriah.Waterland@Sun.COM 
3569781SMoriah.Waterland@Sun.COM 		/*
3579781SMoriah.Waterland@Sun.COM 		 * Public interface: Instruct pkgrm not to use the
3589781SMoriah.Waterland@Sun.COM 		 * $root_path/etc/vfstab file for determining the
3599781SMoriah.Waterland@Sun.COM 		 * client's mount points. This option assumes the
3609781SMoriah.Waterland@Sun.COM 		 * mount points are correct on the server and it
3619781SMoriah.Waterland@Sun.COM 		 * behaves consistently with Solaris 2.5 and earlier
3629781SMoriah.Waterland@Sun.COM 		 * releases.
3639781SMoriah.Waterland@Sun.COM 		 */
3649781SMoriah.Waterland@Sun.COM 		case 'M':
3659781SMoriah.Waterland@Sun.COM 		    no_map_client = 1;
3669781SMoriah.Waterland@Sun.COM 		    break;
3679781SMoriah.Waterland@Sun.COM 
3689781SMoriah.Waterland@Sun.COM 		/*
3699781SMoriah.Waterland@Sun.COM 		 * Public interface: package removal occurs in
3709781SMoriah.Waterland@Sun.COM 		 * non-interactive mode.  Suppress output of the list of
3719781SMoriah.Waterland@Sun.COM 		 * removed files. The default mode is interactive.
3729781SMoriah.Waterland@Sun.COM 		 */
3739781SMoriah.Waterland@Sun.COM 		case 'n':
3749781SMoriah.Waterland@Sun.COM 		    nointeract++;
3759781SMoriah.Waterland@Sun.COM 		    (void) echoSetFlag(B_FALSE);
3769781SMoriah.Waterland@Sun.COM 		    break;
3779781SMoriah.Waterland@Sun.COM 
3789781SMoriah.Waterland@Sun.COM 		/*
3799781SMoriah.Waterland@Sun.COM 		 * Not a public interface: the -O option allows the behavior
3809781SMoriah.Waterland@Sun.COM 		 * of the package tools to be modified. Recognized options:
3819781SMoriah.Waterland@Sun.COM 		 * -> debug
3829781SMoriah.Waterland@Sun.COM 		 * ---> enable debugging output
3839781SMoriah.Waterland@Sun.COM 		 * -> nozones
3849781SMoriah.Waterland@Sun.COM 		 * ---> act as though in global zone with no non-global zones
3859781SMoriah.Waterland@Sun.COM 		 * -> inherited-filesystems
3869781SMoriah.Waterland@Sun.COM 		 * ---> add specified file system to list of file systems
3879781SMoriah.Waterland@Sun.COM 		 * ---> that are inherited from the global zone
3889781SMoriah.Waterland@Sun.COM 		 * -> enable-hollow-package-support
3899781SMoriah.Waterland@Sun.COM 		 * --> Enable hollow package support. When specified, for any
3909781SMoriah.Waterland@Sun.COM 		 * --> package that has SUNW_PKG_HOLLOW=true:
3919781SMoriah.Waterland@Sun.COM 		 * --> Do not calculate and verify package size against target
3929781SMoriah.Waterland@Sun.COM 		 * --> Do not run any package procedure or class action scripts
3939781SMoriah.Waterland@Sun.COM 		 * --> Do not create or remove any target directories
3949781SMoriah.Waterland@Sun.COM 		 * --> Do not perform any script locking
3959781SMoriah.Waterland@Sun.COM 		 * --> Do not install or uninstall any components of any package
3969781SMoriah.Waterland@Sun.COM 		 * --> Do not output any status or database update messages
3979781SMoriah.Waterland@Sun.COM 		 * -> zonelist="<names...>"
3989781SMoriah.Waterland@Sun.COM 		 * ---> add package to space-separated list of zones only
3999781SMoriah.Waterland@Sun.COM 		 */
4009781SMoriah.Waterland@Sun.COM 
4019781SMoriah.Waterland@Sun.COM 		case 'O':
4029781SMoriah.Waterland@Sun.COM 			for (p = strtok(optarg, ","); p != (char *)NULL;
4039781SMoriah.Waterland@Sun.COM 				p = strtok(NULL, ",")) {
4049781SMoriah.Waterland@Sun.COM 
4059781SMoriah.Waterland@Sun.COM 				if (strcmp(p, "nozones") == 0) {
4069781SMoriah.Waterland@Sun.COM 					noZones = B_TRUE;
4079781SMoriah.Waterland@Sun.COM 					continue;
4089781SMoriah.Waterland@Sun.COM 				}
4099781SMoriah.Waterland@Sun.COM 
4109781SMoriah.Waterland@Sun.COM 				if (strncmp(p, INHERITFS, INHERITFS_LEN) == 0) {
4119781SMoriah.Waterland@Sun.COM 					if (z_add_inherited_file_system(
4129781SMoriah.Waterland@Sun.COM 						p+INHERITFS_LEN) == B_FALSE) {
4139781SMoriah.Waterland@Sun.COM 						progerr(ERR_NOSUCH_INHERITED,
4149781SMoriah.Waterland@Sun.COM 							p+INHERITFS_LEN);
4159781SMoriah.Waterland@Sun.COM 						quit(1);
4169781SMoriah.Waterland@Sun.COM 						/* NOTREACHED */
4179781SMoriah.Waterland@Sun.COM 					}
4189781SMoriah.Waterland@Sun.COM 					continue;
4199781SMoriah.Waterland@Sun.COM 				}
4209781SMoriah.Waterland@Sun.COM 
4219781SMoriah.Waterland@Sun.COM 				if (strcmp(p,
4229781SMoriah.Waterland@Sun.COM 					"enable-hollow-package-support") == 0) {
4239781SMoriah.Waterland@Sun.COM 					set_depend_pkginfo_DB(B_TRUE);
4249781SMoriah.Waterland@Sun.COM 					continue;
4259781SMoriah.Waterland@Sun.COM 				}
4269781SMoriah.Waterland@Sun.COM 
4279781SMoriah.Waterland@Sun.COM 				if (strcmp(p, "debug") == 0) {
4289781SMoriah.Waterland@Sun.COM 					/* set debug flag/enable debug output */
4299781SMoriah.Waterland@Sun.COM 					debugFlag = B_TRUE;
4309781SMoriah.Waterland@Sun.COM 					(void) echoDebugSetFlag(debugFlag);
4319781SMoriah.Waterland@Sun.COM 
4329781SMoriah.Waterland@Sun.COM 					/* debug info on arguments to pkgadd */
4339781SMoriah.Waterland@Sun.COM 					for (n = 0; n < argc && argv[n]; n++) {
4349781SMoriah.Waterland@Sun.COM 						echoDebug(DBG_ARG, n, argv[n]);
4359781SMoriah.Waterland@Sun.COM 					}
4369781SMoriah.Waterland@Sun.COM 
4379781SMoriah.Waterland@Sun.COM 					continue;
4389781SMoriah.Waterland@Sun.COM 				}
4399781SMoriah.Waterland@Sun.COM 
4409781SMoriah.Waterland@Sun.COM 				if (strncmp(p, "zonelist=", 9) == 0) {
4419781SMoriah.Waterland@Sun.COM 					if (z_set_zone_spec(p + 9) == -1)
4429781SMoriah.Waterland@Sun.COM 						quit(1);
4439781SMoriah.Waterland@Sun.COM 					usedZoneList = B_TRUE;
4449781SMoriah.Waterland@Sun.COM 					continue;
4459781SMoriah.Waterland@Sun.COM 				}
4469781SMoriah.Waterland@Sun.COM 
4479781SMoriah.Waterland@Sun.COM 				/* -O option not recognized - issue warning */
4489781SMoriah.Waterland@Sun.COM 
4499781SMoriah.Waterland@Sun.COM 				progerr(ERR_INVALID_O_OPTION, p);
4509781SMoriah.Waterland@Sun.COM 				continue;
4519781SMoriah.Waterland@Sun.COM 			}
4529781SMoriah.Waterland@Sun.COM 			break;
4539781SMoriah.Waterland@Sun.COM 
4549781SMoriah.Waterland@Sun.COM 		/*
4559781SMoriah.Waterland@Sun.COM 		 * Public interface: defines the full path name of a
4569781SMoriah.Waterland@Sun.COM 		 * directory to use as the root_path.  All files,
4579781SMoriah.Waterland@Sun.COM 		 * including package system information files, are
4589781SMoriah.Waterland@Sun.COM 		 * relocated to a directory tree starting in the
4599781SMoriah.Waterland@Sun.COM 		 * specified root_path.
4609781SMoriah.Waterland@Sun.COM 		 */
4619781SMoriah.Waterland@Sun.COM 		case 'R':
4629781SMoriah.Waterland@Sun.COM 		    if (!set_inst_root(optarg)) {
4639781SMoriah.Waterland@Sun.COM 			    progerr(ERR_ROOT_CMD);
4649781SMoriah.Waterland@Sun.COM 			    exit(1);
4659781SMoriah.Waterland@Sun.COM 		    }
4669781SMoriah.Waterland@Sun.COM 		    break;
4679781SMoriah.Waterland@Sun.COM 
4689781SMoriah.Waterland@Sun.COM 		/*
4699781SMoriah.Waterland@Sun.COM 		 * Public interface: remove the specified package(s)
4709781SMoriah.Waterland@Sun.COM 		 * from the directory spool.  The default directory
4719781SMoriah.Waterland@Sun.COM 		 * for spooled packages is /var/sadm/pkg.
4729781SMoriah.Waterland@Sun.COM 		 */
4739781SMoriah.Waterland@Sun.COM 		case 's':
4749781SMoriah.Waterland@Sun.COM 		    spoolDir = flex_device(optarg, 1);
4759781SMoriah.Waterland@Sun.COM 		    break;
4769781SMoriah.Waterland@Sun.COM 
4779781SMoriah.Waterland@Sun.COM 		/*
4789781SMoriah.Waterland@Sun.COM 		 * Public interface: Allow admin to establish the client
4799781SMoriah.Waterland@Sun.COM 		 * filesystem using a vfstab-like file of stable format.
4809781SMoriah.Waterland@Sun.COM 		 */
4819781SMoriah.Waterland@Sun.COM 		case 'V':
4829781SMoriah.Waterland@Sun.COM 		    vfstab_file = flex_device(optarg, 2);
4839781SMoriah.Waterland@Sun.COM 		    no_map_client = 0;
4849781SMoriah.Waterland@Sun.COM 		    break;
4859781SMoriah.Waterland@Sun.COM 
4869781SMoriah.Waterland@Sun.COM 		/*
4879781SMoriah.Waterland@Sun.COM 		 * Public interface: trace all of the scripts that
4889781SMoriah.Waterland@Sun.COM 		 * get executed by pkgrm, located in the
4899781SMoriah.Waterland@Sun.COM 		 * pkginst/install directory. This option is used for
4909781SMoriah.Waterland@Sun.COM 		 * debugging the procedural and non- procedural
4919781SMoriah.Waterland@Sun.COM 		 * scripts.
4929781SMoriah.Waterland@Sun.COM 		 */
4939781SMoriah.Waterland@Sun.COM 		case 'v':
4949781SMoriah.Waterland@Sun.COM 		    pkgverbose++;
4959781SMoriah.Waterland@Sun.COM 		    break;
4969781SMoriah.Waterland@Sun.COM 
4979781SMoriah.Waterland@Sun.COM 		/*
4989781SMoriah.Waterland@Sun.COM 		 * Public interface: remove packages based on the
4999781SMoriah.Waterland@Sun.COM 		 * CATEGORY variable from the installed/spooled
5009781SMoriah.Waterland@Sun.COM 		 * pkginfo file
5019781SMoriah.Waterland@Sun.COM 		 */
5029781SMoriah.Waterland@Sun.COM 		case 'Y':
5039781SMoriah.Waterland@Sun.COM 		    catg_arg = strdup(optarg);
5049781SMoriah.Waterland@Sun.COM 
5059781SMoriah.Waterland@Sun.COM 		    if ((category = get_categories(catg_arg)) == NULL) {
5069781SMoriah.Waterland@Sun.COM 			    progerr(ERR_CAT_INV, catg_arg);
5079781SMoriah.Waterland@Sun.COM 			    exit(1);
5089781SMoriah.Waterland@Sun.COM 		    } else if (is_not_valid_category(category,
5099781SMoriah.Waterland@Sun.COM 				    get_prog_name())) {
5109781SMoriah.Waterland@Sun.COM 			    progerr(ERR_CAT_SYS);
5119781SMoriah.Waterland@Sun.COM 			    exit(1);
5129781SMoriah.Waterland@Sun.COM 		    } else if (is_not_valid_length(category)) {
5139781SMoriah.Waterland@Sun.COM 			    progerr(ERR_CAT_LNGTH);
5149781SMoriah.Waterland@Sun.COM 			    exit(1);
5159781SMoriah.Waterland@Sun.COM 		    }
5169781SMoriah.Waterland@Sun.COM 
5179781SMoriah.Waterland@Sun.COM 		    break;
5189781SMoriah.Waterland@Sun.COM 
5199781SMoriah.Waterland@Sun.COM 		/*
5209781SMoriah.Waterland@Sun.COM 		 * unrecognized option
5219781SMoriah.Waterland@Sun.COM 		 */
5229781SMoriah.Waterland@Sun.COM 		default:
5239781SMoriah.Waterland@Sun.COM 		    usage();
5249781SMoriah.Waterland@Sun.COM 		    /* NOTREACHED */
5259781SMoriah.Waterland@Sun.COM 		}
5269781SMoriah.Waterland@Sun.COM 	}
5279781SMoriah.Waterland@Sun.COM 
5289781SMoriah.Waterland@Sun.COM 	/*
5299781SMoriah.Waterland@Sun.COM 	 * ********************************************************************
5309781SMoriah.Waterland@Sun.COM 	 * validate command line options
5319781SMoriah.Waterland@Sun.COM 	 * ********************************************************************
5329781SMoriah.Waterland@Sun.COM 	 */
5339781SMoriah.Waterland@Sun.COM 
5349781SMoriah.Waterland@Sun.COM 	/* set "debug echo" flag according to setting of "-O debug" option */
5359781SMoriah.Waterland@Sun.COM 
5369781SMoriah.Waterland@Sun.COM 	(void) echoDebugSetFlag(debugFlag);
5379781SMoriah.Waterland@Sun.COM 
5389781SMoriah.Waterland@Sun.COM 	/* output entry debugging information */
5399781SMoriah.Waterland@Sun.COM 
5409781SMoriah.Waterland@Sun.COM 	if (z_running_in_global_zone()) {
5419781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_ENTRY_IN_GZ, prog_full_name);
5429781SMoriah.Waterland@Sun.COM 	} else {
5439781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_ENTRY_IN_LZ, prog_full_name, getzoneid(),
5449781SMoriah.Waterland@Sun.COM 			z_get_zonename());
5459781SMoriah.Waterland@Sun.COM 	}
5469781SMoriah.Waterland@Sun.COM 
5479781SMoriah.Waterland@Sun.COM 	/* -s cannot be used with several */
5489781SMoriah.Waterland@Sun.COM 
5499781SMoriah.Waterland@Sun.COM 	if (spoolDir != (char *)NULL) {
5509781SMoriah.Waterland@Sun.COM 		if (admnfile != (char *)NULL) {
5519781SMoriah.Waterland@Sun.COM 			progerr(ERR_SPOOLDIR_AND_ADMNFILE);
5529781SMoriah.Waterland@Sun.COM 			usage();
5539781SMoriah.Waterland@Sun.COM 			/* NOTREACHED */
5549781SMoriah.Waterland@Sun.COM 		}
5559781SMoriah.Waterland@Sun.COM 
5569781SMoriah.Waterland@Sun.COM 		if (pkgrmremote != 0) {
5579781SMoriah.Waterland@Sun.COM 			progerr(ERR_SPOOLDIR_AND_PKGRMREMOTE);
5589781SMoriah.Waterland@Sun.COM 			usage();
5599781SMoriah.Waterland@Sun.COM 			/* NOTREACHED */
5609781SMoriah.Waterland@Sun.COM 		}
5619781SMoriah.Waterland@Sun.COM 
5629781SMoriah.Waterland@Sun.COM 		if (pkgverbose != 0) {
5639781SMoriah.Waterland@Sun.COM 			progerr(ERR_SPOOLDIR_AND_PKGVERBOSE);
5649781SMoriah.Waterland@Sun.COM 			usage();
5659781SMoriah.Waterland@Sun.COM 			/* NOTREACHED */
5669781SMoriah.Waterland@Sun.COM 		}
5679781SMoriah.Waterland@Sun.COM 
5689781SMoriah.Waterland@Sun.COM 		if (is_an_inst_root() != 0) {
5699781SMoriah.Waterland@Sun.COM 			progerr(ERR_SPOOLDIR_AND_INST_ROOT);
5709781SMoriah.Waterland@Sun.COM 			usage();
5719781SMoriah.Waterland@Sun.COM 			/* NOTREACHED */
5729781SMoriah.Waterland@Sun.COM 		}
5739781SMoriah.Waterland@Sun.COM 	}
5749781SMoriah.Waterland@Sun.COM 
5759781SMoriah.Waterland@Sun.COM 	/* -V cannot be used with -A */
5769781SMoriah.Waterland@Sun.COM 
5779781SMoriah.Waterland@Sun.COM 	if (no_map_client && pkgrmremote) {
5789781SMoriah.Waterland@Sun.COM 		progerr(ERR_V_USED_AND_PKGRMREMOTE);
5799781SMoriah.Waterland@Sun.COM 		usage();
5809781SMoriah.Waterland@Sun.COM 		/* NOTREACHED */
5819781SMoriah.Waterland@Sun.COM 	}
5829781SMoriah.Waterland@Sun.COM 
5839781SMoriah.Waterland@Sun.COM 	/* -n used without pkg names or category */
5849781SMoriah.Waterland@Sun.COM 
5859781SMoriah.Waterland@Sun.COM 	if (nointeract && (optind == argc) && (catg_arg == NULL)) {
5869781SMoriah.Waterland@Sun.COM 		progerr(ERR_BAD_N_PKGRM);
5879781SMoriah.Waterland@Sun.COM 		usage();
5889781SMoriah.Waterland@Sun.COM 		/* NOTREACHED */
5899781SMoriah.Waterland@Sun.COM 	}
5909781SMoriah.Waterland@Sun.COM 
5919781SMoriah.Waterland@Sun.COM 	/* Error if specified zone list isn't valid on target */
5929781SMoriah.Waterland@Sun.COM 	if (usedZoneList && z_verify_zone_spec() == -1)
5939781SMoriah.Waterland@Sun.COM 		usage();
5949781SMoriah.Waterland@Sun.COM 
5959781SMoriah.Waterland@Sun.COM 	/*
5969781SMoriah.Waterland@Sun.COM 	 * hook SIGINT and SIGHUP interrupts into quit.c's trap handler
5979781SMoriah.Waterland@Sun.COM 	 */
5989781SMoriah.Waterland@Sun.COM 
5999781SMoriah.Waterland@Sun.COM 	/* hold SIGINT/SIGHUP interrupts */
6009781SMoriah.Waterland@Sun.COM 
6019781SMoriah.Waterland@Sun.COM 	(void) sighold(SIGHUP);
6029781SMoriah.Waterland@Sun.COM 	(void) sighold(SIGINT);
6039781SMoriah.Waterland@Sun.COM 
6049781SMoriah.Waterland@Sun.COM 	/* connect quit.c:trap() to SIGINT */
6059781SMoriah.Waterland@Sun.COM 
6069781SMoriah.Waterland@Sun.COM 	nact.sa_handler = quitGetTrapHandler();
6079781SMoriah.Waterland@Sun.COM 	nact.sa_flags = SA_RESTART;
6089781SMoriah.Waterland@Sun.COM 	(void) sigemptyset(&nact.sa_mask);
6099781SMoriah.Waterland@Sun.COM 
6109781SMoriah.Waterland@Sun.COM 	(void) sigaction(SIGINT, &nact, &oact);
6119781SMoriah.Waterland@Sun.COM 
6129781SMoriah.Waterland@Sun.COM 	/* connect quit.c:trap() to SIGHUP */
6139781SMoriah.Waterland@Sun.COM 
6149781SMoriah.Waterland@Sun.COM 	nact.sa_handler = quitGetTrapHandler();
6159781SMoriah.Waterland@Sun.COM 	nact.sa_flags = SA_RESTART;
6169781SMoriah.Waterland@Sun.COM 	(void) sigemptyset(&nact.sa_mask);
6179781SMoriah.Waterland@Sun.COM 
6189781SMoriah.Waterland@Sun.COM 	(void) sigaction(SIGHUP, &nact, &oact);
6199781SMoriah.Waterland@Sun.COM 
6209781SMoriah.Waterland@Sun.COM 	/* release hold on signals */
6219781SMoriah.Waterland@Sun.COM 
6229781SMoriah.Waterland@Sun.COM 	(void) sigrelse(SIGHUP);
6239781SMoriah.Waterland@Sun.COM 	(void) sigrelse(SIGINT);
6249781SMoriah.Waterland@Sun.COM 
6259781SMoriah.Waterland@Sun.COM 	/* establish temporary directory to use */
6269781SMoriah.Waterland@Sun.COM 
6279781SMoriah.Waterland@Sun.COM 	tmpdir = getenv("TMPDIR");
6289781SMoriah.Waterland@Sun.COM 	if (tmpdir == NULL) {
6299781SMoriah.Waterland@Sun.COM 		tmpdir = P_tmpdir;
6309781SMoriah.Waterland@Sun.COM 	}
6319781SMoriah.Waterland@Sun.COM 
6329781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_PKGRM_TMPDIR, tmpdir);
6339781SMoriah.Waterland@Sun.COM 
6349781SMoriah.Waterland@Sun.COM 	/* initialize path parameters */
6359781SMoriah.Waterland@Sun.COM 
6369781SMoriah.Waterland@Sun.COM 	set_PKGpaths(get_inst_root());
6379781SMoriah.Waterland@Sun.COM 
6389781SMoriah.Waterland@Sun.COM 	/*
6399781SMoriah.Waterland@Sun.COM 	 * initialize installation admin parameters - if removing from a spool
6409781SMoriah.Waterland@Sun.COM 	 * directory then the admin file is ignore.
6419781SMoriah.Waterland@Sun.COM 	 */
6429781SMoriah.Waterland@Sun.COM 
6439781SMoriah.Waterland@Sun.COM 	if (spoolDir == NULL) {
6449781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_PKGRM_ADMINFILE, admnfile ? admnfile : "");
6459781SMoriah.Waterland@Sun.COM 		setadminFile(admnfile);
6469781SMoriah.Waterland@Sun.COM 	}
6479781SMoriah.Waterland@Sun.COM 
6489781SMoriah.Waterland@Sun.COM 	/*
6499781SMoriah.Waterland@Sun.COM 	 * if running in the global zone, and non-global zones exist, then
6509781SMoriah.Waterland@Sun.COM 	 * enable hollow package support so that any packages that are marked
6519781SMoriah.Waterland@Sun.COM 	 * SUNW_PKG_HOLLOW=true will be correctly removed in non-global zones
6529781SMoriah.Waterland@Sun.COM 	 * when removed directly in the global zone by the global zone admin.
6539781SMoriah.Waterland@Sun.COM 	 */
6549781SMoriah.Waterland@Sun.COM 
6559781SMoriah.Waterland@Sun.COM 	if (is_depend_pkginfo_DB()) {
6569781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_PKGRM_HOLLOW_ENABLED);
6579781SMoriah.Waterland@Sun.COM 	} else if ((z_running_in_global_zone() == B_TRUE) &&
6589781SMoriah.Waterland@Sun.COM 		(z_non_global_zones_exist() == B_TRUE)) {
6599781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_PKGRM_ENABLING_HOLLOW);
6609781SMoriah.Waterland@Sun.COM 		set_depend_pkginfo_DB(B_TRUE);
6619781SMoriah.Waterland@Sun.COM 	}
6629781SMoriah.Waterland@Sun.COM 
6639781SMoriah.Waterland@Sun.COM 	/*
6649781SMoriah.Waterland@Sun.COM 	 * See if user wants this to be handled as an old style pkg.
6659781SMoriah.Waterland@Sun.COM 	 * NOTE : the ``exception_pkg()'' stuff is to be used only
6669781SMoriah.Waterland@Sun.COM 	 * through on495. This function comes out for on1095. See
6679781SMoriah.Waterland@Sun.COM 	 * PSARC 1993-546. -- JST
6689781SMoriah.Waterland@Sun.COM 	 */
6699781SMoriah.Waterland@Sun.COM 	if (getenv("NONABI_SCRIPTS") != NULL) {
6709781SMoriah.Waterland@Sun.COM 		old_pkg = 1;
6719781SMoriah.Waterland@Sun.COM 	}
6729781SMoriah.Waterland@Sun.COM 
6739781SMoriah.Waterland@Sun.COM 	/*
6749781SMoriah.Waterland@Sun.COM 	 * See if the user wants to process symlinks consistent with
6759781SMoriah.Waterland@Sun.COM 	 * the old behavior.
6769781SMoriah.Waterland@Sun.COM 	 */
6779781SMoriah.Waterland@Sun.COM 
6789781SMoriah.Waterland@Sun.COM 	if (getenv("PKG_NONABI_SYMLINKS") != NULL) {
6799781SMoriah.Waterland@Sun.COM 		old_symlinks = 1;
6809781SMoriah.Waterland@Sun.COM 	}
6819781SMoriah.Waterland@Sun.COM 
6829781SMoriah.Waterland@Sun.COM 	if (devtype((spoolDir ? spoolDir : get_PKGLOC()), &pkgdev) ||
6839781SMoriah.Waterland@Sun.COM 	    pkgdev.dirname == NULL) {
6849781SMoriah.Waterland@Sun.COM 		progerr(ERR_BAD_DEVICE, spoolDir ? spoolDir : get_PKGLOC());
6859781SMoriah.Waterland@Sun.COM 		quit(1);
6869781SMoriah.Waterland@Sun.COM 		/* NOTREACHED */
6879781SMoriah.Waterland@Sun.COM 	}
6889781SMoriah.Waterland@Sun.COM 
6899781SMoriah.Waterland@Sun.COM 	pkgdir = pkgdev.dirname;
6909781SMoriah.Waterland@Sun.COM 	repeat = ((optind >= argc) && pkgdev.mount);
6919781SMoriah.Waterland@Sun.COM 
6929781SMoriah.Waterland@Sun.COM 	/*
6939781SMoriah.Waterland@Sun.COM 	 * error if there are packages on the command line and a category
6949781SMoriah.Waterland@Sun.COM 	 * was specified
6959781SMoriah.Waterland@Sun.COM 	 */
6969781SMoriah.Waterland@Sun.COM 
6979781SMoriah.Waterland@Sun.COM 	if (optind < argc && catg_arg != NULL) {
6989781SMoriah.Waterland@Sun.COM 		progerr(ERR_PKGS_AND_CAT_PKGRM);
6999781SMoriah.Waterland@Sun.COM 		usage();
7009781SMoriah.Waterland@Sun.COM 		/* NOTREACHED */
7019781SMoriah.Waterland@Sun.COM 	}
7029781SMoriah.Waterland@Sun.COM 
7039781SMoriah.Waterland@Sun.COM 	/*
7049781SMoriah.Waterland@Sun.COM 	 * ********************************************************************
7059781SMoriah.Waterland@Sun.COM 	 * main package processing "loop"
7069781SMoriah.Waterland@Sun.COM 	 * ********************************************************************
7079781SMoriah.Waterland@Sun.COM 	 */
7089781SMoriah.Waterland@Sun.COM 
7099781SMoriah.Waterland@Sun.COM 	for (;;) {
7109781SMoriah.Waterland@Sun.COM 		boolean_t	b;
7119781SMoriah.Waterland@Sun.COM 		char		**pkglist;	/* points to array of pkgs */
7129781SMoriah.Waterland@Sun.COM 
7139781SMoriah.Waterland@Sun.COM 		/*
7149781SMoriah.Waterland@Sun.COM 		 * mount the spool device if required
7159781SMoriah.Waterland@Sun.COM 		 */
7169781SMoriah.Waterland@Sun.COM 
7179781SMoriah.Waterland@Sun.COM 		if (pkgdev.mount) {
7189781SMoriah.Waterland@Sun.COM 			if (n = pkgmount(&pkgdev, NULL, 0, 0, 1)) {
7199781SMoriah.Waterland@Sun.COM 				quit(n);
7209781SMoriah.Waterland@Sun.COM 				/* NOTREACHED */
7219781SMoriah.Waterland@Sun.COM 			}
7229781SMoriah.Waterland@Sun.COM 		}
7239781SMoriah.Waterland@Sun.COM 
7249781SMoriah.Waterland@Sun.COM 		if (chdir(pkgdev.dirname)) {
7259781SMoriah.Waterland@Sun.COM 			progerr(ERR_CHDIR, pkgdev.dirname);
7269781SMoriah.Waterland@Sun.COM 			quit(1);
7279781SMoriah.Waterland@Sun.COM 			/* NOTREACHED */
7289781SMoriah.Waterland@Sun.COM 		}
7299781SMoriah.Waterland@Sun.COM 
7309781SMoriah.Waterland@Sun.COM 		/*
7319781SMoriah.Waterland@Sun.COM 		 * spool device mounted/available - get the list of the
7329781SMoriah.Waterland@Sun.COM 		 * packages to remove
7339781SMoriah.Waterland@Sun.COM 		 */
7349781SMoriah.Waterland@Sun.COM 
7359781SMoriah.Waterland@Sun.COM 		n = pkgGetPackageList(&pkglist, argv, optind,
7369781SMoriah.Waterland@Sun.COM 			catg_arg, category, &pkgdev);
7379781SMoriah.Waterland@Sun.COM 
7389781SMoriah.Waterland@Sun.COM 		switch (n) {
7399781SMoriah.Waterland@Sun.COM 			case -1:	/* no packages found */
7409781SMoriah.Waterland@Sun.COM 				echoDebug(DBG_PKGLIST_RM_NONFOUND,
7419781SMoriah.Waterland@Sun.COM 					PSTR(pkgdev.dirname));
7429781SMoriah.Waterland@Sun.COM 				progerr(ERR_NOPKGS, pkgdev.dirname);
7439781SMoriah.Waterland@Sun.COM 				quit(1);
7449781SMoriah.Waterland@Sun.COM 				/* NOTREACHED */
7459781SMoriah.Waterland@Sun.COM 
7469781SMoriah.Waterland@Sun.COM 			case 0:		/* packages found */
7479781SMoriah.Waterland@Sun.COM 				break;
7489781SMoriah.Waterland@Sun.COM 
7499781SMoriah.Waterland@Sun.COM 			default:	/* "quit" error */
7509781SMoriah.Waterland@Sun.COM 				echoDebug(DBG_PKGLIST_RM_ERROR,
7519781SMoriah.Waterland@Sun.COM 					pkgdev.dirname, n);
7529781SMoriah.Waterland@Sun.COM 				quit(n);
7539781SMoriah.Waterland@Sun.COM 				/* NOTREACHED */
7549781SMoriah.Waterland@Sun.COM 		}
7559781SMoriah.Waterland@Sun.COM 
7569781SMoriah.Waterland@Sun.COM 		/*
7579781SMoriah.Waterland@Sun.COM 		 * count the number of packages to remove
7589781SMoriah.Waterland@Sun.COM 		 * NOTE: npkgs is a global variable that is referenced by quit.c
7599781SMoriah.Waterland@Sun.COM 		 * when error messages are generated - it is referenced directly
7609781SMoriah.Waterland@Sun.COM 		 * by the other functions called below...
7619781SMoriah.Waterland@Sun.COM 		 */
7629781SMoriah.Waterland@Sun.COM 
7639781SMoriah.Waterland@Sun.COM 		for (npkgs = 0; pkglist[npkgs] != (char *)NULL; /* void */) {
7649781SMoriah.Waterland@Sun.COM 			pkgLgth = strlen(pkglist[npkgs]);
7659781SMoriah.Waterland@Sun.COM 			if (pkgLgth > longestPkg) {
7669781SMoriah.Waterland@Sun.COM 				longestPkg = pkgLgth;
7679781SMoriah.Waterland@Sun.COM 			}
7689781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_PKG_SELECTED, npkgs, pkglist[npkgs]);
7699781SMoriah.Waterland@Sun.COM 			npkgs++;
7709781SMoriah.Waterland@Sun.COM 		}
7719781SMoriah.Waterland@Sun.COM 
7729781SMoriah.Waterland@Sun.COM 		/* output number of packages to be removed */
7739781SMoriah.Waterland@Sun.COM 
7749781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_NUM_PKGS_TO_REMOVE, npkgs, longestPkg);
7759781SMoriah.Waterland@Sun.COM 
7769781SMoriah.Waterland@Sun.COM 		/*
7779781SMoriah.Waterland@Sun.COM 		 * package list generated - remove packages
7789781SMoriah.Waterland@Sun.COM 		 */
7799781SMoriah.Waterland@Sun.COM 
7809781SMoriah.Waterland@Sun.COM 		b = remove_packages(pkglist, nodelete, longestPkg, repeat,
7819781SMoriah.Waterland@Sun.COM 			altBinDir, pkgdev.dirname, spoolDir, noZones);
7829781SMoriah.Waterland@Sun.COM 
7839781SMoriah.Waterland@Sun.COM 		/*
7849781SMoriah.Waterland@Sun.COM 		 * unmount the spool directory if necessary
7859781SMoriah.Waterland@Sun.COM 		 */
7869781SMoriah.Waterland@Sun.COM 
7879781SMoriah.Waterland@Sun.COM 		if (pkgdev.mount) {
7889781SMoriah.Waterland@Sun.COM 			(void) chdir("/");
7899781SMoriah.Waterland@Sun.COM 			if (pkgumount(&pkgdev)) {
7909781SMoriah.Waterland@Sun.COM 				progerr(ERR_PKGUNMOUNT, pkgdev.bdevice);
7919781SMoriah.Waterland@Sun.COM 				quit(99);
7929781SMoriah.Waterland@Sun.COM 				/* NOTREACHED */
7939781SMoriah.Waterland@Sun.COM 
7949781SMoriah.Waterland@Sun.COM 			}
7959781SMoriah.Waterland@Sun.COM 		}
7969781SMoriah.Waterland@Sun.COM 
7979781SMoriah.Waterland@Sun.COM 		/*
7989781SMoriah.Waterland@Sun.COM 		 * continue with next sequence of packages if continue set
7999781SMoriah.Waterland@Sun.COM 		 */
8009781SMoriah.Waterland@Sun.COM 
8019781SMoriah.Waterland@Sun.COM 		if (b == B_TRUE) {
8029781SMoriah.Waterland@Sun.COM 			continue;
8039781SMoriah.Waterland@Sun.COM 		}
8049781SMoriah.Waterland@Sun.COM 
8059781SMoriah.Waterland@Sun.COM 		/*
8069781SMoriah.Waterland@Sun.COM 		 * not continuing - quit with 0 exit code
8079781SMoriah.Waterland@Sun.COM 		 */
8089781SMoriah.Waterland@Sun.COM 
8099781SMoriah.Waterland@Sun.COM 		quit(0);
8109781SMoriah.Waterland@Sun.COM 		/* NOTREACHED */
8119781SMoriah.Waterland@Sun.COM #ifdef lint
8129781SMoriah.Waterland@Sun.COM 		return (0);
8139781SMoriah.Waterland@Sun.COM #endif	/* lint */
8149781SMoriah.Waterland@Sun.COM 	}
8159781SMoriah.Waterland@Sun.COM }
8169781SMoriah.Waterland@Sun.COM 
8179781SMoriah.Waterland@Sun.COM /*
8189781SMoriah.Waterland@Sun.COM  * *****************************************************************************
8199781SMoriah.Waterland@Sun.COM  * static internal (private) functions
8209781SMoriah.Waterland@Sun.COM  * *****************************************************************************
8219781SMoriah.Waterland@Sun.COM  */
8229781SMoriah.Waterland@Sun.COM 
8239781SMoriah.Waterland@Sun.COM /*
8249781SMoriah.Waterland@Sun.COM  * Name:	doRemove
8259781SMoriah.Waterland@Sun.COM  * Description:	Remove a package from the global zone, and optionally from one
8269781SMoriah.Waterland@Sun.COM  *		or more non-global zones.
8279781SMoriah.Waterland@Sun.COM  * Arguments:	a_nodelete: should the files and scripts remain installed?
8289781SMoriah.Waterland@Sun.COM  *			- if != 0 pass -F flag to pkgremove - suppress
8299781SMoriah.Waterland@Sun.COM  *			the removal of any files and any class action scripts
8309781SMoriah.Waterland@Sun.COM  *			and suppress the running of any class action scripts.
8319781SMoriah.Waterland@Sun.COM  *			The package files remain but the package looks like it
8329781SMoriah.Waterland@Sun.COM  *			is not installed. This is mainly for use by upgrade.
8339781SMoriah.Waterland@Sun.COM  *			- if == 0 do not pass -F flag to pkgremove - all
8349781SMoriah.Waterland@Sun.COM  *			files and class action scripts are removed, and any
8359781SMoriah.Waterland@Sun.COM  *			appropriate class action scripts are run.
8369781SMoriah.Waterland@Sun.COM  *		a_altBinDir - pointer to string representing location of the
8379781SMoriah.Waterland@Sun.COM  *			pkgremove executable to run. If not NULL, then pass
8389781SMoriah.Waterland@Sun.COM  *			the path specified to the -b option to pkgremove.
8399781SMoriah.Waterland@Sun.COM  *		a_longestPkg - length of the longest package "name" (for
8409781SMoriah.Waterland@Sun.COM  *			output format alignment)
8419781SMoriah.Waterland@Sun.COM  *		a_adminFile - pointer to string representing the admin
8429781SMoriah.Waterland@Sun.COM  *			file to pass to pkgremove when removing a package from
8439781SMoriah.Waterland@Sun.COM  *			the global zone only. Typically the admin file used for
8449781SMoriah.Waterland@Sun.COM  *			the global zone is the admin file passed in by the user.
8459781SMoriah.Waterland@Sun.COM  *			If this is == NULL no admin file is given to pkgremove.
8469781SMoriah.Waterland@Sun.COM  *		a_zoneAdminFile - pointer to string representing the admin
8479781SMoriah.Waterland@Sun.COM  *			file to pass to pkgremove when removing the package
8489781SMoriah.Waterland@Sun.COM  *			from a non-global zone only. Typically the admin file
8499781SMoriah.Waterland@Sun.COM  *			used for non-global zones supresses all checks since
8509781SMoriah.Waterland@Sun.COM  *			the dependency checking is done for all zones first
8519781SMoriah.Waterland@Sun.COM  *			before proceeding.
8529781SMoriah.Waterland@Sun.COM  *			A zoneAdminFile MUST be specified if a_zlst != NULL.
8539781SMoriah.Waterland@Sun.COM  *			A zoneAdminFile must NOT be specified if a_zlst == NULL.
8549781SMoriah.Waterland@Sun.COM  *		a_zlst - list of zones to process; NULL if no zones to process.
8559781SMoriah.Waterland@Sun.COM  * Returns:	int	(see ckreturn() function for details)
8569781SMoriah.Waterland@Sun.COM  *		0 - success
8579781SMoriah.Waterland@Sun.COM  *		1 - package operation failed (fatal error)
8589781SMoriah.Waterland@Sun.COM  *		2 - non-fatal error (warning)
8599781SMoriah.Waterland@Sun.COM  *		3 - user selected quit (operation interrupted)
8609781SMoriah.Waterland@Sun.COM  *		4 - admin settings prevented operation
8619781SMoriah.Waterland@Sun.COM  *		5 - interaction required and -n (non-interactive) specified
8629781SMoriah.Waterland@Sun.COM  *		"10" will be added to indicate "immediate reboot required"
8639781SMoriah.Waterland@Sun.COM  *		"20" will be added to indicate "reboot after install required"
8649781SMoriah.Waterland@Sun.COM  */
8659781SMoriah.Waterland@Sun.COM 
8669781SMoriah.Waterland@Sun.COM static int
8679781SMoriah.Waterland@Sun.COM doRemove(int a_nodelete, char *a_altBinDir, int a_longestPkg, char *a_adminFile,
8689781SMoriah.Waterland@Sun.COM 	char *a_zoneAdminFile, zoneList_t a_zlst)
8699781SMoriah.Waterland@Sun.COM {
8709781SMoriah.Waterland@Sun.COM 	boolean_t	b;
8719781SMoriah.Waterland@Sun.COM 	char		**inheritedPkgDirs;
8729781SMoriah.Waterland@Sun.COM 	char		*zoneName;
8739781SMoriah.Waterland@Sun.COM 	char		ans[MAX_INPUT];
8749781SMoriah.Waterland@Sun.COM 	int		n;
8759781SMoriah.Waterland@Sun.COM 	int		zoneIndex;
8769781SMoriah.Waterland@Sun.COM 	int		zonesSkipped;
8779781SMoriah.Waterland@Sun.COM 	struct pkginfo	*pinfo = (struct pkginfo *)NULL;
8789781SMoriah.Waterland@Sun.COM 	zone_state_t	zst;
8799781SMoriah.Waterland@Sun.COM 
8809781SMoriah.Waterland@Sun.COM 	/* entry assertions */
8819781SMoriah.Waterland@Sun.COM 
8829781SMoriah.Waterland@Sun.COM 	if (a_zlst != (zoneList_t)NULL) {
8839781SMoriah.Waterland@Sun.COM 		/* zone list specified - zone admin file required */
8849781SMoriah.Waterland@Sun.COM 		assert(a_zoneAdminFile != (char *)NULL);
8859781SMoriah.Waterland@Sun.COM 		assert(*a_zoneAdminFile != '\0');
8869781SMoriah.Waterland@Sun.COM 	} else {
8879781SMoriah.Waterland@Sun.COM 		/* no zone list specified - no zone admin file needed */
8889781SMoriah.Waterland@Sun.COM 		assert(a_zoneAdminFile == (char *)NULL);
8899781SMoriah.Waterland@Sun.COM 	}
8909781SMoriah.Waterland@Sun.COM 
8919781SMoriah.Waterland@Sun.COM 	/* NOTE: required 'pkgdir' set to spool directory or NULL */
8929781SMoriah.Waterland@Sun.COM 	b = pkginfoIsPkgInstalled(&pinfo, pkginst);
8939781SMoriah.Waterland@Sun.COM 	if (b == B_FALSE) {
8949781SMoriah.Waterland@Sun.COM 		progerr(ERR_NO_SUCH_INSTANCE, pkginst);
8959781SMoriah.Waterland@Sun.COM 		pkginfoFree(&pinfo);
8969781SMoriah.Waterland@Sun.COM 		return (2);
8979781SMoriah.Waterland@Sun.COM 	}
8989781SMoriah.Waterland@Sun.COM 
8999781SMoriah.Waterland@Sun.COM 	/* entry debugging info */
9009781SMoriah.Waterland@Sun.COM 
9019781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_DOREMOVE_ENTRY);
9029781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_DOREMOVE_ARGS, PSTR(pinfo->pkginst), PSTR(pinfo->name),
9039781SMoriah.Waterland@Sun.COM 		PSTR(pinfo->arch), PSTR(pinfo->version), PSTR(pinfo->basedir),
9049781SMoriah.Waterland@Sun.COM 		PSTR(pinfo->catg), pinfo->status);
9059781SMoriah.Waterland@Sun.COM 
9069781SMoriah.Waterland@Sun.COM 	if (!nointeract) {
9079781SMoriah.Waterland@Sun.COM 		char	fmt1[100];
9089781SMoriah.Waterland@Sun.COM 
9099781SMoriah.Waterland@Sun.COM 		/* create format based on max pkg name length */
9109781SMoriah.Waterland@Sun.COM 
9119781SMoriah.Waterland@Sun.COM 		(void) snprintf(fmt1, sizeof (fmt1), "   %%-%d.%ds  %%s",
9129781SMoriah.Waterland@Sun.COM 				a_longestPkg, a_longestPkg);
9139781SMoriah.Waterland@Sun.COM 
9149781SMoriah.Waterland@Sun.COM 		if (pinfo->status == PI_SPOOLED) {
9159781SMoriah.Waterland@Sun.COM 			echo(INFO_SPOOLED);
9169781SMoriah.Waterland@Sun.COM 		} else {
9179781SMoriah.Waterland@Sun.COM 			if (getuid()) {
9189781SMoriah.Waterland@Sun.COM 				progerr(ERR_NOT_ROOT, get_prog_name());
9199781SMoriah.Waterland@Sun.COM 				exit(1);
9209781SMoriah.Waterland@Sun.COM 			}
9219781SMoriah.Waterland@Sun.COM 			echo(INFO_INSTALL);
9229781SMoriah.Waterland@Sun.COM 		}
9239781SMoriah.Waterland@Sun.COM 
9249781SMoriah.Waterland@Sun.COM 		echo(fmt1, pinfo->pkginst, pinfo->name);
9259781SMoriah.Waterland@Sun.COM 
9269781SMoriah.Waterland@Sun.COM 		if (pinfo->arch || pinfo->version) {
9279781SMoriah.Waterland@Sun.COM 			char	fmt2[100];
9289781SMoriah.Waterland@Sun.COM 
9299781SMoriah.Waterland@Sun.COM 			/* create format based on max pkg name length */
9309781SMoriah.Waterland@Sun.COM 
9319781SMoriah.Waterland@Sun.COM 			(void) snprintf(fmt2, sizeof (fmt2), "   %%%d.%ds  ",
9329781SMoriah.Waterland@Sun.COM 					a_longestPkg, a_longestPkg);
9339781SMoriah.Waterland@Sun.COM 
9349781SMoriah.Waterland@Sun.COM 			/* LINTED variable format specifier to fprintf() */
9359781SMoriah.Waterland@Sun.COM 			(void) fprintf(stderr, fmt2, "");
9369781SMoriah.Waterland@Sun.COM 
9379781SMoriah.Waterland@Sun.COM 			if (pinfo->arch) {
9389781SMoriah.Waterland@Sun.COM 				(void) fprintf(stderr, "(%s) ", pinfo->arch);
9399781SMoriah.Waterland@Sun.COM 			}
9409781SMoriah.Waterland@Sun.COM 
9419781SMoriah.Waterland@Sun.COM 			if (pinfo->version) {
9429781SMoriah.Waterland@Sun.COM 				(void) fprintf(stderr, "%s", pinfo->version);
9439781SMoriah.Waterland@Sun.COM 			}
9449781SMoriah.Waterland@Sun.COM 
9459781SMoriah.Waterland@Sun.COM 			(void) fprintf(stderr, "\n");
9469781SMoriah.Waterland@Sun.COM 		}
9479781SMoriah.Waterland@Sun.COM 
9489781SMoriah.Waterland@Sun.COM 		n = ckyorn(ans, NULL, NULL, NULL, ASK_CONFIRM);
9499781SMoriah.Waterland@Sun.COM 		if (n != 0) {
9509781SMoriah.Waterland@Sun.COM 			quit(n);
9519781SMoriah.Waterland@Sun.COM 			/* NOTREACHED */
9529781SMoriah.Waterland@Sun.COM 		}
9539781SMoriah.Waterland@Sun.COM 
9549781SMoriah.Waterland@Sun.COM 		if (strchr("yY", *ans) == NULL) {
9559781SMoriah.Waterland@Sun.COM 			pkginfoFree(&pinfo);
9569781SMoriah.Waterland@Sun.COM 			return (0);
9579781SMoriah.Waterland@Sun.COM 		}
9589781SMoriah.Waterland@Sun.COM 	}
9599781SMoriah.Waterland@Sun.COM 
9609781SMoriah.Waterland@Sun.COM 	if (pinfo->status == PI_PRESVR4) {
9619781SMoriah.Waterland@Sun.COM 		pkginfoFree(&pinfo);
9629781SMoriah.Waterland@Sun.COM 		return (presvr4(pkginst, nointeract));
9639781SMoriah.Waterland@Sun.COM 	}
9649781SMoriah.Waterland@Sun.COM 
9659781SMoriah.Waterland@Sun.COM 	if (pinfo->status == PI_SPOOLED) {
9669781SMoriah.Waterland@Sun.COM 		/* removal from a directory */
9679781SMoriah.Waterland@Sun.COM 		echo(INFO_RMSPOOL, pkginst);
9689781SMoriah.Waterland@Sun.COM 		pkginfoFree(&pinfo);
9699781SMoriah.Waterland@Sun.COM 		return (rrmdir(pkginst));
9709781SMoriah.Waterland@Sun.COM 	}
9719781SMoriah.Waterland@Sun.COM 
9729781SMoriah.Waterland@Sun.COM 	/* exit if not root */
9739781SMoriah.Waterland@Sun.COM 
9749781SMoriah.Waterland@Sun.COM 	if (getuid()) {
9759781SMoriah.Waterland@Sun.COM 		progerr(ERR_NOT_ROOT, get_prog_name());
9769781SMoriah.Waterland@Sun.COM 		exit(1);
9779781SMoriah.Waterland@Sun.COM 	}
9789781SMoriah.Waterland@Sun.COM 
9799781SMoriah.Waterland@Sun.COM 	pkginfoFree(&pinfo);
9809781SMoriah.Waterland@Sun.COM 
9819781SMoriah.Waterland@Sun.COM 	zonesSkipped = 0;
9829781SMoriah.Waterland@Sun.COM 
9839781SMoriah.Waterland@Sun.COM 	if (interrupted != 0) {
9849781SMoriah.Waterland@Sun.COM 		echo(MSG_DOREMOVE_INTERRUPTED_B4_Z, pkginst);
9859781SMoriah.Waterland@Sun.COM 		echoDebug(MSG_DOREMOVE_INTERRUPTED_B4_Z, pkginst);
9869781SMoriah.Waterland@Sun.COM 		return (n);
9879781SMoriah.Waterland@Sun.COM 	}
9889781SMoriah.Waterland@Sun.COM 
9899781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_REMOVE_FLAG_VALUES, "before pkgZoneRemove",
9909781SMoriah.Waterland@Sun.COM 		admnflag, doreboot, failflag, interrupted,
9919781SMoriah.Waterland@Sun.COM 		intrflag, ireboot, nullflag, warnflag);
9929781SMoriah.Waterland@Sun.COM 
9939781SMoriah.Waterland@Sun.COM 	for (zoneIndex = 0;
9949781SMoriah.Waterland@Sun.COM 	    a_zlst != NULL &&
9959781SMoriah.Waterland@Sun.COM 	    (zoneName = z_zlist_get_zonename(a_zlst, zoneIndex)) != NULL;
9969781SMoriah.Waterland@Sun.COM 	    zoneIndex++) {
9979781SMoriah.Waterland@Sun.COM 
9989781SMoriah.Waterland@Sun.COM 		/* skip the zone if it is NOT running */
9999781SMoriah.Waterland@Sun.COM 
10009781SMoriah.Waterland@Sun.COM 		zst = z_zlist_get_current_state(a_zlst, zoneIndex);
10019781SMoriah.Waterland@Sun.COM 		if (zst != ZONE_STATE_RUNNING && zst != ZONE_STATE_MOUNTED) {
10029781SMoriah.Waterland@Sun.COM 			zonesSkipped++;
10039781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_SKIPPING_ZONE, zoneName);
10049781SMoriah.Waterland@Sun.COM 			continue;
10059781SMoriah.Waterland@Sun.COM 		}
10069781SMoriah.Waterland@Sun.COM 
10079781SMoriah.Waterland@Sun.COM 		echo(MSG_REMOVE_PKG_FROM_ZONE, pkginst, zoneName);
10089781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_REMOVE_PKG_FROM_ZONE, pkginst, zoneName);
10099781SMoriah.Waterland@Sun.COM 
10109781SMoriah.Waterland@Sun.COM 		/* determine list of directories inherited from global zone */
10119781SMoriah.Waterland@Sun.COM 
10129781SMoriah.Waterland@Sun.COM 		inheritedPkgDirs = z_zlist_get_inherited_pkg_dirs(a_zlst,
10139781SMoriah.Waterland@Sun.COM 					zoneIndex);
10149781SMoriah.Waterland@Sun.COM 
10159781SMoriah.Waterland@Sun.COM 		/*
10169781SMoriah.Waterland@Sun.COM 		 * remove package from zone; use the zone admin file which
10179781SMoriah.Waterland@Sun.COM 		 * suppresses all checks.
10189781SMoriah.Waterland@Sun.COM 		 */
10199781SMoriah.Waterland@Sun.COM 
10209781SMoriah.Waterland@Sun.COM 		n = pkgZoneRemove(z_zlist_get_scratch(a_zlst, zoneIndex),
10219781SMoriah.Waterland@Sun.COM 			inheritedPkgDirs, a_nodelete, a_altBinDir,
1022*9869SCasper.Dik@Sun.COM 			a_zoneAdminFile, zst, B_FALSE);
10239781SMoriah.Waterland@Sun.COM 
10249781SMoriah.Waterland@Sun.COM 		/* set success/fail condition variables */
10259781SMoriah.Waterland@Sun.COM 
10269781SMoriah.Waterland@Sun.COM 		ckreturn(n);
10279781SMoriah.Waterland@Sun.COM 
10289781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_REMOVE_FLAG_VALUES, "after pkgZoneRemove",
10299781SMoriah.Waterland@Sun.COM 			admnflag, doreboot, failflag, interrupted, intrflag,
10309781SMoriah.Waterland@Sun.COM 			ireboot, nullflag, warnflag);
10319781SMoriah.Waterland@Sun.COM 	}
10329781SMoriah.Waterland@Sun.COM 
10339781SMoriah.Waterland@Sun.COM 	if (zonesSkipped > 0) {
10349781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_ZONES_SKIPPED, zonesSkipped);
10359781SMoriah.Waterland@Sun.COM 
10369781SMoriah.Waterland@Sun.COM 		for (zoneIndex = 0;
10379781SMoriah.Waterland@Sun.COM 			(zoneName = z_zlist_get_zonename(a_zlst, zoneIndex)) !=
10389781SMoriah.Waterland@Sun.COM 				(char *)NULL; zoneIndex++) {
10399781SMoriah.Waterland@Sun.COM 
10409781SMoriah.Waterland@Sun.COM 			/* skip the zone if it IS running */
10419781SMoriah.Waterland@Sun.COM 
10429781SMoriah.Waterland@Sun.COM 			zst = z_zlist_get_current_state(a_zlst, zoneIndex);
10439781SMoriah.Waterland@Sun.COM 			if (zst == ZONE_STATE_RUNNING ||
10449781SMoriah.Waterland@Sun.COM 			    zst == ZONE_STATE_MOUNTED) {
10459781SMoriah.Waterland@Sun.COM 				zonesSkipped++;
10469781SMoriah.Waterland@Sun.COM 				echoDebug(DBG_SKIPPING_ZONE_BOOT, zoneName);
10479781SMoriah.Waterland@Sun.COM 				continue;
10489781SMoriah.Waterland@Sun.COM 			}
10499781SMoriah.Waterland@Sun.COM 
10509781SMoriah.Waterland@Sun.COM 			/* skip the zone if it is NOT bootable */
10519781SMoriah.Waterland@Sun.COM 
10529781SMoriah.Waterland@Sun.COM 			if (z_zlist_is_zone_runnable(a_zlst,
10539781SMoriah.Waterland@Sun.COM 						zoneIndex) == B_FALSE) {
10549781SMoriah.Waterland@Sun.COM 				echo(MSG_SKIPPING_ZONE_NOT_RUNNABLE, zoneName);
10559781SMoriah.Waterland@Sun.COM 				echoDebug(DBG_SKIPPING_ZONE_NOT_RUNNABLE,
10569781SMoriah.Waterland@Sun.COM 					zoneName);
10579781SMoriah.Waterland@Sun.COM 				continue;
10589781SMoriah.Waterland@Sun.COM 			}
10599781SMoriah.Waterland@Sun.COM 
10609781SMoriah.Waterland@Sun.COM 			/* mount up the zone */
10619781SMoriah.Waterland@Sun.COM 
10629781SMoriah.Waterland@Sun.COM 			echo(MSG_BOOTING_ZONE, zoneName);
10639781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_BOOTING_ZONE, zoneName);
10649781SMoriah.Waterland@Sun.COM 
10659781SMoriah.Waterland@Sun.COM 			b = z_zlist_change_zone_state(a_zlst, zoneIndex,
10669781SMoriah.Waterland@Sun.COM 				ZONE_STATE_MOUNTED);
10679781SMoriah.Waterland@Sun.COM 			if (b == B_FALSE) {
10689781SMoriah.Waterland@Sun.COM 				progerr(ERR_CANNOT_BOOT_ZONE, zoneName);
10699781SMoriah.Waterland@Sun.COM 				/* set fatal error return condition */
10709781SMoriah.Waterland@Sun.COM 				ckreturn(1);
10719781SMoriah.Waterland@Sun.COM 				continue;
10729781SMoriah.Waterland@Sun.COM 			}
10739781SMoriah.Waterland@Sun.COM 
10749781SMoriah.Waterland@Sun.COM 			echo(MSG_REMOVE_PKG_FROM_ZONE, pkginst, zoneName);
10759781SMoriah.Waterland@Sun.COM 
10769781SMoriah.Waterland@Sun.COM 			/* determine list of dirs inherited from global zone */
10779781SMoriah.Waterland@Sun.COM 
10789781SMoriah.Waterland@Sun.COM 			inheritedPkgDirs =
10799781SMoriah.Waterland@Sun.COM 				z_zlist_get_inherited_pkg_dirs(a_zlst,
10809781SMoriah.Waterland@Sun.COM 						zoneIndex);
10819781SMoriah.Waterland@Sun.COM 
10829781SMoriah.Waterland@Sun.COM 			/*
10839781SMoriah.Waterland@Sun.COM 			 * remove package from zone; use the zone admin file
10849781SMoriah.Waterland@Sun.COM 			 * which suppresses all checks.
10859781SMoriah.Waterland@Sun.COM 			 */
10869781SMoriah.Waterland@Sun.COM 
10879781SMoriah.Waterland@Sun.COM 			n = pkgZoneRemove(z_zlist_get_scratch(a_zlst,
10889781SMoriah.Waterland@Sun.COM 				zoneIndex), inheritedPkgDirs,
10899781SMoriah.Waterland@Sun.COM 				a_nodelete, a_altBinDir, a_zoneAdminFile,
1090*9869SCasper.Dik@Sun.COM 				ZONE_STATE_MOUNTED, B_TRUE);
10919781SMoriah.Waterland@Sun.COM 
10929781SMoriah.Waterland@Sun.COM 			/* set success/fail condition variables */
10939781SMoriah.Waterland@Sun.COM 
10949781SMoriah.Waterland@Sun.COM 			ckreturn(n);
10959781SMoriah.Waterland@Sun.COM 
10969781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_REMOVE_FLAG_VALUES, "after pkgZoneRemove",
10979781SMoriah.Waterland@Sun.COM 				admnflag, doreboot, failflag, interrupted,
10989781SMoriah.Waterland@Sun.COM 				intrflag, ireboot, nullflag, warnflag);
10999781SMoriah.Waterland@Sun.COM 
11009781SMoriah.Waterland@Sun.COM 			/* restore original state of zone */
11019781SMoriah.Waterland@Sun.COM 
11029781SMoriah.Waterland@Sun.COM 			echo(MSG_RESTORE_ZONE_STATE, zoneName);
11039781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_RESTORE_ZONE_STATE, zoneName);
11049781SMoriah.Waterland@Sun.COM 
11059781SMoriah.Waterland@Sun.COM 			b = z_zlist_restore_zone_state(a_zlst, zoneIndex);
11069781SMoriah.Waterland@Sun.COM 		}
11079781SMoriah.Waterland@Sun.COM 	}
11089781SMoriah.Waterland@Sun.COM 
11099781SMoriah.Waterland@Sun.COM 	/*
11109781SMoriah.Waterland@Sun.COM 	 * Process global zone if it was either the only possible
11119781SMoriah.Waterland@Sun.COM 	 * target (no list of zones specified) or it appears in the list
11129781SMoriah.Waterland@Sun.COM 	 */
11139781SMoriah.Waterland@Sun.COM 	if (a_zlst == NULL || z_on_zone_spec(GLOBAL_ZONENAME)) {
11149781SMoriah.Waterland@Sun.COM 		/* reset interrupted flag before calling pkgremove */
11159781SMoriah.Waterland@Sun.COM 		interrupted = 0;	/* last action was NOT quit */
11169781SMoriah.Waterland@Sun.COM 
11179781SMoriah.Waterland@Sun.COM 		/*
11189781SMoriah.Waterland@Sun.COM 		 * call pkgremove for this package for the global zone;
11199781SMoriah.Waterland@Sun.COM 		 * use the admin file passed in by the user via -a.
11209781SMoriah.Waterland@Sun.COM 		 */
11219781SMoriah.Waterland@Sun.COM 		n = pkgRemove(a_nodelete, a_altBinDir, a_adminFile,
11229781SMoriah.Waterland@Sun.COM 		    z_get_inherited_file_systems());
11239781SMoriah.Waterland@Sun.COM 
11249781SMoriah.Waterland@Sun.COM 		/* set success/fail condition variables */
11259781SMoriah.Waterland@Sun.COM 		ckreturn(n);
11269781SMoriah.Waterland@Sun.COM 	}
11279781SMoriah.Waterland@Sun.COM 
11289781SMoriah.Waterland@Sun.COM 	return (n);
11299781SMoriah.Waterland@Sun.COM }
11309781SMoriah.Waterland@Sun.COM 
11319781SMoriah.Waterland@Sun.COM /*
11329781SMoriah.Waterland@Sun.COM  *  function to clear out any exisiting error return conditions that may have
11339781SMoriah.Waterland@Sun.COM  *  been set by previous calls to ckreturn()
11349781SMoriah.Waterland@Sun.COM  */
11359781SMoriah.Waterland@Sun.COM static void
11369781SMoriah.Waterland@Sun.COM resetreturn()
11379781SMoriah.Waterland@Sun.COM {
11389781SMoriah.Waterland@Sun.COM 	admnflag = 0;	/* != 0 if any pkg op admin setting failure (4) */
11399781SMoriah.Waterland@Sun.COM 	doreboot = 0;	/* != 0 if reboot required after installation (>= 10) */
11409781SMoriah.Waterland@Sun.COM 	failflag = 0;	/* != 0 if fatal error has occurred (1) */
11419781SMoriah.Waterland@Sun.COM 	intrflag = 0;	/* != 0 if user selected quit (3) */
11429781SMoriah.Waterland@Sun.COM 	ireboot = 0;	/* != 0 if immediate reboot required (>= 20) */
11439781SMoriah.Waterland@Sun.COM 	nullflag = 0;	/* != 0 if admin interaction required (5) */
11449781SMoriah.Waterland@Sun.COM 	warnflag = 0;	/* != 0 if non-fatal error has occurred (2) */
11459781SMoriah.Waterland@Sun.COM 	interrupted = 0;	/* last pkg op was quit (1,2,3,4,5) */
11469781SMoriah.Waterland@Sun.COM }
11479781SMoriah.Waterland@Sun.COM 
11489781SMoriah.Waterland@Sun.COM /*
11499781SMoriah.Waterland@Sun.COM  *  function which checks the indicated return value
11509781SMoriah.Waterland@Sun.COM  *  and indicates disposition of installation
11519781SMoriah.Waterland@Sun.COM  */
11529781SMoriah.Waterland@Sun.COM static void
11539781SMoriah.Waterland@Sun.COM ckreturn(int retcode)
11549781SMoriah.Waterland@Sun.COM {
11559781SMoriah.Waterland@Sun.COM 	/*
11569781SMoriah.Waterland@Sun.COM 	 * entry debugging info
11579781SMoriah.Waterland@Sun.COM 	 */
11589781SMoriah.Waterland@Sun.COM 
11599781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_PKGRM_CKRETURN, retcode, PSTR(pkginst));
11609781SMoriah.Waterland@Sun.COM 
11619781SMoriah.Waterland@Sun.COM 	switch (retcode) {
11629781SMoriah.Waterland@Sun.COM 	    case  0:		/* successful */
11639781SMoriah.Waterland@Sun.COM 	    case 10:
11649781SMoriah.Waterland@Sun.COM 	    case 20:
11659781SMoriah.Waterland@Sun.COM 		break; /* empty case */
11669781SMoriah.Waterland@Sun.COM 
11679781SMoriah.Waterland@Sun.COM 	    case  1:		/* package operation failed (fatal error) */
11689781SMoriah.Waterland@Sun.COM 	    case 11:
11699781SMoriah.Waterland@Sun.COM 	    case 21:
11709781SMoriah.Waterland@Sun.COM 		failflag++;
11719781SMoriah.Waterland@Sun.COM 		interrupted++;
11729781SMoriah.Waterland@Sun.COM 		break;
11739781SMoriah.Waterland@Sun.COM 
11749781SMoriah.Waterland@Sun.COM 	    case  2:		/* non-fatal error (warning) */
11759781SMoriah.Waterland@Sun.COM 	    case 12:
11769781SMoriah.Waterland@Sun.COM 	    case 22:
11779781SMoriah.Waterland@Sun.COM 		warnflag++;
11789781SMoriah.Waterland@Sun.COM 		interrupted++;
11799781SMoriah.Waterland@Sun.COM 		break;
11809781SMoriah.Waterland@Sun.COM 
11819781SMoriah.Waterland@Sun.COM 	    case  3:		/* user selected quit; operation interrupted */
11829781SMoriah.Waterland@Sun.COM 	    case 13:
11839781SMoriah.Waterland@Sun.COM 	    case 23:
11849781SMoriah.Waterland@Sun.COM 		intrflag++;
11859781SMoriah.Waterland@Sun.COM 		interrupted++;
11869781SMoriah.Waterland@Sun.COM 		break;
11879781SMoriah.Waterland@Sun.COM 
11889781SMoriah.Waterland@Sun.COM 	    case  4:		/* admin settings prevented operation */
11899781SMoriah.Waterland@Sun.COM 	    case 14:
11909781SMoriah.Waterland@Sun.COM 	    case 24:
11919781SMoriah.Waterland@Sun.COM 		admnflag++;
11929781SMoriah.Waterland@Sun.COM 		interrupted++;
11939781SMoriah.Waterland@Sun.COM 		break;
11949781SMoriah.Waterland@Sun.COM 
11959781SMoriah.Waterland@Sun.COM 	    case  5:		/* administration: interaction req (no -n) */
11969781SMoriah.Waterland@Sun.COM 	    case 15:
11979781SMoriah.Waterland@Sun.COM 	    case 25:
11989781SMoriah.Waterland@Sun.COM 		nullflag++;
11999781SMoriah.Waterland@Sun.COM 		interrupted++;
12009781SMoriah.Waterland@Sun.COM 		break;
12019781SMoriah.Waterland@Sun.COM 
12029781SMoriah.Waterland@Sun.COM 	    default:
12039781SMoriah.Waterland@Sun.COM 		failflag++;
12049781SMoriah.Waterland@Sun.COM 		interrupted++;
12059781SMoriah.Waterland@Sun.COM 		return;
12069781SMoriah.Waterland@Sun.COM 	}
12079781SMoriah.Waterland@Sun.COM 
12089781SMoriah.Waterland@Sun.COM 	if (retcode >= 20) {
12099781SMoriah.Waterland@Sun.COM 		ireboot++;
12109781SMoriah.Waterland@Sun.COM 	} else if (retcode >= 10) {
12119781SMoriah.Waterland@Sun.COM 		doreboot++;
12129781SMoriah.Waterland@Sun.COM 	}
12139781SMoriah.Waterland@Sun.COM }
12149781SMoriah.Waterland@Sun.COM 
12159781SMoriah.Waterland@Sun.COM static int
12169781SMoriah.Waterland@Sun.COM pkgZoneCheckRemove(char *a_zoneName, char **a_inheritedPkgDirs,
12179781SMoriah.Waterland@Sun.COM 	char *a_altBinDir, char *a_adminFile, char *a_stdoutPath,
1218*9869SCasper.Dik@Sun.COM 	zone_state_t a_zoneState, boolean_t tmpzone)
12199781SMoriah.Waterland@Sun.COM {
12209781SMoriah.Waterland@Sun.COM 	char	*arg[MAXARGS];
12219781SMoriah.Waterland@Sun.COM 	char	*p;
12229781SMoriah.Waterland@Sun.COM 	char	adminfd_path[PATH_MAX];
12239781SMoriah.Waterland@Sun.COM 	char	path[PATH_MAX];
12249781SMoriah.Waterland@Sun.COM 	int	fds[MAX_FDS];
12259781SMoriah.Waterland@Sun.COM 	int	maxfds;
12269781SMoriah.Waterland@Sun.COM 	int	n;
12279781SMoriah.Waterland@Sun.COM 	int	nargs;
12289781SMoriah.Waterland@Sun.COM 
12299781SMoriah.Waterland@Sun.COM 	/* entry assertions */
12309781SMoriah.Waterland@Sun.COM 
12319781SMoriah.Waterland@Sun.COM 	assert(a_zoneName != (char *)NULL);
12329781SMoriah.Waterland@Sun.COM 	assert(*a_zoneName != '\0');
12339781SMoriah.Waterland@Sun.COM 
12349781SMoriah.Waterland@Sun.COM 	/* entry debugging info */
12359781SMoriah.Waterland@Sun.COM 
12369781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_PKGZONECHECKREMOVE_ENTRY);
12379781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_PKGZONECHECKREMOVE_ARGS, a_zoneName, PSTR(pkginst),
12389781SMoriah.Waterland@Sun.COM 		PSTR(pkgdev.dirname), PSTR(a_adminFile), PSTR(a_stdoutPath));
12399781SMoriah.Waterland@Sun.COM 
12409781SMoriah.Waterland@Sun.COM 	/* generate path to pkgremove */
12419781SMoriah.Waterland@Sun.COM 
12429781SMoriah.Waterland@Sun.COM 	(void) snprintf(path, sizeof (path), "%s/pkgremove",
12439781SMoriah.Waterland@Sun.COM 		a_altBinDir == (char *)NULL ? PKGBIN : a_altBinDir);
12449781SMoriah.Waterland@Sun.COM 
12459781SMoriah.Waterland@Sun.COM 	/* start at first file descriptor */
12469781SMoriah.Waterland@Sun.COM 
12479781SMoriah.Waterland@Sun.COM 	maxfds = 0;
12489781SMoriah.Waterland@Sun.COM 
12499781SMoriah.Waterland@Sun.COM 	/*
12509781SMoriah.Waterland@Sun.COM 	 * generate argument list for call to pkgremove
12519781SMoriah.Waterland@Sun.COM 	 */
12529781SMoriah.Waterland@Sun.COM 
12539781SMoriah.Waterland@Sun.COM 	/* start at argument 0 */
12549781SMoriah.Waterland@Sun.COM 
12559781SMoriah.Waterland@Sun.COM 	nargs = 0;
12569781SMoriah.Waterland@Sun.COM 
12579781SMoriah.Waterland@Sun.COM 	/* first argument is path to executable */
12589781SMoriah.Waterland@Sun.COM 
12599781SMoriah.Waterland@Sun.COM 	arg[nargs++] = strdup(path);
12609781SMoriah.Waterland@Sun.COM 
12619781SMoriah.Waterland@Sun.COM 	/* second argument is always: pass -O debug to pkgremove: debug mode */
12629781SMoriah.Waterland@Sun.COM 
12639781SMoriah.Waterland@Sun.COM 	if (debugFlag == B_TRUE) {
12649781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-O";
12659781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "debug";
12669781SMoriah.Waterland@Sun.COM 	}
12679781SMoriah.Waterland@Sun.COM 
12689781SMoriah.Waterland@Sun.COM 	/* pkgrm -b dir: pass -b to pkgremove */
12699781SMoriah.Waterland@Sun.COM 
12709781SMoriah.Waterland@Sun.COM 	if (a_altBinDir != (char *)NULL) {
12719781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-b";
12729781SMoriah.Waterland@Sun.COM 		arg[nargs++] = a_altBinDir;
12739781SMoriah.Waterland@Sun.COM 	}
12749781SMoriah.Waterland@Sun.COM 
12759781SMoriah.Waterland@Sun.COM 	/*
12769781SMoriah.Waterland@Sun.COM 	 * NONABI_SCRIPTS defined: pass -o to pkgremove; refers to a
12779781SMoriah.Waterland@Sun.COM 	 * pkg requiring operator interaction during a procedure script
12789781SMoriah.Waterland@Sun.COM 	 * (common before on1093)
12799781SMoriah.Waterland@Sun.COM 	 */
12809781SMoriah.Waterland@Sun.COM 
12819781SMoriah.Waterland@Sun.COM 	if (old_pkg) {
12829781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-o";
12839781SMoriah.Waterland@Sun.COM 	}
12849781SMoriah.Waterland@Sun.COM 
12859781SMoriah.Waterland@Sun.COM 	/*
12869781SMoriah.Waterland@Sun.COM 	 * PKG_NONABI_SYMLINKS defined: pass -y to pkgremove; process
12879781SMoriah.Waterland@Sun.COM 	 * symlinks consistent with old behavior
12889781SMoriah.Waterland@Sun.COM 	 */
12899781SMoriah.Waterland@Sun.COM 
12909781SMoriah.Waterland@Sun.COM 	if (old_symlinks) {
12919781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-y";
12929781SMoriah.Waterland@Sun.COM 	}
12939781SMoriah.Waterland@Sun.COM 
12949781SMoriah.Waterland@Sun.COM 	/* pkgrm -M: pass -M to pkgremove: don't mount client file systems */
12959781SMoriah.Waterland@Sun.COM 
12969781SMoriah.Waterland@Sun.COM 	arg[nargs++] = "-M";
12979781SMoriah.Waterland@Sun.COM 
12989781SMoriah.Waterland@Sun.COM 	/* pkgrm -A: pass -A to pkgremove */
12999781SMoriah.Waterland@Sun.COM 
13009781SMoriah.Waterland@Sun.COM 	if (pkgrmremote) {
13019781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-A";
13029781SMoriah.Waterland@Sun.COM 	}
13039781SMoriah.Waterland@Sun.COM 
13049781SMoriah.Waterland@Sun.COM 	/* pkgrm -v: pass -v to pkgremove: never trace scripts */
13059781SMoriah.Waterland@Sun.COM 
13069781SMoriah.Waterland@Sun.COM 	/* pass "-O enable-hollow-package-support" */
13079781SMoriah.Waterland@Sun.COM 
13089781SMoriah.Waterland@Sun.COM 	if (is_depend_pkginfo_DB()) {
13099781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-O";
13109781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "enable-hollow-package-support";
13119781SMoriah.Waterland@Sun.COM 	}
13129781SMoriah.Waterland@Sun.COM 
13139781SMoriah.Waterland@Sun.COM 	/* pass -n to pkgremove: always in noninteractive mode */
13149781SMoriah.Waterland@Sun.COM 
13159781SMoriah.Waterland@Sun.COM 	arg[nargs++] = "-n";
13169781SMoriah.Waterland@Sun.COM 
13179781SMoriah.Waterland@Sun.COM 	/* pkgrm -a admin: pass -a admin to pkgremove: admin file */
13189781SMoriah.Waterland@Sun.COM 
13199781SMoriah.Waterland@Sun.COM 	if (a_adminFile) {
13209781SMoriah.Waterland@Sun.COM 		int fd;
13219781SMoriah.Waterland@Sun.COM 		fd = openLocal(a_adminFile, O_RDONLY, tmpdir);
13229781SMoriah.Waterland@Sun.COM 		if (fd < 0) {
13239781SMoriah.Waterland@Sun.COM 			progerr(ERR_CANNOT_COPY_LOCAL, a_adminFile,
13249781SMoriah.Waterland@Sun.COM 				errno, strerror(errno));
13259781SMoriah.Waterland@Sun.COM 			return (1);
13269781SMoriah.Waterland@Sun.COM 		}
13279781SMoriah.Waterland@Sun.COM 		(void) snprintf(adminfd_path, sizeof (adminfd_path),
13289781SMoriah.Waterland@Sun.COM 			"/proc/self/fd/%d", fd);
13299781SMoriah.Waterland@Sun.COM 		fds[maxfds++] = fd;
13309781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-a";
13319781SMoriah.Waterland@Sun.COM 		arg[nargs++] = strdup(adminfd_path);
13329781SMoriah.Waterland@Sun.COM 	}
13339781SMoriah.Waterland@Sun.COM 
13349781SMoriah.Waterland@Sun.COM 	/*
13359781SMoriah.Waterland@Sun.COM 	 * pkgadd -R root: pass -R /a to pkgremove in mounted zone
13369781SMoriah.Waterland@Sun.COM 	 */
13379781SMoriah.Waterland@Sun.COM 	if (a_zoneState == ZONE_STATE_MOUNTED) {
13389781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-R";
13399781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "/a";
13409781SMoriah.Waterland@Sun.COM 	}
13419781SMoriah.Waterland@Sun.COM 
13429781SMoriah.Waterland@Sun.COM 	/* pkgrm -F: pass -F to pkgremove: always update DB only */
13439781SMoriah.Waterland@Sun.COM 
13449781SMoriah.Waterland@Sun.COM 	arg[nargs++] = "-F";
13459781SMoriah.Waterland@Sun.COM 
13469781SMoriah.Waterland@Sun.COM 	/* pass "-O preremovecheck" */
13479781SMoriah.Waterland@Sun.COM 
13489781SMoriah.Waterland@Sun.COM 	arg[nargs++] = "-O";
13499781SMoriah.Waterland@Sun.COM 	arg[nargs++] = "preremovecheck";
13509781SMoriah.Waterland@Sun.COM 
13519781SMoriah.Waterland@Sun.COM 	/* add "-O addzonename" */
13529781SMoriah.Waterland@Sun.COM 
13539781SMoriah.Waterland@Sun.COM 	arg[nargs++] = "-O";
13549781SMoriah.Waterland@Sun.COM 	arg[nargs++] = "addzonename";
13559781SMoriah.Waterland@Sun.COM 
13569781SMoriah.Waterland@Sun.COM 	/* add all inherited file systems */
13579781SMoriah.Waterland@Sun.COM 
13589781SMoriah.Waterland@Sun.COM 	if (a_inheritedPkgDirs != (char **)NULL) {
13599781SMoriah.Waterland@Sun.COM 		for (n = 0; a_inheritedPkgDirs[n] != (char *)NULL; n++) {
13609781SMoriah.Waterland@Sun.COM 			char	ifs[MAXPATHLEN+22];
13619781SMoriah.Waterland@Sun.COM 			(void) snprintf(ifs, sizeof (ifs),
13629781SMoriah.Waterland@Sun.COM 				"inherited-filesystem=%s",
13639781SMoriah.Waterland@Sun.COM 				a_inheritedPkgDirs[n]);
13649781SMoriah.Waterland@Sun.COM 			arg[nargs++] = "-O";
13659781SMoriah.Waterland@Sun.COM 			arg[nargs++] = strdup(ifs);
13669781SMoriah.Waterland@Sun.COM 		}
13679781SMoriah.Waterland@Sun.COM 	}
13689781SMoriah.Waterland@Sun.COM 
13699781SMoriah.Waterland@Sun.COM 	/*
13709781SMoriah.Waterland@Sun.COM 	 * add parent zone info/type
13719781SMoriah.Waterland@Sun.COM 	 */
13729781SMoriah.Waterland@Sun.COM 
13739781SMoriah.Waterland@Sun.COM 	p = z_get_zonename();
13749781SMoriah.Waterland@Sun.COM 	if ((p != NULL) && (*p != '\0')) {
13759781SMoriah.Waterland@Sun.COM 			char	zn[MAXPATHLEN];
13769781SMoriah.Waterland@Sun.COM 			(void) snprintf(zn, sizeof (zn),
13779781SMoriah.Waterland@Sun.COM 				"parent-zone-name=%s", p);
13789781SMoriah.Waterland@Sun.COM 			arg[nargs++] = "-O";
13799781SMoriah.Waterland@Sun.COM 			arg[nargs++] = strdup(zn);
13809781SMoriah.Waterland@Sun.COM 	}
13819781SMoriah.Waterland@Sun.COM 
13829781SMoriah.Waterland@Sun.COM 	/* current zone type */
13839781SMoriah.Waterland@Sun.COM 
13849781SMoriah.Waterland@Sun.COM 	arg[nargs++] = "-O";
13859781SMoriah.Waterland@Sun.COM 	if (z_running_in_global_zone() == B_TRUE) {
13869781SMoriah.Waterland@Sun.COM 			char	zn[MAXPATHLEN];
13879781SMoriah.Waterland@Sun.COM 			(void) snprintf(zn, sizeof (zn),
13889781SMoriah.Waterland@Sun.COM 				"parent-zone-type=%s",
13899781SMoriah.Waterland@Sun.COM 				TAG_VALUE_GLOBAL_ZONE);
13909781SMoriah.Waterland@Sun.COM 			arg[nargs++] = strdup(zn);
13919781SMoriah.Waterland@Sun.COM 	} else {
13929781SMoriah.Waterland@Sun.COM 			char	zn[MAXPATHLEN];
13939781SMoriah.Waterland@Sun.COM 			(void) snprintf(zn, sizeof (zn),
13949781SMoriah.Waterland@Sun.COM 				"parent-zone-type=%s",
13959781SMoriah.Waterland@Sun.COM 				TAG_VALUE_NONGLOBAL_ZONE);
13969781SMoriah.Waterland@Sun.COM 			arg[nargs++] = strdup(zn);
13979781SMoriah.Waterland@Sun.COM 	}
13989781SMoriah.Waterland@Sun.COM 
1399*9869SCasper.Dik@Sun.COM 	/* Add arguments how to start the pkgserv */
1400*9869SCasper.Dik@Sun.COM 
1401*9869SCasper.Dik@Sun.COM 	arg[nargs++] = "-O";
1402*9869SCasper.Dik@Sun.COM 	arg[nargs++] = pkgmodeargument(tmpzone ? RUN_ONCE : pkgservergetmode());
1403*9869SCasper.Dik@Sun.COM 
14049781SMoriah.Waterland@Sun.COM 	/* pass -N to pkgremove: program name to report */
14059781SMoriah.Waterland@Sun.COM 
14069781SMoriah.Waterland@Sun.COM 	arg[nargs++] = "-N";
14079781SMoriah.Waterland@Sun.COM 	arg[nargs++] = get_prog_name();
14089781SMoriah.Waterland@Sun.COM 
14099781SMoriah.Waterland@Sun.COM 	/* add package instance name */
14109781SMoriah.Waterland@Sun.COM 
14119781SMoriah.Waterland@Sun.COM 	arg[nargs++] = pkginst;
14129781SMoriah.Waterland@Sun.COM 
14139781SMoriah.Waterland@Sun.COM 	/* terminate argument list */
14149781SMoriah.Waterland@Sun.COM 
14159781SMoriah.Waterland@Sun.COM 	arg[nargs++] = NULL;
14169781SMoriah.Waterland@Sun.COM 
14179781SMoriah.Waterland@Sun.COM 	/* execute pkgremove command */
14189781SMoriah.Waterland@Sun.COM 
14199781SMoriah.Waterland@Sun.COM 	if (debugFlag == B_TRUE) {
14209781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_ZONE_EXEC_ENTER, a_zoneName, arg[0]);
14219781SMoriah.Waterland@Sun.COM 		for (n = 0; arg[n]; n++) {
14229781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_ARG, n, arg[n]);
14239781SMoriah.Waterland@Sun.COM 		}
14249781SMoriah.Waterland@Sun.COM 	}
14259781SMoriah.Waterland@Sun.COM 
14269781SMoriah.Waterland@Sun.COM 	/* terminate file descriptor list */
14279781SMoriah.Waterland@Sun.COM 
14289781SMoriah.Waterland@Sun.COM 	fds[maxfds] = -1;
14299781SMoriah.Waterland@Sun.COM 
14309781SMoriah.Waterland@Sun.COM 	/* exec command in zone */
14319781SMoriah.Waterland@Sun.COM 
14329781SMoriah.Waterland@Sun.COM 	n = z_zone_exec(a_zoneName, path, arg, a_stdoutPath, (char *)NULL, fds);
14339781SMoriah.Waterland@Sun.COM 
14349781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_ZONE_EXEC_EXIT, a_zoneName, arg[0], n,
14359781SMoriah.Waterland@Sun.COM 			PSTR(a_stdoutPath));
14369781SMoriah.Waterland@Sun.COM 
14379781SMoriah.Waterland@Sun.COM 	/*
14389781SMoriah.Waterland@Sun.COM 	 * close any files that were opened for use by the
14399781SMoriah.Waterland@Sun.COM 	 * /proc/self/fd interface so they could be passed to programs
14409781SMoriah.Waterland@Sun.COM 	 * via the z_zone_exec() interface
14419781SMoriah.Waterland@Sun.COM 	 */
14429781SMoriah.Waterland@Sun.COM 
14439781SMoriah.Waterland@Sun.COM 	for (; maxfds > 0; maxfds--) {
14449781SMoriah.Waterland@Sun.COM 		(void) close(fds[maxfds-1]);
14459781SMoriah.Waterland@Sun.COM 	}
14469781SMoriah.Waterland@Sun.COM 
14479781SMoriah.Waterland@Sun.COM 	/* return results of pkgremove in zone execution */
14489781SMoriah.Waterland@Sun.COM 
14499781SMoriah.Waterland@Sun.COM 	return (n);
14509781SMoriah.Waterland@Sun.COM }
14519781SMoriah.Waterland@Sun.COM 
14529781SMoriah.Waterland@Sun.COM static int
14539781SMoriah.Waterland@Sun.COM pkgZoneRemove(char *a_zoneName, char **a_inheritedPkgDirs,
14549781SMoriah.Waterland@Sun.COM 	int a_nodelete, char *a_altBinDir, char *a_adminFile,
1455*9869SCasper.Dik@Sun.COM 	zone_state_t a_zoneState, boolean_t tmpzone)
14569781SMoriah.Waterland@Sun.COM {
14579781SMoriah.Waterland@Sun.COM 	char	*arg[MAXARGS];
14589781SMoriah.Waterland@Sun.COM 	char	*p;
14599781SMoriah.Waterland@Sun.COM 	char	adminfd_path[PATH_MAX];
14609781SMoriah.Waterland@Sun.COM 	char	path[PATH_MAX];
14619781SMoriah.Waterland@Sun.COM 	int	fds[MAX_FDS];
14629781SMoriah.Waterland@Sun.COM 	int	maxfds;
14639781SMoriah.Waterland@Sun.COM 	int	n;
14649781SMoriah.Waterland@Sun.COM 	int	nargs;
14659781SMoriah.Waterland@Sun.COM 
14669781SMoriah.Waterland@Sun.COM 	/* entry assertions */
14679781SMoriah.Waterland@Sun.COM 
14689781SMoriah.Waterland@Sun.COM 	assert(a_zoneName != (char *)NULL);
14699781SMoriah.Waterland@Sun.COM 	assert(*a_zoneName != '\0');
14709781SMoriah.Waterland@Sun.COM 
14719781SMoriah.Waterland@Sun.COM 	/* entry debugging info */
14729781SMoriah.Waterland@Sun.COM 
14739781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_PKGZONEREMOVE_ENTRY);
14749781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_PKGZONEREMOVE_ARGS, a_zoneName, PSTR(pkginst),
14759781SMoriah.Waterland@Sun.COM 		PSTR(pkgdev.dirname), a_nodelete, PSTR(a_adminFile));
14769781SMoriah.Waterland@Sun.COM 
14779781SMoriah.Waterland@Sun.COM 	/* generate path to pkgremove */
14789781SMoriah.Waterland@Sun.COM 
14799781SMoriah.Waterland@Sun.COM 	(void) snprintf(path, sizeof (path), "%s/pkgremove",
14809781SMoriah.Waterland@Sun.COM 		a_altBinDir == (char *)NULL ? PKGBIN : a_altBinDir);
14819781SMoriah.Waterland@Sun.COM 
14829781SMoriah.Waterland@Sun.COM 	/* start at first file descriptor */
14839781SMoriah.Waterland@Sun.COM 
14849781SMoriah.Waterland@Sun.COM 	maxfds = 0;
14859781SMoriah.Waterland@Sun.COM 
14869781SMoriah.Waterland@Sun.COM 	/*
14879781SMoriah.Waterland@Sun.COM 	 * generate argument list for call to pkgremove
14889781SMoriah.Waterland@Sun.COM 	 */
14899781SMoriah.Waterland@Sun.COM 
14909781SMoriah.Waterland@Sun.COM 	/* start at argument 0 */
14919781SMoriah.Waterland@Sun.COM 
14929781SMoriah.Waterland@Sun.COM 	nargs = 0;
14939781SMoriah.Waterland@Sun.COM 
14949781SMoriah.Waterland@Sun.COM 	/* first argument is path to executable */
14959781SMoriah.Waterland@Sun.COM 
14969781SMoriah.Waterland@Sun.COM 	arg[nargs++] = strdup(path);
14979781SMoriah.Waterland@Sun.COM 
14989781SMoriah.Waterland@Sun.COM 	/* second argument is always: pass -O debug to pkgremove: debug mode */
14999781SMoriah.Waterland@Sun.COM 
15009781SMoriah.Waterland@Sun.COM 	if (debugFlag == B_TRUE) {
15019781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-O";
15029781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "debug";
15039781SMoriah.Waterland@Sun.COM 	}
15049781SMoriah.Waterland@Sun.COM 
15059781SMoriah.Waterland@Sun.COM 	/* pkgrm -b dir: pass -b to pkgremove */
15069781SMoriah.Waterland@Sun.COM 
15079781SMoriah.Waterland@Sun.COM 	if (a_altBinDir != (char *)NULL) {
15089781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-b";
15099781SMoriah.Waterland@Sun.COM 		arg[nargs++] = a_altBinDir;
15109781SMoriah.Waterland@Sun.COM 	}
15119781SMoriah.Waterland@Sun.COM 
15129781SMoriah.Waterland@Sun.COM 	/*
15139781SMoriah.Waterland@Sun.COM 	 * NONABI_SCRIPTS defined: pass -o to pkgremove; refers to a
15149781SMoriah.Waterland@Sun.COM 	 * pkg requiring operator interaction during a procedure script
15159781SMoriah.Waterland@Sun.COM 	 * (common before on1093)
15169781SMoriah.Waterland@Sun.COM 	 */
15179781SMoriah.Waterland@Sun.COM 
15189781SMoriah.Waterland@Sun.COM 	if (old_pkg) {
15199781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-o";
15209781SMoriah.Waterland@Sun.COM 	}
15219781SMoriah.Waterland@Sun.COM 
15229781SMoriah.Waterland@Sun.COM 	/*
15239781SMoriah.Waterland@Sun.COM 	 * PKG_NONABI_SYMLINKS defined: pass -y to pkgremove; process
15249781SMoriah.Waterland@Sun.COM 	 * symlinks consistent with old behavior
15259781SMoriah.Waterland@Sun.COM 	 */
15269781SMoriah.Waterland@Sun.COM 
15279781SMoriah.Waterland@Sun.COM 	if (old_symlinks) {
15289781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-y";
15299781SMoriah.Waterland@Sun.COM 	}
15309781SMoriah.Waterland@Sun.COM 
15319781SMoriah.Waterland@Sun.COM 	/* pkgrm -M: pass -M to pkgremove: don't mount client file systems */
15329781SMoriah.Waterland@Sun.COM 
15339781SMoriah.Waterland@Sun.COM 	arg[nargs++] = "-M";
15349781SMoriah.Waterland@Sun.COM 
15359781SMoriah.Waterland@Sun.COM 	/* pkgrm -A: pass -A to pkgremove */
15369781SMoriah.Waterland@Sun.COM 
15379781SMoriah.Waterland@Sun.COM 	if (pkgrmremote) {
15389781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-A";
15399781SMoriah.Waterland@Sun.COM 	}
15409781SMoriah.Waterland@Sun.COM 
15419781SMoriah.Waterland@Sun.COM 	/* pkgrm -v: pass -v to pkgremove: trace scripts */
15429781SMoriah.Waterland@Sun.COM 
15439781SMoriah.Waterland@Sun.COM 	if (pkgverbose) {
15449781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-v";
15459781SMoriah.Waterland@Sun.COM 	}
15469781SMoriah.Waterland@Sun.COM 
15479781SMoriah.Waterland@Sun.COM 	/* pass "-O enable-hollow-package-support" */
15489781SMoriah.Waterland@Sun.COM 
15499781SMoriah.Waterland@Sun.COM 	if (is_depend_pkginfo_DB()) {
15509781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-O";
15519781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "enable-hollow-package-support";
15529781SMoriah.Waterland@Sun.COM 	}
15539781SMoriah.Waterland@Sun.COM 
15549781SMoriah.Waterland@Sun.COM 	/* pkgrm -n: pass -n to pkgremove: noninteractive mode */
15559781SMoriah.Waterland@Sun.COM 
15569781SMoriah.Waterland@Sun.COM 	if (nointeract) {
15579781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-n";
15589781SMoriah.Waterland@Sun.COM 	}
15599781SMoriah.Waterland@Sun.COM 
15609781SMoriah.Waterland@Sun.COM 	/* pkgrm -a admin: pass -a admin to pkgremove: admin file */
15619781SMoriah.Waterland@Sun.COM 
15629781SMoriah.Waterland@Sun.COM 	if (a_adminFile) {
15639781SMoriah.Waterland@Sun.COM 		int fd;
15649781SMoriah.Waterland@Sun.COM 		fd = openLocal(a_adminFile, O_RDONLY, tmpdir);
15659781SMoriah.Waterland@Sun.COM 		if (fd < 0) {
15669781SMoriah.Waterland@Sun.COM 			progerr(ERR_CANNOT_COPY_LOCAL, a_adminFile,
15679781SMoriah.Waterland@Sun.COM 				errno, strerror(errno));
15689781SMoriah.Waterland@Sun.COM 			return (1);
15699781SMoriah.Waterland@Sun.COM 		}
15709781SMoriah.Waterland@Sun.COM 		(void) snprintf(adminfd_path, sizeof (adminfd_path),
15719781SMoriah.Waterland@Sun.COM 			"/proc/self/fd/%d", fd);
15729781SMoriah.Waterland@Sun.COM 		fds[maxfds++] = fd;
15739781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-a";
15749781SMoriah.Waterland@Sun.COM 		arg[nargs++] = adminfd_path;
15759781SMoriah.Waterland@Sun.COM 	}
15769781SMoriah.Waterland@Sun.COM 
15779781SMoriah.Waterland@Sun.COM 	/*
15789781SMoriah.Waterland@Sun.COM 	 * pkgadd -R root: pass -R /a to pkgremove in mounted zone
15799781SMoriah.Waterland@Sun.COM 	 */
15809781SMoriah.Waterland@Sun.COM 	if (a_zoneState == ZONE_STATE_MOUNTED) {
15819781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-R";
15829781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "/a";
15839781SMoriah.Waterland@Sun.COM 	}
15849781SMoriah.Waterland@Sun.COM 
15859781SMoriah.Waterland@Sun.COM 	/* pkgrm -F: pass -F to pkgremove: update DB only */
15869781SMoriah.Waterland@Sun.COM 
15879781SMoriah.Waterland@Sun.COM 	if (a_nodelete) {
15889781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-F";
15899781SMoriah.Waterland@Sun.COM 	}
15909781SMoriah.Waterland@Sun.COM 
15919781SMoriah.Waterland@Sun.COM 	/* add "-O addzonename" */
15929781SMoriah.Waterland@Sun.COM 
15939781SMoriah.Waterland@Sun.COM 	arg[nargs++] = "-O";
15949781SMoriah.Waterland@Sun.COM 	arg[nargs++] = "addzonename";
15959781SMoriah.Waterland@Sun.COM 
15969781SMoriah.Waterland@Sun.COM 	/* add all inherited file systems */
15979781SMoriah.Waterland@Sun.COM 
15989781SMoriah.Waterland@Sun.COM 	if (a_inheritedPkgDirs != (char **)NULL) {
15999781SMoriah.Waterland@Sun.COM 		for (n = 0; a_inheritedPkgDirs[n] != (char *)NULL; n++) {
16009781SMoriah.Waterland@Sun.COM 			char	ifs[MAXPATHLEN+22];
16019781SMoriah.Waterland@Sun.COM 
16029781SMoriah.Waterland@Sun.COM 			(void) snprintf(ifs, sizeof (ifs),
16039781SMoriah.Waterland@Sun.COM 				"inherited-filesystem=%s",
16049781SMoriah.Waterland@Sun.COM 				a_inheritedPkgDirs[n]);
16059781SMoriah.Waterland@Sun.COM 			arg[nargs++] = "-O";
16069781SMoriah.Waterland@Sun.COM 			arg[nargs++] = strdup(ifs);
16079781SMoriah.Waterland@Sun.COM 		}
16089781SMoriah.Waterland@Sun.COM 	}
16099781SMoriah.Waterland@Sun.COM 
16109781SMoriah.Waterland@Sun.COM 	/*
16119781SMoriah.Waterland@Sun.COM 	 * add parent zone info/type
16129781SMoriah.Waterland@Sun.COM 	 */
16139781SMoriah.Waterland@Sun.COM 
16149781SMoriah.Waterland@Sun.COM 	p = z_get_zonename();
16159781SMoriah.Waterland@Sun.COM 	if ((p != NULL) && (*p != '\0')) {
16169781SMoriah.Waterland@Sun.COM 			char	zn[MAXPATHLEN];
16179781SMoriah.Waterland@Sun.COM 			(void) snprintf(zn, sizeof (zn),
16189781SMoriah.Waterland@Sun.COM 				"parent-zone-name=%s", p);
16199781SMoriah.Waterland@Sun.COM 			arg[nargs++] = "-O";
16209781SMoriah.Waterland@Sun.COM 			arg[nargs++] = strdup(zn);
16219781SMoriah.Waterland@Sun.COM 	}
16229781SMoriah.Waterland@Sun.COM 
16239781SMoriah.Waterland@Sun.COM 	/* current zone type */
16249781SMoriah.Waterland@Sun.COM 
16259781SMoriah.Waterland@Sun.COM 	arg[nargs++] = "-O";
16269781SMoriah.Waterland@Sun.COM 	if (z_running_in_global_zone() == B_TRUE) {
16279781SMoriah.Waterland@Sun.COM 			char	zn[MAXPATHLEN];
16289781SMoriah.Waterland@Sun.COM 			(void) snprintf(zn, sizeof (zn),
16299781SMoriah.Waterland@Sun.COM 				"parent-zone-type=%s",
16309781SMoriah.Waterland@Sun.COM 				TAG_VALUE_GLOBAL_ZONE);
16319781SMoriah.Waterland@Sun.COM 			arg[nargs++] = strdup(zn);
16329781SMoriah.Waterland@Sun.COM 	} else {
16339781SMoriah.Waterland@Sun.COM 			char	zn[MAXPATHLEN];
16349781SMoriah.Waterland@Sun.COM 			(void) snprintf(zn, sizeof (zn),
16359781SMoriah.Waterland@Sun.COM 				"parent-zone-type=%s",
16369781SMoriah.Waterland@Sun.COM 				TAG_VALUE_NONGLOBAL_ZONE);
16379781SMoriah.Waterland@Sun.COM 			arg[nargs++] = strdup(zn);
16389781SMoriah.Waterland@Sun.COM 	}
16399781SMoriah.Waterland@Sun.COM 
1640*9869SCasper.Dik@Sun.COM 	/* Add arguments how to start the pkgserv */
1641*9869SCasper.Dik@Sun.COM 
1642*9869SCasper.Dik@Sun.COM 	arg[nargs++] = "-O";
1643*9869SCasper.Dik@Sun.COM 	arg[nargs++] = pkgmodeargument(tmpzone ? RUN_ONCE : pkgservergetmode());
1644*9869SCasper.Dik@Sun.COM 
16459781SMoriah.Waterland@Sun.COM 	/* pass -N to pkgremove: program name to report */
16469781SMoriah.Waterland@Sun.COM 
16479781SMoriah.Waterland@Sun.COM 	arg[nargs++] = "-N";
16489781SMoriah.Waterland@Sun.COM 	arg[nargs++] = get_prog_name();
16499781SMoriah.Waterland@Sun.COM 
16509781SMoriah.Waterland@Sun.COM 	/* add package instance name */
16519781SMoriah.Waterland@Sun.COM 
16529781SMoriah.Waterland@Sun.COM 	arg[nargs++] = pkginst;
16539781SMoriah.Waterland@Sun.COM 
16549781SMoriah.Waterland@Sun.COM 	/* terminate argument list */
16559781SMoriah.Waterland@Sun.COM 
16569781SMoriah.Waterland@Sun.COM 	arg[nargs++] = NULL;
16579781SMoriah.Waterland@Sun.COM 
16589781SMoriah.Waterland@Sun.COM 	/* execute pkgremove command */
16599781SMoriah.Waterland@Sun.COM 
16609781SMoriah.Waterland@Sun.COM 	if (debugFlag == B_TRUE) {
16619781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_ZONE_EXEC_ENTER, a_zoneName, arg[0]);
16629781SMoriah.Waterland@Sun.COM 		for (n = 0; arg[n]; n++) {
16639781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_ARG, n, arg[n]);
16649781SMoriah.Waterland@Sun.COM 		}
16659781SMoriah.Waterland@Sun.COM 	}
16669781SMoriah.Waterland@Sun.COM 
16679781SMoriah.Waterland@Sun.COM 	/* terminate file descriptor list */
16689781SMoriah.Waterland@Sun.COM 
16699781SMoriah.Waterland@Sun.COM 	fds[maxfds] = -1;
16709781SMoriah.Waterland@Sun.COM 
16719781SMoriah.Waterland@Sun.COM 	/* exec command in zone */
16729781SMoriah.Waterland@Sun.COM 
16739781SMoriah.Waterland@Sun.COM 	n = z_zone_exec(a_zoneName, path, arg, (char *)NULL, (char *)NULL, fds);
16749781SMoriah.Waterland@Sun.COM 
16759781SMoriah.Waterland@Sun.COM 	/*
16769781SMoriah.Waterland@Sun.COM 	 * close any files that were opened for use by the
16779781SMoriah.Waterland@Sun.COM 	 * /proc/self/fd interface so they could be passed to programs
16789781SMoriah.Waterland@Sun.COM 	 * via the z_zone_exec() interface
16799781SMoriah.Waterland@Sun.COM 	 */
16809781SMoriah.Waterland@Sun.COM 
16819781SMoriah.Waterland@Sun.COM 	for (; maxfds > 0; maxfds--) {
16829781SMoriah.Waterland@Sun.COM 		(void) close(fds[maxfds-1]);
16839781SMoriah.Waterland@Sun.COM 	}
16849781SMoriah.Waterland@Sun.COM 
16859781SMoriah.Waterland@Sun.COM 	return (n);
16869781SMoriah.Waterland@Sun.COM }
16879781SMoriah.Waterland@Sun.COM 
16889781SMoriah.Waterland@Sun.COM /*
16899781SMoriah.Waterland@Sun.COM  * Name:	pkgRemove
16909781SMoriah.Waterland@Sun.COM  * Description:	Invoke pkgremove in the current zone to perform a remove
16919781SMoriah.Waterland@Sun.COM  *		of a single package from the current zone or standalone system
16929781SMoriah.Waterland@Sun.COM  * Arguments:	a_nodelete: should the files and scripts remain installed?
16939781SMoriah.Waterland@Sun.COM  *			- if != 0 pass -F flag to pkgremove - suppress
16949781SMoriah.Waterland@Sun.COM  *			the removal of any files and any class action scripts
16959781SMoriah.Waterland@Sun.COM  *			and suppress the running of any class action scripts.
16969781SMoriah.Waterland@Sun.COM  *			The package files remain but the package looks like it
16979781SMoriah.Waterland@Sun.COM  *			is not installed. This is mainly for use by upgrade.
16989781SMoriah.Waterland@Sun.COM  *			- if == 0 do not pass -F flag to pkgremove - all
16999781SMoriah.Waterland@Sun.COM  *			files and class action scripts are removed, and any
17009781SMoriah.Waterland@Sun.COM  *			appropriate class action scripts are run.
17019781SMoriah.Waterland@Sun.COM  *		a_altBinDir - pointer to string representing location of the
17029781SMoriah.Waterland@Sun.COM  *			pkgremove executable to run. If not NULL, then pass
17039781SMoriah.Waterland@Sun.COM  *			the path specified to the -b option to pkgremove.
17049781SMoriah.Waterland@Sun.COM  *		a_adminFile - pointer to string representing the admin
17059781SMoriah.Waterland@Sun.COM  *			file to pass to pkgremove when removing the package.
17069781SMoriah.Waterland@Sun.COM  *			If this is == NULL no admin file is given to pkgremove.
17079781SMoriah.Waterland@Sun.COM  *		a_inheritedPkgDirs - pointer to array of strings, each one
17089781SMoriah.Waterland@Sun.COM  *			representing the non-global zones full path of a
17099781SMoriah.Waterland@Sun.COM  *			directory that is inherited from the global zone.
17109781SMoriah.Waterland@Sun.COM  * Returns:	int	(see ckreturn() function for details)
17119781SMoriah.Waterland@Sun.COM  *		0 - success
17129781SMoriah.Waterland@Sun.COM  *		1 - package operation failed (fatal error)
17139781SMoriah.Waterland@Sun.COM  *		2 - non-fatal error (warning)
17149781SMoriah.Waterland@Sun.COM  *		3 - user selected quit (operation interrupted)
17159781SMoriah.Waterland@Sun.COM  *		4 - admin settings prevented operation
17169781SMoriah.Waterland@Sun.COM  *		5 - interaction required and -n (non-interactive) specified
17179781SMoriah.Waterland@Sun.COM  *		"10" will be added to indicate "immediate reboot required"
17189781SMoriah.Waterland@Sun.COM  *		"20" will be added to indicate "reboot after install required"
17199781SMoriah.Waterland@Sun.COM  */
17209781SMoriah.Waterland@Sun.COM 
17219781SMoriah.Waterland@Sun.COM static int
17229781SMoriah.Waterland@Sun.COM pkgRemove(int a_nodelete, char *a_altBinDir, char *a_adminFile,
17239781SMoriah.Waterland@Sun.COM 	char **a_inheritedPkgDirs)
17249781SMoriah.Waterland@Sun.COM {
17259781SMoriah.Waterland@Sun.COM 	char	*arg[MAXARGS];
17269781SMoriah.Waterland@Sun.COM 	char	*p;
17279781SMoriah.Waterland@Sun.COM 	char	path[PATH_MAX];
17289781SMoriah.Waterland@Sun.COM 	int	n;
17299781SMoriah.Waterland@Sun.COM 	int	nargs;
17309781SMoriah.Waterland@Sun.COM 
17319781SMoriah.Waterland@Sun.COM 	/* entry debugging info */
17329781SMoriah.Waterland@Sun.COM 
17339781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_PKGREMOVE_ENTRY);
17349781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_PKGREMOVE_ARGS, PSTR(pkginst), PSTR(pkgdev.dirname),
17359781SMoriah.Waterland@Sun.COM 		a_nodelete, PSTR(a_adminFile));
17369781SMoriah.Waterland@Sun.COM 
17379781SMoriah.Waterland@Sun.COM 	(void) snprintf(path, sizeof (path), "%s/pkgremove",
17389781SMoriah.Waterland@Sun.COM 		a_altBinDir == (char *)NULL ? PKGBIN : a_altBinDir);
17399781SMoriah.Waterland@Sun.COM 
17409781SMoriah.Waterland@Sun.COM 	nargs = 0;
17419781SMoriah.Waterland@Sun.COM 
17429781SMoriah.Waterland@Sun.COM 	/* first argument is path to executable */
17439781SMoriah.Waterland@Sun.COM 
17449781SMoriah.Waterland@Sun.COM 	arg[nargs++] = strdup(path);
17459781SMoriah.Waterland@Sun.COM 
17469781SMoriah.Waterland@Sun.COM 	/* second argument is always: pass -O debug to pkgremove: debug mode */
17479781SMoriah.Waterland@Sun.COM 
17489781SMoriah.Waterland@Sun.COM 	if (debugFlag == B_TRUE) {
17499781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-O";
17509781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "debug";
17519781SMoriah.Waterland@Sun.COM 	}
17529781SMoriah.Waterland@Sun.COM 
1753*9869SCasper.Dik@Sun.COM 	/* Add arguments how to start the pkgserv */
1754*9869SCasper.Dik@Sun.COM 
1755*9869SCasper.Dik@Sun.COM 	arg[nargs++] = "-O";
1756*9869SCasper.Dik@Sun.COM 	arg[nargs++] = pkgmodeargument(pkgservergetmode());
1757*9869SCasper.Dik@Sun.COM 
17589781SMoriah.Waterland@Sun.COM 	/* pkgrm -b dir: pass -b to pkgremove */
17599781SMoriah.Waterland@Sun.COM 
17609781SMoriah.Waterland@Sun.COM 	if (a_altBinDir != (char *)NULL) {
17619781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-b";
17629781SMoriah.Waterland@Sun.COM 		arg[nargs++] = a_altBinDir;
17639781SMoriah.Waterland@Sun.COM 	}
17649781SMoriah.Waterland@Sun.COM 
17659781SMoriah.Waterland@Sun.COM 	/*
17669781SMoriah.Waterland@Sun.COM 	 * NONABI_SCRIPTS defined: pass -o to pkgremove; refers to a
17679781SMoriah.Waterland@Sun.COM 	 * pkg requiring operator interaction during a procedure script
17689781SMoriah.Waterland@Sun.COM 	 * (common before on1093)
17699781SMoriah.Waterland@Sun.COM 	 */
17709781SMoriah.Waterland@Sun.COM 
17719781SMoriah.Waterland@Sun.COM 	if (old_pkg) {
17729781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-o";
17739781SMoriah.Waterland@Sun.COM 	}
17749781SMoriah.Waterland@Sun.COM 
17759781SMoriah.Waterland@Sun.COM 	/*
17769781SMoriah.Waterland@Sun.COM 	 * PKG_NONABI_SYMLINKS defined: pass -y to pkgremove; process
17779781SMoriah.Waterland@Sun.COM 	 * symlinks consistent with old behavior
17789781SMoriah.Waterland@Sun.COM 	 */
17799781SMoriah.Waterland@Sun.COM 
17809781SMoriah.Waterland@Sun.COM 	if (old_symlinks) {
17819781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-y";
17829781SMoriah.Waterland@Sun.COM 	}
17839781SMoriah.Waterland@Sun.COM 
17849781SMoriah.Waterland@Sun.COM 	/* pkgrm -M: pass -M to pkgrm: dont mount client file systems */
17859781SMoriah.Waterland@Sun.COM 
17869781SMoriah.Waterland@Sun.COM 	if (no_map_client) {
17879781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-M";
17889781SMoriah.Waterland@Sun.COM 	}
17899781SMoriah.Waterland@Sun.COM 
17909781SMoriah.Waterland@Sun.COM 	/* pkgrm -A: pass -A to pkgrm */
17919781SMoriah.Waterland@Sun.COM 
17929781SMoriah.Waterland@Sun.COM 	if (pkgrmremote) {
17939781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-A";
17949781SMoriah.Waterland@Sun.COM 	}
17959781SMoriah.Waterland@Sun.COM 
17969781SMoriah.Waterland@Sun.COM 	/* pkgrm -v: pass -v to pkgremove: trace scripts */
17979781SMoriah.Waterland@Sun.COM 
17989781SMoriah.Waterland@Sun.COM 	if (pkgverbose) {
17999781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-v";
18009781SMoriah.Waterland@Sun.COM 	}
18019781SMoriah.Waterland@Sun.COM 
18029781SMoriah.Waterland@Sun.COM 	/* pkgrm -n: pass -n to pkgremove: noninteractive mode */
18039781SMoriah.Waterland@Sun.COM 
18049781SMoriah.Waterland@Sun.COM 	if (nointeract) {
18059781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-n";
18069781SMoriah.Waterland@Sun.COM 	}
18079781SMoriah.Waterland@Sun.COM 
18089781SMoriah.Waterland@Sun.COM 	/* pkgrm -a admin: pass -a admin to pkgremove: admin file */
18099781SMoriah.Waterland@Sun.COM 
18109781SMoriah.Waterland@Sun.COM 	if (a_adminFile) {
18119781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-a";
18129781SMoriah.Waterland@Sun.COM 		arg[nargs++] = strdup(a_adminFile);
18139781SMoriah.Waterland@Sun.COM 	}
18149781SMoriah.Waterland@Sun.COM 
18159781SMoriah.Waterland@Sun.COM 	/* pkgrm -V vfstab: pass -V vfstab to pkgremove: alternate vfstab */
18169781SMoriah.Waterland@Sun.COM 
18179781SMoriah.Waterland@Sun.COM 	if (vfstab_file) {
18189781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-V";
18199781SMoriah.Waterland@Sun.COM 		arg[nargs++] = vfstab_file;
18209781SMoriah.Waterland@Sun.COM 	}
18219781SMoriah.Waterland@Sun.COM 
18229781SMoriah.Waterland@Sun.COM 	/* pkgrm -R root: pass -R root to pkgremove: alternative root */
18239781SMoriah.Waterland@Sun.COM 
18249781SMoriah.Waterland@Sun.COM 	if (is_an_inst_root()) {
18259781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-R";
18269781SMoriah.Waterland@Sun.COM 		arg[nargs++] = get_inst_root();
18279781SMoriah.Waterland@Sun.COM 	}
18289781SMoriah.Waterland@Sun.COM 
18299781SMoriah.Waterland@Sun.COM 	/* pkgrm -F: pass -F to pkgremove: update DB only */
18309781SMoriah.Waterland@Sun.COM 
18319781SMoriah.Waterland@Sun.COM 	if (a_nodelete) {
18329781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-F";
18339781SMoriah.Waterland@Sun.COM 	}
18349781SMoriah.Waterland@Sun.COM 
18359781SMoriah.Waterland@Sun.COM 	/* add all inherited file systems */
18369781SMoriah.Waterland@Sun.COM 
18379781SMoriah.Waterland@Sun.COM 	if (a_inheritedPkgDirs != (char **)NULL) {
18389781SMoriah.Waterland@Sun.COM 		for (n = 0; a_inheritedPkgDirs[n] != (char *)NULL; n++) {
18399781SMoriah.Waterland@Sun.COM 			char	ifs[MAXPATHLEN+22];
18409781SMoriah.Waterland@Sun.COM 			(void) snprintf(ifs, sizeof (ifs),
18419781SMoriah.Waterland@Sun.COM 				"inherited-filesystem=%s",
18429781SMoriah.Waterland@Sun.COM 				a_inheritedPkgDirs[n]);
18439781SMoriah.Waterland@Sun.COM 			arg[nargs++] = "-O";
18449781SMoriah.Waterland@Sun.COM 			arg[nargs++] = strdup(ifs);
18459781SMoriah.Waterland@Sun.COM 		}
18469781SMoriah.Waterland@Sun.COM 	}
18479781SMoriah.Waterland@Sun.COM 
18489781SMoriah.Waterland@Sun.COM 	/*
18499781SMoriah.Waterland@Sun.COM 	 * add parent zone info/type
18509781SMoriah.Waterland@Sun.COM 	 */
18519781SMoriah.Waterland@Sun.COM 
18529781SMoriah.Waterland@Sun.COM 	p = z_get_zonename();
18539781SMoriah.Waterland@Sun.COM 	if ((p != NULL) && (*p != '\0')) {
18549781SMoriah.Waterland@Sun.COM 			char	zn[MAXPATHLEN];
18559781SMoriah.Waterland@Sun.COM 			(void) snprintf(zn, sizeof (zn),
18569781SMoriah.Waterland@Sun.COM 				"parent-zone-name=%s", p);
18579781SMoriah.Waterland@Sun.COM 			arg[nargs++] = "-O";
18589781SMoriah.Waterland@Sun.COM 			arg[nargs++] = strdup(zn);
18599781SMoriah.Waterland@Sun.COM 	}
18609781SMoriah.Waterland@Sun.COM 
18619781SMoriah.Waterland@Sun.COM 	/* current zone type */
18629781SMoriah.Waterland@Sun.COM 
18639781SMoriah.Waterland@Sun.COM 	arg[nargs++] = "-O";
18649781SMoriah.Waterland@Sun.COM 	if (z_running_in_global_zone() == B_TRUE) {
18659781SMoriah.Waterland@Sun.COM 			char	zn[MAXPATHLEN];
18669781SMoriah.Waterland@Sun.COM 			(void) snprintf(zn, sizeof (zn),
18679781SMoriah.Waterland@Sun.COM 				"parent-zone-type=%s",
18689781SMoriah.Waterland@Sun.COM 				TAG_VALUE_GLOBAL_ZONE);
18699781SMoriah.Waterland@Sun.COM 			arg[nargs++] = strdup(zn);
18709781SMoriah.Waterland@Sun.COM 	} else {
18719781SMoriah.Waterland@Sun.COM 			char	zn[MAXPATHLEN];
18729781SMoriah.Waterland@Sun.COM 			(void) snprintf(zn, sizeof (zn),
18739781SMoriah.Waterland@Sun.COM 				"parent-zone-type=%s",
18749781SMoriah.Waterland@Sun.COM 				TAG_VALUE_NONGLOBAL_ZONE);
18759781SMoriah.Waterland@Sun.COM 			arg[nargs++] = strdup(zn);
18769781SMoriah.Waterland@Sun.COM 	}
18779781SMoriah.Waterland@Sun.COM 
18789781SMoriah.Waterland@Sun.COM 	/* pass -N to pkgremove: program name to report */
18799781SMoriah.Waterland@Sun.COM 
18809781SMoriah.Waterland@Sun.COM 	arg[nargs++] = "-N";
18819781SMoriah.Waterland@Sun.COM 	arg[nargs++] = get_prog_name();
18829781SMoriah.Waterland@Sun.COM 
18839781SMoriah.Waterland@Sun.COM 	/* add package instance name */
18849781SMoriah.Waterland@Sun.COM 
18859781SMoriah.Waterland@Sun.COM 	arg[nargs++] = pkginst;
18869781SMoriah.Waterland@Sun.COM 
18879781SMoriah.Waterland@Sun.COM 	/* terminate argument list */
18889781SMoriah.Waterland@Sun.COM 
18899781SMoriah.Waterland@Sun.COM 	arg[nargs++] = NULL;
18909781SMoriah.Waterland@Sun.COM 
18919781SMoriah.Waterland@Sun.COM 	/*
18929781SMoriah.Waterland@Sun.COM 	 * run the appropriate pkgremove command in the specified zone
18939781SMoriah.Waterland@Sun.COM 	 */
18949781SMoriah.Waterland@Sun.COM 
18959781SMoriah.Waterland@Sun.COM 	if (debugFlag == B_TRUE) {
18969781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_ZONE_EXEC_ENTER, "global", arg[0]);
18979781SMoriah.Waterland@Sun.COM 		for (n = 0; arg[n]; n++) {
18989781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_ARG, n, arg[n]);
18999781SMoriah.Waterland@Sun.COM 		}
19009781SMoriah.Waterland@Sun.COM 	}
19019781SMoriah.Waterland@Sun.COM 
19029781SMoriah.Waterland@Sun.COM 	/* execute pkgremove command */
19039781SMoriah.Waterland@Sun.COM 
19049781SMoriah.Waterland@Sun.COM 	n = pkgexecv(NULL, NULL, NULL, NULL, arg);
19059781SMoriah.Waterland@Sun.COM 
19069781SMoriah.Waterland@Sun.COM 	/* return results of pkgrm in this zone */
19079781SMoriah.Waterland@Sun.COM 
19089781SMoriah.Waterland@Sun.COM 	return (n);
19099781SMoriah.Waterland@Sun.COM }
19109781SMoriah.Waterland@Sun.COM 
19119781SMoriah.Waterland@Sun.COM static void
19129781SMoriah.Waterland@Sun.COM usage(void)
19139781SMoriah.Waterland@Sun.COM {
19149781SMoriah.Waterland@Sun.COM 	char	*prog = get_prog_name();
19159781SMoriah.Waterland@Sun.COM 
19169781SMoriah.Waterland@Sun.COM 	(void) fprintf(stderr, ERR_USAGE_PKGRM, prog, prog);
19179781SMoriah.Waterland@Sun.COM 	exit(1);
19189781SMoriah.Waterland@Sun.COM }
19199781SMoriah.Waterland@Sun.COM 
19209781SMoriah.Waterland@Sun.COM /*
19219781SMoriah.Waterland@Sun.COM  * Name:	remove_packages_in_global_with_zones
19229781SMoriah.Waterland@Sun.COM  * Description:	Remove packages from the global zone and from non-global zones
19239781SMoriah.Waterland@Sun.COM  *		when run from the global zone and when non-global zones are
19249781SMoriah.Waterland@Sun.COM  *		present.
19259781SMoriah.Waterland@Sun.COM  * Arguments:	a_pkgList - pointer to array of strings, each string specifying
19269781SMoriah.Waterland@Sun.COM  *			the name of one package to be removed.
19279781SMoriah.Waterland@Sun.COM  *		a_nodelete: should the files and scripts remain installed?
19289781SMoriah.Waterland@Sun.COM  *			- if != 0 pass -F flag to pkgremove - suppress
19299781SMoriah.Waterland@Sun.COM  *			the removal of any files and any class action scripts
19309781SMoriah.Waterland@Sun.COM  *			and suppress the running of any class action scripts.
19319781SMoriah.Waterland@Sun.COM  *			The package files remain but the package looks like it
19329781SMoriah.Waterland@Sun.COM  *			is not installed. This is mainly for use by upgrade.
19339781SMoriah.Waterland@Sun.COM  *			- if == 0 do not pass -F flag to pkgremove - all
19349781SMoriah.Waterland@Sun.COM  *			files and class action scripts are removed, and any
19359781SMoriah.Waterland@Sun.COM  *			appropriate class action scripts are run.
19369781SMoriah.Waterland@Sun.COM  *		a_longestPkg - length of the longest package "name" (for
19379781SMoriah.Waterland@Sun.COM  *			output format alignment)
19389781SMoriah.Waterland@Sun.COM  *		a_repeat - are there more packages avialable in "optind"
19399781SMoriah.Waterland@Sun.COM  *			- B_TRUE - process packages from optind
19409781SMoriah.Waterland@Sun.COM  *			- B_FALSE - do not process packages from optind
19419781SMoriah.Waterland@Sun.COM  *		a_altBinDir - pointer to string representing location of the
19429781SMoriah.Waterland@Sun.COM  *			pkgremove executable to run. If not NULL, then pass
19439781SMoriah.Waterland@Sun.COM  *			the path specified to the -b option to pkgremove.
19449781SMoriah.Waterland@Sun.COM  *		a_pkgdir - pointer to string representing the directory
19459781SMoriah.Waterland@Sun.COM  *			where the packages to be removed are located.
19469781SMoriah.Waterland@Sun.COM  *		a_zlst - list of zones to process; NULL if no zones to process.
19479781SMoriah.Waterland@Sun.COM  * Returns:	int	(see ckreturn() function for details)
19489781SMoriah.Waterland@Sun.COM  *		0 - success
19499781SMoriah.Waterland@Sun.COM  *		1 - package operation failed (fatal error)
19509781SMoriah.Waterland@Sun.COM  *		2 - non-fatal error (warning)
19519781SMoriah.Waterland@Sun.COM  *		3 - user selected quit (operation interrupted)
19529781SMoriah.Waterland@Sun.COM  *		4 - admin settings prevented operation
19539781SMoriah.Waterland@Sun.COM  *		5 - interaction required and -n (non-interactive) specified
19549781SMoriah.Waterland@Sun.COM  *		"10" will be added to indicate "immediate reboot required"
19559781SMoriah.Waterland@Sun.COM  *		"20" will be added to indicate "reboot after install required"
19569781SMoriah.Waterland@Sun.COM  */
19579781SMoriah.Waterland@Sun.COM 
19589781SMoriah.Waterland@Sun.COM static boolean_t
19599781SMoriah.Waterland@Sun.COM remove_packages_in_global_with_zones(char **a_pkgList, int a_nodelete,
19609781SMoriah.Waterland@Sun.COM 	int a_longestPkg, int a_repeat, char *a_altBinDir, char *a_pkgdir,
19619781SMoriah.Waterland@Sun.COM 	zoneList_t a_zlst)
19629781SMoriah.Waterland@Sun.COM {
19639781SMoriah.Waterland@Sun.COM static	char		*zoneAdminFile = (char *)NULL;
19649781SMoriah.Waterland@Sun.COM 
19659781SMoriah.Waterland@Sun.COM 	boolean_t	b;
19669781SMoriah.Waterland@Sun.COM 	char		**inheritedPkgDirs;
19679781SMoriah.Waterland@Sun.COM 	char		*zoneName;
19689781SMoriah.Waterland@Sun.COM 	char		*scratchName;
19699781SMoriah.Waterland@Sun.COM 	char		preremovecheckPath[PATH_MAX+1];
19709781SMoriah.Waterland@Sun.COM 	int		i;
19719781SMoriah.Waterland@Sun.COM 	int		n;
19729781SMoriah.Waterland@Sun.COM 	int		savenpkgs = npkgs;
19739781SMoriah.Waterland@Sun.COM 	int		zoneIndex;
19749781SMoriah.Waterland@Sun.COM 	int		zonesSkipped;
19759781SMoriah.Waterland@Sun.COM 	zone_state_t	zst;
19769781SMoriah.Waterland@Sun.COM 
19779781SMoriah.Waterland@Sun.COM 	/* entry assertions */
19789781SMoriah.Waterland@Sun.COM 
19799781SMoriah.Waterland@Sun.COM 	assert(a_zlst != (zoneList_t)NULL);
19809781SMoriah.Waterland@Sun.COM 	assert(a_pkgList != (char **)NULL);
19819781SMoriah.Waterland@Sun.COM 	assert(a_longestPkg > 0);
19829781SMoriah.Waterland@Sun.COM 	assert(a_pkgdir != (char *)NULL);
19839781SMoriah.Waterland@Sun.COM 	assert(*a_pkgdir != '\0');
19849781SMoriah.Waterland@Sun.COM 
19859781SMoriah.Waterland@Sun.COM 	/* entry debugging info */
19869781SMoriah.Waterland@Sun.COM 
19879781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_PKGREMPKGSGZWNGZ_ENTRY);
19889781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_PKGREMPKGSGZWNGZ_ARGS, a_nodelete, a_longestPkg,
19899781SMoriah.Waterland@Sun.COM 		a_repeat, PSTR(a_altBinDir), PSTR(a_pkgdir));
19909781SMoriah.Waterland@Sun.COM 
19919781SMoriah.Waterland@Sun.COM 	/* check all packages */
19929781SMoriah.Waterland@Sun.COM 
19939781SMoriah.Waterland@Sun.COM 	if (check_packages(a_pkgList, a_pkgdir) != B_TRUE) {
19949781SMoriah.Waterland@Sun.COM 		quit(1);
19959781SMoriah.Waterland@Sun.COM 	}
19969781SMoriah.Waterland@Sun.COM 
19979781SMoriah.Waterland@Sun.COM 	/* create temporary directory for use by zone operations */
19989781SMoriah.Waterland@Sun.COM 
19999781SMoriah.Waterland@Sun.COM 	create_zone_tempdir(&zoneTempDir, tmpdir);
20009781SMoriah.Waterland@Sun.COM 
20019781SMoriah.Waterland@Sun.COM 	/* create hands off settings admin file for use in a non-global zone */
20029781SMoriah.Waterland@Sun.COM 
20039781SMoriah.Waterland@Sun.COM 	create_zone_adminfile(&zoneAdminFile, zoneTempDir, admnfile);
20049781SMoriah.Waterland@Sun.COM 
20059781SMoriah.Waterland@Sun.COM 	/*
20069781SMoriah.Waterland@Sun.COM 	 * all of the packages (as listed in the package list) are
20079781SMoriah.Waterland@Sun.COM 	 * removed one at a time from all non-global zones and then
20089781SMoriah.Waterland@Sun.COM 	 * from the global zone.
20099781SMoriah.Waterland@Sun.COM 	 */
20109781SMoriah.Waterland@Sun.COM 
20119781SMoriah.Waterland@Sun.COM 	for (i = 0; (pkginst = a_pkgList[i]) != NULL; i++) {
20129781SMoriah.Waterland@Sun.COM 		/* reset interrupted flag before calling pkgremove */
20139781SMoriah.Waterland@Sun.COM 
20149781SMoriah.Waterland@Sun.COM 		interrupted = 0;	/* last action was NOT quit */
20159781SMoriah.Waterland@Sun.COM 
20169781SMoriah.Waterland@Sun.COM 		/* skip package if it is "in the global zone only" */
20179781SMoriah.Waterland@Sun.COM 
20189781SMoriah.Waterland@Sun.COM 		if (pkgIsPkgInGzOnly(get_inst_root(), pkginst) == B_TRUE) {
20199781SMoriah.Waterland@Sun.COM 			continue;
20209781SMoriah.Waterland@Sun.COM 		}
20219781SMoriah.Waterland@Sun.COM 
20229781SMoriah.Waterland@Sun.COM 		/*
20239781SMoriah.Waterland@Sun.COM 		 * if operation failed in global zone do not propagate to
20249781SMoriah.Waterland@Sun.COM 		 * non-global zones
20259781SMoriah.Waterland@Sun.COM 		 */
20269781SMoriah.Waterland@Sun.COM 
20279781SMoriah.Waterland@Sun.COM 		zonesSkipped = 0;
20289781SMoriah.Waterland@Sun.COM 
20299781SMoriah.Waterland@Sun.COM 		if (interrupted != 0) {
20309781SMoriah.Waterland@Sun.COM 			echo(MSG_DOREMOVE_INTERRUPTED, pkginst);
20319781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_DOREMOVE_INTERRUPTED, pkginst);
20329781SMoriah.Waterland@Sun.COM 			break;
20339781SMoriah.Waterland@Sun.COM 		}
20349781SMoriah.Waterland@Sun.COM 
20359781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_REMOVE_FLAG_VALUES, "before loop",
20369781SMoriah.Waterland@Sun.COM 			admnflag, doreboot, failflag, interrupted,
20379781SMoriah.Waterland@Sun.COM 			intrflag, ireboot, nullflag, warnflag);
20389781SMoriah.Waterland@Sun.COM 
20399781SMoriah.Waterland@Sun.COM 		for (zoneIndex = 0;
20409781SMoriah.Waterland@Sun.COM 			(zoneName = z_zlist_get_zonename(a_zlst, zoneIndex)) !=
20419781SMoriah.Waterland@Sun.COM 				(char *)NULL; zoneIndex++) {
20429781SMoriah.Waterland@Sun.COM 
20439781SMoriah.Waterland@Sun.COM 			/* skip the zone if it is NOT running */
20449781SMoriah.Waterland@Sun.COM 
20459781SMoriah.Waterland@Sun.COM 			zst = z_zlist_get_current_state(a_zlst, zoneIndex);
20469781SMoriah.Waterland@Sun.COM 			if (zst != ZONE_STATE_RUNNING &&
20479781SMoriah.Waterland@Sun.COM 			    zst != ZONE_STATE_MOUNTED) {
20489781SMoriah.Waterland@Sun.COM 				zonesSkipped++;
20499781SMoriah.Waterland@Sun.COM 				echoDebug(DBG_SKIPPING_ZONE, zoneName);
20509781SMoriah.Waterland@Sun.COM 				continue;
20519781SMoriah.Waterland@Sun.COM 			}
20529781SMoriah.Waterland@Sun.COM 
20539781SMoriah.Waterland@Sun.COM 			echo(MSG_CHECKREMOVE_PKG_IN_ZONE, pkginst, zoneName);
20549781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_CHECKREMOVE_PKG_IN_ZONE, pkginst,
20559781SMoriah.Waterland@Sun.COM 				zoneName);
20569781SMoriah.Waterland@Sun.COM 
20579781SMoriah.Waterland@Sun.COM 			scratchName = z_zlist_get_scratch(a_zlst, zoneIndex);
20589781SMoriah.Waterland@Sun.COM 
20599781SMoriah.Waterland@Sun.COM 			(void) snprintf(preremovecheckPath,
20609781SMoriah.Waterland@Sun.COM 				sizeof (preremovecheckPath),
20619781SMoriah.Waterland@Sun.COM 				"%s/%s.%s.preremovecheck.txt",
20629781SMoriah.Waterland@Sun.COM 				zoneTempDir, pkginst, scratchName);
20639781SMoriah.Waterland@Sun.COM 
20649781SMoriah.Waterland@Sun.COM 			/* determine list of dirs inherited from global zone */
20659781SMoriah.Waterland@Sun.COM 
20669781SMoriah.Waterland@Sun.COM 			inheritedPkgDirs =
20679781SMoriah.Waterland@Sun.COM 				z_zlist_get_inherited_pkg_dirs(a_zlst,
20689781SMoriah.Waterland@Sun.COM 					zoneIndex);
20699781SMoriah.Waterland@Sun.COM 
20709781SMoriah.Waterland@Sun.COM 			/*
20719781SMoriah.Waterland@Sun.COM 			 * dependency check this package this zone; use the
20729781SMoriah.Waterland@Sun.COM 			 * user supplied admin file so that the appropriate
20739781SMoriah.Waterland@Sun.COM 			 * level of dependency checking is (or is not) done.
20749781SMoriah.Waterland@Sun.COM 			 */
20759781SMoriah.Waterland@Sun.COM 
20769781SMoriah.Waterland@Sun.COM 			n = pkgZoneCheckRemove(scratchName, inheritedPkgDirs,
20779781SMoriah.Waterland@Sun.COM 				a_altBinDir, admnfile, preremovecheckPath,
2078*9869SCasper.Dik@Sun.COM 				zst, B_FALSE);
20799781SMoriah.Waterland@Sun.COM 
20809781SMoriah.Waterland@Sun.COM 			/* set success/fail condition variables */
20819781SMoriah.Waterland@Sun.COM 
20829781SMoriah.Waterland@Sun.COM 			ckreturn(n);
20839781SMoriah.Waterland@Sun.COM 
20849781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_REMOVE_FLAG_VALUES,
20859781SMoriah.Waterland@Sun.COM 				"after pkgzonecheckremove",
20869781SMoriah.Waterland@Sun.COM 				admnflag, doreboot, failflag, interrupted,
20879781SMoriah.Waterland@Sun.COM 				intrflag, ireboot, nullflag, warnflag);
20889781SMoriah.Waterland@Sun.COM 		}
20899781SMoriah.Waterland@Sun.COM 
20909781SMoriah.Waterland@Sun.COM 		if (zonesSkipped == 0) {
20919781SMoriah.Waterland@Sun.COM 			continue;
20929781SMoriah.Waterland@Sun.COM 		}
20939781SMoriah.Waterland@Sun.COM 
20949781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_ZONES_SKIPPED, zonesSkipped);
20959781SMoriah.Waterland@Sun.COM 
20969781SMoriah.Waterland@Sun.COM 		for (zoneIndex = 0;
20979781SMoriah.Waterland@Sun.COM 			(zoneName = z_zlist_get_zonename(a_zlst, zoneIndex)) !=
20989781SMoriah.Waterland@Sun.COM 				(char *)NULL; zoneIndex++) {
20999781SMoriah.Waterland@Sun.COM 
21009781SMoriah.Waterland@Sun.COM 			/* skip the zone if it IS running */
21019781SMoriah.Waterland@Sun.COM 
21029781SMoriah.Waterland@Sun.COM 			zst = z_zlist_get_current_state(a_zlst, zoneIndex);
21039781SMoriah.Waterland@Sun.COM 			if (zst == ZONE_STATE_RUNNING ||
21049781SMoriah.Waterland@Sun.COM 			    zst == ZONE_STATE_MOUNTED) {
21059781SMoriah.Waterland@Sun.COM 				zonesSkipped++;
21069781SMoriah.Waterland@Sun.COM 				echoDebug(DBG_SKIPPING_ZONE_BOOT, zoneName);
21079781SMoriah.Waterland@Sun.COM 				continue;
21089781SMoriah.Waterland@Sun.COM 			}
21099781SMoriah.Waterland@Sun.COM 
21109781SMoriah.Waterland@Sun.COM 			/* skip the zone if it is NOT bootable */
21119781SMoriah.Waterland@Sun.COM 
21129781SMoriah.Waterland@Sun.COM 			if (z_zlist_is_zone_runnable(a_zlst,
21139781SMoriah.Waterland@Sun.COM 						zoneIndex) == B_FALSE) {
21149781SMoriah.Waterland@Sun.COM 				echo(MSG_SKIPPING_ZONE_NOT_RUNNABLE, zoneName);
21159781SMoriah.Waterland@Sun.COM 				echoDebug(DBG_SKIPPING_ZONE_NOT_RUNNABLE,
21169781SMoriah.Waterland@Sun.COM 					zoneName);
21179781SMoriah.Waterland@Sun.COM 				continue;
21189781SMoriah.Waterland@Sun.COM 			}
21199781SMoriah.Waterland@Sun.COM 
21209781SMoriah.Waterland@Sun.COM 			/* mount up the zone */
21219781SMoriah.Waterland@Sun.COM 
21229781SMoriah.Waterland@Sun.COM 			echo(MSG_BOOTING_ZONE, zoneName);
21239781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_BOOTING_ZONE, zoneName);
21249781SMoriah.Waterland@Sun.COM 
21259781SMoriah.Waterland@Sun.COM 			b = z_zlist_change_zone_state(a_zlst, zoneIndex,
21269781SMoriah.Waterland@Sun.COM 				ZONE_STATE_MOUNTED);
21279781SMoriah.Waterland@Sun.COM 			if (b == B_FALSE) {
21289781SMoriah.Waterland@Sun.COM 				progerr(ERR_CANNOT_BOOT_ZONE, zoneName);
21299781SMoriah.Waterland@Sun.COM 				/* set fatal error return condition */
21309781SMoriah.Waterland@Sun.COM 				ckreturn(1);
21319781SMoriah.Waterland@Sun.COM 				continue;
21329781SMoriah.Waterland@Sun.COM 			}
21339781SMoriah.Waterland@Sun.COM 
21349781SMoriah.Waterland@Sun.COM 			echo(MSG_CHECKREMOVE_PKG_IN_ZONE, pkginst, zoneName);
21359781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_CHECKREMOVE_PKG_IN_ZONE, pkginst,
21369781SMoriah.Waterland@Sun.COM 					zoneName);
21379781SMoriah.Waterland@Sun.COM 
21389781SMoriah.Waterland@Sun.COM 			scratchName = z_zlist_get_scratch(a_zlst, zoneIndex);
21399781SMoriah.Waterland@Sun.COM 
21409781SMoriah.Waterland@Sun.COM 			(void) snprintf(preremovecheckPath,
21419781SMoriah.Waterland@Sun.COM 				sizeof (preremovecheckPath),
21429781SMoriah.Waterland@Sun.COM 				"%s/%s.%s.preremovecheck.txt",
21439781SMoriah.Waterland@Sun.COM 				zoneTempDir, pkginst, scratchName);
21449781SMoriah.Waterland@Sun.COM 
21459781SMoriah.Waterland@Sun.COM 			/* determine list of dirs inherited from global zone */
21469781SMoriah.Waterland@Sun.COM 
21479781SMoriah.Waterland@Sun.COM 			inheritedPkgDirs =
21489781SMoriah.Waterland@Sun.COM 				z_zlist_get_inherited_pkg_dirs(a_zlst,
21499781SMoriah.Waterland@Sun.COM 					zoneIndex);
21509781SMoriah.Waterland@Sun.COM 
21519781SMoriah.Waterland@Sun.COM 			/*
21529781SMoriah.Waterland@Sun.COM 			 * dependency check this package this zone; use the
21539781SMoriah.Waterland@Sun.COM 			 * user supplied admin file so that the appropriate
21549781SMoriah.Waterland@Sun.COM 			 * level of dependency checking is (or is not) done.
21559781SMoriah.Waterland@Sun.COM 			 */
21569781SMoriah.Waterland@Sun.COM 
21579781SMoriah.Waterland@Sun.COM 			n = pkgZoneCheckRemove(scratchName, inheritedPkgDirs,
21589781SMoriah.Waterland@Sun.COM 				a_altBinDir, admnfile, preremovecheckPath,
2159*9869SCasper.Dik@Sun.COM 				ZONE_STATE_MOUNTED, B_TRUE);
21609781SMoriah.Waterland@Sun.COM 
21619781SMoriah.Waterland@Sun.COM 			/* set success/fail condition variables */
21629781SMoriah.Waterland@Sun.COM 
21639781SMoriah.Waterland@Sun.COM 			ckreturn(n);
21649781SMoriah.Waterland@Sun.COM 
21659781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_REMOVE_FLAG_VALUES,
21669781SMoriah.Waterland@Sun.COM 				"after pkgzonecheckremove",
21679781SMoriah.Waterland@Sun.COM 				admnflag, doreboot, failflag, interrupted,
21689781SMoriah.Waterland@Sun.COM 				intrflag, ireboot, nullflag, warnflag);
21699781SMoriah.Waterland@Sun.COM 
21709781SMoriah.Waterland@Sun.COM 			/* restore original state of zone */
21719781SMoriah.Waterland@Sun.COM 
21729781SMoriah.Waterland@Sun.COM 			echo(MSG_RESTORE_ZONE_STATE, zoneName);
21739781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_RESTORE_ZONE_STATE, zoneName);
21749781SMoriah.Waterland@Sun.COM 
21759781SMoriah.Waterland@Sun.COM 			b = z_zlist_restore_zone_state(a_zlst, zoneIndex);
21769781SMoriah.Waterland@Sun.COM 		}
21779781SMoriah.Waterland@Sun.COM 		npkgs--;
21789781SMoriah.Waterland@Sun.COM 	}
21799781SMoriah.Waterland@Sun.COM 
21809781SMoriah.Waterland@Sun.COM 	/*
21819781SMoriah.Waterland@Sun.COM 	 * look at all pre-remove check files
21829781SMoriah.Waterland@Sun.COM 	 */
21839781SMoriah.Waterland@Sun.COM 
21849781SMoriah.Waterland@Sun.COM 	i = preremove_verify(a_pkgList, a_zlst, zoneTempDir);
21859781SMoriah.Waterland@Sun.COM 	if (i != 0) {
21869781SMoriah.Waterland@Sun.COM 		quit(i);
21879781SMoriah.Waterland@Sun.COM 	}
21889781SMoriah.Waterland@Sun.COM 
21899781SMoriah.Waterland@Sun.COM 	npkgs = savenpkgs;
21909781SMoriah.Waterland@Sun.COM 
21919781SMoriah.Waterland@Sun.COM 	/*
21929781SMoriah.Waterland@Sun.COM 	 * reset all error return condition variables that may have been
21939781SMoriah.Waterland@Sun.COM 	 * set during package removal dependency checking so that they
21949781SMoriah.Waterland@Sun.COM 	 * do not reflect on the success/failure of the actual package
21959781SMoriah.Waterland@Sun.COM 	 * removal operations
21969781SMoriah.Waterland@Sun.COM 	 */
21979781SMoriah.Waterland@Sun.COM 
21989781SMoriah.Waterland@Sun.COM 	resetreturn();
21999781SMoriah.Waterland@Sun.COM 
22009781SMoriah.Waterland@Sun.COM 	/*
22019781SMoriah.Waterland@Sun.COM 	 * all of the packages (as listed in the package list) are
22029781SMoriah.Waterland@Sun.COM 	 * removed one at a time.
22039781SMoriah.Waterland@Sun.COM 	 */
22049781SMoriah.Waterland@Sun.COM 
22059781SMoriah.Waterland@Sun.COM 	interrupted = 0;
22069781SMoriah.Waterland@Sun.COM 	for (i = 0; (pkginst = a_pkgList[i]) != NULL; i++) {
22079781SMoriah.Waterland@Sun.COM 		boolean_t	in_gz_only;
22089781SMoriah.Waterland@Sun.COM 		started = 0;
22099781SMoriah.Waterland@Sun.COM 
22109781SMoriah.Waterland@Sun.COM 		if (shall_we_continue(pkginst, npkgs) == B_FALSE) {
22119781SMoriah.Waterland@Sun.COM 			continue;
22129781SMoriah.Waterland@Sun.COM 		}
22139781SMoriah.Waterland@Sun.COM 
22149781SMoriah.Waterland@Sun.COM 		in_gz_only = pkgIsPkgInGzOnly(get_inst_root(), pkginst);
22159781SMoriah.Waterland@Sun.COM 
22169781SMoriah.Waterland@Sun.COM 		/* reset interrupted flag before calling pkgremove */
22179781SMoriah.Waterland@Sun.COM 
22189781SMoriah.Waterland@Sun.COM 		interrupted = 0;
22199781SMoriah.Waterland@Sun.COM 
22209781SMoriah.Waterland@Sun.COM 		/*
22219781SMoriah.Waterland@Sun.COM 		 * pkgrm invoked from within the global zone and there are
22229781SMoriah.Waterland@Sun.COM 		 * non-global zones configured:
22239781SMoriah.Waterland@Sun.COM 		 * Remove the package from the global zone.
22249781SMoriah.Waterland@Sun.COM 		 * If not removing the package from the global zone only,
22259781SMoriah.Waterland@Sun.COM 		 * then remove the package from the list of zones specified.
22269781SMoriah.Waterland@Sun.COM 		 */
22279781SMoriah.Waterland@Sun.COM 
22289781SMoriah.Waterland@Sun.COM 		if (in_gz_only) {
22299781SMoriah.Waterland@Sun.COM 			/* global zone only */
22309781SMoriah.Waterland@Sun.COM 			n = doRemove(a_nodelete, a_altBinDir, a_longestPkg,
22319781SMoriah.Waterland@Sun.COM 				admnfile, (char *)NULL, (zoneList_t)NULL);
22329781SMoriah.Waterland@Sun.COM 		} else {
22339781SMoriah.Waterland@Sun.COM 			/* global zone and non-global zones */
22349781SMoriah.Waterland@Sun.COM 			n = doRemove(a_nodelete, a_altBinDir, a_longestPkg,
22359781SMoriah.Waterland@Sun.COM 				zoneAdminFile, zoneAdminFile, a_zlst);
22369781SMoriah.Waterland@Sun.COM 		}
22379781SMoriah.Waterland@Sun.COM 
22389781SMoriah.Waterland@Sun.COM 		/* set success/fail condition variables */
22399781SMoriah.Waterland@Sun.COM 
22409781SMoriah.Waterland@Sun.COM 		ckreturn(n);
22419781SMoriah.Waterland@Sun.COM 
22429781SMoriah.Waterland@Sun.COM 		npkgs--;
22439781SMoriah.Waterland@Sun.COM 	}
22449781SMoriah.Waterland@Sun.COM 
22459781SMoriah.Waterland@Sun.COM 	/*
22469781SMoriah.Waterland@Sun.COM 	 * all packages in the package list have been removed.
22479781SMoriah.Waterland@Sun.COM 	 * Continue with removal if:
22489781SMoriah.Waterland@Sun.COM 	 * -- immediate reboot is NOT required
22499781SMoriah.Waterland@Sun.COM 	 * -- there are more packages to remove
22509781SMoriah.Waterland@Sun.COM 	 * else return do NOT continue.
22519781SMoriah.Waterland@Sun.COM 	 */
22529781SMoriah.Waterland@Sun.COM 
22539781SMoriah.Waterland@Sun.COM 	if ((ireboot == 0) && (a_repeat != 0)) {
22549781SMoriah.Waterland@Sun.COM 		return (B_TRUE);
22559781SMoriah.Waterland@Sun.COM 	}
22569781SMoriah.Waterland@Sun.COM 
22579781SMoriah.Waterland@Sun.COM 	/* return 'dont continue' */
22589781SMoriah.Waterland@Sun.COM 
22599781SMoriah.Waterland@Sun.COM 	return (B_FALSE);
22609781SMoriah.Waterland@Sun.COM }
22619781SMoriah.Waterland@Sun.COM 
22629781SMoriah.Waterland@Sun.COM /*
22639781SMoriah.Waterland@Sun.COM  * Name:	remove_packages_in_nonglobal_zone
22649781SMoriah.Waterland@Sun.COM  * Description:	Remove packages in a non-global zone when run from a
22659781SMoriah.Waterland@Sun.COM  *		non-global zone.
22669781SMoriah.Waterland@Sun.COM  * Arguments:	a_pkgList - pointer to array of strings, each string specifying
22679781SMoriah.Waterland@Sun.COM  *			the name of one package to be removed.
22689781SMoriah.Waterland@Sun.COM  *		a_nodelete: should the files and scripts remain installed?
22699781SMoriah.Waterland@Sun.COM  *			- if != 0 pass -F flag to pkgremove - suppress
22709781SMoriah.Waterland@Sun.COM  *			the removal of any files and any class action scripts
22719781SMoriah.Waterland@Sun.COM  *			and suppress the running of any class action scripts.
22729781SMoriah.Waterland@Sun.COM  *			The package files remain but the package looks like it
22739781SMoriah.Waterland@Sun.COM  *			is not installed. This is mainly for use by upgrade.
22749781SMoriah.Waterland@Sun.COM  *			- if == 0 do not pass -F flag to pkgremove - all
22759781SMoriah.Waterland@Sun.COM  *			files and class action scripts are removed, and any
22769781SMoriah.Waterland@Sun.COM  *			appropriate class action scripts are run.
22779781SMoriah.Waterland@Sun.COM  *		a_longestPkg - length of the longest package "name" (for
22789781SMoriah.Waterland@Sun.COM  *			output format alignment)
22799781SMoriah.Waterland@Sun.COM  *		a_repeat - are there more packages avialable in "optind"
22809781SMoriah.Waterland@Sun.COM  *			- B_TRUE - process packages from optind
22819781SMoriah.Waterland@Sun.COM  *			- B_FALSE - do not process packages from optind
22829781SMoriah.Waterland@Sun.COM  *		a_altBinDir - pointer to string representing location of the
22839781SMoriah.Waterland@Sun.COM  *			pkgremove executable to run. If not NULL, then pass
22849781SMoriah.Waterland@Sun.COM  *			the path specified to the -b option to pkgremove.
22859781SMoriah.Waterland@Sun.COM  *		a_pkgdir - pointer to string representing the directory
22869781SMoriah.Waterland@Sun.COM  *			where the packages to be removed are located.
22879781SMoriah.Waterland@Sun.COM  * Returns:	int	(see ckreturn() function for details)
22889781SMoriah.Waterland@Sun.COM  *		0 - success
22899781SMoriah.Waterland@Sun.COM  *		1 - package operation failed (fatal error)
22909781SMoriah.Waterland@Sun.COM  *		2 - non-fatal error (warning)
22919781SMoriah.Waterland@Sun.COM  *		3 - user selected quit (operation interrupted)
22929781SMoriah.Waterland@Sun.COM  *		4 - admin settings prevented operation
22939781SMoriah.Waterland@Sun.COM  *		5 - interaction required and -n (non-interactive) specified
22949781SMoriah.Waterland@Sun.COM  *		"10" will be added to indicate "immediate reboot required"
22959781SMoriah.Waterland@Sun.COM  *		"20" will be added to indicate "reboot after install required"
22969781SMoriah.Waterland@Sun.COM  */
22979781SMoriah.Waterland@Sun.COM 
22989781SMoriah.Waterland@Sun.COM static boolean_t
22999781SMoriah.Waterland@Sun.COM remove_packages_in_nonglobal_zone(char **a_pkgList, int a_nodelete,
23009781SMoriah.Waterland@Sun.COM 	int a_longestPkg, int a_repeat, char *a_altBinDir, char *a_pkgdir)
23019781SMoriah.Waterland@Sun.COM {
23029781SMoriah.Waterland@Sun.COM static	char		*zoneAdminFile = (char *)NULL;
23039781SMoriah.Waterland@Sun.COM 
23049781SMoriah.Waterland@Sun.COM 	int		n;
23059781SMoriah.Waterland@Sun.COM 	int		i;
23069781SMoriah.Waterland@Sun.COM 
23079781SMoriah.Waterland@Sun.COM 	/* entry assertions */
23089781SMoriah.Waterland@Sun.COM 
23099781SMoriah.Waterland@Sun.COM 	assert(a_pkgList != (char **)NULL);
23109781SMoriah.Waterland@Sun.COM 	assert(a_longestPkg > 0);
23119781SMoriah.Waterland@Sun.COM 	assert(a_pkgdir != (char *)NULL);
23129781SMoriah.Waterland@Sun.COM 	assert(*a_pkgdir != '\0');
23139781SMoriah.Waterland@Sun.COM 
23149781SMoriah.Waterland@Sun.COM 	/* entry debugging info */
23159781SMoriah.Waterland@Sun.COM 
23169781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_PKGREMPKGSNGZ_ENTRY);
23179781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_PKGREMPKGSNGZ_ARGS, a_nodelete, a_longestPkg,
23189781SMoriah.Waterland@Sun.COM 		a_repeat, PSTR(a_altBinDir), PSTR(a_pkgdir));
23199781SMoriah.Waterland@Sun.COM 
23209781SMoriah.Waterland@Sun.COM 	/* check all package */
23219781SMoriah.Waterland@Sun.COM 
23229781SMoriah.Waterland@Sun.COM 	if (check_packages(a_pkgList, a_pkgdir) != B_TRUE) {
23239781SMoriah.Waterland@Sun.COM 		quit(1);
23249781SMoriah.Waterland@Sun.COM 	}
23259781SMoriah.Waterland@Sun.COM 
23269781SMoriah.Waterland@Sun.COM 	/* create temporary directory for use by zone operations */
23279781SMoriah.Waterland@Sun.COM 
23289781SMoriah.Waterland@Sun.COM 	create_zone_tempdir(&zoneTempDir, tmpdir);
23299781SMoriah.Waterland@Sun.COM 
23309781SMoriah.Waterland@Sun.COM 	/* create hands off settings admin file for use in a non-global zone */
23319781SMoriah.Waterland@Sun.COM 
23329781SMoriah.Waterland@Sun.COM 	create_zone_adminfile(&zoneAdminFile, zoneTempDir, admnfile);
23339781SMoriah.Waterland@Sun.COM 
23349781SMoriah.Waterland@Sun.COM 	/*
23359781SMoriah.Waterland@Sun.COM 	 * all of the packages (as listed in the package list) are
23369781SMoriah.Waterland@Sun.COM 	 * removed one at a time.
23379781SMoriah.Waterland@Sun.COM 	 */
23389781SMoriah.Waterland@Sun.COM 
23399781SMoriah.Waterland@Sun.COM 	interrupted = 0;
23409781SMoriah.Waterland@Sun.COM 	for (i = 0; (pkginst = a_pkgList[i]) != NULL; i++) {
23419781SMoriah.Waterland@Sun.COM 		started = 0;
23429781SMoriah.Waterland@Sun.COM 
23439781SMoriah.Waterland@Sun.COM 		if (shall_we_continue(pkginst, npkgs) == B_FALSE) {
23449781SMoriah.Waterland@Sun.COM 			continue;
23459781SMoriah.Waterland@Sun.COM 		}
23469781SMoriah.Waterland@Sun.COM 
23479781SMoriah.Waterland@Sun.COM 		interrupted = 0;
23489781SMoriah.Waterland@Sun.COM 
23499781SMoriah.Waterland@Sun.COM 		/*
23509781SMoriah.Waterland@Sun.COM 		 * pkgrm invoked from within a non-global zone: remove
23519781SMoriah.Waterland@Sun.COM 		 * the package from the current zone only - no non-global
23529781SMoriah.Waterland@Sun.COM 		 * zones are possible.
23539781SMoriah.Waterland@Sun.COM 		 */
23549781SMoriah.Waterland@Sun.COM 
23559781SMoriah.Waterland@Sun.COM 		n = doRemove(a_nodelete, a_altBinDir, a_longestPkg,
23569781SMoriah.Waterland@Sun.COM 			admnfile, (char *)NULL, (zoneList_t)NULL);
23579781SMoriah.Waterland@Sun.COM 
23589781SMoriah.Waterland@Sun.COM 		/* set success/fail condition variables */
23599781SMoriah.Waterland@Sun.COM 
23609781SMoriah.Waterland@Sun.COM 		ckreturn(n);
23619781SMoriah.Waterland@Sun.COM 
23629781SMoriah.Waterland@Sun.COM 		npkgs--;
23639781SMoriah.Waterland@Sun.COM 	}
23649781SMoriah.Waterland@Sun.COM 
23659781SMoriah.Waterland@Sun.COM 	/*
23669781SMoriah.Waterland@Sun.COM 	 * all packages in the package list have been removed.
23679781SMoriah.Waterland@Sun.COM 	 * Continue with removal if:
23689781SMoriah.Waterland@Sun.COM 	 * -- immediate reboot is NOT required
23699781SMoriah.Waterland@Sun.COM 	 * -- there are more packages to remove
23709781SMoriah.Waterland@Sun.COM 	 * else return do NOT continue.
23719781SMoriah.Waterland@Sun.COM 	 */
23729781SMoriah.Waterland@Sun.COM 
23739781SMoriah.Waterland@Sun.COM 	if ((ireboot == 0) && (a_repeat != 0)) {
23749781SMoriah.Waterland@Sun.COM 		return (B_TRUE);
23759781SMoriah.Waterland@Sun.COM 	}
23769781SMoriah.Waterland@Sun.COM 
23779781SMoriah.Waterland@Sun.COM 	/* return 'dont continue' */
23789781SMoriah.Waterland@Sun.COM 
23799781SMoriah.Waterland@Sun.COM 	return (B_FALSE);
23809781SMoriah.Waterland@Sun.COM }
23819781SMoriah.Waterland@Sun.COM 
23829781SMoriah.Waterland@Sun.COM /*
23839781SMoriah.Waterland@Sun.COM  * Name:	remove_packages_in_global_no_zones
23849781SMoriah.Waterland@Sun.COM  * Description:	Remove packages from the global zone only when run in the
23859781SMoriah.Waterland@Sun.COM  *		global zone and no non-global zones are installed.
23869781SMoriah.Waterland@Sun.COM  * Arguments:	a_pkgList - pointer to array of strings, each string specifying
23879781SMoriah.Waterland@Sun.COM  *			the name of one package to be removed.
23889781SMoriah.Waterland@Sun.COM  *		a_nodelete: should the files and scripts remain installed?
23899781SMoriah.Waterland@Sun.COM  *			- if != 0 pass -F flag to pkgremove - suppress
23909781SMoriah.Waterland@Sun.COM  *			the removal of any files and any class action scripts
23919781SMoriah.Waterland@Sun.COM  *			and suppress the running of any class action scripts.
23929781SMoriah.Waterland@Sun.COM  *			The package files remain but the package looks like it
23939781SMoriah.Waterland@Sun.COM  *			is not installed. This is mainly for use by upgrade.
23949781SMoriah.Waterland@Sun.COM  *			- if == 0 do not pass -F flag to pkgremove - all
23959781SMoriah.Waterland@Sun.COM  *			files and class action scripts are removed, and any
23969781SMoriah.Waterland@Sun.COM  *			appropriate class action scripts are run.
23979781SMoriah.Waterland@Sun.COM  *		a_longestPkg - length of the longest package "name" (for
23989781SMoriah.Waterland@Sun.COM  *			output format alignment)
23999781SMoriah.Waterland@Sun.COM  *		a_repeat - are there more packages avialable in "optind"
24009781SMoriah.Waterland@Sun.COM  *			- B_TRUE - process packages from optind
24019781SMoriah.Waterland@Sun.COM  *			- B_FALSE - do not process packages from optind
24029781SMoriah.Waterland@Sun.COM  *		a_altBinDir - pointer to string representing location of the
24039781SMoriah.Waterland@Sun.COM  *			pkgremove executable to run. If not NULL, then pass
24049781SMoriah.Waterland@Sun.COM  *			the path specified to the -b option to pkgremove.
24059781SMoriah.Waterland@Sun.COM  * Returns:	int	(see ckreturn() function for details)
24069781SMoriah.Waterland@Sun.COM  *		0 - success
24079781SMoriah.Waterland@Sun.COM  *		1 - package operation failed (fatal error)
24089781SMoriah.Waterland@Sun.COM  *		2 - non-fatal error (warning)
24099781SMoriah.Waterland@Sun.COM  *		3 - user selected quit (operation interrupted)
24109781SMoriah.Waterland@Sun.COM  *		4 - admin settings prevented operation
24119781SMoriah.Waterland@Sun.COM  *		5 - interaction required and -n (non-interactive) specified
24129781SMoriah.Waterland@Sun.COM  *		"10" will be added to indicate "immediate reboot required"
24139781SMoriah.Waterland@Sun.COM  *		"20" will be added to indicate "reboot after install required"
24149781SMoriah.Waterland@Sun.COM  */
24159781SMoriah.Waterland@Sun.COM 
24169781SMoriah.Waterland@Sun.COM static boolean_t
24179781SMoriah.Waterland@Sun.COM remove_packages_in_global_no_zones(char **a_pkgList, int a_nodelete,
24189781SMoriah.Waterland@Sun.COM 	int a_longestPkg, int a_repeat, char *a_altBinDir)
24199781SMoriah.Waterland@Sun.COM {
24209781SMoriah.Waterland@Sun.COM 	int	n;
24219781SMoriah.Waterland@Sun.COM 	int	i;
24229781SMoriah.Waterland@Sun.COM 
24239781SMoriah.Waterland@Sun.COM 	/* entry assertions */
24249781SMoriah.Waterland@Sun.COM 
24259781SMoriah.Waterland@Sun.COM 	assert(a_pkgList != (char **)NULL);
24269781SMoriah.Waterland@Sun.COM 	assert(a_longestPkg > 0);
24279781SMoriah.Waterland@Sun.COM 
24289781SMoriah.Waterland@Sun.COM 	/* entry debugging info */
24299781SMoriah.Waterland@Sun.COM 
24309781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_PKGREMPKGSGZNNGZ_ENTRY);
24319781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_PKGREMPKGSGZNNGZ_ARGS, a_nodelete, a_longestPkg,
24329781SMoriah.Waterland@Sun.COM 		a_repeat, PSTR(a_altBinDir));
24339781SMoriah.Waterland@Sun.COM 
24349781SMoriah.Waterland@Sun.COM 	/*
24359781SMoriah.Waterland@Sun.COM 	 * all of the packages (as listed in the package list) are
24369781SMoriah.Waterland@Sun.COM 	 * removed one at a time.
24379781SMoriah.Waterland@Sun.COM 	 */
24389781SMoriah.Waterland@Sun.COM 
24399781SMoriah.Waterland@Sun.COM 	interrupted = 0;
24409781SMoriah.Waterland@Sun.COM 	for (i = 0; (pkginst = a_pkgList[i]) != NULL; i++) {
24419781SMoriah.Waterland@Sun.COM 		started = 0;
24429781SMoriah.Waterland@Sun.COM 
24439781SMoriah.Waterland@Sun.COM 		if (shall_we_continue(pkginst, npkgs) == B_FALSE) {
24449781SMoriah.Waterland@Sun.COM 			continue;
24459781SMoriah.Waterland@Sun.COM 		}
24469781SMoriah.Waterland@Sun.COM 
24479781SMoriah.Waterland@Sun.COM 		interrupted = 0;
24489781SMoriah.Waterland@Sun.COM 
24499781SMoriah.Waterland@Sun.COM 		/*
24509781SMoriah.Waterland@Sun.COM 		 * pkgrm invoked from within the global zone and there are
24519781SMoriah.Waterland@Sun.COM 		 * NO non-global zones configured:
24529781SMoriah.Waterland@Sun.COM 		 * Remove the package from the global zone only.
24539781SMoriah.Waterland@Sun.COM 		 */
24549781SMoriah.Waterland@Sun.COM 
24559781SMoriah.Waterland@Sun.COM 		n = doRemove(a_nodelete, a_altBinDir, a_longestPkg,
24569781SMoriah.Waterland@Sun.COM 				admnfile, (char *)NULL, (zoneList_t)NULL);
24579781SMoriah.Waterland@Sun.COM 
24589781SMoriah.Waterland@Sun.COM 		/* set success/fail condition variables */
24599781SMoriah.Waterland@Sun.COM 
24609781SMoriah.Waterland@Sun.COM 		ckreturn(n);
24619781SMoriah.Waterland@Sun.COM 
24629781SMoriah.Waterland@Sun.COM 		npkgs--;
24639781SMoriah.Waterland@Sun.COM 	}
24649781SMoriah.Waterland@Sun.COM 
24659781SMoriah.Waterland@Sun.COM 	/*
24669781SMoriah.Waterland@Sun.COM 	 * all packages in the package list have been removed.
24679781SMoriah.Waterland@Sun.COM 	 * Continue with removal if:
24689781SMoriah.Waterland@Sun.COM 	 * -- immediate reboot is NOT required
24699781SMoriah.Waterland@Sun.COM 	 * -- there are more packages to remove
24709781SMoriah.Waterland@Sun.COM 	 * else return do NOT continue.
24719781SMoriah.Waterland@Sun.COM 	 */
24729781SMoriah.Waterland@Sun.COM 
24739781SMoriah.Waterland@Sun.COM 	if ((ireboot == 0) && (a_repeat != 0)) {
24749781SMoriah.Waterland@Sun.COM 		return (B_TRUE);
24759781SMoriah.Waterland@Sun.COM 	}
24769781SMoriah.Waterland@Sun.COM 
24779781SMoriah.Waterland@Sun.COM 	/* return 'dont continue' */
24789781SMoriah.Waterland@Sun.COM 
24799781SMoriah.Waterland@Sun.COM 	return (B_FALSE);
24809781SMoriah.Waterland@Sun.COM }
24819781SMoriah.Waterland@Sun.COM 
24829781SMoriah.Waterland@Sun.COM /*
24839781SMoriah.Waterland@Sun.COM  * Name:	remove_packages_from_spool_directory
24849781SMoriah.Waterland@Sun.COM  * Description:	Remove packages from a spool directory only.
24859781SMoriah.Waterland@Sun.COM  * Arguments:	a_pkgList - pointer to array of strings, each string specifying
24869781SMoriah.Waterland@Sun.COM  *			the name of one package to be removed.
24879781SMoriah.Waterland@Sun.COM  *		a_nodelete: should the files and scripts remain installed?
24889781SMoriah.Waterland@Sun.COM  *			- if != 0 pass -F flag to pkgremove - suppress
24899781SMoriah.Waterland@Sun.COM  *			the removal of any files and any class action scripts
24909781SMoriah.Waterland@Sun.COM  *			and suppress the running of any class action scripts.
24919781SMoriah.Waterland@Sun.COM  *			The package files remain but the package looks like it
24929781SMoriah.Waterland@Sun.COM  *			is not installed. This is mainly for use by upgrade.
24939781SMoriah.Waterland@Sun.COM  *			- if == 0 do not pass -F flag to pkgremove - all
24949781SMoriah.Waterland@Sun.COM  *			files and class action scripts are removed, and any
24959781SMoriah.Waterland@Sun.COM  *			appropriate class action scripts are run.
24969781SMoriah.Waterland@Sun.COM  *		a_longestPkg - length of the longest package "name" (for
24979781SMoriah.Waterland@Sun.COM  *			output format alignment)
24989781SMoriah.Waterland@Sun.COM  *		a_repeat - are there more packages avialable in "optind"
24999781SMoriah.Waterland@Sun.COM  *			- B_TRUE - process packages from optind
25009781SMoriah.Waterland@Sun.COM  *			- B_FALSE - do not process packages from optind
25019781SMoriah.Waterland@Sun.COM  *		a_altBinDir - pointer to string representing location of the
25029781SMoriah.Waterland@Sun.COM  *			pkgremove executable to run. If not NULL, then pass
25039781SMoriah.Waterland@Sun.COM  *			the path specified to the -b option to pkgremove.
25049781SMoriah.Waterland@Sun.COM  * Returns:	int	(see ckreturn() function for details)
25059781SMoriah.Waterland@Sun.COM  *		0 - success
25069781SMoriah.Waterland@Sun.COM  *		1 - package operation failed (fatal error)
25079781SMoriah.Waterland@Sun.COM  *		2 - non-fatal error (warning)
25089781SMoriah.Waterland@Sun.COM  *		3 - user selected quit (operation interrupted)
25099781SMoriah.Waterland@Sun.COM  *		4 - admin settings prevented operation
25109781SMoriah.Waterland@Sun.COM  *		5 - interaction required and -n (non-interactive) specified
25119781SMoriah.Waterland@Sun.COM  *		"10" will be added to indicate "immediate reboot required"
25129781SMoriah.Waterland@Sun.COM  *		"20" will be added to indicate "reboot after install required"
25139781SMoriah.Waterland@Sun.COM  */
25149781SMoriah.Waterland@Sun.COM 
25159781SMoriah.Waterland@Sun.COM static boolean_t
25169781SMoriah.Waterland@Sun.COM remove_packages_from_spool_directory(char **a_pkgList, int a_nodelete,
25179781SMoriah.Waterland@Sun.COM 	int a_longestPkg, int a_repeat, char *a_altBinDir)
25189781SMoriah.Waterland@Sun.COM {
25199781SMoriah.Waterland@Sun.COM 	int	n;
25209781SMoriah.Waterland@Sun.COM 	int	i;
25219781SMoriah.Waterland@Sun.COM 
25229781SMoriah.Waterland@Sun.COM 	/* entry assertions */
25239781SMoriah.Waterland@Sun.COM 
25249781SMoriah.Waterland@Sun.COM 	assert(a_pkgList != (char **)NULL);
25259781SMoriah.Waterland@Sun.COM 	assert(a_longestPkg > 0);
25269781SMoriah.Waterland@Sun.COM 
25279781SMoriah.Waterland@Sun.COM 	/*
25289781SMoriah.Waterland@Sun.COM 	 * all of the packages (as listed in the package list) are
25299781SMoriah.Waterland@Sun.COM 	 * removed one at a time.
25309781SMoriah.Waterland@Sun.COM 	 */
25319781SMoriah.Waterland@Sun.COM 
25329781SMoriah.Waterland@Sun.COM 	interrupted = 0;
25339781SMoriah.Waterland@Sun.COM 	for (i = 0; (pkginst = a_pkgList[i]) != NULL; i++) {
25349781SMoriah.Waterland@Sun.COM 		started = 0;
25359781SMoriah.Waterland@Sun.COM 
25369781SMoriah.Waterland@Sun.COM 		if (shall_we_continue(pkginst, npkgs) == B_FALSE) {
25379781SMoriah.Waterland@Sun.COM 			continue;
25389781SMoriah.Waterland@Sun.COM 		}
25399781SMoriah.Waterland@Sun.COM 
25409781SMoriah.Waterland@Sun.COM 		interrupted = 0;
25419781SMoriah.Waterland@Sun.COM 
25429781SMoriah.Waterland@Sun.COM 		/*
25439781SMoriah.Waterland@Sun.COM 		 * pkgrm invoked from any type of zone BUT the target
25449781SMoriah.Waterland@Sun.COM 		 * to be removed is a local spool directory: remove the
25459781SMoriah.Waterland@Sun.COM 		 * packages from the spool directory only.
25469781SMoriah.Waterland@Sun.COM 		 */
25479781SMoriah.Waterland@Sun.COM 
25489781SMoriah.Waterland@Sun.COM 		n = doRemove(a_nodelete, a_altBinDir, a_longestPkg,
25499781SMoriah.Waterland@Sun.COM 			admnfile, (char *)NULL, (zoneList_t)NULL);
25509781SMoriah.Waterland@Sun.COM 
25519781SMoriah.Waterland@Sun.COM 		/* set success/fail condition variables */
25529781SMoriah.Waterland@Sun.COM 
25539781SMoriah.Waterland@Sun.COM 		ckreturn(n);
25549781SMoriah.Waterland@Sun.COM 
25559781SMoriah.Waterland@Sun.COM 		npkgs--;
25569781SMoriah.Waterland@Sun.COM 	}
25579781SMoriah.Waterland@Sun.COM 
25589781SMoriah.Waterland@Sun.COM 	/*
25599781SMoriah.Waterland@Sun.COM 	 * all packages in the package list have been removed.
25609781SMoriah.Waterland@Sun.COM 	 * Continue with removal if:
25619781SMoriah.Waterland@Sun.COM 	 * -- immediate reboot is NOT required
25629781SMoriah.Waterland@Sun.COM 	 * -- there are more packages to remove
25639781SMoriah.Waterland@Sun.COM 	 * else return do NOT continue.
25649781SMoriah.Waterland@Sun.COM 	 */
25659781SMoriah.Waterland@Sun.COM 
25669781SMoriah.Waterland@Sun.COM 	if ((ireboot == 0) && (a_repeat != 0)) {
25679781SMoriah.Waterland@Sun.COM 		return (B_TRUE);
25689781SMoriah.Waterland@Sun.COM 	}
25699781SMoriah.Waterland@Sun.COM 
25709781SMoriah.Waterland@Sun.COM 	/* return 'dont continue' */
25719781SMoriah.Waterland@Sun.COM 
25729781SMoriah.Waterland@Sun.COM 	return (B_FALSE);
25739781SMoriah.Waterland@Sun.COM }
25749781SMoriah.Waterland@Sun.COM 
25759781SMoriah.Waterland@Sun.COM /*
25769781SMoriah.Waterland@Sun.COM  * Name:	remove_packages
25779781SMoriah.Waterland@Sun.COM  * Description:	Remove packages from the global zone, and optionally from one
25789781SMoriah.Waterland@Sun.COM  *		or more non-global zones, or from a specified spool directory.
25799781SMoriah.Waterland@Sun.COM  * Arguments:	a_pkgList - pointer to array of strings, each string specifying
25809781SMoriah.Waterland@Sun.COM  *			the name of one package to be removed.
25819781SMoriah.Waterland@Sun.COM  *		a_nodelete: should the files and scripts remain installed?
25829781SMoriah.Waterland@Sun.COM  *			- if != 0 pass -F flag to pkgremove - suppress
25839781SMoriah.Waterland@Sun.COM  *			the removal of any files and any class action scripts
25849781SMoriah.Waterland@Sun.COM  *			and suppress the running of any class action scripts.
25859781SMoriah.Waterland@Sun.COM  *			The package files remain but the package looks like it
25869781SMoriah.Waterland@Sun.COM  *			is not installed. This is mainly for use by upgrade.
25879781SMoriah.Waterland@Sun.COM  *			- if == 0 do not pass -F flag to pkgremove - all
25889781SMoriah.Waterland@Sun.COM  *			files and class action scripts are removed, and any
25899781SMoriah.Waterland@Sun.COM  *			appropriate class action scripts are run.
25909781SMoriah.Waterland@Sun.COM  *		a_longestPkg - length of the longest package "name" (for
25919781SMoriah.Waterland@Sun.COM  *			output format alignment)
25929781SMoriah.Waterland@Sun.COM  *		a_repeat - are there more packages avialable in "optind"
25939781SMoriah.Waterland@Sun.COM  *			- B_TRUE - process packages from optind
25949781SMoriah.Waterland@Sun.COM  *			- B_FALSE - do not process packages from optind
25959781SMoriah.Waterland@Sun.COM  *		a_altBinDir - pointer to string representing location of the
25969781SMoriah.Waterland@Sun.COM  *			pkgremove executable to run. If not NULL, then pass
25979781SMoriah.Waterland@Sun.COM  *			the path specified to the -b option to pkgremove.
25989781SMoriah.Waterland@Sun.COM  *		a_pkgdir - pointer to string representing the directory
25999781SMoriah.Waterland@Sun.COM  *			where the packages to be removed are located.
26009781SMoriah.Waterland@Sun.COM  *		a_spoolDir - pointer to string specifying spool directory
26019781SMoriah.Waterland@Sun.COM  *			to remove packages from. If != NULL then all zones
26029781SMoriah.Waterland@Sun.COM  *			processing is bypassed and the packages are removed
26039781SMoriah.Waterland@Sun.COM  *			from the specified spool directory only.
26049781SMoriah.Waterland@Sun.COM  *		a_noZones - if non-global zones are configured, should the
26059781SMoriah.Waterland@Sun.COM  *			packages be removed from the non-global zones?
26069781SMoriah.Waterland@Sun.COM  *			- B_TRUE - do NOT remove packages from non-global zones
26079781SMoriah.Waterland@Sun.COM  *			- B_FALSE - remove packages from non-global zones
26089781SMoriah.Waterland@Sun.COM  * Returns:	int	(see ckreturn() function for details)
26099781SMoriah.Waterland@Sun.COM  *		0 - success
26109781SMoriah.Waterland@Sun.COM  *		1 - package operation failed (fatal error)
26119781SMoriah.Waterland@Sun.COM  *		2 - non-fatal error (warning)
26129781SMoriah.Waterland@Sun.COM  *		3 - user selected quit (operation interrupted)
26139781SMoriah.Waterland@Sun.COM  *		4 - admin settings prevented operation
26149781SMoriah.Waterland@Sun.COM  *		5 - interaction required and -n (non-interactive) specified
26159781SMoriah.Waterland@Sun.COM  *		"10" will be added to indicate "immediate reboot required"
26169781SMoriah.Waterland@Sun.COM  *		"20" will be added to indicate "reboot after install required"
26179781SMoriah.Waterland@Sun.COM  */
26189781SMoriah.Waterland@Sun.COM 
26199781SMoriah.Waterland@Sun.COM static boolean_t
26209781SMoriah.Waterland@Sun.COM remove_packages(char **a_pkgList, int a_nodelete, int a_longestPkg,
26219781SMoriah.Waterland@Sun.COM 	int a_repeat, char *a_altBinDir, char *a_pkgdir, char *a_spoolDir,
26229781SMoriah.Waterland@Sun.COM 	boolean_t a_noZones)
26239781SMoriah.Waterland@Sun.COM {
26249781SMoriah.Waterland@Sun.COM 	zoneList_t	zlst;
26259781SMoriah.Waterland@Sun.COM 	boolean_t	b;
26269781SMoriah.Waterland@Sun.COM 
26279781SMoriah.Waterland@Sun.COM 	/* entry assertions */
26289781SMoriah.Waterland@Sun.COM 
26299781SMoriah.Waterland@Sun.COM 	assert(a_pkgList != (char **)NULL);
26309781SMoriah.Waterland@Sun.COM 
26319781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_REMOVEPKGS_ENTRY);
26329781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_REMOVEPKGS_ARGS, npkgs, a_nodelete, a_longestPkg,
26339781SMoriah.Waterland@Sun.COM 		a_repeat, PSTR(a_pkgdir), PSTR(a_spoolDir));
26349781SMoriah.Waterland@Sun.COM 
26359781SMoriah.Waterland@Sun.COM 	/*
26369781SMoriah.Waterland@Sun.COM 	 * if removing from spool directory, bypass all zones checks
26379781SMoriah.Waterland@Sun.COM 	 */
26389781SMoriah.Waterland@Sun.COM 
26399781SMoriah.Waterland@Sun.COM 	if (a_spoolDir != (char *)NULL) {
26409781SMoriah.Waterland@Sun.COM 		/* in non-global zone */
26419781SMoriah.Waterland@Sun.COM 
26429781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_REMOVE_PKGS_FROM_SPOOL, a_spoolDir);
26439781SMoriah.Waterland@Sun.COM 
26449781SMoriah.Waterland@Sun.COM 		b = remove_packages_from_spool_directory(a_pkgList, a_nodelete,
26459781SMoriah.Waterland@Sun.COM 			a_longestPkg, a_repeat, a_altBinDir);
26469781SMoriah.Waterland@Sun.COM 
26479781SMoriah.Waterland@Sun.COM 		return (B_FALSE);
26489781SMoriah.Waterland@Sun.COM 	}
26499781SMoriah.Waterland@Sun.COM 
26509781SMoriah.Waterland@Sun.COM 	/* exit if not root */
26519781SMoriah.Waterland@Sun.COM 
26529781SMoriah.Waterland@Sun.COM 	if (getuid()) {
26539781SMoriah.Waterland@Sun.COM 		progerr(ERR_NOT_ROOT, get_prog_name());
26549781SMoriah.Waterland@Sun.COM 		exit(1);
26559781SMoriah.Waterland@Sun.COM 	}
26569781SMoriah.Waterland@Sun.COM 
26579781SMoriah.Waterland@Sun.COM 	/*
26589781SMoriah.Waterland@Sun.COM 	 * if running in the global zone AND one or more non-global
26599781SMoriah.Waterland@Sun.COM 	 * zones exist, add packages in a 'zones aware' manner, else
26609781SMoriah.Waterland@Sun.COM 	 * add packages in the standard 'non-zones aware' manner.
26619781SMoriah.Waterland@Sun.COM 	 */
26629781SMoriah.Waterland@Sun.COM 
26639781SMoriah.Waterland@Sun.COM 	if ((a_noZones == B_FALSE) && (z_running_in_global_zone() == B_FALSE)) {
26649781SMoriah.Waterland@Sun.COM 		/* in non-global zone */
26659781SMoriah.Waterland@Sun.COM 
26669781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_IN_LZ);
26679781SMoriah.Waterland@Sun.COM 
26689781SMoriah.Waterland@Sun.COM 		b = z_lock_this_zone(ZLOCKS_PKG_ADMIN);
26699781SMoriah.Waterland@Sun.COM 		if (b != B_TRUE) {
26709781SMoriah.Waterland@Sun.COM 			progerr(ERR_CANNOT_LOCK_THIS_ZONE);
26719781SMoriah.Waterland@Sun.COM 			/* set fatal error return condition */
26729781SMoriah.Waterland@Sun.COM 			ckreturn(1);
26739781SMoriah.Waterland@Sun.COM 			return (B_FALSE);
26749781SMoriah.Waterland@Sun.COM 		}
26759781SMoriah.Waterland@Sun.COM 
26769781SMoriah.Waterland@Sun.COM 		b = remove_packages_in_nonglobal_zone(a_pkgList, a_nodelete,
26779781SMoriah.Waterland@Sun.COM 			a_longestPkg, a_repeat, a_altBinDir, a_pkgdir);
26789781SMoriah.Waterland@Sun.COM 
26799781SMoriah.Waterland@Sun.COM 		(void) z_unlock_this_zone(ZLOCKS_ALL);
26809781SMoriah.Waterland@Sun.COM 
26819781SMoriah.Waterland@Sun.COM 		return (B_FALSE);
26829781SMoriah.Waterland@Sun.COM 	}
26839781SMoriah.Waterland@Sun.COM 
26849781SMoriah.Waterland@Sun.COM 	/* running in the global zone */
26859781SMoriah.Waterland@Sun.COM 
26869781SMoriah.Waterland@Sun.COM 	b = z_non_global_zones_exist();
26879781SMoriah.Waterland@Sun.COM 	if ((a_noZones == B_FALSE) && (b == B_TRUE)) {
26889781SMoriah.Waterland@Sun.COM 
26899781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_IN_GZ_WITH_LZ);
26909781SMoriah.Waterland@Sun.COM 
26919781SMoriah.Waterland@Sun.COM 		/* get a list of all non-global zones */
26929781SMoriah.Waterland@Sun.COM 		zlst = z_get_nonglobal_zone_list();
26939781SMoriah.Waterland@Sun.COM 		if (zlst == (zoneList_t)NULL) {
26949781SMoriah.Waterland@Sun.COM 			progerr(ERR_CANNOT_GET_ZONE_LIST);
26959781SMoriah.Waterland@Sun.COM 			quit(1);
26969781SMoriah.Waterland@Sun.COM 		}
26979781SMoriah.Waterland@Sun.COM 
26989781SMoriah.Waterland@Sun.COM 		/* need to lock all of the zones */
26999781SMoriah.Waterland@Sun.COM 
27009781SMoriah.Waterland@Sun.COM 		quitSetZonelist(zlst);
27019781SMoriah.Waterland@Sun.COM 		b = z_lock_zones(zlst, ZLOCKS_PKG_ADMIN);
27029781SMoriah.Waterland@Sun.COM 		if (b == B_FALSE) {
27039781SMoriah.Waterland@Sun.COM 			z_free_zone_list(zlst);
27049781SMoriah.Waterland@Sun.COM 			progerr(ERR_CANNOT_LOCK_ZONES);
27059781SMoriah.Waterland@Sun.COM 			/* set fatal error return condition */
27069781SMoriah.Waterland@Sun.COM 			ckreturn(1);
27079781SMoriah.Waterland@Sun.COM 			return (B_FALSE);
27089781SMoriah.Waterland@Sun.COM 		}
27099781SMoriah.Waterland@Sun.COM 
27109781SMoriah.Waterland@Sun.COM 		/* add packages to all zones */
27119781SMoriah.Waterland@Sun.COM 
27129781SMoriah.Waterland@Sun.COM 		b = remove_packages_in_global_with_zones(a_pkgList, a_nodelete,
27139781SMoriah.Waterland@Sun.COM 			a_longestPkg, a_repeat, a_altBinDir, a_pkgdir, zlst);
27149781SMoriah.Waterland@Sun.COM 
27159781SMoriah.Waterland@Sun.COM 		/* unlock all zones */
27169781SMoriah.Waterland@Sun.COM 
27179781SMoriah.Waterland@Sun.COM 		(void) z_unlock_zones(zlst, ZLOCKS_ALL);
27189781SMoriah.Waterland@Sun.COM 		quitSetZonelist((zoneList_t)NULL);
27199781SMoriah.Waterland@Sun.COM 
27209781SMoriah.Waterland@Sun.COM 		/* free list of all non-global zones */
27219781SMoriah.Waterland@Sun.COM 
27229781SMoriah.Waterland@Sun.COM 		z_free_zone_list(zlst);
27239781SMoriah.Waterland@Sun.COM 
27249781SMoriah.Waterland@Sun.COM 		return (B_FALSE);
27259781SMoriah.Waterland@Sun.COM 	}
27269781SMoriah.Waterland@Sun.COM 
27279781SMoriah.Waterland@Sun.COM 	/* in global zone no non-global zones */
27289781SMoriah.Waterland@Sun.COM 
27299781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_IN_GZ_NO_LZ);
27309781SMoriah.Waterland@Sun.COM 
27319781SMoriah.Waterland@Sun.COM 	b = z_lock_this_zone(ZLOCKS_PKG_ADMIN);
27329781SMoriah.Waterland@Sun.COM 	if (b != B_TRUE) {
27339781SMoriah.Waterland@Sun.COM 		progerr(ERR_CANNOT_LOCK_THIS_ZONE);
27349781SMoriah.Waterland@Sun.COM 		/* set fatal error return condition */
27359781SMoriah.Waterland@Sun.COM 		ckreturn(1);
27369781SMoriah.Waterland@Sun.COM 		return (B_FALSE);
27379781SMoriah.Waterland@Sun.COM 	}
27389781SMoriah.Waterland@Sun.COM 
27399781SMoriah.Waterland@Sun.COM 	b = remove_packages_in_global_no_zones(a_pkgList, a_nodelete,
27409781SMoriah.Waterland@Sun.COM 			a_longestPkg, a_repeat, a_altBinDir);
27419781SMoriah.Waterland@Sun.COM 
27429781SMoriah.Waterland@Sun.COM 	(void) z_unlock_this_zone(ZLOCKS_ALL);
27439781SMoriah.Waterland@Sun.COM 
27449781SMoriah.Waterland@Sun.COM 	return (B_FALSE);
27459781SMoriah.Waterland@Sun.COM }
27469781SMoriah.Waterland@Sun.COM 
27479781SMoriah.Waterland@Sun.COM /*
27489781SMoriah.Waterland@Sun.COM  * Name:		path_valid
27499781SMoriah.Waterland@Sun.COM  * Description:	Checks a string for being a valid path
27509781SMoriah.Waterland@Sun.COM  *
27519781SMoriah.Waterland@Sun.COM  * Arguments:	path - path to validate
27529781SMoriah.Waterland@Sun.COM  *
27539781SMoriah.Waterland@Sun.COM  * Returns :	B_TRUE - success, B_FALSE otherwise.
27549781SMoriah.Waterland@Sun.COM  *		B_FALSE means path was null, too long (>PATH_MAX),
27559781SMoriah.Waterland@Sun.COM  *		or too short (<1)
27569781SMoriah.Waterland@Sun.COM  */
27579781SMoriah.Waterland@Sun.COM static boolean_t
27589781SMoriah.Waterland@Sun.COM path_valid(char *path)
27599781SMoriah.Waterland@Sun.COM {
27609781SMoriah.Waterland@Sun.COM 	if (path == NULL) {
27619781SMoriah.Waterland@Sun.COM 		return (B_FALSE);
27629781SMoriah.Waterland@Sun.COM 	} else if (strlen(path) > PATH_MAX) {
27639781SMoriah.Waterland@Sun.COM 		return (B_FALSE);
27649781SMoriah.Waterland@Sun.COM 	} else if (strlen(path) >= 1) {
27659781SMoriah.Waterland@Sun.COM 		return (B_TRUE);
27669781SMoriah.Waterland@Sun.COM 	} else {
27679781SMoriah.Waterland@Sun.COM 		/* path < 1 */
27689781SMoriah.Waterland@Sun.COM 		return (B_FALSE);
27699781SMoriah.Waterland@Sun.COM 	}
27709781SMoriah.Waterland@Sun.COM }
27719781SMoriah.Waterland@Sun.COM 
27729781SMoriah.Waterland@Sun.COM /*
27739781SMoriah.Waterland@Sun.COM  */
27749781SMoriah.Waterland@Sun.COM 
27759781SMoriah.Waterland@Sun.COM static boolean_t
27769781SMoriah.Waterland@Sun.COM check_packages(char **a_pkgList, char *a_packageDir)
27779781SMoriah.Waterland@Sun.COM {
27789781SMoriah.Waterland@Sun.COM 	int	savenpkgs = npkgs;
27799781SMoriah.Waterland@Sun.COM 	int	i;
27809781SMoriah.Waterland@Sun.COM 	CAF_T	flags = 0;
27819781SMoriah.Waterland@Sun.COM 
27829781SMoriah.Waterland@Sun.COM 	/* set flags for applicability check */
27839781SMoriah.Waterland@Sun.COM 
27849781SMoriah.Waterland@Sun.COM 	if (z_running_in_global_zone() == B_TRUE) {
27859781SMoriah.Waterland@Sun.COM 		flags |= CAF_IN_GLOBAL_ZONE;
27869781SMoriah.Waterland@Sun.COM 	}
27879781SMoriah.Waterland@Sun.COM 
27889781SMoriah.Waterland@Sun.COM 	/*
27899781SMoriah.Waterland@Sun.COM 	 * for each package to remove, verify that the package is installed
27909781SMoriah.Waterland@Sun.COM 	 * and is removable.
27919781SMoriah.Waterland@Sun.COM 	 */
27929781SMoriah.Waterland@Sun.COM 
27939781SMoriah.Waterland@Sun.COM 	for (i = 0; (pkginst = a_pkgList[i]) != NULL; i++) {
27949781SMoriah.Waterland@Sun.COM 		/* check package applicability */
27959781SMoriah.Waterland@Sun.COM 		if (check_applicability(a_packageDir, pkginst, get_inst_root(),
27969781SMoriah.Waterland@Sun.COM 			flags) == B_FALSE) {
27979781SMoriah.Waterland@Sun.COM 			progerr(ERR_PKG_NOT_REMOVABLE, pkginst);
27989781SMoriah.Waterland@Sun.COM 			npkgs = savenpkgs;
27999781SMoriah.Waterland@Sun.COM 			return (B_FALSE);
28009781SMoriah.Waterland@Sun.COM 		}
28019781SMoriah.Waterland@Sun.COM 		npkgs--;
28029781SMoriah.Waterland@Sun.COM 	}
28039781SMoriah.Waterland@Sun.COM 
28049781SMoriah.Waterland@Sun.COM 	npkgs = savenpkgs;
28059781SMoriah.Waterland@Sun.COM 	return (B_TRUE);
28069781SMoriah.Waterland@Sun.COM }
28079781SMoriah.Waterland@Sun.COM 
28089781SMoriah.Waterland@Sun.COM /*
28099781SMoriah.Waterland@Sun.COM  * - is this package removable from this zone?
28109781SMoriah.Waterland@Sun.COM  * - does the scope of remove conflict with existing installation
28119781SMoriah.Waterland@Sun.COM  */
28129781SMoriah.Waterland@Sun.COM 
28139781SMoriah.Waterland@Sun.COM static boolean_t
28149781SMoriah.Waterland@Sun.COM check_applicability(char *a_packageDir, char *a_pkgInst,
28159781SMoriah.Waterland@Sun.COM 	char *a_rootPath, CAF_T a_flags)
28169781SMoriah.Waterland@Sun.COM {
28179781SMoriah.Waterland@Sun.COM 	FILE		*pkginfoFP;
28189781SMoriah.Waterland@Sun.COM 	boolean_t	all_zones;	/* pkg is "all zones" only */
28199781SMoriah.Waterland@Sun.COM 	char		pkginfoPath[PATH_MAX];
28209781SMoriah.Waterland@Sun.COM 	char		pkgpath[PATH_MAX];
28219781SMoriah.Waterland@Sun.COM 	int		len;
28229781SMoriah.Waterland@Sun.COM 
28239781SMoriah.Waterland@Sun.COM 	/* entry assertions */
28249781SMoriah.Waterland@Sun.COM 
28259781SMoriah.Waterland@Sun.COM 	assert(a_packageDir != (char *)NULL);
28269781SMoriah.Waterland@Sun.COM 	assert(*a_packageDir != '\0');
28279781SMoriah.Waterland@Sun.COM 	assert(a_pkgInst != (char *)NULL);
28289781SMoriah.Waterland@Sun.COM 	assert(*a_pkgInst != '\0');
28299781SMoriah.Waterland@Sun.COM 
28309781SMoriah.Waterland@Sun.COM 	/* normalize root path */
28319781SMoriah.Waterland@Sun.COM 
28329781SMoriah.Waterland@Sun.COM 	if (a_rootPath == (char *)NULL) {
28339781SMoriah.Waterland@Sun.COM 		a_rootPath = "";
28349781SMoriah.Waterland@Sun.COM 	}
28359781SMoriah.Waterland@Sun.COM 
28369781SMoriah.Waterland@Sun.COM 	/*
28379781SMoriah.Waterland@Sun.COM 	 * determine if this package is currently installed
28389781SMoriah.Waterland@Sun.COM 	 * if not installed return success - operation will fail
28399781SMoriah.Waterland@Sun.COM 	 * when the removal is attempted
28409781SMoriah.Waterland@Sun.COM 	 */
28419781SMoriah.Waterland@Sun.COM 
28429781SMoriah.Waterland@Sun.COM 	if (pkginfoIsPkgInstalled((struct pkginfo **)NULL, a_pkgInst) !=
28439781SMoriah.Waterland@Sun.COM 		B_TRUE) {
28449781SMoriah.Waterland@Sun.COM 		return (B_TRUE);
28459781SMoriah.Waterland@Sun.COM 	}
28469781SMoriah.Waterland@Sun.COM 
28479781SMoriah.Waterland@Sun.COM 	/*
28489781SMoriah.Waterland@Sun.COM 	 * calculate paths to various objects
28499781SMoriah.Waterland@Sun.COM 	 */
28509781SMoriah.Waterland@Sun.COM 
28519781SMoriah.Waterland@Sun.COM 	len = snprintf(pkgpath, sizeof (pkgpath), "%s/%s", a_packageDir,
28529781SMoriah.Waterland@Sun.COM 			a_pkgInst);
28539781SMoriah.Waterland@Sun.COM 	if (len > sizeof (pkgpath)) {
28549781SMoriah.Waterland@Sun.COM 		progerr(ERR_CREATE_PATH_2, a_packageDir, a_pkgInst);
28559781SMoriah.Waterland@Sun.COM 		return (B_FALSE);
28569781SMoriah.Waterland@Sun.COM 	}
28579781SMoriah.Waterland@Sun.COM 
28589781SMoriah.Waterland@Sun.COM 	/* if not installed then just return */
28599781SMoriah.Waterland@Sun.COM 
28609781SMoriah.Waterland@Sun.COM 	if (isdir(pkgpath) != 0) {
28619781SMoriah.Waterland@Sun.COM 		progerr(ERR_NO_PKGDIR, pkgpath, a_pkgInst, strerror(errno));
28629781SMoriah.Waterland@Sun.COM 		return (B_TRUE);
28639781SMoriah.Waterland@Sun.COM 	}
28649781SMoriah.Waterland@Sun.COM 
28659781SMoriah.Waterland@Sun.COM 	len = snprintf(pkginfoPath, sizeof (pkginfoPath),
28669781SMoriah.Waterland@Sun.COM 			"%s/pkginfo", pkgpath);
28679781SMoriah.Waterland@Sun.COM 	if (len > sizeof (pkgpath)) {
28689781SMoriah.Waterland@Sun.COM 		progerr(ERR_CREATE_PATH_2, pkgpath, "pkginfo");
28699781SMoriah.Waterland@Sun.COM 		return (B_FALSE);
28709781SMoriah.Waterland@Sun.COM 	}
28719781SMoriah.Waterland@Sun.COM 
28729781SMoriah.Waterland@Sun.COM 	/*
28739781SMoriah.Waterland@Sun.COM 	 * gather information from this packages pkginfo file
28749781SMoriah.Waterland@Sun.COM 	 */
28759781SMoriah.Waterland@Sun.COM 
28769781SMoriah.Waterland@Sun.COM 	pkginfoFP = fopen(pkginfoPath, "r");
28779781SMoriah.Waterland@Sun.COM 
28789781SMoriah.Waterland@Sun.COM 	if (pkginfoFP == (FILE *)NULL) {
28799781SMoriah.Waterland@Sun.COM 		progerr(ERR_NO_PKG_INFOFILE, a_pkgInst, pkginfoPath,
28809781SMoriah.Waterland@Sun.COM 							strerror(errno));
28819781SMoriah.Waterland@Sun.COM 		return (B_FALSE);
28829781SMoriah.Waterland@Sun.COM 	}
28839781SMoriah.Waterland@Sun.COM 
28849781SMoriah.Waterland@Sun.COM 	/* determine "ALLZONES" setting for this package */
28859781SMoriah.Waterland@Sun.COM 
28869781SMoriah.Waterland@Sun.COM 	all_zones = pkginfoParamTruth(pkginfoFP, PKG_ALLZONES_VARIABLE,
28879781SMoriah.Waterland@Sun.COM 			"true", B_FALSE);
28889781SMoriah.Waterland@Sun.COM 
28899781SMoriah.Waterland@Sun.COM 	/* close pkginfo file */
28909781SMoriah.Waterland@Sun.COM 
28919781SMoriah.Waterland@Sun.COM 	(void) fclose(pkginfoFP);
28929781SMoriah.Waterland@Sun.COM 
28939781SMoriah.Waterland@Sun.COM 	/* gather information from the global zone only file */
28949781SMoriah.Waterland@Sun.COM 
28959781SMoriah.Waterland@Sun.COM 	/*
28969781SMoriah.Waterland@Sun.COM 	 * verify package applicability based on information gathered;
28979781SMoriah.Waterland@Sun.COM 	 * the package IS currently installed....
28989781SMoriah.Waterland@Sun.COM 	 */
28999781SMoriah.Waterland@Sun.COM 
29009781SMoriah.Waterland@Sun.COM 	/* pkg ALLZONES=true & not running in global zone */
29019781SMoriah.Waterland@Sun.COM 
29029781SMoriah.Waterland@Sun.COM 	if ((all_zones == B_TRUE) && (!(a_flags & CAF_IN_GLOBAL_ZONE))) {
29039781SMoriah.Waterland@Sun.COM 		progerr(ERR_ALLZONES_AND_IN_LZ_PKGRM, a_pkgInst);
29049781SMoriah.Waterland@Sun.COM 		return (B_FALSE);
29059781SMoriah.Waterland@Sun.COM 	}
29069781SMoriah.Waterland@Sun.COM 
29079781SMoriah.Waterland@Sun.COM 	return (B_TRUE);
29089781SMoriah.Waterland@Sun.COM }
29099781SMoriah.Waterland@Sun.COM 
29109781SMoriah.Waterland@Sun.COM /*
29119781SMoriah.Waterland@Sun.COM  * Name:	shall_we_continue
29129781SMoriah.Waterland@Sun.COM  * Description: Called from within a loop that is installing packages,
29139781SMoriah.Waterland@Sun.COM  *		this function examines various global variables and decides
29149781SMoriah.Waterland@Sun.COM  *		whether or not to ask an appropriate question, and wait for
29159781SMoriah.Waterland@Sun.COM  *		and appropriate reply.
29169781SMoriah.Waterland@Sun.COM  * Arguments:	<<global variables>>
29179781SMoriah.Waterland@Sun.COM  * Returns:	B_TRUE - continue processing with next package
29189781SMoriah.Waterland@Sun.COM  *		B_FALSE - do not continue processing with next package
29199781SMoriah.Waterland@Sun.COM  */
29209781SMoriah.Waterland@Sun.COM 
29219781SMoriah.Waterland@Sun.COM static boolean_t
29229781SMoriah.Waterland@Sun.COM shall_we_continue(char *a_pkgInst, int a_npkgs)
29239781SMoriah.Waterland@Sun.COM {
29249781SMoriah.Waterland@Sun.COM 	char	ans[MAX_INPUT];
29259781SMoriah.Waterland@Sun.COM 	int	n;
29269781SMoriah.Waterland@Sun.COM 
29279781SMoriah.Waterland@Sun.COM 	/* return FALSE if immediate reboot required */
29289781SMoriah.Waterland@Sun.COM 
29299781SMoriah.Waterland@Sun.COM 	if (ireboot) {
29309781SMoriah.Waterland@Sun.COM 		ptext(stderr, MSG_SUSPEND_RM, a_pkgInst);
29319781SMoriah.Waterland@Sun.COM 		return (B_FALSE);
29329781SMoriah.Waterland@Sun.COM 	}
29339781SMoriah.Waterland@Sun.COM 
29349781SMoriah.Waterland@Sun.COM 	/* return TRUE if not interrupted */
29359781SMoriah.Waterland@Sun.COM 
29369781SMoriah.Waterland@Sun.COM 	if (!interrupted) {
29379781SMoriah.Waterland@Sun.COM 		return (B_TRUE);
29389781SMoriah.Waterland@Sun.COM 	}
29399781SMoriah.Waterland@Sun.COM 
29409781SMoriah.Waterland@Sun.COM 	/* output appropriate interrupt message */
29419781SMoriah.Waterland@Sun.COM 
29429781SMoriah.Waterland@Sun.COM 	echo(a_npkgs == 1 ? MSG_1MORETODO : MSG_MORETODO, a_npkgs);
29439781SMoriah.Waterland@Sun.COM 
29449781SMoriah.Waterland@Sun.COM 	/* if running with no interaction (-n) do not ask question */
29459781SMoriah.Waterland@Sun.COM 
29469781SMoriah.Waterland@Sun.COM 	if (nointeract) {
29479781SMoriah.Waterland@Sun.COM 		quit(0);
29489781SMoriah.Waterland@Sun.COM 		/* NOTREACHED */
29499781SMoriah.Waterland@Sun.COM 	}
29509781SMoriah.Waterland@Sun.COM 
29519781SMoriah.Waterland@Sun.COM 	/* interaction possible: ask question */
29529781SMoriah.Waterland@Sun.COM 
29539781SMoriah.Waterland@Sun.COM 	n = ckyorn(ans, NULL, NULL, NULL, ASK_CONTINUE_RM);
29549781SMoriah.Waterland@Sun.COM 	if (n != 0) {
29559781SMoriah.Waterland@Sun.COM 		quit(n);
29569781SMoriah.Waterland@Sun.COM 		/* NOTREACHED */
29579781SMoriah.Waterland@Sun.COM 	}
29589781SMoriah.Waterland@Sun.COM 
29599781SMoriah.Waterland@Sun.COM 	if (strchr("yY", *ans) == NULL) {
29609781SMoriah.Waterland@Sun.COM 		quit(0);
29619781SMoriah.Waterland@Sun.COM 		/* NOTREACHED */
29629781SMoriah.Waterland@Sun.COM 	}
29639781SMoriah.Waterland@Sun.COM 	return (B_TRUE);
29649781SMoriah.Waterland@Sun.COM }
29659781SMoriah.Waterland@Sun.COM 
29669781SMoriah.Waterland@Sun.COM /*
29679781SMoriah.Waterland@Sun.COM  * Name:	create_zone_adminfile
29689781SMoriah.Waterland@Sun.COM  * Description: Given a zone temporary directory and optionally an existing
29699781SMoriah.Waterland@Sun.COM  *		administration file, generate an administration file that
29709781SMoriah.Waterland@Sun.COM  *		can be used to perform "non-interactive" operations in a
29719781SMoriah.Waterland@Sun.COM  *		non-global zone.
29729781SMoriah.Waterland@Sun.COM  * Arguments:	r_zoneAdminFile - pointer to handle that will contain a
29739781SMoriah.Waterland@Sun.COM  *			string representing the path to the temporary
29749781SMoriah.Waterland@Sun.COM  *			administration file created - this must be NULL
29759781SMoriah.Waterland@Sun.COM  *			before the first call to this function - on
29769781SMoriah.Waterland@Sun.COM  *			subsequent calls if the pointer is NOT null then
29779781SMoriah.Waterland@Sun.COM  *			the existing string will NOT be overwritten.
29789781SMoriah.Waterland@Sun.COM  *		a_zoneTempDir - pointer to string representing the path
29799781SMoriah.Waterland@Sun.COM  *			to the zone temporary directory to create the
29809781SMoriah.Waterland@Sun.COM  *			temporary administration file in
29819781SMoriah.Waterland@Sun.COM  *		a_admnfile - pointer to string representing the path to
29829781SMoriah.Waterland@Sun.COM  *			an existing "user" administration file - the
29839781SMoriah.Waterland@Sun.COM  *			administration file created will contain the
29849781SMoriah.Waterland@Sun.COM  *			settings contained in this file, modified as
29859781SMoriah.Waterland@Sun.COM  *			appropriate to supress any interaction;
29869781SMoriah.Waterland@Sun.COM  *			If this is == NULL then the administration file
29879781SMoriah.Waterland@Sun.COM  *			created will not contain any extra settings
29889781SMoriah.Waterland@Sun.COM  * Returns:	void
29899781SMoriah.Waterland@Sun.COM  * NOTE:	Any string returned is placed in new storage for the
29909781SMoriah.Waterland@Sun.COM  *		calling method. The caller must use 'free' to dispose
29919781SMoriah.Waterland@Sun.COM  *		of the storage once the string is no longer needed.
29929781SMoriah.Waterland@Sun.COM  * NOTE:	On any error this function will call 'quit(1)'
29939781SMoriah.Waterland@Sun.COM  */
29949781SMoriah.Waterland@Sun.COM 
29959781SMoriah.Waterland@Sun.COM static void
29969781SMoriah.Waterland@Sun.COM create_zone_adminfile(char **r_zoneAdminFile, char *a_zoneTempDir,
29979781SMoriah.Waterland@Sun.COM 	char *a_admnfile)
29989781SMoriah.Waterland@Sun.COM {
29999781SMoriah.Waterland@Sun.COM 	boolean_t	b;
30009781SMoriah.Waterland@Sun.COM 
30019781SMoriah.Waterland@Sun.COM 	/* entry assertions */
30029781SMoriah.Waterland@Sun.COM 
30039781SMoriah.Waterland@Sun.COM 	assert(r_zoneAdminFile != (char **)NULL);
30049781SMoriah.Waterland@Sun.COM 	assert(a_zoneTempDir != (char *)NULL);
30059781SMoriah.Waterland@Sun.COM 	assert(*a_zoneTempDir != '\0');
30069781SMoriah.Waterland@Sun.COM 
30079781SMoriah.Waterland@Sun.COM 	/* entry debugging info */
30089781SMoriah.Waterland@Sun.COM 
30099781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_CREATE_ZONE_ADMINFILE, a_zoneTempDir, PSTR(a_admnfile));
30109781SMoriah.Waterland@Sun.COM 
30119781SMoriah.Waterland@Sun.COM 	/* if temporary name already exists, do not overwrite */
30129781SMoriah.Waterland@Sun.COM 
30139781SMoriah.Waterland@Sun.COM 	if (*r_zoneAdminFile != (char *)NULL) {
30149781SMoriah.Waterland@Sun.COM 		return;
30159781SMoriah.Waterland@Sun.COM 	}
30169781SMoriah.Waterland@Sun.COM 
30179781SMoriah.Waterland@Sun.COM 	/* create temporary name */
30189781SMoriah.Waterland@Sun.COM 
30199781SMoriah.Waterland@Sun.COM 	*r_zoneAdminFile = tempnam(a_zoneTempDir, "zadmn");
30209781SMoriah.Waterland@Sun.COM 	b = z_create_zone_admin_file(*r_zoneAdminFile, a_admnfile);
30219781SMoriah.Waterland@Sun.COM 	if (b == B_FALSE) {
30229781SMoriah.Waterland@Sun.COM 		progerr(ERR_CREATE_TMPADMIN, *r_zoneAdminFile,
30239781SMoriah.Waterland@Sun.COM 			strerror(errno));
30249781SMoriah.Waterland@Sun.COM 		quit(1);
30259781SMoriah.Waterland@Sun.COM 		/* NOTREACHED */
30269781SMoriah.Waterland@Sun.COM 	}
30279781SMoriah.Waterland@Sun.COM 
30289781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_CREATED_ZONE_ADMINFILE, *r_zoneAdminFile);
30299781SMoriah.Waterland@Sun.COM }
30309781SMoriah.Waterland@Sun.COM 
30319781SMoriah.Waterland@Sun.COM /*
30329781SMoriah.Waterland@Sun.COM  * Name:	create_zone_tempdir
30339781SMoriah.Waterland@Sun.COM  * Description: Given a system temporary directory, create a "zone" specific
30349781SMoriah.Waterland@Sun.COM  *		temporary directory and return the path to the directory
30359781SMoriah.Waterland@Sun.COM  *		created.
30369781SMoriah.Waterland@Sun.COM  * Arguments:	r_zoneTempDir - pointer to handle that will contain a
30379781SMoriah.Waterland@Sun.COM  *			string representing the path to the temporary
30389781SMoriah.Waterland@Sun.COM  *			directory created - this must be NULL before the
30399781SMoriah.Waterland@Sun.COM  *			first call to this function - on subsequent calls
30409781SMoriah.Waterland@Sun.COM  *			if the pointer is NOT null then the existing string
30419781SMoriah.Waterland@Sun.COM  *			will NOT be overwritten.
30429781SMoriah.Waterland@Sun.COM  *		a_zoneTempDir - pointer to string representing the path
30439781SMoriah.Waterland@Sun.COM  *			to the system temporary directory to create the
30449781SMoriah.Waterland@Sun.COM  *			temporary zone directory in
30459781SMoriah.Waterland@Sun.COM  * Returns:	void
30469781SMoriah.Waterland@Sun.COM  * NOTE:	Any string returned is placed in new storage for the
30479781SMoriah.Waterland@Sun.COM  *		calling method. The caller must use 'free' to dispose
30489781SMoriah.Waterland@Sun.COM  *		of the storage once the string is no longer needed.
30499781SMoriah.Waterland@Sun.COM  * NOTE:	On any error this function will call 'quit(1)'
30509781SMoriah.Waterland@Sun.COM  * NOTE:	This function calls "quitSetZoneTmpdir" on success to
30519781SMoriah.Waterland@Sun.COM  *		register the directory created with quit() so that the
30529781SMoriah.Waterland@Sun.COM  *		directory will be automatically deleted on exit.
30539781SMoriah.Waterland@Sun.COM  */
30549781SMoriah.Waterland@Sun.COM 
30559781SMoriah.Waterland@Sun.COM static void
30569781SMoriah.Waterland@Sun.COM create_zone_tempdir(char **r_zoneTempDir, char *a_tmpdir)
30579781SMoriah.Waterland@Sun.COM {
30589781SMoriah.Waterland@Sun.COM 	boolean_t	b;
30599781SMoriah.Waterland@Sun.COM 
30609781SMoriah.Waterland@Sun.COM 	/* entry assertions */
30619781SMoriah.Waterland@Sun.COM 
30629781SMoriah.Waterland@Sun.COM 	assert(r_zoneTempDir != (char **)NULL);
30639781SMoriah.Waterland@Sun.COM 	assert(a_tmpdir != (char *)NULL);
30649781SMoriah.Waterland@Sun.COM 	assert(*a_tmpdir != '\0');
30659781SMoriah.Waterland@Sun.COM 
30669781SMoriah.Waterland@Sun.COM 	/* entry debugging info */
30679781SMoriah.Waterland@Sun.COM 
30689781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_CREATE_ZONE_TEMPDIR, a_tmpdir);
30699781SMoriah.Waterland@Sun.COM 
30709781SMoriah.Waterland@Sun.COM 	/* if temporary directory already exists, do not overwrite */
30719781SMoriah.Waterland@Sun.COM 
30729781SMoriah.Waterland@Sun.COM 	if (*r_zoneTempDir != (char *)NULL) {
30739781SMoriah.Waterland@Sun.COM 		return;
30749781SMoriah.Waterland@Sun.COM 	}
30759781SMoriah.Waterland@Sun.COM 
30769781SMoriah.Waterland@Sun.COM 	/* create temporary directory */
30779781SMoriah.Waterland@Sun.COM 
30789781SMoriah.Waterland@Sun.COM 	b = setup_temporary_directory(r_zoneTempDir, a_tmpdir, "ztemp");
30799781SMoriah.Waterland@Sun.COM 	if (b == B_FALSE) {
30809781SMoriah.Waterland@Sun.COM 		progerr(ERR_ZONETEMPDIR, a_tmpdir, strerror(errno));
30819781SMoriah.Waterland@Sun.COM 		quit(1);
30829781SMoriah.Waterland@Sun.COM 		/* NOTREACHED */
30839781SMoriah.Waterland@Sun.COM 	}
30849781SMoriah.Waterland@Sun.COM 
30859781SMoriah.Waterland@Sun.COM 	/* register with quit() to directory is removed on exit */
30869781SMoriah.Waterland@Sun.COM 
30879781SMoriah.Waterland@Sun.COM 	quitSetZoneTmpdir(*r_zoneTempDir);
30889781SMoriah.Waterland@Sun.COM 
30899781SMoriah.Waterland@Sun.COM 	/* exit debugging info */
30909781SMoriah.Waterland@Sun.COM 
30919781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_CREATED_ZONE_TEMPDIR, *r_zoneTempDir);
30929781SMoriah.Waterland@Sun.COM }
3093