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 #include <stdio.h>
32*9781SMoriah.Waterland@Sun.COM #include <time.h>
33*9781SMoriah.Waterland@Sun.COM #include <wait.h>
34*9781SMoriah.Waterland@Sun.COM #include <stdlib.h>
35*9781SMoriah.Waterland@Sun.COM #include <unistd.h>
36*9781SMoriah.Waterland@Sun.COM #include <ulimit.h>
37*9781SMoriah.Waterland@Sun.COM #include <sys/stat.h>
38*9781SMoriah.Waterland@Sun.COM #include <sys/statvfs.h>
39*9781SMoriah.Waterland@Sun.COM #include <fcntl.h>
40*9781SMoriah.Waterland@Sun.COM #include <errno.h>
41*9781SMoriah.Waterland@Sun.COM #include <ctype.h>
42*9781SMoriah.Waterland@Sun.COM #include <dirent.h>
43*9781SMoriah.Waterland@Sun.COM #include <string.h>
44*9781SMoriah.Waterland@Sun.COM #include <signal.h>
45*9781SMoriah.Waterland@Sun.COM #include <locale.h>
46*9781SMoriah.Waterland@Sun.COM #include <libintl.h>
47*9781SMoriah.Waterland@Sun.COM #include <pkgstrct.h>
48*9781SMoriah.Waterland@Sun.COM #include <pkginfo.h>
49*9781SMoriah.Waterland@Sun.COM #include <pkgdev.h>
50*9781SMoriah.Waterland@Sun.COM #include <pkglocs.h>
51*9781SMoriah.Waterland@Sun.COM #include <pwd.h>
52*9781SMoriah.Waterland@Sun.COM #include <assert.h>
53*9781SMoriah.Waterland@Sun.COM #include <instzones_api.h>
54*9781SMoriah.Waterland@Sun.COM #include <pkglib.h>
55*9781SMoriah.Waterland@Sun.COM #include <pkgweb.h>
56*9781SMoriah.Waterland@Sun.COM #include <install.h>
57*9781SMoriah.Waterland@Sun.COM #include <libinst.h>
58*9781SMoriah.Waterland@Sun.COM #include <libadm.h>
59*9781SMoriah.Waterland@Sun.COM #include <dryrun.h>
60*9781SMoriah.Waterland@Sun.COM #include <messages.h>
61*9781SMoriah.Waterland@Sun.COM #include "pkginstall.h"
62*9781SMoriah.Waterland@Sun.COM 
63*9781SMoriah.Waterland@Sun.COM /* imported globals */
64*9781SMoriah.Waterland@Sun.COM 
65*9781SMoriah.Waterland@Sun.COM extern char	**environ;
66*9781SMoriah.Waterland@Sun.COM extern char	*pkgabrv;
67*9781SMoriah.Waterland@Sun.COM extern char	*pkgname;
68*9781SMoriah.Waterland@Sun.COM extern char	*pkgarch;
69*9781SMoriah.Waterland@Sun.COM extern char	*pkgvers;
70*9781SMoriah.Waterland@Sun.COM extern char	pkgwild[];
71*9781SMoriah.Waterland@Sun.COM 
72*9781SMoriah.Waterland@Sun.COM /* libadm(3LIB) */
73*9781SMoriah.Waterland@Sun.COM 
74*9781SMoriah.Waterland@Sun.COM extern char	*get_install_root(void);
75*9781SMoriah.Waterland@Sun.COM 
76*9781SMoriah.Waterland@Sun.COM /* quit.c */
77*9781SMoriah.Waterland@Sun.COM 
78*9781SMoriah.Waterland@Sun.COM extern sighdlrFunc_t	*quitGetTrapHandler(void);
79*9781SMoriah.Waterland@Sun.COM extern void		quitSetDstreamTmpdir(char *a_dstreamTempDir);
80*9781SMoriah.Waterland@Sun.COM extern void		quitSetInstallStarted(boolean_t a_installStarted);
81*9781SMoriah.Waterland@Sun.COM extern void		quitSetPkgask(boolean_t a_pkgaskFlag);
82*9781SMoriah.Waterland@Sun.COM extern void		quitSetSilentExit(boolean_t a_silentExit);
83*9781SMoriah.Waterland@Sun.COM extern void		quitSetUpdatingExisting(boolean_t a_updatingExisting);
84*9781SMoriah.Waterland@Sun.COM extern void		quitSetZoneName(char *a_zoneName);
85*9781SMoriah.Waterland@Sun.COM 
86*9781SMoriah.Waterland@Sun.COM 
87*9781SMoriah.Waterland@Sun.COM /* static globals */
88*9781SMoriah.Waterland@Sun.COM 
89*9781SMoriah.Waterland@Sun.COM static char	path[PATH_MAX];
90*9781SMoriah.Waterland@Sun.COM static int	ck_instbase(void);
91*9781SMoriah.Waterland@Sun.COM static int	cp_pkgdirs(void);
92*9781SMoriah.Waterland@Sun.COM static int	merg_pkginfos(struct cl_attr **pclass,
93*9781SMoriah.Waterland@Sun.COM 		struct cl_attr ***mpclass);
94*9781SMoriah.Waterland@Sun.COM static int	merg_respfile(void);
95*9781SMoriah.Waterland@Sun.COM static int	mv_pkgdirs(void);
96*9781SMoriah.Waterland@Sun.COM static int	rdonly(char *p);
97*9781SMoriah.Waterland@Sun.COM static void	ck_w_dryrun(int (*func)(), int type);
98*9781SMoriah.Waterland@Sun.COM static void	copyright(void), usage(void);
99*9781SMoriah.Waterland@Sun.COM static void	do_pkgask(boolean_t a_run_request_as_root);
100*9781SMoriah.Waterland@Sun.COM static void	rm_icas(char *casdir);
101*9781SMoriah.Waterland@Sun.COM static void	set_dryrun_dir_loc(void);
102*9781SMoriah.Waterland@Sun.COM static void	unpack(void);
103*9781SMoriah.Waterland@Sun.COM 
104*9781SMoriah.Waterland@Sun.COM void	ckreturn(int retcode, char *msg);
105*9781SMoriah.Waterland@Sun.COM 
106*9781SMoriah.Waterland@Sun.COM static char	*ro_params[] = {
107*9781SMoriah.Waterland@Sun.COM 	"PATH", "NAME", "PKG", "PKGINST",
108*9781SMoriah.Waterland@Sun.COM 	"VERSION", "ARCH",
109*9781SMoriah.Waterland@Sun.COM 	"INSTDATE", "CATEGORY",
110*9781SMoriah.Waterland@Sun.COM 	NULL
111*9781SMoriah.Waterland@Sun.COM };
112*9781SMoriah.Waterland@Sun.COM 
113*9781SMoriah.Waterland@Sun.COM /*
114*9781SMoriah.Waterland@Sun.COM  * The following variable is the name of the device to which stdin
115*9781SMoriah.Waterland@Sun.COM  * is connected during execution of a procedure script. PROC_STDIN is
116*9781SMoriah.Waterland@Sun.COM  * correct for all ABI compliant packages. For non-ABI-compliant
117*9781SMoriah.Waterland@Sun.COM  * packages, the '-o' command line switch changes this to PROC_XSTDIN
118*9781SMoriah.Waterland@Sun.COM  * to allow user interaction during these scripts. -- JST
119*9781SMoriah.Waterland@Sun.COM  */
120*9781SMoriah.Waterland@Sun.COM static char	*script_in = PROC_STDIN;	/* assume ABI compliance */
121*9781SMoriah.Waterland@Sun.COM 
122*9781SMoriah.Waterland@Sun.COM static char	*pkgdrtarg = NULL;
123*9781SMoriah.Waterland@Sun.COM static char	*pkgcontsrc = NULL;
124*9781SMoriah.Waterland@Sun.COM static int	non_abi_scripts = 0;
125*9781SMoriah.Waterland@Sun.COM static char	*respfile = NULL;
126*9781SMoriah.Waterland@Sun.COM static char	*srcinst = NULL;
127*9781SMoriah.Waterland@Sun.COM static int	suppressCopyright = 0;
128*9781SMoriah.Waterland@Sun.COM static int	nointeract = 0;
129*9781SMoriah.Waterland@Sun.COM 
130*9781SMoriah.Waterland@Sun.COM /* exported globals */
131*9781SMoriah.Waterland@Sun.COM 
132*9781SMoriah.Waterland@Sun.COM char		*msgtext;
133*9781SMoriah.Waterland@Sun.COM char		*pkginst = (char *)NULL;
134*9781SMoriah.Waterland@Sun.COM char		*rw_block_size = NULL;
135*9781SMoriah.Waterland@Sun.COM char		ilockfile[PATH_MAX];
136*9781SMoriah.Waterland@Sun.COM char		instdir[PATH_MAX];
137*9781SMoriah.Waterland@Sun.COM char		saveSpoolInstallDir[PATH_MAX];
138*9781SMoriah.Waterland@Sun.COM char		pkgbin[PATH_MAX];
139*9781SMoriah.Waterland@Sun.COM char		pkgloc[PATH_MAX];
140*9781SMoriah.Waterland@Sun.COM char		pkgloc_sav[PATH_MAX];
141*9781SMoriah.Waterland@Sun.COM char		pkgsav[PATH_MAX];
142*9781SMoriah.Waterland@Sun.COM char		rlockfile[PATH_MAX];
143*9781SMoriah.Waterland@Sun.COM char		savlog[PATH_MAX];
144*9781SMoriah.Waterland@Sun.COM char		tmpdir[PATH_MAX];
145*9781SMoriah.Waterland@Sun.COM int		dbchg;
146*9781SMoriah.Waterland@Sun.COM int		dparts = 0;
147*9781SMoriah.Waterland@Sun.COM int		dreboot = 0;
148*9781SMoriah.Waterland@Sun.COM int		failflag = 0;
149*9781SMoriah.Waterland@Sun.COM static int	askflag = 0;		/* non-zero if invoked as "pkgask" */
150*9781SMoriah.Waterland@Sun.COM int		ireboot = 0;
151*9781SMoriah.Waterland@Sun.COM int		maxinst = 1;
152*9781SMoriah.Waterland@Sun.COM int		nocnflct;
153*9781SMoriah.Waterland@Sun.COM int		nosetuid;
154*9781SMoriah.Waterland@Sun.COM int		opresvr4 = 0;
155*9781SMoriah.Waterland@Sun.COM int		pkgverbose = 0;
156*9781SMoriah.Waterland@Sun.COM int		rprcflag;
157*9781SMoriah.Waterland@Sun.COM int		warnflag = 0;
158*9781SMoriah.Waterland@Sun.COM struct admin	adm;
159*9781SMoriah.Waterland@Sun.COM struct cfextra	**extlist; /* pkgmap structure and other path info */
160*9781SMoriah.Waterland@Sun.COM struct pkgdev	pkgdev;
161*9781SMoriah.Waterland@Sun.COM fsblkcnt_t	pkgmap_blks = 0LL;
162*9781SMoriah.Waterland@Sun.COM 
163*9781SMoriah.Waterland@Sun.COM /*
164*9781SMoriah.Waterland@Sun.COM  * this global is referenced by:
165*9781SMoriah.Waterland@Sun.COM  * getinst - [RW] - incremented if:
166*9781SMoriah.Waterland@Sun.COM  * - installing same instance again
167*9781SMoriah.Waterland@Sun.COM  * - overwriting an existing instance
168*9781SMoriah.Waterland@Sun.COM  * - not installing a new instance
169*9781SMoriah.Waterland@Sun.COM  * quit - [RO] - if non-zero and started non-zero:
170*9781SMoriah.Waterland@Sun.COM  * - the new <PKGINST>/install directory and rename <PKGINST>/install.save
171*9781SMoriah.Waterland@Sun.COM  * - back to <PKGINST>/install
172*9781SMoriah.Waterland@Sun.COM  * main.c - [RO] - if non-zero:
173*9781SMoriah.Waterland@Sun.COM  * - alter manner in which parameters are setup for scripts
174*9781SMoriah.Waterland@Sun.COM  * - set UPDATE=yes in environment
175*9781SMoriah.Waterland@Sun.COM  */
176*9781SMoriah.Waterland@Sun.COM static int		update = 0;
177*9781SMoriah.Waterland@Sun.COM 
178*9781SMoriah.Waterland@Sun.COM /* Set by -O debug: debug output is enabled? */
179*9781SMoriah.Waterland@Sun.COM 
180*9781SMoriah.Waterland@Sun.COM static boolean_t	debugFlag = B_FALSE;
181*9781SMoriah.Waterland@Sun.COM 
182*9781SMoriah.Waterland@Sun.COM /* Set by the -G option: install packages in global zone only */
183*9781SMoriah.Waterland@Sun.COM 
184*9781SMoriah.Waterland@Sun.COM static boolean_t	globalZoneOnly = B_FALSE;
185*9781SMoriah.Waterland@Sun.COM 
186*9781SMoriah.Waterland@Sun.COM /* Set by -O patchPkgInstall */
187*9781SMoriah.Waterland@Sun.COM 
188*9781SMoriah.Waterland@Sun.COM static boolean_t patchPkgInstall = B_FALSE;
189*9781SMoriah.Waterland@Sun.COM 
190*9781SMoriah.Waterland@Sun.COM /* Set by -O patchPkgRemoval */
191*9781SMoriah.Waterland@Sun.COM 
192*9781SMoriah.Waterland@Sun.COM static boolean_t patchPkgRemoval = B_FALSE;
193*9781SMoriah.Waterland@Sun.COM 
194*9781SMoriah.Waterland@Sun.COM /* Set by -O preinstallcheck */
195*9781SMoriah.Waterland@Sun.COM 
196*9781SMoriah.Waterland@Sun.COM static boolean_t	preinstallCheck = B_FALSE;
197*9781SMoriah.Waterland@Sun.COM 
198*9781SMoriah.Waterland@Sun.COM /* Set by -O parent-zone-name= */
199*9781SMoriah.Waterland@Sun.COM 
200*9781SMoriah.Waterland@Sun.COM static char		*parentZoneName = (char *)NULL;
201*9781SMoriah.Waterland@Sun.COM 
202*9781SMoriah.Waterland@Sun.COM /* Set by -O parent-zone-type= */
203*9781SMoriah.Waterland@Sun.COM 
204*9781SMoriah.Waterland@Sun.COM static char		*parentZoneType = (char *)NULL;
205*9781SMoriah.Waterland@Sun.COM 
206*9781SMoriah.Waterland@Sun.COM #define	DEFPATH		"/sbin:/usr/sbin:/usr/bin"
207*9781SMoriah.Waterland@Sun.COM #define	MALSIZ	4	/* best guess at likely maximum value of MAXINST */
208*9781SMoriah.Waterland@Sun.COM #define	LSIZE	256	/* maximum line size supported in copyright file */
209*9781SMoriah.Waterland@Sun.COM 
210*9781SMoriah.Waterland@Sun.COM #ifdef	ALLOW_EXCEPTION_PKG_LIST
211*9781SMoriah.Waterland@Sun.COM #define	SCRIPT	0	/* which exception_pkg() pkg list to use (SCRIPTS) */
212*9781SMoriah.Waterland@Sun.COM #define	LINK	1	/* which exception_pkg() pkg list to use (SYMLINKS) */
213*9781SMoriah.Waterland@Sun.COM #endif
214*9781SMoriah.Waterland@Sun.COM 
215*9781SMoriah.Waterland@Sun.COM #if !defined(TEXT_DOMAIN)	/* Should be defined by cc -D */
216*9781SMoriah.Waterland@Sun.COM #define	TEXT_DOMAIN "SYS_TEST"
217*9781SMoriah.Waterland@Sun.COM #endif
218*9781SMoriah.Waterland@Sun.COM 
219*9781SMoriah.Waterland@Sun.COM /* This is the text for the "-O inherited-filesystem=" option */
220*9781SMoriah.Waterland@Sun.COM 
221*9781SMoriah.Waterland@Sun.COM #define	INHERITFS	"inherited-filesystem="
222*9781SMoriah.Waterland@Sun.COM #define	INHERITFS_LEN	((sizeof (INHERITFS))-1)
223*9781SMoriah.Waterland@Sun.COM 
224*9781SMoriah.Waterland@Sun.COM /* This is the text for the "-O parent-zone-name=" option */
225*9781SMoriah.Waterland@Sun.COM 
226*9781SMoriah.Waterland@Sun.COM #define	PARENTZONENAME	"parent-zone-name="
227*9781SMoriah.Waterland@Sun.COM #define	PARENTZONENAME_LEN	((sizeof (PARENTZONENAME))-1)
228*9781SMoriah.Waterland@Sun.COM 
229*9781SMoriah.Waterland@Sun.COM /* This is the text for the "-O parent-zone-type=" option */
230*9781SMoriah.Waterland@Sun.COM 
231*9781SMoriah.Waterland@Sun.COM #define	PARENTZONETYPE	"parent-zone-type="
232*9781SMoriah.Waterland@Sun.COM #define	PARENTZONETYPE_LEN	((sizeof (PARENTZONETYPE))-1)
233*9781SMoriah.Waterland@Sun.COM 
234*9781SMoriah.Waterland@Sun.COM static char *cpio_names[] = {
235*9781SMoriah.Waterland@Sun.COM 	"root",
236*9781SMoriah.Waterland@Sun.COM 	"root.cpio",
237*9781SMoriah.Waterland@Sun.COM 	"reloc",
238*9781SMoriah.Waterland@Sun.COM 	"reloc.cpio",
239*9781SMoriah.Waterland@Sun.COM 	"root.Z",
240*9781SMoriah.Waterland@Sun.COM 	"root.cpio.Z",
241*9781SMoriah.Waterland@Sun.COM 	"reloc.Z",
242*9781SMoriah.Waterland@Sun.COM 	"reloc.cpio.Z",
243*9781SMoriah.Waterland@Sun.COM 	0
244*9781SMoriah.Waterland@Sun.COM };
245*9781SMoriah.Waterland@Sun.COM 
246*9781SMoriah.Waterland@Sun.COM int
247*9781SMoriah.Waterland@Sun.COM main(int argc, char *argv[])
248*9781SMoriah.Waterland@Sun.COM {
249*9781SMoriah.Waterland@Sun.COM 	VFP_T			*cfTmpVfp = (VFP_T *)NULL;	/* t.contents */
250*9781SMoriah.Waterland@Sun.COM 	VFP_T			*cfVfp = (VFP_T *)NULL;		/* contents */
251*9781SMoriah.Waterland@Sun.COM 	VFP_T			*pkgmapVfp;	/* "../pkgmap" file */
252*9781SMoriah.Waterland@Sun.COM 	boolean_t		run_request_as_root = B_FALSE;
253*9781SMoriah.Waterland@Sun.COM 	char			**np;
254*9781SMoriah.Waterland@Sun.COM 	char			*abi_comp_ptr;
255*9781SMoriah.Waterland@Sun.COM 	char			*abi_nm_ptr;
256*9781SMoriah.Waterland@Sun.COM 	char			*abi_sym_ptr;
257*9781SMoriah.Waterland@Sun.COM 	char			*admnfile = NULL;
258*9781SMoriah.Waterland@Sun.COM 	char			*device;
259*9781SMoriah.Waterland@Sun.COM 	char			*p;
260*9781SMoriah.Waterland@Sun.COM 	char			*prog_full_name = NULL;
261*9781SMoriah.Waterland@Sun.COM 	char			*pt;
262*9781SMoriah.Waterland@Sun.COM 	char			*skipped = (char *)NULL;
263*9781SMoriah.Waterland@Sun.COM 	char			*updated = (char *)NULL;
264*9781SMoriah.Waterland@Sun.COM 	char			*vfstab_file = NULL;
265*9781SMoriah.Waterland@Sun.COM 	char			*zoneName = (char *)NULL;
266*9781SMoriah.Waterland@Sun.COM 	char			cbuf[MAX_PKG_PARAM_LENGTH];
267*9781SMoriah.Waterland@Sun.COM 	char			cmdbin[PATH_MAX];
268*9781SMoriah.Waterland@Sun.COM 	char			p_pkginfo[PATH_MAX];
269*9781SMoriah.Waterland@Sun.COM 	char			p_pkgmap[PATH_MAX];
270*9781SMoriah.Waterland@Sun.COM 	char			param[MAX_PKG_PARAM_LENGTH];
271*9781SMoriah.Waterland@Sun.COM 	char			script[PATH_MAX];
272*9781SMoriah.Waterland@Sun.COM 	char			altscript[PATH_MAX];
273*9781SMoriah.Waterland@Sun.COM 	int			c;
274*9781SMoriah.Waterland@Sun.COM 	int			disableAttributes = 0;
275*9781SMoriah.Waterland@Sun.COM 	int			err;
276*9781SMoriah.Waterland@Sun.COM 	int			init_install = 0;
277*9781SMoriah.Waterland@Sun.COM 	int			is_comp_arch;
278*9781SMoriah.Waterland@Sun.COM 	int			live_continue = 0;
279*9781SMoriah.Waterland@Sun.COM 	int			map_client = 1;
280*9781SMoriah.Waterland@Sun.COM 	int			n;
281*9781SMoriah.Waterland@Sun.COM 	int			nparts;
282*9781SMoriah.Waterland@Sun.COM 	int			npkgs;
283*9781SMoriah.Waterland@Sun.COM 	int			part;
284*9781SMoriah.Waterland@Sun.COM 	int			saveSpoolInstall = 0;
285*9781SMoriah.Waterland@Sun.COM 	boolean_t		cont_file_read;
286*9781SMoriah.Waterland@Sun.COM 	struct cl_attr		**pclass = NULL;
287*9781SMoriah.Waterland@Sun.COM 	struct cl_attr		**mergd_pclass = NULL;
288*9781SMoriah.Waterland@Sun.COM 	struct pkginfo		*prvinfo;
289*9781SMoriah.Waterland@Sun.COM 	struct sigaction	nact;
290*9781SMoriah.Waterland@Sun.COM 	struct sigaction	oact;
291*9781SMoriah.Waterland@Sun.COM 	struct stat		statb;
292*9781SMoriah.Waterland@Sun.COM 	struct statvfs64	svfsb;
293*9781SMoriah.Waterland@Sun.COM 	time_t			clock;
294*9781SMoriah.Waterland@Sun.COM 
295*9781SMoriah.Waterland@Sun.COM 	/* reset contents of all default paths */
296*9781SMoriah.Waterland@Sun.COM 
297*9781SMoriah.Waterland@Sun.COM 	(void) memset(path, '\0', sizeof (path));
298*9781SMoriah.Waterland@Sun.COM 	(void) memset(cmdbin, '\0', sizeof (cmdbin));
299*9781SMoriah.Waterland@Sun.COM 	(void) memset(script, '\0', sizeof (script));
300*9781SMoriah.Waterland@Sun.COM 	(void) memset(cbuf, '\0', sizeof (cbuf));
301*9781SMoriah.Waterland@Sun.COM 	(void) memset(param, '\0', sizeof (param));
302*9781SMoriah.Waterland@Sun.COM 
303*9781SMoriah.Waterland@Sun.COM 	/* initialize locale environment */
304*9781SMoriah.Waterland@Sun.COM 
305*9781SMoriah.Waterland@Sun.COM 	(void) setlocale(LC_ALL, "");
306*9781SMoriah.Waterland@Sun.COM 	(void) textdomain(TEXT_DOMAIN);
307*9781SMoriah.Waterland@Sun.COM 
308*9781SMoriah.Waterland@Sun.COM 	/* initialize program name */
309*9781SMoriah.Waterland@Sun.COM 
310*9781SMoriah.Waterland@Sun.COM 	prog_full_name = argv[0];
311*9781SMoriah.Waterland@Sun.COM 	(void) set_prog_name(argv[0]);
312*9781SMoriah.Waterland@Sun.COM 
313*9781SMoriah.Waterland@Sun.COM 	/* tell spmi zones interface how to access package output functions */
314*9781SMoriah.Waterland@Sun.COM 
315*9781SMoriah.Waterland@Sun.COM 	z_set_output_functions(echo, echoDebug, progerr);
316*9781SMoriah.Waterland@Sun.COM 
317*9781SMoriah.Waterland@Sun.COM 	/* exit if not root */
318*9781SMoriah.Waterland@Sun.COM 
319*9781SMoriah.Waterland@Sun.COM 	if (getuid()) {
320*9781SMoriah.Waterland@Sun.COM 		progerr(ERR_NOT_ROOT, get_prog_name());
321*9781SMoriah.Waterland@Sun.COM 		exit(1);
322*9781SMoriah.Waterland@Sun.COM 		/* NOTREACHED */
323*9781SMoriah.Waterland@Sun.COM 	}
324*9781SMoriah.Waterland@Sun.COM 
325*9781SMoriah.Waterland@Sun.COM 	/*
326*9781SMoriah.Waterland@Sun.COM 	 * determine how pkgmap() deals with environment variables:
327*9781SMoriah.Waterland@Sun.COM 	 *  - MAPALL - resolve all variables
328*9781SMoriah.Waterland@Sun.COM 	 *  - MAPBUILD - map only build variables
329*9781SMoriah.Waterland@Sun.COM 	 *  - MAPINSTALL - map only install variables
330*9781SMoriah.Waterland@Sun.COM 	 *  - MAPNONE - map no variables
331*9781SMoriah.Waterland@Sun.COM 	 */
332*9781SMoriah.Waterland@Sun.COM 
333*9781SMoriah.Waterland@Sun.COM 	setmapmode(MAPINSTALL);
334*9781SMoriah.Waterland@Sun.COM 
335*9781SMoriah.Waterland@Sun.COM 	/* set sane umask */
336*9781SMoriah.Waterland@Sun.COM 
337*9781SMoriah.Waterland@Sun.COM 	(void) umask(0022);
338*9781SMoriah.Waterland@Sun.COM 
339*9781SMoriah.Waterland@Sun.COM 	/* initially no source "device" */
340*9781SMoriah.Waterland@Sun.COM 
341*9781SMoriah.Waterland@Sun.COM 	device = NULL;
342*9781SMoriah.Waterland@Sun.COM 
343*9781SMoriah.Waterland@Sun.COM 	/* reset npkgs (used as pkg remaining count in quit.c) */
344*9781SMoriah.Waterland@Sun.COM 
345*9781SMoriah.Waterland@Sun.COM 	npkgs = 0;
346*9781SMoriah.Waterland@Sun.COM 
347*9781SMoriah.Waterland@Sun.COM 	/* Read PKG_INSTALL_ROOT from the environment, if it's there. */
348*9781SMoriah.Waterland@Sun.COM 
349*9781SMoriah.Waterland@Sun.COM 	if (!set_inst_root(getenv("PKG_INSTALL_ROOT"))) {
350*9781SMoriah.Waterland@Sun.COM 		progerr(ERR_ROOT_SET);
351*9781SMoriah.Waterland@Sun.COM 		exit(1);
352*9781SMoriah.Waterland@Sun.COM 	}
353*9781SMoriah.Waterland@Sun.COM 
354*9781SMoriah.Waterland@Sun.COM 	/* parse command line options */
355*9781SMoriah.Waterland@Sun.COM 
356*9781SMoriah.Waterland@Sun.COM 	while ((c = getopt(argc, argv,
357*9781SMoriah.Waterland@Sun.COM 		"?Aa:B:b:Cc:D:d:eFf:GhIiMm:N:noO:p:R:r:StV:vyz")) != EOF) {
358*9781SMoriah.Waterland@Sun.COM 
359*9781SMoriah.Waterland@Sun.COM 		switch (c) {
360*9781SMoriah.Waterland@Sun.COM 
361*9781SMoriah.Waterland@Sun.COM 		/*
362*9781SMoriah.Waterland@Sun.COM 		 * Same as pkgadd: This disables attribute checking.
363*9781SMoriah.Waterland@Sun.COM 		 * It speeds up installation a little bit.
364*9781SMoriah.Waterland@Sun.COM 		 */
365*9781SMoriah.Waterland@Sun.COM 		case 'A':
366*9781SMoriah.Waterland@Sun.COM 			disableAttributes++;
367*9781SMoriah.Waterland@Sun.COM 			break;
368*9781SMoriah.Waterland@Sun.COM 
369*9781SMoriah.Waterland@Sun.COM 		/*
370*9781SMoriah.Waterland@Sun.COM 		 * Same as pkgadd: Define an installation administration
371*9781SMoriah.Waterland@Sun.COM 		 * file, admin, to be used in place of the default
372*9781SMoriah.Waterland@Sun.COM 		 * administration file.  The token none overrides the use
373*9781SMoriah.Waterland@Sun.COM 		 * of any admin file, and thus forces interaction with the
374*9781SMoriah.Waterland@Sun.COM 		 * user. Unless a full path name is given, pkgadd first
375*9781SMoriah.Waterland@Sun.COM 		 * looks in the current working directory for the
376*9781SMoriah.Waterland@Sun.COM 		 * administration file.  If the specified administration
377*9781SMoriah.Waterland@Sun.COM 		 * file is not in the current working directory, pkgadd
378*9781SMoriah.Waterland@Sun.COM 		 * looks in the /var/sadm/install/admin directory for the
379*9781SMoriah.Waterland@Sun.COM 		 * administration file.
380*9781SMoriah.Waterland@Sun.COM 		 */
381*9781SMoriah.Waterland@Sun.COM 		case 'a':
382*9781SMoriah.Waterland@Sun.COM 			admnfile = flex_device(optarg, 0);
383*9781SMoriah.Waterland@Sun.COM 			break;
384*9781SMoriah.Waterland@Sun.COM 
385*9781SMoriah.Waterland@Sun.COM 		/*
386*9781SMoriah.Waterland@Sun.COM 		 * Same as pkgadd: control block size given to
387*9781SMoriah.Waterland@Sun.COM 		 * pkginstall - block size used in read()/write() loop;
388*9781SMoriah.Waterland@Sun.COM 		 * default is st_blksize from stat() of source file.
389*9781SMoriah.Waterland@Sun.COM 		 */
390*9781SMoriah.Waterland@Sun.COM 		case 'B':
391*9781SMoriah.Waterland@Sun.COM 			rw_block_size = optarg;
392*9781SMoriah.Waterland@Sun.COM 			break;
393*9781SMoriah.Waterland@Sun.COM 
394*9781SMoriah.Waterland@Sun.COM 		/*
395*9781SMoriah.Waterland@Sun.COM 		 * Same as pkgadd: location where executables needed
396*9781SMoriah.Waterland@Sun.COM 		 * by procedure scripts can be found
397*9781SMoriah.Waterland@Sun.COM 		 * default is /usr/sadm/install/bin.
398*9781SMoriah.Waterland@Sun.COM 		 */
399*9781SMoriah.Waterland@Sun.COM 		case 'b':
400*9781SMoriah.Waterland@Sun.COM 			if (!path_valid(optarg)) {
401*9781SMoriah.Waterland@Sun.COM 				progerr(ERR_PATH, optarg);
402*9781SMoriah.Waterland@Sun.COM 				exit(1);
403*9781SMoriah.Waterland@Sun.COM 			}
404*9781SMoriah.Waterland@Sun.COM 			if (isdir(optarg) != 0) {
405*9781SMoriah.Waterland@Sun.COM 				char *p = strerror(errno);
406*9781SMoriah.Waterland@Sun.COM 				progerr(ERR_CANNOT_USE_DIR, optarg, p);
407*9781SMoriah.Waterland@Sun.COM 				exit(1);
408*9781SMoriah.Waterland@Sun.COM 			}
409*9781SMoriah.Waterland@Sun.COM 			(void) strlcpy(cmdbin, optarg, sizeof (cmdbin));
410*9781SMoriah.Waterland@Sun.COM 			break;
411*9781SMoriah.Waterland@Sun.COM 
412*9781SMoriah.Waterland@Sun.COM 		/*
413*9781SMoriah.Waterland@Sun.COM 		 * Same as pkgadd: This disables checksum tests on
414*9781SMoriah.Waterland@Sun.COM 		 * the source files. It speeds up installation a little bit.
415*9781SMoriah.Waterland@Sun.COM 		 */
416*9781SMoriah.Waterland@Sun.COM 		case 'C':
417*9781SMoriah.Waterland@Sun.COM 			(void) checksum_off();
418*9781SMoriah.Waterland@Sun.COM 			break;
419*9781SMoriah.Waterland@Sun.COM 
420*9781SMoriah.Waterland@Sun.COM 		/*
421*9781SMoriah.Waterland@Sun.COM 		 * Same as pkgadd: This allows designation of a
422*9781SMoriah.Waterland@Sun.COM 		 * continuation file. It is the same format as a dryrun file
423*9781SMoriah.Waterland@Sun.COM 		 * but it is used to take up where the dryrun left off.
424*9781SMoriah.Waterland@Sun.COM 		 */
425*9781SMoriah.Waterland@Sun.COM 		case 'c':
426*9781SMoriah.Waterland@Sun.COM 			pkgcontsrc = optarg;
427*9781SMoriah.Waterland@Sun.COM 			set_continue_mode();
428*9781SMoriah.Waterland@Sun.COM 			set_dr_info(DR_TYPE, INSTALL_TYPE);
429*9781SMoriah.Waterland@Sun.COM 			init_contfile(pkgcontsrc);
430*9781SMoriah.Waterland@Sun.COM 			break;
431*9781SMoriah.Waterland@Sun.COM 
432*9781SMoriah.Waterland@Sun.COM 		/*
433*9781SMoriah.Waterland@Sun.COM 		 * Same as pkgadd: This allows designation of a
434*9781SMoriah.Waterland@Sun.COM 		 * dryrun file. This pkgadd will create dryrun files
435*9781SMoriah.Waterland@Sun.COM 		 * in the directory provided.
436*9781SMoriah.Waterland@Sun.COM 		 */
437*9781SMoriah.Waterland@Sun.COM 		case 'D':
438*9781SMoriah.Waterland@Sun.COM 			pkgdrtarg = optarg;
439*9781SMoriah.Waterland@Sun.COM 			set_dryrun_mode();
440*9781SMoriah.Waterland@Sun.COM 			set_dr_info(DR_TYPE, INSTALL_TYPE);
441*9781SMoriah.Waterland@Sun.COM 			break;
442*9781SMoriah.Waterland@Sun.COM 
443*9781SMoriah.Waterland@Sun.COM 		/*
444*9781SMoriah.Waterland@Sun.COM 		 * Same as pkgadd: Install or copy a package from
445*9781SMoriah.Waterland@Sun.COM 		 * device. device can be a full path name to a directory
446*9781SMoriah.Waterland@Sun.COM 		 * or the identifiers for tape, floppy disk, or removable
447*9781SMoriah.Waterland@Sun.COM 		 * disk - for example, /var/tmp or /floppy/floppy_name.
448*9781SMoriah.Waterland@Sun.COM 		 * It can also be a device alias - for example,
449*9781SMoriah.Waterland@Sun.COM 		 * /floppy/floppy0, or a datastream created by pkgtrans.
450*9781SMoriah.Waterland@Sun.COM 		 */
451*9781SMoriah.Waterland@Sun.COM 		case 'd':
452*9781SMoriah.Waterland@Sun.COM 			device = flex_device(optarg, 1);
453*9781SMoriah.Waterland@Sun.COM 			break;
454*9781SMoriah.Waterland@Sun.COM 
455*9781SMoriah.Waterland@Sun.COM 		/*
456*9781SMoriah.Waterland@Sun.COM 		 * Different from pkgadd: disable the 32 char name
457*9781SMoriah.Waterland@Sun.COM 		 * limit extension
458*9781SMoriah.Waterland@Sun.COM 		 */
459*9781SMoriah.Waterland@Sun.COM 		case 'e':
460*9781SMoriah.Waterland@Sun.COM 			(void) set_ABI_namelngth();
461*9781SMoriah.Waterland@Sun.COM 			break;
462*9781SMoriah.Waterland@Sun.COM 
463*9781SMoriah.Waterland@Sun.COM 		/*
464*9781SMoriah.Waterland@Sun.COM 		 * Different from pkgadd: specify file system type for
465*9781SMoriah.Waterland@Sun.COM 		 * the package device. Must be used with -m.
466*9781SMoriah.Waterland@Sun.COM 		 */
467*9781SMoriah.Waterland@Sun.COM 		case 'f':
468*9781SMoriah.Waterland@Sun.COM 			pkgdev.fstyp = optarg;
469*9781SMoriah.Waterland@Sun.COM 			break;
470*9781SMoriah.Waterland@Sun.COM 
471*9781SMoriah.Waterland@Sun.COM 		/*
472*9781SMoriah.Waterland@Sun.COM 		 * Same as pkgadd: install package in global zone only.
473*9781SMoriah.Waterland@Sun.COM 		 */
474*9781SMoriah.Waterland@Sun.COM 		case 'G':
475*9781SMoriah.Waterland@Sun.COM 			globalZoneOnly = B_TRUE;
476*9781SMoriah.Waterland@Sun.COM 			break;
477*9781SMoriah.Waterland@Sun.COM 
478*9781SMoriah.Waterland@Sun.COM 		/*
479*9781SMoriah.Waterland@Sun.COM 		 * Same as pkgadd: Enable hollow package support. When
480*9781SMoriah.Waterland@Sun.COM 		 * specified, for any package that has SUNW_PKG_HOLLOW=true:
481*9781SMoriah.Waterland@Sun.COM 		 *  Do not calculate and verify package size against target.
482*9781SMoriah.Waterland@Sun.COM 		 *  Do not run any package procedure or class action scripts.
483*9781SMoriah.Waterland@Sun.COM 		 *  Do not create any target directories.
484*9781SMoriah.Waterland@Sun.COM 		 *  Do not perform any script locking.
485*9781SMoriah.Waterland@Sun.COM 		 *  Do not install any components of any package.
486*9781SMoriah.Waterland@Sun.COM 		 *  Do not output any status or database update messages.
487*9781SMoriah.Waterland@Sun.COM 		 */
488*9781SMoriah.Waterland@Sun.COM 		case 'h':
489*9781SMoriah.Waterland@Sun.COM 			set_depend_pkginfo_DB(B_TRUE);
490*9781SMoriah.Waterland@Sun.COM 			break;
491*9781SMoriah.Waterland@Sun.COM 
492*9781SMoriah.Waterland@Sun.COM 		/*
493*9781SMoriah.Waterland@Sun.COM 		 * Same as pkgadd: Informs scripts that this is
494*9781SMoriah.Waterland@Sun.COM 		 * an initial install by setting the environment parameter
495*9781SMoriah.Waterland@Sun.COM 		 * PKG_INIT_INSTALL=TRUE for all scripts. They may use it as
496*9781SMoriah.Waterland@Sun.COM 		 * they see fit, safe in the knowledge that the target
497*9781SMoriah.Waterland@Sun.COM 		 * filesystem is tabula rasa.
498*9781SMoriah.Waterland@Sun.COM 		 */
499*9781SMoriah.Waterland@Sun.COM 		case 'I':
500*9781SMoriah.Waterland@Sun.COM 			init_install++;
501*9781SMoriah.Waterland@Sun.COM 			break;
502*9781SMoriah.Waterland@Sun.COM 
503*9781SMoriah.Waterland@Sun.COM 		/*
504*9781SMoriah.Waterland@Sun.COM 		 * Different from pkgadd: use by pkgask.
505*9781SMoriah.Waterland@Sun.COM 		 */
506*9781SMoriah.Waterland@Sun.COM 		case 'i':
507*9781SMoriah.Waterland@Sun.COM 			askflag++;
508*9781SMoriah.Waterland@Sun.COM 			quitSetPkgask(B_TRUE);
509*9781SMoriah.Waterland@Sun.COM 			break;
510*9781SMoriah.Waterland@Sun.COM 
511*9781SMoriah.Waterland@Sun.COM 		/*
512*9781SMoriah.Waterland@Sun.COM 		 * Same as pkgadd: Instruct pkgadd not to use the
513*9781SMoriah.Waterland@Sun.COM 		 * $root_path/etc/vfstab file for determining the client's
514*9781SMoriah.Waterland@Sun.COM 		 * mount points. This option assumes the mount points are
515*9781SMoriah.Waterland@Sun.COM 		 * correct on the server and it behaves consistently with
516*9781SMoriah.Waterland@Sun.COM 		 * Solaris 2.5 and earlier releases.
517*9781SMoriah.Waterland@Sun.COM 		 */
518*9781SMoriah.Waterland@Sun.COM 		case 'M':
519*9781SMoriah.Waterland@Sun.COM 			map_client = 0;
520*9781SMoriah.Waterland@Sun.COM 			break;
521*9781SMoriah.Waterland@Sun.COM 
522*9781SMoriah.Waterland@Sun.COM 		/*
523*9781SMoriah.Waterland@Sun.COM 		 * Different from pkgadd: specify device to use for package
524*9781SMoriah.Waterland@Sun.COM 		 * source.
525*9781SMoriah.Waterland@Sun.COM 		 */
526*9781SMoriah.Waterland@Sun.COM 		case 'm':
527*9781SMoriah.Waterland@Sun.COM 			pkgdev.mount = optarg;
528*9781SMoriah.Waterland@Sun.COM 			pkgdev.rdonly++;
529*9781SMoriah.Waterland@Sun.COM 			pkgdev.mntflg++;
530*9781SMoriah.Waterland@Sun.COM 			break;
531*9781SMoriah.Waterland@Sun.COM 
532*9781SMoriah.Waterland@Sun.COM 		/*
533*9781SMoriah.Waterland@Sun.COM 		 * Different from pkgadd: specify program name to use
534*9781SMoriah.Waterland@Sun.COM 		 * for messages.
535*9781SMoriah.Waterland@Sun.COM 		 */
536*9781SMoriah.Waterland@Sun.COM 		case 'N':
537*9781SMoriah.Waterland@Sun.COM 			(void) set_prog_name(optarg);
538*9781SMoriah.Waterland@Sun.COM 			break;
539*9781SMoriah.Waterland@Sun.COM 
540*9781SMoriah.Waterland@Sun.COM 		/*
541*9781SMoriah.Waterland@Sun.COM 		 * Same as pkgadd: installation occurs in
542*9781SMoriah.Waterland@Sun.COM 		 * non-interactive mode.  Suppress output of the list of
543*9781SMoriah.Waterland@Sun.COM 		 * installed files. The default mode is interactive.
544*9781SMoriah.Waterland@Sun.COM 		 */
545*9781SMoriah.Waterland@Sun.COM 		case 'n':
546*9781SMoriah.Waterland@Sun.COM 			nointeract++;
547*9781SMoriah.Waterland@Sun.COM 			(void) echoSetFlag(B_FALSE);
548*9781SMoriah.Waterland@Sun.COM 			break;
549*9781SMoriah.Waterland@Sun.COM 
550*9781SMoriah.Waterland@Sun.COM 		/*
551*9781SMoriah.Waterland@Sun.COM 		 * Almost same as pkgadd: the -O option allows the behavior
552*9781SMoriah.Waterland@Sun.COM 		 * of the package tools to be modified. Recognized options:
553*9781SMoriah.Waterland@Sun.COM 		 * -> debug
554*9781SMoriah.Waterland@Sun.COM 		 * ---> enable debugging output
555*9781SMoriah.Waterland@Sun.COM 		 * -> preinstallcheck
556*9781SMoriah.Waterland@Sun.COM 		 * ---> perform a "pre installation" check of the specified
557*9781SMoriah.Waterland@Sun.COM 		 * ---> package - suppress all regular output and cause a
558*9781SMoriah.Waterland@Sun.COM 		 * ---> series of one or more "name=value" pair format lines
559*9781SMoriah.Waterland@Sun.COM 		 * ---> to be output that describes the "installability" of
560*9781SMoriah.Waterland@Sun.COM 		 * ---> the specified package
561*9781SMoriah.Waterland@Sun.COM 		 * -> enable-hollow-package-support
562*9781SMoriah.Waterland@Sun.COM 		 * --> Enable hollow package support. When specified, for any
563*9781SMoriah.Waterland@Sun.COM 		 * --> package that has SUNW_PKG_HOLLOW=true:
564*9781SMoriah.Waterland@Sun.COM 		 * --> Do not calculate and verify package size against target
565*9781SMoriah.Waterland@Sun.COM 		 * --> Do not run any package procedure or class action scripts
566*9781SMoriah.Waterland@Sun.COM 		 * --> Do not create or remove any target directories
567*9781SMoriah.Waterland@Sun.COM 		 * --> Do not perform any script locking
568*9781SMoriah.Waterland@Sun.COM 		 * --> Do not install or uninstall any components of any package
569*9781SMoriah.Waterland@Sun.COM 		 * --> Do not output any status or database update messages
570*9781SMoriah.Waterland@Sun.COM 		 */
571*9781SMoriah.Waterland@Sun.COM 		case 'O':
572*9781SMoriah.Waterland@Sun.COM 			for (p = strtok(optarg, ","); p != (char *)NULL;
573*9781SMoriah.Waterland@Sun.COM 				p = strtok(NULL, ",")) {
574*9781SMoriah.Waterland@Sun.COM 
575*9781SMoriah.Waterland@Sun.COM 				/* process debug option */
576*9781SMoriah.Waterland@Sun.COM 
577*9781SMoriah.Waterland@Sun.COM 				if (strcmp(p, "debug") == 0) {
578*9781SMoriah.Waterland@Sun.COM 					/* set debug flag/enable debug output */
579*9781SMoriah.Waterland@Sun.COM 					if (debugFlag == B_TRUE) {
580*9781SMoriah.Waterland@Sun.COM 						smlSetVerbose(B_TRUE);
581*9781SMoriah.Waterland@Sun.COM 					}
582*9781SMoriah.Waterland@Sun.COM 					debugFlag = B_TRUE;
583*9781SMoriah.Waterland@Sun.COM 					(void) echoDebugSetFlag(debugFlag);
584*9781SMoriah.Waterland@Sun.COM 
585*9781SMoriah.Waterland@Sun.COM 					/* debug info on arguments to pkgadd */
586*9781SMoriah.Waterland@Sun.COM 					for (n = 0; n < argc && argv[n]; n++) {
587*9781SMoriah.Waterland@Sun.COM 						echoDebug(DBG_ARG, n, argv[n]);
588*9781SMoriah.Waterland@Sun.COM 					}
589*9781SMoriah.Waterland@Sun.COM 
590*9781SMoriah.Waterland@Sun.COM 					continue;
591*9781SMoriah.Waterland@Sun.COM 				}
592*9781SMoriah.Waterland@Sun.COM 
593*9781SMoriah.Waterland@Sun.COM 				/* process enable-hollow-package-support opt */
594*9781SMoriah.Waterland@Sun.COM 
595*9781SMoriah.Waterland@Sun.COM 				if (strcmp(p,
596*9781SMoriah.Waterland@Sun.COM 					"enable-hollow-package-support") == 0) {
597*9781SMoriah.Waterland@Sun.COM 					set_depend_pkginfo_DB(B_TRUE);
598*9781SMoriah.Waterland@Sun.COM 					continue;
599*9781SMoriah.Waterland@Sun.COM 				}
600*9781SMoriah.Waterland@Sun.COM 
601*9781SMoriah.Waterland@Sun.COM 				/* process inherited-filesystem= option */
602*9781SMoriah.Waterland@Sun.COM 
603*9781SMoriah.Waterland@Sun.COM 				if (strncmp(p, INHERITFS, INHERITFS_LEN) == 0) {
604*9781SMoriah.Waterland@Sun.COM 					if (z_add_inherited_file_system(
605*9781SMoriah.Waterland@Sun.COM 						p+INHERITFS_LEN) == B_FALSE) {
606*9781SMoriah.Waterland@Sun.COM 						progerr(ERR_NOSUCH_INHERITED,
607*9781SMoriah.Waterland@Sun.COM 							p+INHERITFS_LEN);
608*9781SMoriah.Waterland@Sun.COM 						quit(1);
609*9781SMoriah.Waterland@Sun.COM 						/* NOTREACHED */
610*9781SMoriah.Waterland@Sun.COM 					}
611*9781SMoriah.Waterland@Sun.COM 					continue;
612*9781SMoriah.Waterland@Sun.COM 				}
613*9781SMoriah.Waterland@Sun.COM 
614*9781SMoriah.Waterland@Sun.COM 				/* process preinstallcheck option */
615*9781SMoriah.Waterland@Sun.COM 
616*9781SMoriah.Waterland@Sun.COM 				if (strcmp(p, "preinstallcheck") == 0) {
617*9781SMoriah.Waterland@Sun.COM 					preinstallCheck = B_TRUE;
618*9781SMoriah.Waterland@Sun.COM 					nointeract++;	/* -n */
619*9781SMoriah.Waterland@Sun.COM 					suppressCopyright++;	/* -S */
620*9781SMoriah.Waterland@Sun.COM 					quitSetSilentExit(B_TRUE);
621*9781SMoriah.Waterland@Sun.COM 					continue;
622*9781SMoriah.Waterland@Sun.COM 				}
623*9781SMoriah.Waterland@Sun.COM 
624*9781SMoriah.Waterland@Sun.COM 				/* process addzonename option */
625*9781SMoriah.Waterland@Sun.COM 
626*9781SMoriah.Waterland@Sun.COM 				if (strcmp(p, "addzonename") == 0) {
627*9781SMoriah.Waterland@Sun.COM 					/*
628*9781SMoriah.Waterland@Sun.COM 					 * set zone name to add to messages;
629*9781SMoriah.Waterland@Sun.COM 					 * first look in the current environment
630*9781SMoriah.Waterland@Sun.COM 					 * and use the default package zone name
631*9781SMoriah.Waterland@Sun.COM 					 * if it is set; otherwise, use the name
632*9781SMoriah.Waterland@Sun.COM 					 * of the current zone
633*9781SMoriah.Waterland@Sun.COM 					 */
634*9781SMoriah.Waterland@Sun.COM 					zoneName =
635*9781SMoriah.Waterland@Sun.COM 						getenv(PKG_ZONENAME_VARIABLE);
636*9781SMoriah.Waterland@Sun.COM 
637*9781SMoriah.Waterland@Sun.COM 					if ((zoneName == (char *)NULL) ||
638*9781SMoriah.Waterland@Sun.COM 							(*zoneName == '\0')) {
639*9781SMoriah.Waterland@Sun.COM 						zoneName = z_get_zonename();
640*9781SMoriah.Waterland@Sun.COM 					}
641*9781SMoriah.Waterland@Sun.COM 
642*9781SMoriah.Waterland@Sun.COM 					if (zoneName != (char *)NULL) {
643*9781SMoriah.Waterland@Sun.COM 						if (*zoneName != '\0') {
644*9781SMoriah.Waterland@Sun.COM 							quitSetZoneName(
645*9781SMoriah.Waterland@Sun.COM 								zoneName);
646*9781SMoriah.Waterland@Sun.COM 						} else {
647*9781SMoriah.Waterland@Sun.COM 							zoneName = (char *)NULL;
648*9781SMoriah.Waterland@Sun.COM 						}
649*9781SMoriah.Waterland@Sun.COM 					}
650*9781SMoriah.Waterland@Sun.COM 					continue;
651*9781SMoriah.Waterland@Sun.COM 				}
652*9781SMoriah.Waterland@Sun.COM 
653*9781SMoriah.Waterland@Sun.COM 				/*
654*9781SMoriah.Waterland@Sun.COM 				 * If this is a patch installation
655*9781SMoriah.Waterland@Sun.COM 				 * then call setPatchUpdate().
656*9781SMoriah.Waterland@Sun.COM 				 */
657*9781SMoriah.Waterland@Sun.COM 
658*9781SMoriah.Waterland@Sun.COM 				if (strcmp(p, "patchPkgInstall") == 0) {
659*9781SMoriah.Waterland@Sun.COM 					setPatchUpdate();
660*9781SMoriah.Waterland@Sun.COM 					patchPkgInstall = B_TRUE;
661*9781SMoriah.Waterland@Sun.COM 					continue;
662*9781SMoriah.Waterland@Sun.COM 				}
663*9781SMoriah.Waterland@Sun.COM 
664*9781SMoriah.Waterland@Sun.COM 				/*
665*9781SMoriah.Waterland@Sun.COM 				 * If this is a patch removal
666*9781SMoriah.Waterland@Sun.COM 				 * then call setPatchUpdate() and set
667*9781SMoriah.Waterland@Sun.COM 				 * patchPkgRemoval flag.
668*9781SMoriah.Waterland@Sun.COM 				 */
669*9781SMoriah.Waterland@Sun.COM 
670*9781SMoriah.Waterland@Sun.COM 				if (strcmp(p, "patchPkgRemoval") == 0) {
671*9781SMoriah.Waterland@Sun.COM 					setPatchUpdate();
672*9781SMoriah.Waterland@Sun.COM 					patchPkgRemoval = B_TRUE;
673*9781SMoriah.Waterland@Sun.COM 					continue;
674*9781SMoriah.Waterland@Sun.COM 				}
675*9781SMoriah.Waterland@Sun.COM 
676*9781SMoriah.Waterland@Sun.COM 				/* process parent-zone-name option */
677*9781SMoriah.Waterland@Sun.COM 
678*9781SMoriah.Waterland@Sun.COM 				if (strncmp(p, PARENTZONENAME,
679*9781SMoriah.Waterland@Sun.COM 						PARENTZONENAME_LEN) == 0) {
680*9781SMoriah.Waterland@Sun.COM 					parentZoneName = p+PARENTZONENAME_LEN;
681*9781SMoriah.Waterland@Sun.COM 					continue;
682*9781SMoriah.Waterland@Sun.COM 				}
683*9781SMoriah.Waterland@Sun.COM 
684*9781SMoriah.Waterland@Sun.COM 				/* process parent-zone-type option */
685*9781SMoriah.Waterland@Sun.COM 
686*9781SMoriah.Waterland@Sun.COM 				if (strncmp(p, PARENTZONETYPE,
687*9781SMoriah.Waterland@Sun.COM 						PARENTZONETYPE_LEN) == 0) {
688*9781SMoriah.Waterland@Sun.COM 					parentZoneType = p+PARENTZONETYPE_LEN;
689*9781SMoriah.Waterland@Sun.COM 					continue;
690*9781SMoriah.Waterland@Sun.COM 				}
691*9781SMoriah.Waterland@Sun.COM 
692*9781SMoriah.Waterland@Sun.COM 				/* option not recognized - issue warning */
693*9781SMoriah.Waterland@Sun.COM 
694*9781SMoriah.Waterland@Sun.COM 				progerr(ERR_INVALID_O_OPTION, p);
695*9781SMoriah.Waterland@Sun.COM 				continue;
696*9781SMoriah.Waterland@Sun.COM 
697*9781SMoriah.Waterland@Sun.COM 			}
698*9781SMoriah.Waterland@Sun.COM 			break;
699*9781SMoriah.Waterland@Sun.COM 
700*9781SMoriah.Waterland@Sun.COM 		/*
701*9781SMoriah.Waterland@Sun.COM 		 * Different from pkgadd: This is an old non-ABI package
702*9781SMoriah.Waterland@Sun.COM 		 */
703*9781SMoriah.Waterland@Sun.COM 		case 'o':
704*9781SMoriah.Waterland@Sun.COM 			non_abi_scripts++;
705*9781SMoriah.Waterland@Sun.COM 			break;
706*9781SMoriah.Waterland@Sun.COM 
707*9781SMoriah.Waterland@Sun.COM 		/*
708*9781SMoriah.Waterland@Sun.COM 		 * Different from pkgadd: specify number of parts to package.
709*9781SMoriah.Waterland@Sun.COM 		 */
710*9781SMoriah.Waterland@Sun.COM 		case 'p':
711*9781SMoriah.Waterland@Sun.COM 			dparts = ds_getinfo(optarg);
712*9781SMoriah.Waterland@Sun.COM 			break;
713*9781SMoriah.Waterland@Sun.COM 
714*9781SMoriah.Waterland@Sun.COM 		/*
715*9781SMoriah.Waterland@Sun.COM 		 * Same as pkgadd: Define the full path name of a
716*9781SMoriah.Waterland@Sun.COM 		 * directory to use as the root_path.  All files,
717*9781SMoriah.Waterland@Sun.COM 		 * including package system information files, are
718*9781SMoriah.Waterland@Sun.COM 		 * relocated to a directory tree starting in the specified
719*9781SMoriah.Waterland@Sun.COM 		 * root_path. The root_path may be specified when
720*9781SMoriah.Waterland@Sun.COM 		 * installing to a client from a server (for example,
721*9781SMoriah.Waterland@Sun.COM 		 * /export/root/client1).
722*9781SMoriah.Waterland@Sun.COM 		 */
723*9781SMoriah.Waterland@Sun.COM 		case 'R':
724*9781SMoriah.Waterland@Sun.COM 			if (!set_inst_root(optarg)) {
725*9781SMoriah.Waterland@Sun.COM 				progerr(ERR_ROOT_CMD);
726*9781SMoriah.Waterland@Sun.COM 				exit(1);
727*9781SMoriah.Waterland@Sun.COM 			}
728*9781SMoriah.Waterland@Sun.COM 			break;
729*9781SMoriah.Waterland@Sun.COM 
730*9781SMoriah.Waterland@Sun.COM 		/*
731*9781SMoriah.Waterland@Sun.COM 		 * Same as pkgadd: Identify a file or directory which
732*9781SMoriah.Waterland@Sun.COM 		 * contains output from a previous pkgask(1M)
733*9781SMoriah.Waterland@Sun.COM 		 * session. This file supplies the interaction responses
734*9781SMoriah.Waterland@Sun.COM 		 * that would be requested by the package in interactive
735*9781SMoriah.Waterland@Sun.COM 		 * mode. response must be a full pathname.
736*9781SMoriah.Waterland@Sun.COM 		 */
737*9781SMoriah.Waterland@Sun.COM 		case 'r':
738*9781SMoriah.Waterland@Sun.COM 			respfile = flex_device(optarg, 2);
739*9781SMoriah.Waterland@Sun.COM 			break;
740*9781SMoriah.Waterland@Sun.COM 
741*9781SMoriah.Waterland@Sun.COM 		/*
742*9781SMoriah.Waterland@Sun.COM 		 * Same as pkgadd: suppress copyright notice being
743*9781SMoriah.Waterland@Sun.COM 		 * output during installation.
744*9781SMoriah.Waterland@Sun.COM 		 */
745*9781SMoriah.Waterland@Sun.COM 		case 'S':
746*9781SMoriah.Waterland@Sun.COM 			suppressCopyright++;
747*9781SMoriah.Waterland@Sun.COM 			break;
748*9781SMoriah.Waterland@Sun.COM 
749*9781SMoriah.Waterland@Sun.COM 		/*
750*9781SMoriah.Waterland@Sun.COM 		 * Same as pkgadd: disable save spool area creation;
751*9781SMoriah.Waterland@Sun.COM 		 * do not spool any partial package contents, that is,
752*9781SMoriah.Waterland@Sun.COM 		 * suppress the creation and population of the package save
753*9781SMoriah.Waterland@Sun.COM 		 * spool area (var/sadm/pkg/PKG/save/pspool/PKG).
754*9781SMoriah.Waterland@Sun.COM 		 */
755*9781SMoriah.Waterland@Sun.COM 		case 't':
756*9781SMoriah.Waterland@Sun.COM 			disable_spool_create();
757*9781SMoriah.Waterland@Sun.COM 			break;
758*9781SMoriah.Waterland@Sun.COM 
759*9781SMoriah.Waterland@Sun.COM 		/*
760*9781SMoriah.Waterland@Sun.COM 		 * Same as pkgadd: Specify an alternative fs_file to map
761*9781SMoriah.Waterland@Sun.COM 		 * the client's file systems.  For example, used in
762*9781SMoriah.Waterland@Sun.COM 		 * situations where the $root_path/etc/vfstab file is
763*9781SMoriah.Waterland@Sun.COM 		 * non-existent or unreliable. Informs the pkginstall
764*9781SMoriah.Waterland@Sun.COM 		 * portion to mount up a client filesystem based upon the
765*9781SMoriah.Waterland@Sun.COM 		 * supplied vfstab-like file of stable format.
766*9781SMoriah.Waterland@Sun.COM 		 */
767*9781SMoriah.Waterland@Sun.COM 		case 'V':
768*9781SMoriah.Waterland@Sun.COM 			vfstab_file = flex_device(optarg, 2);
769*9781SMoriah.Waterland@Sun.COM 			map_client = 1;
770*9781SMoriah.Waterland@Sun.COM 			break;
771*9781SMoriah.Waterland@Sun.COM 
772*9781SMoriah.Waterland@Sun.COM 		/*
773*9781SMoriah.Waterland@Sun.COM 		 * Same as pkgadd: Trace all of the scripts that get
774*9781SMoriah.Waterland@Sun.COM 		 * executed by pkgadd, located in the pkginst/install
775*9781SMoriah.Waterland@Sun.COM 		 * directory. This option is used for debugging the
776*9781SMoriah.Waterland@Sun.COM 		 * procedural and non-procedural scripts
777*9781SMoriah.Waterland@Sun.COM 		 */
778*9781SMoriah.Waterland@Sun.COM 		case 'v':
779*9781SMoriah.Waterland@Sun.COM 			pkgverbose++;
780*9781SMoriah.Waterland@Sun.COM 			break;
781*9781SMoriah.Waterland@Sun.COM 
782*9781SMoriah.Waterland@Sun.COM 		/*
783*9781SMoriah.Waterland@Sun.COM 		 * Different from pkgadd: process this package using
784*9781SMoriah.Waterland@Sun.COM 		 * old non-ABI symlinks
785*9781SMoriah.Waterland@Sun.COM 		 */
786*9781SMoriah.Waterland@Sun.COM 		case 'y':
787*9781SMoriah.Waterland@Sun.COM 			set_nonABI_symlinks();
788*9781SMoriah.Waterland@Sun.COM 			break;
789*9781SMoriah.Waterland@Sun.COM 
790*9781SMoriah.Waterland@Sun.COM 		/*
791*9781SMoriah.Waterland@Sun.COM 		 * Same as pkgadd: perform fresh install from
792*9781SMoriah.Waterland@Sun.COM 		 * package save spool area. When set, the package contents
793*9781SMoriah.Waterland@Sun.COM 		 * are installed from the package spool save area instead
794*9781SMoriah.Waterland@Sun.COM 		 * of from the package root area, so that the original
795*9781SMoriah.Waterland@Sun.COM 		 * source packages are not required to install the
796*9781SMoriah.Waterland@Sun.COM 		 * package. If the -h option is also specified and the
797*9781SMoriah.Waterland@Sun.COM 		 * package is hollow, then this option is ignored. When -z
798*9781SMoriah.Waterland@Sun.COM 		 * is specified:
799*9781SMoriah.Waterland@Sun.COM 		 *  - Editable files are installed from the package instance
800*9781SMoriah.Waterland@Sun.COM 		 *    save area.
801*9781SMoriah.Waterland@Sun.COM 		 *  - Volatile files are installed from the package instance
802*9781SMoriah.Waterland@Sun.COM 		 *    save area.
803*9781SMoriah.Waterland@Sun.COM 		 *  - Executable and data files are installed from the final
804*9781SMoriah.Waterland@Sun.COM 		 *    installed location as specified in the pkgmap file.
805*9781SMoriah.Waterland@Sun.COM 		 *  - Installation scripts are run from the package spool
806*9781SMoriah.Waterland@Sun.COM 		 *    save area.
807*9781SMoriah.Waterland@Sun.COM 		 */
808*9781SMoriah.Waterland@Sun.COM 		case 'z':
809*9781SMoriah.Waterland@Sun.COM 			saveSpoolInstall++;
810*9781SMoriah.Waterland@Sun.COM 			break;
811*9781SMoriah.Waterland@Sun.COM 
812*9781SMoriah.Waterland@Sun.COM 		/*
813*9781SMoriah.Waterland@Sun.COM 		 * unrecognized option
814*9781SMoriah.Waterland@Sun.COM 		 */
815*9781SMoriah.Waterland@Sun.COM 		default:
816*9781SMoriah.Waterland@Sun.COM 			usage();
817*9781SMoriah.Waterland@Sun.COM 			/*NOTREACHED*/
818*9781SMoriah.Waterland@Sun.COM 			/*
819*9781SMoriah.Waterland@Sun.COM 			 * Although usage() calls a noreturn function,
820*9781SMoriah.Waterland@Sun.COM 			 * needed to add return (1);  so that main() would
821*9781SMoriah.Waterland@Sun.COM 			 * pass compilation checks. The statement below
822*9781SMoriah.Waterland@Sun.COM 			 * should never be executed.
823*9781SMoriah.Waterland@Sun.COM 			 */
824*9781SMoriah.Waterland@Sun.COM 			return (1);
825*9781SMoriah.Waterland@Sun.COM 		}
826*9781SMoriah.Waterland@Sun.COM 	}
827*9781SMoriah.Waterland@Sun.COM 
828*9781SMoriah.Waterland@Sun.COM 	/*
829*9781SMoriah.Waterland@Sun.COM 	 * ********************************************************************
830*9781SMoriah.Waterland@Sun.COM 	 * validate command line options
831*9781SMoriah.Waterland@Sun.COM 	 * ********************************************************************
832*9781SMoriah.Waterland@Sun.COM 	 */
833*9781SMoriah.Waterland@Sun.COM 
834*9781SMoriah.Waterland@Sun.COM 	/* set "debug echo" flag according to setting of "-O debug" option */
835*9781SMoriah.Waterland@Sun.COM 
836*9781SMoriah.Waterland@Sun.COM 	(void) echoDebugSetFlag(debugFlag);
837*9781SMoriah.Waterland@Sun.COM 	(void) log_set_verbose(debugFlag);
838*9781SMoriah.Waterland@Sun.COM 
839*9781SMoriah.Waterland@Sun.COM 	/* output entry debugging information */
840*9781SMoriah.Waterland@Sun.COM 
841*9781SMoriah.Waterland@Sun.COM 	if (z_running_in_global_zone()) {
842*9781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_ENTRY_IN_GZ, prog_full_name);
843*9781SMoriah.Waterland@Sun.COM 	} else {
844*9781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_ENTRY_IN_LZ, prog_full_name, getzoneid(),
845*9781SMoriah.Waterland@Sun.COM 			z_get_zonename());
846*9781SMoriah.Waterland@Sun.COM 	}
847*9781SMoriah.Waterland@Sun.COM 
848*9781SMoriah.Waterland@Sun.COM 	if (in_continue_mode() && !in_dryrun_mode()) {
849*9781SMoriah.Waterland@Sun.COM 		progerr(ERR_LIVE_CONTINUE_NOT_SUPPORTED);
850*9781SMoriah.Waterland@Sun.COM 		usage();
851*9781SMoriah.Waterland@Sun.COM 		/*NOTREACHED*/
852*9781SMoriah.Waterland@Sun.COM 	}
853*9781SMoriah.Waterland@Sun.COM 
854*9781SMoriah.Waterland@Sun.COM 	/* pkgask requires a response file */
855*9781SMoriah.Waterland@Sun.COM 
856*9781SMoriah.Waterland@Sun.COM 	if (askflag && (respfile == NULL)) {
857*9781SMoriah.Waterland@Sun.COM 		usage();
858*9781SMoriah.Waterland@Sun.COM 		/*NOTREACHED*/
859*9781SMoriah.Waterland@Sun.COM 	}
860*9781SMoriah.Waterland@Sun.COM 
861*9781SMoriah.Waterland@Sun.COM 	/* if device specified, set appropriate device in pkgdev */
862*9781SMoriah.Waterland@Sun.COM 
863*9781SMoriah.Waterland@Sun.COM 	if (device) {
864*9781SMoriah.Waterland@Sun.COM 		if (pkgdev.mount) {
865*9781SMoriah.Waterland@Sun.COM 			pkgdev.bdevice = device;
866*9781SMoriah.Waterland@Sun.COM 		} else {
867*9781SMoriah.Waterland@Sun.COM 			pkgdev.cdevice = device;
868*9781SMoriah.Waterland@Sun.COM 		}
869*9781SMoriah.Waterland@Sun.COM 	}
870*9781SMoriah.Waterland@Sun.COM 
871*9781SMoriah.Waterland@Sun.COM 	/* if file system type specified, must have a device to mount */
872*9781SMoriah.Waterland@Sun.COM 
873*9781SMoriah.Waterland@Sun.COM 	if (pkgdev.fstyp && !pkgdev.mount) {
874*9781SMoriah.Waterland@Sun.COM 		progerr(ERR_F_REQUIRES_M);
875*9781SMoriah.Waterland@Sun.COM 		usage();
876*9781SMoriah.Waterland@Sun.COM 		/*NOTREACHED*/
877*9781SMoriah.Waterland@Sun.COM 	}
878*9781SMoriah.Waterland@Sun.COM 
879*9781SMoriah.Waterland@Sun.COM 	/* BEGIN DATA GATHERING PHASE */
880*9781SMoriah.Waterland@Sun.COM 
881*9781SMoriah.Waterland@Sun.COM 	/*
882*9781SMoriah.Waterland@Sun.COM 	 * Get the mount table info and store internally.
883*9781SMoriah.Waterland@Sun.COM 	 */
884*9781SMoriah.Waterland@Sun.COM 	cont_file_read = B_FALSE;
885*9781SMoriah.Waterland@Sun.COM 	if (in_continue_mode()) {
886*9781SMoriah.Waterland@Sun.COM 		int error;
887*9781SMoriah.Waterland@Sun.COM 		cont_file_read = read_continuation(&error);
888*9781SMoriah.Waterland@Sun.COM 		if (error == -1) {
889*9781SMoriah.Waterland@Sun.COM 			quit(99);
890*9781SMoriah.Waterland@Sun.COM 			/*NOTREACHED*/
891*9781SMoriah.Waterland@Sun.COM 		}
892*9781SMoriah.Waterland@Sun.COM 		if (!in_dryrun_mode()) {
893*9781SMoriah.Waterland@Sun.COM 			live_continue = 1;
894*9781SMoriah.Waterland@Sun.COM 		}
895*9781SMoriah.Waterland@Sun.COM 	}
896*9781SMoriah.Waterland@Sun.COM 	/* Read the mount table if not done in continuation mode */
897*9781SMoriah.Waterland@Sun.COM 	if (!cont_file_read) {
898*9781SMoriah.Waterland@Sun.COM 		if (get_mntinfo(map_client, vfstab_file)) {
899*9781SMoriah.Waterland@Sun.COM 			quit(99);
900*9781SMoriah.Waterland@Sun.COM 			/*NOTREACHED*/
901*9781SMoriah.Waterland@Sun.COM 		}
902*9781SMoriah.Waterland@Sun.COM 	}
903*9781SMoriah.Waterland@Sun.COM 
904*9781SMoriah.Waterland@Sun.COM 	/*
905*9781SMoriah.Waterland@Sun.COM 	 * This function defines the standard /var/... directories used later
906*9781SMoriah.Waterland@Sun.COM 	 * to construct the paths to the various databases.
907*9781SMoriah.Waterland@Sun.COM 	 */
908*9781SMoriah.Waterland@Sun.COM 
909*9781SMoriah.Waterland@Sun.COM 	set_PKGpaths(get_inst_root());
910*9781SMoriah.Waterland@Sun.COM 
911*9781SMoriah.Waterland@Sun.COM 	/*
912*9781SMoriah.Waterland@Sun.COM 	 * If this is being installed on a client whose /var filesystem is
913*9781SMoriah.Waterland@Sun.COM 	 * mounted in some odd way, remap the administrative paths to the
914*9781SMoriah.Waterland@Sun.COM 	 * real filesystem. This could be avoided by simply mounting up the
915*9781SMoriah.Waterland@Sun.COM 	 * client now; but we aren't yet to the point in the process where
916*9781SMoriah.Waterland@Sun.COM 	 * modification of the filesystem is permitted.
917*9781SMoriah.Waterland@Sun.COM 	 */
918*9781SMoriah.Waterland@Sun.COM 	if (is_an_inst_root()) {
919*9781SMoriah.Waterland@Sun.COM 		int fsys_value;
920*9781SMoriah.Waterland@Sun.COM 
921*9781SMoriah.Waterland@Sun.COM 		fsys_value = fsys(get_PKGLOC());
922*9781SMoriah.Waterland@Sun.COM 		if (use_srvr_map_n(fsys_value))
923*9781SMoriah.Waterland@Sun.COM 			set_PKGLOC(server_map(get_PKGLOC(), fsys_value));
924*9781SMoriah.Waterland@Sun.COM 
925*9781SMoriah.Waterland@Sun.COM 		fsys_value = fsys(get_PKGADM());
926*9781SMoriah.Waterland@Sun.COM 		if (use_srvr_map_n(fsys_value))
927*9781SMoriah.Waterland@Sun.COM 			set_PKGADM(server_map(get_PKGADM(), fsys_value));
928*9781SMoriah.Waterland@Sun.COM 	}
929*9781SMoriah.Waterland@Sun.COM 
930*9781SMoriah.Waterland@Sun.COM 	/*
931*9781SMoriah.Waterland@Sun.COM 	 * Initialize pkginfo PKGSAV entry, just in case we dryrun to
932*9781SMoriah.Waterland@Sun.COM 	 * somewhere else.
933*9781SMoriah.Waterland@Sun.COM 	 */
934*9781SMoriah.Waterland@Sun.COM 	set_infoloc(get_PKGLOC());
935*9781SMoriah.Waterland@Sun.COM 
936*9781SMoriah.Waterland@Sun.COM 	/* pull off directory and package name from end of command line */
937*9781SMoriah.Waterland@Sun.COM 
938*9781SMoriah.Waterland@Sun.COM 	switch (argc-optind) {
939*9781SMoriah.Waterland@Sun.COM 	case 0:	/* missing directory and package instance */
940*9781SMoriah.Waterland@Sun.COM 		progerr(ERR_MISSING_DIR_AND_PKG);
941*9781SMoriah.Waterland@Sun.COM 		usage();
942*9781SMoriah.Waterland@Sun.COM 		/*NOTREACHED*/
943*9781SMoriah.Waterland@Sun.COM 	case 1: /* missing package instance */
944*9781SMoriah.Waterland@Sun.COM 		progerr(ERR_MISSING_PKG_INSTANCE);
945*9781SMoriah.Waterland@Sun.COM 		usage();
946*9781SMoriah.Waterland@Sun.COM 		/*NOTREACHED*/
947*9781SMoriah.Waterland@Sun.COM 	case 2:	/* just right! */
948*9781SMoriah.Waterland@Sun.COM 		pkgdev.dirname = argv[optind++];
949*9781SMoriah.Waterland@Sun.COM 		srcinst = argv[optind++];
950*9781SMoriah.Waterland@Sun.COM 		break;
951*9781SMoriah.Waterland@Sun.COM 	default:	/* too many args! */
952*9781SMoriah.Waterland@Sun.COM 		progerr(ERR_TOO_MANY_CMD_ARGS);
953*9781SMoriah.Waterland@Sun.COM 		usage();
954*9781SMoriah.Waterland@Sun.COM 		break;
955*9781SMoriah.Waterland@Sun.COM 	}
956*9781SMoriah.Waterland@Sun.COM 
957*9781SMoriah.Waterland@Sun.COM 	(void) pkgparam(NULL, NULL);  /* close up prior pkg file if needed */
958*9781SMoriah.Waterland@Sun.COM 
959*9781SMoriah.Waterland@Sun.COM 	/*
960*9781SMoriah.Waterland@Sun.COM 	 * Initialize installation admin parameters by reading
961*9781SMoriah.Waterland@Sun.COM 	 * the adminfile.
962*9781SMoriah.Waterland@Sun.COM 	 */
963*9781SMoriah.Waterland@Sun.COM 
964*9781SMoriah.Waterland@Sun.COM 	if (!askflag && !live_continue) {
965*9781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_PKGINSTALL_ADMINFILE, admnfile ? admnfile : "");
966*9781SMoriah.Waterland@Sun.COM 		setadminFile(admnfile);
967*9781SMoriah.Waterland@Sun.COM 	}
968*9781SMoriah.Waterland@Sun.COM 
969*9781SMoriah.Waterland@Sun.COM 	/*
970*9781SMoriah.Waterland@Sun.COM 	 * about to perform first operation that could be modified by the
971*9781SMoriah.Waterland@Sun.COM 	 * preinstall check option - if preinstall check is selected (that is,
972*9781SMoriah.Waterland@Sun.COM 	 * only gathering dependencies), then output a debug message to
973*9781SMoriah.Waterland@Sun.COM 	 * indicate that the check is beginning. Also turn echo() output
974*9781SMoriah.Waterland@Sun.COM 	 * off and set various other flags.
975*9781SMoriah.Waterland@Sun.COM 	 */
976*9781SMoriah.Waterland@Sun.COM 
977*9781SMoriah.Waterland@Sun.COM 	if (preinstallCheck == B_TRUE) {
978*9781SMoriah.Waterland@Sun.COM 		(void) echoSetFlag(B_FALSE);
979*9781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_PKGINSTALL_PREINSCHK,
980*9781SMoriah.Waterland@Sun.COM 			pkginst ? pkginst : (srcinst ? srcinst : ""),
981*9781SMoriah.Waterland@Sun.COM 			zoneName ? zoneName : "global");
982*9781SMoriah.Waterland@Sun.COM 		cksetPreinstallCheck(B_TRUE);
983*9781SMoriah.Waterland@Sun.COM 		cksetZoneName(zoneName);
984*9781SMoriah.Waterland@Sun.COM 		/* inform quit that the install has started */
985*9781SMoriah.Waterland@Sun.COM 		quitSetInstallStarted(B_TRUE);
986*9781SMoriah.Waterland@Sun.COM 	}
987*9781SMoriah.Waterland@Sun.COM 
988*9781SMoriah.Waterland@Sun.COM 	/*
989*9781SMoriah.Waterland@Sun.COM 	 * validate the "rscriptalt" admin file setting
990*9781SMoriah.Waterland@Sun.COM 	 * The rscriptalt admin file parameter may be set to either
991*9781SMoriah.Waterland@Sun.COM 	 * RSCRIPTALT_ROOT or RSCRIPTALT_NOACCESS:
992*9781SMoriah.Waterland@Sun.COM 	 * --> If rscriptalt is not set, or is set to RSCRIPTALT_NOACCESS,
993*9781SMoriah.Waterland@Sun.COM 	 * --> or is set to any value OTHER than RSCRIPTALT_ROOT, then
994*9781SMoriah.Waterland@Sun.COM 	 * --> assume that the parameter is set to RSCRIPTALT_NOACCESS
995*9781SMoriah.Waterland@Sun.COM 	 * If rscriptalt is set to RSCRIPTALT_ROOT, then run request scripts
996*9781SMoriah.Waterland@Sun.COM 	 * as the "root" user if user "install" is not defined.
997*9781SMoriah.Waterland@Sun.COM 	 * Otherwise, assume rscriptalt is set to RSCRIPTALT_NOACCESS, and run
998*9781SMoriah.Waterland@Sun.COM 	 * request scripts as the "alternative" user if user "install" is not
999*9781SMoriah.Waterland@Sun.COM 	 * defined, as appropriate for the current setting of the NONABI_SCRIPTS
1000*9781SMoriah.Waterland@Sun.COM 	 * environment variable.
1001*9781SMoriah.Waterland@Sun.COM 	 */
1002*9781SMoriah.Waterland@Sun.COM 
1003*9781SMoriah.Waterland@Sun.COM 	if (ADMSET(RSCRIPTALT)) {
1004*9781SMoriah.Waterland@Sun.COM 		p = adm.RSCRIPTALT;
1005*9781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_PKGINSTALL_RSCRIPT_SET_TO, RSCRIPTALT_KEYWORD, p);
1006*9781SMoriah.Waterland@Sun.COM 		if (strcasecmp(p, RSCRIPTALT_ROOT) == 0) {
1007*9781SMoriah.Waterland@Sun.COM 			/* rscriptalt=root */
1008*9781SMoriah.Waterland@Sun.COM 			run_request_as_root = B_TRUE;
1009*9781SMoriah.Waterland@Sun.COM 		} else if (strcasecmp(p, RSCRIPTALT_NOACCESS) == 0) {
1010*9781SMoriah.Waterland@Sun.COM 			/* rscriptalt=noaccess */
1011*9781SMoriah.Waterland@Sun.COM 			run_request_as_root = B_FALSE;
1012*9781SMoriah.Waterland@Sun.COM 		} else {
1013*9781SMoriah.Waterland@Sun.COM 			/* rscriptalt=??? */
1014*9781SMoriah.Waterland@Sun.COM 			logerr(WRN_RSCRIPTALT_BAD, RSCRIPTALT_KEYWORD, p,
1015*9781SMoriah.Waterland@Sun.COM 				RSCRIPTALT_ROOT, RSCRIPTALT_NOACCESS);
1016*9781SMoriah.Waterland@Sun.COM 			logerr(WRN_RSCRIPTALT_USING, RSCRIPTALT_KEYWORD,
1017*9781SMoriah.Waterland@Sun.COM 				RSCRIPTALT_NOACCESS);
1018*9781SMoriah.Waterland@Sun.COM 			run_request_as_root = B_FALSE;
1019*9781SMoriah.Waterland@Sun.COM 		}
1020*9781SMoriah.Waterland@Sun.COM 	} else {
1021*9781SMoriah.Waterland@Sun.COM 		/* rscriptalt not set - assume rscriptalt=noaccess */
1022*9781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_PKGINSTALL_RSCRIPT_NOT_SET, RSCRIPTALT_KEYWORD);
1023*9781SMoriah.Waterland@Sun.COM 		run_request_as_root = B_FALSE;
1024*9781SMoriah.Waterland@Sun.COM 	}
1025*9781SMoriah.Waterland@Sun.COM 
1026*9781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_PKGINSTALL_RSCRIPT_IS_ROOT, run_request_as_root);
1027*9781SMoriah.Waterland@Sun.COM 
1028*9781SMoriah.Waterland@Sun.COM 	/*
1029*9781SMoriah.Waterland@Sun.COM 	 * hook SIGINT and SIGHUP interrupts into quit.c's trap handler
1030*9781SMoriah.Waterland@Sun.COM 	 */
1031*9781SMoriah.Waterland@Sun.COM 
1032*9781SMoriah.Waterland@Sun.COM 	/* hold SIGINT/SIGHUP interrupts */
1033*9781SMoriah.Waterland@Sun.COM 
1034*9781SMoriah.Waterland@Sun.COM 	(void) sighold(SIGHUP);
1035*9781SMoriah.Waterland@Sun.COM 	(void) sighold(SIGINT);
1036*9781SMoriah.Waterland@Sun.COM 
1037*9781SMoriah.Waterland@Sun.COM 	/* connect quit.c:trap() to SIGINT */
1038*9781SMoriah.Waterland@Sun.COM 
1039*9781SMoriah.Waterland@Sun.COM 	nact.sa_handler = quitGetTrapHandler();
1040*9781SMoriah.Waterland@Sun.COM 	nact.sa_flags = SA_RESTART;
1041*9781SMoriah.Waterland@Sun.COM 	(void) sigemptyset(&nact.sa_mask);
1042*9781SMoriah.Waterland@Sun.COM 
1043*9781SMoriah.Waterland@Sun.COM 	(void) sigaction(SIGINT, &nact, &oact);
1044*9781SMoriah.Waterland@Sun.COM 
1045*9781SMoriah.Waterland@Sun.COM 	/* connect quit.c:trap() to SIGHUP */
1046*9781SMoriah.Waterland@Sun.COM 
1047*9781SMoriah.Waterland@Sun.COM 	nact.sa_handler = quitGetTrapHandler();
1048*9781SMoriah.Waterland@Sun.COM 	nact.sa_flags = SA_RESTART;
1049*9781SMoriah.Waterland@Sun.COM 	(void) sigemptyset(&nact.sa_mask);
1050*9781SMoriah.Waterland@Sun.COM 
1051*9781SMoriah.Waterland@Sun.COM 	(void) sigaction(SIGHUP, &nact, &oact);
1052*9781SMoriah.Waterland@Sun.COM 
1053*9781SMoriah.Waterland@Sun.COM 	/* release hold on signals */
1054*9781SMoriah.Waterland@Sun.COM 
1055*9781SMoriah.Waterland@Sun.COM 	(void) sigrelse(SIGHUP);
1056*9781SMoriah.Waterland@Sun.COM 	(void) sigrelse(SIGINT);
1057*9781SMoriah.Waterland@Sun.COM 
1058*9781SMoriah.Waterland@Sun.COM 	/*
1059*9781SMoriah.Waterland@Sun.COM 	 * create required /var... directories if they do not exist;
1060*9781SMoriah.Waterland@Sun.COM 	 * this function will call quit(99) if any required path cannot
1061*9781SMoriah.Waterland@Sun.COM 	 * be created.
1062*9781SMoriah.Waterland@Sun.COM 	 */
1063*9781SMoriah.Waterland@Sun.COM 
1064*9781SMoriah.Waterland@Sun.COM 	ckdirs();
1065*9781SMoriah.Waterland@Sun.COM 
1066*9781SMoriah.Waterland@Sun.COM 	tzset();
1067*9781SMoriah.Waterland@Sun.COM 
1068*9781SMoriah.Waterland@Sun.COM 	/*
1069*9781SMoriah.Waterland@Sun.COM 	 * create path to temporary directory "installXXXXXX" - if TMPDIR
1070*9781SMoriah.Waterland@Sun.COM 	 * environment variable is set, create the directory in $TMPDIR;
1071*9781SMoriah.Waterland@Sun.COM 	 * otherwise, create the directory in P_tmpdir.
1072*9781SMoriah.Waterland@Sun.COM 	 */
1073*9781SMoriah.Waterland@Sun.COM 
1074*9781SMoriah.Waterland@Sun.COM 	pt = getenv("TMPDIR");
1075*9781SMoriah.Waterland@Sun.COM 	(void) snprintf(tmpdir, sizeof (tmpdir), "%s/installXXXXXX",
1076*9781SMoriah.Waterland@Sun.COM 		((pt != (char *)NULL) && (*pt != '\0')) ? pt : P_tmpdir);
1077*9781SMoriah.Waterland@Sun.COM 
1078*9781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_PKGINSTALL_TMPDIR, tmpdir);
1079*9781SMoriah.Waterland@Sun.COM 
1080*9781SMoriah.Waterland@Sun.COM 	if ((mktemp(tmpdir) == NULL) || mkdir(tmpdir, 0771)) {
1081*9781SMoriah.Waterland@Sun.COM 		progerr(ERR_MKDIR, tmpdir);
1082*9781SMoriah.Waterland@Sun.COM 		quit(99);
1083*9781SMoriah.Waterland@Sun.COM 		/*NOTREACHED*/
1084*9781SMoriah.Waterland@Sun.COM 	}
1085*9781SMoriah.Waterland@Sun.COM 
1086*9781SMoriah.Waterland@Sun.COM 	/*
1087*9781SMoriah.Waterland@Sun.COM 	 * if the package device is a file containing a package stream,
1088*9781SMoriah.Waterland@Sun.COM 	 * unpack the stream into a temporary directory
1089*9781SMoriah.Waterland@Sun.COM 	 */
1090*9781SMoriah.Waterland@Sun.COM 
1091*9781SMoriah.Waterland@Sun.COM 	if ((isdir(pkgdev.dirname) != 0) &&
1092*9781SMoriah.Waterland@Sun.COM 		(pkgdev.cdevice == (char *)NULL) &&
1093*9781SMoriah.Waterland@Sun.COM 		(pkgdev.bdevice == (char *)NULL) &&
1094*9781SMoriah.Waterland@Sun.COM 		(isfile((char *)NULL, pkgdev.dirname) == 0)) {
1095*9781SMoriah.Waterland@Sun.COM 
1096*9781SMoriah.Waterland@Sun.COM 		char		*idsName = (char *)NULL;
1097*9781SMoriah.Waterland@Sun.COM 		char		*pkgnames[2];
1098*9781SMoriah.Waterland@Sun.COM 		char		*device = pkgdev.dirname;
1099*9781SMoriah.Waterland@Sun.COM 		boolean_t	b;
1100*9781SMoriah.Waterland@Sun.COM 
1101*9781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_PKGINSTALL_DS_ISFILE, pkgdev.dirname);
1102*9781SMoriah.Waterland@Sun.COM 
1103*9781SMoriah.Waterland@Sun.COM 		/*
1104*9781SMoriah.Waterland@Sun.COM 		 * validate the package source device - return pkgdev info that
1105*9781SMoriah.Waterland@Sun.COM 		 * describes the package source device.
1106*9781SMoriah.Waterland@Sun.COM 		 */
1107*9781SMoriah.Waterland@Sun.COM 
1108*9781SMoriah.Waterland@Sun.COM 		if (devtype(device, &pkgdev)) {
1109*9781SMoriah.Waterland@Sun.COM 			progerr(ERR_BAD_DEVICE, device);
1110*9781SMoriah.Waterland@Sun.COM 			quit(99);
1111*9781SMoriah.Waterland@Sun.COM 			/* NOTREACHED */
1112*9781SMoriah.Waterland@Sun.COM 		}
1113*9781SMoriah.Waterland@Sun.COM 
1114*9781SMoriah.Waterland@Sun.COM 		/* generate the list of packages to verify */
1115*9781SMoriah.Waterland@Sun.COM 
1116*9781SMoriah.Waterland@Sun.COM 		pkgnames[0] = srcinst;
1117*9781SMoriah.Waterland@Sun.COM 		pkgnames[1] = (char *)NULL;
1118*9781SMoriah.Waterland@Sun.COM 
1119*9781SMoriah.Waterland@Sun.COM 		b = open_package_datastream(1, pkgnames, (char *)NULL,
1120*9781SMoriah.Waterland@Sun.COM 			pkgdev.dirname, (int *)NULL, &idsName, tmpdir, &pkgdev,
1121*9781SMoriah.Waterland@Sun.COM 			1);
1122*9781SMoriah.Waterland@Sun.COM 
1123*9781SMoriah.Waterland@Sun.COM 		if (b == B_FALSE) {
1124*9781SMoriah.Waterland@Sun.COM 			progerr(ERR_CANNOT_OPEN_PKG_STREAM,
1125*9781SMoriah.Waterland@Sun.COM 				pkgdev.dirname ? pkgdev.dirname : "?");
1126*9781SMoriah.Waterland@Sun.COM 			quit(99);
1127*9781SMoriah.Waterland@Sun.COM 			/*NOTREACHED*/
1128*9781SMoriah.Waterland@Sun.COM 		}
1129*9781SMoriah.Waterland@Sun.COM 
1130*9781SMoriah.Waterland@Sun.COM 		/* make sure temporary directory is removed on exit */
1131*9781SMoriah.Waterland@Sun.COM 
1132*9781SMoriah.Waterland@Sun.COM 		quitSetDstreamTmpdir(pkgdev.dirname);
1133*9781SMoriah.Waterland@Sun.COM 
1134*9781SMoriah.Waterland@Sun.COM 		/* unpack the package instance from the data stream */
1135*9781SMoriah.Waterland@Sun.COM 
1136*9781SMoriah.Waterland@Sun.COM 		b = unpack_package_from_stream(idsName, srcinst,
1137*9781SMoriah.Waterland@Sun.COM 							pkgdev.dirname);
1138*9781SMoriah.Waterland@Sun.COM 		if (b == B_FALSE) {
1139*9781SMoriah.Waterland@Sun.COM 			progerr(ERR_CANNOT_UNPACK_PKGSTRM,
1140*9781SMoriah.Waterland@Sun.COM 				srcinst ? srcinst : "?",
1141*9781SMoriah.Waterland@Sun.COM 				idsName ? idsName : "?",
1142*9781SMoriah.Waterland@Sun.COM 				pkgdev.dirname ? pkgdev.dirname : "?");
1143*9781SMoriah.Waterland@Sun.COM 			quit(99);
1144*9781SMoriah.Waterland@Sun.COM 			/*NOTREACHED*/
1145*9781SMoriah.Waterland@Sun.COM 		}
1146*9781SMoriah.Waterland@Sun.COM 
1147*9781SMoriah.Waterland@Sun.COM 		/* close the datastream - no longer needed */
1148*9781SMoriah.Waterland@Sun.COM 
1149*9781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_CLOSING_STREAM, idsName, pkgdev.dirname);
1150*9781SMoriah.Waterland@Sun.COM 		(void) ds_close(1);
1151*9781SMoriah.Waterland@Sun.COM 	}
1152*9781SMoriah.Waterland@Sun.COM 
1153*9781SMoriah.Waterland@Sun.COM 	if (snprintf(instdir, PATH_MAX, "%s/%s", pkgdev.dirname, srcinst)
1154*9781SMoriah.Waterland@Sun.COM 	    >= PATH_MAX) {
1155*9781SMoriah.Waterland@Sun.COM 		progerr(ERR_SNPRINTF, instdir);
1156*9781SMoriah.Waterland@Sun.COM 		quit(99);
1157*9781SMoriah.Waterland@Sun.COM 		/*NOTREACHED*/
1158*9781SMoriah.Waterland@Sun.COM 	}
1159*9781SMoriah.Waterland@Sun.COM 
1160*9781SMoriah.Waterland@Sun.COM 	zoneName = getenv(PKG_ZONENAME_VARIABLE);
1161*9781SMoriah.Waterland@Sun.COM 
1162*9781SMoriah.Waterland@Sun.COM 	/*
1163*9781SMoriah.Waterland@Sun.COM 	 * If the environment has a CLIENT_BASEDIR, that takes precedence
1164*9781SMoriah.Waterland@Sun.COM 	 * over anything we will construct. We need to save it here because
1165*9781SMoriah.Waterland@Sun.COM 	 * in three lines, the current environment goes away.
1166*9781SMoriah.Waterland@Sun.COM 	 */
1167*9781SMoriah.Waterland@Sun.COM 	(void) set_env_cbdir();	/* copy over environ */
1168*9781SMoriah.Waterland@Sun.COM 
1169*9781SMoriah.Waterland@Sun.COM 	getuserlocale();
1170*9781SMoriah.Waterland@Sun.COM 
1171*9781SMoriah.Waterland@Sun.COM 	/*
1172*9781SMoriah.Waterland@Sun.COM 	 * current environment has been read; clear environment out
1173*9781SMoriah.Waterland@Sun.COM 	 * so putparam() can be used to populate the new environment
1174*9781SMoriah.Waterland@Sun.COM 	 * to be passed to any executables/scripts.
1175*9781SMoriah.Waterland@Sun.COM 	 */
1176*9781SMoriah.Waterland@Sun.COM 
1177*9781SMoriah.Waterland@Sun.COM 	environ = NULL;
1178*9781SMoriah.Waterland@Sun.COM 
1179*9781SMoriah.Waterland@Sun.COM 	/* write parent condition information to environment */
1180*9781SMoriah.Waterland@Sun.COM 
1181*9781SMoriah.Waterland@Sun.COM 	putConditionInfo(parentZoneName, parentZoneType);
1182*9781SMoriah.Waterland@Sun.COM 
1183*9781SMoriah.Waterland@Sun.COM 	putuserlocale();
1184*9781SMoriah.Waterland@Sun.COM 
1185*9781SMoriah.Waterland@Sun.COM 	if (init_install) {
1186*9781SMoriah.Waterland@Sun.COM 		putparam("PKG_INIT_INSTALL", "TRUE");
1187*9781SMoriah.Waterland@Sun.COM 	}
1188*9781SMoriah.Waterland@Sun.COM 
1189*9781SMoriah.Waterland@Sun.COM 	if (is_an_inst_root()) {
1190*9781SMoriah.Waterland@Sun.COM 		export_client_env(get_inst_root());
1191*9781SMoriah.Waterland@Sun.COM 	}
1192*9781SMoriah.Waterland@Sun.COM 
1193*9781SMoriah.Waterland@Sun.COM 	if (zoneName != (char *)NULL) {
1194*9781SMoriah.Waterland@Sun.COM 		putparam(PKG_ZONENAME_VARIABLE, zoneName);
1195*9781SMoriah.Waterland@Sun.COM 	}
1196*9781SMoriah.Waterland@Sun.COM 
1197*9781SMoriah.Waterland@Sun.COM 	putparam("INST_DATADIR", pkgdev.dirname);
1198*9781SMoriah.Waterland@Sun.COM 
1199*9781SMoriah.Waterland@Sun.COM 	if (non_abi_scripts) {
1200*9781SMoriah.Waterland@Sun.COM 		putparam("NONABI_SCRIPTS", "TRUE");
1201*9781SMoriah.Waterland@Sun.COM 	}
1202*9781SMoriah.Waterland@Sun.COM 
1203*9781SMoriah.Waterland@Sun.COM 	if (nonABI_symlinks()) {
1204*9781SMoriah.Waterland@Sun.COM 		putparam("PKG_NONABI_SYMLINKS", "TRUE");
1205*9781SMoriah.Waterland@Sun.COM 	}
1206*9781SMoriah.Waterland@Sun.COM 
1207*9781SMoriah.Waterland@Sun.COM 	if (get_ABI_namelngth()) {
1208*9781SMoriah.Waterland@Sun.COM 		putparam("PKG_ABI_NAMELENGTH", "TRUE");
1209*9781SMoriah.Waterland@Sun.COM 	}
1210*9781SMoriah.Waterland@Sun.COM 
1211*9781SMoriah.Waterland@Sun.COM 	/* establish path and oambase */
1212*9781SMoriah.Waterland@Sun.COM 
1213*9781SMoriah.Waterland@Sun.COM 	if (cmdbin[0] == '\0') {
1214*9781SMoriah.Waterland@Sun.COM 		(void) strlcpy(cmdbin, PKGBIN, sizeof (cmdbin));
1215*9781SMoriah.Waterland@Sun.COM 	}
1216*9781SMoriah.Waterland@Sun.COM 
1217*9781SMoriah.Waterland@Sun.COM 	(void) snprintf(path, sizeof (path), "%s:%s", DEFPATH, cmdbin);
1218*9781SMoriah.Waterland@Sun.COM 
1219*9781SMoriah.Waterland@Sun.COM 	putparam("PATH", path);
1220*9781SMoriah.Waterland@Sun.COM 
1221*9781SMoriah.Waterland@Sun.COM 	putparam("OAMBASE", OAMBASE);
1222*9781SMoriah.Waterland@Sun.COM 
1223*9781SMoriah.Waterland@Sun.COM 	(void) snprintf(p_pkginfo, sizeof (p_pkginfo),
1224*9781SMoriah.Waterland@Sun.COM 			"%s/%s", instdir, PKGINFO);
1225*9781SMoriah.Waterland@Sun.COM 	(void) snprintf(p_pkgmap, sizeof (p_pkgmap),
1226*9781SMoriah.Waterland@Sun.COM 			"%s/%s", instdir, PKGMAP);
1227*9781SMoriah.Waterland@Sun.COM 
1228*9781SMoriah.Waterland@Sun.COM 	/* Read the environment (from pkginfo or '-e') ... */
1229*9781SMoriah.Waterland@Sun.COM 	abi_nm_ptr = getenv("PKG_ABI_NAMELENGTH");
1230*9781SMoriah.Waterland@Sun.COM 
1231*9781SMoriah.Waterland@Sun.COM 	/* Disable the 32 char name limit extension */
1232*9781SMoriah.Waterland@Sun.COM 	if (abi_nm_ptr && strncasecmp(abi_nm_ptr, "TRUE", 4) == 0) {
1233*9781SMoriah.Waterland@Sun.COM 		(void) set_ABI_namelngth();
1234*9781SMoriah.Waterland@Sun.COM 	}
1235*9781SMoriah.Waterland@Sun.COM 
1236*9781SMoriah.Waterland@Sun.COM 	/*
1237*9781SMoriah.Waterland@Sun.COM 	 * This tests the pkginfo and pkgmap files for validity and
1238*9781SMoriah.Waterland@Sun.COM 	 * puts all delivered pkginfo variables (except for PATH) into
1239*9781SMoriah.Waterland@Sun.COM 	 * our environment. This is where a delivered pkginfo BASEDIR
1240*9781SMoriah.Waterland@Sun.COM 	 * would come from. See set_basedirs() below.
1241*9781SMoriah.Waterland@Sun.COM 	 */
1242*9781SMoriah.Waterland@Sun.COM 
1243*9781SMoriah.Waterland@Sun.COM 	if (pkgenv(srcinst, p_pkginfo, p_pkgmap)) {
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 	echo("\n%s(%s) %s", pkgname, pkgarch, pkgvers);
1249*9781SMoriah.Waterland@Sun.COM 
1250*9781SMoriah.Waterland@Sun.COM 	/*
1251*9781SMoriah.Waterland@Sun.COM 	 * If this script was invoked by 'pkgask', just
1252*9781SMoriah.Waterland@Sun.COM 	 * execute request script and quit (do_pkgask()).
1253*9781SMoriah.Waterland@Sun.COM 	 */
1254*9781SMoriah.Waterland@Sun.COM 
1255*9781SMoriah.Waterland@Sun.COM 	if (askflag) {
1256*9781SMoriah.Waterland@Sun.COM 		do_pkgask(run_request_as_root);
1257*9781SMoriah.Waterland@Sun.COM 	}
1258*9781SMoriah.Waterland@Sun.COM 
1259*9781SMoriah.Waterland@Sun.COM 	/* validate package contents file */
1260*9781SMoriah.Waterland@Sun.COM 
1261*9781SMoriah.Waterland@Sun.COM 	if (vcfile() == 0) {
1262*9781SMoriah.Waterland@Sun.COM 		quit(99);
1263*9781SMoriah.Waterland@Sun.COM 	}
1264*9781SMoriah.Waterland@Sun.COM 
1265*9781SMoriah.Waterland@Sun.COM 	/* if not in dryrun mode aquire packaging lock */
1266*9781SMoriah.Waterland@Sun.COM 
1267*9781SMoriah.Waterland@Sun.COM 	if (!in_dryrun_mode()) {
1268*9781SMoriah.Waterland@Sun.COM 		/* acquire the package lock - at install initialization */
1269*9781SMoriah.Waterland@Sun.COM 		if (!lockinst(get_prog_name(), srcinst, "install-initial")) {
1270*9781SMoriah.Waterland@Sun.COM 			quit(99);
1271*9781SMoriah.Waterland@Sun.COM 			/*NOTREACHED*/
1272*9781SMoriah.Waterland@Sun.COM 		}
1273*9781SMoriah.Waterland@Sun.COM 	}
1274*9781SMoriah.Waterland@Sun.COM 
1275*9781SMoriah.Waterland@Sun.COM 	/*
1276*9781SMoriah.Waterland@Sun.COM 	 * Now do all the various setups based on ABI compliance
1277*9781SMoriah.Waterland@Sun.COM 	 */
1278*9781SMoriah.Waterland@Sun.COM 
1279*9781SMoriah.Waterland@Sun.COM 	/* Read the environment (from pkginfo or '-o') ... */
1280*9781SMoriah.Waterland@Sun.COM 	abi_comp_ptr = getenv("NONABI_SCRIPTS");
1281*9781SMoriah.Waterland@Sun.COM 
1282*9781SMoriah.Waterland@Sun.COM 	/* Read the environment (from pkginfo or '-y') ... */
1283*9781SMoriah.Waterland@Sun.COM 	abi_sym_ptr = getenv("PKG_NONABI_SYMLINKS");
1284*9781SMoriah.Waterland@Sun.COM 
1285*9781SMoriah.Waterland@Sun.COM 	/* bug id 4244631, not ABI compliant */
1286*9781SMoriah.Waterland@Sun.COM 	if (abi_comp_ptr && strncasecmp(abi_comp_ptr, "TRUE", 4) == 0) {
1287*9781SMoriah.Waterland@Sun.COM 		script_in = PROC_XSTDIN;
1288*9781SMoriah.Waterland@Sun.COM 		non_abi_scripts = 1;
1289*9781SMoriah.Waterland@Sun.COM 	}
1290*9781SMoriah.Waterland@Sun.COM 
1291*9781SMoriah.Waterland@Sun.COM #ifdef	ALLOW_EXCEPTION_PKG_LIST
1292*9781SMoriah.Waterland@Sun.COM 	/*
1293*9781SMoriah.Waterland@Sun.COM 	 * *********************************************************************
1294*9781SMoriah.Waterland@Sun.COM 	 * this feature is removed starting with Solaris 10 - there is no built
1295*9781SMoriah.Waterland@Sun.COM 	 * in list of packages that should be run "the old way"
1296*9781SMoriah.Waterland@Sun.COM 	 * *********************************************************************
1297*9781SMoriah.Waterland@Sun.COM 	 */
1298*9781SMoriah.Waterland@Sun.COM 
1299*9781SMoriah.Waterland@Sun.COM 	else if (exception_pkg(srcinst, SCRIPT)) {
1300*9781SMoriah.Waterland@Sun.COM 		/*
1301*9781SMoriah.Waterland@Sun.COM 		 * Until on1095, set it from exception package names as
1302*9781SMoriah.Waterland@Sun.COM 		 * well.
1303*9781SMoriah.Waterland@Sun.COM 		 */
1304*9781SMoriah.Waterland@Sun.COM 		putparam("NONABI_SCRIPTS", "TRUE");
1305*9781SMoriah.Waterland@Sun.COM 		script_in = PROC_XSTDIN;
1306*9781SMoriah.Waterland@Sun.COM 		non_abi_scripts = 1;
1307*9781SMoriah.Waterland@Sun.COM 	}
1308*9781SMoriah.Waterland@Sun.COM #endif
1309*9781SMoriah.Waterland@Sun.COM 
1310*9781SMoriah.Waterland@Sun.COM 	/* Set symlinks to be processed the old way */
1311*9781SMoriah.Waterland@Sun.COM 	if (abi_sym_ptr && strncasecmp(abi_sym_ptr, "TRUE", 4) == 0) {
1312*9781SMoriah.Waterland@Sun.COM 		set_nonABI_symlinks();
1313*9781SMoriah.Waterland@Sun.COM 	}
1314*9781SMoriah.Waterland@Sun.COM 	/*
1315*9781SMoriah.Waterland@Sun.COM 	 * *********************************************************************
1316*9781SMoriah.Waterland@Sun.COM 	 * this feature is removed starting with Solaris 10 - there is no built
1317*9781SMoriah.Waterland@Sun.COM 	 * in list of packages that should be run "the old way"
1318*9781SMoriah.Waterland@Sun.COM 	 * *********************************************************************
1319*9781SMoriah.Waterland@Sun.COM 	 */
1320*9781SMoriah.Waterland@Sun.COM 
1321*9781SMoriah.Waterland@Sun.COM #ifdef	ALLOW_EXCEPTION_PKG_LIST
1322*9781SMoriah.Waterland@Sun.COM 	else if (exception_pkg(srcinst, LINK)) {
1323*9781SMoriah.Waterland@Sun.COM 		/* Until 2.9, set it from the execption list */
1324*9781SMoriah.Waterland@Sun.COM 		putparam("PKG_NONABI_SYMLINKS", "TRUE");
1325*9781SMoriah.Waterland@Sun.COM 		set_nonABI_symlinks();
1326*9781SMoriah.Waterland@Sun.COM 	}
1327*9781SMoriah.Waterland@Sun.COM #endif
1328*9781SMoriah.Waterland@Sun.COM 	/*
1329*9781SMoriah.Waterland@Sun.COM 	 * At this point, script_in, non_abi_scripts & the environment are
1330*9781SMoriah.Waterland@Sun.COM 	 * all set correctly for the ABI status of the package.
1331*9781SMoriah.Waterland@Sun.COM 	 */
1332*9781SMoriah.Waterland@Sun.COM 
1333*9781SMoriah.Waterland@Sun.COM 	if (pt = getenv("MAXINST")) {
1334*9781SMoriah.Waterland@Sun.COM 		maxinst = atol(pt);
1335*9781SMoriah.Waterland@Sun.COM 	}
1336*9781SMoriah.Waterland@Sun.COM 
1337*9781SMoriah.Waterland@Sun.COM 	/*
1338*9781SMoriah.Waterland@Sun.COM 	 * See if were are installing a package that only wants to update
1339*9781SMoriah.Waterland@Sun.COM 	 * the database or only install files associated with CAS's. We
1340*9781SMoriah.Waterland@Sun.COM 	 * only check the PKG_HOLLOW_VARIABLE variable if told to do so by
1341*9781SMoriah.Waterland@Sun.COM 	 * the caller.
1342*9781SMoriah.Waterland@Sun.COM 	 */
1343*9781SMoriah.Waterland@Sun.COM 
1344*9781SMoriah.Waterland@Sun.COM 	if (is_depend_pkginfo_DB()) {
1345*9781SMoriah.Waterland@Sun.COM 		pt = getenv(PKG_HOLLOW_VARIABLE);
1346*9781SMoriah.Waterland@Sun.COM 		if ((pt != NULL) && (strncasecmp(pt, "true", 4) == 0)) {
1347*9781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_PKGREMOVE_HOLLOW_ENABLED);
1348*9781SMoriah.Waterland@Sun.COM 			if (disableAttributes) {
1349*9781SMoriah.Waterland@Sun.COM 				disable_attribute_check();
1350*9781SMoriah.Waterland@Sun.COM 			}
1351*9781SMoriah.Waterland@Sun.COM 
1352*9781SMoriah.Waterland@Sun.COM 			/*
1353*9781SMoriah.Waterland@Sun.COM 			 * this is a hollow package and hollow package support
1354*9781SMoriah.Waterland@Sun.COM 			 * is enabled -- override admin settings to suppress
1355*9781SMoriah.Waterland@Sun.COM 			 * checks that do not make sense since no scripts will
1356*9781SMoriah.Waterland@Sun.COM 			 * be executed and no files will be installed.
1357*9781SMoriah.Waterland@Sun.COM 			 */
1358*9781SMoriah.Waterland@Sun.COM 
1359*9781SMoriah.Waterland@Sun.COM 			setadminSetting("conflict", "nocheck");
1360*9781SMoriah.Waterland@Sun.COM 			setadminSetting("setuid", "nocheck");
1361*9781SMoriah.Waterland@Sun.COM 			setadminSetting("action", "nocheck");
1362*9781SMoriah.Waterland@Sun.COM 			setadminSetting("partial", "nocheck");
1363*9781SMoriah.Waterland@Sun.COM 			setadminSetting("space", "nocheck");
1364*9781SMoriah.Waterland@Sun.COM 			setadminSetting("authentication", "nocheck");
1365*9781SMoriah.Waterland@Sun.COM 		} else {
1366*9781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_PKGREMOVE_HOLLOW_DISABLED);
1367*9781SMoriah.Waterland@Sun.COM 			set_depend_pkginfo_DB(B_FALSE);
1368*9781SMoriah.Waterland@Sun.COM 		}
1369*9781SMoriah.Waterland@Sun.COM 	}
1370*9781SMoriah.Waterland@Sun.COM 
1371*9781SMoriah.Waterland@Sun.COM 	/*
1372*9781SMoriah.Waterland@Sun.COM 	 * if performing a fresh install to a non-global zone, and doing
1373*9781SMoriah.Waterland@Sun.COM 	 * more than just updating the package database (that is, the
1374*9781SMoriah.Waterland@Sun.COM 	 * package to install is NOT "hollow"), then set the global flag
1375*9781SMoriah.Waterland@Sun.COM 	 * that directs installation is from partially spooled packages
1376*9781SMoriah.Waterland@Sun.COM 	 * (that is, packages installed in the global zone).
1377*9781SMoriah.Waterland@Sun.COM 	 */
1378*9781SMoriah.Waterland@Sun.COM 
1379*9781SMoriah.Waterland@Sun.COM 	if (saveSpoolInstall && (!is_depend_pkginfo_DB())) {
1380*9781SMoriah.Waterland@Sun.COM 		set_partial_inst();
1381*9781SMoriah.Waterland@Sun.COM 	} else {
1382*9781SMoriah.Waterland@Sun.COM 		saveSpoolInstall = 0;
1383*9781SMoriah.Waterland@Sun.COM 	}
1384*9781SMoriah.Waterland@Sun.COM 
1385*9781SMoriah.Waterland@Sun.COM 	/*
1386*9781SMoriah.Waterland@Sun.COM 	 * verify that we are not trying to install an
1387*9781SMoriah.Waterland@Sun.COM 	 * INTONLY package with no interaction
1388*9781SMoriah.Waterland@Sun.COM 	 */
1389*9781SMoriah.Waterland@Sun.COM 
1390*9781SMoriah.Waterland@Sun.COM 	if (pt = getenv("INTONLY")) {
1391*9781SMoriah.Waterland@Sun.COM 		if (askflag || nointeract) {
1392*9781SMoriah.Waterland@Sun.COM 			progerr(ERR_INTONLY, pkgabrv ? pkgabrv : "?");
1393*9781SMoriah.Waterland@Sun.COM 			quit(1);
1394*9781SMoriah.Waterland@Sun.COM 			/*NOTREACHED*/
1395*9781SMoriah.Waterland@Sun.COM 		}
1396*9781SMoriah.Waterland@Sun.COM 	}
1397*9781SMoriah.Waterland@Sun.COM 
1398*9781SMoriah.Waterland@Sun.COM 	if (!suppressCopyright && !pkgdev.cdevice) {
1399*9781SMoriah.Waterland@Sun.COM 		copyright();
1400*9781SMoriah.Waterland@Sun.COM 	}
1401*9781SMoriah.Waterland@Sun.COM 
1402*9781SMoriah.Waterland@Sun.COM 	/*
1403*9781SMoriah.Waterland@Sun.COM 	 * inspect the system to determine if any instances of the
1404*9781SMoriah.Waterland@Sun.COM 	 * package being installed already exist on the system
1405*9781SMoriah.Waterland@Sun.COM 	 */
1406*9781SMoriah.Waterland@Sun.COM 
1407*9781SMoriah.Waterland@Sun.COM 	prvinfo = (struct pkginfo *)calloc(MALSIZ, sizeof (struct pkginfo));
1408*9781SMoriah.Waterland@Sun.COM 	if (prvinfo == NULL) {
1409*9781SMoriah.Waterland@Sun.COM 		progerr(ERR_MEMORY, errno);
1410*9781SMoriah.Waterland@Sun.COM 		quit(99);
1411*9781SMoriah.Waterland@Sun.COM 		/*NOTREACHED*/
1412*9781SMoriah.Waterland@Sun.COM 	}
1413*9781SMoriah.Waterland@Sun.COM 
1414*9781SMoriah.Waterland@Sun.COM 	for (;;) {
1415*9781SMoriah.Waterland@Sun.COM 		if (pkginfo(&prvinfo[npkgs], pkgwild, NULL, NULL)) {
1416*9781SMoriah.Waterland@Sun.COM 			if ((errno == ESRCH) || (errno == ENOENT)) {
1417*9781SMoriah.Waterland@Sun.COM 				break;
1418*9781SMoriah.Waterland@Sun.COM 			}
1419*9781SMoriah.Waterland@Sun.COM 			progerr(ERR_SYSINFO, errno);
1420*9781SMoriah.Waterland@Sun.COM 			quit(99);
1421*9781SMoriah.Waterland@Sun.COM 			/*NOTREACHED*/
1422*9781SMoriah.Waterland@Sun.COM 		}
1423*9781SMoriah.Waterland@Sun.COM 		if ((++npkgs % MALSIZ) == 0) {
1424*9781SMoriah.Waterland@Sun.COM 			prvinfo = (struct pkginfo *)realloc(prvinfo,
1425*9781SMoriah.Waterland@Sun.COM 				(npkgs+MALSIZ) * sizeof (struct pkginfo));
1426*9781SMoriah.Waterland@Sun.COM 			if (prvinfo == NULL) {
1427*9781SMoriah.Waterland@Sun.COM 				progerr(ERR_MEMORY, errno);
1428*9781SMoriah.Waterland@Sun.COM 				quit(99);
1429*9781SMoriah.Waterland@Sun.COM 				/*NOTREACHED*/
1430*9781SMoriah.Waterland@Sun.COM 			}
1431*9781SMoriah.Waterland@Sun.COM 		}
1432*9781SMoriah.Waterland@Sun.COM 	}
1433*9781SMoriah.Waterland@Sun.COM 
1434*9781SMoriah.Waterland@Sun.COM 	/*
1435*9781SMoriah.Waterland@Sun.COM 	 * Determine the correct package instance based on how many packages are
1436*9781SMoriah.Waterland@Sun.COM 	 * already installed. If there are none (npkgs == 0), getinst() just
1437*9781SMoriah.Waterland@Sun.COM 	 * returns the package abbreviation. Otherwise, getinst() interacts with
1438*9781SMoriah.Waterland@Sun.COM 	 * the user (or reads the admin file) to determine if an instance which
1439*9781SMoriah.Waterland@Sun.COM 	 * is already installed should be overwritten, or possibly install a new
1440*9781SMoriah.Waterland@Sun.COM 	 * instance of this package
1441*9781SMoriah.Waterland@Sun.COM 	 */
1442*9781SMoriah.Waterland@Sun.COM 
1443*9781SMoriah.Waterland@Sun.COM 	pkginst = getinst(&update, prvinfo, npkgs, preinstallCheck);
1444*9781SMoriah.Waterland@Sun.COM 
1445*9781SMoriah.Waterland@Sun.COM 	/* set "update flag" if updating an existing instance of this package */
1446*9781SMoriah.Waterland@Sun.COM 
1447*9781SMoriah.Waterland@Sun.COM 	if (update) {
1448*9781SMoriah.Waterland@Sun.COM 		setUpdate();
1449*9781SMoriah.Waterland@Sun.COM 	}
1450*9781SMoriah.Waterland@Sun.COM 
1451*9781SMoriah.Waterland@Sun.COM 	/*
1452*9781SMoriah.Waterland@Sun.COM 	 * Need to force UPDATE to be NULL in case a patch has been applied
1453*9781SMoriah.Waterland@Sun.COM 	 * before creating a zone. Some pkgs (SUNWcsr) already spooled
1454*9781SMoriah.Waterland@Sun.COM 	 * to the zone, check the value of UPDATE in their postinstall script.
1455*9781SMoriah.Waterland@Sun.COM 	 * After a pkg has been patched UPDATE exists statically in the
1456*9781SMoriah.Waterland@Sun.COM 	 * pkginfo file and this value must be reset when installing a zone.
1457*9781SMoriah.Waterland@Sun.COM 	 */
1458*9781SMoriah.Waterland@Sun.COM 
1459*9781SMoriah.Waterland@Sun.COM 	if (saveSpoolInstall != 0 && !isPatchUpdate() && !isUpdate()) {
1460*9781SMoriah.Waterland@Sun.COM 		putparam("UPDATE", "");
1461*9781SMoriah.Waterland@Sun.COM 	}
1462*9781SMoriah.Waterland@Sun.COM 
1463*9781SMoriah.Waterland@Sun.COM 	/* inform quit() if updating existing or installing new instance */
1464*9781SMoriah.Waterland@Sun.COM 
1465*9781SMoriah.Waterland@Sun.COM 	quitSetUpdatingExisting(update ? B_TRUE : B_FALSE);
1466*9781SMoriah.Waterland@Sun.COM 
1467*9781SMoriah.Waterland@Sun.COM 	if (respfile) {
1468*9781SMoriah.Waterland@Sun.COM 		(void) set_respfile(respfile, pkginst, RESP_RO);
1469*9781SMoriah.Waterland@Sun.COM 	}
1470*9781SMoriah.Waterland@Sun.COM 
1471*9781SMoriah.Waterland@Sun.COM 	(void) snprintf(pkgloc, sizeof (pkgloc),
1472*9781SMoriah.Waterland@Sun.COM 			"%s/%s", get_PKGLOC(), pkginst);
1473*9781SMoriah.Waterland@Sun.COM 
1474*9781SMoriah.Waterland@Sun.COM 	(void) snprintf(pkgbin, sizeof (pkgbin),
1475*9781SMoriah.Waterland@Sun.COM 			"%s/install", pkgloc);
1476*9781SMoriah.Waterland@Sun.COM 
1477*9781SMoriah.Waterland@Sun.COM 	(void) snprintf(pkgsav, sizeof (pkgsav),
1478*9781SMoriah.Waterland@Sun.COM 			"%s/save", pkgloc);
1479*9781SMoriah.Waterland@Sun.COM 
1480*9781SMoriah.Waterland@Sun.COM 	if (snprintf(saveSpoolInstallDir, PATH_MAX, "%s/pspool/%s", pkgsav,
1481*9781SMoriah.Waterland@Sun.COM 			pkginst) < 0) {
1482*9781SMoriah.Waterland@Sun.COM 		progerr(ERR_SNPRINTF, saveSpoolInstallDir);
1483*9781SMoriah.Waterland@Sun.COM 		quit(99);
1484*9781SMoriah.Waterland@Sun.COM 		/*NOTREACHED*/
1485*9781SMoriah.Waterland@Sun.COM 	}
1486*9781SMoriah.Waterland@Sun.COM 
1487*9781SMoriah.Waterland@Sun.COM 	(void) snprintf(ilockfile, sizeof (ilockfile),
1488*9781SMoriah.Waterland@Sun.COM 			"%s/!I-Lock!", pkgloc);
1489*9781SMoriah.Waterland@Sun.COM 	(void) snprintf(rlockfile, sizeof (rlockfile),
1490*9781SMoriah.Waterland@Sun.COM 			"%s/!R-Lock!", pkgloc);
1491*9781SMoriah.Waterland@Sun.COM 	(void) snprintf(savlog, sizeof (savlog),
1492*9781SMoriah.Waterland@Sun.COM 			"%s/logs/%s", get_PKGADM(), pkginst);
1493*9781SMoriah.Waterland@Sun.COM 
1494*9781SMoriah.Waterland@Sun.COM 	putparam("PKGINST", pkginst);
1495*9781SMoriah.Waterland@Sun.COM 	putparam("PKGSAV", pkgsav);
1496*9781SMoriah.Waterland@Sun.COM 
1497*9781SMoriah.Waterland@Sun.COM 	/*
1498*9781SMoriah.Waterland@Sun.COM 	 * Be sure request script has access to PKG_INSTALL_ROOT if there is
1499*9781SMoriah.Waterland@Sun.COM 	 * one
1500*9781SMoriah.Waterland@Sun.COM 	 */
1501*9781SMoriah.Waterland@Sun.COM 
1502*9781SMoriah.Waterland@Sun.COM 	put_path_params();
1503*9781SMoriah.Waterland@Sun.COM 
1504*9781SMoriah.Waterland@Sun.COM 	if (!map_client) {
1505*9781SMoriah.Waterland@Sun.COM 		putparam("PKG_NO_UNIFIED", "TRUE");
1506*9781SMoriah.Waterland@Sun.COM 	}
1507*9781SMoriah.Waterland@Sun.COM 
1508*9781SMoriah.Waterland@Sun.COM 	/*
1509*9781SMoriah.Waterland@Sun.COM 	 * This maps the client filesystems into the server's space.
1510*9781SMoriah.Waterland@Sun.COM 	 */
1511*9781SMoriah.Waterland@Sun.COM 
1512*9781SMoriah.Waterland@Sun.COM 	if (map_client && !mount_client()) {
1513*9781SMoriah.Waterland@Sun.COM 		logerr(MSG_MANMOUNT);
1514*9781SMoriah.Waterland@Sun.COM 	}
1515*9781SMoriah.Waterland@Sun.COM 
1516*9781SMoriah.Waterland@Sun.COM 	/*
1517*9781SMoriah.Waterland@Sun.COM 	 * If this is an UPDATE then either this is exactly the same version
1518*9781SMoriah.Waterland@Sun.COM 	 * and architecture of an installed package or a different package is
1519*9781SMoriah.Waterland@Sun.COM 	 * intended to entirely replace an installed package of the same name
1520*9781SMoriah.Waterland@Sun.COM 	 * with a different VERSION or ARCH string.
1521*9781SMoriah.Waterland@Sun.COM 	 * Don't merge any databases if only gathering dependencies.
1522*9781SMoriah.Waterland@Sun.COM 	 */
1523*9781SMoriah.Waterland@Sun.COM 
1524*9781SMoriah.Waterland@Sun.COM 	if ((preinstallCheck == B_FALSE) && (update)) {
1525*9781SMoriah.Waterland@Sun.COM 		/*
1526*9781SMoriah.Waterland@Sun.COM 		 * If this version and architecture is already installed,
1527*9781SMoriah.Waterland@Sun.COM 		 * merge the installed and installing parameters and inform
1528*9781SMoriah.Waterland@Sun.COM 		 * all procedure scripts by defining UPDATE in the
1529*9781SMoriah.Waterland@Sun.COM 		 * environment.
1530*9781SMoriah.Waterland@Sun.COM 		 */
1531*9781SMoriah.Waterland@Sun.COM 
1532*9781SMoriah.Waterland@Sun.COM 		if (is_samepkg()) {
1533*9781SMoriah.Waterland@Sun.COM 			/*
1534*9781SMoriah.Waterland@Sun.COM 			 * If it's the same ARCH and VERSION, then a merge
1535*9781SMoriah.Waterland@Sun.COM 			 * and copy operation is necessary.
1536*9781SMoriah.Waterland@Sun.COM 			 */
1537*9781SMoriah.Waterland@Sun.COM 
1538*9781SMoriah.Waterland@Sun.COM 			if (n = merg_pkginfos(pclass, &mergd_pclass)) {
1539*9781SMoriah.Waterland@Sun.COM 				quit(n);
1540*9781SMoriah.Waterland@Sun.COM 				/*NOTREACHED*/
1541*9781SMoriah.Waterland@Sun.COM 			}
1542*9781SMoriah.Waterland@Sun.COM 
1543*9781SMoriah.Waterland@Sun.COM 			if (n = cp_pkgdirs()) {
1544*9781SMoriah.Waterland@Sun.COM 				quit(n);
1545*9781SMoriah.Waterland@Sun.COM 				/*NOTREACHED*/
1546*9781SMoriah.Waterland@Sun.COM 			}
1547*9781SMoriah.Waterland@Sun.COM 
1548*9781SMoriah.Waterland@Sun.COM 		} else {
1549*9781SMoriah.Waterland@Sun.COM 			/*
1550*9781SMoriah.Waterland@Sun.COM 			 * If it's a different ARCH and/or VERSION then this
1551*9781SMoriah.Waterland@Sun.COM 			 * is an "instance=overwrite" situation. The
1552*9781SMoriah.Waterland@Sun.COM 			 * installed base needs to be confirmed and the
1553*9781SMoriah.Waterland@Sun.COM 			 * package directories renamed.
1554*9781SMoriah.Waterland@Sun.COM 			 */
1555*9781SMoriah.Waterland@Sun.COM 
1556*9781SMoriah.Waterland@Sun.COM 			if (n = ck_instbase()) {
1557*9781SMoriah.Waterland@Sun.COM 				quit(n);
1558*9781SMoriah.Waterland@Sun.COM 				/*NOTREACHED*/
1559*9781SMoriah.Waterland@Sun.COM 			}
1560*9781SMoriah.Waterland@Sun.COM 
1561*9781SMoriah.Waterland@Sun.COM 			if (n = mv_pkgdirs()) {
1562*9781SMoriah.Waterland@Sun.COM 				quit(n);
1563*9781SMoriah.Waterland@Sun.COM 				/*NOTREACHED*/
1564*9781SMoriah.Waterland@Sun.COM 			}
1565*9781SMoriah.Waterland@Sun.COM 		}
1566*9781SMoriah.Waterland@Sun.COM 
1567*9781SMoriah.Waterland@Sun.COM 		putparam("UPDATE", "yes");
1568*9781SMoriah.Waterland@Sun.COM 
1569*9781SMoriah.Waterland@Sun.COM 	}
1570*9781SMoriah.Waterland@Sun.COM 
1571*9781SMoriah.Waterland@Sun.COM 	if (in_dryrun_mode()) {
1572*9781SMoriah.Waterland@Sun.COM 		set_dryrun_dir_loc();
1573*9781SMoriah.Waterland@Sun.COM 	}
1574*9781SMoriah.Waterland@Sun.COM 
1575*9781SMoriah.Waterland@Sun.COM 	if (preinstallCheck == B_FALSE) {
1576*9781SMoriah.Waterland@Sun.COM 		/*
1577*9781SMoriah.Waterland@Sun.COM 		 * Determine if the package has been partially installed on or
1578*9781SMoriah.Waterland@Sun.COM 		 * removed from this system.
1579*9781SMoriah.Waterland@Sun.COM 		 */
1580*9781SMoriah.Waterland@Sun.COM 		ck_w_dryrun(ckpartial, PARTIAL);
1581*9781SMoriah.Waterland@Sun.COM 
1582*9781SMoriah.Waterland@Sun.COM 		/*
1583*9781SMoriah.Waterland@Sun.COM 		 * make sure current runlevel is appropriate
1584*9781SMoriah.Waterland@Sun.COM 		 */
1585*9781SMoriah.Waterland@Sun.COM 		ck_w_dryrun(ckrunlevel, RUNLEVEL);
1586*9781SMoriah.Waterland@Sun.COM 	} else {
1587*9781SMoriah.Waterland@Sun.COM 		int	r;
1588*9781SMoriah.Waterland@Sun.COM 
1589*9781SMoriah.Waterland@Sun.COM 		/*
1590*9781SMoriah.Waterland@Sun.COM 		 * Just gathering dependencies - determine if the package has
1591*9781SMoriah.Waterland@Sun.COM 		 * been partially installed on or removed from this system and
1592*9781SMoriah.Waterland@Sun.COM 		 * output information to stdout
1593*9781SMoriah.Waterland@Sun.COM 		 */
1594*9781SMoriah.Waterland@Sun.COM 		r = ckpartial();
1595*9781SMoriah.Waterland@Sun.COM 		(void) fprintf(stdout, "ckpartialinstall=%d\n", r == 8 ? 1 : 0);
1596*9781SMoriah.Waterland@Sun.COM 		(void) fprintf(stdout, "ckpartialremove=%d\n", r == 9 ? 1 : 0);
1597*9781SMoriah.Waterland@Sun.COM 
1598*9781SMoriah.Waterland@Sun.COM 		/*
1599*9781SMoriah.Waterland@Sun.COM 		 * make sure current runlevel is appropriate
1600*9781SMoriah.Waterland@Sun.COM 		 */
1601*9781SMoriah.Waterland@Sun.COM 		r = ckrunlevel();
1602*9781SMoriah.Waterland@Sun.COM 		(void) fprintf(stdout, "ckrunlevel=%d\n", r);
1603*9781SMoriah.Waterland@Sun.COM 	}
1604*9781SMoriah.Waterland@Sun.COM 
1605*9781SMoriah.Waterland@Sun.COM 	if (pkgdev.cdevice) {
1606*9781SMoriah.Waterland@Sun.COM 		/* get first volume which contains info files */
1607*9781SMoriah.Waterland@Sun.COM 		unpack();
1608*9781SMoriah.Waterland@Sun.COM 		if (!suppressCopyright) {
1609*9781SMoriah.Waterland@Sun.COM 			copyright();
1610*9781SMoriah.Waterland@Sun.COM 		}
1611*9781SMoriah.Waterland@Sun.COM 	}
1612*9781SMoriah.Waterland@Sun.COM 
1613*9781SMoriah.Waterland@Sun.COM 	/* update the lock - at the request script */
1614*9781SMoriah.Waterland@Sun.COM 
1615*9781SMoriah.Waterland@Sun.COM 	lockupd("request");
1616*9781SMoriah.Waterland@Sun.COM 
1617*9781SMoriah.Waterland@Sun.COM 	/*
1618*9781SMoriah.Waterland@Sun.COM 	 * If no response file has been provided, initialize response file by
1619*9781SMoriah.Waterland@Sun.COM 	 * executing any request script provided by this package. Initialize
1620*9781SMoriah.Waterland@Sun.COM 	 * the response file if not gathering dependencies only.
1621*9781SMoriah.Waterland@Sun.COM 	 */
1622*9781SMoriah.Waterland@Sun.COM 
1623*9781SMoriah.Waterland@Sun.COM 	if ((!rdonly_respfile()) && (preinstallCheck == B_FALSE)) {
1624*9781SMoriah.Waterland@Sun.COM 		(void) snprintf(path, sizeof (path),
1625*9781SMoriah.Waterland@Sun.COM 			"%s/%s", instdir, REQUEST_FILE);
1626*9781SMoriah.Waterland@Sun.COM 		n = reqexec(update, path, non_abi_scripts,
1627*9781SMoriah.Waterland@Sun.COM 			run_request_as_root);
1628*9781SMoriah.Waterland@Sun.COM 		if (in_dryrun_mode()) {
1629*9781SMoriah.Waterland@Sun.COM 			set_dr_info(REQUESTEXITCODE, n);
1630*9781SMoriah.Waterland@Sun.COM 		}
1631*9781SMoriah.Waterland@Sun.COM 
1632*9781SMoriah.Waterland@Sun.COM 		ckreturn(n, ERR_REQUEST);
1633*9781SMoriah.Waterland@Sun.COM 	}
1634*9781SMoriah.Waterland@Sun.COM 
1635*9781SMoriah.Waterland@Sun.COM 	/*
1636*9781SMoriah.Waterland@Sun.COM 	 * Look for all parameters in response file which begin with a
1637*9781SMoriah.Waterland@Sun.COM 	 * capital letter, and place them in the environment.
1638*9781SMoriah.Waterland@Sun.COM 	 */
1639*9781SMoriah.Waterland@Sun.COM 
1640*9781SMoriah.Waterland@Sun.COM 	if ((is_a_respfile()) && (preinstallCheck == B_FALSE)) {
1641*9781SMoriah.Waterland@Sun.COM 		if (n = merg_respfile()) {
1642*9781SMoriah.Waterland@Sun.COM 			quit(n);
1643*9781SMoriah.Waterland@Sun.COM 			/*NOTREACHED*/
1644*9781SMoriah.Waterland@Sun.COM 		}
1645*9781SMoriah.Waterland@Sun.COM 	}
1646*9781SMoriah.Waterland@Sun.COM 
1647*9781SMoriah.Waterland@Sun.COM 	/*
1648*9781SMoriah.Waterland@Sun.COM 	 * Run a checkinstall script if one is provided by the package.
1649*9781SMoriah.Waterland@Sun.COM 	 * Don't execute checkinstall script if we are only updating the DB.
1650*9781SMoriah.Waterland@Sun.COM 	 * Don't execute checkinstall script if only gathering dependencies.
1651*9781SMoriah.Waterland@Sun.COM 	 */
1652*9781SMoriah.Waterland@Sun.COM 
1653*9781SMoriah.Waterland@Sun.COM 	/* update the lock - at the checkinstall script */
1654*9781SMoriah.Waterland@Sun.COM 	lockupd("checkinstall");
1655*9781SMoriah.Waterland@Sun.COM 
1656*9781SMoriah.Waterland@Sun.COM 	/* Execute checkinstall script if one is provided. */
1657*9781SMoriah.Waterland@Sun.COM 	(void) snprintf(script, sizeof (script), "%s/install/checkinstall",
1658*9781SMoriah.Waterland@Sun.COM 			instdir);
1659*9781SMoriah.Waterland@Sun.COM 	if (access(script, F_OK) != 0) {
1660*9781SMoriah.Waterland@Sun.COM 		/* no script present */
1661*9781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_PKGINSTALL_COC_NONE, pkginst, script,
1662*9781SMoriah.Waterland@Sun.COM 			zoneName ? zoneName : "global");
1663*9781SMoriah.Waterland@Sun.COM 	} else if (is_depend_pkginfo_DB()) {
1664*9781SMoriah.Waterland@Sun.COM 		/* updating db only: skip checkinstall script */
1665*9781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_PKGINSTALL_COC_DBUPD, pkginst, script,
1666*9781SMoriah.Waterland@Sun.COM 			zoneName ? zoneName : "global");
1667*9781SMoriah.Waterland@Sun.COM 	} else if (preinstallCheck == B_TRUE) {
1668*9781SMoriah.Waterland@Sun.COM 		/* only gathering dependencies: skip checkinstall script */
1669*9781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_PKGINSTALL_COC_NODEL, pkginst, script,
1670*9781SMoriah.Waterland@Sun.COM 			zoneName ? zoneName : "global");
1671*9781SMoriah.Waterland@Sun.COM 	} else {
1672*9781SMoriah.Waterland@Sun.COM 		/* script present and ok to run: run the script */
1673*9781SMoriah.Waterland@Sun.COM 		if (zoneName == (char *)NULL) {
1674*9781SMoriah.Waterland@Sun.COM 			echo(MSG_PKGINSTALL_EXECOC_GZ);
1675*9781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_PKGINSTALL_EXECOC_GZ, pkginst, script);
1676*9781SMoriah.Waterland@Sun.COM 		} else {
1677*9781SMoriah.Waterland@Sun.COM 			echo(MSG_PKGINSTALL_EXECOC_LZ, zoneName);
1678*9781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_PKGINSTALL_EXECOC_LZ, pkginst, script,
1679*9781SMoriah.Waterland@Sun.COM 				zoneName);
1680*9781SMoriah.Waterland@Sun.COM 		}
1681*9781SMoriah.Waterland@Sun.COM 		n = chkexec(update, script);
1682*9781SMoriah.Waterland@Sun.COM 		if (in_dryrun_mode()) {
1683*9781SMoriah.Waterland@Sun.COM 			set_dr_info(CHECKEXITCODE, n);
1684*9781SMoriah.Waterland@Sun.COM 		}
1685*9781SMoriah.Waterland@Sun.COM 
1686*9781SMoriah.Waterland@Sun.COM 		if (n == 3) {
1687*9781SMoriah.Waterland@Sun.COM 			echo(WRN_CHKINSTALL);
1688*9781SMoriah.Waterland@Sun.COM 			ckreturn(4, NULL);
1689*9781SMoriah.Waterland@Sun.COM 		} else if (n == 7) {
1690*9781SMoriah.Waterland@Sun.COM 			/* access returned error */
1691*9781SMoriah.Waterland@Sun.COM 			progerr(ERR_CHKINSTALL_NOSCRIPT, script);
1692*9781SMoriah.Waterland@Sun.COM 			ckreturn(4, ERR_CHKINSTALL);
1693*9781SMoriah.Waterland@Sun.COM 		} else {
1694*9781SMoriah.Waterland@Sun.COM 			ckreturn(n, ERR_CHKINSTALL);
1695*9781SMoriah.Waterland@Sun.COM 		}
1696*9781SMoriah.Waterland@Sun.COM 	}
1697*9781SMoriah.Waterland@Sun.COM 
1698*9781SMoriah.Waterland@Sun.COM 	/*
1699*9781SMoriah.Waterland@Sun.COM 	 * Now that the internal data structures are initialized, we can
1700*9781SMoriah.Waterland@Sun.COM 	 * initialize the dryrun files (which may be the same files).
1701*9781SMoriah.Waterland@Sun.COM 	 */
1702*9781SMoriah.Waterland@Sun.COM 
1703*9781SMoriah.Waterland@Sun.COM 	if (pkgdrtarg) {
1704*9781SMoriah.Waterland@Sun.COM 		init_dryrunfile(pkgdrtarg);
1705*9781SMoriah.Waterland@Sun.COM 	}
1706*9781SMoriah.Waterland@Sun.COM 
1707*9781SMoriah.Waterland@Sun.COM 	/*
1708*9781SMoriah.Waterland@Sun.COM 	 * Look for all parameters in response file which begin with a
1709*9781SMoriah.Waterland@Sun.COM 	 * capital letter, and place them in the environment.
1710*9781SMoriah.Waterland@Sun.COM 	 */
1711*9781SMoriah.Waterland@Sun.COM 	if (is_a_respfile()) {
1712*9781SMoriah.Waterland@Sun.COM 		if (n = merg_respfile()) {
1713*9781SMoriah.Waterland@Sun.COM 			quit(n);
1714*9781SMoriah.Waterland@Sun.COM 			/*NOTREACHED*/
1715*9781SMoriah.Waterland@Sun.COM 		}
1716*9781SMoriah.Waterland@Sun.COM 	}
1717*9781SMoriah.Waterland@Sun.COM 
1718*9781SMoriah.Waterland@Sun.COM 	/* update the lock - doing analysis */
1719*9781SMoriah.Waterland@Sun.COM 
1720*9781SMoriah.Waterland@Sun.COM 	lockupd("analysis");
1721*9781SMoriah.Waterland@Sun.COM 
1722*9781SMoriah.Waterland@Sun.COM 	/*
1723*9781SMoriah.Waterland@Sun.COM 	 * Determine package base directory and client base directory
1724*9781SMoriah.Waterland@Sun.COM 	 * if appropriate. Then encapsulate them for future retrieval.
1725*9781SMoriah.Waterland@Sun.COM 	 */
1726*9781SMoriah.Waterland@Sun.COM 	if ((err = set_basedirs(isreloc(instdir), adm.basedir, pkginst,
1727*9781SMoriah.Waterland@Sun.COM 		nointeract)) != 0) {
1728*9781SMoriah.Waterland@Sun.COM 		quit(err);
1729*9781SMoriah.Waterland@Sun.COM 		/*NOTREACHED*/
1730*9781SMoriah.Waterland@Sun.COM 	}
1731*9781SMoriah.Waterland@Sun.COM 
1732*9781SMoriah.Waterland@Sun.COM 	/*
1733*9781SMoriah.Waterland@Sun.COM 	 * Create the base directory if specified.
1734*9781SMoriah.Waterland@Sun.COM 	 * Don't create if we are only updating the DB.
1735*9781SMoriah.Waterland@Sun.COM 	 * Don't create if only gathering dependencies.
1736*9781SMoriah.Waterland@Sun.COM 	 */
1737*9781SMoriah.Waterland@Sun.COM 
1738*9781SMoriah.Waterland@Sun.COM 	if (!is_depend_pkginfo_DB() &&
1739*9781SMoriah.Waterland@Sun.COM 		!preinstallCheck && is_a_basedir()) {
1740*9781SMoriah.Waterland@Sun.COM 		mkbasedir(!nointeract, get_basedir());
1741*9781SMoriah.Waterland@Sun.COM 		echo(MSG_BASE_USED, get_basedir());
1742*9781SMoriah.Waterland@Sun.COM 	}
1743*9781SMoriah.Waterland@Sun.COM 
1744*9781SMoriah.Waterland@Sun.COM 	/*
1745*9781SMoriah.Waterland@Sun.COM 	 * Store PKG_INSTALL_ROOT, BASEDIR & CLIENT_BASEDIR in our
1746*9781SMoriah.Waterland@Sun.COM 	 * environment for later use by procedure scripts.
1747*9781SMoriah.Waterland@Sun.COM 	 */
1748*9781SMoriah.Waterland@Sun.COM 	put_path_params();
1749*9781SMoriah.Waterland@Sun.COM 
1750*9781SMoriah.Waterland@Sun.COM 	/*
1751*9781SMoriah.Waterland@Sun.COM 	 * the following two checks are done in the corresponding
1752*9781SMoriah.Waterland@Sun.COM 	 * ck() routine, but are repeated here to avoid re-processing
1753*9781SMoriah.Waterland@Sun.COM 	 * the database if we are administered to not include these
1754*9781SMoriah.Waterland@Sun.COM 	 * processes
1755*9781SMoriah.Waterland@Sun.COM 	 */
1756*9781SMoriah.Waterland@Sun.COM 	if (ADM(setuid, "nochange")) {
1757*9781SMoriah.Waterland@Sun.COM 		nosetuid++;	/* Clear setuid/gid bits. */
1758*9781SMoriah.Waterland@Sun.COM 	}
1759*9781SMoriah.Waterland@Sun.COM 
1760*9781SMoriah.Waterland@Sun.COM 	if (ADM(conflict, "nochange")) {
1761*9781SMoriah.Waterland@Sun.COM 		nocnflct++;	/* Don't install conflicting files. */
1762*9781SMoriah.Waterland@Sun.COM 	}
1763*9781SMoriah.Waterland@Sun.COM 
1764*9781SMoriah.Waterland@Sun.COM 	/*
1765*9781SMoriah.Waterland@Sun.COM 	 * Get the filesystem space information for the filesystem on which
1766*9781SMoriah.Waterland@Sun.COM 	 * the "contents" file resides.
1767*9781SMoriah.Waterland@Sun.COM 	 */
1768*9781SMoriah.Waterland@Sun.COM 
1769*9781SMoriah.Waterland@Sun.COM 	svfsb.f_bsize = 8192;
1770*9781SMoriah.Waterland@Sun.COM 	svfsb.f_frsize = 1024;
1771*9781SMoriah.Waterland@Sun.COM 
1772*9781SMoriah.Waterland@Sun.COM 	if (statvfs64(get_PKGADM(), &svfsb) == -1) {
1773*9781SMoriah.Waterland@Sun.COM 		int	lerrno = errno;
1774*9781SMoriah.Waterland@Sun.COM 		if (!access(get_PKGADM(), F_OK)) {
1775*9781SMoriah.Waterland@Sun.COM 			progerr(ERR_PKGINSTALL_STATVFS, get_PKGADM(),
1776*9781SMoriah.Waterland@Sun.COM 				strerror(errno));
1777*9781SMoriah.Waterland@Sun.COM 			logerr("(errno %d)", lerrno);
1778*9781SMoriah.Waterland@Sun.COM 			quit(99);
1779*9781SMoriah.Waterland@Sun.COM 			/*NOTREACHED*/
1780*9781SMoriah.Waterland@Sun.COM 		}
1781*9781SMoriah.Waterland@Sun.COM 	}
1782*9781SMoriah.Waterland@Sun.COM 
1783*9781SMoriah.Waterland@Sun.COM 	/*
1784*9781SMoriah.Waterland@Sun.COM 	 * Get the number of blocks used by the pkgmap, ocfile()
1785*9781SMoriah.Waterland@Sun.COM 	 * needs this to properly determine its space requirements.
1786*9781SMoriah.Waterland@Sun.COM 	 */
1787*9781SMoriah.Waterland@Sun.COM 
1788*9781SMoriah.Waterland@Sun.COM 	if (stat(p_pkgmap, &statb) == -1) {
1789*9781SMoriah.Waterland@Sun.COM 		progerr(ERR_PKGINSTALL_STATOF, p_pkgmap, strerror(errno));
1790*9781SMoriah.Waterland@Sun.COM 		quit(99);
1791*9781SMoriah.Waterland@Sun.COM 		/*NOTREACHED*/
1792*9781SMoriah.Waterland@Sun.COM 	}
1793*9781SMoriah.Waterland@Sun.COM 
1794*9781SMoriah.Waterland@Sun.COM 	pkgmap_blks = nblk(statb.st_size, svfsb.f_bsize, svfsb.f_frsize);
1795*9781SMoriah.Waterland@Sun.COM 
1796*9781SMoriah.Waterland@Sun.COM 	/*
1797*9781SMoriah.Waterland@Sun.COM 	 * Merge information in memory with the "contents" file; this creates
1798*9781SMoriah.Waterland@Sun.COM 	 * a temporary version of the "contents" file. Note that in dryrun
1799*9781SMoriah.Waterland@Sun.COM 	 * mode, we still need to record the contents file data somewhere,
1800*9781SMoriah.Waterland@Sun.COM 	 * but we do it in the dryrun directory.
1801*9781SMoriah.Waterland@Sun.COM 	 */
1802*9781SMoriah.Waterland@Sun.COM 
1803*9781SMoriah.Waterland@Sun.COM 	if (in_dryrun_mode()) {
1804*9781SMoriah.Waterland@Sun.COM 		if (n = set_cfdir(pkgdrtarg)) {
1805*9781SMoriah.Waterland@Sun.COM 			quit(n);
1806*9781SMoriah.Waterland@Sun.COM 			/*NOTREACHED*/
1807*9781SMoriah.Waterland@Sun.COM 		}
1808*9781SMoriah.Waterland@Sun.COM 	} else {
1809*9781SMoriah.Waterland@Sun.COM 		if (n = set_cfdir(NULL)) {
1810*9781SMoriah.Waterland@Sun.COM 			quit(n);
1811*9781SMoriah.Waterland@Sun.COM 			/*NOTREACHED*/
1812*9781SMoriah.Waterland@Sun.COM 		}
1813*9781SMoriah.Waterland@Sun.COM 	}
1814*9781SMoriah.Waterland@Sun.COM 	if (!ocfile(&cfVfp, &cfTmpVfp, pkgmap_blks)) {
1815*9781SMoriah.Waterland@Sun.COM 		quit(99);
1816*9781SMoriah.Waterland@Sun.COM 		/*NOTREACHED*/
1817*9781SMoriah.Waterland@Sun.COM 	}
1818*9781SMoriah.Waterland@Sun.COM 
1819*9781SMoriah.Waterland@Sun.COM 	/*
1820*9781SMoriah.Waterland@Sun.COM 	 * if cpio is being used,  tell pkgdbmerg since attributes will
1821*9781SMoriah.Waterland@Sun.COM 	 * have to be check and repaired on all file and directories
1822*9781SMoriah.Waterland@Sun.COM 	 */
1823*9781SMoriah.Waterland@Sun.COM 	for (np = cpio_names; *np != NULL; np++) {
1824*9781SMoriah.Waterland@Sun.COM 		(void) snprintf(path, sizeof (path),
1825*9781SMoriah.Waterland@Sun.COM 			"%s/%s", instdir, *np);
1826*9781SMoriah.Waterland@Sun.COM 		if (iscpio(path, &is_comp_arch)) {
1827*9781SMoriah.Waterland@Sun.COM 			is_WOS_arch();
1828*9781SMoriah.Waterland@Sun.COM 			break;
1829*9781SMoriah.Waterland@Sun.COM 		}
1830*9781SMoriah.Waterland@Sun.COM 	}
1831*9781SMoriah.Waterland@Sun.COM 
1832*9781SMoriah.Waterland@Sun.COM 	/* Establish the class list and the class attributes. */
1833*9781SMoriah.Waterland@Sun.COM 	cl_sets(getenv("CLASSES"));
1834*9781SMoriah.Waterland@Sun.COM 	find_CAS(I_ONLY, pkgbin, instdir);
1835*9781SMoriah.Waterland@Sun.COM 
1836*9781SMoriah.Waterland@Sun.COM 	if (vfpOpen(&pkgmapVfp, p_pkgmap, "r", VFP_NEEDNOW) != 0) {
1837*9781SMoriah.Waterland@Sun.COM 		progerr(ERR_PKGMAP, p_pkgmap);
1838*9781SMoriah.Waterland@Sun.COM 		quit(99);
1839*9781SMoriah.Waterland@Sun.COM 		/*NOTREACHED*/
1840*9781SMoriah.Waterland@Sun.COM 	}
1841*9781SMoriah.Waterland@Sun.COM 
1842*9781SMoriah.Waterland@Sun.COM 	/*
1843*9781SMoriah.Waterland@Sun.COM 	 * This modifies the path list entries in memory to reflect
1844*9781SMoriah.Waterland@Sun.COM 	 * how they should look after the merg is complete
1845*9781SMoriah.Waterland@Sun.COM 	 */
1846*9781SMoriah.Waterland@Sun.COM 
1847*9781SMoriah.Waterland@Sun.COM 	nparts = sortmap(&extlist, pkgmapVfp, cfVfp, cfTmpVfp, zoneName);
1848*9781SMoriah.Waterland@Sun.COM 
1849*9781SMoriah.Waterland@Sun.COM 	if ((n = files_installed()) > 0) {
1850*9781SMoriah.Waterland@Sun.COM 		if (n > 1) {
1851*9781SMoriah.Waterland@Sun.COM 			echo(MSG_INST_MANY, n);
1852*9781SMoriah.Waterland@Sun.COM 		} else {
1853*9781SMoriah.Waterland@Sun.COM 			echo(MSG_INST_ONE, n);
1854*9781SMoriah.Waterland@Sun.COM 		}
1855*9781SMoriah.Waterland@Sun.COM 	}
1856*9781SMoriah.Waterland@Sun.COM 
1857*9781SMoriah.Waterland@Sun.COM 	/*
1858*9781SMoriah.Waterland@Sun.COM 	 * Check ulimit requirement (provided in pkginfo). The purpose of
1859*9781SMoriah.Waterland@Sun.COM 	 * this limit is to terminate pathological file growth resulting from
1860*9781SMoriah.Waterland@Sun.COM 	 * file edits in scripts. It does not apply to files in the pkgmap
1861*9781SMoriah.Waterland@Sun.COM 	 * and it does not apply to any database files manipulated by the
1862*9781SMoriah.Waterland@Sun.COM 	 * installation service.
1863*9781SMoriah.Waterland@Sun.COM 	 */
1864*9781SMoriah.Waterland@Sun.COM 	if (pt = getenv("ULIMIT")) {
1865*9781SMoriah.Waterland@Sun.COM 		if (assign_ulimit(pt) == -1) {
1866*9781SMoriah.Waterland@Sun.COM 			progerr(ERR_BADULIMIT, pt);
1867*9781SMoriah.Waterland@Sun.COM 			quit(99);
1868*9781SMoriah.Waterland@Sun.COM 			/*NOTREACHED*/
1869*9781SMoriah.Waterland@Sun.COM 		}
1870*9781SMoriah.Waterland@Sun.COM 		putparam("PKG_ULIMIT", "TRUE");
1871*9781SMoriah.Waterland@Sun.COM 	}
1872*9781SMoriah.Waterland@Sun.COM 
1873*9781SMoriah.Waterland@Sun.COM 	/*
1874*9781SMoriah.Waterland@Sun.COM 	 * If only gathering dependencies, check and output status of all
1875*9781SMoriah.Waterland@Sun.COM 	 * remaining dependencies and exit.
1876*9781SMoriah.Waterland@Sun.COM 	 */
1877*9781SMoriah.Waterland@Sun.COM 
1878*9781SMoriah.Waterland@Sun.COM 	if (preinstallCheck == B_TRUE) {
1879*9781SMoriah.Waterland@Sun.COM 		/* update the lock file - final checking */
1880*9781SMoriah.Waterland@Sun.COM 
1881*9781SMoriah.Waterland@Sun.COM 		lockupd("preinstallcheck");
1882*9781SMoriah.Waterland@Sun.COM 
1883*9781SMoriah.Waterland@Sun.COM 		/* verify package information files are not corrupt */
1884*9781SMoriah.Waterland@Sun.COM 
1885*9781SMoriah.Waterland@Sun.COM 		(void) fprintf(stdout, "ckpkgfiles=%d\n", ckpkgfiles());
1886*9781SMoriah.Waterland@Sun.COM 
1887*9781SMoriah.Waterland@Sun.COM 		/* verify package dependencies */
1888*9781SMoriah.Waterland@Sun.COM 
1889*9781SMoriah.Waterland@Sun.COM 		(void) fprintf(stdout, "ckdepend=%d\n", ckdepend());
1890*9781SMoriah.Waterland@Sun.COM 
1891*9781SMoriah.Waterland@Sun.COM 		/* Check space requirements */
1892*9781SMoriah.Waterland@Sun.COM 
1893*9781SMoriah.Waterland@Sun.COM 		(void) fprintf(stdout, "ckspace=%d\n", ckspace());
1894*9781SMoriah.Waterland@Sun.COM 
1895*9781SMoriah.Waterland@Sun.COM 		/*
1896*9781SMoriah.Waterland@Sun.COM 		 * Determine if any objects provided by this package conflict
1897*9781SMoriah.Waterland@Sun.COM 		 * with the files of previously installed packages.
1898*9781SMoriah.Waterland@Sun.COM 		 */
1899*9781SMoriah.Waterland@Sun.COM 
1900*9781SMoriah.Waterland@Sun.COM 		(void) fprintf(stdout, "ckconflict=%d\n", ckconflct());
1901*9781SMoriah.Waterland@Sun.COM 
1902*9781SMoriah.Waterland@Sun.COM 		/*
1903*9781SMoriah.Waterland@Sun.COM 		 * Determine if any objects provided by this package will be
1904*9781SMoriah.Waterland@Sun.COM 		 * installed with setuid or setgid enabled.
1905*9781SMoriah.Waterland@Sun.COM 		 */
1906*9781SMoriah.Waterland@Sun.COM 
1907*9781SMoriah.Waterland@Sun.COM 		(void) fprintf(stdout, "cksetuid=%d\n", cksetuid());
1908*9781SMoriah.Waterland@Sun.COM 
1909*9781SMoriah.Waterland@Sun.COM 		/*
1910*9781SMoriah.Waterland@Sun.COM 		 * Determine if any packaging scripts provided with this package
1911*9781SMoriah.Waterland@Sun.COM 		 * will execute as a priviledged user.
1912*9781SMoriah.Waterland@Sun.COM 		 */
1913*9781SMoriah.Waterland@Sun.COM 
1914*9781SMoriah.Waterland@Sun.COM 		(void) fprintf(stdout, "ckpriv=%d\n", ckpriv());
1915*9781SMoriah.Waterland@Sun.COM 
1916*9781SMoriah.Waterland@Sun.COM 		/* Verify neccessary package installation directories exist */
1917*9781SMoriah.Waterland@Sun.COM 
1918*9781SMoriah.Waterland@Sun.COM 		(void) fprintf(stdout, "ckpkgdirs=%d\n", ckpkgdirs());
1919*9781SMoriah.Waterland@Sun.COM 
1920*9781SMoriah.Waterland@Sun.COM 		/*
1921*9781SMoriah.Waterland@Sun.COM 		 * ****** preinstall check done - exit ******
1922*9781SMoriah.Waterland@Sun.COM 		 */
1923*9781SMoriah.Waterland@Sun.COM 
1924*9781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_PKGINSTALL_PREINSCHK_OK);
1925*9781SMoriah.Waterland@Sun.COM 		quit(0);
1926*9781SMoriah.Waterland@Sun.COM 		/*NOTREACHED*/
1927*9781SMoriah.Waterland@Sun.COM 	}
1928*9781SMoriah.Waterland@Sun.COM 
1929*9781SMoriah.Waterland@Sun.COM 	/*
1930*9781SMoriah.Waterland@Sun.COM 	 * Not gathering dependencies only, proceed to check dependencies
1931*9781SMoriah.Waterland@Sun.COM 	 * and continue with the package installation operation.
1932*9781SMoriah.Waterland@Sun.COM 	 */
1933*9781SMoriah.Waterland@Sun.COM 
1934*9781SMoriah.Waterland@Sun.COM 	/*
1935*9781SMoriah.Waterland@Sun.COM 	 * verify package information files are not corrupt
1936*9781SMoriah.Waterland@Sun.COM 	 */
1937*9781SMoriah.Waterland@Sun.COM 	ck_w_dryrun(ckpkgfiles, PKGFILES);
1938*9781SMoriah.Waterland@Sun.COM 
1939*9781SMoriah.Waterland@Sun.COM 	/*
1940*9781SMoriah.Waterland@Sun.COM 	 * verify package dependencies
1941*9781SMoriah.Waterland@Sun.COM 	 */
1942*9781SMoriah.Waterland@Sun.COM 	ck_w_dryrun(ckdepend, DEPEND);
1943*9781SMoriah.Waterland@Sun.COM 
1944*9781SMoriah.Waterland@Sun.COM 	/*
1945*9781SMoriah.Waterland@Sun.COM 	 * Check space requirements.
1946*9781SMoriah.Waterland@Sun.COM 	 */
1947*9781SMoriah.Waterland@Sun.COM 	ck_w_dryrun(ckspace, SPACE);
1948*9781SMoriah.Waterland@Sun.COM 
1949*9781SMoriah.Waterland@Sun.COM 	/*
1950*9781SMoriah.Waterland@Sun.COM 	 * Determine if any objects provided by this package conflict with
1951*9781SMoriah.Waterland@Sun.COM 	 * the files of previously installed packages.
1952*9781SMoriah.Waterland@Sun.COM 	 */
1953*9781SMoriah.Waterland@Sun.COM 	ck_w_dryrun(ckconflct, CONFLICT);
1954*9781SMoriah.Waterland@Sun.COM 
1955*9781SMoriah.Waterland@Sun.COM 	/*
1956*9781SMoriah.Waterland@Sun.COM 	 * Determine if any objects provided by this package will be
1957*9781SMoriah.Waterland@Sun.COM 	 * installed with setuid or setgid enabled.
1958*9781SMoriah.Waterland@Sun.COM 	 */
1959*9781SMoriah.Waterland@Sun.COM 	ck_w_dryrun(cksetuid, SETUID);
1960*9781SMoriah.Waterland@Sun.COM 
1961*9781SMoriah.Waterland@Sun.COM 	/*
1962*9781SMoriah.Waterland@Sun.COM 	 * Determine if any packaging scripts provided with this package will
1963*9781SMoriah.Waterland@Sun.COM 	 * execute as a priviledged user.
1964*9781SMoriah.Waterland@Sun.COM 	 */
1965*9781SMoriah.Waterland@Sun.COM 	ck_w_dryrun(ckpriv, PRIV);
1966*9781SMoriah.Waterland@Sun.COM 
1967*9781SMoriah.Waterland@Sun.COM 	/*
1968*9781SMoriah.Waterland@Sun.COM 	 * Verify neccessary package installation directories exist.
1969*9781SMoriah.Waterland@Sun.COM 	 */
1970*9781SMoriah.Waterland@Sun.COM 	ck_w_dryrun(ckpkgdirs, PKGDIRS);
1971*9781SMoriah.Waterland@Sun.COM 
1972*9781SMoriah.Waterland@Sun.COM 	/*
1973*9781SMoriah.Waterland@Sun.COM 	 * If we have assumed that we were installing setuid or conflicting
1974*9781SMoriah.Waterland@Sun.COM 	 * files, and the user chose to do otherwise, we need to read in the
1975*9781SMoriah.Waterland@Sun.COM 	 * package map again and re-merg with the "contents" file
1976*9781SMoriah.Waterland@Sun.COM 	 */
1977*9781SMoriah.Waterland@Sun.COM 
1978*9781SMoriah.Waterland@Sun.COM 	if (rprcflag) {
1979*9781SMoriah.Waterland@Sun.COM 		nparts = sortmap(&extlist, pkgmapVfp, cfVfp,
1980*9781SMoriah.Waterland@Sun.COM 				cfTmpVfp, zoneName);
1981*9781SMoriah.Waterland@Sun.COM 	}
1982*9781SMoriah.Waterland@Sun.COM 
1983*9781SMoriah.Waterland@Sun.COM 	(void) vfpClose(&pkgmapVfp);
1984*9781SMoriah.Waterland@Sun.COM 
1985*9781SMoriah.Waterland@Sun.COM 	/* BEGIN INSTALLATION PHASE */
1986*9781SMoriah.Waterland@Sun.COM 	if (in_dryrun_mode()) {
1987*9781SMoriah.Waterland@Sun.COM 		echo(MSG_PKGINSTALL_DRYRUN, pkgname, pkginst);
1988*9781SMoriah.Waterland@Sun.COM 	} else if (zoneName == (char *)NULL) {
1989*9781SMoriah.Waterland@Sun.COM 		echo(MSG_PKGINSTALL_INSIN_GZ, pkgname, pkginst);
1990*9781SMoriah.Waterland@Sun.COM 	} else {
1991*9781SMoriah.Waterland@Sun.COM 		echo(MSG_PKGINSTALL_INSIN_LZ, pkgname, pkginst, zoneName);
1992*9781SMoriah.Waterland@Sun.COM 	}
1993*9781SMoriah.Waterland@Sun.COM 
1994*9781SMoriah.Waterland@Sun.COM 	/* inform quit that the install has started */
1995*9781SMoriah.Waterland@Sun.COM 
1996*9781SMoriah.Waterland@Sun.COM 	quitSetInstallStarted(B_TRUE);
1997*9781SMoriah.Waterland@Sun.COM 
1998*9781SMoriah.Waterland@Sun.COM 	/*
1999*9781SMoriah.Waterland@Sun.COM 	 * This replaces the contents file with recently created temp version
2000*9781SMoriah.Waterland@Sun.COM 	 * which contains information about the objects being installed.
2001*9781SMoriah.Waterland@Sun.COM 	 * Under old lock protocol it closes both files and releases the
2002*9781SMoriah.Waterland@Sun.COM 	 * locks. Beginning in Solaris 2.7, this lock method should be
2003*9781SMoriah.Waterland@Sun.COM 	 * reviewed.
2004*9781SMoriah.Waterland@Sun.COM 	 */
2005*9781SMoriah.Waterland@Sun.COM 
2006*9781SMoriah.Waterland@Sun.COM 	n = swapcfile(&cfVfp, &cfTmpVfp, pkginst, dbchg);
2007*9781SMoriah.Waterland@Sun.COM 	if (n == RESULT_WRN) {
2008*9781SMoriah.Waterland@Sun.COM 		warnflag++;
2009*9781SMoriah.Waterland@Sun.COM 	} else if (n == RESULT_ERR) {
2010*9781SMoriah.Waterland@Sun.COM 		quit(99);
2011*9781SMoriah.Waterland@Sun.COM 		/*NOTREACHED*/
2012*9781SMoriah.Waterland@Sun.COM 	}
2013*9781SMoriah.Waterland@Sun.COM 
2014*9781SMoriah.Waterland@Sun.COM 	/*
2015*9781SMoriah.Waterland@Sun.COM 	 * Create install-specific lockfile to indicate start of
2016*9781SMoriah.Waterland@Sun.COM 	 * installation. This is really just an information file. If the
2017*9781SMoriah.Waterland@Sun.COM 	 * process dies, the initial lockfile (from lockinst(), is
2018*9781SMoriah.Waterland@Sun.COM 	 * relinquished by the kernel, but this one remains in support of the
2019*9781SMoriah.Waterland@Sun.COM 	 * post-mortem.
2020*9781SMoriah.Waterland@Sun.COM 	 */
2021*9781SMoriah.Waterland@Sun.COM 
2022*9781SMoriah.Waterland@Sun.COM 	if (access(ilockfile, F_OK) == 0) {
2023*9781SMoriah.Waterland@Sun.COM 		(void) remove(ilockfile);
2024*9781SMoriah.Waterland@Sun.COM 	}
2025*9781SMoriah.Waterland@Sun.COM 
2026*9781SMoriah.Waterland@Sun.COM 	if (open(ilockfile, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL, 0644) < 0) {
2027*9781SMoriah.Waterland@Sun.COM 		progerr(ERR_LOCKFILE, ilockfile);
2028*9781SMoriah.Waterland@Sun.COM 		quit(99);
2029*9781SMoriah.Waterland@Sun.COM 		/*NOTREACHED*/
2030*9781SMoriah.Waterland@Sun.COM 	}
2031*9781SMoriah.Waterland@Sun.COM 
2032*9781SMoriah.Waterland@Sun.COM 	(void) time(&clock);
2033*9781SMoriah.Waterland@Sun.COM 	/* LINTED warning: do not use cftime(); ... */
2034*9781SMoriah.Waterland@Sun.COM 	(void) cftime(cbuf, "%b %d \045Y \045H:\045M", &clock);
2035*9781SMoriah.Waterland@Sun.COM 	putparam("INSTDATE", qstrdup(cbuf));
2036*9781SMoriah.Waterland@Sun.COM 
2037*9781SMoriah.Waterland@Sun.COM 	/*
2038*9781SMoriah.Waterland@Sun.COM 	 * Store information about package being installed;
2039*9781SMoriah.Waterland@Sun.COM 	 * modify installation parameters as neccessary and
2040*9781SMoriah.Waterland@Sun.COM 	 * copy contents of 'install' directory into $pkgloc
2041*9781SMoriah.Waterland@Sun.COM 	 */
2042*9781SMoriah.Waterland@Sun.COM 	merginfo(mergd_pclass, saveSpoolInstall);
2043*9781SMoriah.Waterland@Sun.COM 
2044*9781SMoriah.Waterland@Sun.COM 	/* If this was just a dryrun, then quit() will write out that file. */
2045*9781SMoriah.Waterland@Sun.COM 	if (in_dryrun_mode()) {
2046*9781SMoriah.Waterland@Sun.COM 		quit(0);
2047*9781SMoriah.Waterland@Sun.COM 		/*NOTREACHED*/
2048*9781SMoriah.Waterland@Sun.COM 	}
2049*9781SMoriah.Waterland@Sun.COM 
2050*9781SMoriah.Waterland@Sun.COM 	if (opresvr4) {
2051*9781SMoriah.Waterland@Sun.COM 		/*
2052*9781SMoriah.Waterland@Sun.COM 		 * we are overwriting a pre-svr4 package, so remove the file
2053*9781SMoriah.Waterland@Sun.COM 		 * in /usr/options now
2054*9781SMoriah.Waterland@Sun.COM 		 */
2055*9781SMoriah.Waterland@Sun.COM 		(void) snprintf(path, sizeof (path),
2056*9781SMoriah.Waterland@Sun.COM 			"%s/%s.name", get_PKGOLD(), pkginst);
2057*9781SMoriah.Waterland@Sun.COM 		if (remove(path) && (errno != ENOENT)) {
2058*9781SMoriah.Waterland@Sun.COM 			progerr(ERR_OPRESVR4, path);
2059*9781SMoriah.Waterland@Sun.COM 			warnflag++;
2060*9781SMoriah.Waterland@Sun.COM 		}
2061*9781SMoriah.Waterland@Sun.COM 	}
2062*9781SMoriah.Waterland@Sun.COM 
2063*9781SMoriah.Waterland@Sun.COM 	/*
2064*9781SMoriah.Waterland@Sun.COM 	 * Execute preinstall script, if one was provided with the
2065*9781SMoriah.Waterland@Sun.COM 	 * package. We check the package to avoid running an old
2066*9781SMoriah.Waterland@Sun.COM 	 * preinstall script if one was provided with a prior instance.
2067*9781SMoriah.Waterland@Sun.COM 	 * Don't execute preinstall script if we are only updating the DB.
2068*9781SMoriah.Waterland@Sun.COM 	 */
2069*9781SMoriah.Waterland@Sun.COM 
2070*9781SMoriah.Waterland@Sun.COM 	/* update the lock - at the preinstall altscript */
2071*9781SMoriah.Waterland@Sun.COM 	lockupd("preinstall");
2072*9781SMoriah.Waterland@Sun.COM 
2073*9781SMoriah.Waterland@Sun.COM 	/* preinstall script in the media (package source) */
2074*9781SMoriah.Waterland@Sun.COM 	(void) snprintf(altscript, sizeof (altscript), "%s/install/preinstall",
2075*9781SMoriah.Waterland@Sun.COM 			instdir);
2076*9781SMoriah.Waterland@Sun.COM 
2077*9781SMoriah.Waterland@Sun.COM 	/* preinstall script in the pkgbin instead of media */
2078*9781SMoriah.Waterland@Sun.COM 	(void) snprintf(script, sizeof (script), "%s/preinstall", pkgbin);
2079*9781SMoriah.Waterland@Sun.COM 
2080*9781SMoriah.Waterland@Sun.COM 	if (access(altscript, F_OK) != 0) {
2081*9781SMoriah.Waterland@Sun.COM 		/* no script present */
2082*9781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_PKGINSTALL_POCALT_NONE, pkginst, altscript,
2083*9781SMoriah.Waterland@Sun.COM 			zoneName ? zoneName : "global");
2084*9781SMoriah.Waterland@Sun.COM 	} else if (access(script, F_OK) != 0) {
2085*9781SMoriah.Waterland@Sun.COM 		/* no script present */
2086*9781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_PKGINSTALL_POC_NONE, pkginst, script,
2087*9781SMoriah.Waterland@Sun.COM 			zoneName ? zoneName : "global");
2088*9781SMoriah.Waterland@Sun.COM 	} else if (is_depend_pkginfo_DB()) {
2089*9781SMoriah.Waterland@Sun.COM 		/* updating db only: skip preinstall script */
2090*9781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_PKGINSTALL_POC_DBUPD, pkginst, script,
2091*9781SMoriah.Waterland@Sun.COM 			zoneName ? zoneName : "global");
2092*9781SMoriah.Waterland@Sun.COM 	} else {
2093*9781SMoriah.Waterland@Sun.COM 		/* script present and ok to run: run the script */
2094*9781SMoriah.Waterland@Sun.COM 		assert(preinstallCheck == B_FALSE);
2095*9781SMoriah.Waterland@Sun.COM 
2096*9781SMoriah.Waterland@Sun.COM 		set_ulimit("preinstall", ERR_PREINSTALL);
2097*9781SMoriah.Waterland@Sun.COM 		if (zoneName == (char *)NULL) {
2098*9781SMoriah.Waterland@Sun.COM 			echo(MSG_PKGINSTALL_EXEPOC_GZ);
2099*9781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_PKGINSTALL_EXEPOC_GZ, pkginst, script);
2100*9781SMoriah.Waterland@Sun.COM 		} else {
2101*9781SMoriah.Waterland@Sun.COM 			echo(MSG_PKGINSTALL_EXEPOC_LZ, zoneName);
2102*9781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_PKGINSTALL_EXEPOC_LZ, pkginst, script,
2103*9781SMoriah.Waterland@Sun.COM 				zoneName);
2104*9781SMoriah.Waterland@Sun.COM 		}
2105*9781SMoriah.Waterland@Sun.COM 		putparam("PKG_PROC_script", "preinstall");
2106*9781SMoriah.Waterland@Sun.COM 		if (pkgverbose) {
2107*9781SMoriah.Waterland@Sun.COM 			ckreturn(pkgexecl(script_in, PROC_STDOUT,
2108*9781SMoriah.Waterland@Sun.COM 				PROC_USER, PROC_GRP, SHELL, "-x",
2109*9781SMoriah.Waterland@Sun.COM 				script, NULL), ERR_PREINSTALL);
2110*9781SMoriah.Waterland@Sun.COM 		} else {
2111*9781SMoriah.Waterland@Sun.COM 			ckreturn(pkgexecl(script_in, PROC_STDOUT,
2112*9781SMoriah.Waterland@Sun.COM 				PROC_USER, PROC_GRP, SHELL, script,
2113*9781SMoriah.Waterland@Sun.COM 				NULL), ERR_PREINSTALL);
2114*9781SMoriah.Waterland@Sun.COM 		}
2115*9781SMoriah.Waterland@Sun.COM 
2116*9781SMoriah.Waterland@Sun.COM 		clr_ulimit();
2117*9781SMoriah.Waterland@Sun.COM 		(void) remove(script);	/* no longer needed. */
2118*9781SMoriah.Waterland@Sun.COM 	}
2119*9781SMoriah.Waterland@Sun.COM 
2120*9781SMoriah.Waterland@Sun.COM 	/*
2121*9781SMoriah.Waterland@Sun.COM 	 * Check delivered package for a postinstall script while
2122*9781SMoriah.Waterland@Sun.COM 	 * we're still on volume 1.
2123*9781SMoriah.Waterland@Sun.COM 	 */
2124*9781SMoriah.Waterland@Sun.COM 
2125*9781SMoriah.Waterland@Sun.COM 	(void) snprintf(script, sizeof (script),
2126*9781SMoriah.Waterland@Sun.COM 			"%s/install/postinstall", instdir);
2127*9781SMoriah.Waterland@Sun.COM 	if (access(script, F_OK) == 0) {
2128*9781SMoriah.Waterland@Sun.COM 		(void) snprintf(script, sizeof (script),
2129*9781SMoriah.Waterland@Sun.COM 					"%s/postinstall", pkgbin);
2130*9781SMoriah.Waterland@Sun.COM 	} else {
2131*9781SMoriah.Waterland@Sun.COM 		script[0] = '\0';
2132*9781SMoriah.Waterland@Sun.COM 	}
2133*9781SMoriah.Waterland@Sun.COM 
2134*9781SMoriah.Waterland@Sun.COM 	/* update the lock - at the install phase */
2135*9781SMoriah.Waterland@Sun.COM 
2136*9781SMoriah.Waterland@Sun.COM 	lockupd("install");
2137*9781SMoriah.Waterland@Sun.COM 
2138*9781SMoriah.Waterland@Sun.COM 	/*
2139*9781SMoriah.Waterland@Sun.COM 	 * install package one part (volume) at a time
2140*9781SMoriah.Waterland@Sun.COM 	 */
2141*9781SMoriah.Waterland@Sun.COM 
2142*9781SMoriah.Waterland@Sun.COM 	part = 1;
2143*9781SMoriah.Waterland@Sun.COM 	while (part <= nparts) {
2144*9781SMoriah.Waterland@Sun.COM 		if ((part > 1) && pkgdev.cdevice) {
2145*9781SMoriah.Waterland@Sun.COM 			unpack();
2146*9781SMoriah.Waterland@Sun.COM 		}
2147*9781SMoriah.Waterland@Sun.COM 
2148*9781SMoriah.Waterland@Sun.COM 		instvol(extlist, srcinst, part, nparts,
2149*9781SMoriah.Waterland@Sun.COM 			&cfVfp, &cfTmpVfp, &updated,
2150*9781SMoriah.Waterland@Sun.COM 			&skipped, zoneName);
2151*9781SMoriah.Waterland@Sun.COM 
2152*9781SMoriah.Waterland@Sun.COM 		if (part++ >= nparts) {
2153*9781SMoriah.Waterland@Sun.COM 			break;
2154*9781SMoriah.Waterland@Sun.COM 		}
2155*9781SMoriah.Waterland@Sun.COM 	}
2156*9781SMoriah.Waterland@Sun.COM 
2157*9781SMoriah.Waterland@Sun.COM 	z_destroyMountTable();
2158*9781SMoriah.Waterland@Sun.COM 
2159*9781SMoriah.Waterland@Sun.COM 	/*
2160*9781SMoriah.Waterland@Sun.COM 	 * Now that all install class action scripts have been used, we
2161*9781SMoriah.Waterland@Sun.COM 	 * delete them from the package directory.
2162*9781SMoriah.Waterland@Sun.COM 	 */
2163*9781SMoriah.Waterland@Sun.COM 	rm_icas(pkgbin);
2164*9781SMoriah.Waterland@Sun.COM 
2165*9781SMoriah.Waterland@Sun.COM 	if ((globalZoneOnly) && (!patchPkgInstall) && (!patchPkgRemoval)) {
2166*9781SMoriah.Waterland@Sun.COM 		boolean_t   b;
2167*9781SMoriah.Waterland@Sun.COM 		b = pkgAddPackageToGzonlyList(pkginst, get_inst_root());
2168*9781SMoriah.Waterland@Sun.COM 		if (b == B_FALSE) {
2169*9781SMoriah.Waterland@Sun.COM 			progerr(ERR_PKGINSTALL_GZONLY_ADD, pkginst);
2170*9781SMoriah.Waterland@Sun.COM 			ckreturn(1, NULL);
2171*9781SMoriah.Waterland@Sun.COM 		}
2172*9781SMoriah.Waterland@Sun.COM 	}
2173*9781SMoriah.Waterland@Sun.COM 
2174*9781SMoriah.Waterland@Sun.COM 	/*
2175*9781SMoriah.Waterland@Sun.COM 	 * Execute postinstall script, if any
2176*9781SMoriah.Waterland@Sun.COM 	 * Don't execute postinstall script if we are only updating the DB.
2177*9781SMoriah.Waterland@Sun.COM 	 */
2178*9781SMoriah.Waterland@Sun.COM 
2179*9781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_PKGINSTALL_INSDONE, is_depend_pkginfo_DB(),
2180*9781SMoriah.Waterland@Sun.COM 		is_depend_pkginfo_DB(), saveSpoolInstall,
2181*9781SMoriah.Waterland@Sun.COM 		updated ? updated : "",
2182*9781SMoriah.Waterland@Sun.COM 		skipped ? skipped : "",
2183*9781SMoriah.Waterland@Sun.COM 		script ? script : "",
2184*9781SMoriah.Waterland@Sun.COM 		script ? access(script, F_OK) : -1);
2185*9781SMoriah.Waterland@Sun.COM 
2186*9781SMoriah.Waterland@Sun.COM 	/* update the lock - at the postinstall script */
2187*9781SMoriah.Waterland@Sun.COM 	lockupd("postinstall");
2188*9781SMoriah.Waterland@Sun.COM 
2189*9781SMoriah.Waterland@Sun.COM 	if ((script == (char *)NULL) || (*script == '\0')) {
2190*9781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_PKGINSTALL_POIS_NOPATH, pkginst,
2191*9781SMoriah.Waterland@Sun.COM 			zoneName ? zoneName : "global");
2192*9781SMoriah.Waterland@Sun.COM 	} else if (access(script, F_OK) != 0) {
2193*9781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_PKGINSTALL_POIS_NONE, pkginst, script,
2194*9781SMoriah.Waterland@Sun.COM 			zoneName ? zoneName : "global");
2195*9781SMoriah.Waterland@Sun.COM 	} else if (is_depend_pkginfo_DB()) {
2196*9781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_PKGINSTALL_POIS_DBUPD, pkginst, script,
2197*9781SMoriah.Waterland@Sun.COM 			zoneName ? zoneName : "global");
2198*9781SMoriah.Waterland@Sun.COM 	} else if ((saveSpoolInstall != 0) && (updated == (char *)NULL) &&
2199*9781SMoriah.Waterland@Sun.COM 				(skipped != (char *)NULL)) {
2200*9781SMoriah.Waterland@Sun.COM 		/*
2201*9781SMoriah.Waterland@Sun.COM 		 * fresh installing into non-global zone, no object was
2202*9781SMoriah.Waterland@Sun.COM 		 * updated (installed/verified in non-inherited area),
2203*9781SMoriah.Waterland@Sun.COM 		 * and and at least one object was skipped (verified in
2204*9781SMoriah.Waterland@Sun.COM 		 * inherited area) - this means all objects were skipped
2205*9781SMoriah.Waterland@Sun.COM 		 * so do not run the postinstall script.
2206*9781SMoriah.Waterland@Sun.COM 		 */
2207*9781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_PKGINSTALL_POIS_SKIPPING,
2208*9781SMoriah.Waterland@Sun.COM 			zoneName ? zoneName : "global", pkginst, script);
2209*9781SMoriah.Waterland@Sun.COM 	} else {
2210*9781SMoriah.Waterland@Sun.COM 		/* script present and ok to run: run the script */
2211*9781SMoriah.Waterland@Sun.COM 		set_ulimit("postinstall", ERR_POSTINSTALL);
2212*9781SMoriah.Waterland@Sun.COM 		if (zoneName == (char *)NULL) {
2213*9781SMoriah.Waterland@Sun.COM 			echo(MSG_PKGINSTALL_EXEPIC_GZ);
2214*9781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_PKGINSTALL_EXEPIC_GZ, pkginst, script);
2215*9781SMoriah.Waterland@Sun.COM 		} else {
2216*9781SMoriah.Waterland@Sun.COM 			echo(MSG_PKGINSTALL_EXEPIC_LZ, zoneName);
2217*9781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_PKGINSTALL_EXEPIC_LZ, pkginst, script,
2218*9781SMoriah.Waterland@Sun.COM 				zoneName);
2219*9781SMoriah.Waterland@Sun.COM 		}
2220*9781SMoriah.Waterland@Sun.COM 		putparam("PKG_PROC_SCRIPT", "postinstall");
2221*9781SMoriah.Waterland@Sun.COM 		putparam("TMPDIR", tmpdir);
2222*9781SMoriah.Waterland@Sun.COM 		if (pkgverbose) {
2223*9781SMoriah.Waterland@Sun.COM 			ckreturn(pkgexecl(script_in, PROC_STDOUT,
2224*9781SMoriah.Waterland@Sun.COM 				PROC_USER, PROC_GRP, SHELL, "-x",
2225*9781SMoriah.Waterland@Sun.COM 				script, NULL), ERR_POSTINSTALL);
2226*9781SMoriah.Waterland@Sun.COM 		} else {
2227*9781SMoriah.Waterland@Sun.COM 			ckreturn(pkgexecl(script_in, PROC_STDOUT,
2228*9781SMoriah.Waterland@Sun.COM 				PROC_USER, PROC_GRP, SHELL, script,
2229*9781SMoriah.Waterland@Sun.COM 				NULL), ERR_POSTINSTALL);
2230*9781SMoriah.Waterland@Sun.COM 		}
2231*9781SMoriah.Waterland@Sun.COM 
2232*9781SMoriah.Waterland@Sun.COM 		clr_ulimit();
2233*9781SMoriah.Waterland@Sun.COM 		(void) remove(script);	/* no longer needed */
2234*9781SMoriah.Waterland@Sun.COM 	}
2235*9781SMoriah.Waterland@Sun.COM 
2236*9781SMoriah.Waterland@Sun.COM 	if (!warnflag && !failflag) {
2237*9781SMoriah.Waterland@Sun.COM 		if (pt = getenv("PREDEPEND"))
2238*9781SMoriah.Waterland@Sun.COM 			predepend(pt);
2239*9781SMoriah.Waterland@Sun.COM 		(void) remove(rlockfile);
2240*9781SMoriah.Waterland@Sun.COM 		(void) remove(ilockfile);
2241*9781SMoriah.Waterland@Sun.COM 		(void) remove(savlog);
2242*9781SMoriah.Waterland@Sun.COM 	}
2243*9781SMoriah.Waterland@Sun.COM 
2244*9781SMoriah.Waterland@Sun.COM 	/* release the generic package lock */
2245*9781SMoriah.Waterland@Sun.COM 
2246*9781SMoriah.Waterland@Sun.COM 	(void) unlockinst();
2247*9781SMoriah.Waterland@Sun.COM 
2248*9781SMoriah.Waterland@Sun.COM 	quit(0);
2249*9781SMoriah.Waterland@Sun.COM 	/* LINTED: no return */
2250*9781SMoriah.Waterland@Sun.COM }
2251*9781SMoriah.Waterland@Sun.COM 
2252*9781SMoriah.Waterland@Sun.COM /*
2253*9781SMoriah.Waterland@Sun.COM  * This function merges the environment data in the response file with the
2254*9781SMoriah.Waterland@Sun.COM  * current environment.
2255*9781SMoriah.Waterland@Sun.COM  */
2256*9781SMoriah.Waterland@Sun.COM static int
2257*9781SMoriah.Waterland@Sun.COM merg_respfile()
2258*9781SMoriah.Waterland@Sun.COM {
2259*9781SMoriah.Waterland@Sun.COM 	int retcode = 0;
2260*9781SMoriah.Waterland@Sun.COM 	char *resppath = get_respfile();
2261*9781SMoriah.Waterland@Sun.COM 	char *locbasedir;
2262*9781SMoriah.Waterland@Sun.COM 	char param[MAX_PKG_PARAM_LENGTH], *value;
2263*9781SMoriah.Waterland@Sun.COM 	FILE *fp;
2264*9781SMoriah.Waterland@Sun.COM 
2265*9781SMoriah.Waterland@Sun.COM 	if ((fp = fopen(resppath, "r")) == NULL) {
2266*9781SMoriah.Waterland@Sun.COM 		progerr(ERR_RESPONSE, resppath);
2267*9781SMoriah.Waterland@Sun.COM 		return (99);
2268*9781SMoriah.Waterland@Sun.COM 	}
2269*9781SMoriah.Waterland@Sun.COM 
2270*9781SMoriah.Waterland@Sun.COM 	param[0] = '\0';
2271*9781SMoriah.Waterland@Sun.COM 
2272*9781SMoriah.Waterland@Sun.COM 	while (value = fpkgparam(fp, param)) {
2273*9781SMoriah.Waterland@Sun.COM 		if (!isupper(param[0])) {
2274*9781SMoriah.Waterland@Sun.COM 			param[0] = '\0';
2275*9781SMoriah.Waterland@Sun.COM 			continue;
2276*9781SMoriah.Waterland@Sun.COM 		}
2277*9781SMoriah.Waterland@Sun.COM 
2278*9781SMoriah.Waterland@Sun.COM 		if (rdonly(param)) {
2279*9781SMoriah.Waterland@Sun.COM 			progerr(ERR_RDONLY, param);
2280*9781SMoriah.Waterland@Sun.COM 			param[0] = '\0';
2281*9781SMoriah.Waterland@Sun.COM 			continue;
2282*9781SMoriah.Waterland@Sun.COM 		}
2283*9781SMoriah.Waterland@Sun.COM 
2284*9781SMoriah.Waterland@Sun.COM 		/*
2285*9781SMoriah.Waterland@Sun.COM 		 * If this is an update, and the response file
2286*9781SMoriah.Waterland@Sun.COM 		 * specifies the BASEDIR, make sure it matches the
2287*9781SMoriah.Waterland@Sun.COM 		 * existing installation base. If it doesn't, we have
2288*9781SMoriah.Waterland@Sun.COM 		 * to quit.
2289*9781SMoriah.Waterland@Sun.COM 		 */
2290*9781SMoriah.Waterland@Sun.COM 		if (update && strcmp("BASEDIR", param) == 0) {
2291*9781SMoriah.Waterland@Sun.COM 			locbasedir = getenv("BASEDIR");
2292*9781SMoriah.Waterland@Sun.COM 			if (locbasedir && strcmp(value, locbasedir) != 0) {
2293*9781SMoriah.Waterland@Sun.COM 				char *dotptr;
2294*9781SMoriah.Waterland@Sun.COM 				/* Get srcinst down to a name. */
2295*9781SMoriah.Waterland@Sun.COM 				if (dotptr = strchr(srcinst, '.'))
2296*9781SMoriah.Waterland@Sun.COM 					*dotptr = '\000';
2297*9781SMoriah.Waterland@Sun.COM 				progerr(ERR_NEWBD, srcinst,
2298*9781SMoriah.Waterland@Sun.COM 					locbasedir, value);
2299*9781SMoriah.Waterland@Sun.COM 				retcode = 99;
2300*9781SMoriah.Waterland@Sun.COM 			}
2301*9781SMoriah.Waterland@Sun.COM 		}
2302*9781SMoriah.Waterland@Sun.COM 
2303*9781SMoriah.Waterland@Sun.COM 		putparam(param, value);
2304*9781SMoriah.Waterland@Sun.COM 		param[0] = '\0';
2305*9781SMoriah.Waterland@Sun.COM 	}
2306*9781SMoriah.Waterland@Sun.COM 	(void) fclose(fp);
2307*9781SMoriah.Waterland@Sun.COM 
2308*9781SMoriah.Waterland@Sun.COM 	return (retcode);
2309*9781SMoriah.Waterland@Sun.COM }
2310*9781SMoriah.Waterland@Sun.COM 
2311*9781SMoriah.Waterland@Sun.COM /*
2312*9781SMoriah.Waterland@Sun.COM  * This scans the installed pkginfo file for the current BASEDIR. If this
2313*9781SMoriah.Waterland@Sun.COM  * BASEDIR is different from the current BASEDIR, there will definitely be
2314*9781SMoriah.Waterland@Sun.COM  * problems.
2315*9781SMoriah.Waterland@Sun.COM  */
2316*9781SMoriah.Waterland@Sun.COM static int
2317*9781SMoriah.Waterland@Sun.COM ck_instbase(void)
2318*9781SMoriah.Waterland@Sun.COM {
2319*9781SMoriah.Waterland@Sun.COM 	int retcode = 0;
2320*9781SMoriah.Waterland@Sun.COM 	char param[MAX_PKG_PARAM_LENGTH], *value;
2321*9781SMoriah.Waterland@Sun.COM 	char pkginfo_path[PATH_MAX];
2322*9781SMoriah.Waterland@Sun.COM 	FILE *fp;
2323*9781SMoriah.Waterland@Sun.COM 
2324*9781SMoriah.Waterland@Sun.COM 	/* Open the old pkginfo file. */
2325*9781SMoriah.Waterland@Sun.COM 	(void) snprintf(pkginfo_path, sizeof (pkginfo_path),
2326*9781SMoriah.Waterland@Sun.COM 			"%s/%s", pkgloc, PKGINFO);
2327*9781SMoriah.Waterland@Sun.COM 	if ((fp = fopen(pkginfo_path, "r")) == NULL) {
2328*9781SMoriah.Waterland@Sun.COM 		progerr(ERR_PKGINFO, pkginfo_path);
2329*9781SMoriah.Waterland@Sun.COM 		return (99);
2330*9781SMoriah.Waterland@Sun.COM 	}
2331*9781SMoriah.Waterland@Sun.COM 
2332*9781SMoriah.Waterland@Sun.COM 	param[0] = '\000';
2333*9781SMoriah.Waterland@Sun.COM 
2334*9781SMoriah.Waterland@Sun.COM 	while (value = fpkgparam(fp, param)) {
2335*9781SMoriah.Waterland@Sun.COM 		if (strcmp("BASEDIR", param) == 0) {
2336*9781SMoriah.Waterland@Sun.COM 			if (adm.basedir && *(adm.basedir) &&
2337*9781SMoriah.Waterland@Sun.COM 				strchr("/$", *(adm.basedir))) {
2338*9781SMoriah.Waterland@Sun.COM 				char *dotptr;
2339*9781SMoriah.Waterland@Sun.COM 
2340*9781SMoriah.Waterland@Sun.COM 				/*
2341*9781SMoriah.Waterland@Sun.COM 				 * Get srcinst down to a name.
2342*9781SMoriah.Waterland@Sun.COM 				 */
2343*9781SMoriah.Waterland@Sun.COM 				if (dotptr = strchr(srcinst, '.'))
2344*9781SMoriah.Waterland@Sun.COM 					*dotptr = '\000';
2345*9781SMoriah.Waterland@Sun.COM 				if (strcmp(value,
2346*9781SMoriah.Waterland@Sun.COM 					adm.basedir) != 0) {
2347*9781SMoriah.Waterland@Sun.COM 					progerr(ERR_ADMBD, srcinst,
2348*9781SMoriah.Waterland@Sun.COM 						value, adm.basedir);
2349*9781SMoriah.Waterland@Sun.COM 					retcode = 4;
2350*9781SMoriah.Waterland@Sun.COM 					break;
2351*9781SMoriah.Waterland@Sun.COM 				}
2352*9781SMoriah.Waterland@Sun.COM 			} else if (ADM(basedir, "ask"))
2353*9781SMoriah.Waterland@Sun.COM 				/*
2354*9781SMoriah.Waterland@Sun.COM 				 * If it's going to ask later, let it know
2355*9781SMoriah.Waterland@Sun.COM 				 * that it *must* agree with the BASEDIR we
2356*9781SMoriah.Waterland@Sun.COM 				 * just picked up.
2357*9781SMoriah.Waterland@Sun.COM 				 */
2358*9781SMoriah.Waterland@Sun.COM 				adm.basedir = "update";
2359*9781SMoriah.Waterland@Sun.COM 
2360*9781SMoriah.Waterland@Sun.COM 			putparam(param, value);
2361*9781SMoriah.Waterland@Sun.COM 			break;
2362*9781SMoriah.Waterland@Sun.COM 		}
2363*9781SMoriah.Waterland@Sun.COM 
2364*9781SMoriah.Waterland@Sun.COM 		param[0] = '\0';
2365*9781SMoriah.Waterland@Sun.COM 	}
2366*9781SMoriah.Waterland@Sun.COM 	(void) fclose(fp);
2367*9781SMoriah.Waterland@Sun.COM 
2368*9781SMoriah.Waterland@Sun.COM 	return (retcode);
2369*9781SMoriah.Waterland@Sun.COM }
2370*9781SMoriah.Waterland@Sun.COM 
2371*9781SMoriah.Waterland@Sun.COM /*
2372*9781SMoriah.Waterland@Sun.COM  * Since this is an overwrite of a different version of the package, none of
2373*9781SMoriah.Waterland@Sun.COM  * the old files should remain, so we rename them.
2374*9781SMoriah.Waterland@Sun.COM  */
2375*9781SMoriah.Waterland@Sun.COM static int
2376*9781SMoriah.Waterland@Sun.COM mv_pkgdirs(void)
2377*9781SMoriah.Waterland@Sun.COM {
2378*9781SMoriah.Waterland@Sun.COM 	/*
2379*9781SMoriah.Waterland@Sun.COM 	 * If we're not in dryrun mode and we can find an old set of package
2380*9781SMoriah.Waterland@Sun.COM 	 * files over which the new ones will be written, do the rename.
2381*9781SMoriah.Waterland@Sun.COM 	 */
2382*9781SMoriah.Waterland@Sun.COM 	if (!in_dryrun_mode() && pkgloc[0] && !access(pkgloc, F_OK)) {
2383*9781SMoriah.Waterland@Sun.COM 		(void) snprintf(pkgloc_sav, sizeof (pkgloc_sav),
2384*9781SMoriah.Waterland@Sun.COM 			"%s/.save.%s", get_PKGLOC(),
2385*9781SMoriah.Waterland@Sun.COM 			pkginst);
2386*9781SMoriah.Waterland@Sun.COM 		if (pkgloc_sav[0] && !access(pkgloc_sav, F_OK)) {
2387*9781SMoriah.Waterland@Sun.COM 			(void) rrmdir(pkgloc_sav);
2388*9781SMoriah.Waterland@Sun.COM 		}
2389*9781SMoriah.Waterland@Sun.COM 
2390*9781SMoriah.Waterland@Sun.COM 		if (rename(pkgloc, pkgloc_sav) == -1) {
2391*9781SMoriah.Waterland@Sun.COM 			progerr(ERR_PKGBINREN, pkgloc, pkgloc_sav);
2392*9781SMoriah.Waterland@Sun.COM 			return (99);
2393*9781SMoriah.Waterland@Sun.COM 		}
2394*9781SMoriah.Waterland@Sun.COM 	}
2395*9781SMoriah.Waterland@Sun.COM 
2396*9781SMoriah.Waterland@Sun.COM 	return (0);
2397*9781SMoriah.Waterland@Sun.COM }
2398*9781SMoriah.Waterland@Sun.COM 
2399*9781SMoriah.Waterland@Sun.COM /*
2400*9781SMoriah.Waterland@Sun.COM  * Name:	merg_pkginfos
2401*9781SMoriah.Waterland@Sun.COM  * Description:	This function scans the installed pkginfo and merges that
2402*9781SMoriah.Waterland@Sun.COM  *		environment with the installing environment according to
2403*9781SMoriah.Waterland@Sun.COM  *		the following rules:
2404*9781SMoriah.Waterland@Sun.COM  *
2405*9781SMoriah.Waterland@Sun.COM  *		1. CLASSES is a union of the installed and installing CLASSES
2406*9781SMoriah.Waterland@Sun.COM  *			lists.
2407*9781SMoriah.Waterland@Sun.COM  *		2. The installed BASEDIR takes precedence. If it doesn't agree
2408*9781SMoriah.Waterland@Sun.COM  *		   with an administratively imposed BASEDIR, an ERROR is issued.
2409*9781SMoriah.Waterland@Sun.COM  *		3. All other installing parameters are preserved.
2410*9781SMoriah.Waterland@Sun.COM  *		4. All installed parameters are added if they do not overwrite
2411*9781SMoriah.Waterland@Sun.COM  *		   an existing installing parameter.
2412*9781SMoriah.Waterland@Sun.COM  *
2413*9781SMoriah.Waterland@Sun.COM  *		The current environment contains the pkginfo settings for the
2414*9781SMoriah.Waterland@Sun.COM  *		new package to be installed or to be updated.
2415*9781SMoriah.Waterland@Sun.COM  *
2416*9781SMoriah.Waterland@Sun.COM  * Arguments:	pclass - returned list of current classes involved in install
2417*9781SMoriah.Waterland@Sun.COM  *		mpclass - pointer to returned list of current install classes
2418*9781SMoriah.Waterland@Sun.COM  * Returns:	int
2419*9781SMoriah.Waterland@Sun.COM  *		== 0 - all OK
2420*9781SMoriah.Waterland@Sun.COM  *		!= 0 - an error code if a fatal error occurred
2421*9781SMoriah.Waterland@Sun.COM  */
2422*9781SMoriah.Waterland@Sun.COM 
2423*9781SMoriah.Waterland@Sun.COM static int
2424*9781SMoriah.Waterland@Sun.COM merg_pkginfos(struct cl_attr **pclass, struct cl_attr ***mpclass)
2425*9781SMoriah.Waterland@Sun.COM {
2426*9781SMoriah.Waterland@Sun.COM 	FILE	*fp;
2427*9781SMoriah.Waterland@Sun.COM 	char	SUNW_PKG_ALLZONES[MAX_PKG_PARAM_LENGTH] = {'\0'};
2428*9781SMoriah.Waterland@Sun.COM 	char	SUNW_PKG_HOLLOW[MAX_PKG_PARAM_LENGTH] = {'\0'};
2429*9781SMoriah.Waterland@Sun.COM 	char	SUNW_PKG_THISZONE[MAX_PKG_PARAM_LENGTH] = {'\0'};
2430*9781SMoriah.Waterland@Sun.COM 	char	*newValue;
2431*9781SMoriah.Waterland@Sun.COM 	char	*oldValue;
2432*9781SMoriah.Waterland@Sun.COM 	char	*pkgName;
2433*9781SMoriah.Waterland@Sun.COM 	char	*pkgVersion;
2434*9781SMoriah.Waterland@Sun.COM 	char	param[MAX_PKG_PARAM_LENGTH];
2435*9781SMoriah.Waterland@Sun.COM 	char	pkginfo_path[PATH_MAX];
2436*9781SMoriah.Waterland@Sun.COM 	int	retcode = 0;
2437*9781SMoriah.Waterland@Sun.COM 
2438*9781SMoriah.Waterland@Sun.COM 	/* obtain the name of the package (for error messages) */
2439*9781SMoriah.Waterland@Sun.COM 
2440*9781SMoriah.Waterland@Sun.COM 	pkgName = getenv("PKG");
2441*9781SMoriah.Waterland@Sun.COM 	if (pkgName == NULL) {
2442*9781SMoriah.Waterland@Sun.COM 		pkgName = "*current*";	/* default name */
2443*9781SMoriah.Waterland@Sun.COM 	}
2444*9781SMoriah.Waterland@Sun.COM 
2445*9781SMoriah.Waterland@Sun.COM 	/* obtain the version of the package (for error messages) */
2446*9781SMoriah.Waterland@Sun.COM 
2447*9781SMoriah.Waterland@Sun.COM 	pkgVersion = getenv("VERSION");
2448*9781SMoriah.Waterland@Sun.COM 	if (pkgVersion == NULL) {
2449*9781SMoriah.Waterland@Sun.COM 		pkgVersion = "*current*";	/* default version */
2450*9781SMoriah.Waterland@Sun.COM 	}
2451*9781SMoriah.Waterland@Sun.COM 
2452*9781SMoriah.Waterland@Sun.COM 	/* open installed package pkginfo file */
2453*9781SMoriah.Waterland@Sun.COM 
2454*9781SMoriah.Waterland@Sun.COM 	(void) snprintf(pkginfo_path, sizeof (pkginfo_path),
2455*9781SMoriah.Waterland@Sun.COM 			"%s/%s", pkgloc, PKGINFO);
2456*9781SMoriah.Waterland@Sun.COM 	if ((fp = fopen(pkginfo_path, "r")) == NULL) {
2457*9781SMoriah.Waterland@Sun.COM 		progerr(ERR_PKGINFO, pkginfo_path);
2458*9781SMoriah.Waterland@Sun.COM 		return (99);
2459*9781SMoriah.Waterland@Sun.COM 	}
2460*9781SMoriah.Waterland@Sun.COM 
2461*9781SMoriah.Waterland@Sun.COM 	/* entry debugging info */
2462*9781SMoriah.Waterland@Sun.COM 
2463*9781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_MERGINFOS_ENTRY, pkginfo_path);
2464*9781SMoriah.Waterland@Sun.COM 
2465*9781SMoriah.Waterland@Sun.COM 	/*
2466*9781SMoriah.Waterland@Sun.COM 	 * cycle through the currently installed package's pkginfo parameters
2467*9781SMoriah.Waterland@Sun.COM 	 * and let the currently installed package's settings survive if the
2468*9781SMoriah.Waterland@Sun.COM 	 * update to the package does not provide an overriding value
2469*9781SMoriah.Waterland@Sun.COM 	 */
2470*9781SMoriah.Waterland@Sun.COM 
2471*9781SMoriah.Waterland@Sun.COM 	for (param[0] = '\0'; (oldValue = fpkgparam(fp, param)) != NULL;
2472*9781SMoriah.Waterland@Sun.COM 		param[0] = '\0') {
2473*9781SMoriah.Waterland@Sun.COM 
2474*9781SMoriah.Waterland@Sun.COM 		boolean_t	setZoneAttribute = B_FALSE;
2475*9781SMoriah.Waterland@Sun.COM 
2476*9781SMoriah.Waterland@Sun.COM 		/* debug info - attribute currently set to value */
2477*9781SMoriah.Waterland@Sun.COM 
2478*9781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_MERGINFOS_SET_TO, param, oldValue);
2479*9781SMoriah.Waterland@Sun.COM 
2480*9781SMoriah.Waterland@Sun.COM 		/*
2481*9781SMoriah.Waterland@Sun.COM 		 * if zone package attribute is present in the currently
2482*9781SMoriah.Waterland@Sun.COM 		 * installed package, then remember the value for the
2483*9781SMoriah.Waterland@Sun.COM 		 * specific zone package attribute, and set the flag that
2484*9781SMoriah.Waterland@Sun.COM 		 * indicates a zone package attribute is being processed.
2485*9781SMoriah.Waterland@Sun.COM 		 */
2486*9781SMoriah.Waterland@Sun.COM 
2487*9781SMoriah.Waterland@Sun.COM 		if (strcmp(param, PKG_THISZONE_VARIABLE) == 0) {
2488*9781SMoriah.Waterland@Sun.COM 			/* SUNW_PKG_THISZONE currently set */
2489*9781SMoriah.Waterland@Sun.COM 			setZoneAttribute = B_TRUE;
2490*9781SMoriah.Waterland@Sun.COM 			(void) strlcpy(SUNW_PKG_THISZONE, oldValue,
2491*9781SMoriah.Waterland@Sun.COM 					sizeof (SUNW_PKG_THISZONE));
2492*9781SMoriah.Waterland@Sun.COM 		} else if (strcmp(param, PKG_ALLZONES_VARIABLE) == 0) {
2493*9781SMoriah.Waterland@Sun.COM 			/* SUNW_PKG_ALLZONES currently set */
2494*9781SMoriah.Waterland@Sun.COM 			setZoneAttribute = B_TRUE;
2495*9781SMoriah.Waterland@Sun.COM 			(void) strlcpy(SUNW_PKG_ALLZONES, oldValue,
2496*9781SMoriah.Waterland@Sun.COM 					sizeof (SUNW_PKG_ALLZONES));
2497*9781SMoriah.Waterland@Sun.COM 		} else if (strcmp(param, PKG_HOLLOW_VARIABLE) == 0) {
2498*9781SMoriah.Waterland@Sun.COM 			/* SUNW_PKG_THISZONE currently set */
2499*9781SMoriah.Waterland@Sun.COM 			setZoneAttribute = B_TRUE;
2500*9781SMoriah.Waterland@Sun.COM 			(void) strlcpy(SUNW_PKG_HOLLOW, oldValue,
2501*9781SMoriah.Waterland@Sun.COM 					sizeof (SUNW_PKG_HOLLOW));
2502*9781SMoriah.Waterland@Sun.COM 		}
2503*9781SMoriah.Waterland@Sun.COM 
2504*9781SMoriah.Waterland@Sun.COM 		/* handle CLASSES currently being set */
2505*9781SMoriah.Waterland@Sun.COM 
2506*9781SMoriah.Waterland@Sun.COM 		if (strcmp(param, "CLASSES") == 0) {
2507*9781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_MERGINFOS_SET_CLASSES, oldValue);
2508*9781SMoriah.Waterland@Sun.COM 			/* create a list of the current classes */
2509*9781SMoriah.Waterland@Sun.COM 			(void) setlist(&pclass, qstrdup(oldValue));
2510*9781SMoriah.Waterland@Sun.COM 			/* set pointer to list of current classes */
2511*9781SMoriah.Waterland@Sun.COM 			*mpclass = pclass;
2512*9781SMoriah.Waterland@Sun.COM 			continue;
2513*9781SMoriah.Waterland@Sun.COM 		}
2514*9781SMoriah.Waterland@Sun.COM 
2515*9781SMoriah.Waterland@Sun.COM 		/* handle BASEDIR currently being set */
2516*9781SMoriah.Waterland@Sun.COM 
2517*9781SMoriah.Waterland@Sun.COM 		if (strcmp("BASEDIR", param) == 0) {
2518*9781SMoriah.Waterland@Sun.COM 			if (adm.basedir && *(adm.basedir) &&
2519*9781SMoriah.Waterland@Sun.COM 				strchr("/$", *(adm.basedir))) {
2520*9781SMoriah.Waterland@Sun.COM 				char *dotptr;
2521*9781SMoriah.Waterland@Sun.COM 
2522*9781SMoriah.Waterland@Sun.COM 				/* Get srcinst down to a* name */
2523*9781SMoriah.Waterland@Sun.COM 
2524*9781SMoriah.Waterland@Sun.COM 				if (dotptr = strchr(srcinst, '.')) {
2525*9781SMoriah.Waterland@Sun.COM 					*dotptr = '\000';
2526*9781SMoriah.Waterland@Sun.COM 				}
2527*9781SMoriah.Waterland@Sun.COM 				if (strcmp(oldValue, adm.basedir) != 0) {
2528*9781SMoriah.Waterland@Sun.COM 					progerr(ERR_ADMBD, srcinst,
2529*9781SMoriah.Waterland@Sun.COM 						oldValue, adm.basedir);
2530*9781SMoriah.Waterland@Sun.COM 					/* administration */
2531*9781SMoriah.Waterland@Sun.COM 					retcode = 4;
2532*9781SMoriah.Waterland@Sun.COM 					break;
2533*9781SMoriah.Waterland@Sun.COM 				}
2534*9781SMoriah.Waterland@Sun.COM 			} else if (ADM(basedir, "ask")) {
2535*9781SMoriah.Waterland@Sun.COM 				/*
2536*9781SMoriah.Waterland@Sun.COM 				 * If it's going to ask
2537*9781SMoriah.Waterland@Sun.COM 				 * later, let it know that it
2538*9781SMoriah.Waterland@Sun.COM 				 * *must* agree with the
2539*9781SMoriah.Waterland@Sun.COM 				 * BASEDIR we just picked up.
2540*9781SMoriah.Waterland@Sun.COM 				 */
2541*9781SMoriah.Waterland@Sun.COM 				adm.basedir = "update";
2542*9781SMoriah.Waterland@Sun.COM 				echoDebug(DBG_MERGINFOS_ASK_BASEDIR);
2543*9781SMoriah.Waterland@Sun.COM 			}
2544*9781SMoriah.Waterland@Sun.COM 
2545*9781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_MERGINFOS_SET_BASEDIR, oldValue);
2546*9781SMoriah.Waterland@Sun.COM 			putparam(param, oldValue);
2547*9781SMoriah.Waterland@Sun.COM 			continue;
2548*9781SMoriah.Waterland@Sun.COM 		}
2549*9781SMoriah.Waterland@Sun.COM 
2550*9781SMoriah.Waterland@Sun.COM 		/*
2551*9781SMoriah.Waterland@Sun.COM 		 * determine if there is a new value for this attribute.
2552*9781SMoriah.Waterland@Sun.COM 		 */
2553*9781SMoriah.Waterland@Sun.COM 
2554*9781SMoriah.Waterland@Sun.COM 		newValue = getenv(param);
2555*9781SMoriah.Waterland@Sun.COM 
2556*9781SMoriah.Waterland@Sun.COM 		/*
2557*9781SMoriah.Waterland@Sun.COM 		 * If zone attributes of patch packages haven't been verified
2558*9781SMoriah.Waterland@Sun.COM 		 * by pdo, if there is no new value, and a zone attribute
2559*9781SMoriah.Waterland@Sun.COM 		 * is being changed, it is the same as setting the zone package
2560*9781SMoriah.Waterland@Sun.COM 		 * attribute to 'false' - make sure current setting is 'false'.
2561*9781SMoriah.Waterland@Sun.COM 		 */
2562*9781SMoriah.Waterland@Sun.COM 
2563*9781SMoriah.Waterland@Sun.COM 		if ((patchPkgInstall == B_FALSE) && (newValue == NULL) &&
2564*9781SMoriah.Waterland@Sun.COM 		    (setZoneAttribute == B_TRUE) &&
2565*9781SMoriah.Waterland@Sun.COM 		    (strcasecmp(oldValue, "false") != 0)) {
2566*9781SMoriah.Waterland@Sun.COM 
2567*9781SMoriah.Waterland@Sun.COM 			/* unset existing non-"false" zone pkg attr */
2568*9781SMoriah.Waterland@Sun.COM 			progerr(ERR_MERGINFOS_UNSET_ZONEATTR,
2569*9781SMoriah.Waterland@Sun.COM 				pkgName, pkgVersion, param, oldValue);
2570*9781SMoriah.Waterland@Sun.COM 			retcode = 1;
2571*9781SMoriah.Waterland@Sun.COM 			break;
2572*9781SMoriah.Waterland@Sun.COM 		}
2573*9781SMoriah.Waterland@Sun.COM 
2574*9781SMoriah.Waterland@Sun.COM 		/* retain old value if no new value specified */
2575*9781SMoriah.Waterland@Sun.COM 
2576*9781SMoriah.Waterland@Sun.COM 		if (newValue == NULL) {
2577*9781SMoriah.Waterland@Sun.COM 			/* no new value - retain the old value */
2578*9781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_MERGINFOS_RETAIN_OLD, param, oldValue);
2579*9781SMoriah.Waterland@Sun.COM 			putparam(param, oldValue);
2580*9781SMoriah.Waterland@Sun.COM 			continue;
2581*9781SMoriah.Waterland@Sun.COM 		}
2582*9781SMoriah.Waterland@Sun.COM 
2583*9781SMoriah.Waterland@Sun.COM 		/* note if the old and new values are the same */
2584*9781SMoriah.Waterland@Sun.COM 
2585*9781SMoriah.Waterland@Sun.COM 		if (strcmp(newValue, oldValue) == 0) {
2586*9781SMoriah.Waterland@Sun.COM 			/* set existing package parameter to same value */
2587*9781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_MERGINFOS_SET_DUPLICATE, param, oldValue);
2588*9781SMoriah.Waterland@Sun.COM 			continue;
2589*9781SMoriah.Waterland@Sun.COM 		}
2590*9781SMoriah.Waterland@Sun.COM 
2591*9781SMoriah.Waterland@Sun.COM 		/*
2592*9781SMoriah.Waterland@Sun.COM 		 * If zone attributes of patch packages haven't been verified
2593*9781SMoriah.Waterland@Sun.COM 		 * by pdo, check if old and new values differ.
2594*9781SMoriah.Waterland@Sun.COM 		 * Error if zone parameter
2595*9781SMoriah.Waterland@Sun.COM 		 */
2596*9781SMoriah.Waterland@Sun.COM 
2597*9781SMoriah.Waterland@Sun.COM 		if ((patchPkgInstall == B_FALSE) &&
2598*9781SMoriah.Waterland@Sun.COM 		    (setZoneAttribute == B_TRUE)) {
2599*9781SMoriah.Waterland@Sun.COM 			/* illegal change to zone attribute */
2600*9781SMoriah.Waterland@Sun.COM 
2601*9781SMoriah.Waterland@Sun.COM 			progerr(ERR_MERGINFOS_CHANGE_ZONEATTR, pkgName,
2602*9781SMoriah.Waterland@Sun.COM 				pkgVersion, param, oldValue, newValue);
2603*9781SMoriah.Waterland@Sun.COM 
2604*9781SMoriah.Waterland@Sun.COM 			/* set return code to "fatal error" */
2605*9781SMoriah.Waterland@Sun.COM 			retcode = 1;
2606*9781SMoriah.Waterland@Sun.COM 			break;
2607*9781SMoriah.Waterland@Sun.COM 		}
2608*9781SMoriah.Waterland@Sun.COM 
2609*9781SMoriah.Waterland@Sun.COM 		/* note valid change to existing package parameter */
2610*9781SMoriah.Waterland@Sun.COM 
2611*9781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_MERGINFOS_SET_CHANGE, param,
2612*9781SMoriah.Waterland@Sun.COM 				oldValue, newValue);
2613*9781SMoriah.Waterland@Sun.COM 	}
2614*9781SMoriah.Waterland@Sun.COM 
2615*9781SMoriah.Waterland@Sun.COM 	/* close handle on currently installed package's pkginfo file */
2616*9781SMoriah.Waterland@Sun.COM 
2617*9781SMoriah.Waterland@Sun.COM 	(void) fclose(fp);
2618*9781SMoriah.Waterland@Sun.COM 
2619*9781SMoriah.Waterland@Sun.COM 	/* return error if not successful up to this point */
2620*9781SMoriah.Waterland@Sun.COM 
2621*9781SMoriah.Waterland@Sun.COM 	if (retcode != 0) {
2622*9781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_MERGINFOS_EXIT, pkginfo_path, retcode);
2623*9781SMoriah.Waterland@Sun.COM 
2624*9781SMoriah.Waterland@Sun.COM 		return (retcode);
2625*9781SMoriah.Waterland@Sun.COM 	}
2626*9781SMoriah.Waterland@Sun.COM 
2627*9781SMoriah.Waterland@Sun.COM 	/*
2628*9781SMoriah.Waterland@Sun.COM 	 * Skip this if() section, if zone attributes of patch packages
2629*9781SMoriah.Waterland@Sun.COM 	 * have been verified by pdo.
2630*9781SMoriah.Waterland@Sun.COM 	 */
2631*9781SMoriah.Waterland@Sun.COM 
2632*9781SMoriah.Waterland@Sun.COM 	if (patchPkgInstall == B_FALSE) {
2633*9781SMoriah.Waterland@Sun.COM 
2634*9781SMoriah.Waterland@Sun.COM 		/*
2635*9781SMoriah.Waterland@Sun.COM 		 * verify that no zone attribute has been
2636*9781SMoriah.Waterland@Sun.COM 		 * set to an invalid value
2637*9781SMoriah.Waterland@Sun.COM 		 */
2638*9781SMoriah.Waterland@Sun.COM 
2639*9781SMoriah.Waterland@Sun.COM 		/* SUNW_PKG_ALLZONES */
2640*9781SMoriah.Waterland@Sun.COM 
2641*9781SMoriah.Waterland@Sun.COM 		newValue = getenv(PKG_ALLZONES_VARIABLE);
2642*9781SMoriah.Waterland@Sun.COM 
2643*9781SMoriah.Waterland@Sun.COM 		/*
2644*9781SMoriah.Waterland@Sun.COM 		 * complain if setting SUNW_PKG_ALLZONES to other than "false"
2645*9781SMoriah.Waterland@Sun.COM 		 */
2646*9781SMoriah.Waterland@Sun.COM 
2647*9781SMoriah.Waterland@Sun.COM 
2648*9781SMoriah.Waterland@Sun.COM 		if ((newValue != NULL) && (*SUNW_PKG_ALLZONES == '\0') &&
2649*9781SMoriah.Waterland@Sun.COM 		    (strcasecmp(newValue, "false") != 0)) {
2650*9781SMoriah.Waterland@Sun.COM 			/* change ALLZONES from "true" to "false" (unset) */
2651*9781SMoriah.Waterland@Sun.COM 			progerr(ERR_MERGINFOS_SET_ZONEATTR, pkgName,
2652*9781SMoriah.Waterland@Sun.COM 			    pkgVersion, PKG_ALLZONES_VARIABLE, newValue);
2653*9781SMoriah.Waterland@Sun.COM 			return (1);
2654*9781SMoriah.Waterland@Sun.COM 		}
2655*9781SMoriah.Waterland@Sun.COM 
2656*9781SMoriah.Waterland@Sun.COM 		/* SUNW_PKG_THISZONE */
2657*9781SMoriah.Waterland@Sun.COM 
2658*9781SMoriah.Waterland@Sun.COM 		newValue = getenv(PKG_THISZONE_VARIABLE);
2659*9781SMoriah.Waterland@Sun.COM 
2660*9781SMoriah.Waterland@Sun.COM 		/*
2661*9781SMoriah.Waterland@Sun.COM 		 * complain if setting SUNW_PKG_THISZONE to other than "false"
2662*9781SMoriah.Waterland@Sun.COM 		 */
2663*9781SMoriah.Waterland@Sun.COM 
2664*9781SMoriah.Waterland@Sun.COM 		if ((newValue != NULL) && (*SUNW_PKG_THISZONE == '\0') &&
2665*9781SMoriah.Waterland@Sun.COM 		    (strcasecmp(newValue, "false") != 0)) {
2666*9781SMoriah.Waterland@Sun.COM 			/* change THISZONE from "true" to "false" (unset) */
2667*9781SMoriah.Waterland@Sun.COM 			progerr(ERR_MERGINFOS_SET_ZONEATTR, pkgName,
2668*9781SMoriah.Waterland@Sun.COM 			    pkgVersion, PKG_THISZONE_VARIABLE, newValue);
2669*9781SMoriah.Waterland@Sun.COM 			return (1);
2670*9781SMoriah.Waterland@Sun.COM 		}
2671*9781SMoriah.Waterland@Sun.COM 
2672*9781SMoriah.Waterland@Sun.COM 		/* SUNW_PKG_HOLLOW */
2673*9781SMoriah.Waterland@Sun.COM 
2674*9781SMoriah.Waterland@Sun.COM 		newValue = getenv(PKG_HOLLOW_VARIABLE);
2675*9781SMoriah.Waterland@Sun.COM 
2676*9781SMoriah.Waterland@Sun.COM 		/* complain if setting SUNW_PKG_HOLLOW to other than "false" */
2677*9781SMoriah.Waterland@Sun.COM 
2678*9781SMoriah.Waterland@Sun.COM 		if ((newValue != NULL) && (*SUNW_PKG_HOLLOW == '\0') &&
2679*9781SMoriah.Waterland@Sun.COM 		    (strcasecmp(newValue, "false") != 0)) {
2680*9781SMoriah.Waterland@Sun.COM 			/* change HOLLOW from "true" to 'false" (unset) */
2681*9781SMoriah.Waterland@Sun.COM 			progerr(ERR_MERGINFOS_SET_ZONEATTR, pkgName,
2682*9781SMoriah.Waterland@Sun.COM 			    pkgVersion, PKG_HOLLOW_VARIABLE, newValue);
2683*9781SMoriah.Waterland@Sun.COM 			return (1);
2684*9781SMoriah.Waterland@Sun.COM 		}
2685*9781SMoriah.Waterland@Sun.COM 
2686*9781SMoriah.Waterland@Sun.COM 	}
2687*9781SMoriah.Waterland@Sun.COM 
2688*9781SMoriah.Waterland@Sun.COM 	/* return */
2689*9781SMoriah.Waterland@Sun.COM 
2690*9781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_MERGINFOS_EXIT, pkginfo_path, 0);
2691*9781SMoriah.Waterland@Sun.COM 
2692*9781SMoriah.Waterland@Sun.COM 	return (0);
2693*9781SMoriah.Waterland@Sun.COM }
2694*9781SMoriah.Waterland@Sun.COM 
2695*9781SMoriah.Waterland@Sun.COM static void
2696*9781SMoriah.Waterland@Sun.COM set_dryrun_dir_loc(void)
2697*9781SMoriah.Waterland@Sun.COM {
2698*9781SMoriah.Waterland@Sun.COM 	/* Set pkg location to the dryrun directory */
2699*9781SMoriah.Waterland@Sun.COM 	set_PKGLOC(pkgdrtarg);
2700*9781SMoriah.Waterland@Sun.COM 	(void) snprintf(pkgloc, sizeof (pkgloc),
2701*9781SMoriah.Waterland@Sun.COM 			"%s/%s", get_PKGLOC(), pkginst);
2702*9781SMoriah.Waterland@Sun.COM 	(void) snprintf(pkgbin, sizeof (pkgbin),
2703*9781SMoriah.Waterland@Sun.COM 			"%s/install", pkgloc);
2704*9781SMoriah.Waterland@Sun.COM 	(void) snprintf(pkgsav, sizeof (pkgsav),
2705*9781SMoriah.Waterland@Sun.COM 			"%s/save", pkgloc);
2706*9781SMoriah.Waterland@Sun.COM 	(void) snprintf(ilockfile, sizeof (ilockfile),
2707*9781SMoriah.Waterland@Sun.COM 			"%s/!I-Lock!", pkgloc);
2708*9781SMoriah.Waterland@Sun.COM 	(void) snprintf(rlockfile, sizeof (rlockfile),
2709*9781SMoriah.Waterland@Sun.COM 			"%s/!R-Lock!", pkgloc);
2710*9781SMoriah.Waterland@Sun.COM 	(void) snprintf(savlog, sizeof (savlog),
2711*9781SMoriah.Waterland@Sun.COM 			"%s/logs/%s", get_PKGADM(), pkginst);
2712*9781SMoriah.Waterland@Sun.COM }
2713*9781SMoriah.Waterland@Sun.COM 
2714*9781SMoriah.Waterland@Sun.COM /*
2715*9781SMoriah.Waterland@Sun.COM  * If we are updating a pkg, then we need to copy the "old" pkgloc so that
2716*9781SMoriah.Waterland@Sun.COM  * any scripts that got removed in the new version aren't left around.  So we
2717*9781SMoriah.Waterland@Sun.COM  * copy it here to .save.pkgloc, then in quit() we can restore our state, or
2718*9781SMoriah.Waterland@Sun.COM  * remove it.
2719*9781SMoriah.Waterland@Sun.COM  */
2720*9781SMoriah.Waterland@Sun.COM static int
2721*9781SMoriah.Waterland@Sun.COM cp_pkgdirs(void)
2722*9781SMoriah.Waterland@Sun.COM {
2723*9781SMoriah.Waterland@Sun.COM 	if (in_dryrun_mode()) {
2724*9781SMoriah.Waterland@Sun.COM 		set_dryrun_dir_loc();
2725*9781SMoriah.Waterland@Sun.COM 	}
2726*9781SMoriah.Waterland@Sun.COM 
2727*9781SMoriah.Waterland@Sun.COM 	/*
2728*9781SMoriah.Waterland@Sun.COM 	 * If we're not in dryrun mode and we can find an old set of package
2729*9781SMoriah.Waterland@Sun.COM 	 * files over which the new ones will be written, do the copy.
2730*9781SMoriah.Waterland@Sun.COM 	 */
2731*9781SMoriah.Waterland@Sun.COM 	if (!in_dryrun_mode() && pkgloc[0] && !access(pkgloc, F_OK)) {
2732*9781SMoriah.Waterland@Sun.COM 		int status;
2733*9781SMoriah.Waterland@Sun.COM 		int r;
2734*9781SMoriah.Waterland@Sun.COM 
2735*9781SMoriah.Waterland@Sun.COM 		(void) snprintf(pkgloc_sav, sizeof (pkgloc_sav), "%s/.save.%s",
2736*9781SMoriah.Waterland@Sun.COM 			get_PKGLOC(), pkginst);
2737*9781SMoriah.Waterland@Sun.COM 
2738*9781SMoriah.Waterland@Sun.COM 		/*
2739*9781SMoriah.Waterland@Sun.COM 		 * Even though it takes a while, we use a recursive copy here
2740*9781SMoriah.Waterland@Sun.COM 		 * because if the current pkgadd fails for any reason, we
2741*9781SMoriah.Waterland@Sun.COM 		 * don't want to lose this data.
2742*9781SMoriah.Waterland@Sun.COM 		 */
2743*9781SMoriah.Waterland@Sun.COM 		r = e_ExecCmdList(&status, (char **)NULL, (char *)NULL,
2744*9781SMoriah.Waterland@Sun.COM 			"/usr/bin/cp", "cp", "-r", pkgloc, pkgloc_sav,
2745*9781SMoriah.Waterland@Sun.COM 			(char *)NULL);
2746*9781SMoriah.Waterland@Sun.COM 
2747*9781SMoriah.Waterland@Sun.COM 		if ((r != 0) || (status == -1) || (WEXITSTATUS(status) != 0)) {
2748*9781SMoriah.Waterland@Sun.COM 			progerr(ERR_PKGBINCP, pkgloc, pkgloc_sav);
2749*9781SMoriah.Waterland@Sun.COM 			return (99);
2750*9781SMoriah.Waterland@Sun.COM 		}
2751*9781SMoriah.Waterland@Sun.COM 	}
2752*9781SMoriah.Waterland@Sun.COM 
2753*9781SMoriah.Waterland@Sun.COM 	return (0);
2754*9781SMoriah.Waterland@Sun.COM }
2755*9781SMoriah.Waterland@Sun.COM 
2756*9781SMoriah.Waterland@Sun.COM /*
2757*9781SMoriah.Waterland@Sun.COM  * This implements the pkgask function. It just executes the request script
2758*9781SMoriah.Waterland@Sun.COM  * and stores the results in a response file.
2759*9781SMoriah.Waterland@Sun.COM  */
2760*9781SMoriah.Waterland@Sun.COM static void
2761*9781SMoriah.Waterland@Sun.COM do_pkgask(boolean_t a_run_request_as_root)
2762*9781SMoriah.Waterland@Sun.COM {
2763*9781SMoriah.Waterland@Sun.COM 	if (pkgdev.cdevice) {
2764*9781SMoriah.Waterland@Sun.COM 		unpack();
2765*9781SMoriah.Waterland@Sun.COM 		if (!suppressCopyright) {
2766*9781SMoriah.Waterland@Sun.COM 			copyright();
2767*9781SMoriah.Waterland@Sun.COM 		}
2768*9781SMoriah.Waterland@Sun.COM 	}
2769*9781SMoriah.Waterland@Sun.COM 	(void) snprintf(path, sizeof (path), "%s/%s", instdir, REQUEST_FILE);
2770*9781SMoriah.Waterland@Sun.COM 	if (access(path, F_OK)) {
2771*9781SMoriah.Waterland@Sun.COM 		progerr(ERR_NOREQUEST);
2772*9781SMoriah.Waterland@Sun.COM 		quit(1);
2773*9781SMoriah.Waterland@Sun.COM 		/*NOTREACHED*/
2774*9781SMoriah.Waterland@Sun.COM 	}
2775*9781SMoriah.Waterland@Sun.COM 
2776*9781SMoriah.Waterland@Sun.COM 	(void) set_respfile(respfile, srcinst, RESP_WR);
2777*9781SMoriah.Waterland@Sun.COM 
2778*9781SMoriah.Waterland@Sun.COM 	if (is_a_respfile()) {
2779*9781SMoriah.Waterland@Sun.COM 		ckreturn(reqexec(update, path, non_abi_scripts,
2780*9781SMoriah.Waterland@Sun.COM 			a_run_request_as_root), ERR_REQUEST);
2781*9781SMoriah.Waterland@Sun.COM 	} else {
2782*9781SMoriah.Waterland@Sun.COM 		failflag++;
2783*9781SMoriah.Waterland@Sun.COM 	}
2784*9781SMoriah.Waterland@Sun.COM 
2785*9781SMoriah.Waterland@Sun.COM 	if (warnflag || failflag) {
2786*9781SMoriah.Waterland@Sun.COM 		(void) remove(respfile);
2787*9781SMoriah.Waterland@Sun.COM 		echo("\nResponse file <%s> was not created.",
2788*9781SMoriah.Waterland@Sun.COM 			get_respfile());
2789*9781SMoriah.Waterland@Sun.COM 	} else {
2790*9781SMoriah.Waterland@Sun.COM 		echo("\nResponse file <%s> was created.",
2791*9781SMoriah.Waterland@Sun.COM 			get_respfile());
2792*9781SMoriah.Waterland@Sun.COM 	}
2793*9781SMoriah.Waterland@Sun.COM 
2794*9781SMoriah.Waterland@Sun.COM 	quit(0);
2795*9781SMoriah.Waterland@Sun.COM 	/*NOTREACHED*/
2796*9781SMoriah.Waterland@Sun.COM }
2797*9781SMoriah.Waterland@Sun.COM 
2798*9781SMoriah.Waterland@Sun.COM /*
2799*9781SMoriah.Waterland@Sun.COM  * This function runs a check utility and acts appropriately based upon the
2800*9781SMoriah.Waterland@Sun.COM  * return code. It deals appropriately with the dryrun file if it is present.
2801*9781SMoriah.Waterland@Sun.COM  */
2802*9781SMoriah.Waterland@Sun.COM static void
2803*9781SMoriah.Waterland@Sun.COM ck_w_dryrun(int (*func)(), int type)
2804*9781SMoriah.Waterland@Sun.COM {
2805*9781SMoriah.Waterland@Sun.COM 	int n;
2806*9781SMoriah.Waterland@Sun.COM 
2807*9781SMoriah.Waterland@Sun.COM 	n = func();
2808*9781SMoriah.Waterland@Sun.COM 	if (in_dryrun_mode())
2809*9781SMoriah.Waterland@Sun.COM 		set_dr_info(type, !n);
2810*9781SMoriah.Waterland@Sun.COM 
2811*9781SMoriah.Waterland@Sun.COM 	if (n) {
2812*9781SMoriah.Waterland@Sun.COM 		quit(n);
2813*9781SMoriah.Waterland@Sun.COM 		/*NOTREACHED*/
2814*9781SMoriah.Waterland@Sun.COM 	}
2815*9781SMoriah.Waterland@Sun.COM }
2816*9781SMoriah.Waterland@Sun.COM 
2817*9781SMoriah.Waterland@Sun.COM /*
2818*9781SMoriah.Waterland@Sun.COM  * This function deletes all install class action scripts from the package
2819*9781SMoriah.Waterland@Sun.COM  * directory on the root filesystem.
2820*9781SMoriah.Waterland@Sun.COM  */
2821*9781SMoriah.Waterland@Sun.COM static void
2822*9781SMoriah.Waterland@Sun.COM rm_icas(char *cas_dir)
2823*9781SMoriah.Waterland@Sun.COM {
2824*9781SMoriah.Waterland@Sun.COM 	DIR	*pdirfp;
2825*9781SMoriah.Waterland@Sun.COM 	struct	dirent *dp;
2826*9781SMoriah.Waterland@Sun.COM 	char path[PATH_MAX];
2827*9781SMoriah.Waterland@Sun.COM 
2828*9781SMoriah.Waterland@Sun.COM 	if ((pdirfp = opendir(cas_dir)) == NULL)
2829*9781SMoriah.Waterland@Sun.COM 		return;
2830*9781SMoriah.Waterland@Sun.COM 
2831*9781SMoriah.Waterland@Sun.COM 	while ((dp = readdir(pdirfp)) != NULL) {
2832*9781SMoriah.Waterland@Sun.COM 		if (dp->d_name[0] == '.')
2833*9781SMoriah.Waterland@Sun.COM 			continue;
2834*9781SMoriah.Waterland@Sun.COM 
2835*9781SMoriah.Waterland@Sun.COM 		if (dp->d_name[0] == 'i' && dp->d_name[1] == '.') {
2836*9781SMoriah.Waterland@Sun.COM 			(void) snprintf(path, sizeof (path),
2837*9781SMoriah.Waterland@Sun.COM 				"%s/%s", cas_dir, dp->d_name);
2838*9781SMoriah.Waterland@Sun.COM 			(void) remove(path);
2839*9781SMoriah.Waterland@Sun.COM 		}
2840*9781SMoriah.Waterland@Sun.COM 	}
2841*9781SMoriah.Waterland@Sun.COM 	(void) closedir(pdirfp);
2842*9781SMoriah.Waterland@Sun.COM }
2843*9781SMoriah.Waterland@Sun.COM 
2844*9781SMoriah.Waterland@Sun.COM void
2845*9781SMoriah.Waterland@Sun.COM ckreturn(int retcode, char *msg)
2846*9781SMoriah.Waterland@Sun.COM {
2847*9781SMoriah.Waterland@Sun.COM 	switch (retcode) {
2848*9781SMoriah.Waterland@Sun.COM 		case 2:
2849*9781SMoriah.Waterland@Sun.COM 		case 12:
2850*9781SMoriah.Waterland@Sun.COM 		case 22:
2851*9781SMoriah.Waterland@Sun.COM 		warnflag++;
2852*9781SMoriah.Waterland@Sun.COM 		if (msg) {
2853*9781SMoriah.Waterland@Sun.COM 			progerr("%s", msg);
2854*9781SMoriah.Waterland@Sun.COM 		}
2855*9781SMoriah.Waterland@Sun.COM 		/*FALLTHRU*/
2856*9781SMoriah.Waterland@Sun.COM 		case 10:
2857*9781SMoriah.Waterland@Sun.COM 		case 20:
2858*9781SMoriah.Waterland@Sun.COM 		if (retcode >= 10 && retcode < 20) {
2859*9781SMoriah.Waterland@Sun.COM 			dreboot++;
2860*9781SMoriah.Waterland@Sun.COM 		}
2861*9781SMoriah.Waterland@Sun.COM 		if (retcode >= 20) {
2862*9781SMoriah.Waterland@Sun.COM 			ireboot++;
2863*9781SMoriah.Waterland@Sun.COM 		}
2864*9781SMoriah.Waterland@Sun.COM 		/*FALLTHRU*/
2865*9781SMoriah.Waterland@Sun.COM 		case 0:
2866*9781SMoriah.Waterland@Sun.COM 		break; /* okay */
2867*9781SMoriah.Waterland@Sun.COM 
2868*9781SMoriah.Waterland@Sun.COM 		case -1:
2869*9781SMoriah.Waterland@Sun.COM 		retcode = 99;
2870*9781SMoriah.Waterland@Sun.COM 		/*FALLTHRU*/
2871*9781SMoriah.Waterland@Sun.COM 		case 99:
2872*9781SMoriah.Waterland@Sun.COM 		case 1:
2873*9781SMoriah.Waterland@Sun.COM 		case 11:
2874*9781SMoriah.Waterland@Sun.COM 		case 21:
2875*9781SMoriah.Waterland@Sun.COM 		case 4:
2876*9781SMoriah.Waterland@Sun.COM 		case 14:
2877*9781SMoriah.Waterland@Sun.COM 		case 24:
2878*9781SMoriah.Waterland@Sun.COM 		case 5:
2879*9781SMoriah.Waterland@Sun.COM 		case 15:
2880*9781SMoriah.Waterland@Sun.COM 		case 25:
2881*9781SMoriah.Waterland@Sun.COM 		if (msg) {
2882*9781SMoriah.Waterland@Sun.COM 			progerr("%s", msg);
2883*9781SMoriah.Waterland@Sun.COM 		}
2884*9781SMoriah.Waterland@Sun.COM 		/*FALLTHRU*/
2885*9781SMoriah.Waterland@Sun.COM 		case 3:
2886*9781SMoriah.Waterland@Sun.COM 		case 13:
2887*9781SMoriah.Waterland@Sun.COM 		case 23:
2888*9781SMoriah.Waterland@Sun.COM 		quit(retcode);
2889*9781SMoriah.Waterland@Sun.COM 		/*NOTREACHED*/
2890*9781SMoriah.Waterland@Sun.COM 		default:
2891*9781SMoriah.Waterland@Sun.COM 		if (msg) {
2892*9781SMoriah.Waterland@Sun.COM 			progerr("%s", msg);
2893*9781SMoriah.Waterland@Sun.COM 		}
2894*9781SMoriah.Waterland@Sun.COM 		quit(1);
2895*9781SMoriah.Waterland@Sun.COM 		/*NOTREACHED*/
2896*9781SMoriah.Waterland@Sun.COM 	}
2897*9781SMoriah.Waterland@Sun.COM }
2898*9781SMoriah.Waterland@Sun.COM 
2899*9781SMoriah.Waterland@Sun.COM static void
2900*9781SMoriah.Waterland@Sun.COM copyright(void)
2901*9781SMoriah.Waterland@Sun.COM {
2902*9781SMoriah.Waterland@Sun.COM 	FILE	*fp;
2903*9781SMoriah.Waterland@Sun.COM 	char	line[LSIZE];
2904*9781SMoriah.Waterland@Sun.COM 	char	path[PATH_MAX];
2905*9781SMoriah.Waterland@Sun.COM 
2906*9781SMoriah.Waterland@Sun.COM 	/* Compose full path for copyright file */
2907*9781SMoriah.Waterland@Sun.COM 	(void) snprintf(path, sizeof (path), "%s/%s", instdir, COPYRIGHT_FILE);
2908*9781SMoriah.Waterland@Sun.COM 
2909*9781SMoriah.Waterland@Sun.COM 	if ((fp = fopen(path, "r")) == NULL) {
2910*9781SMoriah.Waterland@Sun.COM 		if (getenv("VENDOR") != NULL)
2911*9781SMoriah.Waterland@Sun.COM 			echo(getenv("VENDOR"));
2912*9781SMoriah.Waterland@Sun.COM 	} else {
2913*9781SMoriah.Waterland@Sun.COM 		while (fgets(line, LSIZE, fp))
2914*9781SMoriah.Waterland@Sun.COM 			(void) fprintf(stdout, "%s", line); /* bug #1083713 */
2915*9781SMoriah.Waterland@Sun.COM 		(void) fclose(fp);
2916*9781SMoriah.Waterland@Sun.COM 	}
2917*9781SMoriah.Waterland@Sun.COM }
2918*9781SMoriah.Waterland@Sun.COM 
2919*9781SMoriah.Waterland@Sun.COM static int
2920*9781SMoriah.Waterland@Sun.COM rdonly(char *p)
2921*9781SMoriah.Waterland@Sun.COM {
2922*9781SMoriah.Waterland@Sun.COM 	int	i;
2923*9781SMoriah.Waterland@Sun.COM 
2924*9781SMoriah.Waterland@Sun.COM 	for (i = 0; ro_params[i]; i++) {
2925*9781SMoriah.Waterland@Sun.COM 		if (strcmp(p, ro_params[i]) == 0)
2926*9781SMoriah.Waterland@Sun.COM 			return (1);
2927*9781SMoriah.Waterland@Sun.COM 	}
2928*9781SMoriah.Waterland@Sun.COM 	return (0);
2929*9781SMoriah.Waterland@Sun.COM }
2930*9781SMoriah.Waterland@Sun.COM 
2931*9781SMoriah.Waterland@Sun.COM static void
2932*9781SMoriah.Waterland@Sun.COM unpack(void)
2933*9781SMoriah.Waterland@Sun.COM {
2934*9781SMoriah.Waterland@Sun.COM 	/*
2935*9781SMoriah.Waterland@Sun.COM 	 * read in next part from stream, even if we decide
2936*9781SMoriah.Waterland@Sun.COM 	 * later that we don't need it
2937*9781SMoriah.Waterland@Sun.COM 	 */
2938*9781SMoriah.Waterland@Sun.COM 	if (dparts < 1) {
2939*9781SMoriah.Waterland@Sun.COM 		progerr(ERR_DSTREAMCNT);
2940*9781SMoriah.Waterland@Sun.COM 		quit(99);
2941*9781SMoriah.Waterland@Sun.COM 		/*NOTREACHED*/
2942*9781SMoriah.Waterland@Sun.COM 	}
2943*9781SMoriah.Waterland@Sun.COM 	if ((access(instdir, F_OK) == 0) && rrmdir(instdir)) {
2944*9781SMoriah.Waterland@Sun.COM 		progerr(ERR_RMDIR, instdir);
2945*9781SMoriah.Waterland@Sun.COM 		quit(99);
2946*9781SMoriah.Waterland@Sun.COM 		/*NOTREACHED*/
2947*9781SMoriah.Waterland@Sun.COM 	}
2948*9781SMoriah.Waterland@Sun.COM 	if (mkdir(instdir, 0755)) {
2949*9781SMoriah.Waterland@Sun.COM 		progerr(ERR_MKDIR, instdir);
2950*9781SMoriah.Waterland@Sun.COM 		quit(99);
2951*9781SMoriah.Waterland@Sun.COM 		/*NOTREACHED*/
2952*9781SMoriah.Waterland@Sun.COM 	}
2953*9781SMoriah.Waterland@Sun.COM 	if (chdir(instdir)) {
2954*9781SMoriah.Waterland@Sun.COM 		progerr(ERR_CHDIR, instdir);
2955*9781SMoriah.Waterland@Sun.COM 		quit(99);
2956*9781SMoriah.Waterland@Sun.COM 		/*NOTREACHED*/
2957*9781SMoriah.Waterland@Sun.COM 	}
2958*9781SMoriah.Waterland@Sun.COM 	if (!ds_fd_open()) {
2959*9781SMoriah.Waterland@Sun.COM 		dparts = ds_findpkg(pkgdev.cdevice, srcinst);
2960*9781SMoriah.Waterland@Sun.COM 		if (dparts < 1) {
2961*9781SMoriah.Waterland@Sun.COM 			progerr(ERR_DSARCH, srcinst);
2962*9781SMoriah.Waterland@Sun.COM 			quit(99);
2963*9781SMoriah.Waterland@Sun.COM 			/*NOTREACHED*/
2964*9781SMoriah.Waterland@Sun.COM 		}
2965*9781SMoriah.Waterland@Sun.COM 	}
2966*9781SMoriah.Waterland@Sun.COM 
2967*9781SMoriah.Waterland@Sun.COM 	dparts--;
2968*9781SMoriah.Waterland@Sun.COM 
2969*9781SMoriah.Waterland@Sun.COM 	if (ds_next(pkgdev.cdevice, instdir)) {
2970*9781SMoriah.Waterland@Sun.COM 		progerr(ERR_DSTREAM);
2971*9781SMoriah.Waterland@Sun.COM 		quit(99);
2972*9781SMoriah.Waterland@Sun.COM 		/*NOTREACHED*/
2973*9781SMoriah.Waterland@Sun.COM 	}
2974*9781SMoriah.Waterland@Sun.COM 	if (chdir(get_PKGADM())) {
2975*9781SMoriah.Waterland@Sun.COM 		progerr(ERR_CHDIR, get_PKGADM());
2976*9781SMoriah.Waterland@Sun.COM 		quit(99);
2977*9781SMoriah.Waterland@Sun.COM 		/*NOTREACHED*/
2978*9781SMoriah.Waterland@Sun.COM 	}
2979*9781SMoriah.Waterland@Sun.COM 	ds_close(1);
2980*9781SMoriah.Waterland@Sun.COM }
2981*9781SMoriah.Waterland@Sun.COM 
2982*9781SMoriah.Waterland@Sun.COM static void
2983*9781SMoriah.Waterland@Sun.COM usage(void)
2984*9781SMoriah.Waterland@Sun.COM {
2985*9781SMoriah.Waterland@Sun.COM 	(void) fprintf(stderr, ERR_USAGE_PKGINSTALL);
2986*9781SMoriah.Waterland@Sun.COM 	exit(1);
2987*9781SMoriah.Waterland@Sun.COM 	/*NOTREACHED*/
2988*9781SMoriah.Waterland@Sun.COM }
2989