xref: /titanic_53/usr/src/cmd/svr4pkg/pkgrm/main.c (revision 5c51f1241dbbdf2656d0e10011981411ed0c9673)
1*5c51f124SMoriah Waterland /*
2*5c51f124SMoriah Waterland  * CDDL HEADER START
3*5c51f124SMoriah Waterland  *
4*5c51f124SMoriah Waterland  * The contents of this file are subject to the terms of the
5*5c51f124SMoriah Waterland  * Common Development and Distribution License (the "License").
6*5c51f124SMoriah Waterland  * You may not use this file except in compliance with the License.
7*5c51f124SMoriah Waterland  *
8*5c51f124SMoriah Waterland  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*5c51f124SMoriah Waterland  * or http://www.opensolaris.org/os/licensing.
10*5c51f124SMoriah Waterland  * See the License for the specific language governing permissions
11*5c51f124SMoriah Waterland  * and limitations under the License.
12*5c51f124SMoriah Waterland  *
13*5c51f124SMoriah Waterland  * When distributing Covered Code, include this CDDL HEADER in each
14*5c51f124SMoriah Waterland  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*5c51f124SMoriah Waterland  * If applicable, add the following below this CDDL HEADER, with the
16*5c51f124SMoriah Waterland  * fields enclosed by brackets "[]" replaced with your own identifying
17*5c51f124SMoriah Waterland  * information: Portions Copyright [yyyy] [name of copyright owner]
18*5c51f124SMoriah Waterland  *
19*5c51f124SMoriah Waterland  * CDDL HEADER END
20*5c51f124SMoriah Waterland  */
21*5c51f124SMoriah Waterland 
22*5c51f124SMoriah Waterland /*
23*5c51f124SMoriah Waterland  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
24*5c51f124SMoriah Waterland  * Use is subject to license terms.
25*5c51f124SMoriah Waterland  */
26*5c51f124SMoriah Waterland 
27*5c51f124SMoriah Waterland /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
28*5c51f124SMoriah Waterland /* All Rights Reserved */
29*5c51f124SMoriah Waterland 
30*5c51f124SMoriah Waterland 
31*5c51f124SMoriah Waterland /*
32*5c51f124SMoriah Waterland  * System includes
33*5c51f124SMoriah Waterland  */
34*5c51f124SMoriah Waterland 
35*5c51f124SMoriah Waterland #include <stdio.h>
36*5c51f124SMoriah Waterland #include <stdlib.h>
37*5c51f124SMoriah Waterland #include <unistd.h>
38*5c51f124SMoriah Waterland #include <string.h>
39*5c51f124SMoriah Waterland #include <signal.h>
40*5c51f124SMoriah Waterland #include <errno.h>
41*5c51f124SMoriah Waterland #include <locale.h>
42*5c51f124SMoriah Waterland #include <libintl.h>
43*5c51f124SMoriah Waterland #include <pkgstrct.h>
44*5c51f124SMoriah Waterland #include <pkgdev.h>
45*5c51f124SMoriah Waterland #include <pkginfo.h>
46*5c51f124SMoriah Waterland #include <pkglocs.h>
47*5c51f124SMoriah Waterland #include <pkglib.h>
48*5c51f124SMoriah Waterland #include <assert.h>
49*5c51f124SMoriah Waterland 
50*5c51f124SMoriah Waterland /*
51*5c51f124SMoriah Waterland  * libinstzones includes
52*5c51f124SMoriah Waterland  */
53*5c51f124SMoriah Waterland 
54*5c51f124SMoriah Waterland #include <instzones_api.h>
55*5c51f124SMoriah Waterland 
56*5c51f124SMoriah Waterland /*
57*5c51f124SMoriah Waterland  * consolidation pkg command library includes
58*5c51f124SMoriah Waterland  */
59*5c51f124SMoriah Waterland 
60*5c51f124SMoriah Waterland #include <pkglib.h>
61*5c51f124SMoriah Waterland 
62*5c51f124SMoriah Waterland /*
63*5c51f124SMoriah Waterland  * local pkg command library includes
64*5c51f124SMoriah Waterland  */
65*5c51f124SMoriah Waterland 
66*5c51f124SMoriah Waterland #include "install.h"
67*5c51f124SMoriah Waterland #include "libinst.h"
68*5c51f124SMoriah Waterland #include "libadm.h"
69*5c51f124SMoriah Waterland #include "messages.h"
70*5c51f124SMoriah Waterland 
71*5c51f124SMoriah Waterland /*
72*5c51f124SMoriah Waterland  * pkgrm local includes
73*5c51f124SMoriah Waterland  */
74*5c51f124SMoriah Waterland 
75*5c51f124SMoriah Waterland #include "quit.h"
76*5c51f124SMoriah Waterland 
77*5c51f124SMoriah Waterland /*
78*5c51f124SMoriah Waterland  * exported global variables
79*5c51f124SMoriah Waterland  */
80*5c51f124SMoriah Waterland 
81*5c51f124SMoriah Waterland /* these globals are set by ckreturn and used by quit.c */
82*5c51f124SMoriah Waterland 
83*5c51f124SMoriah Waterland int	admnflag = 0;	/* != 0 if any pkg op admin setting failure (4) */
84*5c51f124SMoriah Waterland int	doreboot = 0;	/* != 0 if reboot required after installation */
85*5c51f124SMoriah Waterland int	failflag = 0;	/* != 0 if fatal error has occurred (1) */
86*5c51f124SMoriah Waterland int	intrflag = 0;	/* != 0 if user selected quit (3) */
87*5c51f124SMoriah Waterland int	ireboot = 0;	/* != 0 if immediate reboot required */
88*5c51f124SMoriah Waterland int	nullflag = 0;	/* != 0 if admin interaction required (5) */
89*5c51f124SMoriah Waterland int	warnflag = 0;	/* != 0 if non-fatal error has occurred (2) */
90*5c51f124SMoriah Waterland 
91*5c51f124SMoriah Waterland /* imported by quit.c */
92*5c51f124SMoriah Waterland int	npkgs = 0;	/* the number of packages yet to be installed */
93*5c51f124SMoriah Waterland 
94*5c51f124SMoriah Waterland /* imported by presvr4.c */
95*5c51f124SMoriah Waterland int	started = 0;
96*5c51f124SMoriah Waterland char	*tmpdir = NULL;	/* location to place temporary files */
97*5c51f124SMoriah Waterland 
98*5c51f124SMoriah Waterland /* imported by various (many) */
99*5c51f124SMoriah Waterland struct admin	adm;	/* holds info about installation admin */
100*5c51f124SMoriah Waterland struct pkgdev	pkgdev;	/* holds info about the installation device */
101*5c51f124SMoriah Waterland 
102*5c51f124SMoriah Waterland /*
103*5c51f124SMoriah Waterland  * internal global variables
104*5c51f124SMoriah Waterland  */
105*5c51f124SMoriah Waterland 
106*5c51f124SMoriah Waterland static char	*admnfile = NULL;	/* file to use for installation admin */
107*5c51f124SMoriah Waterland static char	*pkginst = NULL;	/* current pkg/src instance 2 process */
108*5c51f124SMoriah Waterland static char	*vfstab_file = NULL;
109*5c51f124SMoriah Waterland static char	*zoneTempDir = (char *)NULL;
110*5c51f124SMoriah Waterland 
111*5c51f124SMoriah Waterland /* set by ckreturn() */
112*5c51f124SMoriah Waterland 
113*5c51f124SMoriah Waterland static int	interrupted = 0;	/* last pkg op was quit (1,2,3,4,5) */
114*5c51f124SMoriah Waterland 
115*5c51f124SMoriah Waterland static int	nointeract = 0;		/* non-zero - no user interaction */
116*5c51f124SMoriah Waterland static int	pkgrmremote = 0;	/* remove pkg objs stored remotely  */
117*5c51f124SMoriah Waterland static int	pkgverbose = 0;		/* non-zero if verbose mode selected */
118*5c51f124SMoriah Waterland 
119*5c51f124SMoriah Waterland /*
120*5c51f124SMoriah Waterland  * Assume the package complies with the standards as regards user
121*5c51f124SMoriah Waterland  * interaction during procedure scripts.
122*5c51f124SMoriah Waterland  */
123*5c51f124SMoriah Waterland 
124*5c51f124SMoriah Waterland static int	old_pkg = 0;
125*5c51f124SMoriah Waterland static int	old_symlinks = 0;
126*5c51f124SMoriah Waterland static int	no_map_client = 0;
127*5c51f124SMoriah Waterland 
128*5c51f124SMoriah Waterland /* Set by -O nozones: do not process any zones */
129*5c51f124SMoriah Waterland 
130*5c51f124SMoriah Waterland static boolean_t	noZones = B_FALSE;
131*5c51f124SMoriah Waterland 
132*5c51f124SMoriah Waterland /* Set by -O zonelist=<names...>: process only named zones */
133*5c51f124SMoriah Waterland 
134*5c51f124SMoriah Waterland static boolean_t	usedZoneList = B_FALSE;
135*5c51f124SMoriah Waterland 
136*5c51f124SMoriah Waterland /* Set by -O debug: debug output is enabled? */
137*5c51f124SMoriah Waterland 
138*5c51f124SMoriah Waterland static boolean_t	debugFlag = B_FALSE;
139*5c51f124SMoriah Waterland 
140*5c51f124SMoriah Waterland /*
141*5c51f124SMoriah Waterland  * imported (external) functions
142*5c51f124SMoriah Waterland  */
143*5c51f124SMoriah Waterland 
144*5c51f124SMoriah Waterland /* presvr4.c */
145*5c51f124SMoriah Waterland 
146*5c51f124SMoriah Waterland extern int	presvr4(char *pkg, int a_nointeract);
147*5c51f124SMoriah Waterland 
148*5c51f124SMoriah Waterland /* check.c */
149*5c51f124SMoriah Waterland 
150*5c51f124SMoriah Waterland extern int	preremove_verify(char **a_pkgList, zoneList_t a_zlst,
151*5c51f124SMoriah Waterland 			char *a_zoneTempDir);
152*5c51f124SMoriah Waterland /* quit.c */
153*5c51f124SMoriah Waterland 
154*5c51f124SMoriah Waterland extern void	quitSetZonelist(zoneList_t a_zlst);
155*5c51f124SMoriah Waterland 
156*5c51f124SMoriah Waterland /*
157*5c51f124SMoriah Waterland  * imported (external) variables
158*5c51f124SMoriah Waterland  */
159*5c51f124SMoriah Waterland 
160*5c51f124SMoriah Waterland extern char	*pkgdir;
161*5c51f124SMoriah Waterland 
162*5c51f124SMoriah Waterland /* printable string - if string is null results in ??? */
163*5c51f124SMoriah Waterland 
164*5c51f124SMoriah Waterland #define	PSTR(STR) (((STR) == (char *)NULL) ? "???" : (STR))
165*5c51f124SMoriah Waterland 
166*5c51f124SMoriah Waterland #define	MAX_FDS	20
167*5c51f124SMoriah Waterland 
168*5c51f124SMoriah Waterland #if !defined(TEXT_DOMAIN)	/* Should be defined by cc -D */
169*5c51f124SMoriah Waterland #define	TEXT_DOMAIN "SYS_TEST"
170*5c51f124SMoriah Waterland #endif
171*5c51f124SMoriah Waterland 
172*5c51f124SMoriah Waterland #define	INHERITFS	"inherited-filesystem="
173*5c51f124SMoriah Waterland #define	INHERITFS_LEN	((sizeof (INHERITFS))-1)
174*5c51f124SMoriah Waterland 
175*5c51f124SMoriah Waterland /*
176*5c51f124SMoriah Waterland  * forward declarations
177*5c51f124SMoriah Waterland  */
178*5c51f124SMoriah Waterland 
179*5c51f124SMoriah Waterland static void		ckreturn(int retcode);
180*5c51f124SMoriah Waterland static void		create_zone_adminfile(char **r_zoneAdminFile,
181*5c51f124SMoriah Waterland 				char *a_zoneTempDir, char *a_admnfile);
182*5c51f124SMoriah Waterland static void		create_zone_tempdir(char **r_zoneTempDir,
183*5c51f124SMoriah Waterland 				char *a_tmpdir);
184*5c51f124SMoriah Waterland static int		doRemove(int a_nodelete, char *a_altBinDir,
185*5c51f124SMoriah Waterland 				int a_longestPkg, char *a_adminFile,
186*5c51f124SMoriah Waterland 				char *a_zoneAdminFile, zoneList_t zlst);
187*5c51f124SMoriah Waterland static int		pkgRemove(int a_nodelete, char *a_altBinDir,
188*5c51f124SMoriah Waterland 				char *a_adminFile, char **a_inheritedPkgDirs);
189*5c51f124SMoriah Waterland static int		pkgZoneCheckRemove(char *a_zoneName,
190*5c51f124SMoriah Waterland 				char **a_inheritedPkgDirs, char *a_altBinDir,
191*5c51f124SMoriah Waterland 				char *a_adminFile, char *a_stdoutPath,
192*5c51f124SMoriah Waterland 				zone_state_t a_zoneState);
193*5c51f124SMoriah Waterland static int		pkgZoneRemove(char *a_zoneName,
194*5c51f124SMoriah Waterland 				char **a_inheritedPkgDirs, int a_nodelete,
195*5c51f124SMoriah Waterland 				char *a_altBinDir, char *a_adminFile,
196*5c51f124SMoriah Waterland 				zone_state_t a_zoneState);
197*5c51f124SMoriah Waterland static void		resetreturn();
198*5c51f124SMoriah Waterland static void		usage(void);
199*5c51f124SMoriah Waterland static boolean_t	check_applicability(char *a_packageDir,
200*5c51f124SMoriah Waterland 				char *a_pkgInst, char *a_rootPath,
201*5c51f124SMoriah Waterland 				CAF_T a_flags);
202*5c51f124SMoriah Waterland static boolean_t	check_packages(char **a_pkgList, char *a_packageDir);
203*5c51f124SMoriah Waterland static boolean_t	path_valid(char *path);
204*5c51f124SMoriah Waterland static boolean_t	remove_packages(char **a_pkgList, int a_nodelete,
205*5c51f124SMoriah Waterland 				int a_longestPkg, int a_repeat,
206*5c51f124SMoriah Waterland 				char *a_altBinDir, char *a_pkgdir,
207*5c51f124SMoriah Waterland 				char *a_spoolDir, boolean_t a_noZones);
208*5c51f124SMoriah Waterland static boolean_t	remove_packages_from_spool_directory(char **a_pkgList,
209*5c51f124SMoriah Waterland 				int a_nodelete, int a_longestPkg, int a_repeat,
210*5c51f124SMoriah Waterland 				char *a_altBinDir);
211*5c51f124SMoriah Waterland static boolean_t	remove_packages_in_global_no_zones(char **a_pkgList,
212*5c51f124SMoriah Waterland 				int a_nodelete, int a_longestPkg, int a_repeat,
213*5c51f124SMoriah Waterland 				char *a_altBinDir);
214*5c51f124SMoriah Waterland static boolean_t	remove_packages_in_global_with_zones(char **a_pkgList,
215*5c51f124SMoriah Waterland 				int a_nodelete, int a_longestPkg, int a_repeat,
216*5c51f124SMoriah Waterland 				char *a_altBinDir, char *a_pkgdir,
217*5c51f124SMoriah Waterland 				zoneList_t a_zlst);
218*5c51f124SMoriah Waterland static boolean_t	remove_packages_in_nonglobal_zone(char **a_pkgList,
219*5c51f124SMoriah Waterland 				int a_nodelete, int a_longestPkg, int a_repeat,
220*5c51f124SMoriah Waterland 				char *a_altBinDir, char *a_pkgdir);
221*5c51f124SMoriah Waterland static boolean_t	shall_we_continue(char *a_pkgInst, int a_npkgs);
222*5c51f124SMoriah Waterland 
223*5c51f124SMoriah Waterland /*
224*5c51f124SMoriah Waterland  * *****************************************************************************
225*5c51f124SMoriah Waterland  * global external (public) functions
226*5c51f124SMoriah Waterland  * *****************************************************************************
227*5c51f124SMoriah Waterland  */
228*5c51f124SMoriah Waterland 
229*5c51f124SMoriah Waterland /*
230*5c51f124SMoriah Waterland  * Name:	main
231*5c51f124SMoriah Waterland  * Description:	main entry point for pkgrm
232*5c51f124SMoriah Waterland  * Returns:	int
233*5c51f124SMoriah Waterland  *   0        Successful completion
234*5c51f124SMoriah Waterland  *   1        Fatal error.
235*5c51f124SMoriah Waterland  *   2        Warning.
236*5c51f124SMoriah Waterland  *   3        Interruption.
237*5c51f124SMoriah Waterland  *   4        Administration.
238*5c51f124SMoriah Waterland  *   5        Administration. Interaction is required. Do not use pkgrm -n.
239*5c51f124SMoriah Waterland  *  10       Reboot after removal of all packages.
240*5c51f124SMoriah Waterland  *  20       Reboot after removal of this package.
241*5c51f124SMoriah Waterland  */
242*5c51f124SMoriah Waterland 
243*5c51f124SMoriah Waterland int
244*5c51f124SMoriah Waterland main(int argc, char **argv)
245*5c51f124SMoriah Waterland {
246*5c51f124SMoriah Waterland 	char			**category = NULL;
247*5c51f124SMoriah Waterland 	char			*altBinDir = (char *)NULL;
248*5c51f124SMoriah Waterland 	char			*catg_arg = NULL;
249*5c51f124SMoriah Waterland 	char			*p;
250*5c51f124SMoriah Waterland 	char			*prog_full_name = NULL;
251*5c51f124SMoriah Waterland 	char			*spoolDir = 0;
252*5c51f124SMoriah Waterland 	int			c;
253*5c51f124SMoriah Waterland 	int			longestPkg = 0;
254*5c51f124SMoriah Waterland 	int			n;
255*5c51f124SMoriah Waterland 	int			nodelete = 0;	/* dont rm files/run scripts */
256*5c51f124SMoriah Waterland 	int			pkgLgth = 0;
257*5c51f124SMoriah Waterland 	int			repeat;
258*5c51f124SMoriah Waterland 	struct sigaction	nact;
259*5c51f124SMoriah Waterland 	struct sigaction	oact;
260*5c51f124SMoriah Waterland 
261*5c51f124SMoriah Waterland 	/* initialize locale environment */
262*5c51f124SMoriah Waterland 
263*5c51f124SMoriah Waterland 	(void) setlocale(LC_ALL, "");
264*5c51f124SMoriah Waterland 	(void) textdomain(TEXT_DOMAIN);
265*5c51f124SMoriah Waterland 
266*5c51f124SMoriah Waterland 	/* initialize program name */
267*5c51f124SMoriah Waterland 
268*5c51f124SMoriah Waterland 	prog_full_name = argv[0];
269*5c51f124SMoriah Waterland 	(void) set_prog_name(argv[0]);
270*5c51f124SMoriah Waterland 
271*5c51f124SMoriah Waterland 	/* tell spmi zones interface how to access package output functions */
272*5c51f124SMoriah Waterland 
273*5c51f124SMoriah Waterland 	z_set_output_functions(echo, echoDebug, progerr);
274*5c51f124SMoriah Waterland 
275*5c51f124SMoriah Waterland 	/* tell quit which ckreturn function to call */
276*5c51f124SMoriah Waterland 
277*5c51f124SMoriah Waterland 	quitSetCkreturnFunc(&ckreturn);
278*5c51f124SMoriah Waterland 
279*5c51f124SMoriah Waterland 	/* Read PKG_INSTALL_ROOT from the environment, if it's there. */
280*5c51f124SMoriah Waterland 
281*5c51f124SMoriah Waterland 	if (!set_inst_root(getenv("PKG_INSTALL_ROOT"))) {
282*5c51f124SMoriah Waterland 		progerr(ERR_ROOT_SET);
283*5c51f124SMoriah Waterland 		exit(1);
284*5c51f124SMoriah Waterland 	}
285*5c51f124SMoriah Waterland 
286*5c51f124SMoriah Waterland 	if (z_running_in_global_zone() && !enable_local_fs()) {
287*5c51f124SMoriah Waterland 		progerr(ERR_CANNOT_ENABLE_LOCAL_FS);
288*5c51f124SMoriah Waterland 	}
289*5c51f124SMoriah Waterland 
290*5c51f124SMoriah Waterland 	/*
291*5c51f124SMoriah Waterland 	 * ********************************************************************
292*5c51f124SMoriah Waterland 	 * parse command line options
293*5c51f124SMoriah Waterland 	 * ********************************************************************
294*5c51f124SMoriah Waterland 	 */
295*5c51f124SMoriah Waterland 
296*5c51f124SMoriah Waterland 	while ((c = getopt(argc, argv, "?Aa:b:FMnO:R:s:V:vY:Z")) != EOF) {
297*5c51f124SMoriah Waterland 		switch (c) {
298*5c51f124SMoriah Waterland 		/*
299*5c51f124SMoriah Waterland 		 * Public interface: Allow admin to remove objects
300*5c51f124SMoriah Waterland 		 * from a service area via a reference client.
301*5c51f124SMoriah Waterland 		 * Remove the package files from the client's file
302*5c51f124SMoriah Waterland 		 * system, absolutely. If a file is shared with other
303*5c51f124SMoriah Waterland 		 * packages, the default behavior is to not remove
304*5c51f124SMoriah Waterland 		 * the file from the client's file system.
305*5c51f124SMoriah Waterland 		 */
306*5c51f124SMoriah Waterland 		case 'A':
307*5c51f124SMoriah Waterland 		    pkgrmremote++;
308*5c51f124SMoriah Waterland 		    break;
309*5c51f124SMoriah Waterland 
310*5c51f124SMoriah Waterland 		/*
311*5c51f124SMoriah Waterland 		 * Public interface: Use the installation
312*5c51f124SMoriah Waterland 		 * administration file, admin, in place of the
313*5c51f124SMoriah Waterland 		 * default admin file. pkgrm first looks in the
314*5c51f124SMoriah Waterland 		 * current working directory for the administration
315*5c51f124SMoriah Waterland 		 * file.  If the specified administration file is not
316*5c51f124SMoriah Waterland 		 * in the current working directory, pkgrm looks in
317*5c51f124SMoriah Waterland 		 * the /var/sadm/install/admin directory for the
318*5c51f124SMoriah Waterland 		 * administra- tion file.
319*5c51f124SMoriah Waterland 		 */
320*5c51f124SMoriah Waterland 		case 'a':
321*5c51f124SMoriah Waterland 		    admnfile = flex_device(optarg, 0);
322*5c51f124SMoriah Waterland 		    break;
323*5c51f124SMoriah Waterland 
324*5c51f124SMoriah Waterland 		/*
325*5c51f124SMoriah Waterland 		 * Not a public interface:  location where package executables
326*5c51f124SMoriah Waterland 		 * can be found - default is /usr/sadm/install/bin.
327*5c51f124SMoriah Waterland 		 */
328*5c51f124SMoriah Waterland 		case 'b':
329*5c51f124SMoriah Waterland 			if (!path_valid(optarg)) {
330*5c51f124SMoriah Waterland 				progerr(ERR_PATH, optarg);
331*5c51f124SMoriah Waterland 				quit(1);
332*5c51f124SMoriah Waterland 			}
333*5c51f124SMoriah Waterland 			if (isdir(optarg) != 0) {
334*5c51f124SMoriah Waterland 				p = strerror(errno);
335*5c51f124SMoriah Waterland 				progerr(ERR_CANNOT_USE_DIR, optarg, p);
336*5c51f124SMoriah Waterland 				quit(1);
337*5c51f124SMoriah Waterland 			}
338*5c51f124SMoriah Waterland 			altBinDir = optarg;
339*5c51f124SMoriah Waterland 			break;
340*5c51f124SMoriah Waterland 
341*5c51f124SMoriah Waterland 		/*
342*5c51f124SMoriah Waterland 		 * Not a public interface: pass -F option to
343*5c51f124SMoriah Waterland 		 * pkgremove which suppresses the removal of any
344*5c51f124SMoriah Waterland 		 * files and any class action scripts, and suppresses
345*5c51f124SMoriah Waterland 		 * the running of any class action scripts.  The
346*5c51f124SMoriah Waterland 		 * package files remain but the package looks like it
347*5c51f124SMoriah Waterland 		 * is not installed. This is mainly for use by the
348*5c51f124SMoriah Waterland 		 * upgrade process.
349*5c51f124SMoriah Waterland 		 */
350*5c51f124SMoriah Waterland 		case 'F':
351*5c51f124SMoriah Waterland 		    nodelete++;
352*5c51f124SMoriah Waterland 		    break;
353*5c51f124SMoriah Waterland 
354*5c51f124SMoriah Waterland 		/*
355*5c51f124SMoriah Waterland 		 * Public interface: Instruct pkgrm not to use the
356*5c51f124SMoriah Waterland 		 * $root_path/etc/vfstab file for determining the
357*5c51f124SMoriah Waterland 		 * client's mount points. This option assumes the
358*5c51f124SMoriah Waterland 		 * mount points are correct on the server and it
359*5c51f124SMoriah Waterland 		 * behaves consistently with Solaris 2.5 and earlier
360*5c51f124SMoriah Waterland 		 * releases.
361*5c51f124SMoriah Waterland 		 */
362*5c51f124SMoriah Waterland 		case 'M':
363*5c51f124SMoriah Waterland 		    no_map_client = 1;
364*5c51f124SMoriah Waterland 		    break;
365*5c51f124SMoriah Waterland 
366*5c51f124SMoriah Waterland 		/*
367*5c51f124SMoriah Waterland 		 * Public interface: package removal occurs in
368*5c51f124SMoriah Waterland 		 * non-interactive mode.  Suppress output of the list of
369*5c51f124SMoriah Waterland 		 * removed files. The default mode is interactive.
370*5c51f124SMoriah Waterland 		 */
371*5c51f124SMoriah Waterland 		case 'n':
372*5c51f124SMoriah Waterland 		    nointeract++;
373*5c51f124SMoriah Waterland 		    (void) echoSetFlag(B_FALSE);
374*5c51f124SMoriah Waterland 		    break;
375*5c51f124SMoriah Waterland 
376*5c51f124SMoriah Waterland 		/*
377*5c51f124SMoriah Waterland 		 * Not a public interface: the -O option allows the behavior
378*5c51f124SMoriah Waterland 		 * of the package tools to be modified. Recognized options:
379*5c51f124SMoriah Waterland 		 * -> debug
380*5c51f124SMoriah Waterland 		 * ---> enable debugging output
381*5c51f124SMoriah Waterland 		 * -> nozones
382*5c51f124SMoriah Waterland 		 * ---> act as though in global zone with no non-global zones
383*5c51f124SMoriah Waterland 		 * -> inherited-filesystems
384*5c51f124SMoriah Waterland 		 * ---> add specified file system to list of file systems
385*5c51f124SMoriah Waterland 		 * ---> that are inherited from the global zone
386*5c51f124SMoriah Waterland 		 * -> enable-hollow-package-support
387*5c51f124SMoriah Waterland 		 * --> Enable hollow package support. When specified, for any
388*5c51f124SMoriah Waterland 		 * --> package that has SUNW_PKG_HOLLOW=true:
389*5c51f124SMoriah Waterland 		 * --> Do not calculate and verify package size against target
390*5c51f124SMoriah Waterland 		 * --> Do not run any package procedure or class action scripts
391*5c51f124SMoriah Waterland 		 * --> Do not create or remove any target directories
392*5c51f124SMoriah Waterland 		 * --> Do not perform any script locking
393*5c51f124SMoriah Waterland 		 * --> Do not install or uninstall any components of any package
394*5c51f124SMoriah Waterland 		 * --> Do not output any status or database update messages
395*5c51f124SMoriah Waterland 		 * -> zonelist="<names...>"
396*5c51f124SMoriah Waterland 		 * ---> add package to space-separated list of zones only
397*5c51f124SMoriah Waterland 		 */
398*5c51f124SMoriah Waterland 
399*5c51f124SMoriah Waterland 		case 'O':
400*5c51f124SMoriah Waterland 			for (p = strtok(optarg, ","); p != (char *)NULL;
401*5c51f124SMoriah Waterland 				p = strtok(NULL, ",")) {
402*5c51f124SMoriah Waterland 
403*5c51f124SMoriah Waterland 				if (strcmp(p, "nozones") == 0) {
404*5c51f124SMoriah Waterland 					noZones = B_TRUE;
405*5c51f124SMoriah Waterland 					continue;
406*5c51f124SMoriah Waterland 				}
407*5c51f124SMoriah Waterland 
408*5c51f124SMoriah Waterland 				if (strncmp(p, INHERITFS, INHERITFS_LEN) == 0) {
409*5c51f124SMoriah Waterland 					if (z_add_inherited_file_system(
410*5c51f124SMoriah Waterland 						p+INHERITFS_LEN) == B_FALSE) {
411*5c51f124SMoriah Waterland 						progerr(ERR_NOSUCH_INHERITED,
412*5c51f124SMoriah Waterland 							p+INHERITFS_LEN);
413*5c51f124SMoriah Waterland 						quit(1);
414*5c51f124SMoriah Waterland 						/* NOTREACHED */
415*5c51f124SMoriah Waterland 					}
416*5c51f124SMoriah Waterland 					continue;
417*5c51f124SMoriah Waterland 				}
418*5c51f124SMoriah Waterland 
419*5c51f124SMoriah Waterland 				if (strcmp(p,
420*5c51f124SMoriah Waterland 					"enable-hollow-package-support") == 0) {
421*5c51f124SMoriah Waterland 					set_depend_pkginfo_DB(B_TRUE);
422*5c51f124SMoriah Waterland 					continue;
423*5c51f124SMoriah Waterland 				}
424*5c51f124SMoriah Waterland 
425*5c51f124SMoriah Waterland 				if (strcmp(p, "debug") == 0) {
426*5c51f124SMoriah Waterland 					/* set debug flag/enable debug output */
427*5c51f124SMoriah Waterland 					debugFlag = B_TRUE;
428*5c51f124SMoriah Waterland 					(void) echoDebugSetFlag(debugFlag);
429*5c51f124SMoriah Waterland 
430*5c51f124SMoriah Waterland 					/* debug info on arguments to pkgadd */
431*5c51f124SMoriah Waterland 					for (n = 0; n < argc && argv[n]; n++) {
432*5c51f124SMoriah Waterland 						echoDebug(DBG_ARG, n, argv[n]);
433*5c51f124SMoriah Waterland 					}
434*5c51f124SMoriah Waterland 
435*5c51f124SMoriah Waterland 					continue;
436*5c51f124SMoriah Waterland 				}
437*5c51f124SMoriah Waterland 
438*5c51f124SMoriah Waterland 				if (strncmp(p, "zonelist=", 9) == 0) {
439*5c51f124SMoriah Waterland 					if (z_set_zone_spec(p + 9) == -1)
440*5c51f124SMoriah Waterland 						quit(1);
441*5c51f124SMoriah Waterland 					usedZoneList = B_TRUE;
442*5c51f124SMoriah Waterland 					continue;
443*5c51f124SMoriah Waterland 				}
444*5c51f124SMoriah Waterland 
445*5c51f124SMoriah Waterland 				/* -O option not recognized - issue warning */
446*5c51f124SMoriah Waterland 
447*5c51f124SMoriah Waterland 				progerr(ERR_INVALID_O_OPTION, p);
448*5c51f124SMoriah Waterland 				continue;
449*5c51f124SMoriah Waterland 			}
450*5c51f124SMoriah Waterland 			break;
451*5c51f124SMoriah Waterland 
452*5c51f124SMoriah Waterland 		/*
453*5c51f124SMoriah Waterland 		 * Public interface: defines the full path name of a
454*5c51f124SMoriah Waterland 		 * directory to use as the root_path.  All files,
455*5c51f124SMoriah Waterland 		 * including package system information files, are
456*5c51f124SMoriah Waterland 		 * relocated to a directory tree starting in the
457*5c51f124SMoriah Waterland 		 * specified root_path.
458*5c51f124SMoriah Waterland 		 */
459*5c51f124SMoriah Waterland 		case 'R':
460*5c51f124SMoriah Waterland 		    if (!set_inst_root(optarg)) {
461*5c51f124SMoriah Waterland 			    progerr(ERR_ROOT_CMD);
462*5c51f124SMoriah Waterland 			    exit(1);
463*5c51f124SMoriah Waterland 		    }
464*5c51f124SMoriah Waterland 		    break;
465*5c51f124SMoriah Waterland 
466*5c51f124SMoriah Waterland 		/*
467*5c51f124SMoriah Waterland 		 * Public interface: remove the specified package(s)
468*5c51f124SMoriah Waterland 		 * from the directory spool.  The default directory
469*5c51f124SMoriah Waterland 		 * for spooled packages is /var/sadm/pkg.
470*5c51f124SMoriah Waterland 		 */
471*5c51f124SMoriah Waterland 		case 's':
472*5c51f124SMoriah Waterland 		    spoolDir = flex_device(optarg, 1);
473*5c51f124SMoriah Waterland 		    break;
474*5c51f124SMoriah Waterland 
475*5c51f124SMoriah Waterland 		/*
476*5c51f124SMoriah Waterland 		 * Public interface: Allow admin to establish the client
477*5c51f124SMoriah Waterland 		 * filesystem using a vfstab-like file of stable format.
478*5c51f124SMoriah Waterland 		 */
479*5c51f124SMoriah Waterland 		case 'V':
480*5c51f124SMoriah Waterland 		    vfstab_file = flex_device(optarg, 2);
481*5c51f124SMoriah Waterland 		    no_map_client = 0;
482*5c51f124SMoriah Waterland 		    break;
483*5c51f124SMoriah Waterland 
484*5c51f124SMoriah Waterland 		/*
485*5c51f124SMoriah Waterland 		 * Public interface: trace all of the scripts that
486*5c51f124SMoriah Waterland 		 * get executed by pkgrm, located in the
487*5c51f124SMoriah Waterland 		 * pkginst/install directory. This option is used for
488*5c51f124SMoriah Waterland 		 * debugging the procedural and non- procedural
489*5c51f124SMoriah Waterland 		 * scripts.
490*5c51f124SMoriah Waterland 		 */
491*5c51f124SMoriah Waterland 		case 'v':
492*5c51f124SMoriah Waterland 		    pkgverbose++;
493*5c51f124SMoriah Waterland 		    break;
494*5c51f124SMoriah Waterland 
495*5c51f124SMoriah Waterland 		/*
496*5c51f124SMoriah Waterland 		 * Public interface: remove packages based on the
497*5c51f124SMoriah Waterland 		 * CATEGORY variable from the installed/spooled
498*5c51f124SMoriah Waterland 		 * pkginfo file
499*5c51f124SMoriah Waterland 		 */
500*5c51f124SMoriah Waterland 		case 'Y':
501*5c51f124SMoriah Waterland 		    catg_arg = strdup(optarg);
502*5c51f124SMoriah Waterland 
503*5c51f124SMoriah Waterland 		    if ((category = get_categories(catg_arg)) == NULL) {
504*5c51f124SMoriah Waterland 			    progerr(ERR_CAT_INV, catg_arg);
505*5c51f124SMoriah Waterland 			    exit(1);
506*5c51f124SMoriah Waterland 		    } else if (is_not_valid_category(category,
507*5c51f124SMoriah Waterland 				    get_prog_name())) {
508*5c51f124SMoriah Waterland 			    progerr(ERR_CAT_SYS);
509*5c51f124SMoriah Waterland 			    exit(1);
510*5c51f124SMoriah Waterland 		    } else if (is_not_valid_length(category)) {
511*5c51f124SMoriah Waterland 			    progerr(ERR_CAT_LNGTH);
512*5c51f124SMoriah Waterland 			    exit(1);
513*5c51f124SMoriah Waterland 		    }
514*5c51f124SMoriah Waterland 
515*5c51f124SMoriah Waterland 		    break;
516*5c51f124SMoriah Waterland 
517*5c51f124SMoriah Waterland 		/*
518*5c51f124SMoriah Waterland 		 * unrecognized option
519*5c51f124SMoriah Waterland 		 */
520*5c51f124SMoriah Waterland 		default:
521*5c51f124SMoriah Waterland 		    usage();
522*5c51f124SMoriah Waterland 		    /* NOTREACHED */
523*5c51f124SMoriah Waterland 		}
524*5c51f124SMoriah Waterland 	}
525*5c51f124SMoriah Waterland 
526*5c51f124SMoriah Waterland 	/*
527*5c51f124SMoriah Waterland 	 * ********************************************************************
528*5c51f124SMoriah Waterland 	 * validate command line options
529*5c51f124SMoriah Waterland 	 * ********************************************************************
530*5c51f124SMoriah Waterland 	 */
531*5c51f124SMoriah Waterland 
532*5c51f124SMoriah Waterland 	/* set "debug echo" flag according to setting of "-O debug" option */
533*5c51f124SMoriah Waterland 
534*5c51f124SMoriah Waterland 	(void) echoDebugSetFlag(debugFlag);
535*5c51f124SMoriah Waterland 
536*5c51f124SMoriah Waterland 	/* output entry debugging information */
537*5c51f124SMoriah Waterland 
538*5c51f124SMoriah Waterland 	if (z_running_in_global_zone()) {
539*5c51f124SMoriah Waterland 		echoDebug(DBG_ENTRY_IN_GZ, prog_full_name);
540*5c51f124SMoriah Waterland 	} else {
541*5c51f124SMoriah Waterland 		echoDebug(DBG_ENTRY_IN_LZ, prog_full_name, getzoneid(),
542*5c51f124SMoriah Waterland 			z_get_zonename());
543*5c51f124SMoriah Waterland 	}
544*5c51f124SMoriah Waterland 
545*5c51f124SMoriah Waterland 	/* -s cannot be used with several */
546*5c51f124SMoriah Waterland 
547*5c51f124SMoriah Waterland 	if (spoolDir != (char *)NULL) {
548*5c51f124SMoriah Waterland 		if (admnfile != (char *)NULL) {
549*5c51f124SMoriah Waterland 			progerr(ERR_SPOOLDIR_AND_ADMNFILE);
550*5c51f124SMoriah Waterland 			usage();
551*5c51f124SMoriah Waterland 			/* NOTREACHED */
552*5c51f124SMoriah Waterland 		}
553*5c51f124SMoriah Waterland 
554*5c51f124SMoriah Waterland 		if (pkgrmremote != 0) {
555*5c51f124SMoriah Waterland 			progerr(ERR_SPOOLDIR_AND_PKGRMREMOTE);
556*5c51f124SMoriah Waterland 			usage();
557*5c51f124SMoriah Waterland 			/* NOTREACHED */
558*5c51f124SMoriah Waterland 		}
559*5c51f124SMoriah Waterland 
560*5c51f124SMoriah Waterland 		if (pkgverbose != 0) {
561*5c51f124SMoriah Waterland 			progerr(ERR_SPOOLDIR_AND_PKGVERBOSE);
562*5c51f124SMoriah Waterland 			usage();
563*5c51f124SMoriah Waterland 			/* NOTREACHED */
564*5c51f124SMoriah Waterland 		}
565*5c51f124SMoriah Waterland 
566*5c51f124SMoriah Waterland 		if (is_an_inst_root() != 0) {
567*5c51f124SMoriah Waterland 			progerr(ERR_SPOOLDIR_AND_INST_ROOT);
568*5c51f124SMoriah Waterland 			usage();
569*5c51f124SMoriah Waterland 			/* NOTREACHED */
570*5c51f124SMoriah Waterland 		}
571*5c51f124SMoriah Waterland 	}
572*5c51f124SMoriah Waterland 
573*5c51f124SMoriah Waterland 	/* -V cannot be used with -A */
574*5c51f124SMoriah Waterland 
575*5c51f124SMoriah Waterland 	if (no_map_client && pkgrmremote) {
576*5c51f124SMoriah Waterland 		progerr(ERR_V_USED_AND_PKGRMREMOTE);
577*5c51f124SMoriah Waterland 		usage();
578*5c51f124SMoriah Waterland 		/* NOTREACHED */
579*5c51f124SMoriah Waterland 	}
580*5c51f124SMoriah Waterland 
581*5c51f124SMoriah Waterland 	/* -n used without pkg names or category */
582*5c51f124SMoriah Waterland 
583*5c51f124SMoriah Waterland 	if (nointeract && (optind == argc) && (catg_arg == NULL)) {
584*5c51f124SMoriah Waterland 		progerr(ERR_BAD_N_PKGRM);
585*5c51f124SMoriah Waterland 		usage();
586*5c51f124SMoriah Waterland 		/* NOTREACHED */
587*5c51f124SMoriah Waterland 	}
588*5c51f124SMoriah Waterland 
589*5c51f124SMoriah Waterland 	/* Error if specified zone list isn't valid on target */
590*5c51f124SMoriah Waterland 	if (usedZoneList && z_verify_zone_spec() == -1)
591*5c51f124SMoriah Waterland 		usage();
592*5c51f124SMoriah Waterland 
593*5c51f124SMoriah Waterland 	/*
594*5c51f124SMoriah Waterland 	 * hook SIGINT and SIGHUP interrupts into quit.c's trap handler
595*5c51f124SMoriah Waterland 	 */
596*5c51f124SMoriah Waterland 
597*5c51f124SMoriah Waterland 	/* hold SIGINT/SIGHUP interrupts */
598*5c51f124SMoriah Waterland 
599*5c51f124SMoriah Waterland 	(void) sighold(SIGHUP);
600*5c51f124SMoriah Waterland 	(void) sighold(SIGINT);
601*5c51f124SMoriah Waterland 
602*5c51f124SMoriah Waterland 	/* connect quit.c:trap() to SIGINT */
603*5c51f124SMoriah Waterland 
604*5c51f124SMoriah Waterland 	nact.sa_handler = quitGetTrapHandler();
605*5c51f124SMoriah Waterland 	nact.sa_flags = SA_RESTART;
606*5c51f124SMoriah Waterland 	(void) sigemptyset(&nact.sa_mask);
607*5c51f124SMoriah Waterland 
608*5c51f124SMoriah Waterland 	(void) sigaction(SIGINT, &nact, &oact);
609*5c51f124SMoriah Waterland 
610*5c51f124SMoriah Waterland 	/* connect quit.c:trap() to SIGHUP */
611*5c51f124SMoriah Waterland 
612*5c51f124SMoriah Waterland 	nact.sa_handler = quitGetTrapHandler();
613*5c51f124SMoriah Waterland 	nact.sa_flags = SA_RESTART;
614*5c51f124SMoriah Waterland 	(void) sigemptyset(&nact.sa_mask);
615*5c51f124SMoriah Waterland 
616*5c51f124SMoriah Waterland 	(void) sigaction(SIGHUP, &nact, &oact);
617*5c51f124SMoriah Waterland 
618*5c51f124SMoriah Waterland 	/* release hold on signals */
619*5c51f124SMoriah Waterland 
620*5c51f124SMoriah Waterland 	(void) sigrelse(SIGHUP);
621*5c51f124SMoriah Waterland 	(void) sigrelse(SIGINT);
622*5c51f124SMoriah Waterland 
623*5c51f124SMoriah Waterland 	/* establish temporary directory to use */
624*5c51f124SMoriah Waterland 
625*5c51f124SMoriah Waterland 	tmpdir = getenv("TMPDIR");
626*5c51f124SMoriah Waterland 	if (tmpdir == NULL) {
627*5c51f124SMoriah Waterland 		tmpdir = P_tmpdir;
628*5c51f124SMoriah Waterland 	}
629*5c51f124SMoriah Waterland 
630*5c51f124SMoriah Waterland 	echoDebug(DBG_PKGRM_TMPDIR, tmpdir);
631*5c51f124SMoriah Waterland 
632*5c51f124SMoriah Waterland 	/* initialize path parameters */
633*5c51f124SMoriah Waterland 
634*5c51f124SMoriah Waterland 	set_PKGpaths(get_inst_root());
635*5c51f124SMoriah Waterland 
636*5c51f124SMoriah Waterland 	/*
637*5c51f124SMoriah Waterland 	 * initialize installation admin parameters - if removing from a spool
638*5c51f124SMoriah Waterland 	 * directory then the admin file is ignore.
639*5c51f124SMoriah Waterland 	 */
640*5c51f124SMoriah Waterland 
641*5c51f124SMoriah Waterland 	if (spoolDir == NULL) {
642*5c51f124SMoriah Waterland 		echoDebug(DBG_PKGRM_ADMINFILE, admnfile ? admnfile : "");
643*5c51f124SMoriah Waterland 		setadminFile(admnfile);
644*5c51f124SMoriah Waterland 	}
645*5c51f124SMoriah Waterland 
646*5c51f124SMoriah Waterland 	/*
647*5c51f124SMoriah Waterland 	 * if running in the global zone, and non-global zones exist, then
648*5c51f124SMoriah Waterland 	 * enable hollow package support so that any packages that are marked
649*5c51f124SMoriah Waterland 	 * SUNW_PKG_HOLLOW=true will be correctly removed in non-global zones
650*5c51f124SMoriah Waterland 	 * when removed directly in the global zone by the global zone admin.
651*5c51f124SMoriah Waterland 	 */
652*5c51f124SMoriah Waterland 
653*5c51f124SMoriah Waterland 	if (is_depend_pkginfo_DB()) {
654*5c51f124SMoriah Waterland 		echoDebug(DBG_PKGRM_HOLLOW_ENABLED);
655*5c51f124SMoriah Waterland 	} else if ((z_running_in_global_zone() == B_TRUE) &&
656*5c51f124SMoriah Waterland 		(z_non_global_zones_exist() == B_TRUE)) {
657*5c51f124SMoriah Waterland 		echoDebug(DBG_PKGRM_ENABLING_HOLLOW);
658*5c51f124SMoriah Waterland 		set_depend_pkginfo_DB(B_TRUE);
659*5c51f124SMoriah Waterland 	}
660*5c51f124SMoriah Waterland 
661*5c51f124SMoriah Waterland 	/*
662*5c51f124SMoriah Waterland 	 * See if user wants this to be handled as an old style pkg.
663*5c51f124SMoriah Waterland 	 * NOTE : the ``exception_pkg()'' stuff is to be used only
664*5c51f124SMoriah Waterland 	 * through on495. This function comes out for on1095. See
665*5c51f124SMoriah Waterland 	 * PSARC 1993-546. -- JST
666*5c51f124SMoriah Waterland 	 */
667*5c51f124SMoriah Waterland 	if (getenv("NONABI_SCRIPTS") != NULL) {
668*5c51f124SMoriah Waterland 		old_pkg = 1;
669*5c51f124SMoriah Waterland 	}
670*5c51f124SMoriah Waterland 
671*5c51f124SMoriah Waterland 	/*
672*5c51f124SMoriah Waterland 	 * See if the user wants to process symlinks consistent with
673*5c51f124SMoriah Waterland 	 * the old behavior.
674*5c51f124SMoriah Waterland 	 */
675*5c51f124SMoriah Waterland 
676*5c51f124SMoriah Waterland 	if (getenv("PKG_NONABI_SYMLINKS") != NULL) {
677*5c51f124SMoriah Waterland 		old_symlinks = 1;
678*5c51f124SMoriah Waterland 	}
679*5c51f124SMoriah Waterland 
680*5c51f124SMoriah Waterland 	if (devtype((spoolDir ? spoolDir : get_PKGLOC()), &pkgdev) ||
681*5c51f124SMoriah Waterland 	    pkgdev.dirname == NULL) {
682*5c51f124SMoriah Waterland 		progerr(ERR_BAD_DEVICE, spoolDir ? spoolDir : get_PKGLOC());
683*5c51f124SMoriah Waterland 		quit(1);
684*5c51f124SMoriah Waterland 		/* NOTREACHED */
685*5c51f124SMoriah Waterland 	}
686*5c51f124SMoriah Waterland 
687*5c51f124SMoriah Waterland 	pkgdir = pkgdev.dirname;
688*5c51f124SMoriah Waterland 	repeat = ((optind >= argc) && pkgdev.mount);
689*5c51f124SMoriah Waterland 
690*5c51f124SMoriah Waterland 	/*
691*5c51f124SMoriah Waterland 	 * error if there are packages on the command line and a category
692*5c51f124SMoriah Waterland 	 * was specified
693*5c51f124SMoriah Waterland 	 */
694*5c51f124SMoriah Waterland 
695*5c51f124SMoriah Waterland 	if (optind < argc && catg_arg != NULL) {
696*5c51f124SMoriah Waterland 		progerr(ERR_PKGS_AND_CAT_PKGRM);
697*5c51f124SMoriah Waterland 		usage();
698*5c51f124SMoriah Waterland 		/* NOTREACHED */
699*5c51f124SMoriah Waterland 	}
700*5c51f124SMoriah Waterland 
701*5c51f124SMoriah Waterland 	/*
702*5c51f124SMoriah Waterland 	 * ********************************************************************
703*5c51f124SMoriah Waterland 	 * main package processing "loop"
704*5c51f124SMoriah Waterland 	 * ********************************************************************
705*5c51f124SMoriah Waterland 	 */
706*5c51f124SMoriah Waterland 
707*5c51f124SMoriah Waterland 	for (;;) {
708*5c51f124SMoriah Waterland 		boolean_t	b;
709*5c51f124SMoriah Waterland 		char		**pkglist;	/* points to array of pkgs */
710*5c51f124SMoriah Waterland 
711*5c51f124SMoriah Waterland 		/*
712*5c51f124SMoriah Waterland 		 * mount the spool device if required
713*5c51f124SMoriah Waterland 		 */
714*5c51f124SMoriah Waterland 
715*5c51f124SMoriah Waterland 		if (pkgdev.mount) {
716*5c51f124SMoriah Waterland 			if (n = pkgmount(&pkgdev, NULL, 0, 0, 1)) {
717*5c51f124SMoriah Waterland 				quit(n);
718*5c51f124SMoriah Waterland 				/* NOTREACHED */
719*5c51f124SMoriah Waterland 			}
720*5c51f124SMoriah Waterland 		}
721*5c51f124SMoriah Waterland 
722*5c51f124SMoriah Waterland 		if (chdir(pkgdev.dirname)) {
723*5c51f124SMoriah Waterland 			progerr(ERR_CHDIR, pkgdev.dirname);
724*5c51f124SMoriah Waterland 			quit(1);
725*5c51f124SMoriah Waterland 			/* NOTREACHED */
726*5c51f124SMoriah Waterland 		}
727*5c51f124SMoriah Waterland 
728*5c51f124SMoriah Waterland 		/*
729*5c51f124SMoriah Waterland 		 * spool device mounted/available - get the list of the
730*5c51f124SMoriah Waterland 		 * packages to remove
731*5c51f124SMoriah Waterland 		 */
732*5c51f124SMoriah Waterland 
733*5c51f124SMoriah Waterland 		n = pkgGetPackageList(&pkglist, argv, optind,
734*5c51f124SMoriah Waterland 			catg_arg, category, &pkgdev);
735*5c51f124SMoriah Waterland 
736*5c51f124SMoriah Waterland 		switch (n) {
737*5c51f124SMoriah Waterland 			case -1:	/* no packages found */
738*5c51f124SMoriah Waterland 				echoDebug(DBG_PKGLIST_RM_NONFOUND,
739*5c51f124SMoriah Waterland 					PSTR(pkgdev.dirname));
740*5c51f124SMoriah Waterland 				progerr(ERR_NOPKGS, pkgdev.dirname);
741*5c51f124SMoriah Waterland 				quit(1);
742*5c51f124SMoriah Waterland 				/* NOTREACHED */
743*5c51f124SMoriah Waterland 
744*5c51f124SMoriah Waterland 			case 0:		/* packages found */
745*5c51f124SMoriah Waterland 				break;
746*5c51f124SMoriah Waterland 
747*5c51f124SMoriah Waterland 			default:	/* "quit" error */
748*5c51f124SMoriah Waterland 				echoDebug(DBG_PKGLIST_RM_ERROR,
749*5c51f124SMoriah Waterland 					pkgdev.dirname, n);
750*5c51f124SMoriah Waterland 				quit(n);
751*5c51f124SMoriah Waterland 				/* NOTREACHED */
752*5c51f124SMoriah Waterland 		}
753*5c51f124SMoriah Waterland 
754*5c51f124SMoriah Waterland 		/*
755*5c51f124SMoriah Waterland 		 * count the number of packages to remove
756*5c51f124SMoriah Waterland 		 * NOTE: npkgs is a global variable that is referenced by quit.c
757*5c51f124SMoriah Waterland 		 * when error messages are generated - it is referenced directly
758*5c51f124SMoriah Waterland 		 * by the other functions called below...
759*5c51f124SMoriah Waterland 		 */
760*5c51f124SMoriah Waterland 
761*5c51f124SMoriah Waterland 		for (npkgs = 0; pkglist[npkgs] != (char *)NULL; /* void */) {
762*5c51f124SMoriah Waterland 			pkgLgth = strlen(pkglist[npkgs]);
763*5c51f124SMoriah Waterland 			if (pkgLgth > longestPkg) {
764*5c51f124SMoriah Waterland 				longestPkg = pkgLgth;
765*5c51f124SMoriah Waterland 			}
766*5c51f124SMoriah Waterland 			echoDebug(DBG_PKG_SELECTED, npkgs, pkglist[npkgs]);
767*5c51f124SMoriah Waterland 			npkgs++;
768*5c51f124SMoriah Waterland 		}
769*5c51f124SMoriah Waterland 
770*5c51f124SMoriah Waterland 		/* output number of packages to be removed */
771*5c51f124SMoriah Waterland 
772*5c51f124SMoriah Waterland 		echoDebug(DBG_NUM_PKGS_TO_REMOVE, npkgs, longestPkg);
773*5c51f124SMoriah Waterland 
774*5c51f124SMoriah Waterland 		/*
775*5c51f124SMoriah Waterland 		 * package list generated - remove packages
776*5c51f124SMoriah Waterland 		 */
777*5c51f124SMoriah Waterland 
778*5c51f124SMoriah Waterland 		b = remove_packages(pkglist, nodelete, longestPkg, repeat,
779*5c51f124SMoriah Waterland 			altBinDir, pkgdev.dirname, spoolDir, noZones);
780*5c51f124SMoriah Waterland 
781*5c51f124SMoriah Waterland 		/*
782*5c51f124SMoriah Waterland 		 * unmount the spool directory if necessary
783*5c51f124SMoriah Waterland 		 */
784*5c51f124SMoriah Waterland 
785*5c51f124SMoriah Waterland 		if (pkgdev.mount) {
786*5c51f124SMoriah Waterland 			(void) chdir("/");
787*5c51f124SMoriah Waterland 			if (pkgumount(&pkgdev)) {
788*5c51f124SMoriah Waterland 				progerr(ERR_PKGUNMOUNT, pkgdev.bdevice);
789*5c51f124SMoriah Waterland 				quit(99);
790*5c51f124SMoriah Waterland 				/* NOTREACHED */
791*5c51f124SMoriah Waterland 
792*5c51f124SMoriah Waterland 			}
793*5c51f124SMoriah Waterland 		}
794*5c51f124SMoriah Waterland 
795*5c51f124SMoriah Waterland 		/*
796*5c51f124SMoriah Waterland 		 * continue with next sequence of packages if continue set
797*5c51f124SMoriah Waterland 		 */
798*5c51f124SMoriah Waterland 
799*5c51f124SMoriah Waterland 		if (b == B_TRUE) {
800*5c51f124SMoriah Waterland 			continue;
801*5c51f124SMoriah Waterland 		}
802*5c51f124SMoriah Waterland 
803*5c51f124SMoriah Waterland 		/*
804*5c51f124SMoriah Waterland 		 * not continuing - quit with 0 exit code
805*5c51f124SMoriah Waterland 		 */
806*5c51f124SMoriah Waterland 
807*5c51f124SMoriah Waterland 		quit(0);
808*5c51f124SMoriah Waterland 		/* NOTREACHED */
809*5c51f124SMoriah Waterland #ifdef lint
810*5c51f124SMoriah Waterland 		return (0);
811*5c51f124SMoriah Waterland #endif	/* lint */
812*5c51f124SMoriah Waterland 	}
813*5c51f124SMoriah Waterland }
814*5c51f124SMoriah Waterland 
815*5c51f124SMoriah Waterland /*
816*5c51f124SMoriah Waterland  * *****************************************************************************
817*5c51f124SMoriah Waterland  * static internal (private) functions
818*5c51f124SMoriah Waterland  * *****************************************************************************
819*5c51f124SMoriah Waterland  */
820*5c51f124SMoriah Waterland 
821*5c51f124SMoriah Waterland /*
822*5c51f124SMoriah Waterland  * Name:	doRemove
823*5c51f124SMoriah Waterland  * Description:	Remove a package from the global zone, and optionally from one
824*5c51f124SMoriah Waterland  *		or more non-global zones.
825*5c51f124SMoriah Waterland  * Arguments:	a_nodelete: should the files and scripts remain installed?
826*5c51f124SMoriah Waterland  *			- if != 0 pass -F flag to pkgremove - suppress
827*5c51f124SMoriah Waterland  *			the removal of any files and any class action scripts
828*5c51f124SMoriah Waterland  *			and suppress the running of any class action scripts.
829*5c51f124SMoriah Waterland  *			The package files remain but the package looks like it
830*5c51f124SMoriah Waterland  *			is not installed. This is mainly for use by upgrade.
831*5c51f124SMoriah Waterland  *			- if == 0 do not pass -F flag to pkgremove - all
832*5c51f124SMoriah Waterland  *			files and class action scripts are removed, and any
833*5c51f124SMoriah Waterland  *			appropriate class action scripts are run.
834*5c51f124SMoriah Waterland  *		a_altBinDir - pointer to string representing location of the
835*5c51f124SMoriah Waterland  *			pkgremove executable to run. If not NULL, then pass
836*5c51f124SMoriah Waterland  *			the path specified to the -b option to pkgremove.
837*5c51f124SMoriah Waterland  *		a_longestPkg - length of the longest package "name" (for
838*5c51f124SMoriah Waterland  *			output format alignment)
839*5c51f124SMoriah Waterland  *		a_adminFile - pointer to string representing the admin
840*5c51f124SMoriah Waterland  *			file to pass to pkgremove when removing a package from
841*5c51f124SMoriah Waterland  *			the global zone only. Typically the admin file used for
842*5c51f124SMoriah Waterland  *			the global zone is the admin file passed in by the user.
843*5c51f124SMoriah Waterland  *			If this is == NULL no admin file is given to pkgremove.
844*5c51f124SMoriah Waterland  *		a_zoneAdminFile - pointer to string representing the admin
845*5c51f124SMoriah Waterland  *			file to pass to pkgremove when removing the package
846*5c51f124SMoriah Waterland  *			from a non-global zone only. Typically the admin file
847*5c51f124SMoriah Waterland  *			used for non-global zones supresses all checks since
848*5c51f124SMoriah Waterland  *			the dependency checking is done for all zones first
849*5c51f124SMoriah Waterland  *			before proceeding.
850*5c51f124SMoriah Waterland  *			A zoneAdminFile MUST be specified if a_zlst != NULL.
851*5c51f124SMoriah Waterland  *			A zoneAdminFile must NOT be specified if a_zlst == NULL.
852*5c51f124SMoriah Waterland  *		a_zlst - list of zones to process; NULL if no zones to process.
853*5c51f124SMoriah Waterland  * Returns:	int	(see ckreturn() function for details)
854*5c51f124SMoriah Waterland  *		0 - success
855*5c51f124SMoriah Waterland  *		1 - package operation failed (fatal error)
856*5c51f124SMoriah Waterland  *		2 - non-fatal error (warning)
857*5c51f124SMoriah Waterland  *		3 - user selected quit (operation interrupted)
858*5c51f124SMoriah Waterland  *		4 - admin settings prevented operation
859*5c51f124SMoriah Waterland  *		5 - interaction required and -n (non-interactive) specified
860*5c51f124SMoriah Waterland  *		"10" will be added to indicate "immediate reboot required"
861*5c51f124SMoriah Waterland  *		"20" will be added to indicate "reboot after install required"
862*5c51f124SMoriah Waterland  */
863*5c51f124SMoriah Waterland 
864*5c51f124SMoriah Waterland static int
865*5c51f124SMoriah Waterland doRemove(int a_nodelete, char *a_altBinDir, int a_longestPkg, char *a_adminFile,
866*5c51f124SMoriah Waterland 	char *a_zoneAdminFile, zoneList_t a_zlst)
867*5c51f124SMoriah Waterland {
868*5c51f124SMoriah Waterland 	boolean_t	b;
869*5c51f124SMoriah Waterland 	char		**inheritedPkgDirs;
870*5c51f124SMoriah Waterland 	char		*zoneName;
871*5c51f124SMoriah Waterland 	char		ans[MAX_INPUT];
872*5c51f124SMoriah Waterland 	int		n;
873*5c51f124SMoriah Waterland 	int		zoneIndex;
874*5c51f124SMoriah Waterland 	int		zonesSkipped;
875*5c51f124SMoriah Waterland 	struct pkginfo	*pinfo = (struct pkginfo *)NULL;
876*5c51f124SMoriah Waterland 	zone_state_t	zst;
877*5c51f124SMoriah Waterland 
878*5c51f124SMoriah Waterland 	/* entry assertions */
879*5c51f124SMoriah Waterland 
880*5c51f124SMoriah Waterland 	if (a_zlst != (zoneList_t)NULL) {
881*5c51f124SMoriah Waterland 		/* zone list specified - zone admin file required */
882*5c51f124SMoriah Waterland 		assert(a_zoneAdminFile != (char *)NULL);
883*5c51f124SMoriah Waterland 		assert(*a_zoneAdminFile != '\0');
884*5c51f124SMoriah Waterland 	} else {
885*5c51f124SMoriah Waterland 		/* no zone list specified - no zone admin file needed */
886*5c51f124SMoriah Waterland 		assert(a_zoneAdminFile == (char *)NULL);
887*5c51f124SMoriah Waterland 	}
888*5c51f124SMoriah Waterland 
889*5c51f124SMoriah Waterland 	/* NOTE: required 'pkgdir' set to spool directory or NULL */
890*5c51f124SMoriah Waterland 	b = pkginfoIsPkgInstalled(&pinfo, pkginst);
891*5c51f124SMoriah Waterland 	if (b == B_FALSE) {
892*5c51f124SMoriah Waterland 		progerr(ERR_NO_SUCH_INSTANCE, pkginst);
893*5c51f124SMoriah Waterland 		pkginfoFree(&pinfo);
894*5c51f124SMoriah Waterland 		return (2);
895*5c51f124SMoriah Waterland 	}
896*5c51f124SMoriah Waterland 
897*5c51f124SMoriah Waterland 	/* entry debugging info */
898*5c51f124SMoriah Waterland 
899*5c51f124SMoriah Waterland 	echoDebug(DBG_DOREMOVE_ENTRY);
900*5c51f124SMoriah Waterland 	echoDebug(DBG_DOREMOVE_ARGS, PSTR(pinfo->pkginst), PSTR(pinfo->name),
901*5c51f124SMoriah Waterland 		PSTR(pinfo->arch), PSTR(pinfo->version), PSTR(pinfo->basedir),
902*5c51f124SMoriah Waterland 		PSTR(pinfo->catg), pinfo->status);
903*5c51f124SMoriah Waterland 
904*5c51f124SMoriah Waterland 	if (!nointeract) {
905*5c51f124SMoriah Waterland 		char	fmt1[100];
906*5c51f124SMoriah Waterland 
907*5c51f124SMoriah Waterland 		/* create format based on max pkg name length */
908*5c51f124SMoriah Waterland 
909*5c51f124SMoriah Waterland 		(void) snprintf(fmt1, sizeof (fmt1), "   %%-%d.%ds  %%s",
910*5c51f124SMoriah Waterland 				a_longestPkg, a_longestPkg);
911*5c51f124SMoriah Waterland 
912*5c51f124SMoriah Waterland 		if (pinfo->status == PI_SPOOLED) {
913*5c51f124SMoriah Waterland 			echo(INFO_SPOOLED);
914*5c51f124SMoriah Waterland 		} else {
915*5c51f124SMoriah Waterland 			if (getuid()) {
916*5c51f124SMoriah Waterland 				progerr(ERR_NOT_ROOT, get_prog_name());
917*5c51f124SMoriah Waterland 				exit(1);
918*5c51f124SMoriah Waterland 			}
919*5c51f124SMoriah Waterland 			echo(INFO_INSTALL);
920*5c51f124SMoriah Waterland 		}
921*5c51f124SMoriah Waterland 
922*5c51f124SMoriah Waterland 		echo(fmt1, pinfo->pkginst, pinfo->name);
923*5c51f124SMoriah Waterland 
924*5c51f124SMoriah Waterland 		if (pinfo->arch || pinfo->version) {
925*5c51f124SMoriah Waterland 			char	fmt2[100];
926*5c51f124SMoriah Waterland 
927*5c51f124SMoriah Waterland 			/* create format based on max pkg name length */
928*5c51f124SMoriah Waterland 
929*5c51f124SMoriah Waterland 			(void) snprintf(fmt2, sizeof (fmt2), "   %%%d.%ds  ",
930*5c51f124SMoriah Waterland 					a_longestPkg, a_longestPkg);
931*5c51f124SMoriah Waterland 
932*5c51f124SMoriah Waterland 			/* LINTED variable format specifier to fprintf() */
933*5c51f124SMoriah Waterland 			(void) fprintf(stderr, fmt2, "");
934*5c51f124SMoriah Waterland 
935*5c51f124SMoriah Waterland 			if (pinfo->arch) {
936*5c51f124SMoriah Waterland 				(void) fprintf(stderr, "(%s) ", pinfo->arch);
937*5c51f124SMoriah Waterland 			}
938*5c51f124SMoriah Waterland 
939*5c51f124SMoriah Waterland 			if (pinfo->version) {
940*5c51f124SMoriah Waterland 				(void) fprintf(stderr, "%s", pinfo->version);
941*5c51f124SMoriah Waterland 			}
942*5c51f124SMoriah Waterland 
943*5c51f124SMoriah Waterland 			(void) fprintf(stderr, "\n");
944*5c51f124SMoriah Waterland 		}
945*5c51f124SMoriah Waterland 
946*5c51f124SMoriah Waterland 		n = ckyorn(ans, NULL, NULL, NULL, ASK_CONFIRM);
947*5c51f124SMoriah Waterland 		if (n != 0) {
948*5c51f124SMoriah Waterland 			quit(n);
949*5c51f124SMoriah Waterland 			/* NOTREACHED */
950*5c51f124SMoriah Waterland 		}
951*5c51f124SMoriah Waterland 
952*5c51f124SMoriah Waterland 		if (strchr("yY", *ans) == NULL) {
953*5c51f124SMoriah Waterland 			pkginfoFree(&pinfo);
954*5c51f124SMoriah Waterland 			return (0);
955*5c51f124SMoriah Waterland 		}
956*5c51f124SMoriah Waterland 	}
957*5c51f124SMoriah Waterland 
958*5c51f124SMoriah Waterland 	if (pinfo->status == PI_PRESVR4) {
959*5c51f124SMoriah Waterland 		pkginfoFree(&pinfo);
960*5c51f124SMoriah Waterland 		return (presvr4(pkginst, nointeract));
961*5c51f124SMoriah Waterland 	}
962*5c51f124SMoriah Waterland 
963*5c51f124SMoriah Waterland 	if (pinfo->status == PI_SPOOLED) {
964*5c51f124SMoriah Waterland 		/* removal from a directory */
965*5c51f124SMoriah Waterland 		echo(INFO_RMSPOOL, pkginst);
966*5c51f124SMoriah Waterland 		pkginfoFree(&pinfo);
967*5c51f124SMoriah Waterland 		return (rrmdir(pkginst));
968*5c51f124SMoriah Waterland 	}
969*5c51f124SMoriah Waterland 
970*5c51f124SMoriah Waterland 	/* exit if not root */
971*5c51f124SMoriah Waterland 
972*5c51f124SMoriah Waterland 	if (getuid()) {
973*5c51f124SMoriah Waterland 		progerr(ERR_NOT_ROOT, get_prog_name());
974*5c51f124SMoriah Waterland 		exit(1);
975*5c51f124SMoriah Waterland 	}
976*5c51f124SMoriah Waterland 
977*5c51f124SMoriah Waterland 	pkginfoFree(&pinfo);
978*5c51f124SMoriah Waterland 
979*5c51f124SMoriah Waterland 	zonesSkipped = 0;
980*5c51f124SMoriah Waterland 
981*5c51f124SMoriah Waterland 	if (interrupted != 0) {
982*5c51f124SMoriah Waterland 		echo(MSG_DOREMOVE_INTERRUPTED_B4_Z, pkginst);
983*5c51f124SMoriah Waterland 		echoDebug(MSG_DOREMOVE_INTERRUPTED_B4_Z, pkginst);
984*5c51f124SMoriah Waterland 		return (n);
985*5c51f124SMoriah Waterland 	}
986*5c51f124SMoriah Waterland 
987*5c51f124SMoriah Waterland 	echoDebug(DBG_REMOVE_FLAG_VALUES, "before pkgZoneRemove",
988*5c51f124SMoriah Waterland 		admnflag, doreboot, failflag, interrupted,
989*5c51f124SMoriah Waterland 		intrflag, ireboot, nullflag, warnflag);
990*5c51f124SMoriah Waterland 
991*5c51f124SMoriah Waterland 	for (zoneIndex = 0;
992*5c51f124SMoriah Waterland 	    a_zlst != NULL &&
993*5c51f124SMoriah Waterland 	    (zoneName = z_zlist_get_zonename(a_zlst, zoneIndex)) != NULL;
994*5c51f124SMoriah Waterland 	    zoneIndex++) {
995*5c51f124SMoriah Waterland 
996*5c51f124SMoriah Waterland 		/* skip the zone if it is NOT running */
997*5c51f124SMoriah Waterland 
998*5c51f124SMoriah Waterland 		zst = z_zlist_get_current_state(a_zlst, zoneIndex);
999*5c51f124SMoriah Waterland 		if (zst != ZONE_STATE_RUNNING && zst != ZONE_STATE_MOUNTED) {
1000*5c51f124SMoriah Waterland 			zonesSkipped++;
1001*5c51f124SMoriah Waterland 			echoDebug(DBG_SKIPPING_ZONE, zoneName);
1002*5c51f124SMoriah Waterland 			continue;
1003*5c51f124SMoriah Waterland 		}
1004*5c51f124SMoriah Waterland 
1005*5c51f124SMoriah Waterland 		echo(MSG_REMOVE_PKG_FROM_ZONE, pkginst, zoneName);
1006*5c51f124SMoriah Waterland 		echoDebug(DBG_REMOVE_PKG_FROM_ZONE, pkginst, zoneName);
1007*5c51f124SMoriah Waterland 
1008*5c51f124SMoriah Waterland 		/* determine list of directories inherited from global zone */
1009*5c51f124SMoriah Waterland 
1010*5c51f124SMoriah Waterland 		inheritedPkgDirs = z_zlist_get_inherited_pkg_dirs(a_zlst,
1011*5c51f124SMoriah Waterland 					zoneIndex);
1012*5c51f124SMoriah Waterland 
1013*5c51f124SMoriah Waterland 		/*
1014*5c51f124SMoriah Waterland 		 * remove package from zone; use the zone admin file which
1015*5c51f124SMoriah Waterland 		 * suppresses all checks.
1016*5c51f124SMoriah Waterland 		 */
1017*5c51f124SMoriah Waterland 
1018*5c51f124SMoriah Waterland 		n = pkgZoneRemove(z_zlist_get_scratch(a_zlst, zoneIndex),
1019*5c51f124SMoriah Waterland 			inheritedPkgDirs, a_nodelete, a_altBinDir,
1020*5c51f124SMoriah Waterland 			a_zoneAdminFile, zst);
1021*5c51f124SMoriah Waterland 
1022*5c51f124SMoriah Waterland 		/* set success/fail condition variables */
1023*5c51f124SMoriah Waterland 
1024*5c51f124SMoriah Waterland 		ckreturn(n);
1025*5c51f124SMoriah Waterland 
1026*5c51f124SMoriah Waterland 		echoDebug(DBG_REMOVE_FLAG_VALUES, "after pkgZoneRemove",
1027*5c51f124SMoriah Waterland 			admnflag, doreboot, failflag, interrupted, intrflag,
1028*5c51f124SMoriah Waterland 			ireboot, nullflag, warnflag);
1029*5c51f124SMoriah Waterland 	}
1030*5c51f124SMoriah Waterland 
1031*5c51f124SMoriah Waterland 	if (zonesSkipped > 0) {
1032*5c51f124SMoriah Waterland 		echoDebug(DBG_ZONES_SKIPPED, zonesSkipped);
1033*5c51f124SMoriah Waterland 
1034*5c51f124SMoriah Waterland 		for (zoneIndex = 0;
1035*5c51f124SMoriah Waterland 			(zoneName = z_zlist_get_zonename(a_zlst, zoneIndex)) !=
1036*5c51f124SMoriah Waterland 				(char *)NULL; zoneIndex++) {
1037*5c51f124SMoriah Waterland 
1038*5c51f124SMoriah Waterland 			/* skip the zone if it IS running */
1039*5c51f124SMoriah Waterland 
1040*5c51f124SMoriah Waterland 			zst = z_zlist_get_current_state(a_zlst, zoneIndex);
1041*5c51f124SMoriah Waterland 			if (zst == ZONE_STATE_RUNNING ||
1042*5c51f124SMoriah Waterland 			    zst == ZONE_STATE_MOUNTED) {
1043*5c51f124SMoriah Waterland 				zonesSkipped++;
1044*5c51f124SMoriah Waterland 				echoDebug(DBG_SKIPPING_ZONE_BOOT, zoneName);
1045*5c51f124SMoriah Waterland 				continue;
1046*5c51f124SMoriah Waterland 			}
1047*5c51f124SMoriah Waterland 
1048*5c51f124SMoriah Waterland 			/* skip the zone if it is NOT bootable */
1049*5c51f124SMoriah Waterland 
1050*5c51f124SMoriah Waterland 			if (z_zlist_is_zone_runnable(a_zlst,
1051*5c51f124SMoriah Waterland 						zoneIndex) == B_FALSE) {
1052*5c51f124SMoriah Waterland 				echo(MSG_SKIPPING_ZONE_NOT_RUNNABLE, zoneName);
1053*5c51f124SMoriah Waterland 				echoDebug(DBG_SKIPPING_ZONE_NOT_RUNNABLE,
1054*5c51f124SMoriah Waterland 					zoneName);
1055*5c51f124SMoriah Waterland 				continue;
1056*5c51f124SMoriah Waterland 			}
1057*5c51f124SMoriah Waterland 
1058*5c51f124SMoriah Waterland 			/* mount up the zone */
1059*5c51f124SMoriah Waterland 
1060*5c51f124SMoriah Waterland 			echo(MSG_BOOTING_ZONE, zoneName);
1061*5c51f124SMoriah Waterland 			echoDebug(DBG_BOOTING_ZONE, zoneName);
1062*5c51f124SMoriah Waterland 
1063*5c51f124SMoriah Waterland 			b = z_zlist_change_zone_state(a_zlst, zoneIndex,
1064*5c51f124SMoriah Waterland 				ZONE_STATE_MOUNTED);
1065*5c51f124SMoriah Waterland 			if (b == B_FALSE) {
1066*5c51f124SMoriah Waterland 				progerr(ERR_CANNOT_BOOT_ZONE, zoneName);
1067*5c51f124SMoriah Waterland 				/* set fatal error return condition */
1068*5c51f124SMoriah Waterland 				ckreturn(1);
1069*5c51f124SMoriah Waterland 				continue;
1070*5c51f124SMoriah Waterland 			}
1071*5c51f124SMoriah Waterland 
1072*5c51f124SMoriah Waterland 			echo(MSG_REMOVE_PKG_FROM_ZONE, pkginst, zoneName);
1073*5c51f124SMoriah Waterland 
1074*5c51f124SMoriah Waterland 			/* determine list of dirs inherited from global zone */
1075*5c51f124SMoriah Waterland 
1076*5c51f124SMoriah Waterland 			inheritedPkgDirs =
1077*5c51f124SMoriah Waterland 				z_zlist_get_inherited_pkg_dirs(a_zlst,
1078*5c51f124SMoriah Waterland 						zoneIndex);
1079*5c51f124SMoriah Waterland 
1080*5c51f124SMoriah Waterland 			/*
1081*5c51f124SMoriah Waterland 			 * remove package from zone; use the zone admin file
1082*5c51f124SMoriah Waterland 			 * which suppresses all checks.
1083*5c51f124SMoriah Waterland 			 */
1084*5c51f124SMoriah Waterland 
1085*5c51f124SMoriah Waterland 			n = pkgZoneRemove(z_zlist_get_scratch(a_zlst,
1086*5c51f124SMoriah Waterland 				zoneIndex), inheritedPkgDirs,
1087*5c51f124SMoriah Waterland 				a_nodelete, a_altBinDir, a_zoneAdminFile,
1088*5c51f124SMoriah Waterland 				ZONE_STATE_MOUNTED);
1089*5c51f124SMoriah Waterland 
1090*5c51f124SMoriah Waterland 			/* set success/fail condition variables */
1091*5c51f124SMoriah Waterland 
1092*5c51f124SMoriah Waterland 			ckreturn(n);
1093*5c51f124SMoriah Waterland 
1094*5c51f124SMoriah Waterland 			echoDebug(DBG_REMOVE_FLAG_VALUES, "after pkgZoneRemove",
1095*5c51f124SMoriah Waterland 				admnflag, doreboot, failflag, interrupted,
1096*5c51f124SMoriah Waterland 				intrflag, ireboot, nullflag, warnflag);
1097*5c51f124SMoriah Waterland 
1098*5c51f124SMoriah Waterland 			/* restore original state of zone */
1099*5c51f124SMoriah Waterland 
1100*5c51f124SMoriah Waterland 			echo(MSG_RESTORE_ZONE_STATE, zoneName);
1101*5c51f124SMoriah Waterland 			echoDebug(DBG_RESTORE_ZONE_STATE, zoneName);
1102*5c51f124SMoriah Waterland 
1103*5c51f124SMoriah Waterland 			b = z_zlist_restore_zone_state(a_zlst, zoneIndex);
1104*5c51f124SMoriah Waterland 		}
1105*5c51f124SMoriah Waterland 	}
1106*5c51f124SMoriah Waterland 
1107*5c51f124SMoriah Waterland 	/*
1108*5c51f124SMoriah Waterland 	 * Process global zone if it was either the only possible
1109*5c51f124SMoriah Waterland 	 * target (no list of zones specified) or it appears in the list
1110*5c51f124SMoriah Waterland 	 */
1111*5c51f124SMoriah Waterland 	if (a_zlst == NULL || z_on_zone_spec(GLOBAL_ZONENAME)) {
1112*5c51f124SMoriah Waterland 		/* reset interrupted flag before calling pkgremove */
1113*5c51f124SMoriah Waterland 		interrupted = 0;	/* last action was NOT quit */
1114*5c51f124SMoriah Waterland 
1115*5c51f124SMoriah Waterland 		/*
1116*5c51f124SMoriah Waterland 		 * call pkgremove for this package for the global zone;
1117*5c51f124SMoriah Waterland 		 * use the admin file passed in by the user via -a.
1118*5c51f124SMoriah Waterland 		 */
1119*5c51f124SMoriah Waterland 		n = pkgRemove(a_nodelete, a_altBinDir, a_adminFile,
1120*5c51f124SMoriah Waterland 		    z_get_inherited_file_systems());
1121*5c51f124SMoriah Waterland 
1122*5c51f124SMoriah Waterland 		/* set success/fail condition variables */
1123*5c51f124SMoriah Waterland 		ckreturn(n);
1124*5c51f124SMoriah Waterland 	}
1125*5c51f124SMoriah Waterland 
1126*5c51f124SMoriah Waterland 	return (n);
1127*5c51f124SMoriah Waterland }
1128*5c51f124SMoriah Waterland 
1129*5c51f124SMoriah Waterland /*
1130*5c51f124SMoriah Waterland  *  function to clear out any exisiting error return conditions that may have
1131*5c51f124SMoriah Waterland  *  been set by previous calls to ckreturn()
1132*5c51f124SMoriah Waterland  */
1133*5c51f124SMoriah Waterland static void
1134*5c51f124SMoriah Waterland resetreturn()
1135*5c51f124SMoriah Waterland {
1136*5c51f124SMoriah Waterland 	admnflag = 0;	/* != 0 if any pkg op admin setting failure (4) */
1137*5c51f124SMoriah Waterland 	doreboot = 0;	/* != 0 if reboot required after installation (>= 10) */
1138*5c51f124SMoriah Waterland 	failflag = 0;	/* != 0 if fatal error has occurred (1) */
1139*5c51f124SMoriah Waterland 	intrflag = 0;	/* != 0 if user selected quit (3) */
1140*5c51f124SMoriah Waterland 	ireboot = 0;	/* != 0 if immediate reboot required (>= 20) */
1141*5c51f124SMoriah Waterland 	nullflag = 0;	/* != 0 if admin interaction required (5) */
1142*5c51f124SMoriah Waterland 	warnflag = 0;	/* != 0 if non-fatal error has occurred (2) */
1143*5c51f124SMoriah Waterland 	interrupted = 0;	/* last pkg op was quit (1,2,3,4,5) */
1144*5c51f124SMoriah Waterland }
1145*5c51f124SMoriah Waterland 
1146*5c51f124SMoriah Waterland /*
1147*5c51f124SMoriah Waterland  *  function which checks the indicated return value
1148*5c51f124SMoriah Waterland  *  and indicates disposition of installation
1149*5c51f124SMoriah Waterland  */
1150*5c51f124SMoriah Waterland static void
1151*5c51f124SMoriah Waterland ckreturn(int retcode)
1152*5c51f124SMoriah Waterland {
1153*5c51f124SMoriah Waterland 	/*
1154*5c51f124SMoriah Waterland 	 * entry debugging info
1155*5c51f124SMoriah Waterland 	 */
1156*5c51f124SMoriah Waterland 
1157*5c51f124SMoriah Waterland 	echoDebug(DBG_PKGRM_CKRETURN, retcode, PSTR(pkginst));
1158*5c51f124SMoriah Waterland 
1159*5c51f124SMoriah Waterland 	switch (retcode) {
1160*5c51f124SMoriah Waterland 	    case  0:		/* successful */
1161*5c51f124SMoriah Waterland 	    case 10:
1162*5c51f124SMoriah Waterland 	    case 20:
1163*5c51f124SMoriah Waterland 		break; /* empty case */
1164*5c51f124SMoriah Waterland 
1165*5c51f124SMoriah Waterland 	    case  1:		/* package operation failed (fatal error) */
1166*5c51f124SMoriah Waterland 	    case 11:
1167*5c51f124SMoriah Waterland 	    case 21:
1168*5c51f124SMoriah Waterland 		failflag++;
1169*5c51f124SMoriah Waterland 		interrupted++;
1170*5c51f124SMoriah Waterland 		break;
1171*5c51f124SMoriah Waterland 
1172*5c51f124SMoriah Waterland 	    case  2:		/* non-fatal error (warning) */
1173*5c51f124SMoriah Waterland 	    case 12:
1174*5c51f124SMoriah Waterland 	    case 22:
1175*5c51f124SMoriah Waterland 		warnflag++;
1176*5c51f124SMoriah Waterland 		interrupted++;
1177*5c51f124SMoriah Waterland 		break;
1178*5c51f124SMoriah Waterland 
1179*5c51f124SMoriah Waterland 	    case  3:		/* user selected quit; operation interrupted */
1180*5c51f124SMoriah Waterland 	    case 13:
1181*5c51f124SMoriah Waterland 	    case 23:
1182*5c51f124SMoriah Waterland 		intrflag++;
1183*5c51f124SMoriah Waterland 		interrupted++;
1184*5c51f124SMoriah Waterland 		break;
1185*5c51f124SMoriah Waterland 
1186*5c51f124SMoriah Waterland 	    case  4:		/* admin settings prevented operation */
1187*5c51f124SMoriah Waterland 	    case 14:
1188*5c51f124SMoriah Waterland 	    case 24:
1189*5c51f124SMoriah Waterland 		admnflag++;
1190*5c51f124SMoriah Waterland 		interrupted++;
1191*5c51f124SMoriah Waterland 		break;
1192*5c51f124SMoriah Waterland 
1193*5c51f124SMoriah Waterland 	    case  5:		/* administration: interaction req (no -n) */
1194*5c51f124SMoriah Waterland 	    case 15:
1195*5c51f124SMoriah Waterland 	    case 25:
1196*5c51f124SMoriah Waterland 		nullflag++;
1197*5c51f124SMoriah Waterland 		interrupted++;
1198*5c51f124SMoriah Waterland 		break;
1199*5c51f124SMoriah Waterland 
1200*5c51f124SMoriah Waterland 	    default:
1201*5c51f124SMoriah Waterland 		failflag++;
1202*5c51f124SMoriah Waterland 		interrupted++;
1203*5c51f124SMoriah Waterland 		return;
1204*5c51f124SMoriah Waterland 	}
1205*5c51f124SMoriah Waterland 
1206*5c51f124SMoriah Waterland 	if (retcode >= 20) {
1207*5c51f124SMoriah Waterland 		ireboot++;
1208*5c51f124SMoriah Waterland 	} else if (retcode >= 10) {
1209*5c51f124SMoriah Waterland 		doreboot++;
1210*5c51f124SMoriah Waterland 	}
1211*5c51f124SMoriah Waterland }
1212*5c51f124SMoriah Waterland 
1213*5c51f124SMoriah Waterland static int
1214*5c51f124SMoriah Waterland pkgZoneCheckRemove(char *a_zoneName, char **a_inheritedPkgDirs,
1215*5c51f124SMoriah Waterland 	char *a_altBinDir, char *a_adminFile, char *a_stdoutPath,
1216*5c51f124SMoriah Waterland 	zone_state_t a_zoneState)
1217*5c51f124SMoriah Waterland {
1218*5c51f124SMoriah Waterland 	char	*arg[MAXARGS];
1219*5c51f124SMoriah Waterland 	char	*p;
1220*5c51f124SMoriah Waterland 	char	adminfd_path[PATH_MAX];
1221*5c51f124SMoriah Waterland 	char	path[PATH_MAX];
1222*5c51f124SMoriah Waterland 	int	fds[MAX_FDS];
1223*5c51f124SMoriah Waterland 	int	maxfds;
1224*5c51f124SMoriah Waterland 	int	n;
1225*5c51f124SMoriah Waterland 	int	nargs;
1226*5c51f124SMoriah Waterland 
1227*5c51f124SMoriah Waterland 	/* entry assertions */
1228*5c51f124SMoriah Waterland 
1229*5c51f124SMoriah Waterland 	assert(a_zoneName != (char *)NULL);
1230*5c51f124SMoriah Waterland 	assert(*a_zoneName != '\0');
1231*5c51f124SMoriah Waterland 
1232*5c51f124SMoriah Waterland 	/* entry debugging info */
1233*5c51f124SMoriah Waterland 
1234*5c51f124SMoriah Waterland 	echoDebug(DBG_PKGZONECHECKREMOVE_ENTRY);
1235*5c51f124SMoriah Waterland 	echoDebug(DBG_PKGZONECHECKREMOVE_ARGS, a_zoneName, PSTR(pkginst),
1236*5c51f124SMoriah Waterland 		PSTR(pkgdev.dirname), PSTR(a_adminFile), PSTR(a_stdoutPath));
1237*5c51f124SMoriah Waterland 
1238*5c51f124SMoriah Waterland 	/* generate path to pkgremove */
1239*5c51f124SMoriah Waterland 
1240*5c51f124SMoriah Waterland 	(void) snprintf(path, sizeof (path), "%s/pkgremove",
1241*5c51f124SMoriah Waterland 		a_altBinDir == (char *)NULL ? PKGBIN : a_altBinDir);
1242*5c51f124SMoriah Waterland 
1243*5c51f124SMoriah Waterland 	/* start at first file descriptor */
1244*5c51f124SMoriah Waterland 
1245*5c51f124SMoriah Waterland 	maxfds = 0;
1246*5c51f124SMoriah Waterland 
1247*5c51f124SMoriah Waterland 	/*
1248*5c51f124SMoriah Waterland 	 * generate argument list for call to pkgremove
1249*5c51f124SMoriah Waterland 	 */
1250*5c51f124SMoriah Waterland 
1251*5c51f124SMoriah Waterland 	/* start at argument 0 */
1252*5c51f124SMoriah Waterland 
1253*5c51f124SMoriah Waterland 	nargs = 0;
1254*5c51f124SMoriah Waterland 
1255*5c51f124SMoriah Waterland 	/* first argument is path to executable */
1256*5c51f124SMoriah Waterland 
1257*5c51f124SMoriah Waterland 	arg[nargs++] = strdup(path);
1258*5c51f124SMoriah Waterland 
1259*5c51f124SMoriah Waterland 	/* second argument is always: pass -O debug to pkgremove: debug mode */
1260*5c51f124SMoriah Waterland 
1261*5c51f124SMoriah Waterland 	if (debugFlag == B_TRUE) {
1262*5c51f124SMoriah Waterland 		arg[nargs++] = "-O";
1263*5c51f124SMoriah Waterland 		arg[nargs++] = "debug";
1264*5c51f124SMoriah Waterland 	}
1265*5c51f124SMoriah Waterland 
1266*5c51f124SMoriah Waterland 	/* pkgrm -b dir: pass -b to pkgremove */
1267*5c51f124SMoriah Waterland 
1268*5c51f124SMoriah Waterland 	if (a_altBinDir != (char *)NULL) {
1269*5c51f124SMoriah Waterland 		arg[nargs++] = "-b";
1270*5c51f124SMoriah Waterland 		arg[nargs++] = a_altBinDir;
1271*5c51f124SMoriah Waterland 	}
1272*5c51f124SMoriah Waterland 
1273*5c51f124SMoriah Waterland 	/*
1274*5c51f124SMoriah Waterland 	 * NONABI_SCRIPTS defined: pass -o to pkgremove; refers to a
1275*5c51f124SMoriah Waterland 	 * pkg requiring operator interaction during a procedure script
1276*5c51f124SMoriah Waterland 	 * (common before on1093)
1277*5c51f124SMoriah Waterland 	 */
1278*5c51f124SMoriah Waterland 
1279*5c51f124SMoriah Waterland 	if (old_pkg) {
1280*5c51f124SMoriah Waterland 		arg[nargs++] = "-o";
1281*5c51f124SMoriah Waterland 	}
1282*5c51f124SMoriah Waterland 
1283*5c51f124SMoriah Waterland 	/*
1284*5c51f124SMoriah Waterland 	 * PKG_NONABI_SYMLINKS defined: pass -y to pkgremove; process
1285*5c51f124SMoriah Waterland 	 * symlinks consistent with old behavior
1286*5c51f124SMoriah Waterland 	 */
1287*5c51f124SMoriah Waterland 
1288*5c51f124SMoriah Waterland 	if (old_symlinks) {
1289*5c51f124SMoriah Waterland 		arg[nargs++] = "-y";
1290*5c51f124SMoriah Waterland 	}
1291*5c51f124SMoriah Waterland 
1292*5c51f124SMoriah Waterland 	/* pkgrm -M: pass -M to pkgremove: don't mount client file systems */
1293*5c51f124SMoriah Waterland 
1294*5c51f124SMoriah Waterland 	arg[nargs++] = "-M";
1295*5c51f124SMoriah Waterland 
1296*5c51f124SMoriah Waterland 	/* pkgrm -A: pass -A to pkgremove */
1297*5c51f124SMoriah Waterland 
1298*5c51f124SMoriah Waterland 	if (pkgrmremote) {
1299*5c51f124SMoriah Waterland 		arg[nargs++] = "-A";
1300*5c51f124SMoriah Waterland 	}
1301*5c51f124SMoriah Waterland 
1302*5c51f124SMoriah Waterland 	/* pkgrm -v: pass -v to pkgremove: never trace scripts */
1303*5c51f124SMoriah Waterland 
1304*5c51f124SMoriah Waterland 	/* pass "-O enable-hollow-package-support" */
1305*5c51f124SMoriah Waterland 
1306*5c51f124SMoriah Waterland 	if (is_depend_pkginfo_DB()) {
1307*5c51f124SMoriah Waterland 		arg[nargs++] = "-O";
1308*5c51f124SMoriah Waterland 		arg[nargs++] = "enable-hollow-package-support";
1309*5c51f124SMoriah Waterland 	}
1310*5c51f124SMoriah Waterland 
1311*5c51f124SMoriah Waterland 	/* pass -n to pkgremove: always in noninteractive mode */
1312*5c51f124SMoriah Waterland 
1313*5c51f124SMoriah Waterland 	arg[nargs++] = "-n";
1314*5c51f124SMoriah Waterland 
1315*5c51f124SMoriah Waterland 	/* pkgrm -a admin: pass -a admin to pkgremove: admin file */
1316*5c51f124SMoriah Waterland 
1317*5c51f124SMoriah Waterland 	if (a_adminFile) {
1318*5c51f124SMoriah Waterland 		int fd;
1319*5c51f124SMoriah Waterland 		fd = openLocal(a_adminFile, O_RDONLY, tmpdir);
1320*5c51f124SMoriah Waterland 		if (fd < 0) {
1321*5c51f124SMoriah Waterland 			progerr(ERR_CANNOT_COPY_LOCAL, a_adminFile,
1322*5c51f124SMoriah Waterland 				errno, strerror(errno));
1323*5c51f124SMoriah Waterland 			return (1);
1324*5c51f124SMoriah Waterland 		}
1325*5c51f124SMoriah Waterland 		(void) snprintf(adminfd_path, sizeof (adminfd_path),
1326*5c51f124SMoriah Waterland 			"/proc/self/fd/%d", fd);
1327*5c51f124SMoriah Waterland 		fds[maxfds++] = fd;
1328*5c51f124SMoriah Waterland 		arg[nargs++] = "-a";
1329*5c51f124SMoriah Waterland 		arg[nargs++] = strdup(adminfd_path);
1330*5c51f124SMoriah Waterland 	}
1331*5c51f124SMoriah Waterland 
1332*5c51f124SMoriah Waterland 	/*
1333*5c51f124SMoriah Waterland 	 * pkgadd -R root: pass -R /a to pkgremove in mounted zone
1334*5c51f124SMoriah Waterland 	 */
1335*5c51f124SMoriah Waterland 	if (a_zoneState == ZONE_STATE_MOUNTED) {
1336*5c51f124SMoriah Waterland 		arg[nargs++] = "-R";
1337*5c51f124SMoriah Waterland 		arg[nargs++] = "/a";
1338*5c51f124SMoriah Waterland 	}
1339*5c51f124SMoriah Waterland 
1340*5c51f124SMoriah Waterland 	/* pkgrm -F: pass -F to pkgremove: always update DB only */
1341*5c51f124SMoriah Waterland 
1342*5c51f124SMoriah Waterland 	arg[nargs++] = "-F";
1343*5c51f124SMoriah Waterland 
1344*5c51f124SMoriah Waterland 	/* pass "-O preremovecheck" */
1345*5c51f124SMoriah Waterland 
1346*5c51f124SMoriah Waterland 	arg[nargs++] = "-O";
1347*5c51f124SMoriah Waterland 	arg[nargs++] = "preremovecheck";
1348*5c51f124SMoriah Waterland 
1349*5c51f124SMoriah Waterland 	/* add "-O addzonename" */
1350*5c51f124SMoriah Waterland 
1351*5c51f124SMoriah Waterland 	arg[nargs++] = "-O";
1352*5c51f124SMoriah Waterland 	arg[nargs++] = "addzonename";
1353*5c51f124SMoriah Waterland 
1354*5c51f124SMoriah Waterland 	/* add all inherited file systems */
1355*5c51f124SMoriah Waterland 
1356*5c51f124SMoriah Waterland 	if (a_inheritedPkgDirs != (char **)NULL) {
1357*5c51f124SMoriah Waterland 		for (n = 0; a_inheritedPkgDirs[n] != (char *)NULL; n++) {
1358*5c51f124SMoriah Waterland 			char	ifs[MAXPATHLEN+22];
1359*5c51f124SMoriah Waterland 			(void) snprintf(ifs, sizeof (ifs),
1360*5c51f124SMoriah Waterland 				"inherited-filesystem=%s",
1361*5c51f124SMoriah Waterland 				a_inheritedPkgDirs[n]);
1362*5c51f124SMoriah Waterland 			arg[nargs++] = "-O";
1363*5c51f124SMoriah Waterland 			arg[nargs++] = strdup(ifs);
1364*5c51f124SMoriah Waterland 		}
1365*5c51f124SMoriah Waterland 	}
1366*5c51f124SMoriah Waterland 
1367*5c51f124SMoriah Waterland 	/*
1368*5c51f124SMoriah Waterland 	 * add parent zone info/type
1369*5c51f124SMoriah Waterland 	 */
1370*5c51f124SMoriah Waterland 
1371*5c51f124SMoriah Waterland 	p = z_get_zonename();
1372*5c51f124SMoriah Waterland 	if ((p != NULL) && (*p != '\0')) {
1373*5c51f124SMoriah Waterland 			char	zn[MAXPATHLEN];
1374*5c51f124SMoriah Waterland 			(void) snprintf(zn, sizeof (zn),
1375*5c51f124SMoriah Waterland 				"parent-zone-name=%s", p);
1376*5c51f124SMoriah Waterland 			arg[nargs++] = "-O";
1377*5c51f124SMoriah Waterland 			arg[nargs++] = strdup(zn);
1378*5c51f124SMoriah Waterland 	}
1379*5c51f124SMoriah Waterland 
1380*5c51f124SMoriah Waterland 	/* current zone type */
1381*5c51f124SMoriah Waterland 
1382*5c51f124SMoriah Waterland 	arg[nargs++] = "-O";
1383*5c51f124SMoriah Waterland 	if (z_running_in_global_zone() == B_TRUE) {
1384*5c51f124SMoriah Waterland 			char	zn[MAXPATHLEN];
1385*5c51f124SMoriah Waterland 			(void) snprintf(zn, sizeof (zn),
1386*5c51f124SMoriah Waterland 				"parent-zone-type=%s",
1387*5c51f124SMoriah Waterland 				TAG_VALUE_GLOBAL_ZONE);
1388*5c51f124SMoriah Waterland 			arg[nargs++] = strdup(zn);
1389*5c51f124SMoriah Waterland 	} else {
1390*5c51f124SMoriah Waterland 			char	zn[MAXPATHLEN];
1391*5c51f124SMoriah Waterland 			(void) snprintf(zn, sizeof (zn),
1392*5c51f124SMoriah Waterland 				"parent-zone-type=%s",
1393*5c51f124SMoriah Waterland 				TAG_VALUE_NONGLOBAL_ZONE);
1394*5c51f124SMoriah Waterland 			arg[nargs++] = strdup(zn);
1395*5c51f124SMoriah Waterland 	}
1396*5c51f124SMoriah Waterland 
1397*5c51f124SMoriah Waterland 	/* pass -N to pkgremove: program name to report */
1398*5c51f124SMoriah Waterland 
1399*5c51f124SMoriah Waterland 	arg[nargs++] = "-N";
1400*5c51f124SMoriah Waterland 	arg[nargs++] = get_prog_name();
1401*5c51f124SMoriah Waterland 
1402*5c51f124SMoriah Waterland 	/* add package instance name */
1403*5c51f124SMoriah Waterland 
1404*5c51f124SMoriah Waterland 	arg[nargs++] = pkginst;
1405*5c51f124SMoriah Waterland 
1406*5c51f124SMoriah Waterland 	/* terminate argument list */
1407*5c51f124SMoriah Waterland 
1408*5c51f124SMoriah Waterland 	arg[nargs++] = NULL;
1409*5c51f124SMoriah Waterland 
1410*5c51f124SMoriah Waterland 	/* execute pkgremove command */
1411*5c51f124SMoriah Waterland 
1412*5c51f124SMoriah Waterland 	if (debugFlag == B_TRUE) {
1413*5c51f124SMoriah Waterland 		echoDebug(DBG_ZONE_EXEC_ENTER, a_zoneName, arg[0]);
1414*5c51f124SMoriah Waterland 		for (n = 0; arg[n]; n++) {
1415*5c51f124SMoriah Waterland 			echoDebug(DBG_ARG, n, arg[n]);
1416*5c51f124SMoriah Waterland 		}
1417*5c51f124SMoriah Waterland 	}
1418*5c51f124SMoriah Waterland 
1419*5c51f124SMoriah Waterland 	/* terminate file descriptor list */
1420*5c51f124SMoriah Waterland 
1421*5c51f124SMoriah Waterland 	fds[maxfds] = -1;
1422*5c51f124SMoriah Waterland 
1423*5c51f124SMoriah Waterland 	/* exec command in zone */
1424*5c51f124SMoriah Waterland 
1425*5c51f124SMoriah Waterland 	n = z_zone_exec(a_zoneName, path, arg, a_stdoutPath, (char *)NULL, fds);
1426*5c51f124SMoriah Waterland 
1427*5c51f124SMoriah Waterland 	echoDebug(DBG_ZONE_EXEC_EXIT, a_zoneName, arg[0], n,
1428*5c51f124SMoriah Waterland 			PSTR(a_stdoutPath));
1429*5c51f124SMoriah Waterland 
1430*5c51f124SMoriah Waterland 	/*
1431*5c51f124SMoriah Waterland 	 * close any files that were opened for use by the
1432*5c51f124SMoriah Waterland 	 * /proc/self/fd interface so they could be passed to programs
1433*5c51f124SMoriah Waterland 	 * via the z_zone_exec() interface
1434*5c51f124SMoriah Waterland 	 */
1435*5c51f124SMoriah Waterland 
1436*5c51f124SMoriah Waterland 	for (; maxfds > 0; maxfds--) {
1437*5c51f124SMoriah Waterland 		(void) close(fds[maxfds-1]);
1438*5c51f124SMoriah Waterland 	}
1439*5c51f124SMoriah Waterland 
1440*5c51f124SMoriah Waterland 	/* return results of pkgremove in zone execution */
1441*5c51f124SMoriah Waterland 
1442*5c51f124SMoriah Waterland 	return (n);
1443*5c51f124SMoriah Waterland }
1444*5c51f124SMoriah Waterland 
1445*5c51f124SMoriah Waterland static int
1446*5c51f124SMoriah Waterland pkgZoneRemove(char *a_zoneName, char **a_inheritedPkgDirs,
1447*5c51f124SMoriah Waterland 	int a_nodelete, char *a_altBinDir, char *a_adminFile,
1448*5c51f124SMoriah Waterland 	zone_state_t a_zoneState)
1449*5c51f124SMoriah Waterland {
1450*5c51f124SMoriah Waterland 	char	*arg[MAXARGS];
1451*5c51f124SMoriah Waterland 	char	*p;
1452*5c51f124SMoriah Waterland 	char	adminfd_path[PATH_MAX];
1453*5c51f124SMoriah Waterland 	char	path[PATH_MAX];
1454*5c51f124SMoriah Waterland 	int	fds[MAX_FDS];
1455*5c51f124SMoriah Waterland 	int	maxfds;
1456*5c51f124SMoriah Waterland 	int	n;
1457*5c51f124SMoriah Waterland 	int	nargs;
1458*5c51f124SMoriah Waterland 
1459*5c51f124SMoriah Waterland 	/* entry assertions */
1460*5c51f124SMoriah Waterland 
1461*5c51f124SMoriah Waterland 	assert(a_zoneName != (char *)NULL);
1462*5c51f124SMoriah Waterland 	assert(*a_zoneName != '\0');
1463*5c51f124SMoriah Waterland 
1464*5c51f124SMoriah Waterland 	/* entry debugging info */
1465*5c51f124SMoriah Waterland 
1466*5c51f124SMoriah Waterland 	echoDebug(DBG_PKGZONEREMOVE_ENTRY);
1467*5c51f124SMoriah Waterland 	echoDebug(DBG_PKGZONEREMOVE_ARGS, a_zoneName, PSTR(pkginst),
1468*5c51f124SMoriah Waterland 		PSTR(pkgdev.dirname), a_nodelete, PSTR(a_adminFile));
1469*5c51f124SMoriah Waterland 
1470*5c51f124SMoriah Waterland 	/* generate path to pkgremove */
1471*5c51f124SMoriah Waterland 
1472*5c51f124SMoriah Waterland 	(void) snprintf(path, sizeof (path), "%s/pkgremove",
1473*5c51f124SMoriah Waterland 		a_altBinDir == (char *)NULL ? PKGBIN : a_altBinDir);
1474*5c51f124SMoriah Waterland 
1475*5c51f124SMoriah Waterland 	/* start at first file descriptor */
1476*5c51f124SMoriah Waterland 
1477*5c51f124SMoriah Waterland 	maxfds = 0;
1478*5c51f124SMoriah Waterland 
1479*5c51f124SMoriah Waterland 	/*
1480*5c51f124SMoriah Waterland 	 * generate argument list for call to pkgremove
1481*5c51f124SMoriah Waterland 	 */
1482*5c51f124SMoriah Waterland 
1483*5c51f124SMoriah Waterland 	/* start at argument 0 */
1484*5c51f124SMoriah Waterland 
1485*5c51f124SMoriah Waterland 	nargs = 0;
1486*5c51f124SMoriah Waterland 
1487*5c51f124SMoriah Waterland 	/* first argument is path to executable */
1488*5c51f124SMoriah Waterland 
1489*5c51f124SMoriah Waterland 	arg[nargs++] = strdup(path);
1490*5c51f124SMoriah Waterland 
1491*5c51f124SMoriah Waterland 	/* second argument is always: pass -O debug to pkgremove: debug mode */
1492*5c51f124SMoriah Waterland 
1493*5c51f124SMoriah Waterland 	if (debugFlag == B_TRUE) {
1494*5c51f124SMoriah Waterland 		arg[nargs++] = "-O";
1495*5c51f124SMoriah Waterland 		arg[nargs++] = "debug";
1496*5c51f124SMoriah Waterland 	}
1497*5c51f124SMoriah Waterland 
1498*5c51f124SMoriah Waterland 	/* pkgrm -b dir: pass -b to pkgremove */
1499*5c51f124SMoriah Waterland 
1500*5c51f124SMoriah Waterland 	if (a_altBinDir != (char *)NULL) {
1501*5c51f124SMoriah Waterland 		arg[nargs++] = "-b";
1502*5c51f124SMoriah Waterland 		arg[nargs++] = a_altBinDir;
1503*5c51f124SMoriah Waterland 	}
1504*5c51f124SMoriah Waterland 
1505*5c51f124SMoriah Waterland 	/*
1506*5c51f124SMoriah Waterland 	 * NONABI_SCRIPTS defined: pass -o to pkgremove; refers to a
1507*5c51f124SMoriah Waterland 	 * pkg requiring operator interaction during a procedure script
1508*5c51f124SMoriah Waterland 	 * (common before on1093)
1509*5c51f124SMoriah Waterland 	 */
1510*5c51f124SMoriah Waterland 
1511*5c51f124SMoriah Waterland 	if (old_pkg) {
1512*5c51f124SMoriah Waterland 		arg[nargs++] = "-o";
1513*5c51f124SMoriah Waterland 	}
1514*5c51f124SMoriah Waterland 
1515*5c51f124SMoriah Waterland 	/*
1516*5c51f124SMoriah Waterland 	 * PKG_NONABI_SYMLINKS defined: pass -y to pkgremove; process
1517*5c51f124SMoriah Waterland 	 * symlinks consistent with old behavior
1518*5c51f124SMoriah Waterland 	 */
1519*5c51f124SMoriah Waterland 
1520*5c51f124SMoriah Waterland 	if (old_symlinks) {
1521*5c51f124SMoriah Waterland 		arg[nargs++] = "-y";
1522*5c51f124SMoriah Waterland 	}
1523*5c51f124SMoriah Waterland 
1524*5c51f124SMoriah Waterland 	/* pkgrm -M: pass -M to pkgremove: don't mount client file systems */
1525*5c51f124SMoriah Waterland 
1526*5c51f124SMoriah Waterland 	arg[nargs++] = "-M";
1527*5c51f124SMoriah Waterland 
1528*5c51f124SMoriah Waterland 	/* pkgrm -A: pass -A to pkgremove */
1529*5c51f124SMoriah Waterland 
1530*5c51f124SMoriah Waterland 	if (pkgrmremote) {
1531*5c51f124SMoriah Waterland 		arg[nargs++] = "-A";
1532*5c51f124SMoriah Waterland 	}
1533*5c51f124SMoriah Waterland 
1534*5c51f124SMoriah Waterland 	/* pkgrm -v: pass -v to pkgremove: trace scripts */
1535*5c51f124SMoriah Waterland 
1536*5c51f124SMoriah Waterland 	if (pkgverbose) {
1537*5c51f124SMoriah Waterland 		arg[nargs++] = "-v";
1538*5c51f124SMoriah Waterland 	}
1539*5c51f124SMoriah Waterland 
1540*5c51f124SMoriah Waterland 	/* pass "-O enable-hollow-package-support" */
1541*5c51f124SMoriah Waterland 
1542*5c51f124SMoriah Waterland 	if (is_depend_pkginfo_DB()) {
1543*5c51f124SMoriah Waterland 		arg[nargs++] = "-O";
1544*5c51f124SMoriah Waterland 		arg[nargs++] = "enable-hollow-package-support";
1545*5c51f124SMoriah Waterland 	}
1546*5c51f124SMoriah Waterland 
1547*5c51f124SMoriah Waterland 	/* pkgrm -n: pass -n to pkgremove: noninteractive mode */
1548*5c51f124SMoriah Waterland 
1549*5c51f124SMoriah Waterland 	if (nointeract) {
1550*5c51f124SMoriah Waterland 		arg[nargs++] = "-n";
1551*5c51f124SMoriah Waterland 	}
1552*5c51f124SMoriah Waterland 
1553*5c51f124SMoriah Waterland 	/* pkgrm -a admin: pass -a admin to pkgremove: admin file */
1554*5c51f124SMoriah Waterland 
1555*5c51f124SMoriah Waterland 	if (a_adminFile) {
1556*5c51f124SMoriah Waterland 		int fd;
1557*5c51f124SMoriah Waterland 		fd = openLocal(a_adminFile, O_RDONLY, tmpdir);
1558*5c51f124SMoriah Waterland 		if (fd < 0) {
1559*5c51f124SMoriah Waterland 			progerr(ERR_CANNOT_COPY_LOCAL, a_adminFile,
1560*5c51f124SMoriah Waterland 				errno, strerror(errno));
1561*5c51f124SMoriah Waterland 			return (1);
1562*5c51f124SMoriah Waterland 		}
1563*5c51f124SMoriah Waterland 		(void) snprintf(adminfd_path, sizeof (adminfd_path),
1564*5c51f124SMoriah Waterland 			"/proc/self/fd/%d", fd);
1565*5c51f124SMoriah Waterland 		fds[maxfds++] = fd;
1566*5c51f124SMoriah Waterland 		arg[nargs++] = "-a";
1567*5c51f124SMoriah Waterland 		arg[nargs++] = adminfd_path;
1568*5c51f124SMoriah Waterland 	}
1569*5c51f124SMoriah Waterland 
1570*5c51f124SMoriah Waterland 	/*
1571*5c51f124SMoriah Waterland 	 * pkgadd -R root: pass -R /a to pkgremove in mounted zone
1572*5c51f124SMoriah Waterland 	 */
1573*5c51f124SMoriah Waterland 	if (a_zoneState == ZONE_STATE_MOUNTED) {
1574*5c51f124SMoriah Waterland 		arg[nargs++] = "-R";
1575*5c51f124SMoriah Waterland 		arg[nargs++] = "/a";
1576*5c51f124SMoriah Waterland 	}
1577*5c51f124SMoriah Waterland 
1578*5c51f124SMoriah Waterland 	/* pkgrm -F: pass -F to pkgremove: update DB only */
1579*5c51f124SMoriah Waterland 
1580*5c51f124SMoriah Waterland 	if (a_nodelete) {
1581*5c51f124SMoriah Waterland 		arg[nargs++] = "-F";
1582*5c51f124SMoriah Waterland 	}
1583*5c51f124SMoriah Waterland 
1584*5c51f124SMoriah Waterland 	/* add "-O addzonename" */
1585*5c51f124SMoriah Waterland 
1586*5c51f124SMoriah Waterland 	arg[nargs++] = "-O";
1587*5c51f124SMoriah Waterland 	arg[nargs++] = "addzonename";
1588*5c51f124SMoriah Waterland 
1589*5c51f124SMoriah Waterland 	/* add all inherited file systems */
1590*5c51f124SMoriah Waterland 
1591*5c51f124SMoriah Waterland 	if (a_inheritedPkgDirs != (char **)NULL) {
1592*5c51f124SMoriah Waterland 		for (n = 0; a_inheritedPkgDirs[n] != (char *)NULL; n++) {
1593*5c51f124SMoriah Waterland 			char	ifs[MAXPATHLEN+22];
1594*5c51f124SMoriah Waterland 
1595*5c51f124SMoriah Waterland 			(void) snprintf(ifs, sizeof (ifs),
1596*5c51f124SMoriah Waterland 				"inherited-filesystem=%s",
1597*5c51f124SMoriah Waterland 				a_inheritedPkgDirs[n]);
1598*5c51f124SMoriah Waterland 			arg[nargs++] = "-O";
1599*5c51f124SMoriah Waterland 			arg[nargs++] = strdup(ifs);
1600*5c51f124SMoriah Waterland 		}
1601*5c51f124SMoriah Waterland 	}
1602*5c51f124SMoriah Waterland 
1603*5c51f124SMoriah Waterland 	/*
1604*5c51f124SMoriah Waterland 	 * add parent zone info/type
1605*5c51f124SMoriah Waterland 	 */
1606*5c51f124SMoriah Waterland 
1607*5c51f124SMoriah Waterland 	p = z_get_zonename();
1608*5c51f124SMoriah Waterland 	if ((p != NULL) && (*p != '\0')) {
1609*5c51f124SMoriah Waterland 			char	zn[MAXPATHLEN];
1610*5c51f124SMoriah Waterland 			(void) snprintf(zn, sizeof (zn),
1611*5c51f124SMoriah Waterland 				"parent-zone-name=%s", p);
1612*5c51f124SMoriah Waterland 			arg[nargs++] = "-O";
1613*5c51f124SMoriah Waterland 			arg[nargs++] = strdup(zn);
1614*5c51f124SMoriah Waterland 	}
1615*5c51f124SMoriah Waterland 
1616*5c51f124SMoriah Waterland 	/* current zone type */
1617*5c51f124SMoriah Waterland 
1618*5c51f124SMoriah Waterland 	arg[nargs++] = "-O";
1619*5c51f124SMoriah Waterland 	if (z_running_in_global_zone() == B_TRUE) {
1620*5c51f124SMoriah Waterland 			char	zn[MAXPATHLEN];
1621*5c51f124SMoriah Waterland 			(void) snprintf(zn, sizeof (zn),
1622*5c51f124SMoriah Waterland 				"parent-zone-type=%s",
1623*5c51f124SMoriah Waterland 				TAG_VALUE_GLOBAL_ZONE);
1624*5c51f124SMoriah Waterland 			arg[nargs++] = strdup(zn);
1625*5c51f124SMoriah Waterland 	} else {
1626*5c51f124SMoriah Waterland 			char	zn[MAXPATHLEN];
1627*5c51f124SMoriah Waterland 			(void) snprintf(zn, sizeof (zn),
1628*5c51f124SMoriah Waterland 				"parent-zone-type=%s",
1629*5c51f124SMoriah Waterland 				TAG_VALUE_NONGLOBAL_ZONE);
1630*5c51f124SMoriah Waterland 			arg[nargs++] = strdup(zn);
1631*5c51f124SMoriah Waterland 	}
1632*5c51f124SMoriah Waterland 
1633*5c51f124SMoriah Waterland 	/* pass -N to pkgremove: program name to report */
1634*5c51f124SMoriah Waterland 
1635*5c51f124SMoriah Waterland 	arg[nargs++] = "-N";
1636*5c51f124SMoriah Waterland 	arg[nargs++] = get_prog_name();
1637*5c51f124SMoriah Waterland 
1638*5c51f124SMoriah Waterland 	/* add package instance name */
1639*5c51f124SMoriah Waterland 
1640*5c51f124SMoriah Waterland 	arg[nargs++] = pkginst;
1641*5c51f124SMoriah Waterland 
1642*5c51f124SMoriah Waterland 	/* terminate argument list */
1643*5c51f124SMoriah Waterland 
1644*5c51f124SMoriah Waterland 	arg[nargs++] = NULL;
1645*5c51f124SMoriah Waterland 
1646*5c51f124SMoriah Waterland 	/* execute pkgremove command */
1647*5c51f124SMoriah Waterland 
1648*5c51f124SMoriah Waterland 	if (debugFlag == B_TRUE) {
1649*5c51f124SMoriah Waterland 		echoDebug(DBG_ZONE_EXEC_ENTER, a_zoneName, arg[0]);
1650*5c51f124SMoriah Waterland 		for (n = 0; arg[n]; n++) {
1651*5c51f124SMoriah Waterland 			echoDebug(DBG_ARG, n, arg[n]);
1652*5c51f124SMoriah Waterland 		}
1653*5c51f124SMoriah Waterland 	}
1654*5c51f124SMoriah Waterland 
1655*5c51f124SMoriah Waterland 	/* terminate file descriptor list */
1656*5c51f124SMoriah Waterland 
1657*5c51f124SMoriah Waterland 	fds[maxfds] = -1;
1658*5c51f124SMoriah Waterland 
1659*5c51f124SMoriah Waterland 	/* exec command in zone */
1660*5c51f124SMoriah Waterland 
1661*5c51f124SMoriah Waterland 	n = z_zone_exec(a_zoneName, path, arg, (char *)NULL, (char *)NULL, fds);
1662*5c51f124SMoriah Waterland 
1663*5c51f124SMoriah Waterland 	/*
1664*5c51f124SMoriah Waterland 	 * close any files that were opened for use by the
1665*5c51f124SMoriah Waterland 	 * /proc/self/fd interface so they could be passed to programs
1666*5c51f124SMoriah Waterland 	 * via the z_zone_exec() interface
1667*5c51f124SMoriah Waterland 	 */
1668*5c51f124SMoriah Waterland 
1669*5c51f124SMoriah Waterland 	for (; maxfds > 0; maxfds--) {
1670*5c51f124SMoriah Waterland 		(void) close(fds[maxfds-1]);
1671*5c51f124SMoriah Waterland 	}
1672*5c51f124SMoriah Waterland 
1673*5c51f124SMoriah Waterland 	return (n);
1674*5c51f124SMoriah Waterland }
1675*5c51f124SMoriah Waterland 
1676*5c51f124SMoriah Waterland /*
1677*5c51f124SMoriah Waterland  * Name:	pkgRemove
1678*5c51f124SMoriah Waterland  * Description:	Invoke pkgremove in the current zone to perform a remove
1679*5c51f124SMoriah Waterland  *		of a single package from the current zone or standalone system
1680*5c51f124SMoriah Waterland  * Arguments:	a_nodelete: should the files and scripts remain installed?
1681*5c51f124SMoriah Waterland  *			- if != 0 pass -F flag to pkgremove - suppress
1682*5c51f124SMoriah Waterland  *			the removal of any files and any class action scripts
1683*5c51f124SMoriah Waterland  *			and suppress the running of any class action scripts.
1684*5c51f124SMoriah Waterland  *			The package files remain but the package looks like it
1685*5c51f124SMoriah Waterland  *			is not installed. This is mainly for use by upgrade.
1686*5c51f124SMoriah Waterland  *			- if == 0 do not pass -F flag to pkgremove - all
1687*5c51f124SMoriah Waterland  *			files and class action scripts are removed, and any
1688*5c51f124SMoriah Waterland  *			appropriate class action scripts are run.
1689*5c51f124SMoriah Waterland  *		a_altBinDir - pointer to string representing location of the
1690*5c51f124SMoriah Waterland  *			pkgremove executable to run. If not NULL, then pass
1691*5c51f124SMoriah Waterland  *			the path specified to the -b option to pkgremove.
1692*5c51f124SMoriah Waterland  *		a_adminFile - pointer to string representing the admin
1693*5c51f124SMoriah Waterland  *			file to pass to pkgremove when removing the package.
1694*5c51f124SMoriah Waterland  *			If this is == NULL no admin file is given to pkgremove.
1695*5c51f124SMoriah Waterland  *		a_inheritedPkgDirs - pointer to array of strings, each one
1696*5c51f124SMoriah Waterland  *			representing the non-global zones full path of a
1697*5c51f124SMoriah Waterland  *			directory that is inherited from the global zone.
1698*5c51f124SMoriah Waterland  * Returns:	int	(see ckreturn() function for details)
1699*5c51f124SMoriah Waterland  *		0 - success
1700*5c51f124SMoriah Waterland  *		1 - package operation failed (fatal error)
1701*5c51f124SMoriah Waterland  *		2 - non-fatal error (warning)
1702*5c51f124SMoriah Waterland  *		3 - user selected quit (operation interrupted)
1703*5c51f124SMoriah Waterland  *		4 - admin settings prevented operation
1704*5c51f124SMoriah Waterland  *		5 - interaction required and -n (non-interactive) specified
1705*5c51f124SMoriah Waterland  *		"10" will be added to indicate "immediate reboot required"
1706*5c51f124SMoriah Waterland  *		"20" will be added to indicate "reboot after install required"
1707*5c51f124SMoriah Waterland  */
1708*5c51f124SMoriah Waterland 
1709*5c51f124SMoriah Waterland static int
1710*5c51f124SMoriah Waterland pkgRemove(int a_nodelete, char *a_altBinDir, char *a_adminFile,
1711*5c51f124SMoriah Waterland 	char **a_inheritedPkgDirs)
1712*5c51f124SMoriah Waterland {
1713*5c51f124SMoriah Waterland 	char	*arg[MAXARGS];
1714*5c51f124SMoriah Waterland 	char	*p;
1715*5c51f124SMoriah Waterland 	char	path[PATH_MAX];
1716*5c51f124SMoriah Waterland 	int	n;
1717*5c51f124SMoriah Waterland 	int	nargs;
1718*5c51f124SMoriah Waterland 
1719*5c51f124SMoriah Waterland 	/* entry debugging info */
1720*5c51f124SMoriah Waterland 
1721*5c51f124SMoriah Waterland 	echoDebug(DBG_PKGREMOVE_ENTRY);
1722*5c51f124SMoriah Waterland 	echoDebug(DBG_PKGREMOVE_ARGS, PSTR(pkginst), PSTR(pkgdev.dirname),
1723*5c51f124SMoriah Waterland 		a_nodelete, PSTR(a_adminFile));
1724*5c51f124SMoriah Waterland 
1725*5c51f124SMoriah Waterland 	(void) snprintf(path, sizeof (path), "%s/pkgremove",
1726*5c51f124SMoriah Waterland 		a_altBinDir == (char *)NULL ? PKGBIN : a_altBinDir);
1727*5c51f124SMoriah Waterland 
1728*5c51f124SMoriah Waterland 	nargs = 0;
1729*5c51f124SMoriah Waterland 
1730*5c51f124SMoriah Waterland 	/* first argument is path to executable */
1731*5c51f124SMoriah Waterland 
1732*5c51f124SMoriah Waterland 	arg[nargs++] = strdup(path);
1733*5c51f124SMoriah Waterland 
1734*5c51f124SMoriah Waterland 	/* second argument is always: pass -O debug to pkgremove: debug mode */
1735*5c51f124SMoriah Waterland 
1736*5c51f124SMoriah Waterland 	if (debugFlag == B_TRUE) {
1737*5c51f124SMoriah Waterland 		arg[nargs++] = "-O";
1738*5c51f124SMoriah Waterland 		arg[nargs++] = "debug";
1739*5c51f124SMoriah Waterland 	}
1740*5c51f124SMoriah Waterland 
1741*5c51f124SMoriah Waterland 	/* pkgrm -b dir: pass -b to pkgremove */
1742*5c51f124SMoriah Waterland 
1743*5c51f124SMoriah Waterland 	if (a_altBinDir != (char *)NULL) {
1744*5c51f124SMoriah Waterland 		arg[nargs++] = "-b";
1745*5c51f124SMoriah Waterland 		arg[nargs++] = a_altBinDir;
1746*5c51f124SMoriah Waterland 	}
1747*5c51f124SMoriah Waterland 
1748*5c51f124SMoriah Waterland 	/*
1749*5c51f124SMoriah Waterland 	 * NONABI_SCRIPTS defined: pass -o to pkgremove; refers to a
1750*5c51f124SMoriah Waterland 	 * pkg requiring operator interaction during a procedure script
1751*5c51f124SMoriah Waterland 	 * (common before on1093)
1752*5c51f124SMoriah Waterland 	 */
1753*5c51f124SMoriah Waterland 
1754*5c51f124SMoriah Waterland 	if (old_pkg) {
1755*5c51f124SMoriah Waterland 		arg[nargs++] = "-o";
1756*5c51f124SMoriah Waterland 	}
1757*5c51f124SMoriah Waterland 
1758*5c51f124SMoriah Waterland 	/*
1759*5c51f124SMoriah Waterland 	 * PKG_NONABI_SYMLINKS defined: pass -y to pkgremove; process
1760*5c51f124SMoriah Waterland 	 * symlinks consistent with old behavior
1761*5c51f124SMoriah Waterland 	 */
1762*5c51f124SMoriah Waterland 
1763*5c51f124SMoriah Waterland 	if (old_symlinks) {
1764*5c51f124SMoriah Waterland 		arg[nargs++] = "-y";
1765*5c51f124SMoriah Waterland 	}
1766*5c51f124SMoriah Waterland 
1767*5c51f124SMoriah Waterland 	/* pkgrm -M: pass -M to pkgrm: dont mount client file systems */
1768*5c51f124SMoriah Waterland 
1769*5c51f124SMoriah Waterland 	if (no_map_client) {
1770*5c51f124SMoriah Waterland 		arg[nargs++] = "-M";
1771*5c51f124SMoriah Waterland 	}
1772*5c51f124SMoriah Waterland 
1773*5c51f124SMoriah Waterland 	/* pkgrm -A: pass -A to pkgrm */
1774*5c51f124SMoriah Waterland 
1775*5c51f124SMoriah Waterland 	if (pkgrmremote) {
1776*5c51f124SMoriah Waterland 		arg[nargs++] = "-A";
1777*5c51f124SMoriah Waterland 	}
1778*5c51f124SMoriah Waterland 
1779*5c51f124SMoriah Waterland 	/* pkgrm -v: pass -v to pkgremove: trace scripts */
1780*5c51f124SMoriah Waterland 
1781*5c51f124SMoriah Waterland 	if (pkgverbose) {
1782*5c51f124SMoriah Waterland 		arg[nargs++] = "-v";
1783*5c51f124SMoriah Waterland 	}
1784*5c51f124SMoriah Waterland 
1785*5c51f124SMoriah Waterland 	/* pkgrm -n: pass -n to pkgremove: noninteractive mode */
1786*5c51f124SMoriah Waterland 
1787*5c51f124SMoriah Waterland 	if (nointeract) {
1788*5c51f124SMoriah Waterland 		arg[nargs++] = "-n";
1789*5c51f124SMoriah Waterland 	}
1790*5c51f124SMoriah Waterland 
1791*5c51f124SMoriah Waterland 	/* pkgrm -a admin: pass -a admin to pkgremove: admin file */
1792*5c51f124SMoriah Waterland 
1793*5c51f124SMoriah Waterland 	if (a_adminFile) {
1794*5c51f124SMoriah Waterland 		arg[nargs++] = "-a";
1795*5c51f124SMoriah Waterland 		arg[nargs++] = strdup(a_adminFile);
1796*5c51f124SMoriah Waterland 	}
1797*5c51f124SMoriah Waterland 
1798*5c51f124SMoriah Waterland 	/* pkgrm -V vfstab: pass -V vfstab to pkgremove: alternate vfstab */
1799*5c51f124SMoriah Waterland 
1800*5c51f124SMoriah Waterland 	if (vfstab_file) {
1801*5c51f124SMoriah Waterland 		arg[nargs++] = "-V";
1802*5c51f124SMoriah Waterland 		arg[nargs++] = vfstab_file;
1803*5c51f124SMoriah Waterland 	}
1804*5c51f124SMoriah Waterland 
1805*5c51f124SMoriah Waterland 	/* pkgrm -R root: pass -R root to pkgremove: alternative root */
1806*5c51f124SMoriah Waterland 
1807*5c51f124SMoriah Waterland 	if (is_an_inst_root()) {
1808*5c51f124SMoriah Waterland 		arg[nargs++] = "-R";
1809*5c51f124SMoriah Waterland 		arg[nargs++] = get_inst_root();
1810*5c51f124SMoriah Waterland 	}
1811*5c51f124SMoriah Waterland 
1812*5c51f124SMoriah Waterland 	/* pkgrm -F: pass -F to pkgremove: update DB only */
1813*5c51f124SMoriah Waterland 
1814*5c51f124SMoriah Waterland 	if (a_nodelete) {
1815*5c51f124SMoriah Waterland 		arg[nargs++] = "-F";
1816*5c51f124SMoriah Waterland 	}
1817*5c51f124SMoriah Waterland 
1818*5c51f124SMoriah Waterland 	/* add all inherited file systems */
1819*5c51f124SMoriah Waterland 
1820*5c51f124SMoriah Waterland 	if (a_inheritedPkgDirs != (char **)NULL) {
1821*5c51f124SMoriah Waterland 		for (n = 0; a_inheritedPkgDirs[n] != (char *)NULL; n++) {
1822*5c51f124SMoriah Waterland 			char	ifs[MAXPATHLEN+22];
1823*5c51f124SMoriah Waterland 			(void) snprintf(ifs, sizeof (ifs),
1824*5c51f124SMoriah Waterland 				"inherited-filesystem=%s",
1825*5c51f124SMoriah Waterland 				a_inheritedPkgDirs[n]);
1826*5c51f124SMoriah Waterland 			arg[nargs++] = "-O";
1827*5c51f124SMoriah Waterland 			arg[nargs++] = strdup(ifs);
1828*5c51f124SMoriah Waterland 		}
1829*5c51f124SMoriah Waterland 	}
1830*5c51f124SMoriah Waterland 
1831*5c51f124SMoriah Waterland 	/*
1832*5c51f124SMoriah Waterland 	 * add parent zone info/type
1833*5c51f124SMoriah Waterland 	 */
1834*5c51f124SMoriah Waterland 
1835*5c51f124SMoriah Waterland 	p = z_get_zonename();
1836*5c51f124SMoriah Waterland 	if ((p != NULL) && (*p != '\0')) {
1837*5c51f124SMoriah Waterland 			char	zn[MAXPATHLEN];
1838*5c51f124SMoriah Waterland 			(void) snprintf(zn, sizeof (zn),
1839*5c51f124SMoriah Waterland 				"parent-zone-name=%s", p);
1840*5c51f124SMoriah Waterland 			arg[nargs++] = "-O";
1841*5c51f124SMoriah Waterland 			arg[nargs++] = strdup(zn);
1842*5c51f124SMoriah Waterland 	}
1843*5c51f124SMoriah Waterland 
1844*5c51f124SMoriah Waterland 	/* current zone type */
1845*5c51f124SMoriah Waterland 
1846*5c51f124SMoriah Waterland 	arg[nargs++] = "-O";
1847*5c51f124SMoriah Waterland 	if (z_running_in_global_zone() == B_TRUE) {
1848*5c51f124SMoriah Waterland 			char	zn[MAXPATHLEN];
1849*5c51f124SMoriah Waterland 			(void) snprintf(zn, sizeof (zn),
1850*5c51f124SMoriah Waterland 				"parent-zone-type=%s",
1851*5c51f124SMoriah Waterland 				TAG_VALUE_GLOBAL_ZONE);
1852*5c51f124SMoriah Waterland 			arg[nargs++] = strdup(zn);
1853*5c51f124SMoriah Waterland 	} else {
1854*5c51f124SMoriah Waterland 			char	zn[MAXPATHLEN];
1855*5c51f124SMoriah Waterland 			(void) snprintf(zn, sizeof (zn),
1856*5c51f124SMoriah Waterland 				"parent-zone-type=%s",
1857*5c51f124SMoriah Waterland 				TAG_VALUE_NONGLOBAL_ZONE);
1858*5c51f124SMoriah Waterland 			arg[nargs++] = strdup(zn);
1859*5c51f124SMoriah Waterland 	}
1860*5c51f124SMoriah Waterland 
1861*5c51f124SMoriah Waterland 	/* pass -N to pkgremove: program name to report */
1862*5c51f124SMoriah Waterland 
1863*5c51f124SMoriah Waterland 	arg[nargs++] = "-N";
1864*5c51f124SMoriah Waterland 	arg[nargs++] = get_prog_name();
1865*5c51f124SMoriah Waterland 
1866*5c51f124SMoriah Waterland 	/* add package instance name */
1867*5c51f124SMoriah Waterland 
1868*5c51f124SMoriah Waterland 	arg[nargs++] = pkginst;
1869*5c51f124SMoriah Waterland 
1870*5c51f124SMoriah Waterland 	/* terminate argument list */
1871*5c51f124SMoriah Waterland 
1872*5c51f124SMoriah Waterland 	arg[nargs++] = NULL;
1873*5c51f124SMoriah Waterland 
1874*5c51f124SMoriah Waterland 	/*
1875*5c51f124SMoriah Waterland 	 * run the appropriate pkgremove command in the specified zone
1876*5c51f124SMoriah Waterland 	 */
1877*5c51f124SMoriah Waterland 
1878*5c51f124SMoriah Waterland 	if (debugFlag == B_TRUE) {
1879*5c51f124SMoriah Waterland 		echoDebug(DBG_ZONE_EXEC_ENTER, "global", arg[0]);
1880*5c51f124SMoriah Waterland 		for (n = 0; arg[n]; n++) {
1881*5c51f124SMoriah Waterland 			echoDebug(DBG_ARG, n, arg[n]);
1882*5c51f124SMoriah Waterland 		}
1883*5c51f124SMoriah Waterland 	}
1884*5c51f124SMoriah Waterland 
1885*5c51f124SMoriah Waterland 	/* execute pkgremove command */
1886*5c51f124SMoriah Waterland 
1887*5c51f124SMoriah Waterland 	n = pkgexecv(NULL, NULL, NULL, NULL, arg);
1888*5c51f124SMoriah Waterland 
1889*5c51f124SMoriah Waterland 	/* return results of pkgrm in this zone */
1890*5c51f124SMoriah Waterland 
1891*5c51f124SMoriah Waterland 	return (n);
1892*5c51f124SMoriah Waterland }
1893*5c51f124SMoriah Waterland 
1894*5c51f124SMoriah Waterland static void
1895*5c51f124SMoriah Waterland usage(void)
1896*5c51f124SMoriah Waterland {
1897*5c51f124SMoriah Waterland 	char	*prog = get_prog_name();
1898*5c51f124SMoriah Waterland 
1899*5c51f124SMoriah Waterland 	(void) fprintf(stderr, ERR_USAGE_PKGRM, prog, prog);
1900*5c51f124SMoriah Waterland 	exit(1);
1901*5c51f124SMoriah Waterland }
1902*5c51f124SMoriah Waterland 
1903*5c51f124SMoriah Waterland /*
1904*5c51f124SMoriah Waterland  * Name:	remove_packages_in_global_with_zones
1905*5c51f124SMoriah Waterland  * Description:	Remove packages from the global zone and from non-global zones
1906*5c51f124SMoriah Waterland  *		when run from the global zone and when non-global zones are
1907*5c51f124SMoriah Waterland  *		present.
1908*5c51f124SMoriah Waterland  * Arguments:	a_pkgList - pointer to array of strings, each string specifying
1909*5c51f124SMoriah Waterland  *			the name of one package to be removed.
1910*5c51f124SMoriah Waterland  *		a_nodelete: should the files and scripts remain installed?
1911*5c51f124SMoriah Waterland  *			- if != 0 pass -F flag to pkgremove - suppress
1912*5c51f124SMoriah Waterland  *			the removal of any files and any class action scripts
1913*5c51f124SMoriah Waterland  *			and suppress the running of any class action scripts.
1914*5c51f124SMoriah Waterland  *			The package files remain but the package looks like it
1915*5c51f124SMoriah Waterland  *			is not installed. This is mainly for use by upgrade.
1916*5c51f124SMoriah Waterland  *			- if == 0 do not pass -F flag to pkgremove - all
1917*5c51f124SMoriah Waterland  *			files and class action scripts are removed, and any
1918*5c51f124SMoriah Waterland  *			appropriate class action scripts are run.
1919*5c51f124SMoriah Waterland  *		a_longestPkg - length of the longest package "name" (for
1920*5c51f124SMoriah Waterland  *			output format alignment)
1921*5c51f124SMoriah Waterland  *		a_repeat - are there more packages avialable in "optind"
1922*5c51f124SMoriah Waterland  *			- B_TRUE - process packages from optind
1923*5c51f124SMoriah Waterland  *			- B_FALSE - do not process packages from optind
1924*5c51f124SMoriah Waterland  *		a_altBinDir - pointer to string representing location of the
1925*5c51f124SMoriah Waterland  *			pkgremove executable to run. If not NULL, then pass
1926*5c51f124SMoriah Waterland  *			the path specified to the -b option to pkgremove.
1927*5c51f124SMoriah Waterland  *		a_pkgdir - pointer to string representing the directory
1928*5c51f124SMoriah Waterland  *			where the packages to be removed are located.
1929*5c51f124SMoriah Waterland  *		a_zlst - list of zones to process; NULL if no zones to process.
1930*5c51f124SMoriah Waterland  * Returns:	int	(see ckreturn() function for details)
1931*5c51f124SMoriah Waterland  *		0 - success
1932*5c51f124SMoriah Waterland  *		1 - package operation failed (fatal error)
1933*5c51f124SMoriah Waterland  *		2 - non-fatal error (warning)
1934*5c51f124SMoriah Waterland  *		3 - user selected quit (operation interrupted)
1935*5c51f124SMoriah Waterland  *		4 - admin settings prevented operation
1936*5c51f124SMoriah Waterland  *		5 - interaction required and -n (non-interactive) specified
1937*5c51f124SMoriah Waterland  *		"10" will be added to indicate "immediate reboot required"
1938*5c51f124SMoriah Waterland  *		"20" will be added to indicate "reboot after install required"
1939*5c51f124SMoriah Waterland  */
1940*5c51f124SMoriah Waterland 
1941*5c51f124SMoriah Waterland static boolean_t
1942*5c51f124SMoriah Waterland remove_packages_in_global_with_zones(char **a_pkgList, int a_nodelete,
1943*5c51f124SMoriah Waterland 	int a_longestPkg, int a_repeat, char *a_altBinDir, char *a_pkgdir,
1944*5c51f124SMoriah Waterland 	zoneList_t a_zlst)
1945*5c51f124SMoriah Waterland {
1946*5c51f124SMoriah Waterland static	char		*zoneAdminFile = (char *)NULL;
1947*5c51f124SMoriah Waterland 
1948*5c51f124SMoriah Waterland 	boolean_t	b;
1949*5c51f124SMoriah Waterland 	char		**inheritedPkgDirs;
1950*5c51f124SMoriah Waterland 	char		*zoneName;
1951*5c51f124SMoriah Waterland 	char		*scratchName;
1952*5c51f124SMoriah Waterland 	char		preremovecheckPath[PATH_MAX+1];
1953*5c51f124SMoriah Waterland 	int		i;
1954*5c51f124SMoriah Waterland 	int		n;
1955*5c51f124SMoriah Waterland 	int		savenpkgs = npkgs;
1956*5c51f124SMoriah Waterland 	int		zoneIndex;
1957*5c51f124SMoriah Waterland 	int		zonesSkipped;
1958*5c51f124SMoriah Waterland 	zone_state_t	zst;
1959*5c51f124SMoriah Waterland 
1960*5c51f124SMoriah Waterland 	/* entry assertions */
1961*5c51f124SMoriah Waterland 
1962*5c51f124SMoriah Waterland 	assert(a_zlst != (zoneList_t)NULL);
1963*5c51f124SMoriah Waterland 	assert(a_pkgList != (char **)NULL);
1964*5c51f124SMoriah Waterland 	assert(a_longestPkg > 0);
1965*5c51f124SMoriah Waterland 	assert(a_pkgdir != (char *)NULL);
1966*5c51f124SMoriah Waterland 	assert(*a_pkgdir != '\0');
1967*5c51f124SMoriah Waterland 
1968*5c51f124SMoriah Waterland 	/* entry debugging info */
1969*5c51f124SMoriah Waterland 
1970*5c51f124SMoriah Waterland 	echoDebug(DBG_PKGREMPKGSGZWNGZ_ENTRY);
1971*5c51f124SMoriah Waterland 	echoDebug(DBG_PKGREMPKGSGZWNGZ_ARGS, a_nodelete, a_longestPkg,
1972*5c51f124SMoriah Waterland 		a_repeat, PSTR(a_altBinDir), PSTR(a_pkgdir));
1973*5c51f124SMoriah Waterland 
1974*5c51f124SMoriah Waterland 	/* check all packages */
1975*5c51f124SMoriah Waterland 
1976*5c51f124SMoriah Waterland 	if (check_packages(a_pkgList, a_pkgdir) != B_TRUE) {
1977*5c51f124SMoriah Waterland 		quit(1);
1978*5c51f124SMoriah Waterland 	}
1979*5c51f124SMoriah Waterland 
1980*5c51f124SMoriah Waterland 	/* create temporary directory for use by zone operations */
1981*5c51f124SMoriah Waterland 
1982*5c51f124SMoriah Waterland 	create_zone_tempdir(&zoneTempDir, tmpdir);
1983*5c51f124SMoriah Waterland 
1984*5c51f124SMoriah Waterland 	/* create hands off settings admin file for use in a non-global zone */
1985*5c51f124SMoriah Waterland 
1986*5c51f124SMoriah Waterland 	create_zone_adminfile(&zoneAdminFile, zoneTempDir, admnfile);
1987*5c51f124SMoriah Waterland 
1988*5c51f124SMoriah Waterland 	/*
1989*5c51f124SMoriah Waterland 	 * all of the packages (as listed in the package list) are
1990*5c51f124SMoriah Waterland 	 * removed one at a time from all non-global zones and then
1991*5c51f124SMoriah Waterland 	 * from the global zone.
1992*5c51f124SMoriah Waterland 	 */
1993*5c51f124SMoriah Waterland 
1994*5c51f124SMoriah Waterland 	for (i = 0; (pkginst = a_pkgList[i]) != NULL; i++) {
1995*5c51f124SMoriah Waterland 		/* reset interrupted flag before calling pkgremove */
1996*5c51f124SMoriah Waterland 
1997*5c51f124SMoriah Waterland 		interrupted = 0;	/* last action was NOT quit */
1998*5c51f124SMoriah Waterland 
1999*5c51f124SMoriah Waterland 		/* skip package if it is "in the global zone only" */
2000*5c51f124SMoriah Waterland 
2001*5c51f124SMoriah Waterland 		if (pkgIsPkgInGzOnly(get_inst_root(), pkginst) == B_TRUE) {
2002*5c51f124SMoriah Waterland 			continue;
2003*5c51f124SMoriah Waterland 		}
2004*5c51f124SMoriah Waterland 
2005*5c51f124SMoriah Waterland 		/*
2006*5c51f124SMoriah Waterland 		 * if operation failed in global zone do not propagate to
2007*5c51f124SMoriah Waterland 		 * non-global zones
2008*5c51f124SMoriah Waterland 		 */
2009*5c51f124SMoriah Waterland 
2010*5c51f124SMoriah Waterland 		zonesSkipped = 0;
2011*5c51f124SMoriah Waterland 
2012*5c51f124SMoriah Waterland 		if (interrupted != 0) {
2013*5c51f124SMoriah Waterland 			echo(MSG_DOREMOVE_INTERRUPTED, pkginst);
2014*5c51f124SMoriah Waterland 			echoDebug(DBG_DOREMOVE_INTERRUPTED, pkginst);
2015*5c51f124SMoriah Waterland 			break;
2016*5c51f124SMoriah Waterland 		}
2017*5c51f124SMoriah Waterland 
2018*5c51f124SMoriah Waterland 		echoDebug(DBG_REMOVE_FLAG_VALUES, "before loop",
2019*5c51f124SMoriah Waterland 			admnflag, doreboot, failflag, interrupted,
2020*5c51f124SMoriah Waterland 			intrflag, ireboot, nullflag, warnflag);
2021*5c51f124SMoriah Waterland 
2022*5c51f124SMoriah Waterland 		for (zoneIndex = 0;
2023*5c51f124SMoriah Waterland 			(zoneName = z_zlist_get_zonename(a_zlst, zoneIndex)) !=
2024*5c51f124SMoriah Waterland 				(char *)NULL; zoneIndex++) {
2025*5c51f124SMoriah Waterland 
2026*5c51f124SMoriah Waterland 			/* skip the zone if it is NOT running */
2027*5c51f124SMoriah Waterland 
2028*5c51f124SMoriah Waterland 			zst = z_zlist_get_current_state(a_zlst, zoneIndex);
2029*5c51f124SMoriah Waterland 			if (zst != ZONE_STATE_RUNNING &&
2030*5c51f124SMoriah Waterland 			    zst != ZONE_STATE_MOUNTED) {
2031*5c51f124SMoriah Waterland 				zonesSkipped++;
2032*5c51f124SMoriah Waterland 				echoDebug(DBG_SKIPPING_ZONE, zoneName);
2033*5c51f124SMoriah Waterland 				continue;
2034*5c51f124SMoriah Waterland 			}
2035*5c51f124SMoriah Waterland 
2036*5c51f124SMoriah Waterland 			echo(MSG_CHECKREMOVE_PKG_IN_ZONE, pkginst, zoneName);
2037*5c51f124SMoriah Waterland 			echoDebug(DBG_CHECKREMOVE_PKG_IN_ZONE, pkginst,
2038*5c51f124SMoriah Waterland 				zoneName);
2039*5c51f124SMoriah Waterland 
2040*5c51f124SMoriah Waterland 			scratchName = z_zlist_get_scratch(a_zlst, zoneIndex);
2041*5c51f124SMoriah Waterland 
2042*5c51f124SMoriah Waterland 			(void) snprintf(preremovecheckPath,
2043*5c51f124SMoriah Waterland 				sizeof (preremovecheckPath),
2044*5c51f124SMoriah Waterland 				"%s/%s.%s.preremovecheck.txt",
2045*5c51f124SMoriah Waterland 				zoneTempDir, pkginst, scratchName);
2046*5c51f124SMoriah Waterland 
2047*5c51f124SMoriah Waterland 			/* determine list of dirs inherited from global zone */
2048*5c51f124SMoriah Waterland 
2049*5c51f124SMoriah Waterland 			inheritedPkgDirs =
2050*5c51f124SMoriah Waterland 				z_zlist_get_inherited_pkg_dirs(a_zlst,
2051*5c51f124SMoriah Waterland 					zoneIndex);
2052*5c51f124SMoriah Waterland 
2053*5c51f124SMoriah Waterland 			/*
2054*5c51f124SMoriah Waterland 			 * dependency check this package this zone; use the
2055*5c51f124SMoriah Waterland 			 * user supplied admin file so that the appropriate
2056*5c51f124SMoriah Waterland 			 * level of dependency checking is (or is not) done.
2057*5c51f124SMoriah Waterland 			 */
2058*5c51f124SMoriah Waterland 
2059*5c51f124SMoriah Waterland 			n = pkgZoneCheckRemove(scratchName, inheritedPkgDirs,
2060*5c51f124SMoriah Waterland 				a_altBinDir, admnfile, preremovecheckPath,
2061*5c51f124SMoriah Waterland 				zst);
2062*5c51f124SMoriah Waterland 
2063*5c51f124SMoriah Waterland 			/* set success/fail condition variables */
2064*5c51f124SMoriah Waterland 
2065*5c51f124SMoriah Waterland 			ckreturn(n);
2066*5c51f124SMoriah Waterland 
2067*5c51f124SMoriah Waterland 			echoDebug(DBG_REMOVE_FLAG_VALUES,
2068*5c51f124SMoriah Waterland 				"after pkgzonecheckremove",
2069*5c51f124SMoriah Waterland 				admnflag, doreboot, failflag, interrupted,
2070*5c51f124SMoriah Waterland 				intrflag, ireboot, nullflag, warnflag);
2071*5c51f124SMoriah Waterland 		}
2072*5c51f124SMoriah Waterland 
2073*5c51f124SMoriah Waterland 		if (zonesSkipped == 0) {
2074*5c51f124SMoriah Waterland 			continue;
2075*5c51f124SMoriah Waterland 		}
2076*5c51f124SMoriah Waterland 
2077*5c51f124SMoriah Waterland 		echoDebug(DBG_ZONES_SKIPPED, zonesSkipped);
2078*5c51f124SMoriah Waterland 
2079*5c51f124SMoriah Waterland 		for (zoneIndex = 0;
2080*5c51f124SMoriah Waterland 			(zoneName = z_zlist_get_zonename(a_zlst, zoneIndex)) !=
2081*5c51f124SMoriah Waterland 				(char *)NULL; zoneIndex++) {
2082*5c51f124SMoriah Waterland 
2083*5c51f124SMoriah Waterland 			/* skip the zone if it IS running */
2084*5c51f124SMoriah Waterland 
2085*5c51f124SMoriah Waterland 			zst = z_zlist_get_current_state(a_zlst, zoneIndex);
2086*5c51f124SMoriah Waterland 			if (zst == ZONE_STATE_RUNNING ||
2087*5c51f124SMoriah Waterland 			    zst == ZONE_STATE_MOUNTED) {
2088*5c51f124SMoriah Waterland 				zonesSkipped++;
2089*5c51f124SMoriah Waterland 				echoDebug(DBG_SKIPPING_ZONE_BOOT, zoneName);
2090*5c51f124SMoriah Waterland 				continue;
2091*5c51f124SMoriah Waterland 			}
2092*5c51f124SMoriah Waterland 
2093*5c51f124SMoriah Waterland 			/* skip the zone if it is NOT bootable */
2094*5c51f124SMoriah Waterland 
2095*5c51f124SMoriah Waterland 			if (z_zlist_is_zone_runnable(a_zlst,
2096*5c51f124SMoriah Waterland 						zoneIndex) == B_FALSE) {
2097*5c51f124SMoriah Waterland 				echo(MSG_SKIPPING_ZONE_NOT_RUNNABLE, zoneName);
2098*5c51f124SMoriah Waterland 				echoDebug(DBG_SKIPPING_ZONE_NOT_RUNNABLE,
2099*5c51f124SMoriah Waterland 					zoneName);
2100*5c51f124SMoriah Waterland 				continue;
2101*5c51f124SMoriah Waterland 			}
2102*5c51f124SMoriah Waterland 
2103*5c51f124SMoriah Waterland 			/* mount up the zone */
2104*5c51f124SMoriah Waterland 
2105*5c51f124SMoriah Waterland 			echo(MSG_BOOTING_ZONE, zoneName);
2106*5c51f124SMoriah Waterland 			echoDebug(DBG_BOOTING_ZONE, zoneName);
2107*5c51f124SMoriah Waterland 
2108*5c51f124SMoriah Waterland 			b = z_zlist_change_zone_state(a_zlst, zoneIndex,
2109*5c51f124SMoriah Waterland 				ZONE_STATE_MOUNTED);
2110*5c51f124SMoriah Waterland 			if (b == B_FALSE) {
2111*5c51f124SMoriah Waterland 				progerr(ERR_CANNOT_BOOT_ZONE, zoneName);
2112*5c51f124SMoriah Waterland 				/* set fatal error return condition */
2113*5c51f124SMoriah Waterland 				ckreturn(1);
2114*5c51f124SMoriah Waterland 				continue;
2115*5c51f124SMoriah Waterland 			}
2116*5c51f124SMoriah Waterland 
2117*5c51f124SMoriah Waterland 			echo(MSG_CHECKREMOVE_PKG_IN_ZONE, pkginst, zoneName);
2118*5c51f124SMoriah Waterland 			echoDebug(DBG_CHECKREMOVE_PKG_IN_ZONE, pkginst,
2119*5c51f124SMoriah Waterland 					zoneName);
2120*5c51f124SMoriah Waterland 
2121*5c51f124SMoriah Waterland 			scratchName = z_zlist_get_scratch(a_zlst, zoneIndex);
2122*5c51f124SMoriah Waterland 
2123*5c51f124SMoriah Waterland 			(void) snprintf(preremovecheckPath,
2124*5c51f124SMoriah Waterland 				sizeof (preremovecheckPath),
2125*5c51f124SMoriah Waterland 				"%s/%s.%s.preremovecheck.txt",
2126*5c51f124SMoriah Waterland 				zoneTempDir, pkginst, scratchName);
2127*5c51f124SMoriah Waterland 
2128*5c51f124SMoriah Waterland 			/* determine list of dirs inherited from global zone */
2129*5c51f124SMoriah Waterland 
2130*5c51f124SMoriah Waterland 			inheritedPkgDirs =
2131*5c51f124SMoriah Waterland 				z_zlist_get_inherited_pkg_dirs(a_zlst,
2132*5c51f124SMoriah Waterland 					zoneIndex);
2133*5c51f124SMoriah Waterland 
2134*5c51f124SMoriah Waterland 			/*
2135*5c51f124SMoriah Waterland 			 * dependency check this package this zone; use the
2136*5c51f124SMoriah Waterland 			 * user supplied admin file so that the appropriate
2137*5c51f124SMoriah Waterland 			 * level of dependency checking is (or is not) done.
2138*5c51f124SMoriah Waterland 			 */
2139*5c51f124SMoriah Waterland 
2140*5c51f124SMoriah Waterland 			n = pkgZoneCheckRemove(scratchName, inheritedPkgDirs,
2141*5c51f124SMoriah Waterland 				a_altBinDir, admnfile, preremovecheckPath,
2142*5c51f124SMoriah Waterland 				ZONE_STATE_MOUNTED);
2143*5c51f124SMoriah Waterland 
2144*5c51f124SMoriah Waterland 			/* set success/fail condition variables */
2145*5c51f124SMoriah Waterland 
2146*5c51f124SMoriah Waterland 			ckreturn(n);
2147*5c51f124SMoriah Waterland 
2148*5c51f124SMoriah Waterland 			echoDebug(DBG_REMOVE_FLAG_VALUES,
2149*5c51f124SMoriah Waterland 				"after pkgzonecheckremove",
2150*5c51f124SMoriah Waterland 				admnflag, doreboot, failflag, interrupted,
2151*5c51f124SMoriah Waterland 				intrflag, ireboot, nullflag, warnflag);
2152*5c51f124SMoriah Waterland 
2153*5c51f124SMoriah Waterland 			/* restore original state of zone */
2154*5c51f124SMoriah Waterland 
2155*5c51f124SMoriah Waterland 			echo(MSG_RESTORE_ZONE_STATE, zoneName);
2156*5c51f124SMoriah Waterland 			echoDebug(DBG_RESTORE_ZONE_STATE, zoneName);
2157*5c51f124SMoriah Waterland 
2158*5c51f124SMoriah Waterland 			b = z_zlist_restore_zone_state(a_zlst, zoneIndex);
2159*5c51f124SMoriah Waterland 		}
2160*5c51f124SMoriah Waterland 		npkgs--;
2161*5c51f124SMoriah Waterland 	}
2162*5c51f124SMoriah Waterland 
2163*5c51f124SMoriah Waterland 	/*
2164*5c51f124SMoriah Waterland 	 * look at all pre-remove check files
2165*5c51f124SMoriah Waterland 	 */
2166*5c51f124SMoriah Waterland 
2167*5c51f124SMoriah Waterland 	i = preremove_verify(a_pkgList, a_zlst, zoneTempDir);
2168*5c51f124SMoriah Waterland 	if (i != 0) {
2169*5c51f124SMoriah Waterland 		quit(i);
2170*5c51f124SMoriah Waterland 	}
2171*5c51f124SMoriah Waterland 
2172*5c51f124SMoriah Waterland 	npkgs = savenpkgs;
2173*5c51f124SMoriah Waterland 
2174*5c51f124SMoriah Waterland 	/*
2175*5c51f124SMoriah Waterland 	 * reset all error return condition variables that may have been
2176*5c51f124SMoriah Waterland 	 * set during package removal dependency checking so that they
2177*5c51f124SMoriah Waterland 	 * do not reflect on the success/failure of the actual package
2178*5c51f124SMoriah Waterland 	 * removal operations
2179*5c51f124SMoriah Waterland 	 */
2180*5c51f124SMoriah Waterland 
2181*5c51f124SMoriah Waterland 	resetreturn();
2182*5c51f124SMoriah Waterland 
2183*5c51f124SMoriah Waterland 	/*
2184*5c51f124SMoriah Waterland 	 * all of the packages (as listed in the package list) are
2185*5c51f124SMoriah Waterland 	 * removed one at a time.
2186*5c51f124SMoriah Waterland 	 */
2187*5c51f124SMoriah Waterland 
2188*5c51f124SMoriah Waterland 	interrupted = 0;
2189*5c51f124SMoriah Waterland 	for (i = 0; (pkginst = a_pkgList[i]) != NULL; i++) {
2190*5c51f124SMoriah Waterland 		boolean_t	in_gz_only;
2191*5c51f124SMoriah Waterland 		started = 0;
2192*5c51f124SMoriah Waterland 
2193*5c51f124SMoriah Waterland 		if (shall_we_continue(pkginst, npkgs) == B_FALSE) {
2194*5c51f124SMoriah Waterland 			continue;
2195*5c51f124SMoriah Waterland 		}
2196*5c51f124SMoriah Waterland 
2197*5c51f124SMoriah Waterland 		in_gz_only = pkgIsPkgInGzOnly(get_inst_root(), pkginst);
2198*5c51f124SMoriah Waterland 
2199*5c51f124SMoriah Waterland 		/* reset interrupted flag before calling pkgremove */
2200*5c51f124SMoriah Waterland 
2201*5c51f124SMoriah Waterland 		interrupted = 0;
2202*5c51f124SMoriah Waterland 
2203*5c51f124SMoriah Waterland 		/*
2204*5c51f124SMoriah Waterland 		 * pkgrm invoked from within the global zone and there are
2205*5c51f124SMoriah Waterland 		 * non-global zones configured:
2206*5c51f124SMoriah Waterland 		 * Remove the package from the global zone.
2207*5c51f124SMoriah Waterland 		 * If not removing the package from the global zone only,
2208*5c51f124SMoriah Waterland 		 * then remove the package from the list of zones specified.
2209*5c51f124SMoriah Waterland 		 */
2210*5c51f124SMoriah Waterland 
2211*5c51f124SMoriah Waterland 		if (in_gz_only) {
2212*5c51f124SMoriah Waterland 			/* global zone only */
2213*5c51f124SMoriah Waterland 			n = doRemove(a_nodelete, a_altBinDir, a_longestPkg,
2214*5c51f124SMoriah Waterland 				admnfile, (char *)NULL, (zoneList_t)NULL);
2215*5c51f124SMoriah Waterland 		} else {
2216*5c51f124SMoriah Waterland 			/* global zone and non-global zones */
2217*5c51f124SMoriah Waterland 			n = doRemove(a_nodelete, a_altBinDir, a_longestPkg,
2218*5c51f124SMoriah Waterland 				zoneAdminFile, zoneAdminFile, a_zlst);
2219*5c51f124SMoriah Waterland 		}
2220*5c51f124SMoriah Waterland 
2221*5c51f124SMoriah Waterland 		/* set success/fail condition variables */
2222*5c51f124SMoriah Waterland 
2223*5c51f124SMoriah Waterland 		ckreturn(n);
2224*5c51f124SMoriah Waterland 
2225*5c51f124SMoriah Waterland 		npkgs--;
2226*5c51f124SMoriah Waterland 	}
2227*5c51f124SMoriah Waterland 
2228*5c51f124SMoriah Waterland 	/*
2229*5c51f124SMoriah Waterland 	 * all packages in the package list have been removed.
2230*5c51f124SMoriah Waterland 	 * Continue with removal if:
2231*5c51f124SMoriah Waterland 	 * -- immediate reboot is NOT required
2232*5c51f124SMoriah Waterland 	 * -- there are more packages to remove
2233*5c51f124SMoriah Waterland 	 * else return do NOT continue.
2234*5c51f124SMoriah Waterland 	 */
2235*5c51f124SMoriah Waterland 
2236*5c51f124SMoriah Waterland 	if ((ireboot == 0) && (a_repeat != 0)) {
2237*5c51f124SMoriah Waterland 		return (B_TRUE);
2238*5c51f124SMoriah Waterland 	}
2239*5c51f124SMoriah Waterland 
2240*5c51f124SMoriah Waterland 	/* return 'dont continue' */
2241*5c51f124SMoriah Waterland 
2242*5c51f124SMoriah Waterland 	return (B_FALSE);
2243*5c51f124SMoriah Waterland }
2244*5c51f124SMoriah Waterland 
2245*5c51f124SMoriah Waterland /*
2246*5c51f124SMoriah Waterland  * Name:	remove_packages_in_nonglobal_zone
2247*5c51f124SMoriah Waterland  * Description:	Remove packages in a non-global zone when run from a
2248*5c51f124SMoriah Waterland  *		non-global zone.
2249*5c51f124SMoriah Waterland  * Arguments:	a_pkgList - pointer to array of strings, each string specifying
2250*5c51f124SMoriah Waterland  *			the name of one package to be removed.
2251*5c51f124SMoriah Waterland  *		a_nodelete: should the files and scripts remain installed?
2252*5c51f124SMoriah Waterland  *			- if != 0 pass -F flag to pkgremove - suppress
2253*5c51f124SMoriah Waterland  *			the removal of any files and any class action scripts
2254*5c51f124SMoriah Waterland  *			and suppress the running of any class action scripts.
2255*5c51f124SMoriah Waterland  *			The package files remain but the package looks like it
2256*5c51f124SMoriah Waterland  *			is not installed. This is mainly for use by upgrade.
2257*5c51f124SMoriah Waterland  *			- if == 0 do not pass -F flag to pkgremove - all
2258*5c51f124SMoriah Waterland  *			files and class action scripts are removed, and any
2259*5c51f124SMoriah Waterland  *			appropriate class action scripts are run.
2260*5c51f124SMoriah Waterland  *		a_longestPkg - length of the longest package "name" (for
2261*5c51f124SMoriah Waterland  *			output format alignment)
2262*5c51f124SMoriah Waterland  *		a_repeat - are there more packages avialable in "optind"
2263*5c51f124SMoriah Waterland  *			- B_TRUE - process packages from optind
2264*5c51f124SMoriah Waterland  *			- B_FALSE - do not process packages from optind
2265*5c51f124SMoriah Waterland  *		a_altBinDir - pointer to string representing location of the
2266*5c51f124SMoriah Waterland  *			pkgremove executable to run. If not NULL, then pass
2267*5c51f124SMoriah Waterland  *			the path specified to the -b option to pkgremove.
2268*5c51f124SMoriah Waterland  *		a_pkgdir - pointer to string representing the directory
2269*5c51f124SMoriah Waterland  *			where the packages to be removed are located.
2270*5c51f124SMoriah Waterland  * Returns:	int	(see ckreturn() function for details)
2271*5c51f124SMoriah Waterland  *		0 - success
2272*5c51f124SMoriah Waterland  *		1 - package operation failed (fatal error)
2273*5c51f124SMoriah Waterland  *		2 - non-fatal error (warning)
2274*5c51f124SMoriah Waterland  *		3 - user selected quit (operation interrupted)
2275*5c51f124SMoriah Waterland  *		4 - admin settings prevented operation
2276*5c51f124SMoriah Waterland  *		5 - interaction required and -n (non-interactive) specified
2277*5c51f124SMoriah Waterland  *		"10" will be added to indicate "immediate reboot required"
2278*5c51f124SMoriah Waterland  *		"20" will be added to indicate "reboot after install required"
2279*5c51f124SMoriah Waterland  */
2280*5c51f124SMoriah Waterland 
2281*5c51f124SMoriah Waterland static boolean_t
2282*5c51f124SMoriah Waterland remove_packages_in_nonglobal_zone(char **a_pkgList, int a_nodelete,
2283*5c51f124SMoriah Waterland 	int a_longestPkg, int a_repeat, char *a_altBinDir, char *a_pkgdir)
2284*5c51f124SMoriah Waterland {
2285*5c51f124SMoriah Waterland static	char		*zoneAdminFile = (char *)NULL;
2286*5c51f124SMoriah Waterland 
2287*5c51f124SMoriah Waterland 	int		n;
2288*5c51f124SMoriah Waterland 	int		i;
2289*5c51f124SMoriah Waterland 
2290*5c51f124SMoriah Waterland 	/* entry assertions */
2291*5c51f124SMoriah Waterland 
2292*5c51f124SMoriah Waterland 	assert(a_pkgList != (char **)NULL);
2293*5c51f124SMoriah Waterland 	assert(a_longestPkg > 0);
2294*5c51f124SMoriah Waterland 	assert(a_pkgdir != (char *)NULL);
2295*5c51f124SMoriah Waterland 	assert(*a_pkgdir != '\0');
2296*5c51f124SMoriah Waterland 
2297*5c51f124SMoriah Waterland 	/* entry debugging info */
2298*5c51f124SMoriah Waterland 
2299*5c51f124SMoriah Waterland 	echoDebug(DBG_PKGREMPKGSNGZ_ENTRY);
2300*5c51f124SMoriah Waterland 	echoDebug(DBG_PKGREMPKGSNGZ_ARGS, a_nodelete, a_longestPkg,
2301*5c51f124SMoriah Waterland 		a_repeat, PSTR(a_altBinDir), PSTR(a_pkgdir));
2302*5c51f124SMoriah Waterland 
2303*5c51f124SMoriah Waterland 	/* check all package */
2304*5c51f124SMoriah Waterland 
2305*5c51f124SMoriah Waterland 	if (check_packages(a_pkgList, a_pkgdir) != B_TRUE) {
2306*5c51f124SMoriah Waterland 		quit(1);
2307*5c51f124SMoriah Waterland 	}
2308*5c51f124SMoriah Waterland 
2309*5c51f124SMoriah Waterland 	/* create temporary directory for use by zone operations */
2310*5c51f124SMoriah Waterland 
2311*5c51f124SMoriah Waterland 	create_zone_tempdir(&zoneTempDir, tmpdir);
2312*5c51f124SMoriah Waterland 
2313*5c51f124SMoriah Waterland 	/* create hands off settings admin file for use in a non-global zone */
2314*5c51f124SMoriah Waterland 
2315*5c51f124SMoriah Waterland 	create_zone_adminfile(&zoneAdminFile, zoneTempDir, admnfile);
2316*5c51f124SMoriah Waterland 
2317*5c51f124SMoriah Waterland 	/*
2318*5c51f124SMoriah Waterland 	 * all of the packages (as listed in the package list) are
2319*5c51f124SMoriah Waterland 	 * removed one at a time.
2320*5c51f124SMoriah Waterland 	 */
2321*5c51f124SMoriah Waterland 
2322*5c51f124SMoriah Waterland 	interrupted = 0;
2323*5c51f124SMoriah Waterland 	for (i = 0; (pkginst = a_pkgList[i]) != NULL; i++) {
2324*5c51f124SMoriah Waterland 		started = 0;
2325*5c51f124SMoriah Waterland 
2326*5c51f124SMoriah Waterland 		if (shall_we_continue(pkginst, npkgs) == B_FALSE) {
2327*5c51f124SMoriah Waterland 			continue;
2328*5c51f124SMoriah Waterland 		}
2329*5c51f124SMoriah Waterland 
2330*5c51f124SMoriah Waterland 		interrupted = 0;
2331*5c51f124SMoriah Waterland 
2332*5c51f124SMoriah Waterland 		/*
2333*5c51f124SMoriah Waterland 		 * pkgrm invoked from within a non-global zone: remove
2334*5c51f124SMoriah Waterland 		 * the package from the current zone only - no non-global
2335*5c51f124SMoriah Waterland 		 * zones are possible.
2336*5c51f124SMoriah Waterland 		 */
2337*5c51f124SMoriah Waterland 
2338*5c51f124SMoriah Waterland 		n = doRemove(a_nodelete, a_altBinDir, a_longestPkg,
2339*5c51f124SMoriah Waterland 			admnfile, (char *)NULL, (zoneList_t)NULL);
2340*5c51f124SMoriah Waterland 
2341*5c51f124SMoriah Waterland 		/* set success/fail condition variables */
2342*5c51f124SMoriah Waterland 
2343*5c51f124SMoriah Waterland 		ckreturn(n);
2344*5c51f124SMoriah Waterland 
2345*5c51f124SMoriah Waterland 		npkgs--;
2346*5c51f124SMoriah Waterland 	}
2347*5c51f124SMoriah Waterland 
2348*5c51f124SMoriah Waterland 	/*
2349*5c51f124SMoriah Waterland 	 * all packages in the package list have been removed.
2350*5c51f124SMoriah Waterland 	 * Continue with removal if:
2351*5c51f124SMoriah Waterland 	 * -- immediate reboot is NOT required
2352*5c51f124SMoriah Waterland 	 * -- there are more packages to remove
2353*5c51f124SMoriah Waterland 	 * else return do NOT continue.
2354*5c51f124SMoriah Waterland 	 */
2355*5c51f124SMoriah Waterland 
2356*5c51f124SMoriah Waterland 	if ((ireboot == 0) && (a_repeat != 0)) {
2357*5c51f124SMoriah Waterland 		return (B_TRUE);
2358*5c51f124SMoriah Waterland 	}
2359*5c51f124SMoriah Waterland 
2360*5c51f124SMoriah Waterland 	/* return 'dont continue' */
2361*5c51f124SMoriah Waterland 
2362*5c51f124SMoriah Waterland 	return (B_FALSE);
2363*5c51f124SMoriah Waterland }
2364*5c51f124SMoriah Waterland 
2365*5c51f124SMoriah Waterland /*
2366*5c51f124SMoriah Waterland  * Name:	remove_packages_in_global_no_zones
2367*5c51f124SMoriah Waterland  * Description:	Remove packages from the global zone only when run in the
2368*5c51f124SMoriah Waterland  *		global zone and no non-global zones are installed.
2369*5c51f124SMoriah Waterland  * Arguments:	a_pkgList - pointer to array of strings, each string specifying
2370*5c51f124SMoriah Waterland  *			the name of one package to be removed.
2371*5c51f124SMoriah Waterland  *		a_nodelete: should the files and scripts remain installed?
2372*5c51f124SMoriah Waterland  *			- if != 0 pass -F flag to pkgremove - suppress
2373*5c51f124SMoriah Waterland  *			the removal of any files and any class action scripts
2374*5c51f124SMoriah Waterland  *			and suppress the running of any class action scripts.
2375*5c51f124SMoriah Waterland  *			The package files remain but the package looks like it
2376*5c51f124SMoriah Waterland  *			is not installed. This is mainly for use by upgrade.
2377*5c51f124SMoriah Waterland  *			- if == 0 do not pass -F flag to pkgremove - all
2378*5c51f124SMoriah Waterland  *			files and class action scripts are removed, and any
2379*5c51f124SMoriah Waterland  *			appropriate class action scripts are run.
2380*5c51f124SMoriah Waterland  *		a_longestPkg - length of the longest package "name" (for
2381*5c51f124SMoriah Waterland  *			output format alignment)
2382*5c51f124SMoriah Waterland  *		a_repeat - are there more packages avialable in "optind"
2383*5c51f124SMoriah Waterland  *			- B_TRUE - process packages from optind
2384*5c51f124SMoriah Waterland  *			- B_FALSE - do not process packages from optind
2385*5c51f124SMoriah Waterland  *		a_altBinDir - pointer to string representing location of the
2386*5c51f124SMoriah Waterland  *			pkgremove executable to run. If not NULL, then pass
2387*5c51f124SMoriah Waterland  *			the path specified to the -b option to pkgremove.
2388*5c51f124SMoriah Waterland  * Returns:	int	(see ckreturn() function for details)
2389*5c51f124SMoriah Waterland  *		0 - success
2390*5c51f124SMoriah Waterland  *		1 - package operation failed (fatal error)
2391*5c51f124SMoriah Waterland  *		2 - non-fatal error (warning)
2392*5c51f124SMoriah Waterland  *		3 - user selected quit (operation interrupted)
2393*5c51f124SMoriah Waterland  *		4 - admin settings prevented operation
2394*5c51f124SMoriah Waterland  *		5 - interaction required and -n (non-interactive) specified
2395*5c51f124SMoriah Waterland  *		"10" will be added to indicate "immediate reboot required"
2396*5c51f124SMoriah Waterland  *		"20" will be added to indicate "reboot after install required"
2397*5c51f124SMoriah Waterland  */
2398*5c51f124SMoriah Waterland 
2399*5c51f124SMoriah Waterland static boolean_t
2400*5c51f124SMoriah Waterland remove_packages_in_global_no_zones(char **a_pkgList, int a_nodelete,
2401*5c51f124SMoriah Waterland 	int a_longestPkg, int a_repeat, char *a_altBinDir)
2402*5c51f124SMoriah Waterland {
2403*5c51f124SMoriah Waterland 	int	n;
2404*5c51f124SMoriah Waterland 	int	i;
2405*5c51f124SMoriah Waterland 
2406*5c51f124SMoriah Waterland 	/* entry assertions */
2407*5c51f124SMoriah Waterland 
2408*5c51f124SMoriah Waterland 	assert(a_pkgList != (char **)NULL);
2409*5c51f124SMoriah Waterland 	assert(a_longestPkg > 0);
2410*5c51f124SMoriah Waterland 
2411*5c51f124SMoriah Waterland 	/* entry debugging info */
2412*5c51f124SMoriah Waterland 
2413*5c51f124SMoriah Waterland 	echoDebug(DBG_PKGREMPKGSGZNNGZ_ENTRY);
2414*5c51f124SMoriah Waterland 	echoDebug(DBG_PKGREMPKGSGZNNGZ_ARGS, a_nodelete, a_longestPkg,
2415*5c51f124SMoriah Waterland 		a_repeat, PSTR(a_altBinDir));
2416*5c51f124SMoriah Waterland 
2417*5c51f124SMoriah Waterland 	/*
2418*5c51f124SMoriah Waterland 	 * all of the packages (as listed in the package list) are
2419*5c51f124SMoriah Waterland 	 * removed one at a time.
2420*5c51f124SMoriah Waterland 	 */
2421*5c51f124SMoriah Waterland 
2422*5c51f124SMoriah Waterland 	interrupted = 0;
2423*5c51f124SMoriah Waterland 	for (i = 0; (pkginst = a_pkgList[i]) != NULL; i++) {
2424*5c51f124SMoriah Waterland 		started = 0;
2425*5c51f124SMoriah Waterland 
2426*5c51f124SMoriah Waterland 		if (shall_we_continue(pkginst, npkgs) == B_FALSE) {
2427*5c51f124SMoriah Waterland 			continue;
2428*5c51f124SMoriah Waterland 		}
2429*5c51f124SMoriah Waterland 
2430*5c51f124SMoriah Waterland 		interrupted = 0;
2431*5c51f124SMoriah Waterland 
2432*5c51f124SMoriah Waterland 		/*
2433*5c51f124SMoriah Waterland 		 * pkgrm invoked from within the global zone and there are
2434*5c51f124SMoriah Waterland 		 * NO non-global zones configured:
2435*5c51f124SMoriah Waterland 		 * Remove the package from the global zone only.
2436*5c51f124SMoriah Waterland 		 */
2437*5c51f124SMoriah Waterland 
2438*5c51f124SMoriah Waterland 		n = doRemove(a_nodelete, a_altBinDir, a_longestPkg,
2439*5c51f124SMoriah Waterland 				admnfile, (char *)NULL, (zoneList_t)NULL);
2440*5c51f124SMoriah Waterland 
2441*5c51f124SMoriah Waterland 		/* set success/fail condition variables */
2442*5c51f124SMoriah Waterland 
2443*5c51f124SMoriah Waterland 		ckreturn(n);
2444*5c51f124SMoriah Waterland 
2445*5c51f124SMoriah Waterland 		npkgs--;
2446*5c51f124SMoriah Waterland 	}
2447*5c51f124SMoriah Waterland 
2448*5c51f124SMoriah Waterland 	/*
2449*5c51f124SMoriah Waterland 	 * all packages in the package list have been removed.
2450*5c51f124SMoriah Waterland 	 * Continue with removal if:
2451*5c51f124SMoriah Waterland 	 * -- immediate reboot is NOT required
2452*5c51f124SMoriah Waterland 	 * -- there are more packages to remove
2453*5c51f124SMoriah Waterland 	 * else return do NOT continue.
2454*5c51f124SMoriah Waterland 	 */
2455*5c51f124SMoriah Waterland 
2456*5c51f124SMoriah Waterland 	if ((ireboot == 0) && (a_repeat != 0)) {
2457*5c51f124SMoriah Waterland 		return (B_TRUE);
2458*5c51f124SMoriah Waterland 	}
2459*5c51f124SMoriah Waterland 
2460*5c51f124SMoriah Waterland 	/* return 'dont continue' */
2461*5c51f124SMoriah Waterland 
2462*5c51f124SMoriah Waterland 	return (B_FALSE);
2463*5c51f124SMoriah Waterland }
2464*5c51f124SMoriah Waterland 
2465*5c51f124SMoriah Waterland /*
2466*5c51f124SMoriah Waterland  * Name:	remove_packages_from_spool_directory
2467*5c51f124SMoriah Waterland  * Description:	Remove packages from a spool directory only.
2468*5c51f124SMoriah Waterland  * Arguments:	a_pkgList - pointer to array of strings, each string specifying
2469*5c51f124SMoriah Waterland  *			the name of one package to be removed.
2470*5c51f124SMoriah Waterland  *		a_nodelete: should the files and scripts remain installed?
2471*5c51f124SMoriah Waterland  *			- if != 0 pass -F flag to pkgremove - suppress
2472*5c51f124SMoriah Waterland  *			the removal of any files and any class action scripts
2473*5c51f124SMoriah Waterland  *			and suppress the running of any class action scripts.
2474*5c51f124SMoriah Waterland  *			The package files remain but the package looks like it
2475*5c51f124SMoriah Waterland  *			is not installed. This is mainly for use by upgrade.
2476*5c51f124SMoriah Waterland  *			- if == 0 do not pass -F flag to pkgremove - all
2477*5c51f124SMoriah Waterland  *			files and class action scripts are removed, and any
2478*5c51f124SMoriah Waterland  *			appropriate class action scripts are run.
2479*5c51f124SMoriah Waterland  *		a_longestPkg - length of the longest package "name" (for
2480*5c51f124SMoriah Waterland  *			output format alignment)
2481*5c51f124SMoriah Waterland  *		a_repeat - are there more packages avialable in "optind"
2482*5c51f124SMoriah Waterland  *			- B_TRUE - process packages from optind
2483*5c51f124SMoriah Waterland  *			- B_FALSE - do not process packages from optind
2484*5c51f124SMoriah Waterland  *		a_altBinDir - pointer to string representing location of the
2485*5c51f124SMoriah Waterland  *			pkgremove executable to run. If not NULL, then pass
2486*5c51f124SMoriah Waterland  *			the path specified to the -b option to pkgremove.
2487*5c51f124SMoriah Waterland  * Returns:	int	(see ckreturn() function for details)
2488*5c51f124SMoriah Waterland  *		0 - success
2489*5c51f124SMoriah Waterland  *		1 - package operation failed (fatal error)
2490*5c51f124SMoriah Waterland  *		2 - non-fatal error (warning)
2491*5c51f124SMoriah Waterland  *		3 - user selected quit (operation interrupted)
2492*5c51f124SMoriah Waterland  *		4 - admin settings prevented operation
2493*5c51f124SMoriah Waterland  *		5 - interaction required and -n (non-interactive) specified
2494*5c51f124SMoriah Waterland  *		"10" will be added to indicate "immediate reboot required"
2495*5c51f124SMoriah Waterland  *		"20" will be added to indicate "reboot after install required"
2496*5c51f124SMoriah Waterland  */
2497*5c51f124SMoriah Waterland 
2498*5c51f124SMoriah Waterland static boolean_t
2499*5c51f124SMoriah Waterland remove_packages_from_spool_directory(char **a_pkgList, int a_nodelete,
2500*5c51f124SMoriah Waterland 	int a_longestPkg, int a_repeat, char *a_altBinDir)
2501*5c51f124SMoriah Waterland {
2502*5c51f124SMoriah Waterland 	int	n;
2503*5c51f124SMoriah Waterland 	int	i;
2504*5c51f124SMoriah Waterland 
2505*5c51f124SMoriah Waterland 	/* entry assertions */
2506*5c51f124SMoriah Waterland 
2507*5c51f124SMoriah Waterland 	assert(a_pkgList != (char **)NULL);
2508*5c51f124SMoriah Waterland 	assert(a_longestPkg > 0);
2509*5c51f124SMoriah Waterland 
2510*5c51f124SMoriah Waterland 	/*
2511*5c51f124SMoriah Waterland 	 * all of the packages (as listed in the package list) are
2512*5c51f124SMoriah Waterland 	 * removed one at a time.
2513*5c51f124SMoriah Waterland 	 */
2514*5c51f124SMoriah Waterland 
2515*5c51f124SMoriah Waterland 	interrupted = 0;
2516*5c51f124SMoriah Waterland 	for (i = 0; (pkginst = a_pkgList[i]) != NULL; i++) {
2517*5c51f124SMoriah Waterland 		started = 0;
2518*5c51f124SMoriah Waterland 
2519*5c51f124SMoriah Waterland 		if (shall_we_continue(pkginst, npkgs) == B_FALSE) {
2520*5c51f124SMoriah Waterland 			continue;
2521*5c51f124SMoriah Waterland 		}
2522*5c51f124SMoriah Waterland 
2523*5c51f124SMoriah Waterland 		interrupted = 0;
2524*5c51f124SMoriah Waterland 
2525*5c51f124SMoriah Waterland 		/*
2526*5c51f124SMoriah Waterland 		 * pkgrm invoked from any type of zone BUT the target
2527*5c51f124SMoriah Waterland 		 * to be removed is a local spool directory: remove the
2528*5c51f124SMoriah Waterland 		 * packages from the spool directory only.
2529*5c51f124SMoriah Waterland 		 */
2530*5c51f124SMoriah Waterland 
2531*5c51f124SMoriah Waterland 		n = doRemove(a_nodelete, a_altBinDir, a_longestPkg,
2532*5c51f124SMoriah Waterland 			admnfile, (char *)NULL, (zoneList_t)NULL);
2533*5c51f124SMoriah Waterland 
2534*5c51f124SMoriah Waterland 		/* set success/fail condition variables */
2535*5c51f124SMoriah Waterland 
2536*5c51f124SMoriah Waterland 		ckreturn(n);
2537*5c51f124SMoriah Waterland 
2538*5c51f124SMoriah Waterland 		npkgs--;
2539*5c51f124SMoriah Waterland 	}
2540*5c51f124SMoriah Waterland 
2541*5c51f124SMoriah Waterland 	/*
2542*5c51f124SMoriah Waterland 	 * all packages in the package list have been removed.
2543*5c51f124SMoriah Waterland 	 * Continue with removal if:
2544*5c51f124SMoriah Waterland 	 * -- immediate reboot is NOT required
2545*5c51f124SMoriah Waterland 	 * -- there are more packages to remove
2546*5c51f124SMoriah Waterland 	 * else return do NOT continue.
2547*5c51f124SMoriah Waterland 	 */
2548*5c51f124SMoriah Waterland 
2549*5c51f124SMoriah Waterland 	if ((ireboot == 0) && (a_repeat != 0)) {
2550*5c51f124SMoriah Waterland 		return (B_TRUE);
2551*5c51f124SMoriah Waterland 	}
2552*5c51f124SMoriah Waterland 
2553*5c51f124SMoriah Waterland 	/* return 'dont continue' */
2554*5c51f124SMoriah Waterland 
2555*5c51f124SMoriah Waterland 	return (B_FALSE);
2556*5c51f124SMoriah Waterland }
2557*5c51f124SMoriah Waterland 
2558*5c51f124SMoriah Waterland /*
2559*5c51f124SMoriah Waterland  * Name:	remove_packages
2560*5c51f124SMoriah Waterland  * Description:	Remove packages from the global zone, and optionally from one
2561*5c51f124SMoriah Waterland  *		or more non-global zones, or from a specified spool directory.
2562*5c51f124SMoriah Waterland  * Arguments:	a_pkgList - pointer to array of strings, each string specifying
2563*5c51f124SMoriah Waterland  *			the name of one package to be removed.
2564*5c51f124SMoriah Waterland  *		a_nodelete: should the files and scripts remain installed?
2565*5c51f124SMoriah Waterland  *			- if != 0 pass -F flag to pkgremove - suppress
2566*5c51f124SMoriah Waterland  *			the removal of any files and any class action scripts
2567*5c51f124SMoriah Waterland  *			and suppress the running of any class action scripts.
2568*5c51f124SMoriah Waterland  *			The package files remain but the package looks like it
2569*5c51f124SMoriah Waterland  *			is not installed. This is mainly for use by upgrade.
2570*5c51f124SMoriah Waterland  *			- if == 0 do not pass -F flag to pkgremove - all
2571*5c51f124SMoriah Waterland  *			files and class action scripts are removed, and any
2572*5c51f124SMoriah Waterland  *			appropriate class action scripts are run.
2573*5c51f124SMoriah Waterland  *		a_longestPkg - length of the longest package "name" (for
2574*5c51f124SMoriah Waterland  *			output format alignment)
2575*5c51f124SMoriah Waterland  *		a_repeat - are there more packages avialable in "optind"
2576*5c51f124SMoriah Waterland  *			- B_TRUE - process packages from optind
2577*5c51f124SMoriah Waterland  *			- B_FALSE - do not process packages from optind
2578*5c51f124SMoriah Waterland  *		a_altBinDir - pointer to string representing location of the
2579*5c51f124SMoriah Waterland  *			pkgremove executable to run. If not NULL, then pass
2580*5c51f124SMoriah Waterland  *			the path specified to the -b option to pkgremove.
2581*5c51f124SMoriah Waterland  *		a_pkgdir - pointer to string representing the directory
2582*5c51f124SMoriah Waterland  *			where the packages to be removed are located.
2583*5c51f124SMoriah Waterland  *		a_spoolDir - pointer to string specifying spool directory
2584*5c51f124SMoriah Waterland  *			to remove packages from. If != NULL then all zones
2585*5c51f124SMoriah Waterland  *			processing is bypassed and the packages are removed
2586*5c51f124SMoriah Waterland  *			from the specified spool directory only.
2587*5c51f124SMoriah Waterland  *		a_noZones - if non-global zones are configured, should the
2588*5c51f124SMoriah Waterland  *			packages be removed from the non-global zones?
2589*5c51f124SMoriah Waterland  *			- B_TRUE - do NOT remove packages from non-global zones
2590*5c51f124SMoriah Waterland  *			- B_FALSE - remove packages from non-global zones
2591*5c51f124SMoriah Waterland  * Returns:	int	(see ckreturn() function for details)
2592*5c51f124SMoriah Waterland  *		0 - success
2593*5c51f124SMoriah Waterland  *		1 - package operation failed (fatal error)
2594*5c51f124SMoriah Waterland  *		2 - non-fatal error (warning)
2595*5c51f124SMoriah Waterland  *		3 - user selected quit (operation interrupted)
2596*5c51f124SMoriah Waterland  *		4 - admin settings prevented operation
2597*5c51f124SMoriah Waterland  *		5 - interaction required and -n (non-interactive) specified
2598*5c51f124SMoriah Waterland  *		"10" will be added to indicate "immediate reboot required"
2599*5c51f124SMoriah Waterland  *		"20" will be added to indicate "reboot after install required"
2600*5c51f124SMoriah Waterland  */
2601*5c51f124SMoriah Waterland 
2602*5c51f124SMoriah Waterland static boolean_t
2603*5c51f124SMoriah Waterland remove_packages(char **a_pkgList, int a_nodelete, int a_longestPkg,
2604*5c51f124SMoriah Waterland 	int a_repeat, char *a_altBinDir, char *a_pkgdir, char *a_spoolDir,
2605*5c51f124SMoriah Waterland 	boolean_t a_noZones)
2606*5c51f124SMoriah Waterland {
2607*5c51f124SMoriah Waterland 	zoneList_t	zlst;
2608*5c51f124SMoriah Waterland 	boolean_t	b;
2609*5c51f124SMoriah Waterland 
2610*5c51f124SMoriah Waterland 	/* entry assertions */
2611*5c51f124SMoriah Waterland 
2612*5c51f124SMoriah Waterland 	assert(a_pkgList != (char **)NULL);
2613*5c51f124SMoriah Waterland 
2614*5c51f124SMoriah Waterland 	echoDebug(DBG_REMOVEPKGS_ENTRY);
2615*5c51f124SMoriah Waterland 	echoDebug(DBG_REMOVEPKGS_ARGS, npkgs, a_nodelete, a_longestPkg,
2616*5c51f124SMoriah Waterland 		a_repeat, PSTR(a_pkgdir), PSTR(a_spoolDir));
2617*5c51f124SMoriah Waterland 
2618*5c51f124SMoriah Waterland 	/*
2619*5c51f124SMoriah Waterland 	 * if removing from spool directory, bypass all zones checks
2620*5c51f124SMoriah Waterland 	 */
2621*5c51f124SMoriah Waterland 
2622*5c51f124SMoriah Waterland 	if (a_spoolDir != (char *)NULL) {
2623*5c51f124SMoriah Waterland 		/* in non-global zone */
2624*5c51f124SMoriah Waterland 
2625*5c51f124SMoriah Waterland 		echoDebug(DBG_REMOVE_PKGS_FROM_SPOOL, a_spoolDir);
2626*5c51f124SMoriah Waterland 
2627*5c51f124SMoriah Waterland 		b = remove_packages_from_spool_directory(a_pkgList, a_nodelete,
2628*5c51f124SMoriah Waterland 			a_longestPkg, a_repeat, a_altBinDir);
2629*5c51f124SMoriah Waterland 
2630*5c51f124SMoriah Waterland 		return (B_FALSE);
2631*5c51f124SMoriah Waterland 	}
2632*5c51f124SMoriah Waterland 
2633*5c51f124SMoriah Waterland 	/* exit if not root */
2634*5c51f124SMoriah Waterland 
2635*5c51f124SMoriah Waterland 	if (getuid()) {
2636*5c51f124SMoriah Waterland 		progerr(ERR_NOT_ROOT, get_prog_name());
2637*5c51f124SMoriah Waterland 		exit(1);
2638*5c51f124SMoriah Waterland 	}
2639*5c51f124SMoriah Waterland 
2640*5c51f124SMoriah Waterland 	/*
2641*5c51f124SMoriah Waterland 	 * if running in the global zone AND one or more non-global
2642*5c51f124SMoriah Waterland 	 * zones exist, add packages in a 'zones aware' manner, else
2643*5c51f124SMoriah Waterland 	 * add packages in the standard 'non-zones aware' manner.
2644*5c51f124SMoriah Waterland 	 */
2645*5c51f124SMoriah Waterland 
2646*5c51f124SMoriah Waterland 	if ((a_noZones == B_FALSE) && (z_running_in_global_zone() == B_FALSE)) {
2647*5c51f124SMoriah Waterland 		/* in non-global zone */
2648*5c51f124SMoriah Waterland 
2649*5c51f124SMoriah Waterland 		echoDebug(DBG_IN_LZ);
2650*5c51f124SMoriah Waterland 
2651*5c51f124SMoriah Waterland 		b = z_lock_this_zone(ZLOCKS_PKG_ADMIN);
2652*5c51f124SMoriah Waterland 		if (b != B_TRUE) {
2653*5c51f124SMoriah Waterland 			progerr(ERR_CANNOT_LOCK_THIS_ZONE);
2654*5c51f124SMoriah Waterland 			/* set fatal error return condition */
2655*5c51f124SMoriah Waterland 			ckreturn(1);
2656*5c51f124SMoriah Waterland 			return (B_FALSE);
2657*5c51f124SMoriah Waterland 		}
2658*5c51f124SMoriah Waterland 
2659*5c51f124SMoriah Waterland 		b = remove_packages_in_nonglobal_zone(a_pkgList, a_nodelete,
2660*5c51f124SMoriah Waterland 			a_longestPkg, a_repeat, a_altBinDir, a_pkgdir);
2661*5c51f124SMoriah Waterland 
2662*5c51f124SMoriah Waterland 		(void) z_unlock_this_zone(ZLOCKS_ALL);
2663*5c51f124SMoriah Waterland 
2664*5c51f124SMoriah Waterland 		return (B_FALSE);
2665*5c51f124SMoriah Waterland 	}
2666*5c51f124SMoriah Waterland 
2667*5c51f124SMoriah Waterland 	/* running in the global zone */
2668*5c51f124SMoriah Waterland 
2669*5c51f124SMoriah Waterland 	b = z_non_global_zones_exist();
2670*5c51f124SMoriah Waterland 	if ((a_noZones == B_FALSE) && (b == B_TRUE)) {
2671*5c51f124SMoriah Waterland 
2672*5c51f124SMoriah Waterland 		echoDebug(DBG_IN_GZ_WITH_LZ);
2673*5c51f124SMoriah Waterland 
2674*5c51f124SMoriah Waterland 		/* get a list of all non-global zones */
2675*5c51f124SMoriah Waterland 		zlst = z_get_nonglobal_zone_list();
2676*5c51f124SMoriah Waterland 		if (zlst == (zoneList_t)NULL) {
2677*5c51f124SMoriah Waterland 			progerr(ERR_CANNOT_GET_ZONE_LIST);
2678*5c51f124SMoriah Waterland 			quit(1);
2679*5c51f124SMoriah Waterland 		}
2680*5c51f124SMoriah Waterland 
2681*5c51f124SMoriah Waterland 		/* need to lock all of the zones */
2682*5c51f124SMoriah Waterland 
2683*5c51f124SMoriah Waterland 		quitSetZonelist(zlst);
2684*5c51f124SMoriah Waterland 		b = z_lock_zones(zlst, ZLOCKS_PKG_ADMIN);
2685*5c51f124SMoriah Waterland 		if (b == B_FALSE) {
2686*5c51f124SMoriah Waterland 			z_free_zone_list(zlst);
2687*5c51f124SMoriah Waterland 			progerr(ERR_CANNOT_LOCK_ZONES);
2688*5c51f124SMoriah Waterland 			/* set fatal error return condition */
2689*5c51f124SMoriah Waterland 			ckreturn(1);
2690*5c51f124SMoriah Waterland 			return (B_FALSE);
2691*5c51f124SMoriah Waterland 		}
2692*5c51f124SMoriah Waterland 
2693*5c51f124SMoriah Waterland 		/* add packages to all zones */
2694*5c51f124SMoriah Waterland 
2695*5c51f124SMoriah Waterland 		b = remove_packages_in_global_with_zones(a_pkgList, a_nodelete,
2696*5c51f124SMoriah Waterland 			a_longestPkg, a_repeat, a_altBinDir, a_pkgdir, zlst);
2697*5c51f124SMoriah Waterland 
2698*5c51f124SMoriah Waterland 		/* unlock all zones */
2699*5c51f124SMoriah Waterland 
2700*5c51f124SMoriah Waterland 		(void) z_unlock_zones(zlst, ZLOCKS_ALL);
2701*5c51f124SMoriah Waterland 		quitSetZonelist((zoneList_t)NULL);
2702*5c51f124SMoriah Waterland 
2703*5c51f124SMoriah Waterland 		/* free list of all non-global zones */
2704*5c51f124SMoriah Waterland 
2705*5c51f124SMoriah Waterland 		z_free_zone_list(zlst);
2706*5c51f124SMoriah Waterland 
2707*5c51f124SMoriah Waterland 		return (B_FALSE);
2708*5c51f124SMoriah Waterland 	}
2709*5c51f124SMoriah Waterland 
2710*5c51f124SMoriah Waterland 	/* in global zone no non-global zones */
2711*5c51f124SMoriah Waterland 
2712*5c51f124SMoriah Waterland 	echoDebug(DBG_IN_GZ_NO_LZ);
2713*5c51f124SMoriah Waterland 
2714*5c51f124SMoriah Waterland 	b = z_lock_this_zone(ZLOCKS_PKG_ADMIN);
2715*5c51f124SMoriah Waterland 	if (b != B_TRUE) {
2716*5c51f124SMoriah Waterland 		progerr(ERR_CANNOT_LOCK_THIS_ZONE);
2717*5c51f124SMoriah Waterland 		/* set fatal error return condition */
2718*5c51f124SMoriah Waterland 		ckreturn(1);
2719*5c51f124SMoriah Waterland 		return (B_FALSE);
2720*5c51f124SMoriah Waterland 	}
2721*5c51f124SMoriah Waterland 
2722*5c51f124SMoriah Waterland 	b = remove_packages_in_global_no_zones(a_pkgList, a_nodelete,
2723*5c51f124SMoriah Waterland 			a_longestPkg, a_repeat, a_altBinDir);
2724*5c51f124SMoriah Waterland 
2725*5c51f124SMoriah Waterland 	(void) z_unlock_this_zone(ZLOCKS_ALL);
2726*5c51f124SMoriah Waterland 
2727*5c51f124SMoriah Waterland 	return (B_FALSE);
2728*5c51f124SMoriah Waterland }
2729*5c51f124SMoriah Waterland 
2730*5c51f124SMoriah Waterland /*
2731*5c51f124SMoriah Waterland  * Name:		path_valid
2732*5c51f124SMoriah Waterland  * Description:	Checks a string for being a valid path
2733*5c51f124SMoriah Waterland  *
2734*5c51f124SMoriah Waterland  * Arguments:	path - path to validate
2735*5c51f124SMoriah Waterland  *
2736*5c51f124SMoriah Waterland  * Returns :	B_TRUE - success, B_FALSE otherwise.
2737*5c51f124SMoriah Waterland  *		B_FALSE means path was null, too long (>PATH_MAX),
2738*5c51f124SMoriah Waterland  *		or too short (<1)
2739*5c51f124SMoriah Waterland  */
2740*5c51f124SMoriah Waterland static boolean_t
2741*5c51f124SMoriah Waterland path_valid(char *path)
2742*5c51f124SMoriah Waterland {
2743*5c51f124SMoriah Waterland 	if (path == NULL) {
2744*5c51f124SMoriah Waterland 		return (B_FALSE);
2745*5c51f124SMoriah Waterland 	} else if (strlen(path) > PATH_MAX) {
2746*5c51f124SMoriah Waterland 		return (B_FALSE);
2747*5c51f124SMoriah Waterland 	} else if (strlen(path) >= 1) {
2748*5c51f124SMoriah Waterland 		return (B_TRUE);
2749*5c51f124SMoriah Waterland 	} else {
2750*5c51f124SMoriah Waterland 		/* path < 1 */
2751*5c51f124SMoriah Waterland 		return (B_FALSE);
2752*5c51f124SMoriah Waterland 	}
2753*5c51f124SMoriah Waterland }
2754*5c51f124SMoriah Waterland 
2755*5c51f124SMoriah Waterland /*
2756*5c51f124SMoriah Waterland  */
2757*5c51f124SMoriah Waterland 
2758*5c51f124SMoriah Waterland static boolean_t
2759*5c51f124SMoriah Waterland check_packages(char **a_pkgList, char *a_packageDir)
2760*5c51f124SMoriah Waterland {
2761*5c51f124SMoriah Waterland 	int	savenpkgs = npkgs;
2762*5c51f124SMoriah Waterland 	int	i;
2763*5c51f124SMoriah Waterland 	CAF_T	flags = 0;
2764*5c51f124SMoriah Waterland 
2765*5c51f124SMoriah Waterland 	/* set flags for applicability check */
2766*5c51f124SMoriah Waterland 
2767*5c51f124SMoriah Waterland 	if (z_running_in_global_zone() == B_TRUE) {
2768*5c51f124SMoriah Waterland 		flags |= CAF_IN_GLOBAL_ZONE;
2769*5c51f124SMoriah Waterland 	}
2770*5c51f124SMoriah Waterland 
2771*5c51f124SMoriah Waterland 	/*
2772*5c51f124SMoriah Waterland 	 * for each package to remove, verify that the package is installed
2773*5c51f124SMoriah Waterland 	 * and is removable.
2774*5c51f124SMoriah Waterland 	 */
2775*5c51f124SMoriah Waterland 
2776*5c51f124SMoriah Waterland 	for (i = 0; (pkginst = a_pkgList[i]) != NULL; i++) {
2777*5c51f124SMoriah Waterland 		/* check package applicability */
2778*5c51f124SMoriah Waterland 		if (check_applicability(a_packageDir, pkginst, get_inst_root(),
2779*5c51f124SMoriah Waterland 			flags) == B_FALSE) {
2780*5c51f124SMoriah Waterland 			progerr(ERR_PKG_NOT_REMOVABLE, pkginst);
2781*5c51f124SMoriah Waterland 			npkgs = savenpkgs;
2782*5c51f124SMoriah Waterland 			return (B_FALSE);
2783*5c51f124SMoriah Waterland 		}
2784*5c51f124SMoriah Waterland 		npkgs--;
2785*5c51f124SMoriah Waterland 	}
2786*5c51f124SMoriah Waterland 
2787*5c51f124SMoriah Waterland 	npkgs = savenpkgs;
2788*5c51f124SMoriah Waterland 	return (B_TRUE);
2789*5c51f124SMoriah Waterland }
2790*5c51f124SMoriah Waterland 
2791*5c51f124SMoriah Waterland /*
2792*5c51f124SMoriah Waterland  * - is this package removable from this zone?
2793*5c51f124SMoriah Waterland  * - does the scope of remove conflict with existing installation
2794*5c51f124SMoriah Waterland  */
2795*5c51f124SMoriah Waterland 
2796*5c51f124SMoriah Waterland static boolean_t
2797*5c51f124SMoriah Waterland check_applicability(char *a_packageDir, char *a_pkgInst,
2798*5c51f124SMoriah Waterland 	char *a_rootPath, CAF_T a_flags)
2799*5c51f124SMoriah Waterland {
2800*5c51f124SMoriah Waterland 	FILE		*pkginfoFP;
2801*5c51f124SMoriah Waterland 	boolean_t	all_zones;	/* pkg is "all zones" only */
2802*5c51f124SMoriah Waterland 	char		pkginfoPath[PATH_MAX];
2803*5c51f124SMoriah Waterland 	char		pkgpath[PATH_MAX];
2804*5c51f124SMoriah Waterland 	int		len;
2805*5c51f124SMoriah Waterland 
2806*5c51f124SMoriah Waterland 	/* entry assertions */
2807*5c51f124SMoriah Waterland 
2808*5c51f124SMoriah Waterland 	assert(a_packageDir != (char *)NULL);
2809*5c51f124SMoriah Waterland 	assert(*a_packageDir != '\0');
2810*5c51f124SMoriah Waterland 	assert(a_pkgInst != (char *)NULL);
2811*5c51f124SMoriah Waterland 	assert(*a_pkgInst != '\0');
2812*5c51f124SMoriah Waterland 
2813*5c51f124SMoriah Waterland 	/* normalize root path */
2814*5c51f124SMoriah Waterland 
2815*5c51f124SMoriah Waterland 	if (a_rootPath == (char *)NULL) {
2816*5c51f124SMoriah Waterland 		a_rootPath = "";
2817*5c51f124SMoriah Waterland 	}
2818*5c51f124SMoriah Waterland 
2819*5c51f124SMoriah Waterland 	/*
2820*5c51f124SMoriah Waterland 	 * determine if this package is currently installed
2821*5c51f124SMoriah Waterland 	 * if not installed return success - operation will fail
2822*5c51f124SMoriah Waterland 	 * when the removal is attempted
2823*5c51f124SMoriah Waterland 	 */
2824*5c51f124SMoriah Waterland 
2825*5c51f124SMoriah Waterland 	if (pkginfoIsPkgInstalled((struct pkginfo **)NULL, a_pkgInst) !=
2826*5c51f124SMoriah Waterland 		B_TRUE) {
2827*5c51f124SMoriah Waterland 		return (B_TRUE);
2828*5c51f124SMoriah Waterland 	}
2829*5c51f124SMoriah Waterland 
2830*5c51f124SMoriah Waterland 	/*
2831*5c51f124SMoriah Waterland 	 * calculate paths to various objects
2832*5c51f124SMoriah Waterland 	 */
2833*5c51f124SMoriah Waterland 
2834*5c51f124SMoriah Waterland 	len = snprintf(pkgpath, sizeof (pkgpath), "%s/%s", a_packageDir,
2835*5c51f124SMoriah Waterland 			a_pkgInst);
2836*5c51f124SMoriah Waterland 	if (len > sizeof (pkgpath)) {
2837*5c51f124SMoriah Waterland 		progerr(ERR_CREATE_PATH_2, a_packageDir, a_pkgInst);
2838*5c51f124SMoriah Waterland 		return (B_FALSE);
2839*5c51f124SMoriah Waterland 	}
2840*5c51f124SMoriah Waterland 
2841*5c51f124SMoriah Waterland 	/* if not installed then just return */
2842*5c51f124SMoriah Waterland 
2843*5c51f124SMoriah Waterland 	if (isdir(pkgpath) != 0) {
2844*5c51f124SMoriah Waterland 		progerr(ERR_NO_PKGDIR, pkgpath, a_pkgInst, strerror(errno));
2845*5c51f124SMoriah Waterland 		return (B_TRUE);
2846*5c51f124SMoriah Waterland 	}
2847*5c51f124SMoriah Waterland 
2848*5c51f124SMoriah Waterland 	len = snprintf(pkginfoPath, sizeof (pkginfoPath),
2849*5c51f124SMoriah Waterland 			"%s/pkginfo", pkgpath);
2850*5c51f124SMoriah Waterland 	if (len > sizeof (pkgpath)) {
2851*5c51f124SMoriah Waterland 		progerr(ERR_CREATE_PATH_2, pkgpath, "pkginfo");
2852*5c51f124SMoriah Waterland 		return (B_FALSE);
2853*5c51f124SMoriah Waterland 	}
2854*5c51f124SMoriah Waterland 
2855*5c51f124SMoriah Waterland 	/*
2856*5c51f124SMoriah Waterland 	 * gather information from this packages pkginfo file
2857*5c51f124SMoriah Waterland 	 */
2858*5c51f124SMoriah Waterland 
2859*5c51f124SMoriah Waterland 	pkginfoFP = fopen(pkginfoPath, "r");
2860*5c51f124SMoriah Waterland 
2861*5c51f124SMoriah Waterland 	if (pkginfoFP == (FILE *)NULL) {
2862*5c51f124SMoriah Waterland 		progerr(ERR_NO_PKG_INFOFILE, a_pkgInst, pkginfoPath,
2863*5c51f124SMoriah Waterland 							strerror(errno));
2864*5c51f124SMoriah Waterland 		return (B_FALSE);
2865*5c51f124SMoriah Waterland 	}
2866*5c51f124SMoriah Waterland 
2867*5c51f124SMoriah Waterland 	/* determine "ALLZONES" setting for this package */
2868*5c51f124SMoriah Waterland 
2869*5c51f124SMoriah Waterland 	all_zones = pkginfoParamTruth(pkginfoFP, PKG_ALLZONES_VARIABLE,
2870*5c51f124SMoriah Waterland 			"true", B_FALSE);
2871*5c51f124SMoriah Waterland 
2872*5c51f124SMoriah Waterland 	/* close pkginfo file */
2873*5c51f124SMoriah Waterland 
2874*5c51f124SMoriah Waterland 	(void) fclose(pkginfoFP);
2875*5c51f124SMoriah Waterland 
2876*5c51f124SMoriah Waterland 	/* gather information from the global zone only file */
2877*5c51f124SMoriah Waterland 
2878*5c51f124SMoriah Waterland 	/*
2879*5c51f124SMoriah Waterland 	 * verify package applicability based on information gathered;
2880*5c51f124SMoriah Waterland 	 * the package IS currently installed....
2881*5c51f124SMoriah Waterland 	 */
2882*5c51f124SMoriah Waterland 
2883*5c51f124SMoriah Waterland 	/* pkg ALLZONES=true & not running in global zone */
2884*5c51f124SMoriah Waterland 
2885*5c51f124SMoriah Waterland 	if ((all_zones == B_TRUE) && (!(a_flags & CAF_IN_GLOBAL_ZONE))) {
2886*5c51f124SMoriah Waterland 		progerr(ERR_ALLZONES_AND_IN_LZ_PKGRM, a_pkgInst);
2887*5c51f124SMoriah Waterland 		return (B_FALSE);
2888*5c51f124SMoriah Waterland 	}
2889*5c51f124SMoriah Waterland 
2890*5c51f124SMoriah Waterland 	return (B_TRUE);
2891*5c51f124SMoriah Waterland }
2892*5c51f124SMoriah Waterland 
2893*5c51f124SMoriah Waterland /*
2894*5c51f124SMoriah Waterland  * Name:	shall_we_continue
2895*5c51f124SMoriah Waterland  * Description: Called from within a loop that is installing packages,
2896*5c51f124SMoriah Waterland  *		this function examines various global variables and decides
2897*5c51f124SMoriah Waterland  *		whether or not to ask an appropriate question, and wait for
2898*5c51f124SMoriah Waterland  *		and appropriate reply.
2899*5c51f124SMoriah Waterland  * Arguments:	<<global variables>>
2900*5c51f124SMoriah Waterland  * Returns:	B_TRUE - continue processing with next package
2901*5c51f124SMoriah Waterland  *		B_FALSE - do not continue processing with next package
2902*5c51f124SMoriah Waterland  */
2903*5c51f124SMoriah Waterland 
2904*5c51f124SMoriah Waterland static boolean_t
2905*5c51f124SMoriah Waterland shall_we_continue(char *a_pkgInst, int a_npkgs)
2906*5c51f124SMoriah Waterland {
2907*5c51f124SMoriah Waterland 	char	ans[MAX_INPUT];
2908*5c51f124SMoriah Waterland 	int	n;
2909*5c51f124SMoriah Waterland 
2910*5c51f124SMoriah Waterland 	/* return FALSE if immediate reboot required */
2911*5c51f124SMoriah Waterland 
2912*5c51f124SMoriah Waterland 	if (ireboot) {
2913*5c51f124SMoriah Waterland 		ptext(stderr, MSG_SUSPEND_RM, a_pkgInst);
2914*5c51f124SMoriah Waterland 		return (B_FALSE);
2915*5c51f124SMoriah Waterland 	}
2916*5c51f124SMoriah Waterland 
2917*5c51f124SMoriah Waterland 	/* return TRUE if not interrupted */
2918*5c51f124SMoriah Waterland 
2919*5c51f124SMoriah Waterland 	if (!interrupted) {
2920*5c51f124SMoriah Waterland 		return (B_TRUE);
2921*5c51f124SMoriah Waterland 	}
2922*5c51f124SMoriah Waterland 
2923*5c51f124SMoriah Waterland 	/* output appropriate interrupt message */
2924*5c51f124SMoriah Waterland 
2925*5c51f124SMoriah Waterland 	echo(a_npkgs == 1 ? MSG_1MORETODO : MSG_MORETODO, a_npkgs);
2926*5c51f124SMoriah Waterland 
2927*5c51f124SMoriah Waterland 	/* if running with no interaction (-n) do not ask question */
2928*5c51f124SMoriah Waterland 
2929*5c51f124SMoriah Waterland 	if (nointeract) {
2930*5c51f124SMoriah Waterland 		quit(0);
2931*5c51f124SMoriah Waterland 		/* NOTREACHED */
2932*5c51f124SMoriah Waterland 	}
2933*5c51f124SMoriah Waterland 
2934*5c51f124SMoriah Waterland 	/* interaction possible: ask question */
2935*5c51f124SMoriah Waterland 
2936*5c51f124SMoriah Waterland 	n = ckyorn(ans, NULL, NULL, NULL, ASK_CONTINUE_RM);
2937*5c51f124SMoriah Waterland 	if (n != 0) {
2938*5c51f124SMoriah Waterland 		quit(n);
2939*5c51f124SMoriah Waterland 		/* NOTREACHED */
2940*5c51f124SMoriah Waterland 	}
2941*5c51f124SMoriah Waterland 
2942*5c51f124SMoriah Waterland 	if (strchr("yY", *ans) == NULL) {
2943*5c51f124SMoriah Waterland 		quit(0);
2944*5c51f124SMoriah Waterland 		/* NOTREACHED */
2945*5c51f124SMoriah Waterland 	}
2946*5c51f124SMoriah Waterland 	return (B_TRUE);
2947*5c51f124SMoriah Waterland }
2948*5c51f124SMoriah Waterland 
2949*5c51f124SMoriah Waterland /*
2950*5c51f124SMoriah Waterland  * Name:	create_zone_adminfile
2951*5c51f124SMoriah Waterland  * Description: Given a zone temporary directory and optionally an existing
2952*5c51f124SMoriah Waterland  *		administration file, generate an administration file that
2953*5c51f124SMoriah Waterland  *		can be used to perform "non-interactive" operations in a
2954*5c51f124SMoriah Waterland  *		non-global zone.
2955*5c51f124SMoriah Waterland  * Arguments:	r_zoneAdminFile - pointer to handle that will contain a
2956*5c51f124SMoriah Waterland  *			string representing the path to the temporary
2957*5c51f124SMoriah Waterland  *			administration file created - this must be NULL
2958*5c51f124SMoriah Waterland  *			before the first call to this function - on
2959*5c51f124SMoriah Waterland  *			subsequent calls if the pointer is NOT null then
2960*5c51f124SMoriah Waterland  *			the existing string will NOT be overwritten.
2961*5c51f124SMoriah Waterland  *		a_zoneTempDir - pointer to string representing the path
2962*5c51f124SMoriah Waterland  *			to the zone temporary directory to create the
2963*5c51f124SMoriah Waterland  *			temporary administration file in
2964*5c51f124SMoriah Waterland  *		a_admnfile - pointer to string representing the path to
2965*5c51f124SMoriah Waterland  *			an existing "user" administration file - the
2966*5c51f124SMoriah Waterland  *			administration file created will contain the
2967*5c51f124SMoriah Waterland  *			settings contained in this file, modified as
2968*5c51f124SMoriah Waterland  *			appropriate to supress any interaction;
2969*5c51f124SMoriah Waterland  *			If this is == NULL then the administration file
2970*5c51f124SMoriah Waterland  *			created will not contain any extra settings
2971*5c51f124SMoriah Waterland  * Returns:	void
2972*5c51f124SMoriah Waterland  * NOTE:	Any string returned is placed in new storage for the
2973*5c51f124SMoriah Waterland  *		calling method. The caller must use 'free' to dispose
2974*5c51f124SMoriah Waterland  *		of the storage once the string is no longer needed.
2975*5c51f124SMoriah Waterland  * NOTE:	On any error this function will call 'quit(1)'
2976*5c51f124SMoriah Waterland  */
2977*5c51f124SMoriah Waterland 
2978*5c51f124SMoriah Waterland static void
2979*5c51f124SMoriah Waterland create_zone_adminfile(char **r_zoneAdminFile, char *a_zoneTempDir,
2980*5c51f124SMoriah Waterland 	char *a_admnfile)
2981*5c51f124SMoriah Waterland {
2982*5c51f124SMoriah Waterland 	boolean_t	b;
2983*5c51f124SMoriah Waterland 
2984*5c51f124SMoriah Waterland 	/* entry assertions */
2985*5c51f124SMoriah Waterland 
2986*5c51f124SMoriah Waterland 	assert(r_zoneAdminFile != (char **)NULL);
2987*5c51f124SMoriah Waterland 	assert(a_zoneTempDir != (char *)NULL);
2988*5c51f124SMoriah Waterland 	assert(*a_zoneTempDir != '\0');
2989*5c51f124SMoriah Waterland 
2990*5c51f124SMoriah Waterland 	/* entry debugging info */
2991*5c51f124SMoriah Waterland 
2992*5c51f124SMoriah Waterland 	echoDebug(DBG_CREATE_ZONE_ADMINFILE, a_zoneTempDir, PSTR(a_admnfile));
2993*5c51f124SMoriah Waterland 
2994*5c51f124SMoriah Waterland 	/* if temporary name already exists, do not overwrite */
2995*5c51f124SMoriah Waterland 
2996*5c51f124SMoriah Waterland 	if (*r_zoneAdminFile != (char *)NULL) {
2997*5c51f124SMoriah Waterland 		return;
2998*5c51f124SMoriah Waterland 	}
2999*5c51f124SMoriah Waterland 
3000*5c51f124SMoriah Waterland 	/* create temporary name */
3001*5c51f124SMoriah Waterland 
3002*5c51f124SMoriah Waterland 	*r_zoneAdminFile = tempnam(a_zoneTempDir, "zadmn");
3003*5c51f124SMoriah Waterland 	b = z_create_zone_admin_file(*r_zoneAdminFile, a_admnfile);
3004*5c51f124SMoriah Waterland 	if (b == B_FALSE) {
3005*5c51f124SMoriah Waterland 		progerr(ERR_CREATE_TMPADMIN, *r_zoneAdminFile,
3006*5c51f124SMoriah Waterland 			strerror(errno));
3007*5c51f124SMoriah Waterland 		quit(1);
3008*5c51f124SMoriah Waterland 		/* NOTREACHED */
3009*5c51f124SMoriah Waterland 	}
3010*5c51f124SMoriah Waterland 
3011*5c51f124SMoriah Waterland 	echoDebug(DBG_CREATED_ZONE_ADMINFILE, *r_zoneAdminFile);
3012*5c51f124SMoriah Waterland }
3013*5c51f124SMoriah Waterland 
3014*5c51f124SMoriah Waterland /*
3015*5c51f124SMoriah Waterland  * Name:	create_zone_tempdir
3016*5c51f124SMoriah Waterland  * Description: Given a system temporary directory, create a "zone" specific
3017*5c51f124SMoriah Waterland  *		temporary directory and return the path to the directory
3018*5c51f124SMoriah Waterland  *		created.
3019*5c51f124SMoriah Waterland  * Arguments:	r_zoneTempDir - pointer to handle that will contain a
3020*5c51f124SMoriah Waterland  *			string representing the path to the temporary
3021*5c51f124SMoriah Waterland  *			directory created - this must be NULL before the
3022*5c51f124SMoriah Waterland  *			first call to this function - on subsequent calls
3023*5c51f124SMoriah Waterland  *			if the pointer is NOT null then the existing string
3024*5c51f124SMoriah Waterland  *			will NOT be overwritten.
3025*5c51f124SMoriah Waterland  *		a_zoneTempDir - pointer to string representing the path
3026*5c51f124SMoriah Waterland  *			to the system temporary directory to create the
3027*5c51f124SMoriah Waterland  *			temporary zone directory in
3028*5c51f124SMoriah Waterland  * Returns:	void
3029*5c51f124SMoriah Waterland  * NOTE:	Any string returned is placed in new storage for the
3030*5c51f124SMoriah Waterland  *		calling method. The caller must use 'free' to dispose
3031*5c51f124SMoriah Waterland  *		of the storage once the string is no longer needed.
3032*5c51f124SMoriah Waterland  * NOTE:	On any error this function will call 'quit(1)'
3033*5c51f124SMoriah Waterland  * NOTE:	This function calls "quitSetZoneTmpdir" on success to
3034*5c51f124SMoriah Waterland  *		register the directory created with quit() so that the
3035*5c51f124SMoriah Waterland  *		directory will be automatically deleted on exit.
3036*5c51f124SMoriah Waterland  */
3037*5c51f124SMoriah Waterland 
3038*5c51f124SMoriah Waterland static void
3039*5c51f124SMoriah Waterland create_zone_tempdir(char **r_zoneTempDir, char *a_tmpdir)
3040*5c51f124SMoriah Waterland {
3041*5c51f124SMoriah Waterland 	boolean_t	b;
3042*5c51f124SMoriah Waterland 
3043*5c51f124SMoriah Waterland 	/* entry assertions */
3044*5c51f124SMoriah Waterland 
3045*5c51f124SMoriah Waterland 	assert(r_zoneTempDir != (char **)NULL);
3046*5c51f124SMoriah Waterland 	assert(a_tmpdir != (char *)NULL);
3047*5c51f124SMoriah Waterland 	assert(*a_tmpdir != '\0');
3048*5c51f124SMoriah Waterland 
3049*5c51f124SMoriah Waterland 	/* entry debugging info */
3050*5c51f124SMoriah Waterland 
3051*5c51f124SMoriah Waterland 	echoDebug(DBG_CREATE_ZONE_TEMPDIR, a_tmpdir);
3052*5c51f124SMoriah Waterland 
3053*5c51f124SMoriah Waterland 	/* if temporary directory already exists, do not overwrite */
3054*5c51f124SMoriah Waterland 
3055*5c51f124SMoriah Waterland 	if (*r_zoneTempDir != (char *)NULL) {
3056*5c51f124SMoriah Waterland 		return;
3057*5c51f124SMoriah Waterland 	}
3058*5c51f124SMoriah Waterland 
3059*5c51f124SMoriah Waterland 	/* create temporary directory */
3060*5c51f124SMoriah Waterland 
3061*5c51f124SMoriah Waterland 	b = setup_temporary_directory(r_zoneTempDir, a_tmpdir, "ztemp");
3062*5c51f124SMoriah Waterland 	if (b == B_FALSE) {
3063*5c51f124SMoriah Waterland 		progerr(ERR_ZONETEMPDIR, a_tmpdir, strerror(errno));
3064*5c51f124SMoriah Waterland 		quit(1);
3065*5c51f124SMoriah Waterland 		/* NOTREACHED */
3066*5c51f124SMoriah Waterland 	}
3067*5c51f124SMoriah Waterland 
3068*5c51f124SMoriah Waterland 	/* register with quit() to directory is removed on exit */
3069*5c51f124SMoriah Waterland 
3070*5c51f124SMoriah Waterland 	quitSetZoneTmpdir(*r_zoneTempDir);
3071*5c51f124SMoriah Waterland 
3072*5c51f124SMoriah Waterland 	/* exit debugging info */
3073*5c51f124SMoriah Waterland 
3074*5c51f124SMoriah Waterland 	echoDebug(DBG_CREATED_ZONE_TEMPDIR, *r_zoneTempDir);
3075*5c51f124SMoriah Waterland }
3076