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