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