xref: /onnv-gate/usr/src/cmd/svr4pkg/pkgadd/main.c (revision 9781:ccf49524d5dc)
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  * Program:	pkgadd / pkgask
33*9781SMoriah.Waterland@Sun.COM  *
34*9781SMoriah.Waterland@Sun.COM  * Function:	public command and private utility functions that
35*9781SMoriah.Waterland@Sun.COM  *		implement the package add and package ask operations.
36*9781SMoriah.Waterland@Sun.COM  *
37*9781SMoriah.Waterland@Sun.COM  */
38*9781SMoriah.Waterland@Sun.COM 
39*9781SMoriah.Waterland@Sun.COM /*
40*9781SMoriah.Waterland@Sun.COM  * System includes
41*9781SMoriah.Waterland@Sun.COM  */
42*9781SMoriah.Waterland@Sun.COM 
43*9781SMoriah.Waterland@Sun.COM #include <stdio.h>
44*9781SMoriah.Waterland@Sun.COM #include <limits.h>
45*9781SMoriah.Waterland@Sun.COM #include <stdlib.h>
46*9781SMoriah.Waterland@Sun.COM #include <unistd.h>
47*9781SMoriah.Waterland@Sun.COM #include <string.h>
48*9781SMoriah.Waterland@Sun.COM #include <fcntl.h>
49*9781SMoriah.Waterland@Sun.COM #include <sys/types.h>
50*9781SMoriah.Waterland@Sun.COM #include <sys/stat.h>
51*9781SMoriah.Waterland@Sun.COM #include <signal.h>
52*9781SMoriah.Waterland@Sun.COM #include <errno.h>
53*9781SMoriah.Waterland@Sun.COM #include <pkgdev.h>
54*9781SMoriah.Waterland@Sun.COM #include <pkginfo.h>
55*9781SMoriah.Waterland@Sun.COM #include <pkglocs.h>
56*9781SMoriah.Waterland@Sun.COM #include <locale.h>
57*9781SMoriah.Waterland@Sun.COM #include <libintl.h>
58*9781SMoriah.Waterland@Sun.COM #include <pkgtrans.h>
59*9781SMoriah.Waterland@Sun.COM #include <boot_http.h>
60*9781SMoriah.Waterland@Sun.COM #include <assert.h>
61*9781SMoriah.Waterland@Sun.COM 
62*9781SMoriah.Waterland@Sun.COM /*
63*9781SMoriah.Waterland@Sun.COM  * consolidation pkg command library includes
64*9781SMoriah.Waterland@Sun.COM  */
65*9781SMoriah.Waterland@Sun.COM #include <pkglib.h>
66*9781SMoriah.Waterland@Sun.COM #include <pkgerr.h>
67*9781SMoriah.Waterland@Sun.COM #include <pkgweb.h>
68*9781SMoriah.Waterland@Sun.COM 
69*9781SMoriah.Waterland@Sun.COM #include <instzones_api.h>
70*9781SMoriah.Waterland@Sun.COM 
71*9781SMoriah.Waterland@Sun.COM /*
72*9781SMoriah.Waterland@Sun.COM  * local pkg command library includes
73*9781SMoriah.Waterland@Sun.COM  */
74*9781SMoriah.Waterland@Sun.COM #include <install.h>
75*9781SMoriah.Waterland@Sun.COM #include <libinst.h>
76*9781SMoriah.Waterland@Sun.COM #include <libadm.h>
77*9781SMoriah.Waterland@Sun.COM #include <messages.h>
78*9781SMoriah.Waterland@Sun.COM 
79*9781SMoriah.Waterland@Sun.COM 
80*9781SMoriah.Waterland@Sun.COM /*
81*9781SMoriah.Waterland@Sun.COM  * pkgadd local includes
82*9781SMoriah.Waterland@Sun.COM  */
83*9781SMoriah.Waterland@Sun.COM 
84*9781SMoriah.Waterland@Sun.COM #include "quit.h"
85*9781SMoriah.Waterland@Sun.COM 
86*9781SMoriah.Waterland@Sun.COM /*
87*9781SMoriah.Waterland@Sun.COM  * imported global variables/functions
88*9781SMoriah.Waterland@Sun.COM  */
89*9781SMoriah.Waterland@Sun.COM 
90*9781SMoriah.Waterland@Sun.COM /* presvr4.c */
91*9781SMoriah.Waterland@Sun.COM extern int	presvr4(char **ppkg, int a_nointeract);
92*9781SMoriah.Waterland@Sun.COM 
93*9781SMoriah.Waterland@Sun.COM /* check.c */
94*9781SMoriah.Waterland@Sun.COM extern int	preinstall_verify(char **a_pkgList, zoneList_t a_zlst,
95*9781SMoriah.Waterland@Sun.COM 			char *a_zoneTempDir);
96*9781SMoriah.Waterland@Sun.COM 
97*9781SMoriah.Waterland@Sun.COM /*
98*9781SMoriah.Waterland@Sun.COM  * ckquit is a global that controls 'ckyorn' (defined in libadm)
99*9781SMoriah.Waterland@Sun.COM  * If ckquit is non-zero, then "quit" is allowed as an answer when
100*9781SMoriah.Waterland@Sun.COM  * ckyorn is called. If is it zero, then "quit" is not an allowed answer.
101*9781SMoriah.Waterland@Sun.COM  */
102*9781SMoriah.Waterland@Sun.COM extern int	ckquit;
103*9781SMoriah.Waterland@Sun.COM 
104*9781SMoriah.Waterland@Sun.COM /*
105*9781SMoriah.Waterland@Sun.COM  * exported global variables
106*9781SMoriah.Waterland@Sun.COM  */
107*9781SMoriah.Waterland@Sun.COM 
108*9781SMoriah.Waterland@Sun.COM /* these globals are set by ckreturn and used by quit.c */
109*9781SMoriah.Waterland@Sun.COM 
110*9781SMoriah.Waterland@Sun.COM int	admnflag = 0;	/* != 0 if any pkg op admin setting failure (4) */
111*9781SMoriah.Waterland@Sun.COM int	doreboot = 0;	/* != 0 if reboot required after installation */
112*9781SMoriah.Waterland@Sun.COM int	failflag = 0;	/* != 0 if fatal error has occurred (1) */
113*9781SMoriah.Waterland@Sun.COM int	intrflag = 0;	/* != 0 if user selected quit (3) */
114*9781SMoriah.Waterland@Sun.COM int	ireboot = 0;	/* != 0 if immediate reboot required */
115*9781SMoriah.Waterland@Sun.COM int	nullflag = 0;	/* != 0 if admin interaction required (5) */
116*9781SMoriah.Waterland@Sun.COM int	warnflag = 0;	/* != 0 if non-fatal error has occurred (2) */
117*9781SMoriah.Waterland@Sun.COM 
118*9781SMoriah.Waterland@Sun.COM /* imported by quit.c */
119*9781SMoriah.Waterland@Sun.COM int	npkgs = 0;	/* the number of packages yet to be installed */
120*9781SMoriah.Waterland@Sun.COM 
121*9781SMoriah.Waterland@Sun.COM /* imported by various (many) */
122*9781SMoriah.Waterland@Sun.COM char	*respfile = NULL;	/* response pathname (or NULL) */
123*9781SMoriah.Waterland@Sun.COM char	*tmpdir = NULL;		/* location to place temporary files */
124*9781SMoriah.Waterland@Sun.COM 
125*9781SMoriah.Waterland@Sun.COM struct admin	adm;		/* holds info about installation admin */
126*9781SMoriah.Waterland@Sun.COM struct pkgdev	pkgdev;		/* holds info about the installation device */
127*9781SMoriah.Waterland@Sun.COM 
128*9781SMoriah.Waterland@Sun.COM /*
129*9781SMoriah.Waterland@Sun.COM  * internal global variables
130*9781SMoriah.Waterland@Sun.COM  */
131*9781SMoriah.Waterland@Sun.COM 
132*9781SMoriah.Waterland@Sun.COM static char	*admnfile = NULL;	/* file to use for installation admin */
133*9781SMoriah.Waterland@Sun.COM static char	*ids_name = NULL;	/* name of data stream device */
134*9781SMoriah.Waterland@Sun.COM static char	*pkgcontsrc = NULL;	/* continuation file (-c option) */
135*9781SMoriah.Waterland@Sun.COM static char	*pkgdrtarg = NULL;	/* dry run file (-D option) */
136*9781SMoriah.Waterland@Sun.COM static char	*pkginst = NULL;	/* current pkg/src instance 2 process */
137*9781SMoriah.Waterland@Sun.COM static char	*respdir = NULL;	/* respfile is a directory spec */
138*9781SMoriah.Waterland@Sun.COM static char	*rw_block_size = NULL;
139*9781SMoriah.Waterland@Sun.COM static char	*vfstab_file = NULL;
140*9781SMoriah.Waterland@Sun.COM static int	askflag = 0;		/* non-zero if invoked as "pkgask" */
141*9781SMoriah.Waterland@Sun.COM static int	disableAttributes = 0;	/* Disabling attribute checking */
142*9781SMoriah.Waterland@Sun.COM static int	disableChecksum = 0;	/* Disable checksumming */
143*9781SMoriah.Waterland@Sun.COM static int	disableSaveSpool = 0;	/* Disable partial spool dir create */
144*9781SMoriah.Waterland@Sun.COM static int	init_install = 0;	/* inform scripts initial install */
145*9781SMoriah.Waterland@Sun.COM static int	no_map_client = 0;	/* do not map from vfstab file */
146*9781SMoriah.Waterland@Sun.COM static int	nointeract = 0;		/* non-zero - no user interaction */
147*9781SMoriah.Waterland@Sun.COM static int	pkgverbose = 0;		/* non-zero if verbose mode selected */
148*9781SMoriah.Waterland@Sun.COM static int	saveSpoolInstall = 0;	/* installing from save spool dir */
149*9781SMoriah.Waterland@Sun.COM static int	suppressCopyright = 0;	/* suppress copyright notices */
150*9781SMoriah.Waterland@Sun.COM 
151*9781SMoriah.Waterland@Sun.COM /* set by ckreturn() */
152*9781SMoriah.Waterland@Sun.COM 
153*9781SMoriah.Waterland@Sun.COM static int	interrupted = 0;	/* last pkg op was quit (1,2,3,4,5) */
154*9781SMoriah.Waterland@Sun.COM static int	needconsult = 0;	/* essential ask admin now (1,2,3,5) */
155*9781SMoriah.Waterland@Sun.COM 
156*9781SMoriah.Waterland@Sun.COM /* Set by -O nozones: do not process any zones */
157*9781SMoriah.Waterland@Sun.COM 
158*9781SMoriah.Waterland@Sun.COM static boolean_t	noZones = B_FALSE;
159*9781SMoriah.Waterland@Sun.COM 
160*9781SMoriah.Waterland@Sun.COM /* Set by -O zonelist=<names...>: process only named zones */
161*9781SMoriah.Waterland@Sun.COM 
162*9781SMoriah.Waterland@Sun.COM static boolean_t	usedZoneList = B_FALSE;
163*9781SMoriah.Waterland@Sun.COM 
164*9781SMoriah.Waterland@Sun.COM /* Set by -O debug: debug output is enabled? */
165*9781SMoriah.Waterland@Sun.COM 
166*9781SMoriah.Waterland@Sun.COM static boolean_t	debugFlag = B_FALSE;
167*9781SMoriah.Waterland@Sun.COM 
168*9781SMoriah.Waterland@Sun.COM /* Set by the -G option: install packages in global zone only */
169*9781SMoriah.Waterland@Sun.COM 
170*9781SMoriah.Waterland@Sun.COM static boolean_t	globalZoneOnly = B_FALSE;
171*9781SMoriah.Waterland@Sun.COM 
172*9781SMoriah.Waterland@Sun.COM /* Set by -O patchPkgRemoval */
173*9781SMoriah.Waterland@Sun.COM 
174*9781SMoriah.Waterland@Sun.COM static boolean_t	patchPkgRemoval = B_FALSE;
175*9781SMoriah.Waterland@Sun.COM 
176*9781SMoriah.Waterland@Sun.COM /*
177*9781SMoriah.Waterland@Sun.COM  * Assume the package is ABI and POSIX compliant as regards user
178*9781SMoriah.Waterland@Sun.COM  * interactiion during procedure scripts.
179*9781SMoriah.Waterland@Sun.COM  */
180*9781SMoriah.Waterland@Sun.COM 
181*9781SMoriah.Waterland@Sun.COM static int	old_pkg = 0;
182*9781SMoriah.Waterland@Sun.COM 
183*9781SMoriah.Waterland@Sun.COM /* Assume pkg should be installed according to the ABI */
184*9781SMoriah.Waterland@Sun.COM 
185*9781SMoriah.Waterland@Sun.COM static int	old_symlinks = 0;
186*9781SMoriah.Waterland@Sun.COM 
187*9781SMoriah.Waterland@Sun.COM /*
188*9781SMoriah.Waterland@Sun.COM  * Default name length will be 32 chars - if this is set,
189*9781SMoriah.Waterland@Sun.COM  * disable the 32 char name limit extension
190*9781SMoriah.Waterland@Sun.COM  */
191*9781SMoriah.Waterland@Sun.COM 
192*9781SMoriah.Waterland@Sun.COM static int	ABI_namelength = 0;
193*9781SMoriah.Waterland@Sun.COM 
194*9781SMoriah.Waterland@Sun.COM #if	!defined(TEXT_DOMAIN)	/* Should be defined by cc -D */
195*9781SMoriah.Waterland@Sun.COM #define	TEXT_DOMAIN	"SYS_TEST"
196*9781SMoriah.Waterland@Sun.COM #endif
197*9781SMoriah.Waterland@Sun.COM 
198*9781SMoriah.Waterland@Sun.COM /* printable string - if string is null results in ??? */
199*9781SMoriah.Waterland@Sun.COM 
200*9781SMoriah.Waterland@Sun.COM #define	PSTR(STR) (((STR) == (char *)NULL) ? "???" : (STR))
201*9781SMoriah.Waterland@Sun.COM 
202*9781SMoriah.Waterland@Sun.COM #define	MAX_FDS	20
203*9781SMoriah.Waterland@Sun.COM 
204*9781SMoriah.Waterland@Sun.COM #define	INHERITFS	"inherited-filesystem="
205*9781SMoriah.Waterland@Sun.COM #define	INHERITFS_LEN	((sizeof (INHERITFS))-1)
206*9781SMoriah.Waterland@Sun.COM 
207*9781SMoriah.Waterland@Sun.COM /*
208*9781SMoriah.Waterland@Sun.COM  * forward declarations
209*9781SMoriah.Waterland@Sun.COM  */
210*9781SMoriah.Waterland@Sun.COM 
211*9781SMoriah.Waterland@Sun.COM static int		boot_and_pkginstall_check_in_zones(zoneList_t a_zlst,
212*9781SMoriah.Waterland@Sun.COM 				char *a_idsName, char *a_altBinDir,
213*9781SMoriah.Waterland@Sun.COM 				char *a_zoneAdminFile, char *a_zoneTempDir);
214*9781SMoriah.Waterland@Sun.COM static int		boot_and_install_in_zones(zoneList_t a_zlst,
215*9781SMoriah.Waterland@Sun.COM 				char *a_idsName, char *a_altBinDir,
216*9781SMoriah.Waterland@Sun.COM 				char *a_zoneAdminFile, char *a_zoneTempDir);
217*9781SMoriah.Waterland@Sun.COM static void		pkginstall_check_in_one_zone(char **a_inheritedPkgDirs,
218*9781SMoriah.Waterland@Sun.COM 				char *a_zoneName, char *a_idsName,
219*9781SMoriah.Waterland@Sun.COM 				char *a_zoneAdminFile, char *a_zoneTempDir,
220*9781SMoriah.Waterland@Sun.COM 				char *a_altBinDir, char *a_scratchName,
221*9781SMoriah.Waterland@Sun.COM 				zone_state_t a_zoneState);
222*9781SMoriah.Waterland@Sun.COM static void		ckreturn(int retcode);
223*9781SMoriah.Waterland@Sun.COM static void		create_zone_adminfile(char **r_zoneAdminFile,
224*9781SMoriah.Waterland@Sun.COM 				char *a_zoneTempDir, char *a_admnfile);
225*9781SMoriah.Waterland@Sun.COM static void		create_zone_tempdir(char **r_zoneTempDir,
226*9781SMoriah.Waterland@Sun.COM 				char *a_tmpdir);
227*9781SMoriah.Waterland@Sun.COM static void		install_in_one_zone(char **a_inheritedPkgDirs,
228*9781SMoriah.Waterland@Sun.COM 				char *a_zoneName, char *a_idsName,
229*9781SMoriah.Waterland@Sun.COM 				char *a_zoneAdminFile, char *a_zoneTempDir,
230*9781SMoriah.Waterland@Sun.COM 				char *a_altBinDir, zone_state_t a_zoneState);
231*9781SMoriah.Waterland@Sun.COM static int		pkginstall_check_in_zones(zoneList_t a_zlst,
232*9781SMoriah.Waterland@Sun.COM 				char *a_idsName, char *a_altBinDir,
233*9781SMoriah.Waterland@Sun.COM 				char *a_zoneAdminFile, char *a_zoneTempDir);
234*9781SMoriah.Waterland@Sun.COM static int		install_in_zones(zoneList_t a_zlst, char *a_idsName,
235*9781SMoriah.Waterland@Sun.COM 				char *a_altBinDir, char *a_zoneAdminFile,
236*9781SMoriah.Waterland@Sun.COM 				char *a_zoneTempDir);
237*9781SMoriah.Waterland@Sun.COM static int		pkgInstall(char *ir, char *a_idsName, char *a_pkgDir,
238*9781SMoriah.Waterland@Sun.COM 				char *a_altBinDir, char **a_inheritedPkgDirs);
239*9781SMoriah.Waterland@Sun.COM static int		pkgZoneCheckInstall(char *a_zoneName,
240*9781SMoriah.Waterland@Sun.COM 				char **a_inheritedPkgDirs,
241*9781SMoriah.Waterland@Sun.COM 				zone_state_t a_zoneState,
242*9781SMoriah.Waterland@Sun.COM 				char *a_idsName, char *a_altBinDir,
243*9781SMoriah.Waterland@Sun.COM 				char *a_adminFile, char *a_stdoutPath);
244*9781SMoriah.Waterland@Sun.COM static int		pkgZoneInstall(char *a_zoneName,
245*9781SMoriah.Waterland@Sun.COM 				char **a_inheritedPkgDirs,
246*9781SMoriah.Waterland@Sun.COM 				zone_state_t a_zoneState,
247*9781SMoriah.Waterland@Sun.COM 				char *a_idsName, char *a_altBinDir,
248*9781SMoriah.Waterland@Sun.COM 				char *a_adminFile);
249*9781SMoriah.Waterland@Sun.COM static void		resetreturn();
250*9781SMoriah.Waterland@Sun.COM static void		usage(void);
251*9781SMoriah.Waterland@Sun.COM static boolean_t	add_packages(char **a_pkgList, char *a_uri,
252*9781SMoriah.Waterland@Sun.COM 				char *a_idsName, int a_repeat,
253*9781SMoriah.Waterland@Sun.COM 				char *a_altBinDir, char *a_device,
254*9781SMoriah.Waterland@Sun.COM 				boolean_t a_noZones);
255*9781SMoriah.Waterland@Sun.COM static boolean_t	add_packages_in_global_no_zones(char **a_pkgList,
256*9781SMoriah.Waterland@Sun.COM 				char *a_uri, char *a_idsName, int a_repeat,
257*9781SMoriah.Waterland@Sun.COM 				char *a_altBinDir, char *a_device);
258*9781SMoriah.Waterland@Sun.COM static boolean_t	add_packages_in_global_with_zones(char **a_pkgList,
259*9781SMoriah.Waterland@Sun.COM 				char *a_uri, char *a_idsName, int a_repeat,
260*9781SMoriah.Waterland@Sun.COM 				char *a_altBinDir, char *a_device,
261*9781SMoriah.Waterland@Sun.COM 				zoneList_t a_zlst);
262*9781SMoriah.Waterland@Sun.COM static boolean_t	add_packages_in_nonglobal_zone(char **a_pkgList,
263*9781SMoriah.Waterland@Sun.COM 				char *a_uri, char *a_idsName, int a_repeat,
264*9781SMoriah.Waterland@Sun.COM 				char *a_altBinDir, char *a_device);
265*9781SMoriah.Waterland@Sun.COM static boolean_t	check_applicability(char *a_packageDir,
266*9781SMoriah.Waterland@Sun.COM 				char *a_pkgInst, char *a_rootPath,
267*9781SMoriah.Waterland@Sun.COM 				CAF_T a_flags);
268*9781SMoriah.Waterland@Sun.COM static boolean_t	get_package_list(char ***r_pkgList, char **a_argv,
269*9781SMoriah.Waterland@Sun.COM 				char *a_categories, char **a_categoryList,
270*9781SMoriah.Waterland@Sun.COM 				int a_ignoreSignatures, PKG_ERR *a_err,
271*9781SMoriah.Waterland@Sun.COM 				ushort_t a_httpProxyPort, char *a_httpProxyName,
272*9781SMoriah.Waterland@Sun.COM 				keystore_handle_t a_keystore,
273*9781SMoriah.Waterland@Sun.COM 				char *a_keystoreFile, char *a_idsName,
274*9781SMoriah.Waterland@Sun.COM 				int *r_repeat);
275*9781SMoriah.Waterland@Sun.COM static boolean_t	continue_installation(void);
276*9781SMoriah.Waterland@Sun.COM static boolean_t	unpack_and_check_packages(char **a_pkgList,
277*9781SMoriah.Waterland@Sun.COM 				char *a_idsName, char *a_packageDir);
278*9781SMoriah.Waterland@Sun.COM /*
279*9781SMoriah.Waterland@Sun.COM  * *****************************************************************************
280*9781SMoriah.Waterland@Sun.COM  * global external (public) functions
281*9781SMoriah.Waterland@Sun.COM  * *****************************************************************************
282*9781SMoriah.Waterland@Sun.COM  */
283*9781SMoriah.Waterland@Sun.COM 
284*9781SMoriah.Waterland@Sun.COM /*
285*9781SMoriah.Waterland@Sun.COM  * Name:	main
286*9781SMoriah.Waterland@Sun.COM  * Description:	main entry point for pkgadd/pkgask
287*9781SMoriah.Waterland@Sun.COM  * Returns:	int
288*9781SMoriah.Waterland@Sun.COM  *   0        Successful completion
289*9781SMoriah.Waterland@Sun.COM  *   1        Fatal error.
290*9781SMoriah.Waterland@Sun.COM  *   2        Warning.
291*9781SMoriah.Waterland@Sun.COM  *   3        Interruption.
292*9781SMoriah.Waterland@Sun.COM  *   4        Administration.
293*9781SMoriah.Waterland@Sun.COM  *   5        Administration. Interaction is required. Do not use pkgadd -n.
294*9781SMoriah.Waterland@Sun.COM  * In addition, one of the following values may be added to the previous value
295*9781SMoriah.Waterland@Sun.COM  * as appropriate:
296*9781SMoriah.Waterland@Sun.COM  *  10       Reboot after installation of all packages.
297*9781SMoriah.Waterland@Sun.COM  *  20       Reboot after installation of this package.
298*9781SMoriah.Waterland@Sun.COM  * For example, "14" would indicate both "administration" and "reboot after
299*9781SMoriah.Waterland@Sun.COM  * installation of all packages".
300*9781SMoriah.Waterland@Sun.COM  */
301*9781SMoriah.Waterland@Sun.COM 
302*9781SMoriah.Waterland@Sun.COM int
303*9781SMoriah.Waterland@Sun.COM main(int argc, char **argv)
304*9781SMoriah.Waterland@Sun.COM {
305*9781SMoriah.Waterland@Sun.COM 	PKG_ERR			*err = NULL;
306*9781SMoriah.Waterland@Sun.COM 	WebScheme		scheme = none;
307*9781SMoriah.Waterland@Sun.COM 	char			**category = NULL;
308*9781SMoriah.Waterland@Sun.COM 	char			*abiPtr;
309*9781SMoriah.Waterland@Sun.COM 	char			*altBinDir = (char *)NULL;
310*9781SMoriah.Waterland@Sun.COM 	char			*catg_arg = NULL;
311*9781SMoriah.Waterland@Sun.COM 	char			*device = NULL;		/* dev pkg stored on */
312*9781SMoriah.Waterland@Sun.COM 	char			*dwnld_dir = NULL;
313*9781SMoriah.Waterland@Sun.COM 	char			*keystore_file = NULL;
314*9781SMoriah.Waterland@Sun.COM 	char			*p;
315*9781SMoriah.Waterland@Sun.COM 	char			*q;
316*9781SMoriah.Waterland@Sun.COM 	char			*prog;
317*9781SMoriah.Waterland@Sun.COM 	char			*prog_full_name = NULL;
318*9781SMoriah.Waterland@Sun.COM 	char			*proxy = NULL;
319*9781SMoriah.Waterland@Sun.COM 	char			*spoolDir = NULL;	/* specified with -s */
320*9781SMoriah.Waterland@Sun.COM 	char			*uri = NULL;
321*9781SMoriah.Waterland@Sun.COM 	char			Rpath[PATH_MAX+1] = {'\0'};
322*9781SMoriah.Waterland@Sun.COM 	int			c;
323*9781SMoriah.Waterland@Sun.COM 	int			ignore_sig = 0;
324*9781SMoriah.Waterland@Sun.COM 	int			n;
325*9781SMoriah.Waterland@Sun.COM 	int			repeat;
326*9781SMoriah.Waterland@Sun.COM 	int			retries = NET_RETRIES_DEFAULT;
327*9781SMoriah.Waterland@Sun.COM 	int			timeout = NET_TIMEOUT_DEFAULT;
328*9781SMoriah.Waterland@Sun.COM 	keystore_handle_t	keystore = NULL;
329*9781SMoriah.Waterland@Sun.COM 	struct sigaction	nact;
330*9781SMoriah.Waterland@Sun.COM 	struct sigaction	oact;
331*9781SMoriah.Waterland@Sun.COM 	ushort_t		proxy_port = 0;
332*9781SMoriah.Waterland@Sun.COM 
333*9781SMoriah.Waterland@Sun.COM 	/* initialize locale environment */
334*9781SMoriah.Waterland@Sun.COM 
335*9781SMoriah.Waterland@Sun.COM 	(void) setlocale(LC_ALL, "");
336*9781SMoriah.Waterland@Sun.COM 	(void) textdomain(TEXT_DOMAIN);
337*9781SMoriah.Waterland@Sun.COM 
338*9781SMoriah.Waterland@Sun.COM 	/* initialize program name */
339*9781SMoriah.Waterland@Sun.COM 
340*9781SMoriah.Waterland@Sun.COM 	prog_full_name = argv[0];
341*9781SMoriah.Waterland@Sun.COM 	prog = set_prog_name(argv[0]);
342*9781SMoriah.Waterland@Sun.COM 
343*9781SMoriah.Waterland@Sun.COM 	/* tell spmi zones interface how to access package output functions */
344*9781SMoriah.Waterland@Sun.COM 
345*9781SMoriah.Waterland@Sun.COM 	z_set_output_functions(echo, echoDebug, progerr);
346*9781SMoriah.Waterland@Sun.COM 
347*9781SMoriah.Waterland@Sun.COM 	askflag = (strcmp(prog, "pkgask") == 0);
348*9781SMoriah.Waterland@Sun.COM 
349*9781SMoriah.Waterland@Sun.COM 	/* set sane umask */
350*9781SMoriah.Waterland@Sun.COM 
351*9781SMoriah.Waterland@Sun.COM 	(void) umask(0022);
352*9781SMoriah.Waterland@Sun.COM 
353*9781SMoriah.Waterland@Sun.COM 	/* tell quit which ckreturn function to call */
354*9781SMoriah.Waterland@Sun.COM 
355*9781SMoriah.Waterland@Sun.COM 	quitSetCkreturnFunc(&ckreturn);
356*9781SMoriah.Waterland@Sun.COM 
357*9781SMoriah.Waterland@Sun.COM 	/* initially no source "device" */
358*9781SMoriah.Waterland@Sun.COM 
359*9781SMoriah.Waterland@Sun.COM 	device = NULL;
360*9781SMoriah.Waterland@Sun.COM 
361*9781SMoriah.Waterland@Sun.COM 	/* reset npkgs (used as pkg remaining count in quit.c) */
362*9781SMoriah.Waterland@Sun.COM 
363*9781SMoriah.Waterland@Sun.COM 	npkgs = 0;
364*9781SMoriah.Waterland@Sun.COM 
365*9781SMoriah.Waterland@Sun.COM 	/* set default password prompt for encrypted packages */
366*9781SMoriah.Waterland@Sun.COM 
367*9781SMoriah.Waterland@Sun.COM 	set_passphrase_prompt(MSG_PASSPROMPT);
368*9781SMoriah.Waterland@Sun.COM 
369*9781SMoriah.Waterland@Sun.COM 	/* initialize security operations structures and libraries */
370*9781SMoriah.Waterland@Sun.COM 
371*9781SMoriah.Waterland@Sun.COM 	sec_init();
372*9781SMoriah.Waterland@Sun.COM 
373*9781SMoriah.Waterland@Sun.COM 	if (z_running_in_global_zone() && !enable_local_fs()) {
374*9781SMoriah.Waterland@Sun.COM 		progerr(ERR_CANNOT_ENABLE_LOCAL_FS);
375*9781SMoriah.Waterland@Sun.COM 	}
376*9781SMoriah.Waterland@Sun.COM 
377*9781SMoriah.Waterland@Sun.COM 	/*
378*9781SMoriah.Waterland@Sun.COM 	 * ********************************************************************
379*9781SMoriah.Waterland@Sun.COM 	 * parse command line options
380*9781SMoriah.Waterland@Sun.COM 	 * ********************************************************************
381*9781SMoriah.Waterland@Sun.COM 	 */
382*9781SMoriah.Waterland@Sun.COM 
383*9781SMoriah.Waterland@Sun.COM 	while ((c = getopt(argc, argv,
384*9781SMoriah.Waterland@Sun.COM 		"?Aa:b:B:Cc:D:d:GhIik:MnO:P:R:r:Ss:tV:vx:Y:zZ")) != EOF) {
385*9781SMoriah.Waterland@Sun.COM 		switch (c) {
386*9781SMoriah.Waterland@Sun.COM 
387*9781SMoriah.Waterland@Sun.COM 		/*
388*9781SMoriah.Waterland@Sun.COM 		 * Not a public interface: This disables attribute checking.
389*9781SMoriah.Waterland@Sun.COM 		 * It speeds up installation a little bit.
390*9781SMoriah.Waterland@Sun.COM 		 */
391*9781SMoriah.Waterland@Sun.COM 		case 'A':
392*9781SMoriah.Waterland@Sun.COM 			disableAttributes++;
393*9781SMoriah.Waterland@Sun.COM 			break;
394*9781SMoriah.Waterland@Sun.COM 
395*9781SMoriah.Waterland@Sun.COM 		/*
396*9781SMoriah.Waterland@Sun.COM 		 * Public interface: Define an installation administration
397*9781SMoriah.Waterland@Sun.COM 		 * file, admin, to be used in place of the default
398*9781SMoriah.Waterland@Sun.COM 		 * administration file.	 The token none overrides the use
399*9781SMoriah.Waterland@Sun.COM 		 * of any admin file, and thus forces interaction with the
400*9781SMoriah.Waterland@Sun.COM 		 * user. Unless a full path name is given, pkgadd first
401*9781SMoriah.Waterland@Sun.COM 		 * looks in the current working directory for the
402*9781SMoriah.Waterland@Sun.COM 		 * administration file.	 If the specified administration
403*9781SMoriah.Waterland@Sun.COM 		 * file is not in the current working directory, pkgadd
404*9781SMoriah.Waterland@Sun.COM 		 * looks in the /var/sadm/install/admin directory for the
405*9781SMoriah.Waterland@Sun.COM 		 * administration file.
406*9781SMoriah.Waterland@Sun.COM 		 */
407*9781SMoriah.Waterland@Sun.COM 		case 'a':
408*9781SMoriah.Waterland@Sun.COM 			admnfile = flex_device(optarg, 0);
409*9781SMoriah.Waterland@Sun.COM 			break;
410*9781SMoriah.Waterland@Sun.COM 
411*9781SMoriah.Waterland@Sun.COM 		/*
412*9781SMoriah.Waterland@Sun.COM 		 * Not a public interface: control block size given to
413*9781SMoriah.Waterland@Sun.COM 		 * pkginstall - block size used in read()/write() loop;
414*9781SMoriah.Waterland@Sun.COM 		 * default is st_blksize from stat() of source file.
415*9781SMoriah.Waterland@Sun.COM 		 */
416*9781SMoriah.Waterland@Sun.COM 		case 'B':
417*9781SMoriah.Waterland@Sun.COM 			if (optarg[0] == '-') {
418*9781SMoriah.Waterland@Sun.COM 				usage();
419*9781SMoriah.Waterland@Sun.COM 				quit(1);
420*9781SMoriah.Waterland@Sun.COM 			}
421*9781SMoriah.Waterland@Sun.COM 			rw_block_size = optarg;
422*9781SMoriah.Waterland@Sun.COM 			break;
423*9781SMoriah.Waterland@Sun.COM 
424*9781SMoriah.Waterland@Sun.COM 		/*
425*9781SMoriah.Waterland@Sun.COM 		 * Not a public interface:  location where package executables
426*9781SMoriah.Waterland@Sun.COM 		 * can be found - default is /usr/sadm/install/bin.
427*9781SMoriah.Waterland@Sun.COM 		 */
428*9781SMoriah.Waterland@Sun.COM 		case 'b':
429*9781SMoriah.Waterland@Sun.COM 			if (optarg[0] == '-') {
430*9781SMoriah.Waterland@Sun.COM 				usage();
431*9781SMoriah.Waterland@Sun.COM 				quit(1);
432*9781SMoriah.Waterland@Sun.COM 			}
433*9781SMoriah.Waterland@Sun.COM 			if (!path_valid(optarg)) {
434*9781SMoriah.Waterland@Sun.COM 				progerr(ERR_PATH, optarg);
435*9781SMoriah.Waterland@Sun.COM 				quit(1);
436*9781SMoriah.Waterland@Sun.COM 			}
437*9781SMoriah.Waterland@Sun.COM 			if (isdir(optarg) != 0) {
438*9781SMoriah.Waterland@Sun.COM 				p = strerror(errno);
439*9781SMoriah.Waterland@Sun.COM 				progerr(ERR_CANNOT_USE_DIR, optarg, p);
440*9781SMoriah.Waterland@Sun.COM 				quit(1);
441*9781SMoriah.Waterland@Sun.COM 			}
442*9781SMoriah.Waterland@Sun.COM 			altBinDir = optarg;
443*9781SMoriah.Waterland@Sun.COM 			break;
444*9781SMoriah.Waterland@Sun.COM 
445*9781SMoriah.Waterland@Sun.COM 		/*
446*9781SMoriah.Waterland@Sun.COM 		 * Not a public interface: This disables checksum tests on
447*9781SMoriah.Waterland@Sun.COM 		 * the source files. It speeds up installation a little bit.
448*9781SMoriah.Waterland@Sun.COM 		 */
449*9781SMoriah.Waterland@Sun.COM 		case 'C':
450*9781SMoriah.Waterland@Sun.COM 			disableChecksum++;
451*9781SMoriah.Waterland@Sun.COM 			break;
452*9781SMoriah.Waterland@Sun.COM 
453*9781SMoriah.Waterland@Sun.COM 		/*
454*9781SMoriah.Waterland@Sun.COM 		 * Not a public interface: This allows designation of a
455*9781SMoriah.Waterland@Sun.COM 		 * continuation file. It is the same format as a dryrun file
456*9781SMoriah.Waterland@Sun.COM 		 * but it is used to take up where the dryrun left off.
457*9781SMoriah.Waterland@Sun.COM 		 */
458*9781SMoriah.Waterland@Sun.COM 		case 'c':
459*9781SMoriah.Waterland@Sun.COM 			pkgcontsrc = flex_device(optarg, 0);
460*9781SMoriah.Waterland@Sun.COM 			break;
461*9781SMoriah.Waterland@Sun.COM 
462*9781SMoriah.Waterland@Sun.COM 		/*
463*9781SMoriah.Waterland@Sun.COM 		 * Not a public interface: This allows designation of a
464*9781SMoriah.Waterland@Sun.COM 		 * dryrun file. This pkgadd will create dryrun files
465*9781SMoriah.Waterland@Sun.COM 		 * in the directory provided.
466*9781SMoriah.Waterland@Sun.COM 		 */
467*9781SMoriah.Waterland@Sun.COM 		case 'D':
468*9781SMoriah.Waterland@Sun.COM 			if (optarg[0] == '-') {
469*9781SMoriah.Waterland@Sun.COM 				usage();
470*9781SMoriah.Waterland@Sun.COM 				quit(1);
471*9781SMoriah.Waterland@Sun.COM 			}
472*9781SMoriah.Waterland@Sun.COM 			pkgdrtarg = flex_device(optarg, 0);
473*9781SMoriah.Waterland@Sun.COM 			break;
474*9781SMoriah.Waterland@Sun.COM 
475*9781SMoriah.Waterland@Sun.COM 		/*
476*9781SMoriah.Waterland@Sun.COM 		 * Public interface: Install or copy a package from
477*9781SMoriah.Waterland@Sun.COM 		 * device. device can be a full path name to a directory
478*9781SMoriah.Waterland@Sun.COM 		 * or the identifiers for tape, floppy disk, or removable
479*9781SMoriah.Waterland@Sun.COM 		 * disk - for example, /var/tmp or /floppy/floppy_name.
480*9781SMoriah.Waterland@Sun.COM 		 * It can also be a device alias - for example,
481*9781SMoriah.Waterland@Sun.COM 		 * /floppy/floppy0, or a datastream created by pkgtrans.
482*9781SMoriah.Waterland@Sun.COM 		 */
483*9781SMoriah.Waterland@Sun.COM 		case 'd':
484*9781SMoriah.Waterland@Sun.COM 			if (optarg[0] == '-') {
485*9781SMoriah.Waterland@Sun.COM 				usage();
486*9781SMoriah.Waterland@Sun.COM 				quit(1);
487*9781SMoriah.Waterland@Sun.COM 			}
488*9781SMoriah.Waterland@Sun.COM 			if (!path_valid(optarg)) {
489*9781SMoriah.Waterland@Sun.COM 				progerr(ERR_PATH, optarg);
490*9781SMoriah.Waterland@Sun.COM 				quit(1);
491*9781SMoriah.Waterland@Sun.COM 				/* NOTREACHED */
492*9781SMoriah.Waterland@Sun.COM 			}
493*9781SMoriah.Waterland@Sun.COM 
494*9781SMoriah.Waterland@Sun.COM 			if (strncmp(optarg, HTTP, 7) == 0) {
495*9781SMoriah.Waterland@Sun.COM 				scheme = web_http;
496*9781SMoriah.Waterland@Sun.COM 			} else if (strncmp(optarg, HTTPS, 8) == 0) {
497*9781SMoriah.Waterland@Sun.COM 				scheme = web_https;
498*9781SMoriah.Waterland@Sun.COM 			}
499*9781SMoriah.Waterland@Sun.COM 
500*9781SMoriah.Waterland@Sun.COM 			if (scheme == web_https || scheme == web_http) {
501*9781SMoriah.Waterland@Sun.COM 				uri = optarg;
502*9781SMoriah.Waterland@Sun.COM 				if ((device = malloc(PATH_MAX)) == NULL) {
503*9781SMoriah.Waterland@Sun.COM 					progerr(ERR_MEM);
504*9781SMoriah.Waterland@Sun.COM 					exit(1);
505*9781SMoriah.Waterland@Sun.COM 				}
506*9781SMoriah.Waterland@Sun.COM 				(void) memset(device, '\0', PATH_MAX);
507*9781SMoriah.Waterland@Sun.COM 			} else {
508*9781SMoriah.Waterland@Sun.COM 				device = flex_device(optarg, 1);
509*9781SMoriah.Waterland@Sun.COM 			}
510*9781SMoriah.Waterland@Sun.COM 			break;
511*9781SMoriah.Waterland@Sun.COM 
512*9781SMoriah.Waterland@Sun.COM 		/*
513*9781SMoriah.Waterland@Sun.COM 		 * Public interface: install package in global zone only.
514*9781SMoriah.Waterland@Sun.COM 		 */
515*9781SMoriah.Waterland@Sun.COM 		case 'G':
516*9781SMoriah.Waterland@Sun.COM 			globalZoneOnly = B_TRUE;
517*9781SMoriah.Waterland@Sun.COM 			break;
518*9781SMoriah.Waterland@Sun.COM 
519*9781SMoriah.Waterland@Sun.COM 		/*
520*9781SMoriah.Waterland@Sun.COM 		 * Not a public interface: Enable hollow package support. When
521*9781SMoriah.Waterland@Sun.COM 		 * specified, for any package that has SUNW_PKG_HOLLOW=true:
522*9781SMoriah.Waterland@Sun.COM 		 *  Do not calculate and verify package size against target.
523*9781SMoriah.Waterland@Sun.COM 		 *  Do not run any package procedure or class action scripts.
524*9781SMoriah.Waterland@Sun.COM 		 *  Do not create any target directories.
525*9781SMoriah.Waterland@Sun.COM 		 *  Do not perform any script locking.
526*9781SMoriah.Waterland@Sun.COM 		 *  Do not install any components of any package.
527*9781SMoriah.Waterland@Sun.COM 		 *  Do not output any status or database update messages.
528*9781SMoriah.Waterland@Sun.COM 		 */
529*9781SMoriah.Waterland@Sun.COM 		case 'h':
530*9781SMoriah.Waterland@Sun.COM 			set_depend_pkginfo_DB(B_TRUE);
531*9781SMoriah.Waterland@Sun.COM 			break;
532*9781SMoriah.Waterland@Sun.COM 
533*9781SMoriah.Waterland@Sun.COM 		/*
534*9781SMoriah.Waterland@Sun.COM 		 * Not a public interface: Informs scripts that this is
535*9781SMoriah.Waterland@Sun.COM 		 * an initial install by setting the environment parameter
536*9781SMoriah.Waterland@Sun.COM 		 * PKG_INIT_INSTALL=TRUE for all scripts. They may use it as
537*9781SMoriah.Waterland@Sun.COM 		 * they see fit, safe in the knowledge that the target
538*9781SMoriah.Waterland@Sun.COM 		 * filesystem is tabula rasa.
539*9781SMoriah.Waterland@Sun.COM 		 */
540*9781SMoriah.Waterland@Sun.COM 		case 'I':
541*9781SMoriah.Waterland@Sun.COM 			init_install++;
542*9781SMoriah.Waterland@Sun.COM 			break;
543*9781SMoriah.Waterland@Sun.COM 
544*9781SMoriah.Waterland@Sun.COM 		/*
545*9781SMoriah.Waterland@Sun.COM 		 * Not a public interface: ignore signatures.
546*9781SMoriah.Waterland@Sun.COM 		 */
547*9781SMoriah.Waterland@Sun.COM 		case 'i':
548*9781SMoriah.Waterland@Sun.COM 			ignore_sig++;
549*9781SMoriah.Waterland@Sun.COM 			break;
550*9781SMoriah.Waterland@Sun.COM 
551*9781SMoriah.Waterland@Sun.COM 		/*
552*9781SMoriah.Waterland@Sun.COM 		 * Public interface: Use keystore as the location from which to
553*9781SMoriah.Waterland@Sun.COM 		 * get trusted certificate authority certificates when verifying
554*9781SMoriah.Waterland@Sun.COM 		 * digital signatures found in packages. If no keystore is
555*9781SMoriah.Waterland@Sun.COM 		 * specified, then the default keystore locations are searched
556*9781SMoriah.Waterland@Sun.COM 		 * for valid trusted certificates.
557*9781SMoriah.Waterland@Sun.COM 		 */
558*9781SMoriah.Waterland@Sun.COM 		case 'k':
559*9781SMoriah.Waterland@Sun.COM 			if (!path_valid(optarg)) {
560*9781SMoriah.Waterland@Sun.COM 				progerr(ERR_PATH, optarg);
561*9781SMoriah.Waterland@Sun.COM 				quit(1);
562*9781SMoriah.Waterland@Sun.COM 				/* NOTREACHED */
563*9781SMoriah.Waterland@Sun.COM 			}
564*9781SMoriah.Waterland@Sun.COM 			keystore_file = optarg;
565*9781SMoriah.Waterland@Sun.COM 			break;
566*9781SMoriah.Waterland@Sun.COM 
567*9781SMoriah.Waterland@Sun.COM 		/*
568*9781SMoriah.Waterland@Sun.COM 		 * Public interface: Instruct pkgadd not to use the
569*9781SMoriah.Waterland@Sun.COM 		 * $root_path/etc/vfstab file for determining the client's
570*9781SMoriah.Waterland@Sun.COM 		 * mount points. This option assumes the mount points are
571*9781SMoriah.Waterland@Sun.COM 		 * correct on the server and it behaves consistently with
572*9781SMoriah.Waterland@Sun.COM 		 * Solaris 2.5 and earlier releases.
573*9781SMoriah.Waterland@Sun.COM 		 */
574*9781SMoriah.Waterland@Sun.COM 		case 'M':
575*9781SMoriah.Waterland@Sun.COM 			no_map_client = 1;
576*9781SMoriah.Waterland@Sun.COM 			break;
577*9781SMoriah.Waterland@Sun.COM 
578*9781SMoriah.Waterland@Sun.COM 		/*
579*9781SMoriah.Waterland@Sun.COM 		 * Not a public interface: the -O option allows the behavior
580*9781SMoriah.Waterland@Sun.COM 		 * of the package tools to be modified. Recognized options:
581*9781SMoriah.Waterland@Sun.COM 		 * -> debug
582*9781SMoriah.Waterland@Sun.COM 		 * ---> enable debugging output
583*9781SMoriah.Waterland@Sun.COM 		 * -> addzonename
584*9781SMoriah.Waterland@Sun.COM 		 * ---> add zone name to appropriate messages
585*9781SMoriah.Waterland@Sun.COM 		 * -> nozones
586*9781SMoriah.Waterland@Sun.COM 		 * ---> act as though in global zone with no non-global zones
587*9781SMoriah.Waterland@Sun.COM 		 * -> inherited-filesystems
588*9781SMoriah.Waterland@Sun.COM 		 * ---> add specified file system to list of file systems
589*9781SMoriah.Waterland@Sun.COM 		 * ---> that are inherited from the global zone
590*9781SMoriah.Waterland@Sun.COM 		 * -> enable-hollow-package-support
591*9781SMoriah.Waterland@Sun.COM 		 * ---> Enable hollow package support. When specified, for any
592*9781SMoriah.Waterland@Sun.COM 		 * ---> package that has SUNW_PKG_HOLLOW=true:
593*9781SMoriah.Waterland@Sun.COM 		 * ---> Do not calculate and verify package size against target
594*9781SMoriah.Waterland@Sun.COM 		 * ---> Do not run any package procedure or class action scripts
595*9781SMoriah.Waterland@Sun.COM 		 * ---> Do not create any target directories
596*9781SMoriah.Waterland@Sun.COM 		 * ---> Do not perform any script locking
597*9781SMoriah.Waterland@Sun.COM 		 * ---> Do not install any components of any package
598*9781SMoriah.Waterland@Sun.COM 		 * ---> Do not output any status or database update messages
599*9781SMoriah.Waterland@Sun.COM 		 * -> zonelist="<names...>"
600*9781SMoriah.Waterland@Sun.COM 		 * ---> add package to space/colon separated list of zones only
601*9781SMoriah.Waterland@Sun.COM 		 */
602*9781SMoriah.Waterland@Sun.COM 
603*9781SMoriah.Waterland@Sun.COM 		case 'O':
604*9781SMoriah.Waterland@Sun.COM 			for (p = strtok(optarg, ","); p != (char *)NULL;
605*9781SMoriah.Waterland@Sun.COM 				p = strtok(NULL, ",")) {
606*9781SMoriah.Waterland@Sun.COM 
607*9781SMoriah.Waterland@Sun.COM 				if (strcmp(p, "debug") == 0) {
608*9781SMoriah.Waterland@Sun.COM 					/* set debug flag/enable debug output */
609*9781SMoriah.Waterland@Sun.COM 					debugFlag = B_TRUE;
610*9781SMoriah.Waterland@Sun.COM 					(void) echoDebugSetFlag(debugFlag);
611*9781SMoriah.Waterland@Sun.COM 
612*9781SMoriah.Waterland@Sun.COM 					/* debug info on arguments to pkgadd */
613*9781SMoriah.Waterland@Sun.COM 					for (n = 0; n < argc && argv[n]; n++) {
614*9781SMoriah.Waterland@Sun.COM 						echoDebug(DBG_ARG, n, argv[n]);
615*9781SMoriah.Waterland@Sun.COM 					}
616*9781SMoriah.Waterland@Sun.COM 
617*9781SMoriah.Waterland@Sun.COM 					continue;
618*9781SMoriah.Waterland@Sun.COM 				}
619*9781SMoriah.Waterland@Sun.COM 
620*9781SMoriah.Waterland@Sun.COM 				if (strcmp(p,
621*9781SMoriah.Waterland@Sun.COM 					"enable-hollow-package-support") == 0) {
622*9781SMoriah.Waterland@Sun.COM 					set_depend_pkginfo_DB(B_TRUE);
623*9781SMoriah.Waterland@Sun.COM 					continue;
624*9781SMoriah.Waterland@Sun.COM 				}
625*9781SMoriah.Waterland@Sun.COM 
626*9781SMoriah.Waterland@Sun.COM 				if (strncmp(p, INHERITFS, INHERITFS_LEN) == 0) {
627*9781SMoriah.Waterland@Sun.COM 					if (z_add_inherited_file_system(
628*9781SMoriah.Waterland@Sun.COM 						p+INHERITFS_LEN) == B_FALSE) {
629*9781SMoriah.Waterland@Sun.COM 						progerr(ERR_NOSUCH_INHERITED,
630*9781SMoriah.Waterland@Sun.COM 							p+INHERITFS_LEN);
631*9781SMoriah.Waterland@Sun.COM 						quit(1);
632*9781SMoriah.Waterland@Sun.COM 						/* NOTREACHED */
633*9781SMoriah.Waterland@Sun.COM 					}
634*9781SMoriah.Waterland@Sun.COM 					continue;
635*9781SMoriah.Waterland@Sun.COM 				}
636*9781SMoriah.Waterland@Sun.COM 
637*9781SMoriah.Waterland@Sun.COM 				if (strcmp(p, "addzonename") == 0) {
638*9781SMoriah.Waterland@Sun.COM 					quitSetZoneName(z_get_zonename());
639*9781SMoriah.Waterland@Sun.COM 					continue;
640*9781SMoriah.Waterland@Sun.COM 				}
641*9781SMoriah.Waterland@Sun.COM 
642*9781SMoriah.Waterland@Sun.COM 				if (strcmp(p, "nozones") == 0) {
643*9781SMoriah.Waterland@Sun.COM 					noZones = B_TRUE;
644*9781SMoriah.Waterland@Sun.COM 					continue;
645*9781SMoriah.Waterland@Sun.COM 				}
646*9781SMoriah.Waterland@Sun.COM 
647*9781SMoriah.Waterland@Sun.COM 				/*
648*9781SMoriah.Waterland@Sun.COM 				 * Private interface: package is being
649*9781SMoriah.Waterland@Sun.COM 				 * installed as a patch package.
650*9781SMoriah.Waterland@Sun.COM 				 */
651*9781SMoriah.Waterland@Sun.COM 
652*9781SMoriah.Waterland@Sun.COM 				if (strcmp(p, "patchPkgInstall") == 0) {
653*9781SMoriah.Waterland@Sun.COM 					setPatchUpdate();
654*9781SMoriah.Waterland@Sun.COM 					continue;
655*9781SMoriah.Waterland@Sun.COM 				}
656*9781SMoriah.Waterland@Sun.COM 
657*9781SMoriah.Waterland@Sun.COM 				/*
658*9781SMoriah.Waterland@Sun.COM 				 * If this is a patch removal
659*9781SMoriah.Waterland@Sun.COM 				 * then call setPatchUpdate() and set
660*9781SMoriah.Waterland@Sun.COM 				 * patchPkgRemoval flag.
661*9781SMoriah.Waterland@Sun.COM 				 */
662*9781SMoriah.Waterland@Sun.COM 				if (strcmp(p, "patchPkgRemoval") == 0) {
663*9781SMoriah.Waterland@Sun.COM 					setPatchUpdate();
664*9781SMoriah.Waterland@Sun.COM 					patchPkgRemoval = B_TRUE;
665*9781SMoriah.Waterland@Sun.COM 					continue;
666*9781SMoriah.Waterland@Sun.COM 				}
667*9781SMoriah.Waterland@Sun.COM 
668*9781SMoriah.Waterland@Sun.COM 				if (strncmp(p, "zonelist=", 9) == 0) {
669*9781SMoriah.Waterland@Sun.COM 					/*
670*9781SMoriah.Waterland@Sun.COM 					 * If colons used as separators,
671*9781SMoriah.Waterland@Sun.COM 					 * convert to spaces.
672*9781SMoriah.Waterland@Sun.COM 					 */
673*9781SMoriah.Waterland@Sun.COM 					q = p + 9;
674*9781SMoriah.Waterland@Sun.COM 					while (*q != '\0') {
675*9781SMoriah.Waterland@Sun.COM 						if (*q == ':') {
676*9781SMoriah.Waterland@Sun.COM 							*q = ' ';
677*9781SMoriah.Waterland@Sun.COM 						}
678*9781SMoriah.Waterland@Sun.COM 						q++;
679*9781SMoriah.Waterland@Sun.COM 					}
680*9781SMoriah.Waterland@Sun.COM 
681*9781SMoriah.Waterland@Sun.COM 					if (z_set_zone_spec(p + 9) == -1)
682*9781SMoriah.Waterland@Sun.COM 						quit(1);
683*9781SMoriah.Waterland@Sun.COM 					usedZoneList = B_TRUE;
684*9781SMoriah.Waterland@Sun.COM 					continue;
685*9781SMoriah.Waterland@Sun.COM 				}
686*9781SMoriah.Waterland@Sun.COM 
687*9781SMoriah.Waterland@Sun.COM 				progerr(ERR_INVALID_O_OPTION, p);
688*9781SMoriah.Waterland@Sun.COM 				continue;
689*9781SMoriah.Waterland@Sun.COM 			}
690*9781SMoriah.Waterland@Sun.COM 			break;
691*9781SMoriah.Waterland@Sun.COM 
692*9781SMoriah.Waterland@Sun.COM 		/*
693*9781SMoriah.Waterland@Sun.COM 		 * Public interface: installation occurs in
694*9781SMoriah.Waterland@Sun.COM 		 * non-interactive mode.  Suppress output of the list of
695*9781SMoriah.Waterland@Sun.COM 		 * installed files. The default mode is interactive.
696*9781SMoriah.Waterland@Sun.COM 		 */
697*9781SMoriah.Waterland@Sun.COM 		case 'n':
698*9781SMoriah.Waterland@Sun.COM 			nointeract++;
699*9781SMoriah.Waterland@Sun.COM 			(void) echoSetFlag(B_FALSE);
700*9781SMoriah.Waterland@Sun.COM 			break;
701*9781SMoriah.Waterland@Sun.COM 
702*9781SMoriah.Waterland@Sun.COM 		/*
703*9781SMoriah.Waterland@Sun.COM 		 * Public interface: Password to use to decrypt keystore
704*9781SMoriah.Waterland@Sun.COM 		 * specified with -k, if required. See PASS PHRASE
705*9781SMoriah.Waterland@Sun.COM 		 * ARGUMENTS for more information about the format of this
706*9781SMoriah.Waterland@Sun.COM 		 * option's argument.
707*9781SMoriah.Waterland@Sun.COM 		 */
708*9781SMoriah.Waterland@Sun.COM 		case 'P':
709*9781SMoriah.Waterland@Sun.COM 			if (optarg[0] == '-') {
710*9781SMoriah.Waterland@Sun.COM 				usage();
711*9781SMoriah.Waterland@Sun.COM 				quit(1);
712*9781SMoriah.Waterland@Sun.COM 			}
713*9781SMoriah.Waterland@Sun.COM 			set_passphrase_passarg(optarg);
714*9781SMoriah.Waterland@Sun.COM 			if (ci_strneq(optarg, "pass:", 5)) {
715*9781SMoriah.Waterland@Sun.COM 				/*
716*9781SMoriah.Waterland@Sun.COM 				 * passwords on the command line are highly
717*9781SMoriah.Waterland@Sun.COM 				 * insecure.  complain.
718*9781SMoriah.Waterland@Sun.COM 				 */
719*9781SMoriah.Waterland@Sun.COM 				logerr(PASSWD_CMDLINE, "pass:<pass>");
720*9781SMoriah.Waterland@Sun.COM 			}
721*9781SMoriah.Waterland@Sun.COM 			break;
722*9781SMoriah.Waterland@Sun.COM 
723*9781SMoriah.Waterland@Sun.COM 		/*
724*9781SMoriah.Waterland@Sun.COM 		 * Public interface: Define the full path name of a
725*9781SMoriah.Waterland@Sun.COM 		 * directory to use as the root_path.  All files,
726*9781SMoriah.Waterland@Sun.COM 		 * including package system information files, are
727*9781SMoriah.Waterland@Sun.COM 		 * relocated to a directory tree starting in the specified
728*9781SMoriah.Waterland@Sun.COM 		 * root_path. The root_path may be specified when
729*9781SMoriah.Waterland@Sun.COM 		 * installing to a client from a server (for example,
730*9781SMoriah.Waterland@Sun.COM 		 * /export/root/client1).
731*9781SMoriah.Waterland@Sun.COM 		 */
732*9781SMoriah.Waterland@Sun.COM 		case 'R':
733*9781SMoriah.Waterland@Sun.COM 			if (optarg[0] == '-') {
734*9781SMoriah.Waterland@Sun.COM 				usage();
735*9781SMoriah.Waterland@Sun.COM 				quit(1);
736*9781SMoriah.Waterland@Sun.COM 			}
737*9781SMoriah.Waterland@Sun.COM 			/* determine the real path specified */
738*9781SMoriah.Waterland@Sun.COM 
739*9781SMoriah.Waterland@Sun.COM 			n = resolvepath(optarg, Rpath, sizeof (Rpath)-1);
740*9781SMoriah.Waterland@Sun.COM 
741*9781SMoriah.Waterland@Sun.COM 			/* use supplied path if not resolvable */
742*9781SMoriah.Waterland@Sun.COM 
743*9781SMoriah.Waterland@Sun.COM 			if (n == -1) {
744*9781SMoriah.Waterland@Sun.COM 				(void) strlcpy(Rpath, optarg, sizeof (Rpath));
745*9781SMoriah.Waterland@Sun.COM 			} else {
746*9781SMoriah.Waterland@Sun.COM 				/* null terminate string */
747*9781SMoriah.Waterland@Sun.COM 				Rpath[n] = '\0';
748*9781SMoriah.Waterland@Sun.COM 			}
749*9781SMoriah.Waterland@Sun.COM 
750*9781SMoriah.Waterland@Sun.COM 			/* set the alternative root path */
751*9781SMoriah.Waterland@Sun.COM 
752*9781SMoriah.Waterland@Sun.COM 			if (!set_inst_root(Rpath)) {
753*9781SMoriah.Waterland@Sun.COM 				progerr(ERR_ROOT_CMD);
754*9781SMoriah.Waterland@Sun.COM 				exit(1);
755*9781SMoriah.Waterland@Sun.COM 			}
756*9781SMoriah.Waterland@Sun.COM 			break;
757*9781SMoriah.Waterland@Sun.COM 
758*9781SMoriah.Waterland@Sun.COM 		/*
759*9781SMoriah.Waterland@Sun.COM 		 * Public interface: Identify a file or directory which
760*9781SMoriah.Waterland@Sun.COM 		 * contains output from a previous pkgask(1M)
761*9781SMoriah.Waterland@Sun.COM 		 * session. This file supplies the interaction responses
762*9781SMoriah.Waterland@Sun.COM 		 * that would be requested by the package in interactive
763*9781SMoriah.Waterland@Sun.COM 		 * mode. response must be a full pathname.
764*9781SMoriah.Waterland@Sun.COM 		 */
765*9781SMoriah.Waterland@Sun.COM 		case 'r':
766*9781SMoriah.Waterland@Sun.COM 			if (optarg[0] == '-') {
767*9781SMoriah.Waterland@Sun.COM 				usage();
768*9781SMoriah.Waterland@Sun.COM 				quit(1);
769*9781SMoriah.Waterland@Sun.COM 			}
770*9781SMoriah.Waterland@Sun.COM 			respfile = flex_device(optarg, 2);
771*9781SMoriah.Waterland@Sun.COM 			if (isdir(respfile) == 0)
772*9781SMoriah.Waterland@Sun.COM 				respdir = respfile;
773*9781SMoriah.Waterland@Sun.COM 			break;
774*9781SMoriah.Waterland@Sun.COM 
775*9781SMoriah.Waterland@Sun.COM 		/*
776*9781SMoriah.Waterland@Sun.COM 		 * Not a public interface: suppress copyright notice being
777*9781SMoriah.Waterland@Sun.COM 		 * output during installation.
778*9781SMoriah.Waterland@Sun.COM 		 */
779*9781SMoriah.Waterland@Sun.COM 		case 'S':
780*9781SMoriah.Waterland@Sun.COM 			suppressCopyright++;
781*9781SMoriah.Waterland@Sun.COM 			break;
782*9781SMoriah.Waterland@Sun.COM 
783*9781SMoriah.Waterland@Sun.COM 		/*
784*9781SMoriah.Waterland@Sun.COM 		 * Public interface: Write the package into the directory
785*9781SMoriah.Waterland@Sun.COM 		 * spool instead of installing it. The default directory
786*9781SMoriah.Waterland@Sun.COM 		 * for spooled packages is /var/sadm/pkg.
787*9781SMoriah.Waterland@Sun.COM 		 */
788*9781SMoriah.Waterland@Sun.COM 		case 's':
789*9781SMoriah.Waterland@Sun.COM 			spoolDir = flex_device(optarg, 1);
790*9781SMoriah.Waterland@Sun.COM 			break;
791*9781SMoriah.Waterland@Sun.COM 
792*9781SMoriah.Waterland@Sun.COM 		/*
793*9781SMoriah.Waterland@Sun.COM 		 * Not a public interface: disable save spool area creation;
794*9781SMoriah.Waterland@Sun.COM 		 * suppress the creation and population of the package save
795*9781SMoriah.Waterland@Sun.COM 		 * spool area (var/sadm/pkg/PKG/save/pspool/PKG).
796*9781SMoriah.Waterland@Sun.COM 		 */
797*9781SMoriah.Waterland@Sun.COM 		case 't':
798*9781SMoriah.Waterland@Sun.COM 			disableSaveSpool++;
799*9781SMoriah.Waterland@Sun.COM 			break;
800*9781SMoriah.Waterland@Sun.COM 
801*9781SMoriah.Waterland@Sun.COM 		/*
802*9781SMoriah.Waterland@Sun.COM 		 * Public interface: Specify an alternative fs_file to map
803*9781SMoriah.Waterland@Sun.COM 		 * the client's file systems.  For example, used in
804*9781SMoriah.Waterland@Sun.COM 		 * situations where the $root_path/etc/vfstab file is
805*9781SMoriah.Waterland@Sun.COM 		 * non-existent or unreliable. Informs the pkginstall
806*9781SMoriah.Waterland@Sun.COM 		 * portion to mount up a client filesystem based upon the
807*9781SMoriah.Waterland@Sun.COM 		 * supplied vfstab-like file of stable format.
808*9781SMoriah.Waterland@Sun.COM 		 */
809*9781SMoriah.Waterland@Sun.COM 		case 'V':
810*9781SMoriah.Waterland@Sun.COM 			vfstab_file = flex_device(optarg, 2);
811*9781SMoriah.Waterland@Sun.COM 			no_map_client = 0;
812*9781SMoriah.Waterland@Sun.COM 			break;
813*9781SMoriah.Waterland@Sun.COM 
814*9781SMoriah.Waterland@Sun.COM 		/*
815*9781SMoriah.Waterland@Sun.COM 		 * Public interface: Trace all of the scripts that get
816*9781SMoriah.Waterland@Sun.COM 		 * executed by pkgadd, located in the pkginst/install
817*9781SMoriah.Waterland@Sun.COM 		 * directory. This option is used for debugging the
818*9781SMoriah.Waterland@Sun.COM 		 * procedural and non-procedural scripts
819*9781SMoriah.Waterland@Sun.COM 		 */
820*9781SMoriah.Waterland@Sun.COM 		case 'v':
821*9781SMoriah.Waterland@Sun.COM 			pkgverbose++;
822*9781SMoriah.Waterland@Sun.COM 			break;
823*9781SMoriah.Waterland@Sun.COM 
824*9781SMoriah.Waterland@Sun.COM 		/*
825*9781SMoriah.Waterland@Sun.COM 		 * Public interface: Specify a HTTP[S] proxy to use when
826*9781SMoriah.Waterland@Sun.COM 		 * downloading packages The format of proxy is host:port,
827*9781SMoriah.Waterland@Sun.COM 		 * where host is the hostname of the HTTP[S] proxy, and
828*9781SMoriah.Waterland@Sun.COM 		 * port is the port number associated with the proxy. This
829*9781SMoriah.Waterland@Sun.COM 		 * switch overrides all other methods of specifying a
830*9781SMoriah.Waterland@Sun.COM 		 * proxy. See ENVIRONMENT VARIABLES for more information
831*9781SMoriah.Waterland@Sun.COM 		 * on alternate methods of specifying a default proxy.
832*9781SMoriah.Waterland@Sun.COM 		 */
833*9781SMoriah.Waterland@Sun.COM 		case 'x':
834*9781SMoriah.Waterland@Sun.COM 			if (!path_valid(optarg)) {
835*9781SMoriah.Waterland@Sun.COM 				progerr(ERR_PATH, optarg);
836*9781SMoriah.Waterland@Sun.COM 				quit(1);
837*9781SMoriah.Waterland@Sun.COM 				/* NOTREACHED */
838*9781SMoriah.Waterland@Sun.COM 			}
839*9781SMoriah.Waterland@Sun.COM 			proxy = optarg;
840*9781SMoriah.Waterland@Sun.COM 			break;
841*9781SMoriah.Waterland@Sun.COM 
842*9781SMoriah.Waterland@Sun.COM 		/*
843*9781SMoriah.Waterland@Sun.COM 		 * Public interface: Install packages based on the value
844*9781SMoriah.Waterland@Sun.COM 		 * of the CATEGORY parameter stored in the package's
845*9781SMoriah.Waterland@Sun.COM 		 * pkginfo(4) file. All packages on the source medium
846*9781SMoriah.Waterland@Sun.COM 		 * whose CATEGORY matches one of the specified categories
847*9781SMoriah.Waterland@Sun.COM 		 * will be selected for installation or spooling. Install
848*9781SMoriah.Waterland@Sun.COM 		 * packages that contain the same CATEGORY as the one
849*9781SMoriah.Waterland@Sun.COM 		 * provided on the command line.
850*9781SMoriah.Waterland@Sun.COM 		 */
851*9781SMoriah.Waterland@Sun.COM 		case 'Y':
852*9781SMoriah.Waterland@Sun.COM 			if (optarg[0] == '-') {
853*9781SMoriah.Waterland@Sun.COM 				usage();
854*9781SMoriah.Waterland@Sun.COM 				quit(1);
855*9781SMoriah.Waterland@Sun.COM 			}
856*9781SMoriah.Waterland@Sun.COM 			catg_arg = strdup(optarg);
857*9781SMoriah.Waterland@Sun.COM 
858*9781SMoriah.Waterland@Sun.COM 			if ((category = get_categories(catg_arg)) == NULL) {
859*9781SMoriah.Waterland@Sun.COM 				progerr(ERR_CAT_INV, catg_arg);
860*9781SMoriah.Waterland@Sun.COM 				exit(1);
861*9781SMoriah.Waterland@Sun.COM 			} else if (is_not_valid_length(category)) {
862*9781SMoriah.Waterland@Sun.COM 				progerr(ERR_CAT_LNGTH);
863*9781SMoriah.Waterland@Sun.COM 				exit(1);
864*9781SMoriah.Waterland@Sun.COM 			}
865*9781SMoriah.Waterland@Sun.COM 			break;
866*9781SMoriah.Waterland@Sun.COM 
867*9781SMoriah.Waterland@Sun.COM 		/*
868*9781SMoriah.Waterland@Sun.COM 		 * Not a public interface: perform fresh install from
869*9781SMoriah.Waterland@Sun.COM 		 * package save spool area. When set, the package contents
870*9781SMoriah.Waterland@Sun.COM 		 * are installed from the package spool save area instead
871*9781SMoriah.Waterland@Sun.COM 		 * of from the package root area, so that the original
872*9781SMoriah.Waterland@Sun.COM 		 * source packages are not required to install the
873*9781SMoriah.Waterland@Sun.COM 		 * package. If the -h option is also specified and the
874*9781SMoriah.Waterland@Sun.COM 		 * package is hollow, then this option is ignored. When -z
875*9781SMoriah.Waterland@Sun.COM 		 * is specified:
876*9781SMoriah.Waterland@Sun.COM 		 *  - Editable files are installed from the package instance
877*9781SMoriah.Waterland@Sun.COM 		 *    save area.
878*9781SMoriah.Waterland@Sun.COM 		 *  - Volatile files are installed from the package instance
879*9781SMoriah.Waterland@Sun.COM 		 *    save area.
880*9781SMoriah.Waterland@Sun.COM 		 *  - Executable and data files are installed from the final
881*9781SMoriah.Waterland@Sun.COM 		 *    installed location as specified in the pkgmap file.
882*9781SMoriah.Waterland@Sun.COM 		 *  - Installation scripts are run from the package spool
883*9781SMoriah.Waterland@Sun.COM 		 *    save area.
884*9781SMoriah.Waterland@Sun.COM 		 */
885*9781SMoriah.Waterland@Sun.COM 		case 'z':
886*9781SMoriah.Waterland@Sun.COM 			saveSpoolInstall++;
887*9781SMoriah.Waterland@Sun.COM 			break;
888*9781SMoriah.Waterland@Sun.COM 
889*9781SMoriah.Waterland@Sun.COM 		/*
890*9781SMoriah.Waterland@Sun.COM 		 * unrecognized option
891*9781SMoriah.Waterland@Sun.COM 		 */
892*9781SMoriah.Waterland@Sun.COM 
893*9781SMoriah.Waterland@Sun.COM 		default:
894*9781SMoriah.Waterland@Sun.COM 			usage();
895*9781SMoriah.Waterland@Sun.COM 			return (1);
896*9781SMoriah.Waterland@Sun.COM 		}
897*9781SMoriah.Waterland@Sun.COM 	}
898*9781SMoriah.Waterland@Sun.COM 
899*9781SMoriah.Waterland@Sun.COM 	/*
900*9781SMoriah.Waterland@Sun.COM 	 * ********************************************************************
901*9781SMoriah.Waterland@Sun.COM 	 * validate command line options
902*9781SMoriah.Waterland@Sun.COM 	 * ********************************************************************
903*9781SMoriah.Waterland@Sun.COM 	 */
904*9781SMoriah.Waterland@Sun.COM 
905*9781SMoriah.Waterland@Sun.COM 	/* set "debug echo" flag according to setting of "-O debug" option */
906*9781SMoriah.Waterland@Sun.COM 
907*9781SMoriah.Waterland@Sun.COM 	(void) echoDebugSetFlag(debugFlag);
908*9781SMoriah.Waterland@Sun.COM 
909*9781SMoriah.Waterland@Sun.COM 	/* output entry debugging information */
910*9781SMoriah.Waterland@Sun.COM 
911*9781SMoriah.Waterland@Sun.COM 	if (z_running_in_global_zone()) {
912*9781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_ENTRY_IN_GZ, prog_full_name);
913*9781SMoriah.Waterland@Sun.COM 	} else {
914*9781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_ENTRY_IN_LZ, prog_full_name, getzoneid(),
915*9781SMoriah.Waterland@Sun.COM 			z_get_zonename());
916*9781SMoriah.Waterland@Sun.COM 	}
917*9781SMoriah.Waterland@Sun.COM 
918*9781SMoriah.Waterland@Sun.COM 	/*
919*9781SMoriah.Waterland@Sun.COM 	 * Later, it may be decided to pursue this ability to continue to an
920*9781SMoriah.Waterland@Sun.COM 	 * actual installation based only on the dryrun data. At this time,
921*9781SMoriah.Waterland@Sun.COM 	 * it is too risky.
922*9781SMoriah.Waterland@Sun.COM 	 */
923*9781SMoriah.Waterland@Sun.COM 
924*9781SMoriah.Waterland@Sun.COM 	if (pkgcontsrc && !pkgdrtarg) {
925*9781SMoriah.Waterland@Sun.COM 		progerr(ERR_NO_LIVE_MODE);
926*9781SMoriah.Waterland@Sun.COM 		usage();
927*9781SMoriah.Waterland@Sun.COM 		return (1);
928*9781SMoriah.Waterland@Sun.COM 	}
929*9781SMoriah.Waterland@Sun.COM 
930*9781SMoriah.Waterland@Sun.COM 	/* ignore -G option if not used in the global zone */
931*9781SMoriah.Waterland@Sun.COM 
932*9781SMoriah.Waterland@Sun.COM 	if (!z_running_in_global_zone()) {
933*9781SMoriah.Waterland@Sun.COM 		globalZoneOnly = B_FALSE;
934*9781SMoriah.Waterland@Sun.COM 	}
935*9781SMoriah.Waterland@Sun.COM 
936*9781SMoriah.Waterland@Sun.COM 	/* if zonelist used, must be in global zone */
937*9781SMoriah.Waterland@Sun.COM 
938*9781SMoriah.Waterland@Sun.COM 	if (usedZoneList && !z_running_in_global_zone()) {
939*9781SMoriah.Waterland@Sun.COM 		progerr(ERR_Z_USED_IN_NONGLOBAL_ZONE);
940*9781SMoriah.Waterland@Sun.COM 		return (1);
941*9781SMoriah.Waterland@Sun.COM 	}
942*9781SMoriah.Waterland@Sun.COM 
943*9781SMoriah.Waterland@Sun.COM 	/* -G and zonelist cannot be used together */
944*9781SMoriah.Waterland@Sun.COM 
945*9781SMoriah.Waterland@Sun.COM 	if (globalZoneOnly && usedZoneList) {
946*9781SMoriah.Waterland@Sun.COM 		progerr(ERR_GZ_USED_TOGETHER);
947*9781SMoriah.Waterland@Sun.COM 		usage();
948*9781SMoriah.Waterland@Sun.COM 		return (1);
949*9781SMoriah.Waterland@Sun.COM 	}
950*9781SMoriah.Waterland@Sun.COM 
951*9781SMoriah.Waterland@Sun.COM 	/* -s cannot be used with either -G or zonelist */
952*9781SMoriah.Waterland@Sun.COM 
953*9781SMoriah.Waterland@Sun.COM 	if (spoolDir != NULL) {
954*9781SMoriah.Waterland@Sun.COM 		if (globalZoneOnly) {
955*9781SMoriah.Waterland@Sun.COM 			progerr(ERR_SPOOLDIR_USED_WITH_G);
956*9781SMoriah.Waterland@Sun.COM 			usage();
957*9781SMoriah.Waterland@Sun.COM 			return (1);
958*9781SMoriah.Waterland@Sun.COM 		}
959*9781SMoriah.Waterland@Sun.COM 		if (usedZoneList) {
960*9781SMoriah.Waterland@Sun.COM 			progerr(ERR_SPOOLDIR_USED_WITH_Z);
961*9781SMoriah.Waterland@Sun.COM 			usage();
962*9781SMoriah.Waterland@Sun.COM 			return (1);
963*9781SMoriah.Waterland@Sun.COM 		}
964*9781SMoriah.Waterland@Sun.COM 		if (strcmp(spoolDir, "/var/sadm/pkg") == 0) {
965*9781SMoriah.Waterland@Sun.COM 			progerr(ERR_SPOOLDIR_CANNOT_BE_SYS, "/var/sadm/pkg");
966*9781SMoriah.Waterland@Sun.COM 			usage();
967*9781SMoriah.Waterland@Sun.COM 			return (1);
968*9781SMoriah.Waterland@Sun.COM 		}
969*9781SMoriah.Waterland@Sun.COM 	}
970*9781SMoriah.Waterland@Sun.COM 
971*9781SMoriah.Waterland@Sun.COM 	/* pkgask does not support the same options as pkgadd */
972*9781SMoriah.Waterland@Sun.COM 
973*9781SMoriah.Waterland@Sun.COM 	if (askflag && proxy) {
974*9781SMoriah.Waterland@Sun.COM 		progerr(ERR_PKGASK_AND_PROXY);
975*9781SMoriah.Waterland@Sun.COM 		usage();
976*9781SMoriah.Waterland@Sun.COM 		return (1);
977*9781SMoriah.Waterland@Sun.COM 	}
978*9781SMoriah.Waterland@Sun.COM 
979*9781SMoriah.Waterland@Sun.COM 	if (askflag && uri) {
980*9781SMoriah.Waterland@Sun.COM 		progerr(ERR_PKGASK_AND_URI);
981*9781SMoriah.Waterland@Sun.COM 		usage();
982*9781SMoriah.Waterland@Sun.COM 		return (1);
983*9781SMoriah.Waterland@Sun.COM 	}
984*9781SMoriah.Waterland@Sun.COM 
985*9781SMoriah.Waterland@Sun.COM 	if (askflag && keystore_file) {
986*9781SMoriah.Waterland@Sun.COM 		progerr(ERR_PKGASK_AND_KEYSTORE_FILE);
987*9781SMoriah.Waterland@Sun.COM 		usage();
988*9781SMoriah.Waterland@Sun.COM 		return (1);
989*9781SMoriah.Waterland@Sun.COM 	}
990*9781SMoriah.Waterland@Sun.COM 
991*9781SMoriah.Waterland@Sun.COM 	if (askflag && ignore_sig) {
992*9781SMoriah.Waterland@Sun.COM 		progerr(ERR_PKGASK_AND_IGNORE_SIG);
993*9781SMoriah.Waterland@Sun.COM 		usage();
994*9781SMoriah.Waterland@Sun.COM 		return (1);
995*9781SMoriah.Waterland@Sun.COM 	}
996*9781SMoriah.Waterland@Sun.COM 
997*9781SMoriah.Waterland@Sun.COM 	if (askflag && spoolDir) {
998*9781SMoriah.Waterland@Sun.COM 		progerr(ERR_PKGASK_AND_SPOOLDIR);
999*9781SMoriah.Waterland@Sun.COM 		usage();
1000*9781SMoriah.Waterland@Sun.COM 		return (1);
1001*9781SMoriah.Waterland@Sun.COM 	}
1002*9781SMoriah.Waterland@Sun.COM 
1003*9781SMoriah.Waterland@Sun.COM 	if (askflag && nointeract) {
1004*9781SMoriah.Waterland@Sun.COM 		progerr(ERR_PKGASK_AND_NOINTERACT);
1005*9781SMoriah.Waterland@Sun.COM 		usage();
1006*9781SMoriah.Waterland@Sun.COM 		return (1);
1007*9781SMoriah.Waterland@Sun.COM 	}
1008*9781SMoriah.Waterland@Sun.COM 
1009*9781SMoriah.Waterland@Sun.COM 	/* cannot use response file and web address together */
1010*9781SMoriah.Waterland@Sun.COM 
1011*9781SMoriah.Waterland@Sun.COM 	if (respfile && uri) {
1012*9781SMoriah.Waterland@Sun.COM 		progerr(ERR_RESPFILE_AND_URI);
1013*9781SMoriah.Waterland@Sun.COM 		usage();
1014*9781SMoriah.Waterland@Sun.COM 		return (1);
1015*9781SMoriah.Waterland@Sun.COM 	}
1016*9781SMoriah.Waterland@Sun.COM 
1017*9781SMoriah.Waterland@Sun.COM 	/* cannot use response file/not-interactive and spool-to directory */
1018*9781SMoriah.Waterland@Sun.COM 
1019*9781SMoriah.Waterland@Sun.COM 	if (spoolDir && nointeract) {
1020*9781SMoriah.Waterland@Sun.COM 		progerr(ERR_SPOOLDIR_AND_NOINTERACT);
1021*9781SMoriah.Waterland@Sun.COM 		usage();
1022*9781SMoriah.Waterland@Sun.COM 		return (1);
1023*9781SMoriah.Waterland@Sun.COM 	}
1024*9781SMoriah.Waterland@Sun.COM 
1025*9781SMoriah.Waterland@Sun.COM 	if (spoolDir && respfile) {
1026*9781SMoriah.Waterland@Sun.COM 		progerr(ERR_SPOOLDIR_AND_RESPFILE);
1027*9781SMoriah.Waterland@Sun.COM 		usage();
1028*9781SMoriah.Waterland@Sun.COM 		return (1);
1029*9781SMoriah.Waterland@Sun.COM 	}
1030*9781SMoriah.Waterland@Sun.COM 
1031*9781SMoriah.Waterland@Sun.COM 	if (usedZoneList) {
1032*9781SMoriah.Waterland@Sun.COM 		/* Verify supplied zone list valid for the target */
1033*9781SMoriah.Waterland@Sun.COM 		if (z_verify_zone_spec() == -1)
1034*9781SMoriah.Waterland@Sun.COM 			return (1);
1035*9781SMoriah.Waterland@Sun.COM 
1036*9781SMoriah.Waterland@Sun.COM 		/* -z zonelist=global is logically the same as -G */
1037*9781SMoriah.Waterland@Sun.COM 		if (z_global_only() && z_running_in_global_zone())
1038*9781SMoriah.Waterland@Sun.COM 			globalZoneOnly = B_TRUE;
1039*9781SMoriah.Waterland@Sun.COM 	}
1040*9781SMoriah.Waterland@Sun.COM 
1041*9781SMoriah.Waterland@Sun.COM 	/*
1042*9781SMoriah.Waterland@Sun.COM 	 * hook SIGINT and SIGHUP interrupts into quit.c's trap handler
1043*9781SMoriah.Waterland@Sun.COM 	 */
1044*9781SMoriah.Waterland@Sun.COM 
1045*9781SMoriah.Waterland@Sun.COM 	/* hold SIGINT/SIGHUP interrupts */
1046*9781SMoriah.Waterland@Sun.COM 
1047*9781SMoriah.Waterland@Sun.COM 	(void) sighold(SIGHUP);
1048*9781SMoriah.Waterland@Sun.COM 	(void) sighold(SIGINT);
1049*9781SMoriah.Waterland@Sun.COM 
1050*9781SMoriah.Waterland@Sun.COM 	/* connect quit.c:trap() to SIGINT */
1051*9781SMoriah.Waterland@Sun.COM 
1052*9781SMoriah.Waterland@Sun.COM 	nact.sa_handler = quitGetTrapHandler();
1053*9781SMoriah.Waterland@Sun.COM 	nact.sa_flags = SA_RESTART;
1054*9781SMoriah.Waterland@Sun.COM 	(void) sigemptyset(&nact.sa_mask);
1055*9781SMoriah.Waterland@Sun.COM 
1056*9781SMoriah.Waterland@Sun.COM 	(void) sigaction(SIGINT, &nact, &oact);
1057*9781SMoriah.Waterland@Sun.COM 
1058*9781SMoriah.Waterland@Sun.COM 	/* connect quit.c:trap() to SIGHUP */
1059*9781SMoriah.Waterland@Sun.COM 
1060*9781SMoriah.Waterland@Sun.COM 	nact.sa_handler = quitGetTrapHandler();
1061*9781SMoriah.Waterland@Sun.COM 	nact.sa_flags = SA_RESTART;
1062*9781SMoriah.Waterland@Sun.COM 	(void) sigemptyset(&nact.sa_mask);
1063*9781SMoriah.Waterland@Sun.COM 
1064*9781SMoriah.Waterland@Sun.COM 	(void) sigaction(SIGHUP, &nact, &oact);
1065*9781SMoriah.Waterland@Sun.COM 
1066*9781SMoriah.Waterland@Sun.COM 	/* release hold on signals */
1067*9781SMoriah.Waterland@Sun.COM 
1068*9781SMoriah.Waterland@Sun.COM 	(void) sigrelse(SIGHUP);
1069*9781SMoriah.Waterland@Sun.COM 	(void) sigrelse(SIGINT);
1070*9781SMoriah.Waterland@Sun.COM 
1071*9781SMoriah.Waterland@Sun.COM 	/*
1072*9781SMoriah.Waterland@Sun.COM 	 * This function is in the libadm library; it sets:
1073*9781SMoriah.Waterland@Sun.COM 	 * -> get_PKGLOC() = <install_root>/var/sadm/pkg
1074*9781SMoriah.Waterland@Sun.COM 	 * -> get_PKGOLD() = <install_root>/usr/options
1075*9781SMoriah.Waterland@Sun.COM 	 * -> get_PKGADM() = <install_root>/var/sadm/install
1076*9781SMoriah.Waterland@Sun.COM 	 * -> pkgdir = <install_root>/var/sadm/pkg
1077*9781SMoriah.Waterland@Sun.COM 	 * -> pkg_install_root = <install_root>
1078*9781SMoriah.Waterland@Sun.COM 	 * This controls operations of libadm functions such as:
1079*9781SMoriah.Waterland@Sun.COM 	 * -> pkginfofind, pkginfopen, fpkgparam, pkgparam, get_PKGLOC,
1080*9781SMoriah.Waterland@Sun.COM 	 * -> get_PKGOLD, get_PKGADM, get_install_root
1081*9781SMoriah.Waterland@Sun.COM 	 */
1082*9781SMoriah.Waterland@Sun.COM 
1083*9781SMoriah.Waterland@Sun.COM 	set_PKGpaths(get_inst_root());
1084*9781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_PKGADD_PKGPATHS,
1085*9781SMoriah.Waterland@Sun.COM 		get_PKGLOC() ? get_PKGLOC() : "",
1086*9781SMoriah.Waterland@Sun.COM 		get_PKGADM() ? get_PKGADM() : "");
1087*9781SMoriah.Waterland@Sun.COM 
1088*9781SMoriah.Waterland@Sun.COM 	/*
1089*9781SMoriah.Waterland@Sun.COM 	 * This function is in the libinst library; it reads the specified
1090*9781SMoriah.Waterland@Sun.COM 	 * admin(4) file and, using fpkgparam(), sets the global "adm" structure
1091*9781SMoriah.Waterland@Sun.COM 	 * values to match what is in the specified admin file.
1092*9781SMoriah.Waterland@Sun.COM 	 */
1093*9781SMoriah.Waterland@Sun.COM 
1094*9781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_PKGADD_ADMINFILE, admnfile ? admnfile : "");
1095*9781SMoriah.Waterland@Sun.COM 	setadminFile(admnfile);
1096*9781SMoriah.Waterland@Sun.COM 
1097*9781SMoriah.Waterland@Sun.COM 	/*
1098*9781SMoriah.Waterland@Sun.COM 	 * if running in the global zone, and non-global zones exist, then
1099*9781SMoriah.Waterland@Sun.COM 	 * enable hollow package support so that any packages that are marked
1100*9781SMoriah.Waterland@Sun.COM 	 * SUNW_PKG_HOLLOW=true will be correctly installed in non-global zones
1101*9781SMoriah.Waterland@Sun.COM 	 * when added directly in the global zone by the global zone admin.
1102*9781SMoriah.Waterland@Sun.COM 	 */
1103*9781SMoriah.Waterland@Sun.COM 
1104*9781SMoriah.Waterland@Sun.COM 	if (is_depend_pkginfo_DB()) {
1105*9781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_PKGADD_HOLLOW_ENABLED);
1106*9781SMoriah.Waterland@Sun.COM 	} else if ((z_running_in_global_zone() == B_TRUE) &&
1107*9781SMoriah.Waterland@Sun.COM 		(z_non_global_zones_exist() == B_TRUE)) {
1108*9781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_PKGADD_ENABLING_HOLLOW);
1109*9781SMoriah.Waterland@Sun.COM 		set_depend_pkginfo_DB(B_TRUE);
1110*9781SMoriah.Waterland@Sun.COM 	}
1111*9781SMoriah.Waterland@Sun.COM 
1112*9781SMoriah.Waterland@Sun.COM 	/* if no device and no url, get and validate default device */
1113*9781SMoriah.Waterland@Sun.COM 
1114*9781SMoriah.Waterland@Sun.COM 	if ((device == NULL) && (uri == NULL)) {
1115*9781SMoriah.Waterland@Sun.COM 		device = devattr("spool", "pathname");
1116*9781SMoriah.Waterland@Sun.COM 		if (device == NULL) {
1117*9781SMoriah.Waterland@Sun.COM 			progerr(ERR_NODEVICE);
1118*9781SMoriah.Waterland@Sun.COM 			quit(1);
1119*9781SMoriah.Waterland@Sun.COM 			/* NOTREACHED */
1120*9781SMoriah.Waterland@Sun.COM 		}
1121*9781SMoriah.Waterland@Sun.COM 	}
1122*9781SMoriah.Waterland@Sun.COM 
1123*9781SMoriah.Waterland@Sun.COM 	/* must be root if not directing results to spool directory */
1124*9781SMoriah.Waterland@Sun.COM 
1125*9781SMoriah.Waterland@Sun.COM 	if ((getuid() != 0) && (spoolDir == NULL)) {
1126*9781SMoriah.Waterland@Sun.COM 		progerr(ERR_NOT_ROOT, prog);
1127*9781SMoriah.Waterland@Sun.COM 		exit(1);
1128*9781SMoriah.Waterland@Sun.COM 	}
1129*9781SMoriah.Waterland@Sun.COM 
1130*9781SMoriah.Waterland@Sun.COM 	/*
1131*9781SMoriah.Waterland@Sun.COM 	 * process response file argument
1132*9781SMoriah.Waterland@Sun.COM 	 */
1133*9781SMoriah.Waterland@Sun.COM 
1134*9781SMoriah.Waterland@Sun.COM 	if (respfile) {
1135*9781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_PKGADD_RESPFILE,
1136*9781SMoriah.Waterland@Sun.COM 			respfile, respdir ? respdir : "");
1137*9781SMoriah.Waterland@Sun.COM 
1138*9781SMoriah.Waterland@Sun.COM 		if (respfile[0] != '/') {
1139*9781SMoriah.Waterland@Sun.COM 			progerr(ERR_RSP_FILE_NOTFULLPATH, respfile);
1140*9781SMoriah.Waterland@Sun.COM 			quit(1);
1141*9781SMoriah.Waterland@Sun.COM 			/* NOTREACHED */
1142*9781SMoriah.Waterland@Sun.COM 		}
1143*9781SMoriah.Waterland@Sun.COM 		if (respdir == NULL) {
1144*9781SMoriah.Waterland@Sun.COM 			if (askflag) {
1145*9781SMoriah.Waterland@Sun.COM 				if (access(respfile, F_OK) == 0) {
1146*9781SMoriah.Waterland@Sun.COM 					progerr(ERR_NORESP, respfile);
1147*9781SMoriah.Waterland@Sun.COM 					quit(1);
1148*9781SMoriah.Waterland@Sun.COM 					/* NOTREACHED */
1149*9781SMoriah.Waterland@Sun.COM 				}
1150*9781SMoriah.Waterland@Sun.COM 			} else if (access(respfile, F_OK) != 0) {
1151*9781SMoriah.Waterland@Sun.COM 				progerr(ERR_ACCRESP, respfile);
1152*9781SMoriah.Waterland@Sun.COM 				quit(1);
1153*9781SMoriah.Waterland@Sun.COM 				/* NOTREACHED */
1154*9781SMoriah.Waterland@Sun.COM 			}
1155*9781SMoriah.Waterland@Sun.COM 		}
1156*9781SMoriah.Waterland@Sun.COM 	} else if (askflag) {
1157*9781SMoriah.Waterland@Sun.COM 		progerr(ERR_RSP_FILE_NOT_GIVEN);
1158*9781SMoriah.Waterland@Sun.COM 		usage();
1159*9781SMoriah.Waterland@Sun.COM 		quit(1);
1160*9781SMoriah.Waterland@Sun.COM 		/* NOTREACHED */
1161*9781SMoriah.Waterland@Sun.COM 	}
1162*9781SMoriah.Waterland@Sun.COM 
1163*9781SMoriah.Waterland@Sun.COM 	/* establish temporary directory to use */
1164*9781SMoriah.Waterland@Sun.COM 
1165*9781SMoriah.Waterland@Sun.COM 	if ((tmpdir = getenv("TMPDIR")) == NULL) {
1166*9781SMoriah.Waterland@Sun.COM 		/* use default - no override specified */
1167*9781SMoriah.Waterland@Sun.COM 		tmpdir = P_tmpdir;
1168*9781SMoriah.Waterland@Sun.COM 	}
1169*9781SMoriah.Waterland@Sun.COM 
1170*9781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_PKGADD_TMPDIR, tmpdir);
1171*9781SMoriah.Waterland@Sun.COM 
1172*9781SMoriah.Waterland@Sun.COM 	/*
1173*9781SMoriah.Waterland@Sun.COM 	 * setup and prepare secure package operations
1174*9781SMoriah.Waterland@Sun.COM 	 */
1175*9781SMoriah.Waterland@Sun.COM 
1176*9781SMoriah.Waterland@Sun.COM 	/* initialize error object used by security functions */
1177*9781SMoriah.Waterland@Sun.COM 
1178*9781SMoriah.Waterland@Sun.COM 	err = pkgerr_new();
1179*9781SMoriah.Waterland@Sun.COM 
1180*9781SMoriah.Waterland@Sun.COM 	/* validate keystore file */
1181*9781SMoriah.Waterland@Sun.COM 
1182*9781SMoriah.Waterland@Sun.COM 	if (!check_keystore_admin(&keystore_file)) {
1183*9781SMoriah.Waterland@Sun.COM 		progerr(ERR_ADM_KEYSTORE);
1184*9781SMoriah.Waterland@Sun.COM 		quit(1);
1185*9781SMoriah.Waterland@Sun.COM 		/* NOTREACHED */
1186*9781SMoriah.Waterland@Sun.COM 	}
1187*9781SMoriah.Waterland@Sun.COM 
1188*9781SMoriah.Waterland@Sun.COM 	/* if uri provided, establish session */
1189*9781SMoriah.Waterland@Sun.COM 
1190*9781SMoriah.Waterland@Sun.COM 	if (uri != NULL) {
1191*9781SMoriah.Waterland@Sun.COM 		boolean_t	b;
1192*9781SMoriah.Waterland@Sun.COM 		int		len;
1193*9781SMoriah.Waterland@Sun.COM 		char		*bname = (char *)NULL;
1194*9781SMoriah.Waterland@Sun.COM 
1195*9781SMoriah.Waterland@Sun.COM 		set_web_install();
1196*9781SMoriah.Waterland@Sun.COM 
1197*9781SMoriah.Waterland@Sun.COM 		if (!get_proxy_port(err, &proxy, &proxy_port)) {
1198*9781SMoriah.Waterland@Sun.COM 			pkgerr(err);
1199*9781SMoriah.Waterland@Sun.COM 			quit(1);
1200*9781SMoriah.Waterland@Sun.COM 			/* NOTREACHED */
1201*9781SMoriah.Waterland@Sun.COM 		}
1202*9781SMoriah.Waterland@Sun.COM 
1203*9781SMoriah.Waterland@Sun.COM 		if (proxy == NULL) {
1204*9781SMoriah.Waterland@Sun.COM 			if (!get_proxy_port_admin(&proxy, &proxy_port)) {
1205*9781SMoriah.Waterland@Sun.COM 				progerr(ERR_ADM_PROXY);
1206*9781SMoriah.Waterland@Sun.COM 				quit(1);
1207*9781SMoriah.Waterland@Sun.COM 				/* NOTREACHED */
1208*9781SMoriah.Waterland@Sun.COM 			}
1209*9781SMoriah.Waterland@Sun.COM 		}
1210*9781SMoriah.Waterland@Sun.COM 
1211*9781SMoriah.Waterland@Sun.COM 		if ((retries = web_ck_retries()) == 0) {
1212*9781SMoriah.Waterland@Sun.COM 			pkgerr(err);
1213*9781SMoriah.Waterland@Sun.COM 			quit(1);
1214*9781SMoriah.Waterland@Sun.COM 			/* NOTREACHED */
1215*9781SMoriah.Waterland@Sun.COM 		}
1216*9781SMoriah.Waterland@Sun.COM 
1217*9781SMoriah.Waterland@Sun.COM 		if ((timeout = web_ck_timeout()) == 0) {
1218*9781SMoriah.Waterland@Sun.COM 			pkgerr(err);
1219*9781SMoriah.Waterland@Sun.COM 			quit(1);
1220*9781SMoriah.Waterland@Sun.COM 			/* NOTREACHED */
1221*9781SMoriah.Waterland@Sun.COM 		}
1222*9781SMoriah.Waterland@Sun.COM 
1223*9781SMoriah.Waterland@Sun.COM 		/* create temporary directory */
1224*9781SMoriah.Waterland@Sun.COM 
1225*9781SMoriah.Waterland@Sun.COM 		b = setup_temporary_directory(&dwnld_dir, tmpdir, "dwnld");
1226*9781SMoriah.Waterland@Sun.COM 		if (b != B_TRUE) {
1227*9781SMoriah.Waterland@Sun.COM 			progerr(ERR_DWNLDTEMPDIR, tmpdir, strerror(errno));
1228*9781SMoriah.Waterland@Sun.COM 			quit(1);
1229*9781SMoriah.Waterland@Sun.COM 			/* NOTREACHED */
1230*9781SMoriah.Waterland@Sun.COM 		}
1231*9781SMoriah.Waterland@Sun.COM 		canonize_slashes(dwnld_dir);
1232*9781SMoriah.Waterland@Sun.COM 
1233*9781SMoriah.Waterland@Sun.COM 		/* register with quit() so directory is removed on exit */
1234*9781SMoriah.Waterland@Sun.COM 
1235*9781SMoriah.Waterland@Sun.COM 		quitSetDwnldTmpdir(dwnld_dir);	/* DO NOT FREE() */
1236*9781SMoriah.Waterland@Sun.COM 
1237*9781SMoriah.Waterland@Sun.COM 		/* open keystore if this is a secure download */
1238*9781SMoriah.Waterland@Sun.COM 		if (scheme == web_https) {
1239*9781SMoriah.Waterland@Sun.COM 			if (open_keystore(err, keystore_file,
1240*9781SMoriah.Waterland@Sun.COM 			    get_prog_name(),  pkg_passphrase_cb,
1241*9781SMoriah.Waterland@Sun.COM 			    KEYSTORE_DFLT_FLAGS, &keystore) != 0) {
1242*9781SMoriah.Waterland@Sun.COM 				pkgerr(err);
1243*9781SMoriah.Waterland@Sun.COM 				web_cleanup();
1244*9781SMoriah.Waterland@Sun.COM 				quit(1);
1245*9781SMoriah.Waterland@Sun.COM 				/* NOTREACHED */
1246*9781SMoriah.Waterland@Sun.COM 			}
1247*9781SMoriah.Waterland@Sun.COM 		}
1248*9781SMoriah.Waterland@Sun.COM 
1249*9781SMoriah.Waterland@Sun.COM 		if (!web_session_control(err, uri, dwnld_dir, keystore, proxy,
1250*9781SMoriah.Waterland@Sun.COM 			proxy_port, retries, timeout, nointeract, &bname)) {
1251*9781SMoriah.Waterland@Sun.COM 			pkgerr(err);
1252*9781SMoriah.Waterland@Sun.COM 			web_cleanup();
1253*9781SMoriah.Waterland@Sun.COM 			quit(1);
1254*9781SMoriah.Waterland@Sun.COM 			/* NOTREACHED */
1255*9781SMoriah.Waterland@Sun.COM 		}
1256*9781SMoriah.Waterland@Sun.COM 
1257*9781SMoriah.Waterland@Sun.COM 		/*
1258*9781SMoriah.Waterland@Sun.COM 		 * reset device to point to newly-downloaded file; note
1259*9781SMoriah.Waterland@Sun.COM 		 * when (scheme == web_https || scheme == web_http) that
1260*9781SMoriah.Waterland@Sun.COM 		 * device gets preloaded with a pointer to PATH_MAX bytes
1261*9781SMoriah.Waterland@Sun.COM 		 * allocated via malloc().
1262*9781SMoriah.Waterland@Sun.COM 		 */
1263*9781SMoriah.Waterland@Sun.COM 
1264*9781SMoriah.Waterland@Sun.COM 		len = snprintf(device, PATH_MAX, "%s/%s", dwnld_dir, bname);
1265*9781SMoriah.Waterland@Sun.COM 		if ((len < 0) || (len >= PATH_MAX)) {
1266*9781SMoriah.Waterland@Sun.COM 			progerr(ERR_DIR_CONST, tmpdir);
1267*9781SMoriah.Waterland@Sun.COM 			quit(1);
1268*9781SMoriah.Waterland@Sun.COM 			/* NOTREACHED */
1269*9781SMoriah.Waterland@Sun.COM 		}
1270*9781SMoriah.Waterland@Sun.COM 	}
1271*9781SMoriah.Waterland@Sun.COM 
1272*9781SMoriah.Waterland@Sun.COM 	/*
1273*9781SMoriah.Waterland@Sun.COM 	 * See if user wants this to be handled as an old style pkg.
1274*9781SMoriah.Waterland@Sun.COM 	 * NOTE : the ``exception_pkg()'' stuff is to be used only
1275*9781SMoriah.Waterland@Sun.COM 	 * through on495. This function comes out for on1095. See
1276*9781SMoriah.Waterland@Sun.COM 	 * PSARC 1993-546. -- JST
1277*9781SMoriah.Waterland@Sun.COM 	 */
1278*9781SMoriah.Waterland@Sun.COM 
1279*9781SMoriah.Waterland@Sun.COM 	if (getenv("NONABI_SCRIPTS") != NULL) {
1280*9781SMoriah.Waterland@Sun.COM 		old_pkg = 1;
1281*9781SMoriah.Waterland@Sun.COM 	}
1282*9781SMoriah.Waterland@Sun.COM 
1283*9781SMoriah.Waterland@Sun.COM 	/*
1284*9781SMoriah.Waterland@Sun.COM 	 * See if the user wants to process symlinks consistent with
1285*9781SMoriah.Waterland@Sun.COM 	 * the old behavior.
1286*9781SMoriah.Waterland@Sun.COM 	 */
1287*9781SMoriah.Waterland@Sun.COM 
1288*9781SMoriah.Waterland@Sun.COM 	if (getenv("PKG_NONABI_SYMLINKS") != NULL) {
1289*9781SMoriah.Waterland@Sun.COM 		old_symlinks = 1;
1290*9781SMoriah.Waterland@Sun.COM 	}
1291*9781SMoriah.Waterland@Sun.COM 
1292*9781SMoriah.Waterland@Sun.COM 	/*
1293*9781SMoriah.Waterland@Sun.COM 	 * See if the user wants the package name length restricted.
1294*9781SMoriah.Waterland@Sun.COM 	 */
1295*9781SMoriah.Waterland@Sun.COM 
1296*9781SMoriah.Waterland@Sun.COM 	abiPtr = getenv("PKG_ABI_NAMELENGTH");
1297*9781SMoriah.Waterland@Sun.COM 	if (abiPtr && strncasecmp(abiPtr, "TRUE", 4) == 0) {
1298*9781SMoriah.Waterland@Sun.COM 		ABI_namelength = 1;
1299*9781SMoriah.Waterland@Sun.COM 	}
1300*9781SMoriah.Waterland@Sun.COM 
1301*9781SMoriah.Waterland@Sun.COM 	/*
1302*9781SMoriah.Waterland@Sun.COM 	 * validate the package source device - return pkgdev info that
1303*9781SMoriah.Waterland@Sun.COM 	 * describes the package source device.
1304*9781SMoriah.Waterland@Sun.COM 	 */
1305*9781SMoriah.Waterland@Sun.COM 
1306*9781SMoriah.Waterland@Sun.COM 	if (devtype(device, &pkgdev)) {
1307*9781SMoriah.Waterland@Sun.COM 		progerr(ERR_BAD_DEVICE, device);
1308*9781SMoriah.Waterland@Sun.COM 		quit(1);
1309*9781SMoriah.Waterland@Sun.COM 		/* NOTREACHED */
1310*9781SMoriah.Waterland@Sun.COM 	}
1311*9781SMoriah.Waterland@Sun.COM 
1312*9781SMoriah.Waterland@Sun.COM 	/*
1313*9781SMoriah.Waterland@Sun.COM 	 * If writing the packages into a spool directory instead of
1314*9781SMoriah.Waterland@Sun.COM 	 * installing the packages, open the package datastream and
1315*9781SMoriah.Waterland@Sun.COM 	 * invoke pkgtrans to perform the conversion and exit.
1316*9781SMoriah.Waterland@Sun.COM 	 */
1317*9781SMoriah.Waterland@Sun.COM 
1318*9781SMoriah.Waterland@Sun.COM 	if (spoolDir != (char *)NULL) {
1319*9781SMoriah.Waterland@Sun.COM 		boolean_t	b;
1320*9781SMoriah.Waterland@Sun.COM 		int		n;
1321*9781SMoriah.Waterland@Sun.COM 
1322*9781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_INSTALLING_TO_SPOOL, spoolDir);
1323*9781SMoriah.Waterland@Sun.COM 
1324*9781SMoriah.Waterland@Sun.COM 		b = open_package_datastream(argc, argv, spoolDir, device,
1325*9781SMoriah.Waterland@Sun.COM 						&repeat, &ids_name, tmpdir,
1326*9781SMoriah.Waterland@Sun.COM 						&pkgdev, optind);
1327*9781SMoriah.Waterland@Sun.COM 
1328*9781SMoriah.Waterland@Sun.COM 		quitSetIdsName(ids_name);
1329*9781SMoriah.Waterland@Sun.COM 
1330*9781SMoriah.Waterland@Sun.COM 		if (b != B_TRUE) {
1331*9781SMoriah.Waterland@Sun.COM 			progerr(ERR_CANNOT_OPEN_PKG_STREAM, PSTR(device));
1332*9781SMoriah.Waterland@Sun.COM 			quit(1);
1333*9781SMoriah.Waterland@Sun.COM 		}
1334*9781SMoriah.Waterland@Sun.COM 
1335*9781SMoriah.Waterland@Sun.COM 		n = pkgtrans(device, spoolDir, &argv[optind],
1336*9781SMoriah.Waterland@Sun.COM 				0, NULL, NULL);
1337*9781SMoriah.Waterland@Sun.COM 		quit(n);
1338*9781SMoriah.Waterland@Sun.COM 		/* NOTREACHED */
1339*9781SMoriah.Waterland@Sun.COM 	}
1340*9781SMoriah.Waterland@Sun.COM 
1341*9781SMoriah.Waterland@Sun.COM 	/*
1342*9781SMoriah.Waterland@Sun.COM 	 * error if there are packages on the command line and a category
1343*9781SMoriah.Waterland@Sun.COM 	 * was specified
1344*9781SMoriah.Waterland@Sun.COM 	 */
1345*9781SMoriah.Waterland@Sun.COM 
1346*9781SMoriah.Waterland@Sun.COM 	if ((optind < argc) && (catg_arg != NULL)) {
1347*9781SMoriah.Waterland@Sun.COM 		progerr(ERR_PKGS_AND_CAT_PKGADD);
1348*9781SMoriah.Waterland@Sun.COM 		usage();
1349*9781SMoriah.Waterland@Sun.COM 		quit(1);
1350*9781SMoriah.Waterland@Sun.COM 		/* NOTREACHED */
1351*9781SMoriah.Waterland@Sun.COM 	}
1352*9781SMoriah.Waterland@Sun.COM 
1353*9781SMoriah.Waterland@Sun.COM 	/*
1354*9781SMoriah.Waterland@Sun.COM 	 * ********************************************************************
1355*9781SMoriah.Waterland@Sun.COM 	 * main package processing "loop"
1356*9781SMoriah.Waterland@Sun.COM 	 * ********************************************************************
1357*9781SMoriah.Waterland@Sun.COM 	 */
1358*9781SMoriah.Waterland@Sun.COM 
1359*9781SMoriah.Waterland@Sun.COM 	ids_name = NULL;
1360*9781SMoriah.Waterland@Sun.COM 	quitSetIdsName(ids_name);
1361*9781SMoriah.Waterland@Sun.COM 
1362*9781SMoriah.Waterland@Sun.COM 	for (;;) {
1363*9781SMoriah.Waterland@Sun.COM 		boolean_t	b;
1364*9781SMoriah.Waterland@Sun.COM 		char		**pkglist;	/* points to array of pkgs */
1365*9781SMoriah.Waterland@Sun.COM 
1366*9781SMoriah.Waterland@Sun.COM 		/*
1367*9781SMoriah.Waterland@Sun.COM 		 * open next package data stream
1368*9781SMoriah.Waterland@Sun.COM 		 */
1369*9781SMoriah.Waterland@Sun.COM 
1370*9781SMoriah.Waterland@Sun.COM 		b = open_package_datastream(argc, argv, spoolDir, device,
1371*9781SMoriah.Waterland@Sun.COM 						&repeat, &ids_name, tmpdir,
1372*9781SMoriah.Waterland@Sun.COM 						&pkgdev, optind);
1373*9781SMoriah.Waterland@Sun.COM 
1374*9781SMoriah.Waterland@Sun.COM 		quitSetIdsName(ids_name);
1375*9781SMoriah.Waterland@Sun.COM 
1376*9781SMoriah.Waterland@Sun.COM 		if (b == B_FALSE) {
1377*9781SMoriah.Waterland@Sun.COM 			echoDebug(ERR_CANNOT_OPEN_PKG_STREAM, PSTR(device));
1378*9781SMoriah.Waterland@Sun.COM 			continue;
1379*9781SMoriah.Waterland@Sun.COM 		}
1380*9781SMoriah.Waterland@Sun.COM 
1381*9781SMoriah.Waterland@Sun.COM 		/*
1382*9781SMoriah.Waterland@Sun.COM 		 * package source data stream open - get the package list
1383*9781SMoriah.Waterland@Sun.COM 		 */
1384*9781SMoriah.Waterland@Sun.COM 
1385*9781SMoriah.Waterland@Sun.COM 		b = get_package_list(&pkglist, argv, catg_arg, category,
1386*9781SMoriah.Waterland@Sun.COM 			ignore_sig, err, proxy_port, proxy, keystore,
1387*9781SMoriah.Waterland@Sun.COM 			keystore_file, ids_name, &repeat);
1388*9781SMoriah.Waterland@Sun.COM 
1389*9781SMoriah.Waterland@Sun.COM 		if (b == B_FALSE) {
1390*9781SMoriah.Waterland@Sun.COM 			char	path[PATH_MAX];
1391*9781SMoriah.Waterland@Sun.COM 
1392*9781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_CANNOT_GET_PKGLIST);
1393*9781SMoriah.Waterland@Sun.COM 
1394*9781SMoriah.Waterland@Sun.COM 			/* check for existence of pre-SVR4 package */
1395*9781SMoriah.Waterland@Sun.COM 			(void) snprintf(path, sizeof (path),
1396*9781SMoriah.Waterland@Sun.COM 				"%s/install/INSTALL", pkgdev.dirname);
1397*9781SMoriah.Waterland@Sun.COM 			if (access(path, F_OK) == 0) {
1398*9781SMoriah.Waterland@Sun.COM 				pkginst = ((optind < argc) ?
1399*9781SMoriah.Waterland@Sun.COM 					argv[optind++] : NULL);
1400*9781SMoriah.Waterland@Sun.COM 				ckreturn(presvr4(&pkginst, nointeract));
1401*9781SMoriah.Waterland@Sun.COM 				if (repeat || (optind < argc)) {
1402*9781SMoriah.Waterland@Sun.COM 					continue;
1403*9781SMoriah.Waterland@Sun.COM 				}
1404*9781SMoriah.Waterland@Sun.COM 				quit(0);
1405*9781SMoriah.Waterland@Sun.COM 			}
1406*9781SMoriah.Waterland@Sun.COM 			progerr(ERR_NOPKGS, pkgdev.dirname);
1407*9781SMoriah.Waterland@Sun.COM 			quit(1);
1408*9781SMoriah.Waterland@Sun.COM 			/* NOTREACHED */
1409*9781SMoriah.Waterland@Sun.COM 		}
1410*9781SMoriah.Waterland@Sun.COM 
1411*9781SMoriah.Waterland@Sun.COM 		/*
1412*9781SMoriah.Waterland@Sun.COM 		 * count the number of packages to install
1413*9781SMoriah.Waterland@Sun.COM 		 * NOTE: npkgs is a global variable that is referenced by quit.c
1414*9781SMoriah.Waterland@Sun.COM 		 * when error messages are generated - it is referenced directly
1415*9781SMoriah.Waterland@Sun.COM 		 * by the other functions called below...
1416*9781SMoriah.Waterland@Sun.COM 		 */
1417*9781SMoriah.Waterland@Sun.COM 
1418*9781SMoriah.Waterland@Sun.COM 		for (npkgs = 0; pkglist[npkgs] != (char *)NULL; /* void */) {
1419*9781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_PKG_SELECTED, npkgs, pkglist[npkgs]);
1420*9781SMoriah.Waterland@Sun.COM 			npkgs++;
1421*9781SMoriah.Waterland@Sun.COM 		}
1422*9781SMoriah.Waterland@Sun.COM 
1423*9781SMoriah.Waterland@Sun.COM 		/* output number of packages to be added */
1424*9781SMoriah.Waterland@Sun.COM 
1425*9781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_NUM_PKGS_TO_ADD, npkgs);
1426*9781SMoriah.Waterland@Sun.COM 
1427*9781SMoriah.Waterland@Sun.COM 		/*
1428*9781SMoriah.Waterland@Sun.COM 		 * if pkgask and response container is a file (not a directory),
1429*9781SMoriah.Waterland@Sun.COM 		 * and there is more than one package to install, then it is an
1430*9781SMoriah.Waterland@Sun.COM 		 * error - too many packages to install when response container
1431*9781SMoriah.Waterland@Sun.COM 		 * is a file.
1432*9781SMoriah.Waterland@Sun.COM 		 */
1433*9781SMoriah.Waterland@Sun.COM 
1434*9781SMoriah.Waterland@Sun.COM 		if ((askflag != 0) && (respdir == (char *)NULL) &&
1435*9781SMoriah.Waterland@Sun.COM 			(npkgs > 1)) {
1436*9781SMoriah.Waterland@Sun.COM 			progerr(ERR_TOO_MANY_PKGS);
1437*9781SMoriah.Waterland@Sun.COM 			quit(1);
1438*9781SMoriah.Waterland@Sun.COM 			/* NOTREACHED */
1439*9781SMoriah.Waterland@Sun.COM 		}
1440*9781SMoriah.Waterland@Sun.COM 
1441*9781SMoriah.Waterland@Sun.COM 		/*
1442*9781SMoriah.Waterland@Sun.COM 		 * package list generated - add packages
1443*9781SMoriah.Waterland@Sun.COM 		 */
1444*9781SMoriah.Waterland@Sun.COM 
1445*9781SMoriah.Waterland@Sun.COM 		b = add_packages(pkglist, uri, ids_name, repeat,
1446*9781SMoriah.Waterland@Sun.COM 					altBinDir, device, noZones);
1447*9781SMoriah.Waterland@Sun.COM 
1448*9781SMoriah.Waterland@Sun.COM 		/*
1449*9781SMoriah.Waterland@Sun.COM 		 * close open input data stream (source package) if left open.
1450*9781SMoriah.Waterland@Sun.COM 		 */
1451*9781SMoriah.Waterland@Sun.COM 
1452*9781SMoriah.Waterland@Sun.COM 		if (ids_name) {
1453*9781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_CLOSING_STREAM, ids_name,
1454*9781SMoriah.Waterland@Sun.COM 					PSTR(pkgdev.dirname));
1455*9781SMoriah.Waterland@Sun.COM 			(void) ds_close(1);
1456*9781SMoriah.Waterland@Sun.COM 			rrmdir(pkgdev.dirname);
1457*9781SMoriah.Waterland@Sun.COM 			ids_name = NULL;
1458*9781SMoriah.Waterland@Sun.COM 			quitSetIdsName(ids_name);
1459*9781SMoriah.Waterland@Sun.COM 		}
1460*9781SMoriah.Waterland@Sun.COM 
1461*9781SMoriah.Waterland@Sun.COM 		/*
1462*9781SMoriah.Waterland@Sun.COM 		 * continue with next sequence of packages if continue set
1463*9781SMoriah.Waterland@Sun.COM 		 */
1464*9781SMoriah.Waterland@Sun.COM 
1465*9781SMoriah.Waterland@Sun.COM 		if (b == B_TRUE) {
1466*9781SMoriah.Waterland@Sun.COM 			continue;
1467*9781SMoriah.Waterland@Sun.COM 		}
1468*9781SMoriah.Waterland@Sun.COM 
1469*9781SMoriah.Waterland@Sun.COM 		/*
1470*9781SMoriah.Waterland@Sun.COM 		 * not continuing - quit with 0 exit code
1471*9781SMoriah.Waterland@Sun.COM 		 */
1472*9781SMoriah.Waterland@Sun.COM 
1473*9781SMoriah.Waterland@Sun.COM 		quit(0);
1474*9781SMoriah.Waterland@Sun.COM 		/* NOTREACHED */
1475*9781SMoriah.Waterland@Sun.COM 	}
1476*9781SMoriah.Waterland@Sun.COM 
1477*9781SMoriah.Waterland@Sun.COM 	/* NOTREACHED */
1478*9781SMoriah.Waterland@Sun.COM }
1479*9781SMoriah.Waterland@Sun.COM 
1480*9781SMoriah.Waterland@Sun.COM /*
1481*9781SMoriah.Waterland@Sun.COM  * *****************************************************************************
1482*9781SMoriah.Waterland@Sun.COM  * static internal (private) functions
1483*9781SMoriah.Waterland@Sun.COM  * *****************************************************************************
1484*9781SMoriah.Waterland@Sun.COM  */
1485*9781SMoriah.Waterland@Sun.COM 
1486*9781SMoriah.Waterland@Sun.COM /*
1487*9781SMoriah.Waterland@Sun.COM  * Name:	pkgZoneCheckInstall
1488*9781SMoriah.Waterland@Sun.COM  * Description:	Invoke pkginstall in a specified zone to perform a preinstall
1489*9781SMoriah.Waterland@Sun.COM  *		check of the a single package in the specified zone
1490*9781SMoriah.Waterland@Sun.COM  * Arguments:	a_zoneName - pointer to string representing the name of the
1491*9781SMoriah.Waterland@Sun.COM  *			zone to check install the package in.
1492*9781SMoriah.Waterland@Sun.COM  *		a_inheritedPkgDirs - pointer to array of strings, each one
1493*9781SMoriah.Waterland@Sun.COM  *			representing the non-global zones full path of a
1494*9781SMoriah.Waterland@Sun.COM  *			directory that is inherited from the global zone.
1495*9781SMoriah.Waterland@Sun.COM  *		a_zoneState - current state of the zone; must be mounted or
1496*9781SMoriah.Waterland@Sun.COM  *			running.
1497*9781SMoriah.Waterland@Sun.COM  *		a_idsName - pointer to string representing the data stream
1498*9781SMoriah.Waterland@Sun.COM  *			device (input data stream) containing the package to
1499*9781SMoriah.Waterland@Sun.COM  *			be check installed.
1500*9781SMoriah.Waterland@Sun.COM  *		a_altBinDir - pointer to string representing an alternative
1501*9781SMoriah.Waterland@Sun.COM  *			binary location directory to pass to pkginstall.
1502*9781SMoriah.Waterland@Sun.COM  *			If this is == NULL no alternative binary location is
1503*9781SMoriah.Waterland@Sun.COM  *			passed to pkginstall.
1504*9781SMoriah.Waterland@Sun.COM  *		a_adminFile - pointer to string representing the admin
1505*9781SMoriah.Waterland@Sun.COM  *			file to pass to pkginstall when installing the package.
1506*9781SMoriah.Waterland@Sun.COM  *			If this is == NULL no admin file is given to pkginstall.
1507*9781SMoriah.Waterland@Sun.COM  *		a_stdoutPath - pointer to string representing the local path
1508*9781SMoriah.Waterland@Sun.COM  *			into which all output written by pkginstall to stdout
1509*9781SMoriah.Waterland@Sun.COM  *			is stored.
1510*9781SMoriah.Waterland@Sun.COM  *			If this is == NULL stdout is redirected to /dev/null
1511*9781SMoriah.Waterland@Sun.COM  * Returns:	int	(see ckreturn() function for details)
1512*9781SMoriah.Waterland@Sun.COM  *		0 - success
1513*9781SMoriah.Waterland@Sun.COM  *		1 - package operation failed (fatal error)
1514*9781SMoriah.Waterland@Sun.COM  *		2 - non-fatal error (warning)
1515*9781SMoriah.Waterland@Sun.COM  *		3 - user selected quit (operation interrupted)
1516*9781SMoriah.Waterland@Sun.COM  *		4 - admin settings prevented operation
1517*9781SMoriah.Waterland@Sun.COM  *		5 - interaction required and -n (non-interactive) specified
1518*9781SMoriah.Waterland@Sun.COM  *		"10" will be added to indicate "immediate reboot required"
1519*9781SMoriah.Waterland@Sun.COM  *		"20" will be added to indicate "reboot after install required"
1520*9781SMoriah.Waterland@Sun.COM  */
1521*9781SMoriah.Waterland@Sun.COM 
1522*9781SMoriah.Waterland@Sun.COM static int
1523*9781SMoriah.Waterland@Sun.COM pkgZoneCheckInstall(char *a_zoneName, char **a_inheritedPkgDirs,
1524*9781SMoriah.Waterland@Sun.COM 	zone_state_t a_zoneState, char *a_idsName, char *a_altBinDir,
1525*9781SMoriah.Waterland@Sun.COM 	char *a_adminFile, char *a_stdoutPath)
1526*9781SMoriah.Waterland@Sun.COM {
1527*9781SMoriah.Waterland@Sun.COM 	char	*arg[MAXARGS];
1528*9781SMoriah.Waterland@Sun.COM 	char	*p;
1529*9781SMoriah.Waterland@Sun.COM 	char	adminfd_path[PATH_MAX];
1530*9781SMoriah.Waterland@Sun.COM 	char	path[PATH_MAX];
1531*9781SMoriah.Waterland@Sun.COM 	char	pkgstreamfd_path[PATH_MAX];
1532*9781SMoriah.Waterland@Sun.COM 	int	fds[MAX_FDS];
1533*9781SMoriah.Waterland@Sun.COM 	int	maxfds;
1534*9781SMoriah.Waterland@Sun.COM 	int	n;
1535*9781SMoriah.Waterland@Sun.COM 	int	nargs;
1536*9781SMoriah.Waterland@Sun.COM 
1537*9781SMoriah.Waterland@Sun.COM 	/* entry assertions */
1538*9781SMoriah.Waterland@Sun.COM 
1539*9781SMoriah.Waterland@Sun.COM 	assert(a_zoneName != (char *)NULL);
1540*9781SMoriah.Waterland@Sun.COM 	assert(*a_zoneName != '\0');
1541*9781SMoriah.Waterland@Sun.COM 
1542*9781SMoriah.Waterland@Sun.COM 	/* entry debugging info */
1543*9781SMoriah.Waterland@Sun.COM 
1544*9781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_PKGZONECHECKINSTALL_ENTRY);
1545*9781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_PKGZONECHECKINSTALL_ARGS, a_zoneName, PSTR(pkginst),
1546*9781SMoriah.Waterland@Sun.COM 		PSTR(pkgdev.dirname), PSTR(pkgdev.mount), PSTR(pkgdev.bdevice),
1547*9781SMoriah.Waterland@Sun.COM 		a_zoneState == ZONE_STATE_MOUNTED ? "/a" : "/",
1548*9781SMoriah.Waterland@Sun.COM 		PSTR(a_idsName), PSTR(a_adminFile), PSTR(a_stdoutPath));
1549*9781SMoriah.Waterland@Sun.COM 
1550*9781SMoriah.Waterland@Sun.COM 	/* generate full path to 'phatinstall' to run in zone */
1551*9781SMoriah.Waterland@Sun.COM 
1552*9781SMoriah.Waterland@Sun.COM 	(void) snprintf(path, sizeof (path), "%s/pkginstall",
1553*9781SMoriah.Waterland@Sun.COM 			"/usr/sadm/install/bin");
1554*9781SMoriah.Waterland@Sun.COM 
1555*9781SMoriah.Waterland@Sun.COM 	/* start at first file descriptor */
1556*9781SMoriah.Waterland@Sun.COM 
1557*9781SMoriah.Waterland@Sun.COM 	maxfds = 0;
1558*9781SMoriah.Waterland@Sun.COM 
1559*9781SMoriah.Waterland@Sun.COM 	/*
1560*9781SMoriah.Waterland@Sun.COM 	 * generate argument list for call to pkginstall
1561*9781SMoriah.Waterland@Sun.COM 	 */
1562*9781SMoriah.Waterland@Sun.COM 
1563*9781SMoriah.Waterland@Sun.COM 	/* start at argument 0 */
1564*9781SMoriah.Waterland@Sun.COM 
1565*9781SMoriah.Waterland@Sun.COM 	nargs = 0;
1566*9781SMoriah.Waterland@Sun.COM 
1567*9781SMoriah.Waterland@Sun.COM 	/* first argument is always: full path to executable */
1568*9781SMoriah.Waterland@Sun.COM 
1569*9781SMoriah.Waterland@Sun.COM 	arg[nargs++] = path;
1570*9781SMoriah.Waterland@Sun.COM 
1571*9781SMoriah.Waterland@Sun.COM 	/*
1572*9781SMoriah.Waterland@Sun.COM 	 * second argument is always: pass -O debug to pkginstall: debug mode
1573*9781SMoriah.Waterland@Sun.COM 	 */
1574*9781SMoriah.Waterland@Sun.COM 	if (debugFlag == B_TRUE) {
1575*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-O";
1576*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "debug";
1577*9781SMoriah.Waterland@Sun.COM 	}
1578*9781SMoriah.Waterland@Sun.COM 
1579*9781SMoriah.Waterland@Sun.COM 	/* pkgadd -G: pass -G to pkginstall */
1580*9781SMoriah.Waterland@Sun.COM 
1581*9781SMoriah.Waterland@Sun.COM 	if (globalZoneOnly == B_TRUE) {
1582*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-G";
1583*9781SMoriah.Waterland@Sun.COM 	}
1584*9781SMoriah.Waterland@Sun.COM 
1585*9781SMoriah.Waterland@Sun.COM 	/* pkgadd -b dir: pass -b to pkginstall */
1586*9781SMoriah.Waterland@Sun.COM 
1587*9781SMoriah.Waterland@Sun.COM 	if (a_altBinDir != (char *)NULL) {
1588*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-b";
1589*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = a_altBinDir;
1590*9781SMoriah.Waterland@Sun.COM 	}
1591*9781SMoriah.Waterland@Sun.COM 
1592*9781SMoriah.Waterland@Sun.COM 	/* pkgadd -C: pass -C to pkginstall: disable checksum */
1593*9781SMoriah.Waterland@Sun.COM 
1594*9781SMoriah.Waterland@Sun.COM 	if (disableChecksum) {
1595*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-C";
1596*9781SMoriah.Waterland@Sun.COM 	}
1597*9781SMoriah.Waterland@Sun.COM 
1598*9781SMoriah.Waterland@Sun.COM 	/* pkgadd -A: pass -A to pkginstall: disable attribute checking */
1599*9781SMoriah.Waterland@Sun.COM 
1600*9781SMoriah.Waterland@Sun.COM 	if (disableAttributes) {
1601*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-A";
1602*9781SMoriah.Waterland@Sun.COM 	}
1603*9781SMoriah.Waterland@Sun.COM 
1604*9781SMoriah.Waterland@Sun.COM 	/*
1605*9781SMoriah.Waterland@Sun.COM 	 * NONABI_SCRIPTS defined: pass -o to pkginstall; refers to a
1606*9781SMoriah.Waterland@Sun.COM 	 * pkg requiring operator interaction during a procedure script
1607*9781SMoriah.Waterland@Sun.COM 	 * (common before on1093)
1608*9781SMoriah.Waterland@Sun.COM 	 */
1609*9781SMoriah.Waterland@Sun.COM 
1610*9781SMoriah.Waterland@Sun.COM 	if (old_pkg) {
1611*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-o";
1612*9781SMoriah.Waterland@Sun.COM 	}
1613*9781SMoriah.Waterland@Sun.COM 
1614*9781SMoriah.Waterland@Sun.COM 	/*
1615*9781SMoriah.Waterland@Sun.COM 	 * PKG_NONABI_SYMLINKS defined: pass -y to pkginstall; process
1616*9781SMoriah.Waterland@Sun.COM 	 * symlinks consistent with old behavior
1617*9781SMoriah.Waterland@Sun.COM 	 */
1618*9781SMoriah.Waterland@Sun.COM 
1619*9781SMoriah.Waterland@Sun.COM 	if (old_symlinks) {
1620*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-y";
1621*9781SMoriah.Waterland@Sun.COM 	}
1622*9781SMoriah.Waterland@Sun.COM 
1623*9781SMoriah.Waterland@Sun.COM 	/*
1624*9781SMoriah.Waterland@Sun.COM 	 * PKG_ABI_NAMELENGTH defined: pass -e to pkginstall; causes
1625*9781SMoriah.Waterland@Sun.COM 	 * package name length to be restricted
1626*9781SMoriah.Waterland@Sun.COM 	 */
1627*9781SMoriah.Waterland@Sun.COM 
1628*9781SMoriah.Waterland@Sun.COM 	if (ABI_namelength) {
1629*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-e";
1630*9781SMoriah.Waterland@Sun.COM 	}
1631*9781SMoriah.Waterland@Sun.COM 
1632*9781SMoriah.Waterland@Sun.COM 	/* pkgadd -S: pass -S to pkginstall: suppress copyright notices */
1633*9781SMoriah.Waterland@Sun.COM 
1634*9781SMoriah.Waterland@Sun.COM 	arg[nargs++] = "-S";
1635*9781SMoriah.Waterland@Sun.COM 
1636*9781SMoriah.Waterland@Sun.COM 	/* pkgadd -M: pass -M to pkginstall: dont mount client file systems */
1637*9781SMoriah.Waterland@Sun.COM 
1638*9781SMoriah.Waterland@Sun.COM 	arg[nargs++] = "-M";
1639*9781SMoriah.Waterland@Sun.COM 
1640*9781SMoriah.Waterland@Sun.COM 	/* pkgadd -v: pass -v to pkginstall: never trace scripts */
1641*9781SMoriah.Waterland@Sun.COM 
1642*9781SMoriah.Waterland@Sun.COM 	/* if running pkgask, pass -i to pkginstall: running pkgask */
1643*9781SMoriah.Waterland@Sun.COM 
1644*9781SMoriah.Waterland@Sun.COM 	if (askflag) {
1645*9781SMoriah.Waterland@Sun.COM 		return (0);
1646*9781SMoriah.Waterland@Sun.COM 	}
1647*9781SMoriah.Waterland@Sun.COM 
1648*9781SMoriah.Waterland@Sun.COM 	/* pass "-O enable-hollow-package-support" */
1649*9781SMoriah.Waterland@Sun.COM 
1650*9781SMoriah.Waterland@Sun.COM 	if (is_depend_pkginfo_DB()) {
1651*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-O";
1652*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "enable-hollow-package-support";
1653*9781SMoriah.Waterland@Sun.COM 	}
1654*9781SMoriah.Waterland@Sun.COM 
1655*9781SMoriah.Waterland@Sun.COM 	/* check is always in non-interactive mode */
1656*9781SMoriah.Waterland@Sun.COM 
1657*9781SMoriah.Waterland@Sun.COM 	arg[nargs++] = "-n";
1658*9781SMoriah.Waterland@Sun.COM 
1659*9781SMoriah.Waterland@Sun.COM 	/* pkgadd -a admin: pass -a admin to pkginstall in zone: admin file */
1660*9781SMoriah.Waterland@Sun.COM 
1661*9781SMoriah.Waterland@Sun.COM 	if (a_adminFile) {
1662*9781SMoriah.Waterland@Sun.COM 		int fd;
1663*9781SMoriah.Waterland@Sun.COM 		fd = openLocal(a_adminFile, O_RDONLY, tmpdir);
1664*9781SMoriah.Waterland@Sun.COM 		if (fd < 0) {
1665*9781SMoriah.Waterland@Sun.COM 			progerr(ERR_CANNOT_COPY_LOCAL, a_adminFile,
1666*9781SMoriah.Waterland@Sun.COM 				errno, strerror(errno));
1667*9781SMoriah.Waterland@Sun.COM 			return (1);
1668*9781SMoriah.Waterland@Sun.COM 		}
1669*9781SMoriah.Waterland@Sun.COM 		(void) snprintf(adminfd_path, sizeof (adminfd_path),
1670*9781SMoriah.Waterland@Sun.COM 			"/proc/self/fd/%d", fd);
1671*9781SMoriah.Waterland@Sun.COM 		fds[maxfds++] = fd;
1672*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-a";
1673*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = adminfd_path;
1674*9781SMoriah.Waterland@Sun.COM 	}
1675*9781SMoriah.Waterland@Sun.COM 
1676*9781SMoriah.Waterland@Sun.COM 	/* pkgadd -R root: pass -R /a to pkginstall when zone is mounted */
1677*9781SMoriah.Waterland@Sun.COM 
1678*9781SMoriah.Waterland@Sun.COM 	if (a_zoneState == ZONE_STATE_MOUNTED) {
1679*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-R";
1680*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "/a";
1681*9781SMoriah.Waterland@Sun.COM 	}
1682*9781SMoriah.Waterland@Sun.COM 
1683*9781SMoriah.Waterland@Sun.COM 	/* pass -N to pkginstall: program name to report */
1684*9781SMoriah.Waterland@Sun.COM 
1685*9781SMoriah.Waterland@Sun.COM 	arg[nargs++] = "-N";
1686*9781SMoriah.Waterland@Sun.COM 	arg[nargs++] = get_prog_name();
1687*9781SMoriah.Waterland@Sun.COM 
1688*9781SMoriah.Waterland@Sun.COM 	/* pass "-O preinstallcheck" */
1689*9781SMoriah.Waterland@Sun.COM 
1690*9781SMoriah.Waterland@Sun.COM 	arg[nargs++] = "-O";
1691*9781SMoriah.Waterland@Sun.COM 	arg[nargs++] = "preinstallcheck";
1692*9781SMoriah.Waterland@Sun.COM 
1693*9781SMoriah.Waterland@Sun.COM 	/* add "-O addzonename" */
1694*9781SMoriah.Waterland@Sun.COM 
1695*9781SMoriah.Waterland@Sun.COM 	arg[nargs++] = "-O";
1696*9781SMoriah.Waterland@Sun.COM 	arg[nargs++] = "addzonename";
1697*9781SMoriah.Waterland@Sun.COM 
1698*9781SMoriah.Waterland@Sun.COM 	if (isPatchUpdate()) {
1699*9781SMoriah.Waterland@Sun.COM 		if (patchPkgRemoval == B_TRUE) {
1700*9781SMoriah.Waterland@Sun.COM 			arg[nargs++] = "-O";
1701*9781SMoriah.Waterland@Sun.COM 			arg[nargs++] = "patchPkgRemoval";
1702*9781SMoriah.Waterland@Sun.COM 		} else {
1703*9781SMoriah.Waterland@Sun.COM 			arg[nargs++] = "-O";
1704*9781SMoriah.Waterland@Sun.COM 			arg[nargs++] = "patchPkgInstall";
1705*9781SMoriah.Waterland@Sun.COM 		}
1706*9781SMoriah.Waterland@Sun.COM 	}
1707*9781SMoriah.Waterland@Sun.COM 
1708*9781SMoriah.Waterland@Sun.COM 	/* add all inherited file systems */
1709*9781SMoriah.Waterland@Sun.COM 
1710*9781SMoriah.Waterland@Sun.COM 	if (a_inheritedPkgDirs != (char **)NULL) {
1711*9781SMoriah.Waterland@Sun.COM 		for (n = 0; a_inheritedPkgDirs[n] != (char *)NULL; n++) {
1712*9781SMoriah.Waterland@Sun.COM 			char	ifs[MAXPATHLEN+22];
1713*9781SMoriah.Waterland@Sun.COM 			(void) snprintf(ifs, sizeof (ifs),
1714*9781SMoriah.Waterland@Sun.COM 				"inherited-filesystem=%s",
1715*9781SMoriah.Waterland@Sun.COM 				a_inheritedPkgDirs[n]);
1716*9781SMoriah.Waterland@Sun.COM 			arg[nargs++] = "-O";
1717*9781SMoriah.Waterland@Sun.COM 			arg[nargs++] = strdup(ifs);
1718*9781SMoriah.Waterland@Sun.COM 		}
1719*9781SMoriah.Waterland@Sun.COM 	}
1720*9781SMoriah.Waterland@Sun.COM 
1721*9781SMoriah.Waterland@Sun.COM 	/*
1722*9781SMoriah.Waterland@Sun.COM 	 * add parent zone info/type
1723*9781SMoriah.Waterland@Sun.COM 	 */
1724*9781SMoriah.Waterland@Sun.COM 
1725*9781SMoriah.Waterland@Sun.COM 	p = z_get_zonename();
1726*9781SMoriah.Waterland@Sun.COM 	if ((p != NULL) && (*p != '\0')) {
1727*9781SMoriah.Waterland@Sun.COM 			char	zn[MAXPATHLEN];
1728*9781SMoriah.Waterland@Sun.COM 			(void) snprintf(zn, sizeof (zn),
1729*9781SMoriah.Waterland@Sun.COM 				"parent-zone-name=%s", p);
1730*9781SMoriah.Waterland@Sun.COM 			arg[nargs++] = "-O";
1731*9781SMoriah.Waterland@Sun.COM 			arg[nargs++] = strdup(zn);
1732*9781SMoriah.Waterland@Sun.COM 	}
1733*9781SMoriah.Waterland@Sun.COM 
1734*9781SMoriah.Waterland@Sun.COM 	/* current zone type */
1735*9781SMoriah.Waterland@Sun.COM 
1736*9781SMoriah.Waterland@Sun.COM 	arg[nargs++] = "-O";
1737*9781SMoriah.Waterland@Sun.COM 	if (z_running_in_global_zone() == B_TRUE) {
1738*9781SMoriah.Waterland@Sun.COM 			char	zn[MAXPATHLEN];
1739*9781SMoriah.Waterland@Sun.COM 			(void) snprintf(zn, sizeof (zn),
1740*9781SMoriah.Waterland@Sun.COM 				"parent-zone-type=%s",
1741*9781SMoriah.Waterland@Sun.COM 				TAG_VALUE_GLOBAL_ZONE);
1742*9781SMoriah.Waterland@Sun.COM 			arg[nargs++] = strdup(zn);
1743*9781SMoriah.Waterland@Sun.COM 	} else {
1744*9781SMoriah.Waterland@Sun.COM 			char	zn[MAXPATHLEN];
1745*9781SMoriah.Waterland@Sun.COM 			(void) snprintf(zn, sizeof (zn),
1746*9781SMoriah.Waterland@Sun.COM 				"parent-zone-type=%s",
1747*9781SMoriah.Waterland@Sun.COM 				TAG_VALUE_NONGLOBAL_ZONE);
1748*9781SMoriah.Waterland@Sun.COM 			arg[nargs++] = strdup(zn);
1749*9781SMoriah.Waterland@Sun.COM 	}
1750*9781SMoriah.Waterland@Sun.COM 
1751*9781SMoriah.Waterland@Sun.COM 	/* add in the package stream file */
1752*9781SMoriah.Waterland@Sun.COM 
1753*9781SMoriah.Waterland@Sun.COM 	if (a_idsName != NULL) {
1754*9781SMoriah.Waterland@Sun.COM 		int fd;
1755*9781SMoriah.Waterland@Sun.COM 		fd = openLocal(a_idsName, O_RDONLY, tmpdir);
1756*9781SMoriah.Waterland@Sun.COM 		if (fd < 0) {
1757*9781SMoriah.Waterland@Sun.COM 			progerr(ERR_STREAM_UNAVAILABLE, a_idsName,
1758*9781SMoriah.Waterland@Sun.COM 				pkginst, strerror(errno));
1759*9781SMoriah.Waterland@Sun.COM 			quit(1);
1760*9781SMoriah.Waterland@Sun.COM 		}
1761*9781SMoriah.Waterland@Sun.COM 		(void) snprintf(pkgstreamfd_path, sizeof (pkgstreamfd_path),
1762*9781SMoriah.Waterland@Sun.COM 			"/proc/self/fd/%d", fd);
1763*9781SMoriah.Waterland@Sun.COM 		fds[maxfds++] = fd;
1764*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = pkgstreamfd_path;
1765*9781SMoriah.Waterland@Sun.COM 	} else {
1766*9781SMoriah.Waterland@Sun.COM 		progerr(ERR_PKGZONEINSTALL_NO_STREAM);
1767*9781SMoriah.Waterland@Sun.COM 		quit(1);
1768*9781SMoriah.Waterland@Sun.COM 	}
1769*9781SMoriah.Waterland@Sun.COM 
1770*9781SMoriah.Waterland@Sun.COM 	/* add package instance name */
1771*9781SMoriah.Waterland@Sun.COM 
1772*9781SMoriah.Waterland@Sun.COM 	arg[nargs++] = pkginst;
1773*9781SMoriah.Waterland@Sun.COM 
1774*9781SMoriah.Waterland@Sun.COM 	/* terminate the argument list */
1775*9781SMoriah.Waterland@Sun.COM 
1776*9781SMoriah.Waterland@Sun.COM 	arg[nargs++] = NULL;
1777*9781SMoriah.Waterland@Sun.COM 
1778*9781SMoriah.Waterland@Sun.COM 	/*
1779*9781SMoriah.Waterland@Sun.COM 	 * run the appropriate pkginstall command in the specified zone
1780*9781SMoriah.Waterland@Sun.COM 	 */
1781*9781SMoriah.Waterland@Sun.COM 
1782*9781SMoriah.Waterland@Sun.COM 	if (debugFlag == B_TRUE) {
1783*9781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_ZONE_EXEC_ENTER, a_zoneName, arg[0]);
1784*9781SMoriah.Waterland@Sun.COM 		for (n = 0; arg[n]; n++) {
1785*9781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_ARG, n, arg[n]);
1786*9781SMoriah.Waterland@Sun.COM 		}
1787*9781SMoriah.Waterland@Sun.COM 	}
1788*9781SMoriah.Waterland@Sun.COM 
1789*9781SMoriah.Waterland@Sun.COM 	/* terminate file descriptor list */
1790*9781SMoriah.Waterland@Sun.COM 
1791*9781SMoriah.Waterland@Sun.COM 	fds[maxfds] = -1;
1792*9781SMoriah.Waterland@Sun.COM 
1793*9781SMoriah.Waterland@Sun.COM 	/* exec command in zone */
1794*9781SMoriah.Waterland@Sun.COM 
1795*9781SMoriah.Waterland@Sun.COM 	n = z_zone_exec(a_zoneName, path, arg, a_stdoutPath, (char *)NULL, fds);
1796*9781SMoriah.Waterland@Sun.COM 
1797*9781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_ZONE_EXEC_EXIT, a_zoneName, arg[0], n,
1798*9781SMoriah.Waterland@Sun.COM 			PSTR(a_stdoutPath));
1799*9781SMoriah.Waterland@Sun.COM 
1800*9781SMoriah.Waterland@Sun.COM 	/*
1801*9781SMoriah.Waterland@Sun.COM 	 * close any files that were opened for use by the
1802*9781SMoriah.Waterland@Sun.COM 	 * /proc/self/fd interface so they could be passed to programs
1803*9781SMoriah.Waterland@Sun.COM 	 * via the z_zone_exec() interface
1804*9781SMoriah.Waterland@Sun.COM 	 */
1805*9781SMoriah.Waterland@Sun.COM 
1806*9781SMoriah.Waterland@Sun.COM 	for (; maxfds > 0; maxfds--) {
1807*9781SMoriah.Waterland@Sun.COM 		(void) close(fds[maxfds-1]);
1808*9781SMoriah.Waterland@Sun.COM 	}
1809*9781SMoriah.Waterland@Sun.COM 
1810*9781SMoriah.Waterland@Sun.COM 	/* return results of pkginstall in zone execution */
1811*9781SMoriah.Waterland@Sun.COM 
1812*9781SMoriah.Waterland@Sun.COM 	return (n);
1813*9781SMoriah.Waterland@Sun.COM }
1814*9781SMoriah.Waterland@Sun.COM 
1815*9781SMoriah.Waterland@Sun.COM /*
1816*9781SMoriah.Waterland@Sun.COM  * Name:	pkgZoneInstall
1817*9781SMoriah.Waterland@Sun.COM  * Description:	Invoke pkginstall in a specified zone to perform an install
1818*9781SMoriah.Waterland@Sun.COM  *		of a single package in the specified zone
1819*9781SMoriah.Waterland@Sun.COM  * Arguments:	a_zoneName - pointer to string representing the name of the
1820*9781SMoriah.Waterland@Sun.COM  *			zone to install the package in.
1821*9781SMoriah.Waterland@Sun.COM  *		a_inheritedPkgDirs - pointer to array of strings, each one
1822*9781SMoriah.Waterland@Sun.COM  *			representing the non-global zones full path of a
1823*9781SMoriah.Waterland@Sun.COM  *			directory that is inherited from the global zone.
1824*9781SMoriah.Waterland@Sun.COM  *		a_zoneState - current state of the zone; must be mounted or
1825*9781SMoriah.Waterland@Sun.COM  *			running.
1826*9781SMoriah.Waterland@Sun.COM  *		a_idsName - pointer to string representing the data stream
1827*9781SMoriah.Waterland@Sun.COM  *			device (input data stream) containing the package to
1828*9781SMoriah.Waterland@Sun.COM  *			be installed.
1829*9781SMoriah.Waterland@Sun.COM  *		a_altBinDir - pointer to string representing an alternative
1830*9781SMoriah.Waterland@Sun.COM  *			binary location directory to pass to pkginstall.
1831*9781SMoriah.Waterland@Sun.COM  *			If this is == NULL no alternative binary location is
1832*9781SMoriah.Waterland@Sun.COM  *			passed to pkginstall.
1833*9781SMoriah.Waterland@Sun.COM  *		a_adminFile - pointer to string representing the admin
1834*9781SMoriah.Waterland@Sun.COM  *			file to pass to pkginstall when installing the package.
1835*9781SMoriah.Waterland@Sun.COM  *			If this is == NULL no admin file is given to pkginstall.
1836*9781SMoriah.Waterland@Sun.COM  *		a_stdoutPath - pointer to string representing the local path
1837*9781SMoriah.Waterland@Sun.COM  *			into which all output written by pkginstall to stdout
1838*9781SMoriah.Waterland@Sun.COM  *			is stored.
1839*9781SMoriah.Waterland@Sun.COM  *			If this is == NULL stdout is redirected to /dev/null
1840*9781SMoriah.Waterland@Sun.COM  * Returns:	int	(see ckreturn() function for details)
1841*9781SMoriah.Waterland@Sun.COM  *		0 - success
1842*9781SMoriah.Waterland@Sun.COM  *		1 - package operation failed (fatal error)
1843*9781SMoriah.Waterland@Sun.COM  *		2 - non-fatal error (warning)
1844*9781SMoriah.Waterland@Sun.COM  *		3 - user selected quit (operation interrupted)
1845*9781SMoriah.Waterland@Sun.COM  *		4 - admin settings prevented operation
1846*9781SMoriah.Waterland@Sun.COM  *		5 - interaction required and -n (non-interactive) specified
1847*9781SMoriah.Waterland@Sun.COM  *		"10" will be added to indicate "immediate reboot required"
1848*9781SMoriah.Waterland@Sun.COM  *		"20" will be added to indicate "reboot after install required"
1849*9781SMoriah.Waterland@Sun.COM  */
1850*9781SMoriah.Waterland@Sun.COM 
1851*9781SMoriah.Waterland@Sun.COM static int
1852*9781SMoriah.Waterland@Sun.COM pkgZoneInstall(char *a_zoneName, char **a_inheritedPkgDirs,
1853*9781SMoriah.Waterland@Sun.COM     zone_state_t a_zoneState, char *a_idsName, char *a_altBinDir,
1854*9781SMoriah.Waterland@Sun.COM     char *a_adminFile)
1855*9781SMoriah.Waterland@Sun.COM {
1856*9781SMoriah.Waterland@Sun.COM 	char	*arg[MAXARGS];
1857*9781SMoriah.Waterland@Sun.COM 	char	*p;
1858*9781SMoriah.Waterland@Sun.COM 	char	adminfd_path[PATH_MAX];
1859*9781SMoriah.Waterland@Sun.COM 	char	path[PATH_MAX];
1860*9781SMoriah.Waterland@Sun.COM 	char	pkgstreamfd_path[PATH_MAX];
1861*9781SMoriah.Waterland@Sun.COM 	char	respfilefd_path[PATH_MAX];
1862*9781SMoriah.Waterland@Sun.COM 	int	fds[MAX_FDS];
1863*9781SMoriah.Waterland@Sun.COM 	int	maxfds;
1864*9781SMoriah.Waterland@Sun.COM 	int	n;
1865*9781SMoriah.Waterland@Sun.COM 	int	nargs;
1866*9781SMoriah.Waterland@Sun.COM 
1867*9781SMoriah.Waterland@Sun.COM 	/* entry assertions */
1868*9781SMoriah.Waterland@Sun.COM 
1869*9781SMoriah.Waterland@Sun.COM 	assert(a_zoneName != (char *)NULL);
1870*9781SMoriah.Waterland@Sun.COM 	assert(*a_zoneName != '\0');
1871*9781SMoriah.Waterland@Sun.COM 
1872*9781SMoriah.Waterland@Sun.COM 	/* entry debugging info */
1873*9781SMoriah.Waterland@Sun.COM 
1874*9781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_PKGZONEINSTALL_ENTRY);
1875*9781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_PKGZONEINSTALL_ARGS, a_zoneName, PSTR(pkginst),
1876*9781SMoriah.Waterland@Sun.COM 		PSTR(pkgdev.dirname), PSTR(pkgdev.mount), PSTR(pkgdev.bdevice),
1877*9781SMoriah.Waterland@Sun.COM 		a_zoneState == ZONE_STATE_MOUNTED ? "/a" : "", PSTR(a_idsName),
1878*9781SMoriah.Waterland@Sun.COM 		a_adminFile);
1879*9781SMoriah.Waterland@Sun.COM 
1880*9781SMoriah.Waterland@Sun.COM 	/* generate path to pkginstall */
1881*9781SMoriah.Waterland@Sun.COM 
1882*9781SMoriah.Waterland@Sun.COM 	(void) snprintf(path, sizeof (path), "%s/pkginstall", PKGBIN);
1883*9781SMoriah.Waterland@Sun.COM 
1884*9781SMoriah.Waterland@Sun.COM 	/* start at first file descriptor */
1885*9781SMoriah.Waterland@Sun.COM 
1886*9781SMoriah.Waterland@Sun.COM 	maxfds = 0;
1887*9781SMoriah.Waterland@Sun.COM 
1888*9781SMoriah.Waterland@Sun.COM 	/*
1889*9781SMoriah.Waterland@Sun.COM 	 * generate argument list for call to pkginstall
1890*9781SMoriah.Waterland@Sun.COM 	 */
1891*9781SMoriah.Waterland@Sun.COM 
1892*9781SMoriah.Waterland@Sun.COM 	/* start at argument 0 */
1893*9781SMoriah.Waterland@Sun.COM 
1894*9781SMoriah.Waterland@Sun.COM 	nargs = 0;
1895*9781SMoriah.Waterland@Sun.COM 
1896*9781SMoriah.Waterland@Sun.COM 	/* first argument is path to executable */
1897*9781SMoriah.Waterland@Sun.COM 
1898*9781SMoriah.Waterland@Sun.COM 	arg[nargs++] = path;
1899*9781SMoriah.Waterland@Sun.COM 
1900*9781SMoriah.Waterland@Sun.COM 	/*
1901*9781SMoriah.Waterland@Sun.COM 	 * second argument is always: pass -O debug to pkginstall: debug mode
1902*9781SMoriah.Waterland@Sun.COM 	 */
1903*9781SMoriah.Waterland@Sun.COM 	if (debugFlag == B_TRUE) {
1904*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-O";
1905*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "debug";
1906*9781SMoriah.Waterland@Sun.COM 	}
1907*9781SMoriah.Waterland@Sun.COM 
1908*9781SMoriah.Waterland@Sun.COM 	/* pkgadd -G: pass -G to pkginstall */
1909*9781SMoriah.Waterland@Sun.COM 
1910*9781SMoriah.Waterland@Sun.COM 	if (globalZoneOnly == B_TRUE) {
1911*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-G";
1912*9781SMoriah.Waterland@Sun.COM 	}
1913*9781SMoriah.Waterland@Sun.COM 
1914*9781SMoriah.Waterland@Sun.COM 	/* pkgadd -b dir: pass -b to pkginstall in zone */
1915*9781SMoriah.Waterland@Sun.COM 
1916*9781SMoriah.Waterland@Sun.COM 	if (a_altBinDir != (char *)NULL) {
1917*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-b";
1918*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = a_altBinDir;
1919*9781SMoriah.Waterland@Sun.COM 	}
1920*9781SMoriah.Waterland@Sun.COM 
1921*9781SMoriah.Waterland@Sun.COM 	/* pkgadd -B blocksize: pass -B to pkginstall in zone */
1922*9781SMoriah.Waterland@Sun.COM 
1923*9781SMoriah.Waterland@Sun.COM 	if (rw_block_size != NULL) {
1924*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-B";
1925*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = rw_block_size;
1926*9781SMoriah.Waterland@Sun.COM 	}
1927*9781SMoriah.Waterland@Sun.COM 
1928*9781SMoriah.Waterland@Sun.COM 	/* pkgadd -C: pass -C to pkgadd in zone: disable checksum */
1929*9781SMoriah.Waterland@Sun.COM 
1930*9781SMoriah.Waterland@Sun.COM 	if (disableChecksum) {
1931*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-C";
1932*9781SMoriah.Waterland@Sun.COM 	}
1933*9781SMoriah.Waterland@Sun.COM 
1934*9781SMoriah.Waterland@Sun.COM 	/* pkgadd -A: pass -A to pkgadd in zone: disable attribute checking */
1935*9781SMoriah.Waterland@Sun.COM 
1936*9781SMoriah.Waterland@Sun.COM 	if (disableAttributes) {
1937*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-A";
1938*9781SMoriah.Waterland@Sun.COM 	}
1939*9781SMoriah.Waterland@Sun.COM 
1940*9781SMoriah.Waterland@Sun.COM 	/* pkgadd -S: pass -S to pkgadd in zone: suppress copyright notices */
1941*9781SMoriah.Waterland@Sun.COM 
1942*9781SMoriah.Waterland@Sun.COM 	arg[nargs++] = "-S";
1943*9781SMoriah.Waterland@Sun.COM 
1944*9781SMoriah.Waterland@Sun.COM 	/* pkgadd -I: pass -I to pkgadd in zone: initial install */
1945*9781SMoriah.Waterland@Sun.COM 
1946*9781SMoriah.Waterland@Sun.COM 	if (init_install) {
1947*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-I";
1948*9781SMoriah.Waterland@Sun.COM 	}
1949*9781SMoriah.Waterland@Sun.COM 
1950*9781SMoriah.Waterland@Sun.COM 	/* pkgadd -M: pass -M to pkgadd in zone: dont mount client file sys */
1951*9781SMoriah.Waterland@Sun.COM 
1952*9781SMoriah.Waterland@Sun.COM 	arg[nargs++] = "-M";
1953*9781SMoriah.Waterland@Sun.COM 
1954*9781SMoriah.Waterland@Sun.COM 	/* pkgadd -v: pass -v to pkgadd in zone: trace scripts */
1955*9781SMoriah.Waterland@Sun.COM 
1956*9781SMoriah.Waterland@Sun.COM 	if (pkgverbose) {
1957*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-v";
1958*9781SMoriah.Waterland@Sun.COM 	}
1959*9781SMoriah.Waterland@Sun.COM 
1960*9781SMoriah.Waterland@Sun.COM 	/* pkgadd -z: pass -z to pkgadd in zone fresh inst from pkg save area */
1961*9781SMoriah.Waterland@Sun.COM 
1962*9781SMoriah.Waterland@Sun.COM 	if (saveSpoolInstall) {
1963*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-z";
1964*9781SMoriah.Waterland@Sun.COM 	}
1965*9781SMoriah.Waterland@Sun.COM 
1966*9781SMoriah.Waterland@Sun.COM 	/* pass "-O enable-hollow-package-support" */
1967*9781SMoriah.Waterland@Sun.COM 
1968*9781SMoriah.Waterland@Sun.COM 	if (is_depend_pkginfo_DB()) {
1969*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-O";
1970*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "enable-hollow-package-support";
1971*9781SMoriah.Waterland@Sun.COM 	}
1972*9781SMoriah.Waterland@Sun.COM 
1973*9781SMoriah.Waterland@Sun.COM 	/* pkgadd -t pass -t to pkgadd in zone disable save spool area create */
1974*9781SMoriah.Waterland@Sun.COM 
1975*9781SMoriah.Waterland@Sun.COM 	if (disableSaveSpool) {
1976*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-t";
1977*9781SMoriah.Waterland@Sun.COM 	}
1978*9781SMoriah.Waterland@Sun.COM 
1979*9781SMoriah.Waterland@Sun.COM 	/* if running pkgask, pass -i to pkgadd in zone: running pkgask */
1980*9781SMoriah.Waterland@Sun.COM 
1981*9781SMoriah.Waterland@Sun.COM 	if (askflag) {
1982*9781SMoriah.Waterland@Sun.COM 		echo(MSG_BYPASSING_ZONE, a_zoneName);
1983*9781SMoriah.Waterland@Sun.COM 		return (0);
1984*9781SMoriah.Waterland@Sun.COM 	}
1985*9781SMoriah.Waterland@Sun.COM 
1986*9781SMoriah.Waterland@Sun.COM 	/*
1987*9781SMoriah.Waterland@Sun.COM 	 * pkgadd -n (not pkgask): pass -n to pkginstall: noninteractive mode
1988*9781SMoriah.Waterland@Sun.COM 	 */
1989*9781SMoriah.Waterland@Sun.COM 	if (nointeract && !askflag) {
1990*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-n";
1991*9781SMoriah.Waterland@Sun.COM 	}
1992*9781SMoriah.Waterland@Sun.COM 
1993*9781SMoriah.Waterland@Sun.COM 	/* pkgadd -a admin: pass -a admin to pkginstall in zone: admin file */
1994*9781SMoriah.Waterland@Sun.COM 
1995*9781SMoriah.Waterland@Sun.COM 	if (a_adminFile) {
1996*9781SMoriah.Waterland@Sun.COM 		int fd;
1997*9781SMoriah.Waterland@Sun.COM 		fd = openLocal(a_adminFile, O_RDONLY, tmpdir);
1998*9781SMoriah.Waterland@Sun.COM 		if (fd < 0) {
1999*9781SMoriah.Waterland@Sun.COM 			progerr(ERR_CANNOT_COPY_LOCAL, a_adminFile,
2000*9781SMoriah.Waterland@Sun.COM 				errno, strerror(errno));
2001*9781SMoriah.Waterland@Sun.COM 			return (1);
2002*9781SMoriah.Waterland@Sun.COM 		}
2003*9781SMoriah.Waterland@Sun.COM 		(void) snprintf(adminfd_path, sizeof (adminfd_path),
2004*9781SMoriah.Waterland@Sun.COM 			"/proc/self/fd/%d", fd);
2005*9781SMoriah.Waterland@Sun.COM 		fds[maxfds++] = fd;
2006*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-a";
2007*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = adminfd_path;
2008*9781SMoriah.Waterland@Sun.COM 	}
2009*9781SMoriah.Waterland@Sun.COM 
2010*9781SMoriah.Waterland@Sun.COM 	/* pkgadd -R root: pass -R /a to pkginstall when zone is mounted */
2011*9781SMoriah.Waterland@Sun.COM 	if (a_zoneState == ZONE_STATE_MOUNTED) {
2012*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-R";
2013*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "/a";
2014*9781SMoriah.Waterland@Sun.COM 	}
2015*9781SMoriah.Waterland@Sun.COM 
2016*9781SMoriah.Waterland@Sun.COM 	/*
2017*9781SMoriah.Waterland@Sun.COM 	 * pkgadd -D arg: pass -D dryrun to pkginstall in zone: dryrun
2018*9781SMoriah.Waterland@Sun.COM 	 * mode/file
2019*9781SMoriah.Waterland@Sun.COM 	 */
2020*9781SMoriah.Waterland@Sun.COM 	if (pkgdrtarg) {
2021*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-D";
2022*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = pkgdrtarg;
2023*9781SMoriah.Waterland@Sun.COM 	}
2024*9781SMoriah.Waterland@Sun.COM 
2025*9781SMoriah.Waterland@Sun.COM 	/*
2026*9781SMoriah.Waterland@Sun.COM 	 * pkgadd -c cont: pass -c cont to pkginstall in zone: continuation
2027*9781SMoriah.Waterland@Sun.COM 	 * file
2028*9781SMoriah.Waterland@Sun.COM 	 */
2029*9781SMoriah.Waterland@Sun.COM 	if (pkgcontsrc) {
2030*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-c";
2031*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = pkgcontsrc;
2032*9781SMoriah.Waterland@Sun.COM 	}
2033*9781SMoriah.Waterland@Sun.COM 
2034*9781SMoriah.Waterland@Sun.COM 	/* pkgadd -r resp: pass -r resp to pkginstall in zone: response file */
2035*9781SMoriah.Waterland@Sun.COM 
2036*9781SMoriah.Waterland@Sun.COM 	if (respfile) {
2037*9781SMoriah.Waterland@Sun.COM 		int fd;
2038*9781SMoriah.Waterland@Sun.COM 		fd = openLocal(respfile, O_RDONLY, tmpdir);
2039*9781SMoriah.Waterland@Sun.COM 		if (fd < 0) {
2040*9781SMoriah.Waterland@Sun.COM 			progerr(ERR_CANNOT_COPY_LOCAL, a_adminFile,
2041*9781SMoriah.Waterland@Sun.COM 				errno, strerror(errno));
2042*9781SMoriah.Waterland@Sun.COM 			return (1);
2043*9781SMoriah.Waterland@Sun.COM 		}
2044*9781SMoriah.Waterland@Sun.COM 		(void) snprintf(respfilefd_path,
2045*9781SMoriah.Waterland@Sun.COM 			sizeof (respfilefd_path),
2046*9781SMoriah.Waterland@Sun.COM 			"/proc/self/fd/%d", fd);
2047*9781SMoriah.Waterland@Sun.COM 		fds[maxfds++] = fd;
2048*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-r";
2049*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = respfilefd_path;
2050*9781SMoriah.Waterland@Sun.COM 	}
2051*9781SMoriah.Waterland@Sun.COM 
2052*9781SMoriah.Waterland@Sun.COM 	/* add "-O addzonename" */
2053*9781SMoriah.Waterland@Sun.COM 
2054*9781SMoriah.Waterland@Sun.COM 	arg[nargs++] = "-O";
2055*9781SMoriah.Waterland@Sun.COM 	arg[nargs++] = "addzonename";
2056*9781SMoriah.Waterland@Sun.COM 
2057*9781SMoriah.Waterland@Sun.COM 	if (isPatchUpdate()) {
2058*9781SMoriah.Waterland@Sun.COM 		if (patchPkgRemoval == B_TRUE) {
2059*9781SMoriah.Waterland@Sun.COM 			arg[nargs++] = "-O";
2060*9781SMoriah.Waterland@Sun.COM 			arg[nargs++] = "patchPkgRemoval";
2061*9781SMoriah.Waterland@Sun.COM 		} else {
2062*9781SMoriah.Waterland@Sun.COM 			arg[nargs++] = "-O";
2063*9781SMoriah.Waterland@Sun.COM 			arg[nargs++] = "patchPkgInstall";
2064*9781SMoriah.Waterland@Sun.COM 		}
2065*9781SMoriah.Waterland@Sun.COM 	}
2066*9781SMoriah.Waterland@Sun.COM 
2067*9781SMoriah.Waterland@Sun.COM 	/* add all inherited file systems */
2068*9781SMoriah.Waterland@Sun.COM 
2069*9781SMoriah.Waterland@Sun.COM 	if (a_inheritedPkgDirs != (char **)NULL) {
2070*9781SMoriah.Waterland@Sun.COM 		for (n = 0; a_inheritedPkgDirs[n] != (char *)NULL; n++) {
2071*9781SMoriah.Waterland@Sun.COM 			char	ifs[MAXPATHLEN+22];
2072*9781SMoriah.Waterland@Sun.COM 			(void) snprintf(ifs, sizeof (ifs),
2073*9781SMoriah.Waterland@Sun.COM 				"inherited-filesystem=%s",
2074*9781SMoriah.Waterland@Sun.COM 				a_inheritedPkgDirs[n]);
2075*9781SMoriah.Waterland@Sun.COM 			arg[nargs++] = "-O";
2076*9781SMoriah.Waterland@Sun.COM 			arg[nargs++] = strdup(ifs);
2077*9781SMoriah.Waterland@Sun.COM 		}
2078*9781SMoriah.Waterland@Sun.COM 	}
2079*9781SMoriah.Waterland@Sun.COM 
2080*9781SMoriah.Waterland@Sun.COM 	/*
2081*9781SMoriah.Waterland@Sun.COM 	 * add parent zone info/type
2082*9781SMoriah.Waterland@Sun.COM 	 */
2083*9781SMoriah.Waterland@Sun.COM 
2084*9781SMoriah.Waterland@Sun.COM 	p = z_get_zonename();
2085*9781SMoriah.Waterland@Sun.COM 	if ((p != NULL) && (*p != '\0')) {
2086*9781SMoriah.Waterland@Sun.COM 			char	zn[MAXPATHLEN];
2087*9781SMoriah.Waterland@Sun.COM 			(void) snprintf(zn, sizeof (zn),
2088*9781SMoriah.Waterland@Sun.COM 				"parent-zone-name=%s", p);
2089*9781SMoriah.Waterland@Sun.COM 			arg[nargs++] = "-O";
2090*9781SMoriah.Waterland@Sun.COM 			arg[nargs++] = strdup(zn);
2091*9781SMoriah.Waterland@Sun.COM 	}
2092*9781SMoriah.Waterland@Sun.COM 
2093*9781SMoriah.Waterland@Sun.COM 	/* current zone type */
2094*9781SMoriah.Waterland@Sun.COM 
2095*9781SMoriah.Waterland@Sun.COM 	arg[nargs++] = "-O";
2096*9781SMoriah.Waterland@Sun.COM 	if (z_running_in_global_zone() == B_TRUE) {
2097*9781SMoriah.Waterland@Sun.COM 			char	zn[MAXPATHLEN];
2098*9781SMoriah.Waterland@Sun.COM 			(void) snprintf(zn, sizeof (zn),
2099*9781SMoriah.Waterland@Sun.COM 				"parent-zone-type=%s",
2100*9781SMoriah.Waterland@Sun.COM 				TAG_VALUE_GLOBAL_ZONE);
2101*9781SMoriah.Waterland@Sun.COM 			arg[nargs++] = strdup(zn);
2102*9781SMoriah.Waterland@Sun.COM 	} else {
2103*9781SMoriah.Waterland@Sun.COM 			char	zn[MAXPATHLEN];
2104*9781SMoriah.Waterland@Sun.COM 			(void) snprintf(zn, sizeof (zn),
2105*9781SMoriah.Waterland@Sun.COM 				"parent-zone-type=%s",
2106*9781SMoriah.Waterland@Sun.COM 				TAG_VALUE_NONGLOBAL_ZONE);
2107*9781SMoriah.Waterland@Sun.COM 			arg[nargs++] = strdup(zn);
2108*9781SMoriah.Waterland@Sun.COM 	}
2109*9781SMoriah.Waterland@Sun.COM 
2110*9781SMoriah.Waterland@Sun.COM 	/* add in the package stream file */
2111*9781SMoriah.Waterland@Sun.COM 
2112*9781SMoriah.Waterland@Sun.COM 	if (a_idsName != NULL) {
2113*9781SMoriah.Waterland@Sun.COM 		int fd;
2114*9781SMoriah.Waterland@Sun.COM 		fd = openLocal(a_idsName, O_RDONLY, tmpdir);
2115*9781SMoriah.Waterland@Sun.COM 		if (fd < 0) {
2116*9781SMoriah.Waterland@Sun.COM 			progerr(ERR_STREAM_UNAVAILABLE, a_idsName,
2117*9781SMoriah.Waterland@Sun.COM 				pkginst, strerror(errno));
2118*9781SMoriah.Waterland@Sun.COM 			quit(1);
2119*9781SMoriah.Waterland@Sun.COM 		}
2120*9781SMoriah.Waterland@Sun.COM 		(void) snprintf(pkgstreamfd_path, sizeof (pkgstreamfd_path),
2121*9781SMoriah.Waterland@Sun.COM 			"/proc/self/fd/%d", fd);
2122*9781SMoriah.Waterland@Sun.COM 		fds[maxfds++] = fd;
2123*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = pkgstreamfd_path;
2124*9781SMoriah.Waterland@Sun.COM 	} else {
2125*9781SMoriah.Waterland@Sun.COM 		progerr(ERR_PKGZONEINSTALL_NO_STREAM);
2126*9781SMoriah.Waterland@Sun.COM 		quit(1);
2127*9781SMoriah.Waterland@Sun.COM 	}
2128*9781SMoriah.Waterland@Sun.COM 
2129*9781SMoriah.Waterland@Sun.COM 	/* add package instance name */
2130*9781SMoriah.Waterland@Sun.COM 
2131*9781SMoriah.Waterland@Sun.COM 	arg[nargs++] = pkginst;
2132*9781SMoriah.Waterland@Sun.COM 
2133*9781SMoriah.Waterland@Sun.COM 	/* terminate the argument list */
2134*9781SMoriah.Waterland@Sun.COM 
2135*9781SMoriah.Waterland@Sun.COM 	arg[nargs++] = NULL;
2136*9781SMoriah.Waterland@Sun.COM 
2137*9781SMoriah.Waterland@Sun.COM 	/*
2138*9781SMoriah.Waterland@Sun.COM 	 * run the appropriate pkginstall command in the specified zone
2139*9781SMoriah.Waterland@Sun.COM 	 */
2140*9781SMoriah.Waterland@Sun.COM 
2141*9781SMoriah.Waterland@Sun.COM 	if (debugFlag == B_TRUE) {
2142*9781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_ZONE_EXEC_ENTER, a_zoneName, arg[0]);
2143*9781SMoriah.Waterland@Sun.COM 		for (n = 0; arg[n]; n++) {
2144*9781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_ARG, n, arg[n]);
2145*9781SMoriah.Waterland@Sun.COM 		}
2146*9781SMoriah.Waterland@Sun.COM 	}
2147*9781SMoriah.Waterland@Sun.COM 
2148*9781SMoriah.Waterland@Sun.COM 	/* terminate file descriptor list */
2149*9781SMoriah.Waterland@Sun.COM 
2150*9781SMoriah.Waterland@Sun.COM 	fds[maxfds] = -1;
2151*9781SMoriah.Waterland@Sun.COM 
2152*9781SMoriah.Waterland@Sun.COM 	/* exec command in zone */
2153*9781SMoriah.Waterland@Sun.COM 
2154*9781SMoriah.Waterland@Sun.COM 	n = z_zone_exec(a_zoneName, path, arg, (char *)NULL, (char *)NULL, fds);
2155*9781SMoriah.Waterland@Sun.COM 
2156*9781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_ZONE_EXEC_EXIT, a_zoneName, arg[0], n, "");
2157*9781SMoriah.Waterland@Sun.COM 
2158*9781SMoriah.Waterland@Sun.COM 	/*
2159*9781SMoriah.Waterland@Sun.COM 	 * close any files that were opened for use by the
2160*9781SMoriah.Waterland@Sun.COM 	 * /proc/self/fd interface so they could be passed to programs
2161*9781SMoriah.Waterland@Sun.COM 	 * via the z_zone_exec() interface
2162*9781SMoriah.Waterland@Sun.COM 	 */
2163*9781SMoriah.Waterland@Sun.COM 
2164*9781SMoriah.Waterland@Sun.COM 	for (; maxfds > 0; maxfds--) {
2165*9781SMoriah.Waterland@Sun.COM 		(void) close(fds[maxfds-1]);
2166*9781SMoriah.Waterland@Sun.COM 	}
2167*9781SMoriah.Waterland@Sun.COM 
2168*9781SMoriah.Waterland@Sun.COM 	/* return results of pkginstall in zone execution */
2169*9781SMoriah.Waterland@Sun.COM 
2170*9781SMoriah.Waterland@Sun.COM 	return (n);
2171*9781SMoriah.Waterland@Sun.COM }
2172*9781SMoriah.Waterland@Sun.COM 
2173*9781SMoriah.Waterland@Sun.COM /*
2174*9781SMoriah.Waterland@Sun.COM  * Name:	pkgInstall
2175*9781SMoriah.Waterland@Sun.COM  * Description:	Invoke pkginstall in the current zone to perform an install
2176*9781SMoriah.Waterland@Sun.COM  *		of a single package to the current zone or standalone system
2177*9781SMoriah.Waterland@Sun.COM  * Arguments:	a_altRoot - pointer to string representing the alternative
2178*9781SMoriah.Waterland@Sun.COM  *			root to use for the install
2179*9781SMoriah.Waterland@Sun.COM  *		a_idsName - pointer to string representing the data stream
2180*9781SMoriah.Waterland@Sun.COM  *			device (input data stream) containing the package to
2181*9781SMoriah.Waterland@Sun.COM  *			be installed.
2182*9781SMoriah.Waterland@Sun.COM  *		a_pkgDir - pointer to string representing the path to the
2183*9781SMoriah.Waterland@Sun.COM  *			directory containing the package
2184*9781SMoriah.Waterland@Sun.COM  *		a_altBinDir - pointer to string representing location of the
2185*9781SMoriah.Waterland@Sun.COM  *			pkginstall executable to run. If not NULL, then pass
2186*9781SMoriah.Waterland@Sun.COM  *			the path specified to the -b option to pkginstall.
2187*9781SMoriah.Waterland@Sun.COM  *		a_inheritedPkgDirs - pointer to array of strings, each one
2188*9781SMoriah.Waterland@Sun.COM  *			representing the non-global zones full path of a
2189*9781SMoriah.Waterland@Sun.COM  *			directory that is inherited from the global zone.
2190*9781SMoriah.Waterland@Sun.COM  * Returns:	int	(see ckreturn() function for details)
2191*9781SMoriah.Waterland@Sun.COM  *		0 - success
2192*9781SMoriah.Waterland@Sun.COM  *		1 - package operation failed (fatal error)
2193*9781SMoriah.Waterland@Sun.COM  *		2 - non-fatal error (warning)
2194*9781SMoriah.Waterland@Sun.COM  *		3 - user selected quit (operation interrupted)
2195*9781SMoriah.Waterland@Sun.COM  *		4 - admin settings prevented operation
2196*9781SMoriah.Waterland@Sun.COM  *		5 - interaction required and -n (non-interactive) specified
2197*9781SMoriah.Waterland@Sun.COM  *		"10" will be added to indicate "immediate reboot required"
2198*9781SMoriah.Waterland@Sun.COM  *		"20" will be added to indicate "reboot after install required"
2199*9781SMoriah.Waterland@Sun.COM  * NOTE:	Both a_idsName and a_pkgDir are used to determine where the
2200*9781SMoriah.Waterland@Sun.COM  *		package to be installed is located. If a_idsName is != NULL
2201*9781SMoriah.Waterland@Sun.COM  *		then it must be the path to a device containing a package
2202*9781SMoriah.Waterland@Sun.COM  *		stream that contains the package to be installed. If a_idsName
2203*9781SMoriah.Waterland@Sun.COM  *		is == NULL then a_pkgDir must contain a full path to a directory
2204*9781SMoriah.Waterland@Sun.COM  *		that contains the package to be installed.
2205*9781SMoriah.Waterland@Sun.COM  */
2206*9781SMoriah.Waterland@Sun.COM 
2207*9781SMoriah.Waterland@Sun.COM static int
2208*9781SMoriah.Waterland@Sun.COM pkgInstall(char *a_altRoot, char *a_idsName, char *a_pkgDir, char *a_altBinDir,
2209*9781SMoriah.Waterland@Sun.COM 	char **a_inheritedPkgDirs)
2210*9781SMoriah.Waterland@Sun.COM {
2211*9781SMoriah.Waterland@Sun.COM 	char	*arg[MAXARGS];
2212*9781SMoriah.Waterland@Sun.COM 	char	*p;
2213*9781SMoriah.Waterland@Sun.COM 	char	path[PATH_MAX];
2214*9781SMoriah.Waterland@Sun.COM 	char	buffer[256];
2215*9781SMoriah.Waterland@Sun.COM 	int	n, nargs;
2216*9781SMoriah.Waterland@Sun.COM 
2217*9781SMoriah.Waterland@Sun.COM 	/* entry debugging info */
2218*9781SMoriah.Waterland@Sun.COM 
2219*9781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_PKGINSTALL_ENTRY);
2220*9781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_PKGINSTALL_ARGS, PSTR(pkginst), PSTR(pkgdev.dirname),
2221*9781SMoriah.Waterland@Sun.COM 		PSTR(pkgdev.mount), PSTR(pkgdev.bdevice), PSTR(a_altRoot),
2222*9781SMoriah.Waterland@Sun.COM 		PSTR(a_idsName), PSTR(a_pkgDir));
2223*9781SMoriah.Waterland@Sun.COM 
2224*9781SMoriah.Waterland@Sun.COM 	/* generate full path to 'pkginstall' to run in zone */
2225*9781SMoriah.Waterland@Sun.COM 
2226*9781SMoriah.Waterland@Sun.COM 	(void) snprintf(path, sizeof (path), "%s/pkginstall",
2227*9781SMoriah.Waterland@Sun.COM 		a_altBinDir == (char *)NULL ? PKGBIN : a_altBinDir);
2228*9781SMoriah.Waterland@Sun.COM 	/*
2229*9781SMoriah.Waterland@Sun.COM 	 * generate argument list for call to pkginstall
2230*9781SMoriah.Waterland@Sun.COM 	 */
2231*9781SMoriah.Waterland@Sun.COM 
2232*9781SMoriah.Waterland@Sun.COM 	/* start at argument 0 */
2233*9781SMoriah.Waterland@Sun.COM 
2234*9781SMoriah.Waterland@Sun.COM 	nargs = 0;
2235*9781SMoriah.Waterland@Sun.COM 
2236*9781SMoriah.Waterland@Sun.COM 	/* first argument is path to executable */
2237*9781SMoriah.Waterland@Sun.COM 
2238*9781SMoriah.Waterland@Sun.COM 	arg[nargs++] = path;
2239*9781SMoriah.Waterland@Sun.COM 
2240*9781SMoriah.Waterland@Sun.COM 	/*
2241*9781SMoriah.Waterland@Sun.COM 	 * second argument is always: pass -O debug to pkginstall: debug mode
2242*9781SMoriah.Waterland@Sun.COM 	 */
2243*9781SMoriah.Waterland@Sun.COM 	if (debugFlag == B_TRUE) {
2244*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-O";
2245*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "debug";
2246*9781SMoriah.Waterland@Sun.COM 	}
2247*9781SMoriah.Waterland@Sun.COM 
2248*9781SMoriah.Waterland@Sun.COM 	/* Installation is from a patch package. */
2249*9781SMoriah.Waterland@Sun.COM 
2250*9781SMoriah.Waterland@Sun.COM 	if (isPatchUpdate()) {
2251*9781SMoriah.Waterland@Sun.COM 		if (patchPkgRemoval == B_TRUE) {
2252*9781SMoriah.Waterland@Sun.COM 			arg[nargs++] = "-O";
2253*9781SMoriah.Waterland@Sun.COM 			arg[nargs++] = "patchPkgRemoval";
2254*9781SMoriah.Waterland@Sun.COM 		} else {
2255*9781SMoriah.Waterland@Sun.COM 			arg[nargs++] = "-O";
2256*9781SMoriah.Waterland@Sun.COM 			arg[nargs++] = "patchPkgInstall";
2257*9781SMoriah.Waterland@Sun.COM 		}
2258*9781SMoriah.Waterland@Sun.COM 	}
2259*9781SMoriah.Waterland@Sun.COM 
2260*9781SMoriah.Waterland@Sun.COM 	/*
2261*9781SMoriah.Waterland@Sun.COM 	 * pkgadd -G: pass -G to pkginstall if:
2262*9781SMoriah.Waterland@Sun.COM 	 *  - the -G option is specified on the pkgadd command line
2263*9781SMoriah.Waterland@Sun.COM 	 *  - this package is marked 'this zone only':
2264*9781SMoriah.Waterland@Sun.COM 	 *  -- package has SUNW_PKG_THISZONE=true, or
2265*9781SMoriah.Waterland@Sun.COM 	 *  -- package has a request script
2266*9781SMoriah.Waterland@Sun.COM 	 * Setting -G for pkginstall causes pkginstall to install the package
2267*9781SMoriah.Waterland@Sun.COM 	 * in the target zone. If running in the global zone, will install the
2268*9781SMoriah.Waterland@Sun.COM 	 * package and mark the package as installed "in the global zone only".
2269*9781SMoriah.Waterland@Sun.COM 	 * If running in a non-global zone, will just install the package.
2270*9781SMoriah.Waterland@Sun.COM 	 */
2271*9781SMoriah.Waterland@Sun.COM 
2272*9781SMoriah.Waterland@Sun.COM 	if (globalZoneOnly == B_TRUE) {
2273*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-G";
2274*9781SMoriah.Waterland@Sun.COM 	} else if (pkgPackageIsThisZone(pkginst) == B_TRUE) {
2275*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-G";
2276*9781SMoriah.Waterland@Sun.COM 	}
2277*9781SMoriah.Waterland@Sun.COM 
2278*9781SMoriah.Waterland@Sun.COM 	/* pkgadd -b dir: pass -b to pkginstall */
2279*9781SMoriah.Waterland@Sun.COM 
2280*9781SMoriah.Waterland@Sun.COM 	if (a_altBinDir != (char *)NULL) {
2281*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-b";
2282*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = a_altBinDir;
2283*9781SMoriah.Waterland@Sun.COM 	}
2284*9781SMoriah.Waterland@Sun.COM 
2285*9781SMoriah.Waterland@Sun.COM 	/* pkgadd -B blocksize: pass -B to pkginstall */
2286*9781SMoriah.Waterland@Sun.COM 
2287*9781SMoriah.Waterland@Sun.COM 	if (rw_block_size != NULL) {
2288*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-B";
2289*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = rw_block_size;
2290*9781SMoriah.Waterland@Sun.COM 	}
2291*9781SMoriah.Waterland@Sun.COM 
2292*9781SMoriah.Waterland@Sun.COM 	/* pkgadd -C: pass -C to pkginstall: disable checksum */
2293*9781SMoriah.Waterland@Sun.COM 
2294*9781SMoriah.Waterland@Sun.COM 	if (disableChecksum) {
2295*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-C";
2296*9781SMoriah.Waterland@Sun.COM 	}
2297*9781SMoriah.Waterland@Sun.COM 
2298*9781SMoriah.Waterland@Sun.COM 	/* pkgadd -A: pass -A to pkginstall: disable attribute checking */
2299*9781SMoriah.Waterland@Sun.COM 
2300*9781SMoriah.Waterland@Sun.COM 	if (disableAttributes) {
2301*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-A";
2302*9781SMoriah.Waterland@Sun.COM 	}
2303*9781SMoriah.Waterland@Sun.COM 
2304*9781SMoriah.Waterland@Sun.COM 	/*
2305*9781SMoriah.Waterland@Sun.COM 	 * NONABI_SCRIPTS defined: pass -o to pkginstall; refers to a
2306*9781SMoriah.Waterland@Sun.COM 	 * pkg requiring operator interaction during a procedure script
2307*9781SMoriah.Waterland@Sun.COM 	 * (common before on1093)
2308*9781SMoriah.Waterland@Sun.COM 	 */
2309*9781SMoriah.Waterland@Sun.COM 
2310*9781SMoriah.Waterland@Sun.COM 	if (old_pkg) {
2311*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-o";
2312*9781SMoriah.Waterland@Sun.COM 	}
2313*9781SMoriah.Waterland@Sun.COM 
2314*9781SMoriah.Waterland@Sun.COM 	/*
2315*9781SMoriah.Waterland@Sun.COM 	 * PKG_NONABI_SYMLINKS defined: pass -y to pkginstall; process
2316*9781SMoriah.Waterland@Sun.COM 	 * symlinks consistent with old behavior
2317*9781SMoriah.Waterland@Sun.COM 	 */
2318*9781SMoriah.Waterland@Sun.COM 
2319*9781SMoriah.Waterland@Sun.COM 	if (old_symlinks) {
2320*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-y";
2321*9781SMoriah.Waterland@Sun.COM 	}
2322*9781SMoriah.Waterland@Sun.COM 
2323*9781SMoriah.Waterland@Sun.COM 	/*
2324*9781SMoriah.Waterland@Sun.COM 	 * PKG_ABI_NAMELENGTH defined: pass -e to pkginstall; causes
2325*9781SMoriah.Waterland@Sun.COM 	 * package name length to be restricted
2326*9781SMoriah.Waterland@Sun.COM 	 */
2327*9781SMoriah.Waterland@Sun.COM 
2328*9781SMoriah.Waterland@Sun.COM 	if (ABI_namelength) {
2329*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-e";
2330*9781SMoriah.Waterland@Sun.COM 	}
2331*9781SMoriah.Waterland@Sun.COM 
2332*9781SMoriah.Waterland@Sun.COM 	/* pkgadd -S: pass -S to pkginstall: suppress copyright notices */
2333*9781SMoriah.Waterland@Sun.COM 
2334*9781SMoriah.Waterland@Sun.COM 	if (suppressCopyright) {
2335*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-S";
2336*9781SMoriah.Waterland@Sun.COM 	}
2337*9781SMoriah.Waterland@Sun.COM 
2338*9781SMoriah.Waterland@Sun.COM 	/* pkgadd -I: pass -I to pkginstall: initial install being performed */
2339*9781SMoriah.Waterland@Sun.COM 
2340*9781SMoriah.Waterland@Sun.COM 	if (init_install) {
2341*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-I";
2342*9781SMoriah.Waterland@Sun.COM 	}
2343*9781SMoriah.Waterland@Sun.COM 
2344*9781SMoriah.Waterland@Sun.COM 	/* pkgadd -M: pass -M to pkginstall: dont mount client file systems */
2345*9781SMoriah.Waterland@Sun.COM 
2346*9781SMoriah.Waterland@Sun.COM 	if (no_map_client) {
2347*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-M";
2348*9781SMoriah.Waterland@Sun.COM 	}
2349*9781SMoriah.Waterland@Sun.COM 
2350*9781SMoriah.Waterland@Sun.COM 	/* pkgadd -v: pass -v to pkginstall: trace scripts */
2351*9781SMoriah.Waterland@Sun.COM 
2352*9781SMoriah.Waterland@Sun.COM 	if (pkgverbose) {
2353*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-v";
2354*9781SMoriah.Waterland@Sun.COM 	}
2355*9781SMoriah.Waterland@Sun.COM 
2356*9781SMoriah.Waterland@Sun.COM 	/* pkgadd -z: pass -z to pkginstall: fresh install from pkg save area */
2357*9781SMoriah.Waterland@Sun.COM 
2358*9781SMoriah.Waterland@Sun.COM 	if (saveSpoolInstall) {
2359*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-z";
2360*9781SMoriah.Waterland@Sun.COM 	}
2361*9781SMoriah.Waterland@Sun.COM 
2362*9781SMoriah.Waterland@Sun.COM 	/*
2363*9781SMoriah.Waterland@Sun.COM 	 * if running in a non-global zone and the 'hollow' attribute is
2364*9781SMoriah.Waterland@Sun.COM 	 * passed in, then pass -h to pkginstall so that it knows how to
2365*9781SMoriah.Waterland@Sun.COM 	 * handle hollow packages for this local zone.
2366*9781SMoriah.Waterland@Sun.COM 	 */
2367*9781SMoriah.Waterland@Sun.COM 
2368*9781SMoriah.Waterland@Sun.COM 	if (!z_running_in_global_zone() && is_depend_pkginfo_DB()) {
2369*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-h";
2370*9781SMoriah.Waterland@Sun.COM 	}
2371*9781SMoriah.Waterland@Sun.COM 
2372*9781SMoriah.Waterland@Sun.COM 	/* pkgadd -t: pass -t to pkginstall: disable save spool area creation */
2373*9781SMoriah.Waterland@Sun.COM 
2374*9781SMoriah.Waterland@Sun.COM 	if (disableSaveSpool) {
2375*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-t";
2376*9781SMoriah.Waterland@Sun.COM 	}
2377*9781SMoriah.Waterland@Sun.COM 
2378*9781SMoriah.Waterland@Sun.COM 	/* if running pkgask, pass -i to pkginstall: running pkgask */
2379*9781SMoriah.Waterland@Sun.COM 
2380*9781SMoriah.Waterland@Sun.COM 	if (askflag) {
2381*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-i";
2382*9781SMoriah.Waterland@Sun.COM 	}
2383*9781SMoriah.Waterland@Sun.COM 
2384*9781SMoriah.Waterland@Sun.COM 	/* pkgadd -n (not pkgask): pass -n to pkginstall: noninteractive mode */
2385*9781SMoriah.Waterland@Sun.COM 
2386*9781SMoriah.Waterland@Sun.COM 	if (nointeract && !askflag) {
2387*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-n";
2388*9781SMoriah.Waterland@Sun.COM 	}
2389*9781SMoriah.Waterland@Sun.COM 
2390*9781SMoriah.Waterland@Sun.COM 	/* pkgadd -a admin: pass -a admin to pkginstall: admin file */
2391*9781SMoriah.Waterland@Sun.COM 
2392*9781SMoriah.Waterland@Sun.COM 	if (admnfile) {
2393*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-a";
2394*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = admnfile;
2395*9781SMoriah.Waterland@Sun.COM 	}
2396*9781SMoriah.Waterland@Sun.COM 
2397*9781SMoriah.Waterland@Sun.COM 	/* pkgadd -D dryrun: pass -D dryrun to pkginstall: dryrun mode/file */
2398*9781SMoriah.Waterland@Sun.COM 
2399*9781SMoriah.Waterland@Sun.COM 	if (pkgdrtarg) {
2400*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-D";
2401*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = pkgdrtarg;
2402*9781SMoriah.Waterland@Sun.COM 	}
2403*9781SMoriah.Waterland@Sun.COM 
2404*9781SMoriah.Waterland@Sun.COM 	/* pkgadd -c cont: pass -c cont to pkginstall: continuation file */
2405*9781SMoriah.Waterland@Sun.COM 
2406*9781SMoriah.Waterland@Sun.COM 	if (pkgcontsrc) {
2407*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-c";
2408*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = pkgcontsrc;
2409*9781SMoriah.Waterland@Sun.COM 	}
2410*9781SMoriah.Waterland@Sun.COM 
2411*9781SMoriah.Waterland@Sun.COM 	/* pkgadd -V vfstab: pass -V vfstab to pkginstall: alternate vfstab */
2412*9781SMoriah.Waterland@Sun.COM 
2413*9781SMoriah.Waterland@Sun.COM 	if (vfstab_file) {
2414*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-V";
2415*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = vfstab_file;
2416*9781SMoriah.Waterland@Sun.COM 	}
2417*9781SMoriah.Waterland@Sun.COM 
2418*9781SMoriah.Waterland@Sun.COM 	/* pkgadd -r resp: pass -r resp to pkginstall: response file */
2419*9781SMoriah.Waterland@Sun.COM 
2420*9781SMoriah.Waterland@Sun.COM 	if (respfile) {
2421*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-r";
2422*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = respfile;
2423*9781SMoriah.Waterland@Sun.COM 	}
2424*9781SMoriah.Waterland@Sun.COM 
2425*9781SMoriah.Waterland@Sun.COM 	/* pkgadd -R root: pass -R root to pkginstall: alternative root */
2426*9781SMoriah.Waterland@Sun.COM 
2427*9781SMoriah.Waterland@Sun.COM 	if (a_altRoot && *a_altRoot) {
2428*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-R";
2429*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = a_altRoot;
2430*9781SMoriah.Waterland@Sun.COM 	}
2431*9781SMoriah.Waterland@Sun.COM 
2432*9781SMoriah.Waterland@Sun.COM 	/*
2433*9781SMoriah.Waterland@Sun.COM 	 * If input data stream is available,
2434*9781SMoriah.Waterland@Sun.COM 	 * - add: -d ids_name -p number_of_parts
2435*9781SMoriah.Waterland@Sun.COM 	 * else,
2436*9781SMoriah.Waterland@Sun.COM 	 * - add: -d device -m mount [-f type]
2437*9781SMoriah.Waterland@Sun.COM 	 */
2438*9781SMoriah.Waterland@Sun.COM 
2439*9781SMoriah.Waterland@Sun.COM 	if (a_idsName != NULL) {
2440*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-d";
2441*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = a_idsName;
2442*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-p";
2443*9781SMoriah.Waterland@Sun.COM 		ds_close(1);
2444*9781SMoriah.Waterland@Sun.COM 		ds_putinfo(buffer);
2445*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = buffer;
2446*9781SMoriah.Waterland@Sun.COM 	} else if (pkgdev.mount != NULL) {
2447*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-d";
2448*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = pkgdev.bdevice;
2449*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = "-m";
2450*9781SMoriah.Waterland@Sun.COM 		arg[nargs++] = pkgdev.mount;
2451*9781SMoriah.Waterland@Sun.COM 		if (pkgdev.fstyp != NULL) {
2452*9781SMoriah.Waterland@Sun.COM 			arg[nargs++] = "-f";
2453*9781SMoriah.Waterland@Sun.COM 			arg[nargs++] = pkgdev.fstyp;
2454*9781SMoriah.Waterland@Sun.COM 		}
2455*9781SMoriah.Waterland@Sun.COM 	}
2456*9781SMoriah.Waterland@Sun.COM 
2457*9781SMoriah.Waterland@Sun.COM 	/* add all inherited file systems */
2458*9781SMoriah.Waterland@Sun.COM 
2459*9781SMoriah.Waterland@Sun.COM 	if (a_inheritedPkgDirs != (char **)NULL) {
2460*9781SMoriah.Waterland@Sun.COM 		for (n = 0; a_inheritedPkgDirs[n] != (char *)NULL; n++) {
2461*9781SMoriah.Waterland@Sun.COM 			char	ifs[MAXPATHLEN+22];
2462*9781SMoriah.Waterland@Sun.COM 			(void) snprintf(ifs, sizeof (ifs),
2463*9781SMoriah.Waterland@Sun.COM 				"inherited-filesystem=%s",
2464*9781SMoriah.Waterland@Sun.COM 				a_inheritedPkgDirs[n]);
2465*9781SMoriah.Waterland@Sun.COM 			arg[nargs++] = "-O";
2466*9781SMoriah.Waterland@Sun.COM 			arg[nargs++] = strdup(ifs);
2467*9781SMoriah.Waterland@Sun.COM 		}
2468*9781SMoriah.Waterland@Sun.COM 	}
2469*9781SMoriah.Waterland@Sun.COM 
2470*9781SMoriah.Waterland@Sun.COM 	/*
2471*9781SMoriah.Waterland@Sun.COM 	 * add parent zone info/type
2472*9781SMoriah.Waterland@Sun.COM 	 */
2473*9781SMoriah.Waterland@Sun.COM 
2474*9781SMoriah.Waterland@Sun.COM 	p = z_get_zonename();
2475*9781SMoriah.Waterland@Sun.COM 	if ((p != NULL) && (*p != '\0')) {
2476*9781SMoriah.Waterland@Sun.COM 			char	zn[MAXPATHLEN];
2477*9781SMoriah.Waterland@Sun.COM 			(void) snprintf(zn, sizeof (zn),
2478*9781SMoriah.Waterland@Sun.COM 				"parent-zone-name=%s", p);
2479*9781SMoriah.Waterland@Sun.COM 			arg[nargs++] = "-O";
2480*9781SMoriah.Waterland@Sun.COM 			arg[nargs++] = strdup(zn);
2481*9781SMoriah.Waterland@Sun.COM 	}
2482*9781SMoriah.Waterland@Sun.COM 
2483*9781SMoriah.Waterland@Sun.COM 	/* current zone type */
2484*9781SMoriah.Waterland@Sun.COM 
2485*9781SMoriah.Waterland@Sun.COM 	arg[nargs++] = "-O";
2486*9781SMoriah.Waterland@Sun.COM 	if (z_running_in_global_zone() == B_TRUE) {
2487*9781SMoriah.Waterland@Sun.COM 			char	zn[MAXPATHLEN];
2488*9781SMoriah.Waterland@Sun.COM 			(void) snprintf(zn, sizeof (zn),
2489*9781SMoriah.Waterland@Sun.COM 				"parent-zone-type=%s",
2490*9781SMoriah.Waterland@Sun.COM 				TAG_VALUE_GLOBAL_ZONE);
2491*9781SMoriah.Waterland@Sun.COM 			arg[nargs++] = strdup(zn);
2492*9781SMoriah.Waterland@Sun.COM 	} else {
2493*9781SMoriah.Waterland@Sun.COM 			char	zn[MAXPATHLEN];
2494*9781SMoriah.Waterland@Sun.COM 			(void) snprintf(zn, sizeof (zn),
2495*9781SMoriah.Waterland@Sun.COM 				"parent-zone-type=%s",
2496*9781SMoriah.Waterland@Sun.COM 				TAG_VALUE_NONGLOBAL_ZONE);
2497*9781SMoriah.Waterland@Sun.COM 			arg[nargs++] = strdup(zn);
2498*9781SMoriah.Waterland@Sun.COM 	}
2499*9781SMoriah.Waterland@Sun.COM 
2500*9781SMoriah.Waterland@Sun.COM 	/* pass -N to pkginstall: program name to report */
2501*9781SMoriah.Waterland@Sun.COM 
2502*9781SMoriah.Waterland@Sun.COM 	arg[nargs++] = "-N";
2503*9781SMoriah.Waterland@Sun.COM 	arg[nargs++] = get_prog_name();
2504*9781SMoriah.Waterland@Sun.COM 
2505*9781SMoriah.Waterland@Sun.COM 	/* add package directory name */
2506*9781SMoriah.Waterland@Sun.COM 
2507*9781SMoriah.Waterland@Sun.COM 	arg[nargs++] = a_pkgDir;
2508*9781SMoriah.Waterland@Sun.COM 
2509*9781SMoriah.Waterland@Sun.COM 	/* add package instance name */
2510*9781SMoriah.Waterland@Sun.COM 
2511*9781SMoriah.Waterland@Sun.COM 	arg[nargs++] = pkginst;
2512*9781SMoriah.Waterland@Sun.COM 
2513*9781SMoriah.Waterland@Sun.COM 	/* terminate the argument list */
2514*9781SMoriah.Waterland@Sun.COM 
2515*9781SMoriah.Waterland@Sun.COM 	arg[nargs++] = NULL;
2516*9781SMoriah.Waterland@Sun.COM 
2517*9781SMoriah.Waterland@Sun.COM 	/*
2518*9781SMoriah.Waterland@Sun.COM 	 * run the appropriate pkginstall command in the specified zone
2519*9781SMoriah.Waterland@Sun.COM 	 */
2520*9781SMoriah.Waterland@Sun.COM 
2521*9781SMoriah.Waterland@Sun.COM 	if (debugFlag == B_TRUE) {
2522*9781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_ZONE_EXEC_ENTER, "global", arg[0]);
2523*9781SMoriah.Waterland@Sun.COM 		for (n = 0; arg[n]; n++) {
2524*9781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_ARG, n, arg[n]);
2525*9781SMoriah.Waterland@Sun.COM 		}
2526*9781SMoriah.Waterland@Sun.COM 	}
2527*9781SMoriah.Waterland@Sun.COM 
2528*9781SMoriah.Waterland@Sun.COM 	/* execute pkginstall command */
2529*9781SMoriah.Waterland@Sun.COM 
2530*9781SMoriah.Waterland@Sun.COM 	n = pkgexecv(NULL, NULL, NULL, NULL, arg);
2531*9781SMoriah.Waterland@Sun.COM 
2532*9781SMoriah.Waterland@Sun.COM 	/* return results of pkginstall execution */
2533*9781SMoriah.Waterland@Sun.COM 
2534*9781SMoriah.Waterland@Sun.COM 	return (n);
2535*9781SMoriah.Waterland@Sun.COM }
2536*9781SMoriah.Waterland@Sun.COM 
2537*9781SMoriah.Waterland@Sun.COM /*
2538*9781SMoriah.Waterland@Sun.COM  *  function to clear out any exisiting error return conditions that may have
2539*9781SMoriah.Waterland@Sun.COM  *  been set by previous calls to ckreturn()
2540*9781SMoriah.Waterland@Sun.COM  */
2541*9781SMoriah.Waterland@Sun.COM static void
2542*9781SMoriah.Waterland@Sun.COM resetreturn()
2543*9781SMoriah.Waterland@Sun.COM {
2544*9781SMoriah.Waterland@Sun.COM 	admnflag = 0;	/* != 0 if any pkg op admin setting failure (4) */
2545*9781SMoriah.Waterland@Sun.COM 	doreboot = 0;	/* != 0 if reboot required after installation (>= 10) */
2546*9781SMoriah.Waterland@Sun.COM 	failflag = 0;	/* != 0 if fatal error has occurred (1) */
2547*9781SMoriah.Waterland@Sun.COM 	intrflag = 0;	/* != 0 if user selected quit (3) */
2548*9781SMoriah.Waterland@Sun.COM 	ireboot = 0;	/* != 0 if immediate reboot required (>= 20) */
2549*9781SMoriah.Waterland@Sun.COM 	nullflag = 0;	/* != 0 if admin interaction required (5) */
2550*9781SMoriah.Waterland@Sun.COM 	warnflag = 0;	/* != 0 if non-fatal error has occurred (2) */
2551*9781SMoriah.Waterland@Sun.COM 	interrupted = 0;	/* last pkg op was quit (1,2,3,4,5) */
2552*9781SMoriah.Waterland@Sun.COM 	needconsult = 0;	/* essential ask admin now (1,2,3,5) */
2553*9781SMoriah.Waterland@Sun.COM }
2554*9781SMoriah.Waterland@Sun.COM 
2555*9781SMoriah.Waterland@Sun.COM /*
2556*9781SMoriah.Waterland@Sun.COM  *  function which checks the indicated return value
2557*9781SMoriah.Waterland@Sun.COM  *  and indicates disposition of installation
2558*9781SMoriah.Waterland@Sun.COM  */
2559*9781SMoriah.Waterland@Sun.COM static void
2560*9781SMoriah.Waterland@Sun.COM ckreturn(int retcode)
2561*9781SMoriah.Waterland@Sun.COM {
2562*9781SMoriah.Waterland@Sun.COM 	/*
2563*9781SMoriah.Waterland@Sun.COM 	 * entry debugging info
2564*9781SMoriah.Waterland@Sun.COM 	 */
2565*9781SMoriah.Waterland@Sun.COM 
2566*9781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_PKGADD_CKRETURN, retcode, PSTR(pkginst));
2567*9781SMoriah.Waterland@Sun.COM 
2568*9781SMoriah.Waterland@Sun.COM 	/* reset needconsult so it only reflects this call to ckreturn */
2569*9781SMoriah.Waterland@Sun.COM 	needconsult = 0;
2570*9781SMoriah.Waterland@Sun.COM 
2571*9781SMoriah.Waterland@Sun.COM 	switch (retcode) {
2572*9781SMoriah.Waterland@Sun.COM 	    case  0:		/* successful */
2573*9781SMoriah.Waterland@Sun.COM 	    case 10:
2574*9781SMoriah.Waterland@Sun.COM 	    case 20:
2575*9781SMoriah.Waterland@Sun.COM 		break; /* empty case */
2576*9781SMoriah.Waterland@Sun.COM 
2577*9781SMoriah.Waterland@Sun.COM 	    case  1:		/* package operation failed (fatal error) */
2578*9781SMoriah.Waterland@Sun.COM 	    case 11:
2579*9781SMoriah.Waterland@Sun.COM 	    case 21:
2580*9781SMoriah.Waterland@Sun.COM 		failflag++;
2581*9781SMoriah.Waterland@Sun.COM 		interrupted++;
2582*9781SMoriah.Waterland@Sun.COM 		needconsult++;
2583*9781SMoriah.Waterland@Sun.COM 		break;
2584*9781SMoriah.Waterland@Sun.COM 
2585*9781SMoriah.Waterland@Sun.COM 	    case  2:		/* non-fatal error (warning) */
2586*9781SMoriah.Waterland@Sun.COM 	    case 12:
2587*9781SMoriah.Waterland@Sun.COM 	    case 22:
2588*9781SMoriah.Waterland@Sun.COM 		warnflag++;
2589*9781SMoriah.Waterland@Sun.COM 		interrupted++;
2590*9781SMoriah.Waterland@Sun.COM 		needconsult++;
2591*9781SMoriah.Waterland@Sun.COM 		break;
2592*9781SMoriah.Waterland@Sun.COM 
2593*9781SMoriah.Waterland@Sun.COM 	    case  3:		/* user selected quit; operation interrupted */
2594*9781SMoriah.Waterland@Sun.COM 	    case 13:
2595*9781SMoriah.Waterland@Sun.COM 	    case 23:
2596*9781SMoriah.Waterland@Sun.COM 		intrflag++;
2597*9781SMoriah.Waterland@Sun.COM 		interrupted++;
2598*9781SMoriah.Waterland@Sun.COM 		needconsult++;
2599*9781SMoriah.Waterland@Sun.COM 		break;
2600*9781SMoriah.Waterland@Sun.COM 
2601*9781SMoriah.Waterland@Sun.COM 	    case  4:		/* admin settings prevented operation */
2602*9781SMoriah.Waterland@Sun.COM 	    case 14:
2603*9781SMoriah.Waterland@Sun.COM 	    case 24:
2604*9781SMoriah.Waterland@Sun.COM 		admnflag++;
2605*9781SMoriah.Waterland@Sun.COM 		interrupted++;
2606*9781SMoriah.Waterland@Sun.COM 		break;
2607*9781SMoriah.Waterland@Sun.COM 
2608*9781SMoriah.Waterland@Sun.COM 	    case  5:		/* administration: interaction req (no -n) */
2609*9781SMoriah.Waterland@Sun.COM 	    case 15:
2610*9781SMoriah.Waterland@Sun.COM 	    case 25:
2611*9781SMoriah.Waterland@Sun.COM 		nullflag++;
2612*9781SMoriah.Waterland@Sun.COM 		interrupted++;
2613*9781SMoriah.Waterland@Sun.COM 		needconsult++;
2614*9781SMoriah.Waterland@Sun.COM 		break;
2615*9781SMoriah.Waterland@Sun.COM 
2616*9781SMoriah.Waterland@Sun.COM 	    default:
2617*9781SMoriah.Waterland@Sun.COM 		failflag++;
2618*9781SMoriah.Waterland@Sun.COM 		interrupted++;
2619*9781SMoriah.Waterland@Sun.COM 		needconsult++;
2620*9781SMoriah.Waterland@Sun.COM 		return;
2621*9781SMoriah.Waterland@Sun.COM 	}
2622*9781SMoriah.Waterland@Sun.COM 
2623*9781SMoriah.Waterland@Sun.COM 	if (retcode >= 20) {
2624*9781SMoriah.Waterland@Sun.COM 		ireboot++;
2625*9781SMoriah.Waterland@Sun.COM 	} else if (retcode >= 10) {
2626*9781SMoriah.Waterland@Sun.COM 		doreboot++;
2627*9781SMoriah.Waterland@Sun.COM 	}
2628*9781SMoriah.Waterland@Sun.COM }
2629*9781SMoriah.Waterland@Sun.COM 
2630*9781SMoriah.Waterland@Sun.COM static void
2631*9781SMoriah.Waterland@Sun.COM usage(void)
2632*9781SMoriah.Waterland@Sun.COM {
2633*9781SMoriah.Waterland@Sun.COM 	char *prog = get_prog_name();
2634*9781SMoriah.Waterland@Sun.COM 
2635*9781SMoriah.Waterland@Sun.COM 	if (askflag) {
2636*9781SMoriah.Waterland@Sun.COM 		(void) fprintf(stderr, ERR_USAGE_PKGASK, prog);
2637*9781SMoriah.Waterland@Sun.COM 	} else if (z_running_in_global_zone() == B_FALSE) {
2638*9781SMoriah.Waterland@Sun.COM 		(void) fprintf(stderr, ERR_USAGE_PKGADD_NONGLOBALZONE,
2639*9781SMoriah.Waterland@Sun.COM 			prog, prog);
2640*9781SMoriah.Waterland@Sun.COM 	} else {
2641*9781SMoriah.Waterland@Sun.COM 		(void) fprintf(stderr, ERR_USAGE_PKGADD_GLOBALZONE,
2642*9781SMoriah.Waterland@Sun.COM 			prog, prog);
2643*9781SMoriah.Waterland@Sun.COM 	}
2644*9781SMoriah.Waterland@Sun.COM }
2645*9781SMoriah.Waterland@Sun.COM 
2646*9781SMoriah.Waterland@Sun.COM /*
2647*9781SMoriah.Waterland@Sun.COM  * Name:	check_applicability
2648*9781SMoriah.Waterland@Sun.COM  * Description:	determine if a package is installable in this zone; that is,
2649*9781SMoriah.Waterland@Sun.COM  *		does the scope of install conflict with existing installation
2650*9781SMoriah.Waterland@Sun.COM  *		or can the package be installed
2651*9781SMoriah.Waterland@Sun.COM  * Arguments:	a_packageDir - [RO, *RO] - (char *)
2652*9781SMoriah.Waterland@Sun.COM  *			Pointer to string representing the directory where the
2653*9781SMoriah.Waterland@Sun.COM  *			package is located
2654*9781SMoriah.Waterland@Sun.COM  *		a_pkgInst - [RO, *RO] - (char *)
2655*9781SMoriah.Waterland@Sun.COM  *			Pointer to string representing the name of the package
2656*9781SMoriah.Waterland@Sun.COM  *			to check
2657*9781SMoriah.Waterland@Sun.COM  *		a_rootPath - [RO, *RO] - (char *)
2658*9781SMoriah.Waterland@Sun.COM  *			Pointer to string representing path to the root of the
2659*9781SMoriah.Waterland@Sun.COM  *			file system where the package is to be installed - this
2660*9781SMoriah.Waterland@Sun.COM  *			is usually the same as the "-R" argument to pkgadd
2661*9781SMoriah.Waterland@Sun.COM  *		a_flags - [RO, *RO] - (CAF_T)
2662*9781SMoriah.Waterland@Sun.COM  *			Flags set by the caller to indicate the conditions
2663*9781SMoriah.Waterland@Sun.COM  *			under which the package is to be installed:
2664*9781SMoriah.Waterland@Sun.COM  *				CAF_IN_GLOBAL_ZONE - in global zone
2665*9781SMoriah.Waterland@Sun.COM  *				CAF_SCOPE_GLOBAL - -G specified
2666*9781SMoriah.Waterland@Sun.COM  *				CAF_SCOPE_NONGLOBAL - -Z specified
2667*9781SMoriah.Waterland@Sun.COM  * Returns:	boolean_t
2668*9781SMoriah.Waterland@Sun.COM  *			B_TRUE - the package can be installed
2669*9781SMoriah.Waterland@Sun.COM  *			B_FALSE - the package can not be installed
2670*9781SMoriah.Waterland@Sun.COM  */
2671*9781SMoriah.Waterland@Sun.COM 
2672*9781SMoriah.Waterland@Sun.COM static boolean_t
2673*9781SMoriah.Waterland@Sun.COM check_applicability(char *a_packageDir, char *a_pkgInst, char *a_rootPath,
2674*9781SMoriah.Waterland@Sun.COM 	CAF_T a_flags)
2675*9781SMoriah.Waterland@Sun.COM {
2676*9781SMoriah.Waterland@Sun.COM 	FILE		*pkginfoFP;
2677*9781SMoriah.Waterland@Sun.COM 	FILE		*pkgmapFP;
2678*9781SMoriah.Waterland@Sun.COM 	boolean_t	all_zones;	/* pkg is "all zones" only */
2679*9781SMoriah.Waterland@Sun.COM 	boolean_t	in_gz_only;	/* pkg installed in global zone only */
2680*9781SMoriah.Waterland@Sun.COM 	boolean_t	is_hollow;	/* pkg is "hollow" */
2681*9781SMoriah.Waterland@Sun.COM 	boolean_t	pkg_installed;	/* pkg is installed */
2682*9781SMoriah.Waterland@Sun.COM 	boolean_t	this_zone;	/* pkg is "this zone" only */
2683*9781SMoriah.Waterland@Sun.COM 	boolean_t	reqfile_found = B_FALSE;
2684*9781SMoriah.Waterland@Sun.COM 	char		instPkg[PKGSIZ+1];	/* installed pkg instance nam */
2685*9781SMoriah.Waterland@Sun.COM 	char		instPkgPath[PATH_MAX];	/* installed pkg toplevel dir */
2686*9781SMoriah.Waterland@Sun.COM 	char		pkginfoPath[PATH_MAX];	/* pkg 2 install pkginfo file */
2687*9781SMoriah.Waterland@Sun.COM 	char		pkgmapPath[PATH_MAX];	/* pkg 2 install pkgmap file */
2688*9781SMoriah.Waterland@Sun.COM 	char		pkgpath[PATH_MAX];	/* pkg 2 install toplevel dir */
2689*9781SMoriah.Waterland@Sun.COM 	int		len;
2690*9781SMoriah.Waterland@Sun.COM 	char		line[LINE_MAX];
2691*9781SMoriah.Waterland@Sun.COM 
2692*9781SMoriah.Waterland@Sun.COM 	/* entry assertions */
2693*9781SMoriah.Waterland@Sun.COM 
2694*9781SMoriah.Waterland@Sun.COM 	assert(a_packageDir != (char *)NULL);
2695*9781SMoriah.Waterland@Sun.COM 	assert(*a_packageDir != '\0');
2696*9781SMoriah.Waterland@Sun.COM 	assert(a_pkgInst != (char *)NULL);
2697*9781SMoriah.Waterland@Sun.COM 	assert(*a_pkgInst != '\0');
2698*9781SMoriah.Waterland@Sun.COM 
2699*9781SMoriah.Waterland@Sun.COM 	/* normalize root path */
2700*9781SMoriah.Waterland@Sun.COM 
2701*9781SMoriah.Waterland@Sun.COM 	if (a_rootPath == (char *)NULL) {
2702*9781SMoriah.Waterland@Sun.COM 		a_rootPath = "";
2703*9781SMoriah.Waterland@Sun.COM 	}
2704*9781SMoriah.Waterland@Sun.COM 
2705*9781SMoriah.Waterland@Sun.COM 	/* entry debugging info */
2706*9781SMoriah.Waterland@Sun.COM 
2707*9781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_CHECKAPP_ENTRY);
2708*9781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_CHECKAPP_ARGS, a_pkgInst, a_packageDir, a_rootPath);
2709*9781SMoriah.Waterland@Sun.COM 
2710*9781SMoriah.Waterland@Sun.COM 	/*
2711*9781SMoriah.Waterland@Sun.COM 	 * calculate paths to various objects
2712*9781SMoriah.Waterland@Sun.COM 	 */
2713*9781SMoriah.Waterland@Sun.COM 
2714*9781SMoriah.Waterland@Sun.COM 	/* path to package to be installed top level (main) directory */
2715*9781SMoriah.Waterland@Sun.COM 
2716*9781SMoriah.Waterland@Sun.COM 	len = snprintf(pkgpath, sizeof (pkgpath), "%s/%s", a_packageDir,
2717*9781SMoriah.Waterland@Sun.COM 			a_pkgInst);
2718*9781SMoriah.Waterland@Sun.COM 	if (len > sizeof (pkgpath)) {
2719*9781SMoriah.Waterland@Sun.COM 		progerr(ERR_CREATE_PATH_2, a_packageDir, a_pkgInst);
2720*9781SMoriah.Waterland@Sun.COM 		return (B_FALSE);
2721*9781SMoriah.Waterland@Sun.COM 	}
2722*9781SMoriah.Waterland@Sun.COM 
2723*9781SMoriah.Waterland@Sun.COM 	/* error if package top level directory does not exist */
2724*9781SMoriah.Waterland@Sun.COM 
2725*9781SMoriah.Waterland@Sun.COM 	if (isdir(pkgpath) != 0) {
2726*9781SMoriah.Waterland@Sun.COM 		progerr(ERR_NO_PKGDIR, pkgpath, a_pkgInst, strerror(errno));
2727*9781SMoriah.Waterland@Sun.COM 		return (B_FALSE);
2728*9781SMoriah.Waterland@Sun.COM 	}
2729*9781SMoriah.Waterland@Sun.COM 
2730*9781SMoriah.Waterland@Sun.COM 	/* path to pkginfo file within the package to be installed */
2731*9781SMoriah.Waterland@Sun.COM 
2732*9781SMoriah.Waterland@Sun.COM 	len = snprintf(pkginfoPath, sizeof (pkginfoPath), "%s/pkginfo",
2733*9781SMoriah.Waterland@Sun.COM 			pkgpath);
2734*9781SMoriah.Waterland@Sun.COM 	if (len > sizeof (pkginfoPath)) {
2735*9781SMoriah.Waterland@Sun.COM 		progerr(ERR_CREATE_PATH_2, pkgpath, "pkginfo");
2736*9781SMoriah.Waterland@Sun.COM 		return (B_FALSE);
2737*9781SMoriah.Waterland@Sun.COM 	}
2738*9781SMoriah.Waterland@Sun.COM 
2739*9781SMoriah.Waterland@Sun.COM 	/* path to highest instance of package currently installed */
2740*9781SMoriah.Waterland@Sun.COM 
2741*9781SMoriah.Waterland@Sun.COM 	pkgLocateHighestInst(instPkgPath, sizeof (instPkgPath),
2742*9781SMoriah.Waterland@Sun.COM 		instPkg, sizeof (instPkg), a_rootPath, a_pkgInst);
2743*9781SMoriah.Waterland@Sun.COM 
2744*9781SMoriah.Waterland@Sun.COM 	/*
2745*9781SMoriah.Waterland@Sun.COM 	 * gather information from this package's pkginfo file
2746*9781SMoriah.Waterland@Sun.COM 	 */
2747*9781SMoriah.Waterland@Sun.COM 
2748*9781SMoriah.Waterland@Sun.COM 	pkginfoFP = fopen(pkginfoPath, "r");
2749*9781SMoriah.Waterland@Sun.COM 
2750*9781SMoriah.Waterland@Sun.COM 	if (pkginfoFP == (FILE *)NULL) {
2751*9781SMoriah.Waterland@Sun.COM 		progerr(ERR_NO_PKG_INFOFILE, a_pkgInst, pkginfoPath,
2752*9781SMoriah.Waterland@Sun.COM 							strerror(errno));
2753*9781SMoriah.Waterland@Sun.COM 		return (B_FALSE);
2754*9781SMoriah.Waterland@Sun.COM 	}
2755*9781SMoriah.Waterland@Sun.COM 
2756*9781SMoriah.Waterland@Sun.COM 	/* determine "HOLLOW" setting for this package */
2757*9781SMoriah.Waterland@Sun.COM 
2758*9781SMoriah.Waterland@Sun.COM 	is_hollow = pkginfoParamTruth(pkginfoFP, PKG_HOLLOW_VARIABLE,
2759*9781SMoriah.Waterland@Sun.COM 			"true", B_FALSE);
2760*9781SMoriah.Waterland@Sun.COM 
2761*9781SMoriah.Waterland@Sun.COM 	/* determine "ALLZONES" setting for this package */
2762*9781SMoriah.Waterland@Sun.COM 
2763*9781SMoriah.Waterland@Sun.COM 	all_zones = pkginfoParamTruth(pkginfoFP, PKG_ALLZONES_VARIABLE,
2764*9781SMoriah.Waterland@Sun.COM 			"true", B_FALSE);
2765*9781SMoriah.Waterland@Sun.COM 
2766*9781SMoriah.Waterland@Sun.COM 	/* determine "THISZONE" setting for this package */
2767*9781SMoriah.Waterland@Sun.COM 
2768*9781SMoriah.Waterland@Sun.COM 	this_zone = pkginfoParamTruth(pkginfoFP, PKG_THISZONE_VARIABLE,
2769*9781SMoriah.Waterland@Sun.COM 			"true", B_FALSE);
2770*9781SMoriah.Waterland@Sun.COM 
2771*9781SMoriah.Waterland@Sun.COM 	/* close pkginfo file */
2772*9781SMoriah.Waterland@Sun.COM 
2773*9781SMoriah.Waterland@Sun.COM 	(void) fclose(pkginfoFP);
2774*9781SMoriah.Waterland@Sun.COM 
2775*9781SMoriah.Waterland@Sun.COM 	/*
2776*9781SMoriah.Waterland@Sun.COM 	 * If request file is not found, it may be in the datastream which
2777*9781SMoriah.Waterland@Sun.COM 	 * is not yet unpacked. Check in the pkgmap file.
2778*9781SMoriah.Waterland@Sun.COM 	 */
2779*9781SMoriah.Waterland@Sun.COM 	if (isfile(pkgpath, REQUEST_FILE) != 0) {
2780*9781SMoriah.Waterland@Sun.COM 
2781*9781SMoriah.Waterland@Sun.COM 		/* path to pkgmap file within the package to be installed */
2782*9781SMoriah.Waterland@Sun.COM 		(void) snprintf(pkgmapPath, sizeof (pkgmapPath), "%s/pkgmap",
2783*9781SMoriah.Waterland@Sun.COM 		    pkgpath);
2784*9781SMoriah.Waterland@Sun.COM 
2785*9781SMoriah.Waterland@Sun.COM 		pkgmapFP = fopen(pkgmapPath, "r");
2786*9781SMoriah.Waterland@Sun.COM 
2787*9781SMoriah.Waterland@Sun.COM 		if (pkgmapFP == NULL) {
2788*9781SMoriah.Waterland@Sun.COM 			progerr(ERR_NO_PKG_MAPFILE, a_pkgInst,
2789*9781SMoriah.Waterland@Sun.COM 			    pkgmapPath, strerror(errno));
2790*9781SMoriah.Waterland@Sun.COM 			return (B_FALSE);
2791*9781SMoriah.Waterland@Sun.COM 		}
2792*9781SMoriah.Waterland@Sun.COM 
2793*9781SMoriah.Waterland@Sun.COM 		while (fgets(line, LINE_MAX, pkgmapFP) != NULL) {
2794*9781SMoriah.Waterland@Sun.COM 			if (strstr(line, " i request") != NULL) {
2795*9781SMoriah.Waterland@Sun.COM 				reqfile_found = B_TRUE;
2796*9781SMoriah.Waterland@Sun.COM 				break;
2797*9781SMoriah.Waterland@Sun.COM 			}
2798*9781SMoriah.Waterland@Sun.COM 		}
2799*9781SMoriah.Waterland@Sun.COM 		(void) fclose(pkgmapFP);
2800*9781SMoriah.Waterland@Sun.COM 	} else {
2801*9781SMoriah.Waterland@Sun.COM 		reqfile_found = B_TRUE;
2802*9781SMoriah.Waterland@Sun.COM 	}
2803*9781SMoriah.Waterland@Sun.COM 
2804*9781SMoriah.Waterland@Sun.COM 	/*
2805*9781SMoriah.Waterland@Sun.COM 	 * If this package is not marked for installation in this zone only,
2806*9781SMoriah.Waterland@Sun.COM 	 * check to see if this package has a request script. If this package
2807*9781SMoriah.Waterland@Sun.COM 	 * does have a request script, then mark the package for installation
2808*9781SMoriah.Waterland@Sun.COM 	 * in this zone only. Any package with a request script cannot be
2809*9781SMoriah.Waterland@Sun.COM 	 * installed outside of the zone the pkgadd command is being run in,
2810*9781SMoriah.Waterland@Sun.COM 	 * nor can such a package be installed as part of a new zone install.
2811*9781SMoriah.Waterland@Sun.COM 	 * A new zone install must be non-interactive, which is required
2812*9781SMoriah.Waterland@Sun.COM 	 * by all packages integrated into the Solaris WOS.
2813*9781SMoriah.Waterland@Sun.COM 	 */
2814*9781SMoriah.Waterland@Sun.COM 
2815*9781SMoriah.Waterland@Sun.COM 	if ((!this_zone) && (reqfile_found)) {
2816*9781SMoriah.Waterland@Sun.COM 		if (a_flags & CAF_IN_GLOBAL_ZONE) {
2817*9781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_CHECKAPP_THISZONE_REQUEST, a_pkgInst);
2818*9781SMoriah.Waterland@Sun.COM 		}
2819*9781SMoriah.Waterland@Sun.COM 		this_zone = B_TRUE;
2820*9781SMoriah.Waterland@Sun.COM 	}
2821*9781SMoriah.Waterland@Sun.COM 
2822*9781SMoriah.Waterland@Sun.COM 	/*
2823*9781SMoriah.Waterland@Sun.COM 	 * If this package is already installed, see if the current installation
2824*9781SMoriah.Waterland@Sun.COM 	 * of the package has a request file - if it does, then act as though
2825*9781SMoriah.Waterland@Sun.COM 	 * the current package to be added has a request file - install the
2826*9781SMoriah.Waterland@Sun.COM 	 * package in the current zone only.
2827*9781SMoriah.Waterland@Sun.COM 	 */
2828*9781SMoriah.Waterland@Sun.COM 
2829*9781SMoriah.Waterland@Sun.COM 	if ((!this_zone) && (instPkgPath[0] != '\0') &&
2830*9781SMoriah.Waterland@Sun.COM 		(isfile(instPkgPath, REQUEST_FILE) == 0)) {
2831*9781SMoriah.Waterland@Sun.COM 		if (a_flags & CAF_IN_GLOBAL_ZONE) {
2832*9781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_CHECKAPP_THISZONE_INSTREQ,
2833*9781SMoriah.Waterland@Sun.COM 				a_pkgInst, instPkg);
2834*9781SMoriah.Waterland@Sun.COM 		}
2835*9781SMoriah.Waterland@Sun.COM 		this_zone = B_TRUE;
2836*9781SMoriah.Waterland@Sun.COM 	}
2837*9781SMoriah.Waterland@Sun.COM 
2838*9781SMoriah.Waterland@Sun.COM 	/* gather information from the global zone only file */
2839*9781SMoriah.Waterland@Sun.COM 
2840*9781SMoriah.Waterland@Sun.COM 	in_gz_only = B_FALSE;
2841*9781SMoriah.Waterland@Sun.COM 	if (a_flags & CAF_IN_GLOBAL_ZONE) {
2842*9781SMoriah.Waterland@Sun.COM 		in_gz_only = pkgIsPkgInGzOnly(a_rootPath, a_pkgInst);
2843*9781SMoriah.Waterland@Sun.COM 	}
2844*9781SMoriah.Waterland@Sun.COM 
2845*9781SMoriah.Waterland@Sun.COM 	/* determine if this package is currently installed */
2846*9781SMoriah.Waterland@Sun.COM 
2847*9781SMoriah.Waterland@Sun.COM 	pkg_installed = pkginfoIsPkgInstalled((struct pkginfo **)NULL,
2848*9781SMoriah.Waterland@Sun.COM 								a_pkgInst);
2849*9781SMoriah.Waterland@Sun.COM 
2850*9781SMoriah.Waterland@Sun.COM 	/*
2851*9781SMoriah.Waterland@Sun.COM 	 * verify package applicability based on information gathered,
2852*9781SMoriah.Waterland@Sun.COM 	 * and validate the three SUNW_PKG_ options:
2853*9781SMoriah.Waterland@Sun.COM 	 *
2854*9781SMoriah.Waterland@Sun.COM 	 * -----------|--------------|-------------|-------------|-----------
2855*9781SMoriah.Waterland@Sun.COM 	 * - - - - - -| GLOBAL ZONE -| GLOBAL ZONE | LOCAL ZONE	 | LOCAL ZONE
2856*9781SMoriah.Waterland@Sun.COM 	 * - - - - - -|	- - pkgadd - | pkgadd -G   | pkgadd	 | pkgadd -G
2857*9781SMoriah.Waterland@Sun.COM 	 * ----1------|--------------|-------------|-------------|------------
2858*9781SMoriah.Waterland@Sun.COM 	 * ALLZONES f | add to gz    | add to gz   | add to ls	 | add to ls
2859*9781SMoriah.Waterland@Sun.COM 	 * HOLLOW   f | current lz   | not to curr | only - - - -| only - - -
2860*9781SMoriah.Waterland@Sun.COM 	 * THISZONE f | futr lz - - -| or futr lz  | - - - - - - | - - - - - -
2861*9781SMoriah.Waterland@Sun.COM 	 * ----2------|--------------|-------------|-------------|------------
2862*9781SMoriah.Waterland@Sun.COM 	 * ALLZONES T | add to gz    | operation   | operation	 | operation
2863*9781SMoriah.Waterland@Sun.COM 	 * HOLLOW   f | current lz   | not allowed | not allowed | not allowed
2864*9781SMoriah.Waterland@Sun.COM 	 * THISZONE f | future lz    | - - - - - - | - - - - - - | - - - - - -
2865*9781SMoriah.Waterland@Sun.COM 	 * ----3------|--------------|-------------|-------------|------------
2866*9781SMoriah.Waterland@Sun.COM 	 * ALLZONES T | add to gz    | operation   | operation	 | operation
2867*9781SMoriah.Waterland@Sun.COM 	 * HOLLOW   T | pkg db only  | not allowed | not allowed | not allowed
2868*9781SMoriah.Waterland@Sun.COM 	 * THISZONE f | curr/futr lz | - - - - - - | - - - - - - | - - - - - -
2869*9781SMoriah.Waterland@Sun.COM 	 * ----4------|--------------|-------------|-------------|------------
2870*9781SMoriah.Waterland@Sun.COM 	 * ALLZONES T | bad option   | bad option  | bad option	 | bad option
2871*9781SMoriah.Waterland@Sun.COM 	 * HOLLOW   * | combo - - - -| combo - - - | combo - - - | combo - -
2872*9781SMoriah.Waterland@Sun.COM 	 * THISZONE T |	- - - - - - -|- - - - - - -|- - - - - - -|- - - - - -
2873*9781SMoriah.Waterland@Sun.COM 	 * ----5------|--------------|-------------|-------------|------------
2874*9781SMoriah.Waterland@Sun.COM 	 * ALLZONES f | bad option   | bad option  | bad option	 | bad option
2875*9781SMoriah.Waterland@Sun.COM 	 * HOLLOW   T | combo - - - -| combo - - - | combo - - - | combo - - -
2876*9781SMoriah.Waterland@Sun.COM 	 * THISZONE * | - - - - - - -| - - - - - - | - - - - - - | - - - - - -
2877*9781SMoriah.Waterland@Sun.COM 	 * ----6------|--------------|-------------|-------------|------------
2878*9781SMoriah.Waterland@Sun.COM 	 * ALLZONES f | add to gz    | add to gz   | add to lz	 | add to lz
2879*9781SMoriah.Waterland@Sun.COM 	 * HOLLOW   f | not current  | not current | only - - -	 | only - - -
2880*9781SMoriah.Waterland@Sun.COM 	 * THISZONE T | or future lz | or futr lz  | - - - - - - | - - - - - -
2881*9781SMoriah.Waterland@Sun.COM 	 * -----------|--------------|-------------|-------------|-----------
2882*9781SMoriah.Waterland@Sun.COM 	 */
2883*9781SMoriah.Waterland@Sun.COM 
2884*9781SMoriah.Waterland@Sun.COM 	/* pkg "all zones" && "this zone" (#4) */
2885*9781SMoriah.Waterland@Sun.COM 
2886*9781SMoriah.Waterland@Sun.COM 	if (all_zones && this_zone) {
2887*9781SMoriah.Waterland@Sun.COM 		progerr(ERR_ALLZONES_AND_THISZONE, a_pkgInst,
2888*9781SMoriah.Waterland@Sun.COM 			PKG_ALLZONES_VARIABLE, PKG_THISZONE_VARIABLE);
2889*9781SMoriah.Waterland@Sun.COM 		return (B_FALSE);
2890*9781SMoriah.Waterland@Sun.COM 	}
2891*9781SMoriah.Waterland@Sun.COM 
2892*9781SMoriah.Waterland@Sun.COM 	/* pkg "!all zones" && "hollow" (#5) */
2893*9781SMoriah.Waterland@Sun.COM 
2894*9781SMoriah.Waterland@Sun.COM 	if ((!all_zones) && is_hollow) {
2895*9781SMoriah.Waterland@Sun.COM 		progerr(ERR_NOW_ALLZONES_AND_HOLLOW, a_pkgInst,
2896*9781SMoriah.Waterland@Sun.COM 			PKG_ALLZONES_VARIABLE, PKG_HOLLOW_VARIABLE);
2897*9781SMoriah.Waterland@Sun.COM 		return (B_FALSE);
2898*9781SMoriah.Waterland@Sun.COM 	}
2899*9781SMoriah.Waterland@Sun.COM 
2900*9781SMoriah.Waterland@Sun.COM 	/* pkg ALLZONES=true && -Z specified */
2901*9781SMoriah.Waterland@Sun.COM 
2902*9781SMoriah.Waterland@Sun.COM 	if (all_zones && (a_flags & CAF_SCOPE_NONGLOBAL)) {
2903*9781SMoriah.Waterland@Sun.COM 		progerr(ERR_ALLZONES_AND_Z_USED, a_pkgInst);
2904*9781SMoriah.Waterland@Sun.COM 		return (B_FALSE);
2905*9781SMoriah.Waterland@Sun.COM 	}
2906*9781SMoriah.Waterland@Sun.COM 
2907*9781SMoriah.Waterland@Sun.COM 	/* pkg ALLZONES=true & not running in global zone (#2/#3) */
2908*9781SMoriah.Waterland@Sun.COM 
2909*9781SMoriah.Waterland@Sun.COM 	if (all_zones && (!(a_flags & CAF_IN_GLOBAL_ZONE))) {
2910*9781SMoriah.Waterland@Sun.COM 		progerr(ERR_ALLZONES_AND_IN_LZ, a_pkgInst);
2911*9781SMoriah.Waterland@Sun.COM 		return (B_FALSE);
2912*9781SMoriah.Waterland@Sun.COM 	}
2913*9781SMoriah.Waterland@Sun.COM 
2914*9781SMoriah.Waterland@Sun.COM 	/* pkg "in gz only" & pkg "NOT installed" */
2915*9781SMoriah.Waterland@Sun.COM 
2916*9781SMoriah.Waterland@Sun.COM 	if (in_gz_only && (!pkg_installed)) {
2917*9781SMoriah.Waterland@Sun.COM 		/* MAKE A WARNING */
2918*9781SMoriah.Waterland@Sun.COM 		echo(ERR_IN_GZ_AND_NOT_INSTALLED, a_pkgInst,
2919*9781SMoriah.Waterland@Sun.COM 			pkgGetGzOnlyPath());
2920*9781SMoriah.Waterland@Sun.COM 	}
2921*9781SMoriah.Waterland@Sun.COM 
2922*9781SMoriah.Waterland@Sun.COM 	/* pkg ALLZONES=true & pkg "in gz only" & pkg "is installed" */
2923*9781SMoriah.Waterland@Sun.COM 
2924*9781SMoriah.Waterland@Sun.COM 	if (all_zones && in_gz_only && pkg_installed) {
2925*9781SMoriah.Waterland@Sun.COM 		progerr(ERR_IN_GZ_AND_ALLZONES_AND_INSTALLED, a_pkgInst);
2926*9781SMoriah.Waterland@Sun.COM 		return (B_FALSE);
2927*9781SMoriah.Waterland@Sun.COM 	}
2928*9781SMoriah.Waterland@Sun.COM 
2929*9781SMoriah.Waterland@Sun.COM 	/* pkg ALLZONES=true && -G specified (#2/#3) */
2930*9781SMoriah.Waterland@Sun.COM 
2931*9781SMoriah.Waterland@Sun.COM 	if (all_zones && (a_flags & CAF_SCOPE_GLOBAL)) {
2932*9781SMoriah.Waterland@Sun.COM 		progerr(ERR_ALLZONES_AND_G_USED, a_pkgInst);
2933*9781SMoriah.Waterland@Sun.COM 		return (B_FALSE);
2934*9781SMoriah.Waterland@Sun.COM 	}
2935*9781SMoriah.Waterland@Sun.COM 
2936*9781SMoriah.Waterland@Sun.COM 	/* pkg "!this zone" && "in gz only" & -G not specified */
2937*9781SMoriah.Waterland@Sun.COM 
2938*9781SMoriah.Waterland@Sun.COM 	if ((!this_zone) && in_gz_only && (!(a_flags & CAF_SCOPE_GLOBAL))) {
2939*9781SMoriah.Waterland@Sun.COM 		progerr(ERR_IN_GZ_AND_NO_G_USED, a_pkgInst);
2940*9781SMoriah.Waterland@Sun.COM 		return (B_FALSE);
2941*9781SMoriah.Waterland@Sun.COM 	}
2942*9781SMoriah.Waterland@Sun.COM 
2943*9781SMoriah.Waterland@Sun.COM 	/* pkg "NOT in gz only" & -Z specified */
2944*9781SMoriah.Waterland@Sun.COM 
2945*9781SMoriah.Waterland@Sun.COM 	if ((!in_gz_only) && (a_flags & CAF_SCOPE_NONGLOBAL)) {
2946*9781SMoriah.Waterland@Sun.COM 		progerr(ERR_NOT_IN_GZ_AND_Z_USED, a_pkgInst);
2947*9781SMoriah.Waterland@Sun.COM 		return (B_FALSE);
2948*9781SMoriah.Waterland@Sun.COM 	}
2949*9781SMoriah.Waterland@Sun.COM 
2950*9781SMoriah.Waterland@Sun.COM 	/* pkg "this zone" && -Z specified */
2951*9781SMoriah.Waterland@Sun.COM 
2952*9781SMoriah.Waterland@Sun.COM 	if (this_zone && (a_flags & CAF_SCOPE_NONGLOBAL)) {
2953*9781SMoriah.Waterland@Sun.COM 		progerr(ERR_THISZONE_AND_Z_USED, PKG_THISZONE_VARIABLE,
2954*9781SMoriah.Waterland@Sun.COM 			a_pkgInst);
2955*9781SMoriah.Waterland@Sun.COM 		return (B_FALSE);
2956*9781SMoriah.Waterland@Sun.COM 	}
2957*9781SMoriah.Waterland@Sun.COM 
2958*9781SMoriah.Waterland@Sun.COM 	/*
2959*9781SMoriah.Waterland@Sun.COM 	 * If this package is marked 'this zone only', then mark the package
2960*9781SMoriah.Waterland@Sun.COM 	 * as "add to this zone only". This is referenced by the various
2961*9781SMoriah.Waterland@Sun.COM 	 * add_package_... functions to determine if the package should be
2962*9781SMoriah.Waterland@Sun.COM 	 * added to the current zone, or to all zones, depending on the
2963*9781SMoriah.Waterland@Sun.COM 	 * zone in which the command is being run.
2964*9781SMoriah.Waterland@Sun.COM 	 */
2965*9781SMoriah.Waterland@Sun.COM 
2966*9781SMoriah.Waterland@Sun.COM 	if (this_zone) {
2967*9781SMoriah.Waterland@Sun.COM 		pkgAddThisZonePackage(a_pkgInst);
2968*9781SMoriah.Waterland@Sun.COM 	}
2969*9781SMoriah.Waterland@Sun.COM 
2970*9781SMoriah.Waterland@Sun.COM 	return (B_TRUE);
2971*9781SMoriah.Waterland@Sun.COM }
2972*9781SMoriah.Waterland@Sun.COM 
2973*9781SMoriah.Waterland@Sun.COM /*
2974*9781SMoriah.Waterland@Sun.COM  * Name:	create_zone_adminfile
2975*9781SMoriah.Waterland@Sun.COM  * Description: Given a zone temporary directory and optionally an existing
2976*9781SMoriah.Waterland@Sun.COM  *		administration file, generate an administration file that
2977*9781SMoriah.Waterland@Sun.COM  *		can be used to perform "non-interactive" operations in a
2978*9781SMoriah.Waterland@Sun.COM  *		non-global zone.
2979*9781SMoriah.Waterland@Sun.COM  * Arguments:	r_zoneAdminFile - pointer to handle that will contain a
2980*9781SMoriah.Waterland@Sun.COM  *			string representing the path to the temporary
2981*9781SMoriah.Waterland@Sun.COM  *			administration file created - this must be NULL
2982*9781SMoriah.Waterland@Sun.COM  *			before the first call to this function - on
2983*9781SMoriah.Waterland@Sun.COM  *			subsequent calls if the pointer is NOT null then
2984*9781SMoriah.Waterland@Sun.COM  *			the existing string will NOT be overwritten.
2985*9781SMoriah.Waterland@Sun.COM  *		a_zoneTempDir - pointer to string representing the path
2986*9781SMoriah.Waterland@Sun.COM  *			to the zone temporary directory to create the
2987*9781SMoriah.Waterland@Sun.COM  *			temporary administration file in
2988*9781SMoriah.Waterland@Sun.COM  *		a_admnfile - pointer to string representing the path to
2989*9781SMoriah.Waterland@Sun.COM  *			an existing "user" administration file - the
2990*9781SMoriah.Waterland@Sun.COM  *			administration file created will contain the
2991*9781SMoriah.Waterland@Sun.COM  *			settings contained in this file, modified as
2992*9781SMoriah.Waterland@Sun.COM  *			appropriate to supress any interaction;
2993*9781SMoriah.Waterland@Sun.COM  *			If this is == NULL then the administration file
2994*9781SMoriah.Waterland@Sun.COM  *			created will not contain any extra settings
2995*9781SMoriah.Waterland@Sun.COM  * Returns:	void
2996*9781SMoriah.Waterland@Sun.COM  * NOTE:	Any string returned is placed in new storage for the
2997*9781SMoriah.Waterland@Sun.COM  *		calling method. The caller must use 'free' to dispose
2998*9781SMoriah.Waterland@Sun.COM  *		of the storage once the string is no longer needed.
2999*9781SMoriah.Waterland@Sun.COM  * NOTE:	On any error this function will call 'quit(1)'
3000*9781SMoriah.Waterland@Sun.COM  */
3001*9781SMoriah.Waterland@Sun.COM 
3002*9781SMoriah.Waterland@Sun.COM static void
3003*9781SMoriah.Waterland@Sun.COM create_zone_adminfile(char **r_zoneAdminFile, char *a_zoneTempDir,
3004*9781SMoriah.Waterland@Sun.COM 	char *a_admnfile)
3005*9781SMoriah.Waterland@Sun.COM {
3006*9781SMoriah.Waterland@Sun.COM 	boolean_t	b;
3007*9781SMoriah.Waterland@Sun.COM 
3008*9781SMoriah.Waterland@Sun.COM 	/* entry assertions */
3009*9781SMoriah.Waterland@Sun.COM 
3010*9781SMoriah.Waterland@Sun.COM 	assert(r_zoneAdminFile != (char **)NULL);
3011*9781SMoriah.Waterland@Sun.COM 	assert(a_zoneTempDir != (char *)NULL);
3012*9781SMoriah.Waterland@Sun.COM 	assert(*a_zoneTempDir != '\0');
3013*9781SMoriah.Waterland@Sun.COM 
3014*9781SMoriah.Waterland@Sun.COM 	/* entry debugging info */
3015*9781SMoriah.Waterland@Sun.COM 
3016*9781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_CREATE_ZONE_ADMINFILE, a_zoneTempDir, PSTR(a_admnfile));
3017*9781SMoriah.Waterland@Sun.COM 
3018*9781SMoriah.Waterland@Sun.COM 	/* if temporary name already exists, do not overwrite */
3019*9781SMoriah.Waterland@Sun.COM 
3020*9781SMoriah.Waterland@Sun.COM 	if (*r_zoneAdminFile != (char *)NULL) {
3021*9781SMoriah.Waterland@Sun.COM 		return;
3022*9781SMoriah.Waterland@Sun.COM 	}
3023*9781SMoriah.Waterland@Sun.COM 
3024*9781SMoriah.Waterland@Sun.COM 	/* create temporary name */
3025*9781SMoriah.Waterland@Sun.COM 
3026*9781SMoriah.Waterland@Sun.COM 	*r_zoneAdminFile = tempnam(a_zoneTempDir, "zadmn");
3027*9781SMoriah.Waterland@Sun.COM 	b = z_create_zone_admin_file(*r_zoneAdminFile, a_admnfile);
3028*9781SMoriah.Waterland@Sun.COM 	if (b == B_FALSE) {
3029*9781SMoriah.Waterland@Sun.COM 		progerr(ERR_CREATE_TMPADMIN, *r_zoneAdminFile,
3030*9781SMoriah.Waterland@Sun.COM 			strerror(errno));
3031*9781SMoriah.Waterland@Sun.COM 		quit(1);
3032*9781SMoriah.Waterland@Sun.COM 		/* NOTREACHED */
3033*9781SMoriah.Waterland@Sun.COM 	}
3034*9781SMoriah.Waterland@Sun.COM 
3035*9781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_CREATED_ZONE_ADMINFILE, *r_zoneAdminFile);
3036*9781SMoriah.Waterland@Sun.COM }
3037*9781SMoriah.Waterland@Sun.COM 
3038*9781SMoriah.Waterland@Sun.COM /*
3039*9781SMoriah.Waterland@Sun.COM  * Name:	create_zone_tempdir
3040*9781SMoriah.Waterland@Sun.COM  * Description: Given a system temporary directory, create a "zone" specific
3041*9781SMoriah.Waterland@Sun.COM  *		temporary directory and return the path to the directory
3042*9781SMoriah.Waterland@Sun.COM  *		created.
3043*9781SMoriah.Waterland@Sun.COM  * Arguments:	r_zoneTempDir - pointer to handle that will contain a
3044*9781SMoriah.Waterland@Sun.COM  *			string representing the path to the temporary
3045*9781SMoriah.Waterland@Sun.COM  *			directory created - this must be NULL before the
3046*9781SMoriah.Waterland@Sun.COM  *			first call to this function - on subsequent calls
3047*9781SMoriah.Waterland@Sun.COM  *			if the pointer is NOT null then the existing string
3048*9781SMoriah.Waterland@Sun.COM  *			will NOT be overwritten.
3049*9781SMoriah.Waterland@Sun.COM  *		a_zoneTempDir - pointer to string representing the path
3050*9781SMoriah.Waterland@Sun.COM  *			to the system temporary directory to create the
3051*9781SMoriah.Waterland@Sun.COM  *			temporary zone directory in
3052*9781SMoriah.Waterland@Sun.COM  * Returns:	void
3053*9781SMoriah.Waterland@Sun.COM  * NOTE:	Any string returned is placed in new storage for the
3054*9781SMoriah.Waterland@Sun.COM  *		calling method. The caller must use 'free' to dispose
3055*9781SMoriah.Waterland@Sun.COM  *		of the storage once the string is no longer needed.
3056*9781SMoriah.Waterland@Sun.COM  * NOTE:	On any error this function will call 'quit(1)'
3057*9781SMoriah.Waterland@Sun.COM  * NOTE:	This function calls "quitSetZoneTmpdir" on success to
3058*9781SMoriah.Waterland@Sun.COM  *		register the directory created with quit() so that the
3059*9781SMoriah.Waterland@Sun.COM  *		directory will be automatically deleted on exit.
3060*9781SMoriah.Waterland@Sun.COM  */
3061*9781SMoriah.Waterland@Sun.COM 
3062*9781SMoriah.Waterland@Sun.COM static void
3063*9781SMoriah.Waterland@Sun.COM create_zone_tempdir(char **r_zoneTempDir, char *a_tmpdir)
3064*9781SMoriah.Waterland@Sun.COM {
3065*9781SMoriah.Waterland@Sun.COM 	boolean_t	b;
3066*9781SMoriah.Waterland@Sun.COM 
3067*9781SMoriah.Waterland@Sun.COM 	/* entry assertions */
3068*9781SMoriah.Waterland@Sun.COM 
3069*9781SMoriah.Waterland@Sun.COM 	assert(r_zoneTempDir != (char **)NULL);
3070*9781SMoriah.Waterland@Sun.COM 	assert(a_tmpdir != (char *)NULL);
3071*9781SMoriah.Waterland@Sun.COM 	assert(*a_tmpdir != '\0');
3072*9781SMoriah.Waterland@Sun.COM 
3073*9781SMoriah.Waterland@Sun.COM 	/* entry debugging info */
3074*9781SMoriah.Waterland@Sun.COM 
3075*9781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_CREATE_ZONE_TEMPDIR, a_tmpdir);
3076*9781SMoriah.Waterland@Sun.COM 
3077*9781SMoriah.Waterland@Sun.COM 	/* if temporary directory already exists, do not overwrite */
3078*9781SMoriah.Waterland@Sun.COM 
3079*9781SMoriah.Waterland@Sun.COM 	if (*r_zoneTempDir != (char *)NULL) {
3080*9781SMoriah.Waterland@Sun.COM 		return;
3081*9781SMoriah.Waterland@Sun.COM 	}
3082*9781SMoriah.Waterland@Sun.COM 
3083*9781SMoriah.Waterland@Sun.COM 	/* create temporary directory */
3084*9781SMoriah.Waterland@Sun.COM 
3085*9781SMoriah.Waterland@Sun.COM 	b = setup_temporary_directory(r_zoneTempDir, a_tmpdir, "ztemp");
3086*9781SMoriah.Waterland@Sun.COM 	if (b == B_FALSE) {
3087*9781SMoriah.Waterland@Sun.COM 		progerr(ERR_ZONETEMPDIR, a_tmpdir, strerror(errno));
3088*9781SMoriah.Waterland@Sun.COM 		quit(1);
3089*9781SMoriah.Waterland@Sun.COM 		/* NOTREACHED */
3090*9781SMoriah.Waterland@Sun.COM 	}
3091*9781SMoriah.Waterland@Sun.COM 
3092*9781SMoriah.Waterland@Sun.COM 	/* register with quit() so directory is removed on exit */
3093*9781SMoriah.Waterland@Sun.COM 
3094*9781SMoriah.Waterland@Sun.COM 	quitSetZoneTmpdir(*r_zoneTempDir);
3095*9781SMoriah.Waterland@Sun.COM 
3096*9781SMoriah.Waterland@Sun.COM 	/* exit debugging info */
3097*9781SMoriah.Waterland@Sun.COM 
3098*9781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_CREATED_ZONE_TEMPDIR, *r_zoneTempDir);
3099*9781SMoriah.Waterland@Sun.COM }
3100*9781SMoriah.Waterland@Sun.COM 
3101*9781SMoriah.Waterland@Sun.COM /*
3102*9781SMoriah.Waterland@Sun.COM  * Name:	continue_installation
3103*9781SMoriah.Waterland@Sun.COM  * Description: Called from within a loop that is installing packages,
3104*9781SMoriah.Waterland@Sun.COM  *		this function examines various global variables and decides
3105*9781SMoriah.Waterland@Sun.COM  *		whether or not to ask an appropriate question, and wait for
3106*9781SMoriah.Waterland@Sun.COM  *		and appropriate reply.
3107*9781SMoriah.Waterland@Sun.COM  * Arguments:	<<global variables>>
3108*9781SMoriah.Waterland@Sun.COM  * Returns:	B_TRUE - continue processing with next package
3109*9781SMoriah.Waterland@Sun.COM  *		B_FALSE - do not continue processing with next package
3110*9781SMoriah.Waterland@Sun.COM  */
3111*9781SMoriah.Waterland@Sun.COM 
3112*9781SMoriah.Waterland@Sun.COM static boolean_t
3113*9781SMoriah.Waterland@Sun.COM continue_installation(void)
3114*9781SMoriah.Waterland@Sun.COM {
3115*9781SMoriah.Waterland@Sun.COM 	char	ans[MAX_INPUT];
3116*9781SMoriah.Waterland@Sun.COM 	int	n;
3117*9781SMoriah.Waterland@Sun.COM 
3118*9781SMoriah.Waterland@Sun.COM 	/* return TRUE if not interrupted */
3119*9781SMoriah.Waterland@Sun.COM 
3120*9781SMoriah.Waterland@Sun.COM 	if (!interrupted) {
3121*9781SMoriah.Waterland@Sun.COM 		return (B_TRUE);
3122*9781SMoriah.Waterland@Sun.COM 	}
3123*9781SMoriah.Waterland@Sun.COM 
3124*9781SMoriah.Waterland@Sun.COM 	/*
3125*9781SMoriah.Waterland@Sun.COM 	 * process interrupted - determine whether or not to continue
3126*9781SMoriah.Waterland@Sun.COM 	 */
3127*9781SMoriah.Waterland@Sun.COM 
3128*9781SMoriah.Waterland@Sun.COM 	/* output appropriate interrupted message */
3129*9781SMoriah.Waterland@Sun.COM 
3130*9781SMoriah.Waterland@Sun.COM 	if (askflag) {
3131*9781SMoriah.Waterland@Sun.COM 		echo(npkgs == 1 ? MSG_1MORE_PROC : MSG_MORE_PROC, npkgs);
3132*9781SMoriah.Waterland@Sun.COM 	} else {
3133*9781SMoriah.Waterland@Sun.COM 		echo(npkgs == 1 ? MSG_1MORE_INST : MSG_MORE_INST, npkgs);
3134*9781SMoriah.Waterland@Sun.COM 	}
3135*9781SMoriah.Waterland@Sun.COM 
3136*9781SMoriah.Waterland@Sun.COM 	/* if running with no interaction (-n) do not ask question */
3137*9781SMoriah.Waterland@Sun.COM 
3138*9781SMoriah.Waterland@Sun.COM 	if (nointeract) {
3139*9781SMoriah.Waterland@Sun.COM 		/* if admin required return 'dont continue' */
3140*9781SMoriah.Waterland@Sun.COM 		if (needconsult) {
3141*9781SMoriah.Waterland@Sun.COM 			return (B_FALSE);
3142*9781SMoriah.Waterland@Sun.COM 		}
3143*9781SMoriah.Waterland@Sun.COM 		ckquit = 1;
3144*9781SMoriah.Waterland@Sun.COM 		return (B_TRUE);
3145*9781SMoriah.Waterland@Sun.COM 	}
3146*9781SMoriah.Waterland@Sun.COM 
3147*9781SMoriah.Waterland@Sun.COM 	/* interaction possible: ask question */
3148*9781SMoriah.Waterland@Sun.COM 
3149*9781SMoriah.Waterland@Sun.COM 	ckquit = 0;
3150*9781SMoriah.Waterland@Sun.COM 	n = ckyorn(ans, NULL, NULL, NULL, ASK_CONTINUE_ADD);
3151*9781SMoriah.Waterland@Sun.COM 	if (n != 0) {
3152*9781SMoriah.Waterland@Sun.COM 		quit(n);
3153*9781SMoriah.Waterland@Sun.COM 		/* NOTREACHED */
3154*9781SMoriah.Waterland@Sun.COM 	}
3155*9781SMoriah.Waterland@Sun.COM 	ckquit = 1;
3156*9781SMoriah.Waterland@Sun.COM 	if (strchr("yY", *ans) == NULL) {
3157*9781SMoriah.Waterland@Sun.COM 		return (B_FALSE);
3158*9781SMoriah.Waterland@Sun.COM 	}
3159*9781SMoriah.Waterland@Sun.COM 	return (B_TRUE);
3160*9781SMoriah.Waterland@Sun.COM }
3161*9781SMoriah.Waterland@Sun.COM 
3162*9781SMoriah.Waterland@Sun.COM /*
3163*9781SMoriah.Waterland@Sun.COM  * package can be in a number of formats:
3164*9781SMoriah.Waterland@Sun.COM  * - file containing package stream (pkgadd -d file [pkgs])
3165*9781SMoriah.Waterland@Sun.COM  * - directory containing packages (pkgadd -d /dir [pkgs])
3166*9781SMoriah.Waterland@Sun.COM  * - device containing packages (pkgadd -d diskette1 [pkgs])
3167*9781SMoriah.Waterland@Sun.COM  * non-global zones can be passed open files and strings as arguments
3168*9781SMoriah.Waterland@Sun.COM  * - for file containing package stream
3169*9781SMoriah.Waterland@Sun.COM  * -- the stream can be passed directly to the non-global zone
3170*9781SMoriah.Waterland@Sun.COM  * - for directory
3171*9781SMoriah.Waterland@Sun.COM  * -- convert packages to datastream to pass to the non-global zone
3172*9781SMoriah.Waterland@Sun.COM  * - for device
3173*9781SMoriah.Waterland@Sun.COM  * -- ?
3174*9781SMoriah.Waterland@Sun.COM  */
3175*9781SMoriah.Waterland@Sun.COM 
3176*9781SMoriah.Waterland@Sun.COM static boolean_t
3177*9781SMoriah.Waterland@Sun.COM unpack_and_check_packages(char **a_pkgList, char *a_idsName, char *a_packageDir)
3178*9781SMoriah.Waterland@Sun.COM {
3179*9781SMoriah.Waterland@Sun.COM 	int	savenpkgs = npkgs;
3180*9781SMoriah.Waterland@Sun.COM 	int	i;
3181*9781SMoriah.Waterland@Sun.COM 	CAF_T	flags = 0;
3182*9781SMoriah.Waterland@Sun.COM 
3183*9781SMoriah.Waterland@Sun.COM 	/* entry assertions */
3184*9781SMoriah.Waterland@Sun.COM 
3185*9781SMoriah.Waterland@Sun.COM 	assert(a_pkgList != (char **)NULL);
3186*9781SMoriah.Waterland@Sun.COM 
3187*9781SMoriah.Waterland@Sun.COM 	/* entry debugging info */
3188*9781SMoriah.Waterland@Sun.COM 
3189*9781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_UNPACKCHECK_ENTRY);
3190*9781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_UNPACKCHECK_ARGS, PSTR(a_idsName), PSTR(a_packageDir));
3191*9781SMoriah.Waterland@Sun.COM 
3192*9781SMoriah.Waterland@Sun.COM 	/*
3193*9781SMoriah.Waterland@Sun.COM 	 * set flags for applicability check
3194*9781SMoriah.Waterland@Sun.COM 	 */
3195*9781SMoriah.Waterland@Sun.COM 
3196*9781SMoriah.Waterland@Sun.COM 	/* determine if running in the global zone */
3197*9781SMoriah.Waterland@Sun.COM 
3198*9781SMoriah.Waterland@Sun.COM 	if (z_running_in_global_zone() == B_TRUE) {
3199*9781SMoriah.Waterland@Sun.COM 		flags |= CAF_IN_GLOBAL_ZONE;
3200*9781SMoriah.Waterland@Sun.COM 	}
3201*9781SMoriah.Waterland@Sun.COM 
3202*9781SMoriah.Waterland@Sun.COM 	/* set -G flag */
3203*9781SMoriah.Waterland@Sun.COM 
3204*9781SMoriah.Waterland@Sun.COM 	if (globalZoneOnly == B_TRUE) {
3205*9781SMoriah.Waterland@Sun.COM 		flags |= CAF_SCOPE_GLOBAL;
3206*9781SMoriah.Waterland@Sun.COM 	}
3207*9781SMoriah.Waterland@Sun.COM 
3208*9781SMoriah.Waterland@Sun.COM 	/*
3209*9781SMoriah.Waterland@Sun.COM 	 * for each package to install:
3210*9781SMoriah.Waterland@Sun.COM 	 * - if packages from datastream, unpack package into package dir
3211*9781SMoriah.Waterland@Sun.COM 	 * - check applicability of installing package on this system/zone
3212*9781SMoriah.Waterland@Sun.COM 	 */
3213*9781SMoriah.Waterland@Sun.COM 
3214*9781SMoriah.Waterland@Sun.COM 	for (i = 0; (pkginst = a_pkgList[i]) != NULL; i++) {
3215*9781SMoriah.Waterland@Sun.COM 		if (a_idsName != (char *)NULL) {
3216*9781SMoriah.Waterland@Sun.COM 			/* create stream out of package if not already one */
3217*9781SMoriah.Waterland@Sun.COM 			if (unpack_package_from_stream(a_idsName, pkginst,
3218*9781SMoriah.Waterland@Sun.COM 				a_packageDir) == B_FALSE) {
3219*9781SMoriah.Waterland@Sun.COM 				progerr(ERR_CANNOT_UNPACK_PKGSTRM,
3220*9781SMoriah.Waterland@Sun.COM 					PSTR(pkginst), PSTR(a_idsName),
3221*9781SMoriah.Waterland@Sun.COM 					PSTR(a_packageDir));
3222*9781SMoriah.Waterland@Sun.COM 
3223*9781SMoriah.Waterland@Sun.COM 				npkgs = savenpkgs;
3224*9781SMoriah.Waterland@Sun.COM 				return (B_FALSE);
3225*9781SMoriah.Waterland@Sun.COM 			}
3226*9781SMoriah.Waterland@Sun.COM 		} else {
3227*9781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_PKG_IN_DIR, pkginst, a_packageDir);
3228*9781SMoriah.Waterland@Sun.COM 		}
3229*9781SMoriah.Waterland@Sun.COM 
3230*9781SMoriah.Waterland@Sun.COM 		/* check package applicability */
3231*9781SMoriah.Waterland@Sun.COM 		if (check_applicability(a_packageDir,
3232*9781SMoriah.Waterland@Sun.COM 			pkginst, get_inst_root(), flags) == B_FALSE) {
3233*9781SMoriah.Waterland@Sun.COM 			progerr(ERR_PKG_NOT_INSTALLABLE, pkginst);
3234*9781SMoriah.Waterland@Sun.COM 			npkgs = savenpkgs;
3235*9781SMoriah.Waterland@Sun.COM 			return (B_FALSE);
3236*9781SMoriah.Waterland@Sun.COM 		}
3237*9781SMoriah.Waterland@Sun.COM 		npkgs--;
3238*9781SMoriah.Waterland@Sun.COM 	}
3239*9781SMoriah.Waterland@Sun.COM 
3240*9781SMoriah.Waterland@Sun.COM 	npkgs = savenpkgs;
3241*9781SMoriah.Waterland@Sun.COM 	return (B_TRUE);
3242*9781SMoriah.Waterland@Sun.COM }
3243*9781SMoriah.Waterland@Sun.COM 
3244*9781SMoriah.Waterland@Sun.COM /*
3245*9781SMoriah.Waterland@Sun.COM  * returns:
3246*9781SMoriah.Waterland@Sun.COM  *	B_TRUE - package list generated
3247*9781SMoriah.Waterland@Sun.COM  *	B_FALSE - failed to generate package list
3248*9781SMoriah.Waterland@Sun.COM  *	Will call quit(n) on fatal error.
3249*9781SMoriah.Waterland@Sun.COM  */
3250*9781SMoriah.Waterland@Sun.COM 
3251*9781SMoriah.Waterland@Sun.COM static boolean_t
3252*9781SMoriah.Waterland@Sun.COM get_package_list(char ***r_pkgList, char **a_argv, char *a_categories,
3253*9781SMoriah.Waterland@Sun.COM 	char **a_categoryList, int a_ignoreSignatures, PKG_ERR *a_err,
3254*9781SMoriah.Waterland@Sun.COM 	ushort_t a_httpProxyPort, char *a_httpProxyName,
3255*9781SMoriah.Waterland@Sun.COM 	keystore_handle_t a_keystore, char *a_keystoreFile,
3256*9781SMoriah.Waterland@Sun.COM 	char *a_idsName, int *r_repeat)
3257*9781SMoriah.Waterland@Sun.COM {
3258*9781SMoriah.Waterland@Sun.COM 	int		n;
3259*9781SMoriah.Waterland@Sun.COM 	url_hport_t	*proxytmp = NULL;
3260*9781SMoriah.Waterland@Sun.COM 
3261*9781SMoriah.Waterland@Sun.COM 	/* entry assertions */
3262*9781SMoriah.Waterland@Sun.COM 
3263*9781SMoriah.Waterland@Sun.COM 	assert(r_repeat != (int *)NULL);
3264*9781SMoriah.Waterland@Sun.COM 
3265*9781SMoriah.Waterland@Sun.COM 	/* entry debugging info */
3266*9781SMoriah.Waterland@Sun.COM 
3267*9781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_GETPKGLIST_ENTRY);
3268*9781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_GETPKGLIST_ARGS, PSTR(a_idsName), PSTR(pkgdev.dirname),
3269*9781SMoriah.Waterland@Sun.COM 			*r_repeat);
3270*9781SMoriah.Waterland@Sun.COM 
3271*9781SMoriah.Waterland@Sun.COM 	/*
3272*9781SMoriah.Waterland@Sun.COM 	 * get the list of the packages to add
3273*9781SMoriah.Waterland@Sun.COM 	 */
3274*9781SMoriah.Waterland@Sun.COM 
3275*9781SMoriah.Waterland@Sun.COM 	n = pkgGetPackageList(r_pkgList, a_argv, optind, a_categories,
3276*9781SMoriah.Waterland@Sun.COM 				a_categoryList, &pkgdev);
3277*9781SMoriah.Waterland@Sun.COM 
3278*9781SMoriah.Waterland@Sun.COM 	switch (n) {
3279*9781SMoriah.Waterland@Sun.COM 		case -1:	/* no packages found */
3280*9781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_PKGLIST_NONFOUND, PSTR(a_idsName),
3281*9781SMoriah.Waterland@Sun.COM 					pkgdev.dirname);
3282*9781SMoriah.Waterland@Sun.COM 			return (B_FALSE);
3283*9781SMoriah.Waterland@Sun.COM 
3284*9781SMoriah.Waterland@Sun.COM 		case 0:		/* packages found */
3285*9781SMoriah.Waterland@Sun.COM 			break;
3286*9781SMoriah.Waterland@Sun.COM 
3287*9781SMoriah.Waterland@Sun.COM 		default:	/* "quit" error */
3288*9781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_PKGLIST_ERROR, PSTR(a_idsName),
3289*9781SMoriah.Waterland@Sun.COM 				pkgdev.dirname, n);
3290*9781SMoriah.Waterland@Sun.COM 			quit(n);
3291*9781SMoriah.Waterland@Sun.COM 			/* NOTREACHED */
3292*9781SMoriah.Waterland@Sun.COM 	}
3293*9781SMoriah.Waterland@Sun.COM 
3294*9781SMoriah.Waterland@Sun.COM 	/*
3295*9781SMoriah.Waterland@Sun.COM 	 * If we are not ignoring signatures, check the package's
3296*9781SMoriah.Waterland@Sun.COM 	 * signature if one exists.  pkgask doesn't care about
3297*9781SMoriah.Waterland@Sun.COM 	 * signatures though.
3298*9781SMoriah.Waterland@Sun.COM 	 */
3299*9781SMoriah.Waterland@Sun.COM 	if (!askflag && !a_ignoreSignatures && a_idsName &&
3300*9781SMoriah.Waterland@Sun.COM 		(web_ck_authentication() == AUTH_QUIT)) {
3301*9781SMoriah.Waterland@Sun.COM 
3302*9781SMoriah.Waterland@Sun.COM 		PKCS7		*sig = NULL;
3303*9781SMoriah.Waterland@Sun.COM 		STACK_OF(X509)	*cas = NULL;
3304*9781SMoriah.Waterland@Sun.COM 
3305*9781SMoriah.Waterland@Sun.COM 		/* Retrieve signature */
3306*9781SMoriah.Waterland@Sun.COM 		if (!get_signature(a_err, a_idsName, &pkgdev, &sig)) {
3307*9781SMoriah.Waterland@Sun.COM 			pkgerr(a_err);
3308*9781SMoriah.Waterland@Sun.COM 			web_cleanup();
3309*9781SMoriah.Waterland@Sun.COM 			quit(1);
3310*9781SMoriah.Waterland@Sun.COM 			/* NOTREACHED */
3311*9781SMoriah.Waterland@Sun.COM 		}
3312*9781SMoriah.Waterland@Sun.COM 
3313*9781SMoriah.Waterland@Sun.COM 		if (sig != NULL) {
3314*9781SMoriah.Waterland@Sun.COM 			/* Found signature.  Verify. */
3315*9781SMoriah.Waterland@Sun.COM 			if (a_httpProxyName != NULL) {
3316*9781SMoriah.Waterland@Sun.COM 				/* Proxy will be needed for OCSP */
3317*9781SMoriah.Waterland@Sun.COM 				proxytmp = malloc(sizeof (url_hport_t));
3318*9781SMoriah.Waterland@Sun.COM 				if (url_parse_hostport(a_httpProxyName,
3319*9781SMoriah.Waterland@Sun.COM 					proxytmp, a_httpProxyPort)
3320*9781SMoriah.Waterland@Sun.COM 					!= URL_PARSE_SUCCESS) {
3321*9781SMoriah.Waterland@Sun.COM 					progerr(ERR_PROXY,
3322*9781SMoriah.Waterland@Sun.COM 						a_httpProxyName);
3323*9781SMoriah.Waterland@Sun.COM 					PKCS7_free(sig);
3324*9781SMoriah.Waterland@Sun.COM 					quit(99);
3325*9781SMoriah.Waterland@Sun.COM 					/* NOTREACHED */
3326*9781SMoriah.Waterland@Sun.COM 				}
3327*9781SMoriah.Waterland@Sun.COM 			}
3328*9781SMoriah.Waterland@Sun.COM 
3329*9781SMoriah.Waterland@Sun.COM 			/* Start with fresh error stack */
3330*9781SMoriah.Waterland@Sun.COM 			pkgerr_clear(a_err);
3331*9781SMoriah.Waterland@Sun.COM 
3332*9781SMoriah.Waterland@Sun.COM 			if (a_keystore == NULL) {
3333*9781SMoriah.Waterland@Sun.COM 				/* keystore not opened - open it */
3334*9781SMoriah.Waterland@Sun.COM 				if (open_keystore(a_err, a_keystoreFile,
3335*9781SMoriah.Waterland@Sun.COM 					get_prog_name(), pkg_passphrase_cb,
3336*9781SMoriah.Waterland@Sun.COM 					KEYSTORE_DFLT_FLAGS,
3337*9781SMoriah.Waterland@Sun.COM 					&a_keystore) != 0) {
3338*9781SMoriah.Waterland@Sun.COM 					pkgerr(a_err);
3339*9781SMoriah.Waterland@Sun.COM 					web_cleanup();
3340*9781SMoriah.Waterland@Sun.COM 					PKCS7_free(sig);
3341*9781SMoriah.Waterland@Sun.COM 					quit(1);
3342*9781SMoriah.Waterland@Sun.COM 					/* NOTREACHED */
3343*9781SMoriah.Waterland@Sun.COM 				}
3344*9781SMoriah.Waterland@Sun.COM 			}
3345*9781SMoriah.Waterland@Sun.COM 
3346*9781SMoriah.Waterland@Sun.COM 			/* get trusted CA certs */
3347*9781SMoriah.Waterland@Sun.COM 			if (find_ca_certs(a_err, a_keystore, &cas) != 0) {
3348*9781SMoriah.Waterland@Sun.COM 				pkgerr(a_err);
3349*9781SMoriah.Waterland@Sun.COM 				PKCS7_free(sig);
3350*9781SMoriah.Waterland@Sun.COM 				web_cleanup();
3351*9781SMoriah.Waterland@Sun.COM 				quit(1);
3352*9781SMoriah.Waterland@Sun.COM 				/* NOTREACHED */
3353*9781SMoriah.Waterland@Sun.COM 			}
3354*9781SMoriah.Waterland@Sun.COM 
3355*9781SMoriah.Waterland@Sun.COM 			/* Verify signature */
3356*9781SMoriah.Waterland@Sun.COM 			if (!ds_validate_signature(a_err, &pkgdev,
3357*9781SMoriah.Waterland@Sun.COM 				&a_argv[optind], a_idsName, sig,
3358*9781SMoriah.Waterland@Sun.COM 				cas, proxytmp, nointeract)) {
3359*9781SMoriah.Waterland@Sun.COM 				pkgerr(a_err);
3360*9781SMoriah.Waterland@Sun.COM 				quit(99);
3361*9781SMoriah.Waterland@Sun.COM 				/* NOTREACHED */
3362*9781SMoriah.Waterland@Sun.COM 			}
3363*9781SMoriah.Waterland@Sun.COM 
3364*9781SMoriah.Waterland@Sun.COM 			/* cleanup */
3365*9781SMoriah.Waterland@Sun.COM 			PKCS7_free(sig);
3366*9781SMoriah.Waterland@Sun.COM 			web_cleanup();
3367*9781SMoriah.Waterland@Sun.COM 			pkgerr_free(a_err);
3368*9781SMoriah.Waterland@Sun.COM 		}
3369*9781SMoriah.Waterland@Sun.COM 	}
3370*9781SMoriah.Waterland@Sun.COM 
3371*9781SMoriah.Waterland@Sun.COM 	/* order package list if input data stream specified */
3372*9781SMoriah.Waterland@Sun.COM 
3373*9781SMoriah.Waterland@Sun.COM 	if (a_idsName) {
3374*9781SMoriah.Waterland@Sun.COM 		ds_order(*r_pkgList);
3375*9781SMoriah.Waterland@Sun.COM 	}
3376*9781SMoriah.Waterland@Sun.COM 
3377*9781SMoriah.Waterland@Sun.COM 	return (B_TRUE);
3378*9781SMoriah.Waterland@Sun.COM }
3379*9781SMoriah.Waterland@Sun.COM 
3380*9781SMoriah.Waterland@Sun.COM /*
3381*9781SMoriah.Waterland@Sun.COM  * Name:	install_in_one_zone
3382*9781SMoriah.Waterland@Sun.COM  * Description:	Install a single package in a single zone
3383*9781SMoriah.Waterland@Sun.COM  * Arguments:	a_inheritedPkgDirs - pointer to array of strings, each one
3384*9781SMoriah.Waterland@Sun.COM  *			representing the non-global zones full path of a
3385*9781SMoriah.Waterland@Sun.COM  *			directory that is inherited from the global zone.
3386*9781SMoriah.Waterland@Sun.COM  *		a_zoneName - pointer to string representing the name of the
3387*9781SMoriah.Waterland@Sun.COM  *			zone to install the package into.
3388*9781SMoriah.Waterland@Sun.COM  *		a_idsName - pointer to string representing the data stream
3389*9781SMoriah.Waterland@Sun.COM  *			device (input data stream) containing the package to
3390*9781SMoriah.Waterland@Sun.COM  *			be installed.
3391*9781SMoriah.Waterland@Sun.COM  *			If this is == NULL the package is assumed to be
3392*9781SMoriah.Waterland@Sun.COM  *			spooled in the zone temporary directory.
3393*9781SMoriah.Waterland@Sun.COM  *		a_zoneAdminFile - pointer to string representing the admin
3394*9781SMoriah.Waterland@Sun.COM  *			file to pass to pkginstall when installing the package.
3395*9781SMoriah.Waterland@Sun.COM  *			If this is == NULL no admin file is given to pkginstall.
3396*9781SMoriah.Waterland@Sun.COM  *		a_zoneTempDir - pointer to string representing the temporary
3397*9781SMoriah.Waterland@Sun.COM  *			directory in which spooled packages can be found if
3398*9781SMoriah.Waterland@Sun.COM  *			a_idsName is == NULL.
3399*9781SMoriah.Waterland@Sun.COM  *		a_altBinDir - pointer to string representing an alternative
3400*9781SMoriah.Waterland@Sun.COM  *			binary location directory to pass to pkginstall.
3401*9781SMoriah.Waterland@Sun.COM  *			If this is == NULL no alternative binary location is
3402*9781SMoriah.Waterland@Sun.COM  *			passed to pkginstall.
3403*9781SMoriah.Waterland@Sun.COM  *		a_scratchName - pointer to string representing the name of the
3404*9781SMoriah.Waterland@Sun.COM  *			scratch zone to use for installation.
3405*9781SMoriah.Waterland@Sun.COM  *		a_zoneState - state of the zone; must be mounted or running.
3406*9781SMoriah.Waterland@Sun.COM  * Returns:	void
3407*9781SMoriah.Waterland@Sun.COM  * NOTE:	As a side effect, "ckreturn" is called on the result returned
3408*9781SMoriah.Waterland@Sun.COM  *		from running 'pkginstall' in the zone; this sets several global
3409*9781SMoriah.Waterland@Sun.COM  *		variables which allows the caller to determine the result of
3410*9781SMoriah.Waterland@Sun.COM  *		the installation operation.
3411*9781SMoriah.Waterland@Sun.COM  */
3412*9781SMoriah.Waterland@Sun.COM 
3413*9781SMoriah.Waterland@Sun.COM static void
3414*9781SMoriah.Waterland@Sun.COM install_in_one_zone(char **a_inheritedPkgDirs, char *a_zoneName,
3415*9781SMoriah.Waterland@Sun.COM 	char *a_idsName, char *a_zoneAdminFile, char *a_zoneTempDir,
3416*9781SMoriah.Waterland@Sun.COM 	char *a_altBinDir, zone_state_t a_zoneState)
3417*9781SMoriah.Waterland@Sun.COM {
3418*9781SMoriah.Waterland@Sun.COM 	char	zoneStreamName[PATH_MAX] = {'\0'};
3419*9781SMoriah.Waterland@Sun.COM 	int	n;
3420*9781SMoriah.Waterland@Sun.COM 
3421*9781SMoriah.Waterland@Sun.COM 	/* entry assertions */
3422*9781SMoriah.Waterland@Sun.COM 
3423*9781SMoriah.Waterland@Sun.COM 	assert(a_zoneName != (char *)NULL);
3424*9781SMoriah.Waterland@Sun.COM 	assert(*a_zoneName != '\0');
3425*9781SMoriah.Waterland@Sun.COM 
3426*9781SMoriah.Waterland@Sun.COM 	/* entry debugging info */
3427*9781SMoriah.Waterland@Sun.COM 
3428*9781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_INSTINONEZONE_ENTRY);
3429*9781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_INSTINONEZONE_ARGS, a_zoneName, PSTR(a_idsName),
3430*9781SMoriah.Waterland@Sun.COM 			PSTR(a_zoneAdminFile), PSTR(a_zoneTempDir),
3431*9781SMoriah.Waterland@Sun.COM 			PSTR(a_altBinDir));
3432*9781SMoriah.Waterland@Sun.COM 
3433*9781SMoriah.Waterland@Sun.COM 	/* echo operation to perform to stdout */
3434*9781SMoriah.Waterland@Sun.COM 
3435*9781SMoriah.Waterland@Sun.COM 	echo(MSG_INSTALL_PKG_IN_ZONE, pkginst, a_zoneName);
3436*9781SMoriah.Waterland@Sun.COM 
3437*9781SMoriah.Waterland@Sun.COM 	/* determine path to the package stream */
3438*9781SMoriah.Waterland@Sun.COM 
3439*9781SMoriah.Waterland@Sun.COM 	if (a_idsName == (char *)NULL) {
3440*9781SMoriah.Waterland@Sun.COM 		/* locate temp stream created earlier */
3441*9781SMoriah.Waterland@Sun.COM 		(void) snprintf(zoneStreamName, sizeof (zoneStreamName),
3442*9781SMoriah.Waterland@Sun.COM 			"%s/%s.dstream", a_zoneTempDir, pkginst);
3443*9781SMoriah.Waterland@Sun.COM 	} else {
3444*9781SMoriah.Waterland@Sun.COM 		/* use stream passed in on command line */
3445*9781SMoriah.Waterland@Sun.COM 		(void) snprintf(zoneStreamName, sizeof (zoneStreamName),
3446*9781SMoriah.Waterland@Sun.COM 			"%s", a_idsName);
3447*9781SMoriah.Waterland@Sun.COM 	}
3448*9781SMoriah.Waterland@Sun.COM 
3449*9781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_INSTALL_IN_ZONE, pkginst, a_zoneName, zoneStreamName);
3450*9781SMoriah.Waterland@Sun.COM 
3451*9781SMoriah.Waterland@Sun.COM 	n = pkgZoneInstall(a_zoneName, a_inheritedPkgDirs, a_zoneState,
3452*9781SMoriah.Waterland@Sun.COM 		zoneStreamName, a_altBinDir, a_zoneAdminFile);
3453*9781SMoriah.Waterland@Sun.COM 
3454*9781SMoriah.Waterland@Sun.COM 	/* set success/fail condition variables */
3455*9781SMoriah.Waterland@Sun.COM 
3456*9781SMoriah.Waterland@Sun.COM 	ckreturn(n);
3457*9781SMoriah.Waterland@Sun.COM 
3458*9781SMoriah.Waterland@Sun.COM 	/* exit debugging info */
3459*9781SMoriah.Waterland@Sun.COM 
3460*9781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_INSTALL_FLAG_VALUES, "after install", admnflag, doreboot,
3461*9781SMoriah.Waterland@Sun.COM 		failflag, interrupted, intrflag, ireboot, needconsult,
3462*9781SMoriah.Waterland@Sun.COM 		nullflag, warnflag);
3463*9781SMoriah.Waterland@Sun.COM }
3464*9781SMoriah.Waterland@Sun.COM 
3465*9781SMoriah.Waterland@Sun.COM /*
3466*9781SMoriah.Waterland@Sun.COM  * Name:	install_in_zones
3467*9781SMoriah.Waterland@Sun.COM  * Description:	Install a single package in the zones that are running from
3468*9781SMoriah.Waterland@Sun.COM  *		a list of zones
3469*9781SMoriah.Waterland@Sun.COM  * Arguments:	a_zlst - list of zones to install the package into
3470*9781SMoriah.Waterland@Sun.COM  *		a_idsName - pointer to string representing the data stream
3471*9781SMoriah.Waterland@Sun.COM  *			device (input data stream) containing the package to
3472*9781SMoriah.Waterland@Sun.COM  *			be installed.
3473*9781SMoriah.Waterland@Sun.COM  *			If this is == NULL the package is assumed to be
3474*9781SMoriah.Waterland@Sun.COM  *			spooled in the zone temporary directory.
3475*9781SMoriah.Waterland@Sun.COM  *		a_altBinDir - pointer to string representing an alternative
3476*9781SMoriah.Waterland@Sun.COM  *			binary location directory to pass to pkginstall.
3477*9781SMoriah.Waterland@Sun.COM  *			If this is == NULL no alternative binary location is
3478*9781SMoriah.Waterland@Sun.COM  *			passed to pkginstall.
3479*9781SMoriah.Waterland@Sun.COM  *		a_zoneAdminFile - pointer to string representing the admin
3480*9781SMoriah.Waterland@Sun.COM  *			file to pass to pkginstall when installing the package.
3481*9781SMoriah.Waterland@Sun.COM  *			If this is == NULL no admin file is given to pkginstall.
3482*9781SMoriah.Waterland@Sun.COM  *		a_zoneTempDir - pointer to string representing the temporary
3483*9781SMoriah.Waterland@Sun.COM  *			directory in which spooled packages can be found if
3484*9781SMoriah.Waterland@Sun.COM  *			a_idsName is == NULL.
3485*9781SMoriah.Waterland@Sun.COM  */
3486*9781SMoriah.Waterland@Sun.COM 
3487*9781SMoriah.Waterland@Sun.COM static int
3488*9781SMoriah.Waterland@Sun.COM install_in_zones(zoneList_t a_zlst, char *a_idsName, char *a_altBinDir,
3489*9781SMoriah.Waterland@Sun.COM 	char *a_zoneAdminFile, char *a_zoneTempDir)
3490*9781SMoriah.Waterland@Sun.COM {
3491*9781SMoriah.Waterland@Sun.COM 	char		**inheritedPkgDirs;
3492*9781SMoriah.Waterland@Sun.COM 	char		*zoneName;
3493*9781SMoriah.Waterland@Sun.COM 	int		zoneIndex;
3494*9781SMoriah.Waterland@Sun.COM 	int		zonesSkipped = 0;
3495*9781SMoriah.Waterland@Sun.COM 	zone_state_t	zst;
3496*9781SMoriah.Waterland@Sun.COM 
3497*9781SMoriah.Waterland@Sun.COM 	/* entry assertions */
3498*9781SMoriah.Waterland@Sun.COM 
3499*9781SMoriah.Waterland@Sun.COM 	assert(a_zlst != (zoneList_t)NULL);
3500*9781SMoriah.Waterland@Sun.COM 
3501*9781SMoriah.Waterland@Sun.COM 	/* entry debugging info */
3502*9781SMoriah.Waterland@Sun.COM 
3503*9781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_INSTALLINZONES_ENTRY);
3504*9781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_INSTALLINZONES_ARGS, PSTR(a_idsName),
3505*9781SMoriah.Waterland@Sun.COM 			PSTR(a_zoneAdminFile), PSTR(a_zoneTempDir));
3506*9781SMoriah.Waterland@Sun.COM 
3507*9781SMoriah.Waterland@Sun.COM 	/* process each zone in the list */
3508*9781SMoriah.Waterland@Sun.COM 
3509*9781SMoriah.Waterland@Sun.COM 	for (zoneIndex = 0;
3510*9781SMoriah.Waterland@Sun.COM 		(zoneName = z_zlist_get_zonename(a_zlst, zoneIndex)) != NULL;
3511*9781SMoriah.Waterland@Sun.COM 		zoneIndex++) {
3512*9781SMoriah.Waterland@Sun.COM 
3513*9781SMoriah.Waterland@Sun.COM 		/* skip the zone if it is NOT running */
3514*9781SMoriah.Waterland@Sun.COM 
3515*9781SMoriah.Waterland@Sun.COM 		zst = z_zlist_get_current_state(a_zlst, zoneIndex);
3516*9781SMoriah.Waterland@Sun.COM 		if (zst != ZONE_STATE_RUNNING && zst != ZONE_STATE_MOUNTED) {
3517*9781SMoriah.Waterland@Sun.COM 			zonesSkipped++;
3518*9781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_SKIPPING_ZONE, zoneName);
3519*9781SMoriah.Waterland@Sun.COM 			continue;
3520*9781SMoriah.Waterland@Sun.COM 		}
3521*9781SMoriah.Waterland@Sun.COM 
3522*9781SMoriah.Waterland@Sun.COM 		/* determine list of directories inherited from global zone */
3523*9781SMoriah.Waterland@Sun.COM 
3524*9781SMoriah.Waterland@Sun.COM 		inheritedPkgDirs = z_zlist_get_inherited_pkg_dirs(a_zlst,
3525*9781SMoriah.Waterland@Sun.COM 					zoneIndex);
3526*9781SMoriah.Waterland@Sun.COM 
3527*9781SMoriah.Waterland@Sun.COM 		/* install the package in this zone */
3528*9781SMoriah.Waterland@Sun.COM 
3529*9781SMoriah.Waterland@Sun.COM 		install_in_one_zone(inheritedPkgDirs,
3530*9781SMoriah.Waterland@Sun.COM 		    z_zlist_get_scratch(a_zlst, zoneIndex), a_idsName,
3531*9781SMoriah.Waterland@Sun.COM 		    a_zoneAdminFile, a_zoneTempDir, a_altBinDir, zst);
3532*9781SMoriah.Waterland@Sun.COM 	}
3533*9781SMoriah.Waterland@Sun.COM 
3534*9781SMoriah.Waterland@Sun.COM 	return (zonesSkipped);
3535*9781SMoriah.Waterland@Sun.COM }
3536*9781SMoriah.Waterland@Sun.COM 
3537*9781SMoriah.Waterland@Sun.COM /*
3538*9781SMoriah.Waterland@Sun.COM  * Name:	boot_and_install_in_zones
3539*9781SMoriah.Waterland@Sun.COM  * Description:	Install a single package in the zones that are NOT running from
3540*9781SMoriah.Waterland@Sun.COM  *		a list of zones - each zone is booted, the package installed,
3541*9781SMoriah.Waterland@Sun.COM  *		and the zone is halted
3542*9781SMoriah.Waterland@Sun.COM  * Arguments:	a_zlst - list of zones to install the package into
3543*9781SMoriah.Waterland@Sun.COM  *		a_idsName - pointer to string representing the data stream
3544*9781SMoriah.Waterland@Sun.COM  *			device (input data stream) containing the package to
3545*9781SMoriah.Waterland@Sun.COM  *			be installed.
3546*9781SMoriah.Waterland@Sun.COM  *			If this is == NULL the package is assumed to be
3547*9781SMoriah.Waterland@Sun.COM  *			spooled in the zone temporary directory.
3548*9781SMoriah.Waterland@Sun.COM  *		a_altBinDir - pointer to string representing an alternative
3549*9781SMoriah.Waterland@Sun.COM  *			binary location directory to pass to pkginstall.
3550*9781SMoriah.Waterland@Sun.COM  *			If this is == NULL no alternative binary location is
3551*9781SMoriah.Waterland@Sun.COM  *			passed to pkginstall.
3552*9781SMoriah.Waterland@Sun.COM  *		a_zoneAdminFile - pointer to string representing the admin
3553*9781SMoriah.Waterland@Sun.COM  *			file to pass to pkginstall when installing the package.
3554*9781SMoriah.Waterland@Sun.COM  *			If this is == NULL no admin file is given to pkginstall.
3555*9781SMoriah.Waterland@Sun.COM  *		a_zoneTempDir - pointer to string representing the temporary
3556*9781SMoriah.Waterland@Sun.COM  *			directory in which spooled packages can be found if
3557*9781SMoriah.Waterland@Sun.COM  *			a_idsName is == NULL.
3558*9781SMoriah.Waterland@Sun.COM  */
3559*9781SMoriah.Waterland@Sun.COM 
3560*9781SMoriah.Waterland@Sun.COM static int
3561*9781SMoriah.Waterland@Sun.COM boot_and_install_in_zones(zoneList_t a_zlst, char *a_idsName, char *a_altBinDir,
3562*9781SMoriah.Waterland@Sun.COM 	char *a_zoneAdminFile, char *a_zoneTempDir)
3563*9781SMoriah.Waterland@Sun.COM {
3564*9781SMoriah.Waterland@Sun.COM 	boolean_t	b;
3565*9781SMoriah.Waterland@Sun.COM 	char		**inheritedPkgDirs;
3566*9781SMoriah.Waterland@Sun.COM 	char		*zoneName;
3567*9781SMoriah.Waterland@Sun.COM 	int		zoneIndex;
3568*9781SMoriah.Waterland@Sun.COM 	int		zonesSkipped = 0;
3569*9781SMoriah.Waterland@Sun.COM 	zone_state_t	zst;
3570*9781SMoriah.Waterland@Sun.COM 
3571*9781SMoriah.Waterland@Sun.COM 	/* entry assertions */
3572*9781SMoriah.Waterland@Sun.COM 
3573*9781SMoriah.Waterland@Sun.COM 	assert(a_zlst != (zoneList_t)NULL);
3574*9781SMoriah.Waterland@Sun.COM 
3575*9781SMoriah.Waterland@Sun.COM 	/* entry debugging info */
3576*9781SMoriah.Waterland@Sun.COM 
3577*9781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_BOOTINSTALLINZONES_ENTRY);
3578*9781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_BOOTINSTALLINZONES_ARGS, PSTR(a_idsName),
3579*9781SMoriah.Waterland@Sun.COM 			PSTR(a_zoneAdminFile), PSTR(a_zoneTempDir));
3580*9781SMoriah.Waterland@Sun.COM 
3581*9781SMoriah.Waterland@Sun.COM 	/* process each zone in the list */
3582*9781SMoriah.Waterland@Sun.COM 
3583*9781SMoriah.Waterland@Sun.COM 	for (zoneIndex = 0;
3584*9781SMoriah.Waterland@Sun.COM 		(zoneName = z_zlist_get_zonename(a_zlst, zoneIndex)) != NULL;
3585*9781SMoriah.Waterland@Sun.COM 		zoneIndex++) {
3586*9781SMoriah.Waterland@Sun.COM 
3587*9781SMoriah.Waterland@Sun.COM 		/* skip the zone if it IS running */
3588*9781SMoriah.Waterland@Sun.COM 
3589*9781SMoriah.Waterland@Sun.COM 		zst = z_zlist_get_current_state(a_zlst, zoneIndex);
3590*9781SMoriah.Waterland@Sun.COM 		if (zst == ZONE_STATE_RUNNING || zst == ZONE_STATE_MOUNTED) {
3591*9781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_SKIPPING_ZONE_BOOT, zoneName);
3592*9781SMoriah.Waterland@Sun.COM 			continue;
3593*9781SMoriah.Waterland@Sun.COM 		}
3594*9781SMoriah.Waterland@Sun.COM 
3595*9781SMoriah.Waterland@Sun.COM 		/* skip the zone if it is NOT bootable */
3596*9781SMoriah.Waterland@Sun.COM 
3597*9781SMoriah.Waterland@Sun.COM 		if (z_zlist_is_zone_runnable(a_zlst, zoneIndex) == B_FALSE) {
3598*9781SMoriah.Waterland@Sun.COM 			echo(MSG_SKIPPING_ZONE_NOT_RUNNABLE, zoneName);
3599*9781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_SKIPPING_ZONE_NOT_RUNNABLE, zoneName);
3600*9781SMoriah.Waterland@Sun.COM 			continue;
3601*9781SMoriah.Waterland@Sun.COM 		}
3602*9781SMoriah.Waterland@Sun.COM 
3603*9781SMoriah.Waterland@Sun.COM 		/* mount up the zone */
3604*9781SMoriah.Waterland@Sun.COM 
3605*9781SMoriah.Waterland@Sun.COM 		echo(MSG_BOOTING_ZONE, zoneName);
3606*9781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_BOOTING_ZONE, zoneName);
3607*9781SMoriah.Waterland@Sun.COM 
3608*9781SMoriah.Waterland@Sun.COM 		b = z_zlist_change_zone_state(a_zlst, zoneIndex,
3609*9781SMoriah.Waterland@Sun.COM 					ZONE_STATE_MOUNTED);
3610*9781SMoriah.Waterland@Sun.COM 		if (b == B_FALSE) {
3611*9781SMoriah.Waterland@Sun.COM 			progerr(ERR_CANNOT_BOOT_ZONE, zoneName);
3612*9781SMoriah.Waterland@Sun.COM 			/* set fatal error return condition */
3613*9781SMoriah.Waterland@Sun.COM 			ckreturn(1);
3614*9781SMoriah.Waterland@Sun.COM 			zonesSkipped++;
3615*9781SMoriah.Waterland@Sun.COM 			continue;
3616*9781SMoriah.Waterland@Sun.COM 		}
3617*9781SMoriah.Waterland@Sun.COM 
3618*9781SMoriah.Waterland@Sun.COM 		/* determine list of directories inherited from global zone */
3619*9781SMoriah.Waterland@Sun.COM 
3620*9781SMoriah.Waterland@Sun.COM 		inheritedPkgDirs = z_zlist_get_inherited_pkg_dirs(a_zlst,
3621*9781SMoriah.Waterland@Sun.COM 					zoneIndex);
3622*9781SMoriah.Waterland@Sun.COM 
3623*9781SMoriah.Waterland@Sun.COM 		/* install the package in this zone */
3624*9781SMoriah.Waterland@Sun.COM 
3625*9781SMoriah.Waterland@Sun.COM 		install_in_one_zone(inheritedPkgDirs,
3626*9781SMoriah.Waterland@Sun.COM 		    z_zlist_get_scratch(a_zlst, zoneIndex), a_idsName,
3627*9781SMoriah.Waterland@Sun.COM 		    a_zoneAdminFile, a_zoneTempDir, a_altBinDir,
3628*9781SMoriah.Waterland@Sun.COM 		    ZONE_STATE_MOUNTED);
3629*9781SMoriah.Waterland@Sun.COM 
3630*9781SMoriah.Waterland@Sun.COM 		/* restore original state of zone */
3631*9781SMoriah.Waterland@Sun.COM 
3632*9781SMoriah.Waterland@Sun.COM 		echo(MSG_RESTORE_ZONE_STATE, zoneName);
3633*9781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_RESTORE_ZONE_STATE, zoneName);
3634*9781SMoriah.Waterland@Sun.COM 
3635*9781SMoriah.Waterland@Sun.COM 		b = z_zlist_restore_zone_state(a_zlst, zoneIndex);
3636*9781SMoriah.Waterland@Sun.COM 	}
3637*9781SMoriah.Waterland@Sun.COM 
3638*9781SMoriah.Waterland@Sun.COM 	return (zonesSkipped);
3639*9781SMoriah.Waterland@Sun.COM }
3640*9781SMoriah.Waterland@Sun.COM 
3641*9781SMoriah.Waterland@Sun.COM /*
3642*9781SMoriah.Waterland@Sun.COM  * Name:	pkginstall_check_in_one_zone
3643*9781SMoriah.Waterland@Sun.COM  * Description:	Do a pre install check of a single package in a single zone
3644*9781SMoriah.Waterland@Sun.COM  * Arguments:	a_inheritedPkgDirs - pointer to array of strings, each one
3645*9781SMoriah.Waterland@Sun.COM  *			representing the non-global zones full path of a
3646*9781SMoriah.Waterland@Sun.COM  *			directory that is inherited from the global zone.
3647*9781SMoriah.Waterland@Sun.COM  *		a_zoneName - pointer to string representing the name of the
3648*9781SMoriah.Waterland@Sun.COM  *			zone to check install the package in.
3649*9781SMoriah.Waterland@Sun.COM  *		a_idsName - pointer to string representing the data stream
3650*9781SMoriah.Waterland@Sun.COM  *			device (input data stream) containing the package to
3651*9781SMoriah.Waterland@Sun.COM  *			be check installed.
3652*9781SMoriah.Waterland@Sun.COM  *			If this is == NULL the package is assumed to be
3653*9781SMoriah.Waterland@Sun.COM  *			spooled in the zone temporary directory.
3654*9781SMoriah.Waterland@Sun.COM  *		a_zoneAdminFile - pointer to string representing the admin
3655*9781SMoriah.Waterland@Sun.COM  *			file to pass to pkginstall when installing the package.
3656*9781SMoriah.Waterland@Sun.COM  *			If this is == NULL no admin file is given to pkginstall.
3657*9781SMoriah.Waterland@Sun.COM  *		a_zoneTempDir - pointer to string representing the temporary
3658*9781SMoriah.Waterland@Sun.COM  *			directory in which spooled packages can be found if
3659*9781SMoriah.Waterland@Sun.COM  *			a_idsName is == NULL.
3660*9781SMoriah.Waterland@Sun.COM  *		a_altBinDir - pointer to string representing an alternative
3661*9781SMoriah.Waterland@Sun.COM  *			binary location directory to pass to pkginstall.
3662*9781SMoriah.Waterland@Sun.COM  *			If this is == NULL no alternative binary location is
3663*9781SMoriah.Waterland@Sun.COM  *			passed to pkginstall.
3664*9781SMoriah.Waterland@Sun.COM  *		a_scratchName - pointer to string representing the name of the
3665*9781SMoriah.Waterland@Sun.COM  *			scratch zone to use for installation.
3666*9781SMoriah.Waterland@Sun.COM  *		a_zoneState - state of the zone; must be mounted or running.
3667*9781SMoriah.Waterland@Sun.COM  * Returns:	void
3668*9781SMoriah.Waterland@Sun.COM  * NOTE:	As a side effect, "ckreturn" is called on the result returned
3669*9781SMoriah.Waterland@Sun.COM  *		from running 'pkginstall' in the zone; this sets several global
3670*9781SMoriah.Waterland@Sun.COM  *		variables which allows the caller to determine the result of
3671*9781SMoriah.Waterland@Sun.COM  *		the pre installation check operation.
3672*9781SMoriah.Waterland@Sun.COM  */
3673*9781SMoriah.Waterland@Sun.COM 
3674*9781SMoriah.Waterland@Sun.COM static void
3675*9781SMoriah.Waterland@Sun.COM pkginstall_check_in_one_zone(char **a_inheritedPkgDirs, char *a_zoneName,
3676*9781SMoriah.Waterland@Sun.COM 	char *a_idsName, char *a_zoneAdminFile, char *a_zoneTempDir,
3677*9781SMoriah.Waterland@Sun.COM 	char *a_altBinDir, char *a_scratchName, zone_state_t a_zoneState)
3678*9781SMoriah.Waterland@Sun.COM {
3679*9781SMoriah.Waterland@Sun.COM 	char	preinstallcheckPath[PATH_MAX+1];
3680*9781SMoriah.Waterland@Sun.COM 	char	zoneStreamName[PATH_MAX] = {'\0'};
3681*9781SMoriah.Waterland@Sun.COM 	int	n;
3682*9781SMoriah.Waterland@Sun.COM 
3683*9781SMoriah.Waterland@Sun.COM 	echo(MSG_CHECKINSTALL_PKG_IN_ZONE, pkginst, a_zoneName);
3684*9781SMoriah.Waterland@Sun.COM 	echoDebug(MSG_CHECKINSTALL_PKG_IN_ZONE, pkginst, a_zoneName);
3685*9781SMoriah.Waterland@Sun.COM 
3686*9781SMoriah.Waterland@Sun.COM 	(void) snprintf(preinstallcheckPath, sizeof (preinstallcheckPath),
3687*9781SMoriah.Waterland@Sun.COM 		"%s/%s.%s.preinstallcheck.txt", a_zoneTempDir, pkginst,
3688*9781SMoriah.Waterland@Sun.COM 		a_zoneName);
3689*9781SMoriah.Waterland@Sun.COM 
3690*9781SMoriah.Waterland@Sun.COM 	if (a_idsName == (char *)NULL) {
3691*9781SMoriah.Waterland@Sun.COM 		/* locate temporary stream created earlier */
3692*9781SMoriah.Waterland@Sun.COM 		(void) snprintf(zoneStreamName, sizeof (zoneStreamName),
3693*9781SMoriah.Waterland@Sun.COM 			"%s/%s.dstream", a_zoneTempDir, pkginst);
3694*9781SMoriah.Waterland@Sun.COM 	} else {
3695*9781SMoriah.Waterland@Sun.COM 		(void) snprintf(zoneStreamName, sizeof (zoneStreamName),
3696*9781SMoriah.Waterland@Sun.COM 			"%s", a_idsName);
3697*9781SMoriah.Waterland@Sun.COM 	}
3698*9781SMoriah.Waterland@Sun.COM 
3699*9781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_CHECKINSTALL_IN_ZONE, pkginst, a_zoneName,
3700*9781SMoriah.Waterland@Sun.COM 						zoneStreamName);
3701*9781SMoriah.Waterland@Sun.COM 
3702*9781SMoriah.Waterland@Sun.COM 	n = pkgZoneCheckInstall(a_scratchName, a_inheritedPkgDirs,
3703*9781SMoriah.Waterland@Sun.COM 	    a_zoneState, zoneStreamName, a_altBinDir, a_zoneAdminFile,
3704*9781SMoriah.Waterland@Sun.COM 	    preinstallcheckPath);
3705*9781SMoriah.Waterland@Sun.COM 
3706*9781SMoriah.Waterland@Sun.COM 	/* set success/fail condition variables */
3707*9781SMoriah.Waterland@Sun.COM 
3708*9781SMoriah.Waterland@Sun.COM 	ckreturn(n);
3709*9781SMoriah.Waterland@Sun.COM 
3710*9781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_INSTALL_FLAG_VALUES, "after preinstall check",
3711*9781SMoriah.Waterland@Sun.COM 		admnflag, doreboot, failflag, interrupted, intrflag,
3712*9781SMoriah.Waterland@Sun.COM 		ireboot, needconsult, nullflag, warnflag);
3713*9781SMoriah.Waterland@Sun.COM }
3714*9781SMoriah.Waterland@Sun.COM 
3715*9781SMoriah.Waterland@Sun.COM /*
3716*9781SMoriah.Waterland@Sun.COM  * Name:	pkginstall_check_in_zones
3717*9781SMoriah.Waterland@Sun.COM  * Description:	Check installation of a single package in the zones that
3718*9781SMoriah.Waterland@Sun.COM  *		are running from a list of zones
3719*9781SMoriah.Waterland@Sun.COM  * Arguments:	a_zlst - list of zones to check install the package
3720*9781SMoriah.Waterland@Sun.COM  *		a_idsName - pointer to string representing the data stream
3721*9781SMoriah.Waterland@Sun.COM  *			device (input data stream) containing the package to
3722*9781SMoriah.Waterland@Sun.COM  *			be check installed.
3723*9781SMoriah.Waterland@Sun.COM  *			If this is == NULL the package is assumed to be
3724*9781SMoriah.Waterland@Sun.COM  *			spooled in the zone temporary directory.
3725*9781SMoriah.Waterland@Sun.COM  *		a_altBinDir - pointer to string representing an alternative
3726*9781SMoriah.Waterland@Sun.COM  *			binary location directory to pass to pkginstall.
3727*9781SMoriah.Waterland@Sun.COM  *			If this is == NULL no alternative binary location is
3728*9781SMoriah.Waterland@Sun.COM  *			passed to pkginstall.
3729*9781SMoriah.Waterland@Sun.COM  *		a_zoneAdminFile - pointer to string representing the admin
3730*9781SMoriah.Waterland@Sun.COM  *			file to pass to pkginstall when checking the installing
3731*9781SMoriah.Waterland@Sun.COM  *			of the package.
3732*9781SMoriah.Waterland@Sun.COM  *			If this is == NULL no admin file is given to pkginstall.
3733*9781SMoriah.Waterland@Sun.COM  *		a_zoneTempDir - pointer to string representing the temporary
3734*9781SMoriah.Waterland@Sun.COM  *			directory in which spooled packages can be found if
3735*9781SMoriah.Waterland@Sun.COM  *			a_idsName is == NULL.
3736*9781SMoriah.Waterland@Sun.COM  */
3737*9781SMoriah.Waterland@Sun.COM 
3738*9781SMoriah.Waterland@Sun.COM static int
3739*9781SMoriah.Waterland@Sun.COM pkginstall_check_in_zones(zoneList_t a_zlst, char *a_idsName, char *a_altBinDir,
3740*9781SMoriah.Waterland@Sun.COM 	char *a_zoneAdminFile, char *a_zoneTempDir)
3741*9781SMoriah.Waterland@Sun.COM {
3742*9781SMoriah.Waterland@Sun.COM 	char		**inheritedPkgDirs;
3743*9781SMoriah.Waterland@Sun.COM 	char		*zoneName;
3744*9781SMoriah.Waterland@Sun.COM 	int		zoneIndex;
3745*9781SMoriah.Waterland@Sun.COM 	int		zonesSkipped = 0;
3746*9781SMoriah.Waterland@Sun.COM 	zone_state_t	zst;
3747*9781SMoriah.Waterland@Sun.COM 
3748*9781SMoriah.Waterland@Sun.COM 	for (zoneIndex = 0;
3749*9781SMoriah.Waterland@Sun.COM 		(zoneName = z_zlist_get_zonename(a_zlst, zoneIndex)) != NULL;
3750*9781SMoriah.Waterland@Sun.COM 		zoneIndex++) {
3751*9781SMoriah.Waterland@Sun.COM 
3752*9781SMoriah.Waterland@Sun.COM 		zst = z_zlist_get_current_state(a_zlst, zoneIndex);
3753*9781SMoriah.Waterland@Sun.COM 		if (zst != ZONE_STATE_RUNNING && zst != ZONE_STATE_MOUNTED) {
3754*9781SMoriah.Waterland@Sun.COM 			zonesSkipped++;
3755*9781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_SKIPPING_ZONE, zoneName);
3756*9781SMoriah.Waterland@Sun.COM 			continue;
3757*9781SMoriah.Waterland@Sun.COM 		}
3758*9781SMoriah.Waterland@Sun.COM 
3759*9781SMoriah.Waterland@Sun.COM 		inheritedPkgDirs = z_zlist_get_inherited_pkg_dirs(a_zlst,
3760*9781SMoriah.Waterland@Sun.COM 					zoneIndex);
3761*9781SMoriah.Waterland@Sun.COM 
3762*9781SMoriah.Waterland@Sun.COM 		pkginstall_check_in_one_zone(inheritedPkgDirs, zoneName,
3763*9781SMoriah.Waterland@Sun.COM 		    a_idsName, a_zoneAdminFile, a_zoneTempDir, a_altBinDir,
3764*9781SMoriah.Waterland@Sun.COM 		    z_zlist_get_scratch(a_zlst, zoneIndex), zst);
3765*9781SMoriah.Waterland@Sun.COM 	}
3766*9781SMoriah.Waterland@Sun.COM 
3767*9781SMoriah.Waterland@Sun.COM 	return (zonesSkipped);
3768*9781SMoriah.Waterland@Sun.COM }
3769*9781SMoriah.Waterland@Sun.COM 
3770*9781SMoriah.Waterland@Sun.COM /*
3771*9781SMoriah.Waterland@Sun.COM  * Name:	boot_and_pkginstall_check_in_zones
3772*9781SMoriah.Waterland@Sun.COM  * Description:	Check installation of a single package in the zones that
3773*9781SMoriah.Waterland@Sun.COM  *		are NOT running from a list of zones - each zone is booted,
3774*9781SMoriah.Waterland@Sun.COM  *		the package installation is checked, and the zone is halted.
3775*9781SMoriah.Waterland@Sun.COM  * Arguments:	a_zlst - list of zones to install the package into
3776*9781SMoriah.Waterland@Sun.COM  *		a_idsName - pointer to string representing the data stream
3777*9781SMoriah.Waterland@Sun.COM  *			device (input data stream) containing the package to
3778*9781SMoriah.Waterland@Sun.COM  *			be check installed.
3779*9781SMoriah.Waterland@Sun.COM  *			If this is == NULL the package is assumed to be
3780*9781SMoriah.Waterland@Sun.COM  *			spooled in the zone temporary directory.
3781*9781SMoriah.Waterland@Sun.COM  *		a_altBinDir - pointer to string representing an alternative
3782*9781SMoriah.Waterland@Sun.COM  *			binary location directory to pass to pkginstall.
3783*9781SMoriah.Waterland@Sun.COM  *			If this is == NULL no alternative binary location is
3784*9781SMoriah.Waterland@Sun.COM  *			passed to pkginstall.
3785*9781SMoriah.Waterland@Sun.COM  *		a_zoneAdminFile - pointer to string representing the admin
3786*9781SMoriah.Waterland@Sun.COM  *			file to pass to pkginstall when check installing the
3787*9781SMoriah.Waterland@Sun.COM  *			package.
3788*9781SMoriah.Waterland@Sun.COM  *			If this is == NULL no admin file is given to pkginstall.
3789*9781SMoriah.Waterland@Sun.COM  *		a_zoneTempDir - pointer to string representing the temporary
3790*9781SMoriah.Waterland@Sun.COM  *			directory in which spooled packages can be found if
3791*9781SMoriah.Waterland@Sun.COM  *			a_idsName is == NULL.
3792*9781SMoriah.Waterland@Sun.COM  */
3793*9781SMoriah.Waterland@Sun.COM 
3794*9781SMoriah.Waterland@Sun.COM static int
3795*9781SMoriah.Waterland@Sun.COM boot_and_pkginstall_check_in_zones(zoneList_t a_zlst, char *a_idsName,
3796*9781SMoriah.Waterland@Sun.COM 	char *a_altBinDir, char *a_zoneAdminFile, char *a_zoneTempDir)
3797*9781SMoriah.Waterland@Sun.COM {
3798*9781SMoriah.Waterland@Sun.COM 	int		zoneIndex;
3799*9781SMoriah.Waterland@Sun.COM 	int		zonesSkipped = 0;
3800*9781SMoriah.Waterland@Sun.COM 	char		*zoneName;
3801*9781SMoriah.Waterland@Sun.COM 	boolean_t	b;
3802*9781SMoriah.Waterland@Sun.COM 	char		**inheritedPkgDirs;
3803*9781SMoriah.Waterland@Sun.COM 	zone_state_t	zst;
3804*9781SMoriah.Waterland@Sun.COM 
3805*9781SMoriah.Waterland@Sun.COM 	/* entry assertions */
3806*9781SMoriah.Waterland@Sun.COM 
3807*9781SMoriah.Waterland@Sun.COM 	assert(a_zlst != (zoneList_t)NULL);
3808*9781SMoriah.Waterland@Sun.COM 
3809*9781SMoriah.Waterland@Sun.COM 	/* entry debugging info */
3810*9781SMoriah.Waterland@Sun.COM 
3811*9781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_BOOTCHECKINSTALLINZONES_ENTRY);
3812*9781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_BOOTCHECKINSTALLINZONES_ARGS, PSTR(a_idsName),
3813*9781SMoriah.Waterland@Sun.COM 			PSTR(a_zoneAdminFile), PSTR(a_zoneTempDir));
3814*9781SMoriah.Waterland@Sun.COM 
3815*9781SMoriah.Waterland@Sun.COM 	/* process each zone in the list */
3816*9781SMoriah.Waterland@Sun.COM 
3817*9781SMoriah.Waterland@Sun.COM 	for (zoneIndex = 0;
3818*9781SMoriah.Waterland@Sun.COM 		(zoneName = z_zlist_get_zonename(a_zlst, zoneIndex)) != NULL;
3819*9781SMoriah.Waterland@Sun.COM 		zoneIndex++) {
3820*9781SMoriah.Waterland@Sun.COM 
3821*9781SMoriah.Waterland@Sun.COM 		/* skip the zone if it IS running */
3822*9781SMoriah.Waterland@Sun.COM 
3823*9781SMoriah.Waterland@Sun.COM 		zst = z_zlist_get_current_state(a_zlst, zoneIndex);
3824*9781SMoriah.Waterland@Sun.COM 		if (zst == ZONE_STATE_RUNNING || zst == ZONE_STATE_MOUNTED) {
3825*9781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_SKIPPING_ZONE_BOOT, zoneName);
3826*9781SMoriah.Waterland@Sun.COM 			continue;
3827*9781SMoriah.Waterland@Sun.COM 		}
3828*9781SMoriah.Waterland@Sun.COM 
3829*9781SMoriah.Waterland@Sun.COM 		/* skip the zone if it is NOT bootable */
3830*9781SMoriah.Waterland@Sun.COM 
3831*9781SMoriah.Waterland@Sun.COM 		if (z_zlist_is_zone_runnable(a_zlst, zoneIndex) == B_FALSE) {
3832*9781SMoriah.Waterland@Sun.COM 			echo(MSG_SKIPPING_ZONE_NOT_RUNNABLE, zoneName);
3833*9781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_SKIPPING_ZONE_NOT_RUNNABLE, zoneName);
3834*9781SMoriah.Waterland@Sun.COM 			continue;
3835*9781SMoriah.Waterland@Sun.COM 		}
3836*9781SMoriah.Waterland@Sun.COM 
3837*9781SMoriah.Waterland@Sun.COM 		/* mount up the zone */
3838*9781SMoriah.Waterland@Sun.COM 
3839*9781SMoriah.Waterland@Sun.COM 		echo(MSG_BOOTING_ZONE, zoneName);
3840*9781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_BOOTING_ZONE, zoneName);
3841*9781SMoriah.Waterland@Sun.COM 
3842*9781SMoriah.Waterland@Sun.COM 		b = z_zlist_change_zone_state(a_zlst, zoneIndex,
3843*9781SMoriah.Waterland@Sun.COM 		    ZONE_STATE_MOUNTED);
3844*9781SMoriah.Waterland@Sun.COM 		if (b == B_FALSE) {
3845*9781SMoriah.Waterland@Sun.COM 			progerr(ERR_CANNOT_BOOT_ZONE, zoneName);
3846*9781SMoriah.Waterland@Sun.COM 			/* set fatal error return condition */
3847*9781SMoriah.Waterland@Sun.COM 			ckreturn(1);
3848*9781SMoriah.Waterland@Sun.COM 			zonesSkipped++;
3849*9781SMoriah.Waterland@Sun.COM 			continue;
3850*9781SMoriah.Waterland@Sun.COM 		}
3851*9781SMoriah.Waterland@Sun.COM 
3852*9781SMoriah.Waterland@Sun.COM 		/* determine list of directories inherited from global zone */
3853*9781SMoriah.Waterland@Sun.COM 
3854*9781SMoriah.Waterland@Sun.COM 		inheritedPkgDirs = z_zlist_get_inherited_pkg_dirs(a_zlst,
3855*9781SMoriah.Waterland@Sun.COM 					zoneIndex);
3856*9781SMoriah.Waterland@Sun.COM 
3857*9781SMoriah.Waterland@Sun.COM 		/* pre-installation check of the package in this zone */
3858*9781SMoriah.Waterland@Sun.COM 
3859*9781SMoriah.Waterland@Sun.COM 		pkginstall_check_in_one_zone(inheritedPkgDirs, zoneName,
3860*9781SMoriah.Waterland@Sun.COM 		    a_idsName, a_zoneAdminFile, a_zoneTempDir, a_altBinDir,
3861*9781SMoriah.Waterland@Sun.COM 		    z_zlist_get_scratch(a_zlst, zoneIndex),
3862*9781SMoriah.Waterland@Sun.COM 		    ZONE_STATE_MOUNTED);
3863*9781SMoriah.Waterland@Sun.COM 
3864*9781SMoriah.Waterland@Sun.COM 		/* restore original state of zone */
3865*9781SMoriah.Waterland@Sun.COM 
3866*9781SMoriah.Waterland@Sun.COM 		echo(MSG_RESTORE_ZONE_STATE, zoneName);
3867*9781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_RESTORE_ZONE_STATE, zoneName);
3868*9781SMoriah.Waterland@Sun.COM 
3869*9781SMoriah.Waterland@Sun.COM 		b = z_zlist_restore_zone_state(a_zlst, zoneIndex);
3870*9781SMoriah.Waterland@Sun.COM 	}
3871*9781SMoriah.Waterland@Sun.COM 
3872*9781SMoriah.Waterland@Sun.COM 	return (zonesSkipped);
3873*9781SMoriah.Waterland@Sun.COM }
3874*9781SMoriah.Waterland@Sun.COM 
3875*9781SMoriah.Waterland@Sun.COM /*
3876*9781SMoriah.Waterland@Sun.COM  * Function:	add_packages_in_global_with_zones
3877*9781SMoriah.Waterland@Sun.COM  * Description: call this function to add a list of packages in the global zone
3878*9781SMoriah.Waterland@Sun.COM  *		when one or more non-global zones exist
3879*9781SMoriah.Waterland@Sun.COM  * returns:
3880*9781SMoriah.Waterland@Sun.COM  *	B_TRUE to process next data stream
3881*9781SMoriah.Waterland@Sun.COM  *	B_FALSE to exit
3882*9781SMoriah.Waterland@Sun.COM  */
3883*9781SMoriah.Waterland@Sun.COM 
3884*9781SMoriah.Waterland@Sun.COM static boolean_t
3885*9781SMoriah.Waterland@Sun.COM add_packages_in_global_with_zones(char **a_pkgList, char *a_uri,
3886*9781SMoriah.Waterland@Sun.COM 	char *a_idsName, int a_repeat, char *a_altBinDir,
3887*9781SMoriah.Waterland@Sun.COM 	char *a_device, zoneList_t a_zlst)
3888*9781SMoriah.Waterland@Sun.COM {
3889*9781SMoriah.Waterland@Sun.COM static	char		*zoneTempDir = (char *)NULL;
3890*9781SMoriah.Waterland@Sun.COM static	char		*zoneAdminFile = (char *)NULL;
3891*9781SMoriah.Waterland@Sun.COM 
3892*9781SMoriah.Waterland@Sun.COM 	boolean_t	b;
3893*9781SMoriah.Waterland@Sun.COM 	char		*packageDir;
3894*9781SMoriah.Waterland@Sun.COM 	char		instdir[PATH_MAX];
3895*9781SMoriah.Waterland@Sun.COM 	char		respfile_path[PATH_MAX];
3896*9781SMoriah.Waterland@Sun.COM 	char		zoneStreamName[PATH_MAX] = {'\0'};
3897*9781SMoriah.Waterland@Sun.COM 	int		i;
3898*9781SMoriah.Waterland@Sun.COM 	int		n;
3899*9781SMoriah.Waterland@Sun.COM 	int		savenpkgs = npkgs;
3900*9781SMoriah.Waterland@Sun.COM 	int		zonesSkipped;
3901*9781SMoriah.Waterland@Sun.COM 	boolean_t	globalPresent;
3902*9781SMoriah.Waterland@Sun.COM 
3903*9781SMoriah.Waterland@Sun.COM 	/* entry assertions */
3904*9781SMoriah.Waterland@Sun.COM 
3905*9781SMoriah.Waterland@Sun.COM 	assert(a_pkgList != (char **)NULL);
3906*9781SMoriah.Waterland@Sun.COM 	assert(a_zlst != (zoneList_t)NULL);
3907*9781SMoriah.Waterland@Sun.COM 
3908*9781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_ADDPACKAGES_GZ_W_LZ_ENTRY);
3909*9781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_ADDPACKAGES_GZ_W_LZ_ARGS, npkgs, PSTR(a_uri),
3910*9781SMoriah.Waterland@Sun.COM 			PSTR(a_idsName), a_repeat, PSTR(a_device));
3911*9781SMoriah.Waterland@Sun.COM 
3912*9781SMoriah.Waterland@Sun.COM 	/* create temporary directory for use by zone operations */
3913*9781SMoriah.Waterland@Sun.COM 
3914*9781SMoriah.Waterland@Sun.COM 	create_zone_tempdir(&zoneTempDir, tmpdir);
3915*9781SMoriah.Waterland@Sun.COM 
3916*9781SMoriah.Waterland@Sun.COM 	/* create hands off settings admin file for use in a non-global zone */
3917*9781SMoriah.Waterland@Sun.COM 
3918*9781SMoriah.Waterland@Sun.COM 	create_zone_adminfile(&zoneAdminFile, zoneTempDir, admnfile);
3919*9781SMoriah.Waterland@Sun.COM 
3920*9781SMoriah.Waterland@Sun.COM 	/* determine directory where packages can be found */
3921*9781SMoriah.Waterland@Sun.COM 
3922*9781SMoriah.Waterland@Sun.COM 	if (a_idsName == (char *)NULL) {
3923*9781SMoriah.Waterland@Sun.COM 		/* no stream - directory containing packages provided */
3924*9781SMoriah.Waterland@Sun.COM 		packageDir = pkgdev.dirname;
3925*9781SMoriah.Waterland@Sun.COM 	} else {
3926*9781SMoriah.Waterland@Sun.COM 		packageDir = zoneTempDir;
3927*9781SMoriah.Waterland@Sun.COM 	}
3928*9781SMoriah.Waterland@Sun.COM 
3929*9781SMoriah.Waterland@Sun.COM 	/* unpack and check all packages */
3930*9781SMoriah.Waterland@Sun.COM 
3931*9781SMoriah.Waterland@Sun.COM 	b = unpack_and_check_packages(a_pkgList, a_idsName, packageDir);
3932*9781SMoriah.Waterland@Sun.COM 	if (b != B_TRUE) {
3933*9781SMoriah.Waterland@Sun.COM 		quit(1);
3934*9781SMoriah.Waterland@Sun.COM 	}
3935*9781SMoriah.Waterland@Sun.COM 
3936*9781SMoriah.Waterland@Sun.COM 	/*
3937*9781SMoriah.Waterland@Sun.COM 	 * if the packages are contained in a directory, convert the
3938*9781SMoriah.Waterland@Sun.COM 	 * packages into individual streams because pkgZoneInstall is only able
3939*9781SMoriah.Waterland@Sun.COM 	 * to pass a stream to the non-global zone's pkginstall command.
3940*9781SMoriah.Waterland@Sun.COM 	 * After this code is executed:
3941*9781SMoriah.Waterland@Sun.COM 	 * if the original input was a datastream:
3942*9781SMoriah.Waterland@Sun.COM 	 * -> that datastream has been unpacked into "instdir"
3943*9781SMoriah.Waterland@Sun.COM 	 * if the original input was a directory with packages in it:
3944*9781SMoriah.Waterland@Sun.COM 	 * -> those packages have been placed into a single datastream
3945*9781SMoriah.Waterland@Sun.COM 	 */
3946*9781SMoriah.Waterland@Sun.COM 
3947*9781SMoriah.Waterland@Sun.COM 	if (a_idsName == (char *)NULL) {
3948*9781SMoriah.Waterland@Sun.COM 		for (i = 0; (pkginst = a_pkgList[i]) != NULL; i++) {
3949*9781SMoriah.Waterland@Sun.COM 			char	*pkgs[2];
3950*9781SMoriah.Waterland@Sun.COM 
3951*9781SMoriah.Waterland@Sun.COM 			/* package is not a stream - create one */
3952*9781SMoriah.Waterland@Sun.COM 
3953*9781SMoriah.Waterland@Sun.COM 			(void) snprintf(zoneStreamName, sizeof (zoneStreamName),
3954*9781SMoriah.Waterland@Sun.COM 				"%s/%s.dstream", zoneTempDir, pkginst);
3955*9781SMoriah.Waterland@Sun.COM 
3956*9781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_CONVERTING_PKG, packageDir, pkginst,
3957*9781SMoriah.Waterland@Sun.COM 				zoneStreamName);
3958*9781SMoriah.Waterland@Sun.COM 
3959*9781SMoriah.Waterland@Sun.COM 			/* set up list of packages to be this package only */
3960*9781SMoriah.Waterland@Sun.COM 
3961*9781SMoriah.Waterland@Sun.COM 			pkgs[0] = pkginst;
3962*9781SMoriah.Waterland@Sun.COM 			pkgs[1] = (char *)NULL;
3963*9781SMoriah.Waterland@Sun.COM 
3964*9781SMoriah.Waterland@Sun.COM 			n = pkgtrans(packageDir, zoneStreamName, pkgs,
3965*9781SMoriah.Waterland@Sun.COM 					PT_SILENT|PT_ODTSTREAM, NULL, NULL);
3966*9781SMoriah.Waterland@Sun.COM 			if (n != 0) {
3967*9781SMoriah.Waterland@Sun.COM 				progerr(ERR_CANNOT_CONVERT_PKGSTRM,
3968*9781SMoriah.Waterland@Sun.COM 					pkginst, packageDir, zoneStreamName);
3969*9781SMoriah.Waterland@Sun.COM 				quit(1);
3970*9781SMoriah.Waterland@Sun.COM 			}
3971*9781SMoriah.Waterland@Sun.COM 			npkgs--;
3972*9781SMoriah.Waterland@Sun.COM 		}
3973*9781SMoriah.Waterland@Sun.COM 		npkgs = savenpkgs;
3974*9781SMoriah.Waterland@Sun.COM 	}
3975*9781SMoriah.Waterland@Sun.COM 
3976*9781SMoriah.Waterland@Sun.COM 	/*
3977*9781SMoriah.Waterland@Sun.COM 	 * Phase I - run collect dependency information for all packages for all
3978*9781SMoriah.Waterland@Sun.COM 	 * zones - this involves running pkginstall with the "preinstallcheck"
3979*9781SMoriah.Waterland@Sun.COM 	 * option which causes all dependency checks to be performed without
3980*9781SMoriah.Waterland@Sun.COM 	 * actually doing the installation of the packages. This information is
3981*9781SMoriah.Waterland@Sun.COM 	 * gathered in the zone temporary directory and is used later to present
3982*9781SMoriah.Waterland@Sun.COM 	 * the dependency check results to the system administrator depending
3983*9781SMoriah.Waterland@Sun.COM 	 * on the administration settings.
3984*9781SMoriah.Waterland@Sun.COM 	 */
3985*9781SMoriah.Waterland@Sun.COM 
3986*9781SMoriah.Waterland@Sun.COM 	for (i = 0; (pkginst = a_pkgList[i]) != NULL; i++) {
3987*9781SMoriah.Waterland@Sun.COM 
3988*9781SMoriah.Waterland@Sun.COM 		/* reset interrupted flag before calling pkginstall */
3989*9781SMoriah.Waterland@Sun.COM 
3990*9781SMoriah.Waterland@Sun.COM 		interrupted = 0;	/* last action was NOT quit */
3991*9781SMoriah.Waterland@Sun.COM 
3992*9781SMoriah.Waterland@Sun.COM 		/*
3993*9781SMoriah.Waterland@Sun.COM 		 * if this package is marked "install in this zone only", then
3994*9781SMoriah.Waterland@Sun.COM 		 * do not check dependencies in any other zone
3995*9781SMoriah.Waterland@Sun.COM 		 */
3996*9781SMoriah.Waterland@Sun.COM 
3997*9781SMoriah.Waterland@Sun.COM 		if (pkgPackageIsThisZone(pkginst) == B_TRUE) {
3998*9781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_VERIFY_SKIP_THISZONE, pkginst);
3999*9781SMoriah.Waterland@Sun.COM 			npkgs--;
4000*9781SMoriah.Waterland@Sun.COM 			continue;
4001*9781SMoriah.Waterland@Sun.COM 		}
4002*9781SMoriah.Waterland@Sun.COM 
4003*9781SMoriah.Waterland@Sun.COM 		/*
4004*9781SMoriah.Waterland@Sun.COM 		 * if operation failed in global zone do not propagate
4005*9781SMoriah.Waterland@Sun.COM 		 * to any non-global zones
4006*9781SMoriah.Waterland@Sun.COM 		 */
4007*9781SMoriah.Waterland@Sun.COM 
4008*9781SMoriah.Waterland@Sun.COM 		if (interrupted != 0) {
4009*9781SMoriah.Waterland@Sun.COM 			echo(MSG_CHECKINSTALL_INTERRUPT_B4_Z, pkginst);
4010*9781SMoriah.Waterland@Sun.COM 			echoDebug(MSG_CHECKINSTALL_INTERRUPT_B4_Z, pkginst);
4011*9781SMoriah.Waterland@Sun.COM 			break;
4012*9781SMoriah.Waterland@Sun.COM 		}
4013*9781SMoriah.Waterland@Sun.COM 
4014*9781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_INSTALL_FLAG_VALUES, "after pkginstall",
4015*9781SMoriah.Waterland@Sun.COM 			admnflag, doreboot, failflag, interrupted, intrflag,
4016*9781SMoriah.Waterland@Sun.COM 			ireboot, needconsult, nullflag, warnflag);
4017*9781SMoriah.Waterland@Sun.COM 
4018*9781SMoriah.Waterland@Sun.COM 		/*
4019*9781SMoriah.Waterland@Sun.COM 		 * call pkginstall to verify this package for all non-global
4020*9781SMoriah.Waterland@Sun.COM 		 * zones that are currently booted
4021*9781SMoriah.Waterland@Sun.COM 		 */
4022*9781SMoriah.Waterland@Sun.COM 
4023*9781SMoriah.Waterland@Sun.COM 		zonesSkipped = pkginstall_check_in_zones(a_zlst, a_idsName,
4024*9781SMoriah.Waterland@Sun.COM 				a_altBinDir, admnfile, zoneTempDir);
4025*9781SMoriah.Waterland@Sun.COM 
4026*9781SMoriah.Waterland@Sun.COM 		/*
4027*9781SMoriah.Waterland@Sun.COM 		 * if any zones were skipped (becuase they are not currently
4028*9781SMoriah.Waterland@Sun.COM 		 * booted), boot each zone one at a time and call pkginstall
4029*9781SMoriah.Waterland@Sun.COM 		 * to verify this package for each such non-global zone
4030*9781SMoriah.Waterland@Sun.COM 		 */
4031*9781SMoriah.Waterland@Sun.COM 
4032*9781SMoriah.Waterland@Sun.COM 		if (zonesSkipped > 0) {
4033*9781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_ZONES_SKIPPED, zonesSkipped);
4034*9781SMoriah.Waterland@Sun.COM 
4035*9781SMoriah.Waterland@Sun.COM 			zonesSkipped =
4036*9781SMoriah.Waterland@Sun.COM 				boot_and_pkginstall_check_in_zones(a_zlst,
4037*9781SMoriah.Waterland@Sun.COM 				a_idsName, a_altBinDir, admnfile,
4038*9781SMoriah.Waterland@Sun.COM 				zoneTempDir);
4039*9781SMoriah.Waterland@Sun.COM 
4040*9781SMoriah.Waterland@Sun.COM 			if (zonesSkipped > 0) {
4041*9781SMoriah.Waterland@Sun.COM 				progerr(ERR_INSTALL_ZONES_SKIPPED,
4042*9781SMoriah.Waterland@Sun.COM 							zonesSkipped);
4043*9781SMoriah.Waterland@Sun.COM 			}
4044*9781SMoriah.Waterland@Sun.COM 		}
4045*9781SMoriah.Waterland@Sun.COM 
4046*9781SMoriah.Waterland@Sun.COM 		npkgs--;
4047*9781SMoriah.Waterland@Sun.COM 	}
4048*9781SMoriah.Waterland@Sun.COM 
4049*9781SMoriah.Waterland@Sun.COM 	/*
4050*9781SMoriah.Waterland@Sun.COM 	 * At this point, all of the dependency information has been gathered
4051*9781SMoriah.Waterland@Sun.COM 	 * and is ready to be analyzed. This function processes all of that
4052*9781SMoriah.Waterland@Sun.COM 	 * dependency information and presents the results to the system
4053*9781SMoriah.Waterland@Sun.COM 	 * administrator, depending on the current administration settings.
4054*9781SMoriah.Waterland@Sun.COM 	 */
4055*9781SMoriah.Waterland@Sun.COM 
4056*9781SMoriah.Waterland@Sun.COM 	i = preinstall_verify(a_pkgList, a_zlst, zoneTempDir);
4057*9781SMoriah.Waterland@Sun.COM 	if (i != 0) {
4058*9781SMoriah.Waterland@Sun.COM 		/* dependency checks failed - exit */
4059*9781SMoriah.Waterland@Sun.COM 		quit(i);
4060*9781SMoriah.Waterland@Sun.COM 	}
4061*9781SMoriah.Waterland@Sun.COM 
4062*9781SMoriah.Waterland@Sun.COM 	npkgs = savenpkgs;
4063*9781SMoriah.Waterland@Sun.COM 
4064*9781SMoriah.Waterland@Sun.COM 	/*
4065*9781SMoriah.Waterland@Sun.COM 	 * reset all error return condition variables that may have been
4066*9781SMoriah.Waterland@Sun.COM 	 * set during package installation dependency checking so that they
4067*9781SMoriah.Waterland@Sun.COM 	 * do not reflect on the success/failure of the actual package
4068*9781SMoriah.Waterland@Sun.COM 	 * installation operations
4069*9781SMoriah.Waterland@Sun.COM 	 */
4070*9781SMoriah.Waterland@Sun.COM 
4071*9781SMoriah.Waterland@Sun.COM 	resetreturn();
4072*9781SMoriah.Waterland@Sun.COM 
4073*9781SMoriah.Waterland@Sun.COM 	/*
4074*9781SMoriah.Waterland@Sun.COM 	 * At this point, all of the dependency checking is completed, and
4075*9781SMoriah.Waterland@Sun.COM 	 * the installation of the packages can proceed. Install each package
4076*9781SMoriah.Waterland@Sun.COM 	 * one at a time, starting with the global zone, and the for each
4077*9781SMoriah.Waterland@Sun.COM 	 * non-global zone that is booted, and then for each non-global zone
4078*9781SMoriah.Waterland@Sun.COM 	 * that is not currently booted.
4079*9781SMoriah.Waterland@Sun.COM 	 */
4080*9781SMoriah.Waterland@Sun.COM 
4081*9781SMoriah.Waterland@Sun.COM 	globalPresent = z_on_zone_spec(GLOBAL_ZONENAME);
4082*9781SMoriah.Waterland@Sun.COM 
4083*9781SMoriah.Waterland@Sun.COM 	for (i = 0; (pkginst = a_pkgList[i]) != NULL; i++) {
4084*9781SMoriah.Waterland@Sun.COM 		/*
4085*9781SMoriah.Waterland@Sun.COM 		 * if immediate reboot required from last package and this is
4086*9781SMoriah.Waterland@Sun.COM 		 * not 'pkgask' then suspend installation of remaining packages
4087*9781SMoriah.Waterland@Sun.COM 		 */
4088*9781SMoriah.Waterland@Sun.COM 
4089*9781SMoriah.Waterland@Sun.COM 		if ((ireboot != 0) && (askflag == 0)) {
4090*9781SMoriah.Waterland@Sun.COM 			ptext(stderr, MSG_SUSPEND_ADD, pkginst);
4091*9781SMoriah.Waterland@Sun.COM 				continue;
4092*9781SMoriah.Waterland@Sun.COM 		}
4093*9781SMoriah.Waterland@Sun.COM 
4094*9781SMoriah.Waterland@Sun.COM 		/*
4095*9781SMoriah.Waterland@Sun.COM 		 * handle interrupt if the previous pkginstall was interrupted
4096*9781SMoriah.Waterland@Sun.COM 		 */
4097*9781SMoriah.Waterland@Sun.COM 
4098*9781SMoriah.Waterland@Sun.COM 		if (continue_installation() == B_FALSE) {
4099*9781SMoriah.Waterland@Sun.COM 			return (B_FALSE);
4100*9781SMoriah.Waterland@Sun.COM 		}
4101*9781SMoriah.Waterland@Sun.COM 
4102*9781SMoriah.Waterland@Sun.COM 		/*
4103*9781SMoriah.Waterland@Sun.COM 		 * if pkgask, handle response file creation:
4104*9781SMoriah.Waterland@Sun.COM 		 * - if the response file is a directory, then create a path to
4105*9781SMoriah.Waterland@Sun.COM 		 * -- a package instance within the response file directory.
4106*9781SMoriah.Waterland@Sun.COM 		 * - If the response file is NOT a directory, if more than one
4107*9781SMoriah.Waterland@Sun.COM 		 * -- package is to be installed.
4108*9781SMoriah.Waterland@Sun.COM 		 */
4109*9781SMoriah.Waterland@Sun.COM 
4110*9781SMoriah.Waterland@Sun.COM 		if ((askflag != 0) && (respdir != (char *)NULL)) {
4111*9781SMoriah.Waterland@Sun.COM 			(void) snprintf(respfile_path, sizeof (respfile_path),
4112*9781SMoriah.Waterland@Sun.COM 					"%s/%s", respdir, pkginst);
4113*9781SMoriah.Waterland@Sun.COM 			respfile = respfile_path;
4114*9781SMoriah.Waterland@Sun.COM 		}
4115*9781SMoriah.Waterland@Sun.COM 
4116*9781SMoriah.Waterland@Sun.COM 		echo(MSG_PROC_INST, pkginst,
4117*9781SMoriah.Waterland@Sun.COM 			(a_uri && a_idsName) ? a_uri : a_device);
4118*9781SMoriah.Waterland@Sun.COM 
4119*9781SMoriah.Waterland@Sun.COM 		/*
4120*9781SMoriah.Waterland@Sun.COM 		 * If we're installing another package in the same
4121*9781SMoriah.Waterland@Sun.COM 		 * session, the second through nth pkginstall, must
4122*9781SMoriah.Waterland@Sun.COM 		 * continue from where the prior one left off. For this
4123*9781SMoriah.Waterland@Sun.COM 		 * reason, the continuation feature (implied by the
4124*9781SMoriah.Waterland@Sun.COM 		 * nature of the command) is used for the remaining
4125*9781SMoriah.Waterland@Sun.COM 		 * packages.
4126*9781SMoriah.Waterland@Sun.COM 		 */
4127*9781SMoriah.Waterland@Sun.COM 
4128*9781SMoriah.Waterland@Sun.COM 		if ((i == 1) && (pkgdrtarg != (char *)NULL)) {
4129*9781SMoriah.Waterland@Sun.COM 			pkgcontsrc = pkgdrtarg;
4130*9781SMoriah.Waterland@Sun.COM 		}
4131*9781SMoriah.Waterland@Sun.COM 
4132*9781SMoriah.Waterland@Sun.COM 		if (globalPresent) {
4133*9781SMoriah.Waterland@Sun.COM 			/*
4134*9781SMoriah.Waterland@Sun.COM 			 * call pkginstall for this package for the global zone
4135*9781SMoriah.Waterland@Sun.COM 			 */
4136*9781SMoriah.Waterland@Sun.COM 
4137*9781SMoriah.Waterland@Sun.COM 			echo(MSG_INSTALLING_PKG_IN_GZ, pkginst);
4138*9781SMoriah.Waterland@Sun.COM 
4139*9781SMoriah.Waterland@Sun.COM 			/* reset interrupted flag before calling pkginstall */
4140*9781SMoriah.Waterland@Sun.COM 
4141*9781SMoriah.Waterland@Sun.COM 			interrupted = 0;	/* last action was NOT quit */
4142*9781SMoriah.Waterland@Sun.COM 
4143*9781SMoriah.Waterland@Sun.COM 			n = pkgInstall(get_inst_root(), NULL, packageDir,
4144*9781SMoriah.Waterland@Sun.COM 			    a_altBinDir,  NULL);
4145*9781SMoriah.Waterland@Sun.COM 
4146*9781SMoriah.Waterland@Sun.COM 			/* set success/fail condition variables */
4147*9781SMoriah.Waterland@Sun.COM 
4148*9781SMoriah.Waterland@Sun.COM 			ckreturn(n);
4149*9781SMoriah.Waterland@Sun.COM 
4150*9781SMoriah.Waterland@Sun.COM 			/*
4151*9781SMoriah.Waterland@Sun.COM 			 * if operation failed in global zone do not propagate
4152*9781SMoriah.Waterland@Sun.COM 			 * to any non-global zones
4153*9781SMoriah.Waterland@Sun.COM 			 */
4154*9781SMoriah.Waterland@Sun.COM 
4155*9781SMoriah.Waterland@Sun.COM 			if (interrupted != 0) {
4156*9781SMoriah.Waterland@Sun.COM 				echo(MSG_INSTALL_INTERRUPT_B4_ZONES, pkginst);
4157*9781SMoriah.Waterland@Sun.COM 				echoDebug(MSG_INSTALL_INTERRUPT_B4_ZONES,
4158*9781SMoriah.Waterland@Sun.COM 				    pkginst);
4159*9781SMoriah.Waterland@Sun.COM 				break;
4160*9781SMoriah.Waterland@Sun.COM 			}
4161*9781SMoriah.Waterland@Sun.COM 		}
4162*9781SMoriah.Waterland@Sun.COM 
4163*9781SMoriah.Waterland@Sun.COM 		/*
4164*9781SMoriah.Waterland@Sun.COM 		 * if this package is marked "install in this zone only",
4165*9781SMoriah.Waterland@Sun.COM 		 * then only need to install the package in the global zone;
4166*9781SMoriah.Waterland@Sun.COM 		 * skip installation in any non-global zones.
4167*9781SMoriah.Waterland@Sun.COM 		 */
4168*9781SMoriah.Waterland@Sun.COM 
4169*9781SMoriah.Waterland@Sun.COM 		if (pkgPackageIsThisZone(pkginst) == B_TRUE) {
4170*9781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_INSTALL_SKIP_THISZONE, pkginst);
4171*9781SMoriah.Waterland@Sun.COM 			npkgs--;
4172*9781SMoriah.Waterland@Sun.COM 			continue;
4173*9781SMoriah.Waterland@Sun.COM 		}
4174*9781SMoriah.Waterland@Sun.COM 
4175*9781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_INSTALL_FLAG_VALUES, "install in running zones",
4176*9781SMoriah.Waterland@Sun.COM 			admnflag, doreboot, failflag, interrupted, intrflag,
4177*9781SMoriah.Waterland@Sun.COM 			ireboot, needconsult, nullflag, warnflag);
4178*9781SMoriah.Waterland@Sun.COM 
4179*9781SMoriah.Waterland@Sun.COM 		/* install package in currently booted zones */
4180*9781SMoriah.Waterland@Sun.COM 
4181*9781SMoriah.Waterland@Sun.COM 		zonesSkipped = install_in_zones(a_zlst, a_idsName, a_altBinDir,
4182*9781SMoriah.Waterland@Sun.COM 					zoneAdminFile, zoneTempDir);
4183*9781SMoriah.Waterland@Sun.COM 
4184*9781SMoriah.Waterland@Sun.COM 		/* install package in zones that are not currently booted */
4185*9781SMoriah.Waterland@Sun.COM 
4186*9781SMoriah.Waterland@Sun.COM 		if (zonesSkipped > 0) {
4187*9781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_ZONES_SKIPPED, zonesSkipped);
4188*9781SMoriah.Waterland@Sun.COM 
4189*9781SMoriah.Waterland@Sun.COM 			zonesSkipped = boot_and_install_in_zones(a_zlst,
4190*9781SMoriah.Waterland@Sun.COM 				a_idsName, a_altBinDir, zoneAdminFile,
4191*9781SMoriah.Waterland@Sun.COM 				zoneTempDir);
4192*9781SMoriah.Waterland@Sun.COM 
4193*9781SMoriah.Waterland@Sun.COM 			if (zonesSkipped > 0) {
4194*9781SMoriah.Waterland@Sun.COM 				progerr(ERR_INSTALL_ZONES_SKIPPED,
4195*9781SMoriah.Waterland@Sun.COM 							zonesSkipped);
4196*9781SMoriah.Waterland@Sun.COM 			}
4197*9781SMoriah.Waterland@Sun.COM 		}
4198*9781SMoriah.Waterland@Sun.COM 
4199*9781SMoriah.Waterland@Sun.COM 		/*
4200*9781SMoriah.Waterland@Sun.COM 		 * package completely installed - remove any temporary stream
4201*9781SMoriah.Waterland@Sun.COM 		 * of the package that might have been created
4202*9781SMoriah.Waterland@Sun.COM 		 */
4203*9781SMoriah.Waterland@Sun.COM 
4204*9781SMoriah.Waterland@Sun.COM 		if (a_idsName == (char *)NULL) {
4205*9781SMoriah.Waterland@Sun.COM 			/* locate temporary stream created earlier */
4206*9781SMoriah.Waterland@Sun.COM 			(void) snprintf(zoneStreamName, sizeof (zoneStreamName),
4207*9781SMoriah.Waterland@Sun.COM 				"%s/%s.dstream", zoneTempDir, pkginst);
4208*9781SMoriah.Waterland@Sun.COM 			/* remove stream - no longer needed */
4209*9781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_REMOVING_DSTREAM_PKGDIR, zoneStreamName,
4210*9781SMoriah.Waterland@Sun.COM 					pkginst);
4211*9781SMoriah.Waterland@Sun.COM 			(void) remove(zoneStreamName);
4212*9781SMoriah.Waterland@Sun.COM 		} else {
4213*9781SMoriah.Waterland@Sun.COM 			/* remove package - no longer needed */
4214*9781SMoriah.Waterland@Sun.COM 			if (snprintf(instdir, sizeof (instdir), "%s/%s",
4215*9781SMoriah.Waterland@Sun.COM 					zoneTempDir, pkginst) >= PATH_MAX) {
4216*9781SMoriah.Waterland@Sun.COM 				progerr(ERR_CANNOT_CREATE_PKGPATH, tmpdir);
4217*9781SMoriah.Waterland@Sun.COM 				quit(1);
4218*9781SMoriah.Waterland@Sun.COM 			}
4219*9781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_REMOVING_PKG_TMPDIR, instdir, pkginst);
4220*9781SMoriah.Waterland@Sun.COM 			(void) remove(instdir);
4221*9781SMoriah.Waterland@Sun.COM 		}
4222*9781SMoriah.Waterland@Sun.COM 
4223*9781SMoriah.Waterland@Sun.COM 		/* decrement number of packages left to install */
4224*9781SMoriah.Waterland@Sun.COM 
4225*9781SMoriah.Waterland@Sun.COM 		npkgs--;
4226*9781SMoriah.Waterland@Sun.COM 
4227*9781SMoriah.Waterland@Sun.COM 		/*
4228*9781SMoriah.Waterland@Sun.COM 		 * if no packages left to install, unmount package source
4229*9781SMoriah.Waterland@Sun.COM 		 * device if appropriate
4230*9781SMoriah.Waterland@Sun.COM 		 */
4231*9781SMoriah.Waterland@Sun.COM 
4232*9781SMoriah.Waterland@Sun.COM 		if ((npkgs <= 0) && (pkgdev.mount || a_idsName)) {
4233*9781SMoriah.Waterland@Sun.COM 			(void) chdir("/");
4234*9781SMoriah.Waterland@Sun.COM 			if (!a_idsName) {
4235*9781SMoriah.Waterland@Sun.COM 				echoDebug(DBG_UNMOUNTING_DEV,
4236*9781SMoriah.Waterland@Sun.COM 							PSTR(pkgdev.mount));
4237*9781SMoriah.Waterland@Sun.COM 				(void) pkgumount(&pkgdev);
4238*9781SMoriah.Waterland@Sun.COM 			}
4239*9781SMoriah.Waterland@Sun.COM 		}
4240*9781SMoriah.Waterland@Sun.COM 	}
4241*9781SMoriah.Waterland@Sun.COM 
4242*9781SMoriah.Waterland@Sun.COM 	/*
4243*9781SMoriah.Waterland@Sun.COM 	 * all packages in the package list have been installed.
4244*9781SMoriah.Waterland@Sun.COM 	 * Continue with installation if:
4245*9781SMoriah.Waterland@Sun.COM 	 * -- immediate reboot is NOT required
4246*9781SMoriah.Waterland@Sun.COM 	 * -- there are more packages to install
4247*9781SMoriah.Waterland@Sun.COM 	 * -- the package source is a path to a file
4248*9781SMoriah.Waterland@Sun.COM 	 * else return do NOT continue.
4249*9781SMoriah.Waterland@Sun.COM 	 */
4250*9781SMoriah.Waterland@Sun.COM 
4251*9781SMoriah.Waterland@Sun.COM 	if ((ireboot == 0) && (a_repeat != 0) &&
4252*9781SMoriah.Waterland@Sun.COM 		(pkgdev.pathname == (char *)NULL)) {
4253*9781SMoriah.Waterland@Sun.COM 		return (B_TRUE);
4254*9781SMoriah.Waterland@Sun.COM 	}
4255*9781SMoriah.Waterland@Sun.COM 
4256*9781SMoriah.Waterland@Sun.COM 	/* return 'dont continue' */
4257*9781SMoriah.Waterland@Sun.COM 
4258*9781SMoriah.Waterland@Sun.COM 	return (B_FALSE);
4259*9781SMoriah.Waterland@Sun.COM }
4260*9781SMoriah.Waterland@Sun.COM 
4261*9781SMoriah.Waterland@Sun.COM /*
4262*9781SMoriah.Waterland@Sun.COM  * Function:	add_packages_in_nonglobal_zone
4263*9781SMoriah.Waterland@Sun.COM  * Description: call this function to add a list of packages in a non-global
4264*9781SMoriah.Waterland@Sun.COM  *		zone
4265*9781SMoriah.Waterland@Sun.COM  * returns:
4266*9781SMoriah.Waterland@Sun.COM  *	B_TRUE to process next data stream
4267*9781SMoriah.Waterland@Sun.COM  *	B_FALSE to exit
4268*9781SMoriah.Waterland@Sun.COM  */
4269*9781SMoriah.Waterland@Sun.COM 
4270*9781SMoriah.Waterland@Sun.COM static boolean_t
4271*9781SMoriah.Waterland@Sun.COM add_packages_in_nonglobal_zone(char **a_pkgList, char *a_uri,
4272*9781SMoriah.Waterland@Sun.COM 	char *a_idsName, int a_repeat, char *a_altBinDir, char *a_device)
4273*9781SMoriah.Waterland@Sun.COM {
4274*9781SMoriah.Waterland@Sun.COM static	char		*zoneTempDir = (char *)NULL;
4275*9781SMoriah.Waterland@Sun.COM 
4276*9781SMoriah.Waterland@Sun.COM 	char		*packageDir;
4277*9781SMoriah.Waterland@Sun.COM 	char		respfile_path[PATH_MAX];
4278*9781SMoriah.Waterland@Sun.COM 	int		i;
4279*9781SMoriah.Waterland@Sun.COM 	int		n;
4280*9781SMoriah.Waterland@Sun.COM 	boolean_t	b;
4281*9781SMoriah.Waterland@Sun.COM 	int		savenpkgs = npkgs;
4282*9781SMoriah.Waterland@Sun.COM 
4283*9781SMoriah.Waterland@Sun.COM 	/* entry assertions */
4284*9781SMoriah.Waterland@Sun.COM 
4285*9781SMoriah.Waterland@Sun.COM 	assert(a_pkgList != (char **)NULL);
4286*9781SMoriah.Waterland@Sun.COM 
4287*9781SMoriah.Waterland@Sun.COM 	/* entry debugging info */
4288*9781SMoriah.Waterland@Sun.COM 
4289*9781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_ADDPACKAGES_LZ_ENTRY);
4290*9781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_ADDPACKAGES_LZ_ARGS, npkgs, PSTR(a_uri), PSTR(a_idsName),
4291*9781SMoriah.Waterland@Sun.COM 		a_repeat, PSTR(a_device));
4292*9781SMoriah.Waterland@Sun.COM 
4293*9781SMoriah.Waterland@Sun.COM 	/* create temporary directory for use by zone operations */
4294*9781SMoriah.Waterland@Sun.COM 
4295*9781SMoriah.Waterland@Sun.COM 	create_zone_tempdir(&zoneTempDir, tmpdir);
4296*9781SMoriah.Waterland@Sun.COM 
4297*9781SMoriah.Waterland@Sun.COM 	/*
4298*9781SMoriah.Waterland@Sun.COM 	 * package can be in a number of formats:
4299*9781SMoriah.Waterland@Sun.COM 	 * - file containing package stream (pkgadd -d file [pkgs])
4300*9781SMoriah.Waterland@Sun.COM 	 * - directory containing packages (pkgadd -d /dir [pkgs])
4301*9781SMoriah.Waterland@Sun.COM 	 * - device containing packages (pkgadd -d diskette1 [pkgs])
4302*9781SMoriah.Waterland@Sun.COM 	 * non-global zones can be passed open file drescriptors and
4303*9781SMoriah.Waterland@Sun.COM 	 * strings as arguments
4304*9781SMoriah.Waterland@Sun.COM 	 * - for file containing package stream
4305*9781SMoriah.Waterland@Sun.COM 	 * -- the stream can be passed directly to the non-global zone
4306*9781SMoriah.Waterland@Sun.COM 	 * - for directory
4307*9781SMoriah.Waterland@Sun.COM 	 * -- convert packages to datastream to pass to the non-global zone
4308*9781SMoriah.Waterland@Sun.COM 	 * - for device
4309*9781SMoriah.Waterland@Sun.COM 	 */
4310*9781SMoriah.Waterland@Sun.COM 
4311*9781SMoriah.Waterland@Sun.COM 	/* determine directory where packages can be found */
4312*9781SMoriah.Waterland@Sun.COM 
4313*9781SMoriah.Waterland@Sun.COM 	if (a_idsName == (char *)NULL) {
4314*9781SMoriah.Waterland@Sun.COM 		/* no stream - directory containing packages provided */
4315*9781SMoriah.Waterland@Sun.COM 		packageDir = pkgdev.dirname;
4316*9781SMoriah.Waterland@Sun.COM 	} else {
4317*9781SMoriah.Waterland@Sun.COM 		packageDir = zoneTempDir;
4318*9781SMoriah.Waterland@Sun.COM 	}
4319*9781SMoriah.Waterland@Sun.COM 
4320*9781SMoriah.Waterland@Sun.COM 	b = unpack_and_check_packages(a_pkgList, a_idsName, packageDir);
4321*9781SMoriah.Waterland@Sun.COM 	if (b != B_TRUE) {
4322*9781SMoriah.Waterland@Sun.COM 		quit(1);
4323*9781SMoriah.Waterland@Sun.COM 	}
4324*9781SMoriah.Waterland@Sun.COM 
4325*9781SMoriah.Waterland@Sun.COM 	/*
4326*9781SMoriah.Waterland@Sun.COM 	 * this is the main loop where all of the packages (as listed in the
4327*9781SMoriah.Waterland@Sun.COM 	 * package list) are added one at a time.
4328*9781SMoriah.Waterland@Sun.COM 	 */
4329*9781SMoriah.Waterland@Sun.COM 
4330*9781SMoriah.Waterland@Sun.COM 	for (i = 0; (pkginst = a_pkgList[i]) != NULL; i++) {
4331*9781SMoriah.Waterland@Sun.COM 		npkgs--;
4332*9781SMoriah.Waterland@Sun.COM 	}
4333*9781SMoriah.Waterland@Sun.COM 
4334*9781SMoriah.Waterland@Sun.COM 	npkgs = savenpkgs;
4335*9781SMoriah.Waterland@Sun.COM 
4336*9781SMoriah.Waterland@Sun.COM 	/*
4337*9781SMoriah.Waterland@Sun.COM 	 * this is the main loop where all of the packages (as listed in the
4338*9781SMoriah.Waterland@Sun.COM 	 * package list) are added one at a time.
4339*9781SMoriah.Waterland@Sun.COM 	 */
4340*9781SMoriah.Waterland@Sun.COM 
4341*9781SMoriah.Waterland@Sun.COM 	for (i = 0; (pkginst = a_pkgList[i]) != NULL; i++) {
4342*9781SMoriah.Waterland@Sun.COM 		/*
4343*9781SMoriah.Waterland@Sun.COM 		 * if immediate reboot required from last package and this is
4344*9781SMoriah.Waterland@Sun.COM 		 * not 'pkgask' then suspend installation of remaining packages
4345*9781SMoriah.Waterland@Sun.COM 		 */
4346*9781SMoriah.Waterland@Sun.COM 
4347*9781SMoriah.Waterland@Sun.COM 		if ((ireboot != 0) && (askflag == 0)) {
4348*9781SMoriah.Waterland@Sun.COM 			ptext(stderr, MSG_SUSPEND_ADD, pkginst);
4349*9781SMoriah.Waterland@Sun.COM 				continue;
4350*9781SMoriah.Waterland@Sun.COM 		}
4351*9781SMoriah.Waterland@Sun.COM 
4352*9781SMoriah.Waterland@Sun.COM 		/*
4353*9781SMoriah.Waterland@Sun.COM 		 * handle interrupt if the previous pkginstall was interrupted
4354*9781SMoriah.Waterland@Sun.COM 		 */
4355*9781SMoriah.Waterland@Sun.COM 
4356*9781SMoriah.Waterland@Sun.COM 		if (continue_installation() == B_FALSE) {
4357*9781SMoriah.Waterland@Sun.COM 			return (B_FALSE);
4358*9781SMoriah.Waterland@Sun.COM 		}
4359*9781SMoriah.Waterland@Sun.COM 
4360*9781SMoriah.Waterland@Sun.COM 		/*
4361*9781SMoriah.Waterland@Sun.COM 		 * if pkgask, handle response file creation:
4362*9781SMoriah.Waterland@Sun.COM 		 * - if the response file is a directory, then create a path to
4363*9781SMoriah.Waterland@Sun.COM 		 * -- a package instance within the response file directory.
4364*9781SMoriah.Waterland@Sun.COM 		 * - If the response file is NOT a directory, if more than one
4365*9781SMoriah.Waterland@Sun.COM 		 * -- package is to be installed.
4366*9781SMoriah.Waterland@Sun.COM 		 */
4367*9781SMoriah.Waterland@Sun.COM 
4368*9781SMoriah.Waterland@Sun.COM 		if ((askflag != 0) && (respdir != (char *)NULL)) {
4369*9781SMoriah.Waterland@Sun.COM 			(void) snprintf(respfile_path, sizeof (respfile_path),
4370*9781SMoriah.Waterland@Sun.COM 					"%s/%s", respdir, pkginst);
4371*9781SMoriah.Waterland@Sun.COM 			respfile = respfile_path;
4372*9781SMoriah.Waterland@Sun.COM 		}
4373*9781SMoriah.Waterland@Sun.COM 
4374*9781SMoriah.Waterland@Sun.COM 		echo(MSG_PROC_INST, pkginst,
4375*9781SMoriah.Waterland@Sun.COM 			(a_uri && a_idsName) ? a_uri : a_device);
4376*9781SMoriah.Waterland@Sun.COM 
4377*9781SMoriah.Waterland@Sun.COM 		/*
4378*9781SMoriah.Waterland@Sun.COM 		 * If we're installing another package in the same
4379*9781SMoriah.Waterland@Sun.COM 		 * session, the second through nth pkginstall, must
4380*9781SMoriah.Waterland@Sun.COM 		 * continue from where the prior one left off. For this
4381*9781SMoriah.Waterland@Sun.COM 		 * reason, the continuation feature (implied by the
4382*9781SMoriah.Waterland@Sun.COM 		 * nature of the command) is used for the remaining
4383*9781SMoriah.Waterland@Sun.COM 		 * packages.
4384*9781SMoriah.Waterland@Sun.COM 		 */
4385*9781SMoriah.Waterland@Sun.COM 
4386*9781SMoriah.Waterland@Sun.COM 		if ((i == 1) && (pkgdrtarg != (char *)NULL)) {
4387*9781SMoriah.Waterland@Sun.COM 			pkgcontsrc = pkgdrtarg;
4388*9781SMoriah.Waterland@Sun.COM 		}
4389*9781SMoriah.Waterland@Sun.COM 
4390*9781SMoriah.Waterland@Sun.COM 		/* reset interrupted flag before calling pkginstall */
4391*9781SMoriah.Waterland@Sun.COM 
4392*9781SMoriah.Waterland@Sun.COM 		interrupted = 0;	/* last action was NOT quit */
4393*9781SMoriah.Waterland@Sun.COM 
4394*9781SMoriah.Waterland@Sun.COM 		/* call pkginstall for this package */
4395*9781SMoriah.Waterland@Sun.COM 
4396*9781SMoriah.Waterland@Sun.COM 		n = pkgInstall(get_inst_root(), NULL,
4397*9781SMoriah.Waterland@Sun.COM 				packageDir, a_altBinDir,
4398*9781SMoriah.Waterland@Sun.COM 				(char **)NULL);
4399*9781SMoriah.Waterland@Sun.COM 
4400*9781SMoriah.Waterland@Sun.COM 		/* set success/fail condition variables */
4401*9781SMoriah.Waterland@Sun.COM 
4402*9781SMoriah.Waterland@Sun.COM 		ckreturn(n);
4403*9781SMoriah.Waterland@Sun.COM 
4404*9781SMoriah.Waterland@Sun.COM 		/* decrement number of packages left to install */
4405*9781SMoriah.Waterland@Sun.COM 
4406*9781SMoriah.Waterland@Sun.COM 		npkgs--;
4407*9781SMoriah.Waterland@Sun.COM 
4408*9781SMoriah.Waterland@Sun.COM 		/*
4409*9781SMoriah.Waterland@Sun.COM 		 * if no packages left to install, unmount package source
4410*9781SMoriah.Waterland@Sun.COM 		 * device if appropriate
4411*9781SMoriah.Waterland@Sun.COM 		 */
4412*9781SMoriah.Waterland@Sun.COM 
4413*9781SMoriah.Waterland@Sun.COM 		if ((npkgs <= 0) && (pkgdev.mount || a_idsName)) {
4414*9781SMoriah.Waterland@Sun.COM 			(void) chdir("/");
4415*9781SMoriah.Waterland@Sun.COM 			if (!a_idsName) {
4416*9781SMoriah.Waterland@Sun.COM 				(void) pkgumount(&pkgdev);
4417*9781SMoriah.Waterland@Sun.COM 			}
4418*9781SMoriah.Waterland@Sun.COM 		}
4419*9781SMoriah.Waterland@Sun.COM 	}
4420*9781SMoriah.Waterland@Sun.COM 
4421*9781SMoriah.Waterland@Sun.COM 	/*
4422*9781SMoriah.Waterland@Sun.COM 	 * all packages in the package list have been installed.
4423*9781SMoriah.Waterland@Sun.COM 	 * Continue with installation if:
4424*9781SMoriah.Waterland@Sun.COM 	 * -- immediate reboot is NOT required
4425*9781SMoriah.Waterland@Sun.COM 	 * -- there are more packages to install
4426*9781SMoriah.Waterland@Sun.COM 	 * -- the package source is a path to a file
4427*9781SMoriah.Waterland@Sun.COM 	 * else return do NOT continue.
4428*9781SMoriah.Waterland@Sun.COM 	 */
4429*9781SMoriah.Waterland@Sun.COM 
4430*9781SMoriah.Waterland@Sun.COM 	if ((ireboot == 0) && (a_repeat != 0) &&
4431*9781SMoriah.Waterland@Sun.COM 		(pkgdev.pathname == (char *)NULL)) {
4432*9781SMoriah.Waterland@Sun.COM 		return (B_TRUE);
4433*9781SMoriah.Waterland@Sun.COM 	}
4434*9781SMoriah.Waterland@Sun.COM 
4435*9781SMoriah.Waterland@Sun.COM 	/* return 'dont continue' */
4436*9781SMoriah.Waterland@Sun.COM 
4437*9781SMoriah.Waterland@Sun.COM 	return (B_FALSE);
4438*9781SMoriah.Waterland@Sun.COM }
4439*9781SMoriah.Waterland@Sun.COM 
4440*9781SMoriah.Waterland@Sun.COM /*
4441*9781SMoriah.Waterland@Sun.COM  * Function:	add_packages_in_global_no_zones
4442*9781SMoriah.Waterland@Sun.COM  * Description: call this function to add a list of packages in the global zone
4443*9781SMoriah.Waterland@Sun.COM  *		when no non-global zones exist
4444*9781SMoriah.Waterland@Sun.COM  * returns:
4445*9781SMoriah.Waterland@Sun.COM  *	B_TRUE to process next data stream
4446*9781SMoriah.Waterland@Sun.COM  *	B_FALSE to exit
4447*9781SMoriah.Waterland@Sun.COM  */
4448*9781SMoriah.Waterland@Sun.COM 
4449*9781SMoriah.Waterland@Sun.COM static boolean_t
4450*9781SMoriah.Waterland@Sun.COM add_packages_in_global_no_zones(char **a_pkgList, char *a_uri,
4451*9781SMoriah.Waterland@Sun.COM 	char *a_idsName, int a_repeat, char *a_altBinDir, char *a_device)
4452*9781SMoriah.Waterland@Sun.COM {
4453*9781SMoriah.Waterland@Sun.COM 	int		n;
4454*9781SMoriah.Waterland@Sun.COM 	int		i;
4455*9781SMoriah.Waterland@Sun.COM 	char		respfile_path[PATH_MAX];
4456*9781SMoriah.Waterland@Sun.COM 	CAF_T		flags = 0;
4457*9781SMoriah.Waterland@Sun.COM 
4458*9781SMoriah.Waterland@Sun.COM 	/* entry assertions */
4459*9781SMoriah.Waterland@Sun.COM 
4460*9781SMoriah.Waterland@Sun.COM 	assert(a_pkgList != (char **)NULL);
4461*9781SMoriah.Waterland@Sun.COM 
4462*9781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_ADDPACKAGES_GZ_NO_LZ_ENTRY);
4463*9781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_ADDPACKAGES_GZ_NO_LZ_ARGS, npkgs, PSTR(a_uri),
4464*9781SMoriah.Waterland@Sun.COM 		PSTR(a_idsName), a_repeat, PSTR(a_device));
4465*9781SMoriah.Waterland@Sun.COM 
4466*9781SMoriah.Waterland@Sun.COM 	/*
4467*9781SMoriah.Waterland@Sun.COM 	 * set flags for applicability check
4468*9781SMoriah.Waterland@Sun.COM 	 */
4469*9781SMoriah.Waterland@Sun.COM 
4470*9781SMoriah.Waterland@Sun.COM 	/* in the global zone */
4471*9781SMoriah.Waterland@Sun.COM 
4472*9781SMoriah.Waterland@Sun.COM 	flags |= CAF_IN_GLOBAL_ZONE;
4473*9781SMoriah.Waterland@Sun.COM 
4474*9781SMoriah.Waterland@Sun.COM 	/* set -G flag */
4475*9781SMoriah.Waterland@Sun.COM 
4476*9781SMoriah.Waterland@Sun.COM 	if (globalZoneOnly == B_TRUE) {
4477*9781SMoriah.Waterland@Sun.COM 		flags |= CAF_SCOPE_GLOBAL;
4478*9781SMoriah.Waterland@Sun.COM 	}
4479*9781SMoriah.Waterland@Sun.COM 
4480*9781SMoriah.Waterland@Sun.COM 	/*
4481*9781SMoriah.Waterland@Sun.COM 	 * this is the main loop where all of the packages (as listed in the
4482*9781SMoriah.Waterland@Sun.COM 	 * package list) are added one at a time.
4483*9781SMoriah.Waterland@Sun.COM 	 */
4484*9781SMoriah.Waterland@Sun.COM 
4485*9781SMoriah.Waterland@Sun.COM 	for (i = 0; (pkginst = a_pkgList[i]) != NULL; i++) {
4486*9781SMoriah.Waterland@Sun.COM 		/*
4487*9781SMoriah.Waterland@Sun.COM 		 * if immediate reboot required from last package and this is
4488*9781SMoriah.Waterland@Sun.COM 		 * not 'pkgask' then suspend installation of remaining packages
4489*9781SMoriah.Waterland@Sun.COM 		 */
4490*9781SMoriah.Waterland@Sun.COM 
4491*9781SMoriah.Waterland@Sun.COM 		if ((ireboot != 0) && (askflag == 0)) {
4492*9781SMoriah.Waterland@Sun.COM 			ptext(stderr, MSG_SUSPEND_ADD, pkginst);
4493*9781SMoriah.Waterland@Sun.COM 				continue;
4494*9781SMoriah.Waterland@Sun.COM 		}
4495*9781SMoriah.Waterland@Sun.COM 
4496*9781SMoriah.Waterland@Sun.COM 		/*
4497*9781SMoriah.Waterland@Sun.COM 		 * handle interrupt if the previous pkginstall was interrupted
4498*9781SMoriah.Waterland@Sun.COM 		 */
4499*9781SMoriah.Waterland@Sun.COM 
4500*9781SMoriah.Waterland@Sun.COM 		if (continue_installation() == B_FALSE) {
4501*9781SMoriah.Waterland@Sun.COM 			return (B_FALSE);
4502*9781SMoriah.Waterland@Sun.COM 		}
4503*9781SMoriah.Waterland@Sun.COM 
4504*9781SMoriah.Waterland@Sun.COM 		/*
4505*9781SMoriah.Waterland@Sun.COM 		 * check package applicability to install in this context
4506*9781SMoriah.Waterland@Sun.COM 		 */
4507*9781SMoriah.Waterland@Sun.COM 
4508*9781SMoriah.Waterland@Sun.COM 		if (check_applicability(pkgdev.dirname,
4509*9781SMoriah.Waterland@Sun.COM 			pkginst, get_inst_root(), flags) == B_FALSE) {
4510*9781SMoriah.Waterland@Sun.COM 			progerr(ERR_PKG_NOT_APPLICABLE, pkginst);
4511*9781SMoriah.Waterland@Sun.COM 			quit(1);
4512*9781SMoriah.Waterland@Sun.COM 		}
4513*9781SMoriah.Waterland@Sun.COM 
4514*9781SMoriah.Waterland@Sun.COM 		/*
4515*9781SMoriah.Waterland@Sun.COM 		 * if pkgask, handle response file creation:
4516*9781SMoriah.Waterland@Sun.COM 		 * - if the response file is a directory, then create a path to
4517*9781SMoriah.Waterland@Sun.COM 		 * -- a package instance within the response file directory.
4518*9781SMoriah.Waterland@Sun.COM 		 * - If the response file is NOT a directory, if more than one
4519*9781SMoriah.Waterland@Sun.COM 		 * -- package is to be installed.
4520*9781SMoriah.Waterland@Sun.COM 		 */
4521*9781SMoriah.Waterland@Sun.COM 
4522*9781SMoriah.Waterland@Sun.COM 		if ((askflag != 0) && (respdir != (char *)NULL)) {
4523*9781SMoriah.Waterland@Sun.COM 			(void) snprintf(respfile_path, sizeof (respfile_path),
4524*9781SMoriah.Waterland@Sun.COM 					"%s/%s", respdir, pkginst);
4525*9781SMoriah.Waterland@Sun.COM 			respfile = respfile_path;
4526*9781SMoriah.Waterland@Sun.COM 		}
4527*9781SMoriah.Waterland@Sun.COM 
4528*9781SMoriah.Waterland@Sun.COM 		echo(MSG_PROC_INST, pkginst,
4529*9781SMoriah.Waterland@Sun.COM 			(a_uri && a_idsName) ? a_uri : a_device);
4530*9781SMoriah.Waterland@Sun.COM 
4531*9781SMoriah.Waterland@Sun.COM 		/*
4532*9781SMoriah.Waterland@Sun.COM 		 * If we're installing another package in the same
4533*9781SMoriah.Waterland@Sun.COM 		 * session, the second through nth pkginstall, must
4534*9781SMoriah.Waterland@Sun.COM 		 * continue from where the prior one left off. For this
4535*9781SMoriah.Waterland@Sun.COM 		 * reason, the continuation feature (implied by the
4536*9781SMoriah.Waterland@Sun.COM 		 * nature of the command) is used for the remaining
4537*9781SMoriah.Waterland@Sun.COM 		 * packages.
4538*9781SMoriah.Waterland@Sun.COM 		 */
4539*9781SMoriah.Waterland@Sun.COM 
4540*9781SMoriah.Waterland@Sun.COM 		if ((i == 1) && (pkgdrtarg != (char *)NULL)) {
4541*9781SMoriah.Waterland@Sun.COM 			pkgcontsrc = pkgdrtarg;
4542*9781SMoriah.Waterland@Sun.COM 		}
4543*9781SMoriah.Waterland@Sun.COM 
4544*9781SMoriah.Waterland@Sun.COM 		/* reset interrupted flag before calling pkginstall */
4545*9781SMoriah.Waterland@Sun.COM 
4546*9781SMoriah.Waterland@Sun.COM 		interrupted = 0;	/* last action was NOT quit */
4547*9781SMoriah.Waterland@Sun.COM 
4548*9781SMoriah.Waterland@Sun.COM 		/* call pkginstall for this package */
4549*9781SMoriah.Waterland@Sun.COM 
4550*9781SMoriah.Waterland@Sun.COM 		n = pkgInstall(get_inst_root(), a_idsName,
4551*9781SMoriah.Waterland@Sun.COM 				pkgdev.dirname, a_altBinDir,
4552*9781SMoriah.Waterland@Sun.COM 				z_get_inherited_file_systems());
4553*9781SMoriah.Waterland@Sun.COM 
4554*9781SMoriah.Waterland@Sun.COM 		/* set success/fail condition variables */
4555*9781SMoriah.Waterland@Sun.COM 
4556*9781SMoriah.Waterland@Sun.COM 		ckreturn(n);
4557*9781SMoriah.Waterland@Sun.COM 
4558*9781SMoriah.Waterland@Sun.COM 		/* decrement number of packages left to install */
4559*9781SMoriah.Waterland@Sun.COM 
4560*9781SMoriah.Waterland@Sun.COM 		npkgs--;
4561*9781SMoriah.Waterland@Sun.COM 
4562*9781SMoriah.Waterland@Sun.COM 		/*
4563*9781SMoriah.Waterland@Sun.COM 		 * if no packages left to install, unmount package source
4564*9781SMoriah.Waterland@Sun.COM 		 * device if appropriate
4565*9781SMoriah.Waterland@Sun.COM 		 */
4566*9781SMoriah.Waterland@Sun.COM 
4567*9781SMoriah.Waterland@Sun.COM 		if ((npkgs <= 0) && (pkgdev.mount || a_idsName)) {
4568*9781SMoriah.Waterland@Sun.COM 			(void) chdir("/");
4569*9781SMoriah.Waterland@Sun.COM 			if (!a_idsName) {
4570*9781SMoriah.Waterland@Sun.COM 				(void) pkgumount(&pkgdev);
4571*9781SMoriah.Waterland@Sun.COM 			}
4572*9781SMoriah.Waterland@Sun.COM 		}
4573*9781SMoriah.Waterland@Sun.COM 	}
4574*9781SMoriah.Waterland@Sun.COM 
4575*9781SMoriah.Waterland@Sun.COM 	/*
4576*9781SMoriah.Waterland@Sun.COM 	 * all packages in the package list have been installed.
4577*9781SMoriah.Waterland@Sun.COM 	 * Continue with installation if:
4578*9781SMoriah.Waterland@Sun.COM 	 * -- immediate reboot is NOT required
4579*9781SMoriah.Waterland@Sun.COM 	 * -- there are more packages to install
4580*9781SMoriah.Waterland@Sun.COM 	 * -- the package source is a path to a file
4581*9781SMoriah.Waterland@Sun.COM 	 * else return do NOT continue.
4582*9781SMoriah.Waterland@Sun.COM 	 */
4583*9781SMoriah.Waterland@Sun.COM 
4584*9781SMoriah.Waterland@Sun.COM 	if ((ireboot == 0) && (a_repeat != 0) &&
4585*9781SMoriah.Waterland@Sun.COM 		(pkgdev.pathname == (char *)NULL)) {
4586*9781SMoriah.Waterland@Sun.COM 		return (B_TRUE);
4587*9781SMoriah.Waterland@Sun.COM 	}
4588*9781SMoriah.Waterland@Sun.COM 
4589*9781SMoriah.Waterland@Sun.COM 	/* return 'dont continue' */
4590*9781SMoriah.Waterland@Sun.COM 
4591*9781SMoriah.Waterland@Sun.COM 	return (B_FALSE);
4592*9781SMoriah.Waterland@Sun.COM }
4593*9781SMoriah.Waterland@Sun.COM 
4594*9781SMoriah.Waterland@Sun.COM /*
4595*9781SMoriah.Waterland@Sun.COM  * returns:
4596*9781SMoriah.Waterland@Sun.COM  *	B_TRUE to process next data stream
4597*9781SMoriah.Waterland@Sun.COM  *	B_FALSE to exit
4598*9781SMoriah.Waterland@Sun.COM  */
4599*9781SMoriah.Waterland@Sun.COM 
4600*9781SMoriah.Waterland@Sun.COM static boolean_t
4601*9781SMoriah.Waterland@Sun.COM add_packages(char **a_pkgList, char *a_uri,
4602*9781SMoriah.Waterland@Sun.COM 	char *a_idsName, int a_repeat, char *a_altBinDir, char *a_device,
4603*9781SMoriah.Waterland@Sun.COM 	boolean_t a_noZones)
4604*9781SMoriah.Waterland@Sun.COM {
4605*9781SMoriah.Waterland@Sun.COM 	zoneList_t	zlst;
4606*9781SMoriah.Waterland@Sun.COM 	boolean_t	b;
4607*9781SMoriah.Waterland@Sun.COM 
4608*9781SMoriah.Waterland@Sun.COM 	/* entry assertions */
4609*9781SMoriah.Waterland@Sun.COM 
4610*9781SMoriah.Waterland@Sun.COM 	assert(a_pkgList != (char **)NULL);
4611*9781SMoriah.Waterland@Sun.COM 
4612*9781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_ADDPACKAGES_ENTRY);
4613*9781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_ADDPACKAGES_ARGS, npkgs, PSTR(a_uri), PSTR(a_idsName),
4614*9781SMoriah.Waterland@Sun.COM 		a_repeat, PSTR(a_altBinDir), PSTR(a_device));
4615*9781SMoriah.Waterland@Sun.COM 
4616*9781SMoriah.Waterland@Sun.COM 	/*
4617*9781SMoriah.Waterland@Sun.COM 	 * if running in the global zone AND one or more non-global
4618*9781SMoriah.Waterland@Sun.COM 	 * zones exist, add packages in a 'zones aware' manner, else
4619*9781SMoriah.Waterland@Sun.COM 	 * add packages in the standard 'non-zones aware' manner.
4620*9781SMoriah.Waterland@Sun.COM 	 */
4621*9781SMoriah.Waterland@Sun.COM 
4622*9781SMoriah.Waterland@Sun.COM 	if ((a_noZones == B_FALSE) && (z_running_in_global_zone() == B_FALSE)) {
4623*9781SMoriah.Waterland@Sun.COM 		/* in non-global zone */
4624*9781SMoriah.Waterland@Sun.COM 
4625*9781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_IN_LZ);
4626*9781SMoriah.Waterland@Sun.COM 
4627*9781SMoriah.Waterland@Sun.COM 		b = z_lock_this_zone(ZLOCKS_PKG_ADMIN);
4628*9781SMoriah.Waterland@Sun.COM 		if (b != B_TRUE) {
4629*9781SMoriah.Waterland@Sun.COM 			progerr(ERR_CANNOT_LOCK_THIS_ZONE);
4630*9781SMoriah.Waterland@Sun.COM 			/* set fatal error return condition */
4631*9781SMoriah.Waterland@Sun.COM 			ckreturn(1);
4632*9781SMoriah.Waterland@Sun.COM 			return (B_FALSE);
4633*9781SMoriah.Waterland@Sun.COM 		}
4634*9781SMoriah.Waterland@Sun.COM 
4635*9781SMoriah.Waterland@Sun.COM 		b = add_packages_in_nonglobal_zone(a_pkgList, a_uri, a_idsName,
4636*9781SMoriah.Waterland@Sun.COM 			a_repeat, a_altBinDir, a_device);
4637*9781SMoriah.Waterland@Sun.COM 
4638*9781SMoriah.Waterland@Sun.COM 		(void) z_unlock_this_zone(ZLOCKS_ALL);
4639*9781SMoriah.Waterland@Sun.COM 
4640*9781SMoriah.Waterland@Sun.COM 		return (B_FALSE);
4641*9781SMoriah.Waterland@Sun.COM 	}
4642*9781SMoriah.Waterland@Sun.COM 
4643*9781SMoriah.Waterland@Sun.COM 	/* running in the global zone */
4644*9781SMoriah.Waterland@Sun.COM 
4645*9781SMoriah.Waterland@Sun.COM 	b = z_non_global_zones_exist();
4646*9781SMoriah.Waterland@Sun.COM 	if ((a_noZones == B_FALSE) && (b == B_TRUE) &&
4647*9781SMoriah.Waterland@Sun.COM 					(globalZoneOnly == B_FALSE)) {
4648*9781SMoriah.Waterland@Sun.COM 
4649*9781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_IN_GZ_WITH_LZ);
4650*9781SMoriah.Waterland@Sun.COM 
4651*9781SMoriah.Waterland@Sun.COM 		/* error if -V specified - what to use in non-global zone? */
4652*9781SMoriah.Waterland@Sun.COM 
4653*9781SMoriah.Waterland@Sun.COM 		if (vfstab_file) {
4654*9781SMoriah.Waterland@Sun.COM 			progerr(ERR_V_USED_WITH_GZS);
4655*9781SMoriah.Waterland@Sun.COM 			quit(1);
4656*9781SMoriah.Waterland@Sun.COM 		}
4657*9781SMoriah.Waterland@Sun.COM 
4658*9781SMoriah.Waterland@Sun.COM 		/* get a list of all non-global zones */
4659*9781SMoriah.Waterland@Sun.COM 		zlst = z_get_nonglobal_zone_list();
4660*9781SMoriah.Waterland@Sun.COM 		if (zlst == (zoneList_t)NULL) {
4661*9781SMoriah.Waterland@Sun.COM 			progerr(ERR_CANNOT_GET_ZONE_LIST);
4662*9781SMoriah.Waterland@Sun.COM 			quit(1);
4663*9781SMoriah.Waterland@Sun.COM 		}
4664*9781SMoriah.Waterland@Sun.COM 
4665*9781SMoriah.Waterland@Sun.COM 		/* need to lock all of the zones */
4666*9781SMoriah.Waterland@Sun.COM 
4667*9781SMoriah.Waterland@Sun.COM 		quitSetZonelist(zlst);
4668*9781SMoriah.Waterland@Sun.COM 		b = z_lock_zones(zlst, ZLOCKS_PKG_ADMIN);
4669*9781SMoriah.Waterland@Sun.COM 		if (b == B_FALSE) {
4670*9781SMoriah.Waterland@Sun.COM 			z_free_zone_list(zlst);
4671*9781SMoriah.Waterland@Sun.COM 			progerr(ERR_CANNOT_LOCK_ZONES);
4672*9781SMoriah.Waterland@Sun.COM 			/* set fatal error return condition */
4673*9781SMoriah.Waterland@Sun.COM 			ckreturn(1);
4674*9781SMoriah.Waterland@Sun.COM 			return (B_FALSE);
4675*9781SMoriah.Waterland@Sun.COM 		}
4676*9781SMoriah.Waterland@Sun.COM 
4677*9781SMoriah.Waterland@Sun.COM 		/* add packages to all zones */
4678*9781SMoriah.Waterland@Sun.COM 
4679*9781SMoriah.Waterland@Sun.COM 		b = add_packages_in_global_with_zones(a_pkgList, a_uri,
4680*9781SMoriah.Waterland@Sun.COM 			a_idsName, a_repeat, a_altBinDir, a_device, zlst);
4681*9781SMoriah.Waterland@Sun.COM 
4682*9781SMoriah.Waterland@Sun.COM 		/* unlock all zones */
4683*9781SMoriah.Waterland@Sun.COM 
4684*9781SMoriah.Waterland@Sun.COM 		(void) z_unlock_zones(zlst, ZLOCKS_ALL);
4685*9781SMoriah.Waterland@Sun.COM 		quitSetZonelist((zoneList_t)NULL);
4686*9781SMoriah.Waterland@Sun.COM 
4687*9781SMoriah.Waterland@Sun.COM 		/* free list of all non-global zones */
4688*9781SMoriah.Waterland@Sun.COM 
4689*9781SMoriah.Waterland@Sun.COM 		z_free_zone_list(zlst);
4690*9781SMoriah.Waterland@Sun.COM 
4691*9781SMoriah.Waterland@Sun.COM 		return (B_FALSE);
4692*9781SMoriah.Waterland@Sun.COM 	}
4693*9781SMoriah.Waterland@Sun.COM 
4694*9781SMoriah.Waterland@Sun.COM 	/* in global zone no non-global zones */
4695*9781SMoriah.Waterland@Sun.COM 
4696*9781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_IN_GZ_NO_LZ);
4697*9781SMoriah.Waterland@Sun.COM 
4698*9781SMoriah.Waterland@Sun.COM 	b = z_lock_this_zone(ZLOCKS_PKG_ADMIN);
4699*9781SMoriah.Waterland@Sun.COM 	if (b != B_TRUE) {
4700*9781SMoriah.Waterland@Sun.COM 		progerr(ERR_CANNOT_LOCK_THIS_ZONE);
4701*9781SMoriah.Waterland@Sun.COM 		/* set fatal error return condition */
4702*9781SMoriah.Waterland@Sun.COM 		ckreturn(1);
4703*9781SMoriah.Waterland@Sun.COM 		return (B_FALSE);
4704*9781SMoriah.Waterland@Sun.COM 	}
4705*9781SMoriah.Waterland@Sun.COM 
4706*9781SMoriah.Waterland@Sun.COM 	b = add_packages_in_global_no_zones(a_pkgList, a_uri, a_idsName,
4707*9781SMoriah.Waterland@Sun.COM 		a_repeat, a_altBinDir, a_device);
4708*9781SMoriah.Waterland@Sun.COM 
4709*9781SMoriah.Waterland@Sun.COM 	(void) z_unlock_this_zone(ZLOCKS_ALL);
4710*9781SMoriah.Waterland@Sun.COM 
4711*9781SMoriah.Waterland@Sun.COM 	return (B_FALSE);
4712*9781SMoriah.Waterland@Sun.COM }
4713