xref: /onnv-gate/usr/src/cmd/svr4pkg/pkginstall/main.c (revision 12734:76969fc28795)
19781SMoriah.Waterland@Sun.COM /*
29781SMoriah.Waterland@Sun.COM  * CDDL HEADER START
39781SMoriah.Waterland@Sun.COM  *
49781SMoriah.Waterland@Sun.COM  * The contents of this file are subject to the terms of the
59781SMoriah.Waterland@Sun.COM  * Common Development and Distribution License (the "License").
69781SMoriah.Waterland@Sun.COM  * You may not use this file except in compliance with the License.
79781SMoriah.Waterland@Sun.COM  *
89781SMoriah.Waterland@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
99781SMoriah.Waterland@Sun.COM  * or http://www.opensolaris.org/os/licensing.
109781SMoriah.Waterland@Sun.COM  * See the License for the specific language governing permissions
119781SMoriah.Waterland@Sun.COM  * and limitations under the License.
129781SMoriah.Waterland@Sun.COM  *
139781SMoriah.Waterland@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
149781SMoriah.Waterland@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
159781SMoriah.Waterland@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
169781SMoriah.Waterland@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
179781SMoriah.Waterland@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
189781SMoriah.Waterland@Sun.COM  *
199781SMoriah.Waterland@Sun.COM  * CDDL HEADER END
209781SMoriah.Waterland@Sun.COM  */
219781SMoriah.Waterland@Sun.COM 
229781SMoriah.Waterland@Sun.COM /*
2312222SNagaraj.Yedathore@Sun.COM  * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
249781SMoriah.Waterland@Sun.COM  */
259781SMoriah.Waterland@Sun.COM 
269781SMoriah.Waterland@Sun.COM /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
279781SMoriah.Waterland@Sun.COM /* All Rights Reserved */
289781SMoriah.Waterland@Sun.COM 
299781SMoriah.Waterland@Sun.COM 
309781SMoriah.Waterland@Sun.COM #include <stdio.h>
319781SMoriah.Waterland@Sun.COM #include <time.h>
329781SMoriah.Waterland@Sun.COM #include <wait.h>
339781SMoriah.Waterland@Sun.COM #include <stdlib.h>
349781SMoriah.Waterland@Sun.COM #include <unistd.h>
359781SMoriah.Waterland@Sun.COM #include <ulimit.h>
369781SMoriah.Waterland@Sun.COM #include <sys/stat.h>
379781SMoriah.Waterland@Sun.COM #include <sys/statvfs.h>
389781SMoriah.Waterland@Sun.COM #include <fcntl.h>
399781SMoriah.Waterland@Sun.COM #include <errno.h>
409781SMoriah.Waterland@Sun.COM #include <ctype.h>
419781SMoriah.Waterland@Sun.COM #include <dirent.h>
429781SMoriah.Waterland@Sun.COM #include <string.h>
439781SMoriah.Waterland@Sun.COM #include <signal.h>
449781SMoriah.Waterland@Sun.COM #include <locale.h>
459781SMoriah.Waterland@Sun.COM #include <libintl.h>
469781SMoriah.Waterland@Sun.COM #include <pkgstrct.h>
479781SMoriah.Waterland@Sun.COM #include <pkginfo.h>
489781SMoriah.Waterland@Sun.COM #include <pkgdev.h>
499781SMoriah.Waterland@Sun.COM #include <pkglocs.h>
509781SMoriah.Waterland@Sun.COM #include <pwd.h>
519781SMoriah.Waterland@Sun.COM #include <assert.h>
529781SMoriah.Waterland@Sun.COM #include <instzones_api.h>
539781SMoriah.Waterland@Sun.COM #include <pkglib.h>
549781SMoriah.Waterland@Sun.COM #include <pkgweb.h>
559781SMoriah.Waterland@Sun.COM #include <install.h>
569781SMoriah.Waterland@Sun.COM #include <libinst.h>
579781SMoriah.Waterland@Sun.COM #include <libadm.h>
589781SMoriah.Waterland@Sun.COM #include <dryrun.h>
599781SMoriah.Waterland@Sun.COM #include <messages.h>
609781SMoriah.Waterland@Sun.COM #include "pkginstall.h"
619781SMoriah.Waterland@Sun.COM 
629781SMoriah.Waterland@Sun.COM /* imported globals */
639781SMoriah.Waterland@Sun.COM 
649781SMoriah.Waterland@Sun.COM extern char	**environ;
659781SMoriah.Waterland@Sun.COM extern char	*pkgabrv;
669781SMoriah.Waterland@Sun.COM extern char	*pkgname;
679781SMoriah.Waterland@Sun.COM extern char	*pkgarch;
689781SMoriah.Waterland@Sun.COM extern char	*pkgvers;
699781SMoriah.Waterland@Sun.COM extern char	pkgwild[];
709781SMoriah.Waterland@Sun.COM 
719781SMoriah.Waterland@Sun.COM /* libadm(3LIB) */
729781SMoriah.Waterland@Sun.COM 
739781SMoriah.Waterland@Sun.COM extern char	*get_install_root(void);
749781SMoriah.Waterland@Sun.COM 
759781SMoriah.Waterland@Sun.COM /* quit.c */
769781SMoriah.Waterland@Sun.COM 
779781SMoriah.Waterland@Sun.COM extern sighdlrFunc_t	*quitGetTrapHandler(void);
789781SMoriah.Waterland@Sun.COM extern void		quitSetDstreamTmpdir(char *a_dstreamTempDir);
799781SMoriah.Waterland@Sun.COM extern void		quitSetInstallStarted(boolean_t a_installStarted);
809781SMoriah.Waterland@Sun.COM extern void		quitSetPkgask(boolean_t a_pkgaskFlag);
819781SMoriah.Waterland@Sun.COM extern void		quitSetSilentExit(boolean_t a_silentExit);
829781SMoriah.Waterland@Sun.COM extern void		quitSetUpdatingExisting(boolean_t a_updatingExisting);
839781SMoriah.Waterland@Sun.COM extern void		quitSetZoneName(char *a_zoneName);
849781SMoriah.Waterland@Sun.COM 
859781SMoriah.Waterland@Sun.COM 
869781SMoriah.Waterland@Sun.COM /* static globals */
879781SMoriah.Waterland@Sun.COM 
889781SMoriah.Waterland@Sun.COM static char	path[PATH_MAX];
899781SMoriah.Waterland@Sun.COM static int	ck_instbase(void);
909781SMoriah.Waterland@Sun.COM static int	cp_pkgdirs(void);
919781SMoriah.Waterland@Sun.COM static int	merg_pkginfos(struct cl_attr **pclass,
929781SMoriah.Waterland@Sun.COM 		struct cl_attr ***mpclass);
939781SMoriah.Waterland@Sun.COM static int	merg_respfile(void);
949781SMoriah.Waterland@Sun.COM static int	mv_pkgdirs(void);
959781SMoriah.Waterland@Sun.COM static int	rdonly(char *p);
969781SMoriah.Waterland@Sun.COM static void	ck_w_dryrun(int (*func)(), int type);
979781SMoriah.Waterland@Sun.COM static void	copyright(void), usage(void);
989781SMoriah.Waterland@Sun.COM static void	do_pkgask(boolean_t a_run_request_as_root);
999781SMoriah.Waterland@Sun.COM static void	rm_icas(char *casdir);
1009781SMoriah.Waterland@Sun.COM static void	set_dryrun_dir_loc(void);
1019781SMoriah.Waterland@Sun.COM static void	unpack(void);
1029781SMoriah.Waterland@Sun.COM 
1039781SMoriah.Waterland@Sun.COM void	ckreturn(int retcode, char *msg);
1049781SMoriah.Waterland@Sun.COM 
1059781SMoriah.Waterland@Sun.COM static char	*ro_params[] = {
1069781SMoriah.Waterland@Sun.COM 	"PATH", "NAME", "PKG", "PKGINST",
1079781SMoriah.Waterland@Sun.COM 	"VERSION", "ARCH",
1089781SMoriah.Waterland@Sun.COM 	"INSTDATE", "CATEGORY",
1099781SMoriah.Waterland@Sun.COM 	NULL
1109781SMoriah.Waterland@Sun.COM };
1119781SMoriah.Waterland@Sun.COM 
1129781SMoriah.Waterland@Sun.COM /*
1139781SMoriah.Waterland@Sun.COM  * The following variable is the name of the device to which stdin
1149781SMoriah.Waterland@Sun.COM  * is connected during execution of a procedure script. PROC_STDIN is
1159781SMoriah.Waterland@Sun.COM  * correct for all ABI compliant packages. For non-ABI-compliant
1169781SMoriah.Waterland@Sun.COM  * packages, the '-o' command line switch changes this to PROC_XSTDIN
1179781SMoriah.Waterland@Sun.COM  * to allow user interaction during these scripts. -- JST
1189781SMoriah.Waterland@Sun.COM  */
1199781SMoriah.Waterland@Sun.COM static char	*script_in = PROC_STDIN;	/* assume ABI compliance */
1209781SMoriah.Waterland@Sun.COM 
1219781SMoriah.Waterland@Sun.COM static char	*pkgdrtarg = NULL;
1229781SMoriah.Waterland@Sun.COM static char	*pkgcontsrc = NULL;
1239781SMoriah.Waterland@Sun.COM static int	non_abi_scripts = 0;
1249781SMoriah.Waterland@Sun.COM static char	*respfile = NULL;
1259781SMoriah.Waterland@Sun.COM static char	*srcinst = NULL;
1269781SMoriah.Waterland@Sun.COM static int	suppressCopyright = 0;
1279781SMoriah.Waterland@Sun.COM static int	nointeract = 0;
1289781SMoriah.Waterland@Sun.COM 
1299781SMoriah.Waterland@Sun.COM /* exported globals */
1309781SMoriah.Waterland@Sun.COM 
1319781SMoriah.Waterland@Sun.COM char		*msgtext;
1329781SMoriah.Waterland@Sun.COM char		*pkginst = (char *)NULL;
1339781SMoriah.Waterland@Sun.COM char		*rw_block_size = NULL;
1349781SMoriah.Waterland@Sun.COM char		ilockfile[PATH_MAX];
1359781SMoriah.Waterland@Sun.COM char		instdir[PATH_MAX];
1369781SMoriah.Waterland@Sun.COM char		saveSpoolInstallDir[PATH_MAX];
1379781SMoriah.Waterland@Sun.COM char		pkgbin[PATH_MAX];
1389781SMoriah.Waterland@Sun.COM char		pkgloc[PATH_MAX];
1399781SMoriah.Waterland@Sun.COM char		pkgloc_sav[PATH_MAX];
1409781SMoriah.Waterland@Sun.COM char		pkgsav[PATH_MAX];
1419781SMoriah.Waterland@Sun.COM char		rlockfile[PATH_MAX];
1429781SMoriah.Waterland@Sun.COM char		savlog[PATH_MAX];
1439781SMoriah.Waterland@Sun.COM char		tmpdir[PATH_MAX];
1449781SMoriah.Waterland@Sun.COM int		dbchg;
1459781SMoriah.Waterland@Sun.COM int		dparts = 0;
1469781SMoriah.Waterland@Sun.COM int		dreboot = 0;
1479781SMoriah.Waterland@Sun.COM int		failflag = 0;
1489781SMoriah.Waterland@Sun.COM static int	askflag = 0;		/* non-zero if invoked as "pkgask" */
1499781SMoriah.Waterland@Sun.COM int		ireboot = 0;
1509781SMoriah.Waterland@Sun.COM int		maxinst = 1;
1519781SMoriah.Waterland@Sun.COM int		nocnflct;
1529781SMoriah.Waterland@Sun.COM int		nosetuid;
1539781SMoriah.Waterland@Sun.COM int		opresvr4 = 0;
1549781SMoriah.Waterland@Sun.COM int		pkgverbose = 0;
1559781SMoriah.Waterland@Sun.COM int		rprcflag;
1569781SMoriah.Waterland@Sun.COM int		warnflag = 0;
1579781SMoriah.Waterland@Sun.COM struct admin	adm;
1589781SMoriah.Waterland@Sun.COM struct cfextra	**extlist; /* pkgmap structure and other path info */
1599781SMoriah.Waterland@Sun.COM struct pkgdev	pkgdev;
1609781SMoriah.Waterland@Sun.COM fsblkcnt_t	pkgmap_blks = 0LL;
1619781SMoriah.Waterland@Sun.COM 
1629781SMoriah.Waterland@Sun.COM /*
1639781SMoriah.Waterland@Sun.COM  * this global is referenced by:
1649781SMoriah.Waterland@Sun.COM  * getinst - [RW] - incremented if:
1659781SMoriah.Waterland@Sun.COM  * - installing same instance again
1669781SMoriah.Waterland@Sun.COM  * - overwriting an existing instance
1679781SMoriah.Waterland@Sun.COM  * - not installing a new instance
1689781SMoriah.Waterland@Sun.COM  * quit - [RO] - if non-zero and started non-zero:
1699781SMoriah.Waterland@Sun.COM  * - the new <PKGINST>/install directory and rename <PKGINST>/install.save
1709781SMoriah.Waterland@Sun.COM  * - back to <PKGINST>/install
1719781SMoriah.Waterland@Sun.COM  * main.c - [RO] - if non-zero:
1729781SMoriah.Waterland@Sun.COM  * - alter manner in which parameters are setup for scripts
1739781SMoriah.Waterland@Sun.COM  * - set UPDATE=yes in environment
1749781SMoriah.Waterland@Sun.COM  */
1759781SMoriah.Waterland@Sun.COM static int		update = 0;
1769781SMoriah.Waterland@Sun.COM 
1779781SMoriah.Waterland@Sun.COM /* Set by -O debug: debug output is enabled? */
1789781SMoriah.Waterland@Sun.COM 
1799781SMoriah.Waterland@Sun.COM static boolean_t	debugFlag = B_FALSE;
1809781SMoriah.Waterland@Sun.COM 
1819781SMoriah.Waterland@Sun.COM /* Set by the -G option: install packages in global zone only */
1829781SMoriah.Waterland@Sun.COM 
1839781SMoriah.Waterland@Sun.COM static boolean_t	globalZoneOnly = B_FALSE;
1849781SMoriah.Waterland@Sun.COM 
1859781SMoriah.Waterland@Sun.COM /* Set by -O patchPkgInstall */
1869781SMoriah.Waterland@Sun.COM 
1879781SMoriah.Waterland@Sun.COM static boolean_t patchPkgInstall = B_FALSE;
1889781SMoriah.Waterland@Sun.COM 
1899781SMoriah.Waterland@Sun.COM /* Set by -O patchPkgRemoval */
1909781SMoriah.Waterland@Sun.COM 
1919781SMoriah.Waterland@Sun.COM static boolean_t patchPkgRemoval = B_FALSE;
1929781SMoriah.Waterland@Sun.COM 
1939781SMoriah.Waterland@Sun.COM /* Set by -O preinstallcheck */
1949781SMoriah.Waterland@Sun.COM 
1959781SMoriah.Waterland@Sun.COM static boolean_t	preinstallCheck = B_FALSE;
1969781SMoriah.Waterland@Sun.COM 
1979781SMoriah.Waterland@Sun.COM /* Set by -O parent-zone-name= */
1989781SMoriah.Waterland@Sun.COM 
1999781SMoriah.Waterland@Sun.COM static char		*parentZoneName = (char *)NULL;
2009781SMoriah.Waterland@Sun.COM 
2019781SMoriah.Waterland@Sun.COM /* Set by -O parent-zone-type= */
2029781SMoriah.Waterland@Sun.COM 
2039781SMoriah.Waterland@Sun.COM static char		*parentZoneType = (char *)NULL;
2049781SMoriah.Waterland@Sun.COM 
2059781SMoriah.Waterland@Sun.COM #define	DEFPATH		"/sbin:/usr/sbin:/usr/bin"
2069781SMoriah.Waterland@Sun.COM #define	MALSIZ	4	/* best guess at likely maximum value of MAXINST */
2079781SMoriah.Waterland@Sun.COM #define	LSIZE	256	/* maximum line size supported in copyright file */
2089781SMoriah.Waterland@Sun.COM 
2099781SMoriah.Waterland@Sun.COM #ifdef	ALLOW_EXCEPTION_PKG_LIST
2109781SMoriah.Waterland@Sun.COM #define	SCRIPT	0	/* which exception_pkg() pkg list to use (SCRIPTS) */
2119781SMoriah.Waterland@Sun.COM #define	LINK	1	/* which exception_pkg() pkg list to use (SYMLINKS) */
2129781SMoriah.Waterland@Sun.COM #endif
2139781SMoriah.Waterland@Sun.COM 
2149781SMoriah.Waterland@Sun.COM #if !defined(TEXT_DOMAIN)	/* Should be defined by cc -D */
2159781SMoriah.Waterland@Sun.COM #define	TEXT_DOMAIN "SYS_TEST"
2169781SMoriah.Waterland@Sun.COM #endif
2179781SMoriah.Waterland@Sun.COM 
2189781SMoriah.Waterland@Sun.COM /* This is the text for the "-O parent-zone-name=" option */
2199781SMoriah.Waterland@Sun.COM 
2209781SMoriah.Waterland@Sun.COM #define	PARENTZONENAME	"parent-zone-name="
2219781SMoriah.Waterland@Sun.COM #define	PARENTZONENAME_LEN	((sizeof (PARENTZONENAME))-1)
2229781SMoriah.Waterland@Sun.COM 
2239781SMoriah.Waterland@Sun.COM /* This is the text for the "-O parent-zone-type=" option */
2249781SMoriah.Waterland@Sun.COM 
2259781SMoriah.Waterland@Sun.COM #define	PARENTZONETYPE	"parent-zone-type="
2269781SMoriah.Waterland@Sun.COM #define	PARENTZONETYPE_LEN	((sizeof (PARENTZONETYPE))-1)
2279781SMoriah.Waterland@Sun.COM 
2289781SMoriah.Waterland@Sun.COM static char *cpio_names[] = {
2299781SMoriah.Waterland@Sun.COM 	"root",
2309781SMoriah.Waterland@Sun.COM 	"root.cpio",
2319781SMoriah.Waterland@Sun.COM 	"reloc",
2329781SMoriah.Waterland@Sun.COM 	"reloc.cpio",
2339781SMoriah.Waterland@Sun.COM 	"root.Z",
2349781SMoriah.Waterland@Sun.COM 	"root.cpio.Z",
2359781SMoriah.Waterland@Sun.COM 	"reloc.Z",
2369781SMoriah.Waterland@Sun.COM 	"reloc.cpio.Z",
2379781SMoriah.Waterland@Sun.COM 	0
2389781SMoriah.Waterland@Sun.COM };
2399781SMoriah.Waterland@Sun.COM 
2409781SMoriah.Waterland@Sun.COM int
main(int argc,char * argv[])2419781SMoriah.Waterland@Sun.COM main(int argc, char *argv[])
2429781SMoriah.Waterland@Sun.COM {
2439869SCasper.Dik@Sun.COM 	VFP_T			*cfTmpVfp = NULL;	/* temporary */
2449781SMoriah.Waterland@Sun.COM 	VFP_T			*pkgmapVfp;	/* "../pkgmap" file */
2459781SMoriah.Waterland@Sun.COM 	boolean_t		run_request_as_root = B_FALSE;
2469781SMoriah.Waterland@Sun.COM 	char			**np;
2479781SMoriah.Waterland@Sun.COM 	char			*abi_comp_ptr;
2489781SMoriah.Waterland@Sun.COM 	char			*abi_nm_ptr;
2499781SMoriah.Waterland@Sun.COM 	char			*abi_sym_ptr;
2509781SMoriah.Waterland@Sun.COM 	char			*admnfile = NULL;
2519781SMoriah.Waterland@Sun.COM 	char			*device;
2529781SMoriah.Waterland@Sun.COM 	char			*p;
2539781SMoriah.Waterland@Sun.COM 	char			*prog_full_name = NULL;
2549781SMoriah.Waterland@Sun.COM 	char			*pt;
2559781SMoriah.Waterland@Sun.COM 	char			*updated = (char *)NULL;
2569781SMoriah.Waterland@Sun.COM 	char			*vfstab_file = NULL;
2579781SMoriah.Waterland@Sun.COM 	char			*zoneName = (char *)NULL;
2589781SMoriah.Waterland@Sun.COM 	char			cbuf[MAX_PKG_PARAM_LENGTH];
2599781SMoriah.Waterland@Sun.COM 	char			cmdbin[PATH_MAX];
2609781SMoriah.Waterland@Sun.COM 	char			p_pkginfo[PATH_MAX];
2619781SMoriah.Waterland@Sun.COM 	char			p_pkgmap[PATH_MAX];
2629781SMoriah.Waterland@Sun.COM 	char			param[MAX_PKG_PARAM_LENGTH];
2639781SMoriah.Waterland@Sun.COM 	char			script[PATH_MAX];
2649781SMoriah.Waterland@Sun.COM 	char			altscript[PATH_MAX];
26512222SNagaraj.Yedathore@Sun.COM 	char			*temp;
2669781SMoriah.Waterland@Sun.COM 	int			c;
2679781SMoriah.Waterland@Sun.COM 	int			disableAttributes = 0;
2689781SMoriah.Waterland@Sun.COM 	int			err;
2699781SMoriah.Waterland@Sun.COM 	int			init_install = 0;
2709781SMoriah.Waterland@Sun.COM 	int			is_comp_arch;
2719781SMoriah.Waterland@Sun.COM 	int			live_continue = 0;
2729781SMoriah.Waterland@Sun.COM 	int			map_client = 1;
2739781SMoriah.Waterland@Sun.COM 	int			n;
2749781SMoriah.Waterland@Sun.COM 	int			nparts;
2759781SMoriah.Waterland@Sun.COM 	int			npkgs;
2769781SMoriah.Waterland@Sun.COM 	int			part;
2779781SMoriah.Waterland@Sun.COM 	int			saveSpoolInstall = 0;
2789781SMoriah.Waterland@Sun.COM 	boolean_t		cont_file_read;
2799781SMoriah.Waterland@Sun.COM 	struct cl_attr		**pclass = NULL;
2809781SMoriah.Waterland@Sun.COM 	struct cl_attr		**mergd_pclass = NULL;
2819781SMoriah.Waterland@Sun.COM 	struct pkginfo		*prvinfo;
2829781SMoriah.Waterland@Sun.COM 	struct sigaction	nact;
2839781SMoriah.Waterland@Sun.COM 	struct sigaction	oact;
2849781SMoriah.Waterland@Sun.COM 	struct stat		statb;
2859781SMoriah.Waterland@Sun.COM 	struct statvfs64	svfsb;
2869781SMoriah.Waterland@Sun.COM 	time_t			clock;
2879869SCasper.Dik@Sun.COM 	PKGserver		pkgserver = NULL;
2889781SMoriah.Waterland@Sun.COM 
2899781SMoriah.Waterland@Sun.COM 	/* reset contents of all default paths */
2909781SMoriah.Waterland@Sun.COM 
2919781SMoriah.Waterland@Sun.COM 	(void) memset(path, '\0', sizeof (path));
2929781SMoriah.Waterland@Sun.COM 	(void) memset(cmdbin, '\0', sizeof (cmdbin));
2939781SMoriah.Waterland@Sun.COM 	(void) memset(script, '\0', sizeof (script));
2949781SMoriah.Waterland@Sun.COM 	(void) memset(cbuf, '\0', sizeof (cbuf));
2959781SMoriah.Waterland@Sun.COM 	(void) memset(param, '\0', sizeof (param));
2969781SMoriah.Waterland@Sun.COM 
2979781SMoriah.Waterland@Sun.COM 	/* initialize locale environment */
2989781SMoriah.Waterland@Sun.COM 
2999781SMoriah.Waterland@Sun.COM 	(void) setlocale(LC_ALL, "");
3009781SMoriah.Waterland@Sun.COM 	(void) textdomain(TEXT_DOMAIN);
3019781SMoriah.Waterland@Sun.COM 
3029781SMoriah.Waterland@Sun.COM 	/* initialize program name */
3039781SMoriah.Waterland@Sun.COM 
3049781SMoriah.Waterland@Sun.COM 	prog_full_name = argv[0];
3059781SMoriah.Waterland@Sun.COM 	(void) set_prog_name(argv[0]);
3069781SMoriah.Waterland@Sun.COM 
3079781SMoriah.Waterland@Sun.COM 	/* tell spmi zones interface how to access package output functions */
3089781SMoriah.Waterland@Sun.COM 
3099781SMoriah.Waterland@Sun.COM 	z_set_output_functions(echo, echoDebug, progerr);
3109781SMoriah.Waterland@Sun.COM 
3119781SMoriah.Waterland@Sun.COM 	/* exit if not root */
3129781SMoriah.Waterland@Sun.COM 
3139781SMoriah.Waterland@Sun.COM 	if (getuid()) {
3149781SMoriah.Waterland@Sun.COM 		progerr(ERR_NOT_ROOT, get_prog_name());
3159781SMoriah.Waterland@Sun.COM 		exit(1);
3169781SMoriah.Waterland@Sun.COM 		/* NOTREACHED */
3179781SMoriah.Waterland@Sun.COM 	}
3189781SMoriah.Waterland@Sun.COM 
3199781SMoriah.Waterland@Sun.COM 	/*
3209781SMoriah.Waterland@Sun.COM 	 * determine how pkgmap() deals with environment variables:
3219781SMoriah.Waterland@Sun.COM 	 *  - MAPALL - resolve all variables
3229781SMoriah.Waterland@Sun.COM 	 *  - MAPBUILD - map only build variables
3239781SMoriah.Waterland@Sun.COM 	 *  - MAPINSTALL - map only install variables
3249781SMoriah.Waterland@Sun.COM 	 *  - MAPNONE - map no variables
3259781SMoriah.Waterland@Sun.COM 	 */
3269781SMoriah.Waterland@Sun.COM 
3279781SMoriah.Waterland@Sun.COM 	setmapmode(MAPINSTALL);
3289781SMoriah.Waterland@Sun.COM 
3299781SMoriah.Waterland@Sun.COM 	/* set sane umask */
3309781SMoriah.Waterland@Sun.COM 
3319781SMoriah.Waterland@Sun.COM 	(void) umask(0022);
3329781SMoriah.Waterland@Sun.COM 
3339781SMoriah.Waterland@Sun.COM 	/* initially no source "device" */
3349781SMoriah.Waterland@Sun.COM 
3359781SMoriah.Waterland@Sun.COM 	device = NULL;
3369781SMoriah.Waterland@Sun.COM 
3379781SMoriah.Waterland@Sun.COM 	/* reset npkgs (used as pkg remaining count in quit.c) */
3389781SMoriah.Waterland@Sun.COM 
3399781SMoriah.Waterland@Sun.COM 	npkgs = 0;
3409781SMoriah.Waterland@Sun.COM 
3419781SMoriah.Waterland@Sun.COM 	/* Read PKG_INSTALL_ROOT from the environment, if it's there. */
3429781SMoriah.Waterland@Sun.COM 
3439781SMoriah.Waterland@Sun.COM 	if (!set_inst_root(getenv("PKG_INSTALL_ROOT"))) {
3449781SMoriah.Waterland@Sun.COM 		progerr(ERR_ROOT_SET);
3459781SMoriah.Waterland@Sun.COM 		exit(1);
3469781SMoriah.Waterland@Sun.COM 	}
3479781SMoriah.Waterland@Sun.COM 
3489869SCasper.Dik@Sun.COM 	pkgserversetmode(DEFAULTMODE);
3499869SCasper.Dik@Sun.COM 
3509781SMoriah.Waterland@Sun.COM 	/* parse command line options */
3519781SMoriah.Waterland@Sun.COM 
3529781SMoriah.Waterland@Sun.COM 	while ((c = getopt(argc, argv,
3539781SMoriah.Waterland@Sun.COM 		"?Aa:B:b:Cc:D:d:eFf:GhIiMm:N:noO:p:R:r:StV:vyz")) != EOF) {
3549781SMoriah.Waterland@Sun.COM 
3559781SMoriah.Waterland@Sun.COM 		switch (c) {
3569781SMoriah.Waterland@Sun.COM 
3579781SMoriah.Waterland@Sun.COM 		/*
3589781SMoriah.Waterland@Sun.COM 		 * Same as pkgadd: This disables attribute checking.
3599781SMoriah.Waterland@Sun.COM 		 * It speeds up installation a little bit.
3609781SMoriah.Waterland@Sun.COM 		 */
3619781SMoriah.Waterland@Sun.COM 		case 'A':
3629781SMoriah.Waterland@Sun.COM 			disableAttributes++;
3639781SMoriah.Waterland@Sun.COM 			break;
3649781SMoriah.Waterland@Sun.COM 
3659781SMoriah.Waterland@Sun.COM 		/*
3669781SMoriah.Waterland@Sun.COM 		 * Same as pkgadd: Define an installation administration
3679781SMoriah.Waterland@Sun.COM 		 * file, admin, to be used in place of the default
3689781SMoriah.Waterland@Sun.COM 		 * administration file.  The token none overrides the use
3699781SMoriah.Waterland@Sun.COM 		 * of any admin file, and thus forces interaction with the
3709781SMoriah.Waterland@Sun.COM 		 * user. Unless a full path name is given, pkgadd first
3719781SMoriah.Waterland@Sun.COM 		 * looks in the current working directory for the
3729781SMoriah.Waterland@Sun.COM 		 * administration file.  If the specified administration
3739781SMoriah.Waterland@Sun.COM 		 * file is not in the current working directory, pkgadd
3749781SMoriah.Waterland@Sun.COM 		 * looks in the /var/sadm/install/admin directory for the
3759781SMoriah.Waterland@Sun.COM 		 * administration file.
3769781SMoriah.Waterland@Sun.COM 		 */
3779781SMoriah.Waterland@Sun.COM 		case 'a':
3789781SMoriah.Waterland@Sun.COM 			admnfile = flex_device(optarg, 0);
3799781SMoriah.Waterland@Sun.COM 			break;
3809781SMoriah.Waterland@Sun.COM 
3819781SMoriah.Waterland@Sun.COM 		/*
3829781SMoriah.Waterland@Sun.COM 		 * Same as pkgadd: control block size given to
3839781SMoriah.Waterland@Sun.COM 		 * pkginstall - block size used in read()/write() loop;
3849781SMoriah.Waterland@Sun.COM 		 * default is st_blksize from stat() of source file.
3859781SMoriah.Waterland@Sun.COM 		 */
3869781SMoriah.Waterland@Sun.COM 		case 'B':
3879781SMoriah.Waterland@Sun.COM 			rw_block_size = optarg;
3889781SMoriah.Waterland@Sun.COM 			break;
3899781SMoriah.Waterland@Sun.COM 
3909781SMoriah.Waterland@Sun.COM 		/*
3919781SMoriah.Waterland@Sun.COM 		 * Same as pkgadd: location where executables needed
3929781SMoriah.Waterland@Sun.COM 		 * by procedure scripts can be found
3939781SMoriah.Waterland@Sun.COM 		 * default is /usr/sadm/install/bin.
3949781SMoriah.Waterland@Sun.COM 		 */
3959781SMoriah.Waterland@Sun.COM 		case 'b':
3969781SMoriah.Waterland@Sun.COM 			if (!path_valid(optarg)) {
3979781SMoriah.Waterland@Sun.COM 				progerr(ERR_PATH, optarg);
3989781SMoriah.Waterland@Sun.COM 				exit(1);
3999781SMoriah.Waterland@Sun.COM 			}
4009781SMoriah.Waterland@Sun.COM 			if (isdir(optarg) != 0) {
4019781SMoriah.Waterland@Sun.COM 				char *p = strerror(errno);
4029781SMoriah.Waterland@Sun.COM 				progerr(ERR_CANNOT_USE_DIR, optarg, p);
4039781SMoriah.Waterland@Sun.COM 				exit(1);
4049781SMoriah.Waterland@Sun.COM 			}
4059781SMoriah.Waterland@Sun.COM 			(void) strlcpy(cmdbin, optarg, sizeof (cmdbin));
4069781SMoriah.Waterland@Sun.COM 			break;
4079781SMoriah.Waterland@Sun.COM 
4089781SMoriah.Waterland@Sun.COM 		/*
4099781SMoriah.Waterland@Sun.COM 		 * Same as pkgadd: This disables checksum tests on
4109781SMoriah.Waterland@Sun.COM 		 * the source files. It speeds up installation a little bit.
4119781SMoriah.Waterland@Sun.COM 		 */
4129781SMoriah.Waterland@Sun.COM 		case 'C':
4139781SMoriah.Waterland@Sun.COM 			(void) checksum_off();
4149781SMoriah.Waterland@Sun.COM 			break;
4159781SMoriah.Waterland@Sun.COM 
4169781SMoriah.Waterland@Sun.COM 		/*
4179781SMoriah.Waterland@Sun.COM 		 * Same as pkgadd: This allows designation of a
4189781SMoriah.Waterland@Sun.COM 		 * continuation file. It is the same format as a dryrun file
4199781SMoriah.Waterland@Sun.COM 		 * but it is used to take up where the dryrun left off.
4209781SMoriah.Waterland@Sun.COM 		 */
4219781SMoriah.Waterland@Sun.COM 		case 'c':
4229781SMoriah.Waterland@Sun.COM 			pkgcontsrc = optarg;
4239781SMoriah.Waterland@Sun.COM 			set_continue_mode();
4249781SMoriah.Waterland@Sun.COM 			set_dr_info(DR_TYPE, INSTALL_TYPE);
4259781SMoriah.Waterland@Sun.COM 			init_contfile(pkgcontsrc);
4269781SMoriah.Waterland@Sun.COM 			break;
4279781SMoriah.Waterland@Sun.COM 
4289781SMoriah.Waterland@Sun.COM 		/*
4299781SMoriah.Waterland@Sun.COM 		 * Same as pkgadd: This allows designation of a
4309781SMoriah.Waterland@Sun.COM 		 * dryrun file. This pkgadd will create dryrun files
4319781SMoriah.Waterland@Sun.COM 		 * in the directory provided.
4329781SMoriah.Waterland@Sun.COM 		 */
4339781SMoriah.Waterland@Sun.COM 		case 'D':
4349781SMoriah.Waterland@Sun.COM 			pkgdrtarg = optarg;
4359781SMoriah.Waterland@Sun.COM 			set_dryrun_mode();
4369781SMoriah.Waterland@Sun.COM 			set_dr_info(DR_TYPE, INSTALL_TYPE);
4379781SMoriah.Waterland@Sun.COM 			break;
4389781SMoriah.Waterland@Sun.COM 
4399781SMoriah.Waterland@Sun.COM 		/*
4409781SMoriah.Waterland@Sun.COM 		 * Same as pkgadd: Install or copy a package from
4419781SMoriah.Waterland@Sun.COM 		 * device. device can be a full path name to a directory
4429781SMoriah.Waterland@Sun.COM 		 * or the identifiers for tape, floppy disk, or removable
4439781SMoriah.Waterland@Sun.COM 		 * disk - for example, /var/tmp or /floppy/floppy_name.
4449781SMoriah.Waterland@Sun.COM 		 * It can also be a device alias - for example,
4459781SMoriah.Waterland@Sun.COM 		 * /floppy/floppy0, or a datastream created by pkgtrans.
4469781SMoriah.Waterland@Sun.COM 		 */
4479781SMoriah.Waterland@Sun.COM 		case 'd':
4489781SMoriah.Waterland@Sun.COM 			device = flex_device(optarg, 1);
4499781SMoriah.Waterland@Sun.COM 			break;
4509781SMoriah.Waterland@Sun.COM 
4519781SMoriah.Waterland@Sun.COM 		/*
4529781SMoriah.Waterland@Sun.COM 		 * Different from pkgadd: disable the 32 char name
4539781SMoriah.Waterland@Sun.COM 		 * limit extension
4549781SMoriah.Waterland@Sun.COM 		 */
4559781SMoriah.Waterland@Sun.COM 		case 'e':
4569781SMoriah.Waterland@Sun.COM 			(void) set_ABI_namelngth();
4579781SMoriah.Waterland@Sun.COM 			break;
4589781SMoriah.Waterland@Sun.COM 
4599781SMoriah.Waterland@Sun.COM 		/*
4609781SMoriah.Waterland@Sun.COM 		 * Different from pkgadd: specify file system type for
4619781SMoriah.Waterland@Sun.COM 		 * the package device. Must be used with -m.
4629781SMoriah.Waterland@Sun.COM 		 */
4639781SMoriah.Waterland@Sun.COM 		case 'f':
4649781SMoriah.Waterland@Sun.COM 			pkgdev.fstyp = optarg;
4659781SMoriah.Waterland@Sun.COM 			break;
4669781SMoriah.Waterland@Sun.COM 
4679781SMoriah.Waterland@Sun.COM 		/*
4689781SMoriah.Waterland@Sun.COM 		 * Same as pkgadd: install package in global zone only.
4699781SMoriah.Waterland@Sun.COM 		 */
4709781SMoriah.Waterland@Sun.COM 		case 'G':
4719781SMoriah.Waterland@Sun.COM 			globalZoneOnly = B_TRUE;
4729781SMoriah.Waterland@Sun.COM 			break;
4739781SMoriah.Waterland@Sun.COM 
4749781SMoriah.Waterland@Sun.COM 		/*
4759781SMoriah.Waterland@Sun.COM 		 * Same as pkgadd: Enable hollow package support. When
4769781SMoriah.Waterland@Sun.COM 		 * specified, for any package that has SUNW_PKG_HOLLOW=true:
4779781SMoriah.Waterland@Sun.COM 		 *  Do not calculate and verify package size against target.
4789781SMoriah.Waterland@Sun.COM 		 *  Do not run any package procedure or class action scripts.
4799781SMoriah.Waterland@Sun.COM 		 *  Do not create any target directories.
4809781SMoriah.Waterland@Sun.COM 		 *  Do not perform any script locking.
4819781SMoriah.Waterland@Sun.COM 		 *  Do not install any components of any package.
4829781SMoriah.Waterland@Sun.COM 		 *  Do not output any status or database update messages.
4839781SMoriah.Waterland@Sun.COM 		 */
4849781SMoriah.Waterland@Sun.COM 		case 'h':
4859781SMoriah.Waterland@Sun.COM 			set_depend_pkginfo_DB(B_TRUE);
4869781SMoriah.Waterland@Sun.COM 			break;
4879781SMoriah.Waterland@Sun.COM 
4889781SMoriah.Waterland@Sun.COM 		/*
4899781SMoriah.Waterland@Sun.COM 		 * Same as pkgadd: Informs scripts that this is
4909781SMoriah.Waterland@Sun.COM 		 * an initial install by setting the environment parameter
4919781SMoriah.Waterland@Sun.COM 		 * PKG_INIT_INSTALL=TRUE for all scripts. They may use it as
4929781SMoriah.Waterland@Sun.COM 		 * they see fit, safe in the knowledge that the target
4939781SMoriah.Waterland@Sun.COM 		 * filesystem is tabula rasa.
4949781SMoriah.Waterland@Sun.COM 		 */
4959781SMoriah.Waterland@Sun.COM 		case 'I':
4969781SMoriah.Waterland@Sun.COM 			init_install++;
4979781SMoriah.Waterland@Sun.COM 			break;
4989781SMoriah.Waterland@Sun.COM 
4999781SMoriah.Waterland@Sun.COM 		/*
5009781SMoriah.Waterland@Sun.COM 		 * Different from pkgadd: use by pkgask.
5019781SMoriah.Waterland@Sun.COM 		 */
5029781SMoriah.Waterland@Sun.COM 		case 'i':
5039781SMoriah.Waterland@Sun.COM 			askflag++;
5049781SMoriah.Waterland@Sun.COM 			quitSetPkgask(B_TRUE);
5059781SMoriah.Waterland@Sun.COM 			break;
5069781SMoriah.Waterland@Sun.COM 
5079781SMoriah.Waterland@Sun.COM 		/*
5089781SMoriah.Waterland@Sun.COM 		 * Same as pkgadd: Instruct pkgadd not to use the
5099781SMoriah.Waterland@Sun.COM 		 * $root_path/etc/vfstab file for determining the client's
5109781SMoriah.Waterland@Sun.COM 		 * mount points. This option assumes the mount points are
5119781SMoriah.Waterland@Sun.COM 		 * correct on the server and it behaves consistently with
5129781SMoriah.Waterland@Sun.COM 		 * Solaris 2.5 and earlier releases.
5139781SMoriah.Waterland@Sun.COM 		 */
5149781SMoriah.Waterland@Sun.COM 		case 'M':
5159781SMoriah.Waterland@Sun.COM 			map_client = 0;
5169781SMoriah.Waterland@Sun.COM 			break;
5179781SMoriah.Waterland@Sun.COM 
5189781SMoriah.Waterland@Sun.COM 		/*
5199781SMoriah.Waterland@Sun.COM 		 * Different from pkgadd: specify device to use for package
5209781SMoriah.Waterland@Sun.COM 		 * source.
5219781SMoriah.Waterland@Sun.COM 		 */
5229781SMoriah.Waterland@Sun.COM 		case 'm':
5239781SMoriah.Waterland@Sun.COM 			pkgdev.mount = optarg;
5249781SMoriah.Waterland@Sun.COM 			pkgdev.rdonly++;
5259781SMoriah.Waterland@Sun.COM 			pkgdev.mntflg++;
5269781SMoriah.Waterland@Sun.COM 			break;
5279781SMoriah.Waterland@Sun.COM 
5289781SMoriah.Waterland@Sun.COM 		/*
5299781SMoriah.Waterland@Sun.COM 		 * Different from pkgadd: specify program name to use
5309781SMoriah.Waterland@Sun.COM 		 * for messages.
5319781SMoriah.Waterland@Sun.COM 		 */
5329781SMoriah.Waterland@Sun.COM 		case 'N':
5339781SMoriah.Waterland@Sun.COM 			(void) set_prog_name(optarg);
5349781SMoriah.Waterland@Sun.COM 			break;
5359781SMoriah.Waterland@Sun.COM 
5369781SMoriah.Waterland@Sun.COM 		/*
5379781SMoriah.Waterland@Sun.COM 		 * Same as pkgadd: installation occurs in
5389781SMoriah.Waterland@Sun.COM 		 * non-interactive mode.  Suppress output of the list of
5399781SMoriah.Waterland@Sun.COM 		 * installed files. The default mode is interactive.
5409781SMoriah.Waterland@Sun.COM 		 */
5419781SMoriah.Waterland@Sun.COM 		case 'n':
5429781SMoriah.Waterland@Sun.COM 			nointeract++;
5439781SMoriah.Waterland@Sun.COM 			(void) echoSetFlag(B_FALSE);
5449781SMoriah.Waterland@Sun.COM 			break;
5459781SMoriah.Waterland@Sun.COM 
5469781SMoriah.Waterland@Sun.COM 		/*
5479781SMoriah.Waterland@Sun.COM 		 * Almost same as pkgadd: the -O option allows the behavior
5489781SMoriah.Waterland@Sun.COM 		 * of the package tools to be modified. Recognized options:
5499781SMoriah.Waterland@Sun.COM 		 * -> debug
5509781SMoriah.Waterland@Sun.COM 		 * ---> enable debugging output
5519781SMoriah.Waterland@Sun.COM 		 * -> preinstallcheck
5529781SMoriah.Waterland@Sun.COM 		 * ---> perform a "pre installation" check of the specified
5539781SMoriah.Waterland@Sun.COM 		 * ---> package - suppress all regular output and cause a
5549781SMoriah.Waterland@Sun.COM 		 * ---> series of one or more "name=value" pair format lines
5559781SMoriah.Waterland@Sun.COM 		 * ---> to be output that describes the "installability" of
5569781SMoriah.Waterland@Sun.COM 		 * ---> the specified package
5579781SMoriah.Waterland@Sun.COM 		 * -> enable-hollow-package-support
5589781SMoriah.Waterland@Sun.COM 		 * --> Enable hollow package support. When specified, for any
5599781SMoriah.Waterland@Sun.COM 		 * --> package that has SUNW_PKG_HOLLOW=true:
5609781SMoriah.Waterland@Sun.COM 		 * --> Do not calculate and verify package size against target
5619781SMoriah.Waterland@Sun.COM 		 * --> Do not run any package procedure or class action scripts
5629781SMoriah.Waterland@Sun.COM 		 * --> Do not create or remove any target directories
5639781SMoriah.Waterland@Sun.COM 		 * --> Do not perform any script locking
5649781SMoriah.Waterland@Sun.COM 		 * --> Do not install or uninstall any components of any package
5659781SMoriah.Waterland@Sun.COM 		 * --> Do not output any status or database update messages
5669781SMoriah.Waterland@Sun.COM 		 */
5679781SMoriah.Waterland@Sun.COM 		case 'O':
5689781SMoriah.Waterland@Sun.COM 			for (p = strtok(optarg, ","); p != (char *)NULL;
5699781SMoriah.Waterland@Sun.COM 				p = strtok(NULL, ",")) {
5709781SMoriah.Waterland@Sun.COM 
5719781SMoriah.Waterland@Sun.COM 				/* process debug option */
5729781SMoriah.Waterland@Sun.COM 
5739781SMoriah.Waterland@Sun.COM 				if (strcmp(p, "debug") == 0) {
5749781SMoriah.Waterland@Sun.COM 					/* set debug flag/enable debug output */
5759781SMoriah.Waterland@Sun.COM 					if (debugFlag == B_TRUE) {
5769781SMoriah.Waterland@Sun.COM 						smlSetVerbose(B_TRUE);
5779781SMoriah.Waterland@Sun.COM 					}
5789781SMoriah.Waterland@Sun.COM 					debugFlag = B_TRUE;
5799781SMoriah.Waterland@Sun.COM 					(void) echoDebugSetFlag(debugFlag);
5809781SMoriah.Waterland@Sun.COM 
5819781SMoriah.Waterland@Sun.COM 					/* debug info on arguments to pkgadd */
5829781SMoriah.Waterland@Sun.COM 					for (n = 0; n < argc && argv[n]; n++) {
5839781SMoriah.Waterland@Sun.COM 						echoDebug(DBG_ARG, n, argv[n]);
5849781SMoriah.Waterland@Sun.COM 					}
5859781SMoriah.Waterland@Sun.COM 
5869781SMoriah.Waterland@Sun.COM 					continue;
5879781SMoriah.Waterland@Sun.COM 				}
5889781SMoriah.Waterland@Sun.COM 
5899781SMoriah.Waterland@Sun.COM 				/* process enable-hollow-package-support opt */
5909781SMoriah.Waterland@Sun.COM 
5919781SMoriah.Waterland@Sun.COM 				if (strcmp(p,
5929781SMoriah.Waterland@Sun.COM 					"enable-hollow-package-support") == 0) {
5939781SMoriah.Waterland@Sun.COM 					set_depend_pkginfo_DB(B_TRUE);
5949781SMoriah.Waterland@Sun.COM 					continue;
5959781SMoriah.Waterland@Sun.COM 				}
5969781SMoriah.Waterland@Sun.COM 
5979781SMoriah.Waterland@Sun.COM 				/* process preinstallcheck option */
5989781SMoriah.Waterland@Sun.COM 
5999781SMoriah.Waterland@Sun.COM 				if (strcmp(p, "preinstallcheck") == 0) {
6009781SMoriah.Waterland@Sun.COM 					preinstallCheck = B_TRUE;
6019781SMoriah.Waterland@Sun.COM 					nointeract++;	/* -n */
6029781SMoriah.Waterland@Sun.COM 					suppressCopyright++;	/* -S */
6039781SMoriah.Waterland@Sun.COM 					quitSetSilentExit(B_TRUE);
6049781SMoriah.Waterland@Sun.COM 					continue;
6059781SMoriah.Waterland@Sun.COM 				}
6069781SMoriah.Waterland@Sun.COM 
6079781SMoriah.Waterland@Sun.COM 				/* process addzonename option */
6089781SMoriah.Waterland@Sun.COM 
6099781SMoriah.Waterland@Sun.COM 				if (strcmp(p, "addzonename") == 0) {
6109781SMoriah.Waterland@Sun.COM 					/*
6119781SMoriah.Waterland@Sun.COM 					 * set zone name to add to messages;
6129781SMoriah.Waterland@Sun.COM 					 * first look in the current environment
6139781SMoriah.Waterland@Sun.COM 					 * and use the default package zone name
6149781SMoriah.Waterland@Sun.COM 					 * if it is set; otherwise, use the name
6159781SMoriah.Waterland@Sun.COM 					 * of the current zone
6169781SMoriah.Waterland@Sun.COM 					 */
6179781SMoriah.Waterland@Sun.COM 					zoneName =
6189781SMoriah.Waterland@Sun.COM 						getenv(PKG_ZONENAME_VARIABLE);
6199781SMoriah.Waterland@Sun.COM 
6209781SMoriah.Waterland@Sun.COM 					if ((zoneName == (char *)NULL) ||
6219781SMoriah.Waterland@Sun.COM 							(*zoneName == '\0')) {
6229781SMoriah.Waterland@Sun.COM 						zoneName = z_get_zonename();
6239781SMoriah.Waterland@Sun.COM 					}
6249781SMoriah.Waterland@Sun.COM 
6259781SMoriah.Waterland@Sun.COM 					if (zoneName != (char *)NULL) {
6269781SMoriah.Waterland@Sun.COM 						if (*zoneName != '\0') {
6279781SMoriah.Waterland@Sun.COM 							quitSetZoneName(
6289781SMoriah.Waterland@Sun.COM 								zoneName);
6299781SMoriah.Waterland@Sun.COM 						} else {
6309781SMoriah.Waterland@Sun.COM 							zoneName = (char *)NULL;
6319781SMoriah.Waterland@Sun.COM 						}
6329781SMoriah.Waterland@Sun.COM 					}
6339781SMoriah.Waterland@Sun.COM 					continue;
6349781SMoriah.Waterland@Sun.COM 				}
6359781SMoriah.Waterland@Sun.COM 
6369781SMoriah.Waterland@Sun.COM 				/*
6379781SMoriah.Waterland@Sun.COM 				 * If this is a patch installation
6389781SMoriah.Waterland@Sun.COM 				 * then call setPatchUpdate().
6399781SMoriah.Waterland@Sun.COM 				 */
6409781SMoriah.Waterland@Sun.COM 
6419781SMoriah.Waterland@Sun.COM 				if (strcmp(p, "patchPkgInstall") == 0) {
6429781SMoriah.Waterland@Sun.COM 					setPatchUpdate();
6439781SMoriah.Waterland@Sun.COM 					patchPkgInstall = B_TRUE;
6449781SMoriah.Waterland@Sun.COM 					continue;
6459781SMoriah.Waterland@Sun.COM 				}
6469781SMoriah.Waterland@Sun.COM 
6479781SMoriah.Waterland@Sun.COM 				/*
6489781SMoriah.Waterland@Sun.COM 				 * If this is a patch removal
6499781SMoriah.Waterland@Sun.COM 				 * then call setPatchUpdate() and set
6509781SMoriah.Waterland@Sun.COM 				 * patchPkgRemoval flag.
6519781SMoriah.Waterland@Sun.COM 				 */
6529781SMoriah.Waterland@Sun.COM 
6539781SMoriah.Waterland@Sun.COM 				if (strcmp(p, "patchPkgRemoval") == 0) {
6549781SMoriah.Waterland@Sun.COM 					setPatchUpdate();
6559781SMoriah.Waterland@Sun.COM 					patchPkgRemoval = B_TRUE;
6569781SMoriah.Waterland@Sun.COM 					continue;
6579781SMoriah.Waterland@Sun.COM 				}
6589781SMoriah.Waterland@Sun.COM 
6599781SMoriah.Waterland@Sun.COM 				/* process parent-zone-name option */
6609781SMoriah.Waterland@Sun.COM 
6619781SMoriah.Waterland@Sun.COM 				if (strncmp(p, PARENTZONENAME,
6629781SMoriah.Waterland@Sun.COM 						PARENTZONENAME_LEN) == 0) {
6639781SMoriah.Waterland@Sun.COM 					parentZoneName = p+PARENTZONENAME_LEN;
6649781SMoriah.Waterland@Sun.COM 					continue;
6659781SMoriah.Waterland@Sun.COM 				}
6669781SMoriah.Waterland@Sun.COM 
6679781SMoriah.Waterland@Sun.COM 				/* process parent-zone-type option */
6689781SMoriah.Waterland@Sun.COM 
6699781SMoriah.Waterland@Sun.COM 				if (strncmp(p, PARENTZONETYPE,
6709781SMoriah.Waterland@Sun.COM 						PARENTZONETYPE_LEN) == 0) {
6719781SMoriah.Waterland@Sun.COM 					parentZoneType = p+PARENTZONETYPE_LEN;
6729781SMoriah.Waterland@Sun.COM 					continue;
6739781SMoriah.Waterland@Sun.COM 				}
6749781SMoriah.Waterland@Sun.COM 
6759869SCasper.Dik@Sun.COM 				if (strncmp(p, PKGSERV_MODE,
6769869SCasper.Dik@Sun.COM 				    PKGSERV_MODE_LEN) == 0) {
6779869SCasper.Dik@Sun.COM 					pkgserversetmode(pkgparsemode(p +
6789869SCasper.Dik@Sun.COM 					    PKGSERV_MODE_LEN));
6799869SCasper.Dik@Sun.COM 					continue;
6809869SCasper.Dik@Sun.COM 				}
6819869SCasper.Dik@Sun.COM 
6829781SMoriah.Waterland@Sun.COM 				/* option not recognized - issue warning */
6839781SMoriah.Waterland@Sun.COM 
6849781SMoriah.Waterland@Sun.COM 				progerr(ERR_INVALID_O_OPTION, p);
6859781SMoriah.Waterland@Sun.COM 				continue;
6869781SMoriah.Waterland@Sun.COM 
6879781SMoriah.Waterland@Sun.COM 			}
6889781SMoriah.Waterland@Sun.COM 			break;
6899781SMoriah.Waterland@Sun.COM 
6909781SMoriah.Waterland@Sun.COM 		/*
6919781SMoriah.Waterland@Sun.COM 		 * Different from pkgadd: This is an old non-ABI package
6929781SMoriah.Waterland@Sun.COM 		 */
6939781SMoriah.Waterland@Sun.COM 		case 'o':
6949781SMoriah.Waterland@Sun.COM 			non_abi_scripts++;
6959781SMoriah.Waterland@Sun.COM 			break;
6969781SMoriah.Waterland@Sun.COM 
6979781SMoriah.Waterland@Sun.COM 		/*
6989781SMoriah.Waterland@Sun.COM 		 * Different from pkgadd: specify number of parts to package.
6999781SMoriah.Waterland@Sun.COM 		 */
7009781SMoriah.Waterland@Sun.COM 		case 'p':
7019781SMoriah.Waterland@Sun.COM 			dparts = ds_getinfo(optarg);
7029781SMoriah.Waterland@Sun.COM 			break;
7039781SMoriah.Waterland@Sun.COM 
7049781SMoriah.Waterland@Sun.COM 		/*
7059781SMoriah.Waterland@Sun.COM 		 * Same as pkgadd: Define the full path name of a
7069781SMoriah.Waterland@Sun.COM 		 * directory to use as the root_path.  All files,
7079781SMoriah.Waterland@Sun.COM 		 * including package system information files, are
7089781SMoriah.Waterland@Sun.COM 		 * relocated to a directory tree starting in the specified
7099781SMoriah.Waterland@Sun.COM 		 * root_path. The root_path may be specified when
7109781SMoriah.Waterland@Sun.COM 		 * installing to a client from a server (for example,
7119781SMoriah.Waterland@Sun.COM 		 * /export/root/client1).
7129781SMoriah.Waterland@Sun.COM 		 */
7139781SMoriah.Waterland@Sun.COM 		case 'R':
7149781SMoriah.Waterland@Sun.COM 			if (!set_inst_root(optarg)) {
7159781SMoriah.Waterland@Sun.COM 				progerr(ERR_ROOT_CMD);
7169781SMoriah.Waterland@Sun.COM 				exit(1);
7179781SMoriah.Waterland@Sun.COM 			}
7189781SMoriah.Waterland@Sun.COM 			break;
7199781SMoriah.Waterland@Sun.COM 
7209781SMoriah.Waterland@Sun.COM 		/*
7219781SMoriah.Waterland@Sun.COM 		 * Same as pkgadd: Identify a file or directory which
7229781SMoriah.Waterland@Sun.COM 		 * contains output from a previous pkgask(1M)
7239781SMoriah.Waterland@Sun.COM 		 * session. This file supplies the interaction responses
7249781SMoriah.Waterland@Sun.COM 		 * that would be requested by the package in interactive
7259781SMoriah.Waterland@Sun.COM 		 * mode. response must be a full pathname.
7269781SMoriah.Waterland@Sun.COM 		 */
7279781SMoriah.Waterland@Sun.COM 		case 'r':
7289781SMoriah.Waterland@Sun.COM 			respfile = flex_device(optarg, 2);
7299781SMoriah.Waterland@Sun.COM 			break;
7309781SMoriah.Waterland@Sun.COM 
7319781SMoriah.Waterland@Sun.COM 		/*
7329781SMoriah.Waterland@Sun.COM 		 * Same as pkgadd: suppress copyright notice being
7339781SMoriah.Waterland@Sun.COM 		 * output during installation.
7349781SMoriah.Waterland@Sun.COM 		 */
7359781SMoriah.Waterland@Sun.COM 		case 'S':
7369781SMoriah.Waterland@Sun.COM 			suppressCopyright++;
7379781SMoriah.Waterland@Sun.COM 			break;
7389781SMoriah.Waterland@Sun.COM 
7399781SMoriah.Waterland@Sun.COM 		/*
7409781SMoriah.Waterland@Sun.COM 		 * Same as pkgadd: disable save spool area creation;
7419781SMoriah.Waterland@Sun.COM 		 * do not spool any partial package contents, that is,
7429781SMoriah.Waterland@Sun.COM 		 * suppress the creation and population of the package save
7439781SMoriah.Waterland@Sun.COM 		 * spool area (var/sadm/pkg/PKG/save/pspool/PKG).
7449781SMoriah.Waterland@Sun.COM 		 */
7459781SMoriah.Waterland@Sun.COM 		case 't':
7469781SMoriah.Waterland@Sun.COM 			disable_spool_create();
7479781SMoriah.Waterland@Sun.COM 			break;
7489781SMoriah.Waterland@Sun.COM 
7499781SMoriah.Waterland@Sun.COM 		/*
7509781SMoriah.Waterland@Sun.COM 		 * Same as pkgadd: Specify an alternative fs_file to map
7519781SMoriah.Waterland@Sun.COM 		 * the client's file systems.  For example, used in
7529781SMoriah.Waterland@Sun.COM 		 * situations where the $root_path/etc/vfstab file is
7539781SMoriah.Waterland@Sun.COM 		 * non-existent or unreliable. Informs the pkginstall
7549781SMoriah.Waterland@Sun.COM 		 * portion to mount up a client filesystem based upon the
7559781SMoriah.Waterland@Sun.COM 		 * supplied vfstab-like file of stable format.
7569781SMoriah.Waterland@Sun.COM 		 */
7579781SMoriah.Waterland@Sun.COM 		case 'V':
7589781SMoriah.Waterland@Sun.COM 			vfstab_file = flex_device(optarg, 2);
7599781SMoriah.Waterland@Sun.COM 			map_client = 1;
7609781SMoriah.Waterland@Sun.COM 			break;
7619781SMoriah.Waterland@Sun.COM 
7629781SMoriah.Waterland@Sun.COM 		/*
7639781SMoriah.Waterland@Sun.COM 		 * Same as pkgadd: Trace all of the scripts that get
7649781SMoriah.Waterland@Sun.COM 		 * executed by pkgadd, located in the pkginst/install
7659781SMoriah.Waterland@Sun.COM 		 * directory. This option is used for debugging the
7669781SMoriah.Waterland@Sun.COM 		 * procedural and non-procedural scripts
7679781SMoriah.Waterland@Sun.COM 		 */
7689781SMoriah.Waterland@Sun.COM 		case 'v':
7699781SMoriah.Waterland@Sun.COM 			pkgverbose++;
7709781SMoriah.Waterland@Sun.COM 			break;
7719781SMoriah.Waterland@Sun.COM 
7729781SMoriah.Waterland@Sun.COM 		/*
7739781SMoriah.Waterland@Sun.COM 		 * Different from pkgadd: process this package using
7749781SMoriah.Waterland@Sun.COM 		 * old non-ABI symlinks
7759781SMoriah.Waterland@Sun.COM 		 */
7769781SMoriah.Waterland@Sun.COM 		case 'y':
7779781SMoriah.Waterland@Sun.COM 			set_nonABI_symlinks();
7789781SMoriah.Waterland@Sun.COM 			break;
7799781SMoriah.Waterland@Sun.COM 
7809781SMoriah.Waterland@Sun.COM 		/*
7819781SMoriah.Waterland@Sun.COM 		 * Same as pkgadd: perform fresh install from
7829781SMoriah.Waterland@Sun.COM 		 * package save spool area. When set, the package contents
7839781SMoriah.Waterland@Sun.COM 		 * are installed from the package spool save area instead
7849781SMoriah.Waterland@Sun.COM 		 * of from the package root area, so that the original
7859781SMoriah.Waterland@Sun.COM 		 * source packages are not required to install the
7869781SMoriah.Waterland@Sun.COM 		 * package. If the -h option is also specified and the
7879781SMoriah.Waterland@Sun.COM 		 * package is hollow, then this option is ignored. When -z
7889781SMoriah.Waterland@Sun.COM 		 * is specified:
7899781SMoriah.Waterland@Sun.COM 		 *  - Editable files are installed from the package instance
7909781SMoriah.Waterland@Sun.COM 		 *    save area.
7919781SMoriah.Waterland@Sun.COM 		 *  - Volatile files are installed from the package instance
7929781SMoriah.Waterland@Sun.COM 		 *    save area.
7939781SMoriah.Waterland@Sun.COM 		 *  - Executable and data files are installed from the final
7949781SMoriah.Waterland@Sun.COM 		 *    installed location as specified in the pkgmap file.
7959781SMoriah.Waterland@Sun.COM 		 *  - Installation scripts are run from the package spool
7969781SMoriah.Waterland@Sun.COM 		 *    save area.
7979781SMoriah.Waterland@Sun.COM 		 */
7989781SMoriah.Waterland@Sun.COM 		case 'z':
7999781SMoriah.Waterland@Sun.COM 			saveSpoolInstall++;
8009781SMoriah.Waterland@Sun.COM 			break;
8019781SMoriah.Waterland@Sun.COM 
8029781SMoriah.Waterland@Sun.COM 		/*
8039781SMoriah.Waterland@Sun.COM 		 * unrecognized option
8049781SMoriah.Waterland@Sun.COM 		 */
8059781SMoriah.Waterland@Sun.COM 		default:
8069781SMoriah.Waterland@Sun.COM 			usage();
8079781SMoriah.Waterland@Sun.COM 			/*NOTREACHED*/
8089781SMoriah.Waterland@Sun.COM 			/*
8099781SMoriah.Waterland@Sun.COM 			 * Although usage() calls a noreturn function,
8109781SMoriah.Waterland@Sun.COM 			 * needed to add return (1);  so that main() would
8119781SMoriah.Waterland@Sun.COM 			 * pass compilation checks. The statement below
8129781SMoriah.Waterland@Sun.COM 			 * should never be executed.
8139781SMoriah.Waterland@Sun.COM 			 */
8149781SMoriah.Waterland@Sun.COM 			return (1);
8159781SMoriah.Waterland@Sun.COM 		}
8169781SMoriah.Waterland@Sun.COM 	}
8179781SMoriah.Waterland@Sun.COM 
8189781SMoriah.Waterland@Sun.COM 	/*
8199781SMoriah.Waterland@Sun.COM 	 * ********************************************************************
8209781SMoriah.Waterland@Sun.COM 	 * validate command line options
8219781SMoriah.Waterland@Sun.COM 	 * ********************************************************************
8229781SMoriah.Waterland@Sun.COM 	 */
8239781SMoriah.Waterland@Sun.COM 
8249781SMoriah.Waterland@Sun.COM 	/* set "debug echo" flag according to setting of "-O debug" option */
8259781SMoriah.Waterland@Sun.COM 
8269781SMoriah.Waterland@Sun.COM 	(void) echoDebugSetFlag(debugFlag);
8279781SMoriah.Waterland@Sun.COM 	(void) log_set_verbose(debugFlag);
8289781SMoriah.Waterland@Sun.COM 
8299781SMoriah.Waterland@Sun.COM 	/* output entry debugging information */
8309781SMoriah.Waterland@Sun.COM 
8319781SMoriah.Waterland@Sun.COM 	if (z_running_in_global_zone()) {
8329781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_ENTRY_IN_GZ, prog_full_name);
8339781SMoriah.Waterland@Sun.COM 	} else {
8349781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_ENTRY_IN_LZ, prog_full_name, getzoneid(),
8359869SCasper.Dik@Sun.COM 		    z_get_zonename());
8369781SMoriah.Waterland@Sun.COM 	}
8379781SMoriah.Waterland@Sun.COM 
8389781SMoriah.Waterland@Sun.COM 	if (in_continue_mode() && !in_dryrun_mode()) {
8399781SMoriah.Waterland@Sun.COM 		progerr(ERR_LIVE_CONTINUE_NOT_SUPPORTED);
8409781SMoriah.Waterland@Sun.COM 		usage();
8419781SMoriah.Waterland@Sun.COM 		/*NOTREACHED*/
8429781SMoriah.Waterland@Sun.COM 	}
8439781SMoriah.Waterland@Sun.COM 
8449781SMoriah.Waterland@Sun.COM 	/* pkgask requires a response file */
8459781SMoriah.Waterland@Sun.COM 
8469781SMoriah.Waterland@Sun.COM 	if (askflag && (respfile == NULL)) {
8479781SMoriah.Waterland@Sun.COM 		usage();
8489781SMoriah.Waterland@Sun.COM 		/*NOTREACHED*/
8499781SMoriah.Waterland@Sun.COM 	}
8509781SMoriah.Waterland@Sun.COM 
8519781SMoriah.Waterland@Sun.COM 	/* if device specified, set appropriate device in pkgdev */
8529781SMoriah.Waterland@Sun.COM 
8539781SMoriah.Waterland@Sun.COM 	if (device) {
8549781SMoriah.Waterland@Sun.COM 		if (pkgdev.mount) {
8559781SMoriah.Waterland@Sun.COM 			pkgdev.bdevice = device;
8569781SMoriah.Waterland@Sun.COM 		} else {
8579781SMoriah.Waterland@Sun.COM 			pkgdev.cdevice = device;
8589781SMoriah.Waterland@Sun.COM 		}
8599781SMoriah.Waterland@Sun.COM 	}
8609781SMoriah.Waterland@Sun.COM 
8619781SMoriah.Waterland@Sun.COM 	/* if file system type specified, must have a device to mount */
8629781SMoriah.Waterland@Sun.COM 
8639781SMoriah.Waterland@Sun.COM 	if (pkgdev.fstyp && !pkgdev.mount) {
8649781SMoriah.Waterland@Sun.COM 		progerr(ERR_F_REQUIRES_M);
8659781SMoriah.Waterland@Sun.COM 		usage();
8669781SMoriah.Waterland@Sun.COM 		/*NOTREACHED*/
8679781SMoriah.Waterland@Sun.COM 	}
8689781SMoriah.Waterland@Sun.COM 
8699781SMoriah.Waterland@Sun.COM 	/* BEGIN DATA GATHERING PHASE */
8709781SMoriah.Waterland@Sun.COM 
8719781SMoriah.Waterland@Sun.COM 	/*
8729781SMoriah.Waterland@Sun.COM 	 * Get the mount table info and store internally.
8739781SMoriah.Waterland@Sun.COM 	 */
8749781SMoriah.Waterland@Sun.COM 	cont_file_read = B_FALSE;
8759781SMoriah.Waterland@Sun.COM 	if (in_continue_mode()) {
8769781SMoriah.Waterland@Sun.COM 		int error;
8779781SMoriah.Waterland@Sun.COM 		cont_file_read = read_continuation(&error);
8789781SMoriah.Waterland@Sun.COM 		if (error == -1) {
8799781SMoriah.Waterland@Sun.COM 			quit(99);
8809781SMoriah.Waterland@Sun.COM 			/*NOTREACHED*/
8819781SMoriah.Waterland@Sun.COM 		}
8829781SMoriah.Waterland@Sun.COM 		if (!in_dryrun_mode()) {
8839781SMoriah.Waterland@Sun.COM 			live_continue = 1;
8849781SMoriah.Waterland@Sun.COM 		}
8859781SMoriah.Waterland@Sun.COM 	}
8869781SMoriah.Waterland@Sun.COM 	/* Read the mount table if not done in continuation mode */
8879781SMoriah.Waterland@Sun.COM 	if (!cont_file_read) {
8889781SMoriah.Waterland@Sun.COM 		if (get_mntinfo(map_client, vfstab_file)) {
8899781SMoriah.Waterland@Sun.COM 			quit(99);
8909781SMoriah.Waterland@Sun.COM 			/*NOTREACHED*/
8919781SMoriah.Waterland@Sun.COM 		}
8929781SMoriah.Waterland@Sun.COM 	}
8939781SMoriah.Waterland@Sun.COM 
8949781SMoriah.Waterland@Sun.COM 	/*
8959781SMoriah.Waterland@Sun.COM 	 * This function defines the standard /var/... directories used later
8969781SMoriah.Waterland@Sun.COM 	 * to construct the paths to the various databases.
8979781SMoriah.Waterland@Sun.COM 	 */
8989781SMoriah.Waterland@Sun.COM 
8999781SMoriah.Waterland@Sun.COM 	set_PKGpaths(get_inst_root());
9009781SMoriah.Waterland@Sun.COM 
9019781SMoriah.Waterland@Sun.COM 	/*
9029781SMoriah.Waterland@Sun.COM 	 * If this is being installed on a client whose /var filesystem is
9039781SMoriah.Waterland@Sun.COM 	 * mounted in some odd way, remap the administrative paths to the
9049781SMoriah.Waterland@Sun.COM 	 * real filesystem. This could be avoided by simply mounting up the
9059781SMoriah.Waterland@Sun.COM 	 * client now; but we aren't yet to the point in the process where
9069781SMoriah.Waterland@Sun.COM 	 * modification of the filesystem is permitted.
9079781SMoriah.Waterland@Sun.COM 	 */
9089781SMoriah.Waterland@Sun.COM 	if (is_an_inst_root()) {
9099781SMoriah.Waterland@Sun.COM 		int fsys_value;
9109781SMoriah.Waterland@Sun.COM 
9119781SMoriah.Waterland@Sun.COM 		fsys_value = fsys(get_PKGLOC());
9129781SMoriah.Waterland@Sun.COM 		if (use_srvr_map_n(fsys_value))
9139781SMoriah.Waterland@Sun.COM 			set_PKGLOC(server_map(get_PKGLOC(), fsys_value));
9149781SMoriah.Waterland@Sun.COM 
9159781SMoriah.Waterland@Sun.COM 		fsys_value = fsys(get_PKGADM());
9169781SMoriah.Waterland@Sun.COM 		if (use_srvr_map_n(fsys_value))
9179781SMoriah.Waterland@Sun.COM 			set_PKGADM(server_map(get_PKGADM(), fsys_value));
9189781SMoriah.Waterland@Sun.COM 	}
9199781SMoriah.Waterland@Sun.COM 
9209781SMoriah.Waterland@Sun.COM 	/*
9219781SMoriah.Waterland@Sun.COM 	 * Initialize pkginfo PKGSAV entry, just in case we dryrun to
9229781SMoriah.Waterland@Sun.COM 	 * somewhere else.
9239781SMoriah.Waterland@Sun.COM 	 */
9249781SMoriah.Waterland@Sun.COM 	set_infoloc(get_PKGLOC());
9259781SMoriah.Waterland@Sun.COM 
9269781SMoriah.Waterland@Sun.COM 	/* pull off directory and package name from end of command line */
9279781SMoriah.Waterland@Sun.COM 
9289781SMoriah.Waterland@Sun.COM 	switch (argc-optind) {
9299781SMoriah.Waterland@Sun.COM 	case 0:	/* missing directory and package instance */
9309781SMoriah.Waterland@Sun.COM 		progerr(ERR_MISSING_DIR_AND_PKG);
9319781SMoriah.Waterland@Sun.COM 		usage();
9329781SMoriah.Waterland@Sun.COM 		/*NOTREACHED*/
9339781SMoriah.Waterland@Sun.COM 	case 1: /* missing package instance */
9349781SMoriah.Waterland@Sun.COM 		progerr(ERR_MISSING_PKG_INSTANCE);
9359781SMoriah.Waterland@Sun.COM 		usage();
9369781SMoriah.Waterland@Sun.COM 		/*NOTREACHED*/
9379781SMoriah.Waterland@Sun.COM 	case 2:	/* just right! */
9389781SMoriah.Waterland@Sun.COM 		pkgdev.dirname = argv[optind++];
9399781SMoriah.Waterland@Sun.COM 		srcinst = argv[optind++];
9409781SMoriah.Waterland@Sun.COM 		break;
9419781SMoriah.Waterland@Sun.COM 	default:	/* too many args! */
9429781SMoriah.Waterland@Sun.COM 		progerr(ERR_TOO_MANY_CMD_ARGS);
9439781SMoriah.Waterland@Sun.COM 		usage();
9449781SMoriah.Waterland@Sun.COM 		break;
9459781SMoriah.Waterland@Sun.COM 	}
9469781SMoriah.Waterland@Sun.COM 
9479781SMoriah.Waterland@Sun.COM 	(void) pkgparam(NULL, NULL);  /* close up prior pkg file if needed */
9489781SMoriah.Waterland@Sun.COM 
9499781SMoriah.Waterland@Sun.COM 	/*
9509781SMoriah.Waterland@Sun.COM 	 * Initialize installation admin parameters by reading
9519781SMoriah.Waterland@Sun.COM 	 * the adminfile.
9529781SMoriah.Waterland@Sun.COM 	 */
9539781SMoriah.Waterland@Sun.COM 
9549781SMoriah.Waterland@Sun.COM 	if (!askflag && !live_continue) {
9559781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_PKGINSTALL_ADMINFILE, admnfile ? admnfile : "");
9569781SMoriah.Waterland@Sun.COM 		setadminFile(admnfile);
9579781SMoriah.Waterland@Sun.COM 	}
9589781SMoriah.Waterland@Sun.COM 
9599781SMoriah.Waterland@Sun.COM 	/*
9609781SMoriah.Waterland@Sun.COM 	 * about to perform first operation that could be modified by the
9619781SMoriah.Waterland@Sun.COM 	 * preinstall check option - if preinstall check is selected (that is,
9629781SMoriah.Waterland@Sun.COM 	 * only gathering dependencies), then output a debug message to
9639781SMoriah.Waterland@Sun.COM 	 * indicate that the check is beginning. Also turn echo() output
9649781SMoriah.Waterland@Sun.COM 	 * off and set various other flags.
9659781SMoriah.Waterland@Sun.COM 	 */
9669781SMoriah.Waterland@Sun.COM 
9679781SMoriah.Waterland@Sun.COM 	if (preinstallCheck == B_TRUE) {
9689781SMoriah.Waterland@Sun.COM 		(void) echoSetFlag(B_FALSE);
9699781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_PKGINSTALL_PREINSCHK,
9709781SMoriah.Waterland@Sun.COM 			pkginst ? pkginst : (srcinst ? srcinst : ""),
9719781SMoriah.Waterland@Sun.COM 			zoneName ? zoneName : "global");
9729781SMoriah.Waterland@Sun.COM 		cksetPreinstallCheck(B_TRUE);
9739781SMoriah.Waterland@Sun.COM 		cksetZoneName(zoneName);
9749781SMoriah.Waterland@Sun.COM 		/* inform quit that the install has started */
9759781SMoriah.Waterland@Sun.COM 		quitSetInstallStarted(B_TRUE);
9769781SMoriah.Waterland@Sun.COM 	}
9779781SMoriah.Waterland@Sun.COM 
9789781SMoriah.Waterland@Sun.COM 	/*
9799781SMoriah.Waterland@Sun.COM 	 * validate the "rscriptalt" admin file setting
9809781SMoriah.Waterland@Sun.COM 	 * The rscriptalt admin file parameter may be set to either
9819781SMoriah.Waterland@Sun.COM 	 * RSCRIPTALT_ROOT or RSCRIPTALT_NOACCESS:
9829781SMoriah.Waterland@Sun.COM 	 * --> If rscriptalt is not set, or is set to RSCRIPTALT_NOACCESS,
9839781SMoriah.Waterland@Sun.COM 	 * --> or is set to any value OTHER than RSCRIPTALT_ROOT, then
9849781SMoriah.Waterland@Sun.COM 	 * --> assume that the parameter is set to RSCRIPTALT_NOACCESS
9859781SMoriah.Waterland@Sun.COM 	 * If rscriptalt is set to RSCRIPTALT_ROOT, then run request scripts
9869781SMoriah.Waterland@Sun.COM 	 * as the "root" user if user "install" is not defined.
9879781SMoriah.Waterland@Sun.COM 	 * Otherwise, assume rscriptalt is set to RSCRIPTALT_NOACCESS, and run
9889781SMoriah.Waterland@Sun.COM 	 * request scripts as the "alternative" user if user "install" is not
9899781SMoriah.Waterland@Sun.COM 	 * defined, as appropriate for the current setting of the NONABI_SCRIPTS
9909781SMoriah.Waterland@Sun.COM 	 * environment variable.
9919781SMoriah.Waterland@Sun.COM 	 */
9929781SMoriah.Waterland@Sun.COM 
9939781SMoriah.Waterland@Sun.COM 	if (ADMSET(RSCRIPTALT)) {
9949781SMoriah.Waterland@Sun.COM 		p = adm.RSCRIPTALT;
9959781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_PKGINSTALL_RSCRIPT_SET_TO, RSCRIPTALT_KEYWORD, p);
9969781SMoriah.Waterland@Sun.COM 		if (strcasecmp(p, RSCRIPTALT_ROOT) == 0) {
9979781SMoriah.Waterland@Sun.COM 			/* rscriptalt=root */
9989781SMoriah.Waterland@Sun.COM 			run_request_as_root = B_TRUE;
9999781SMoriah.Waterland@Sun.COM 		} else if (strcasecmp(p, RSCRIPTALT_NOACCESS) == 0) {
10009781SMoriah.Waterland@Sun.COM 			/* rscriptalt=noaccess */
10019781SMoriah.Waterland@Sun.COM 			run_request_as_root = B_FALSE;
10029781SMoriah.Waterland@Sun.COM 		} else {
10039781SMoriah.Waterland@Sun.COM 			/* rscriptalt=??? */
10049781SMoriah.Waterland@Sun.COM 			logerr(WRN_RSCRIPTALT_BAD, RSCRIPTALT_KEYWORD, p,
10059781SMoriah.Waterland@Sun.COM 				RSCRIPTALT_ROOT, RSCRIPTALT_NOACCESS);
10069781SMoriah.Waterland@Sun.COM 			logerr(WRN_RSCRIPTALT_USING, RSCRIPTALT_KEYWORD,
10079781SMoriah.Waterland@Sun.COM 				RSCRIPTALT_NOACCESS);
10089781SMoriah.Waterland@Sun.COM 			run_request_as_root = B_FALSE;
10099781SMoriah.Waterland@Sun.COM 		}
10109781SMoriah.Waterland@Sun.COM 	} else {
10119781SMoriah.Waterland@Sun.COM 		/* rscriptalt not set - assume rscriptalt=noaccess */
10129781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_PKGINSTALL_RSCRIPT_NOT_SET, RSCRIPTALT_KEYWORD);
10139781SMoriah.Waterland@Sun.COM 		run_request_as_root = B_FALSE;
10149781SMoriah.Waterland@Sun.COM 	}
10159781SMoriah.Waterland@Sun.COM 
10169781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_PKGINSTALL_RSCRIPT_IS_ROOT, run_request_as_root);
10179781SMoriah.Waterland@Sun.COM 
10189781SMoriah.Waterland@Sun.COM 	/*
10199781SMoriah.Waterland@Sun.COM 	 * hook SIGINT and SIGHUP interrupts into quit.c's trap handler
10209781SMoriah.Waterland@Sun.COM 	 */
10219781SMoriah.Waterland@Sun.COM 
10229781SMoriah.Waterland@Sun.COM 	/* hold SIGINT/SIGHUP interrupts */
10239781SMoriah.Waterland@Sun.COM 
10249781SMoriah.Waterland@Sun.COM 	(void) sighold(SIGHUP);
10259781SMoriah.Waterland@Sun.COM 	(void) sighold(SIGINT);
10269781SMoriah.Waterland@Sun.COM 
10279781SMoriah.Waterland@Sun.COM 	/* connect quit.c:trap() to SIGINT */
10289781SMoriah.Waterland@Sun.COM 
10299781SMoriah.Waterland@Sun.COM 	nact.sa_handler = quitGetTrapHandler();
10309781SMoriah.Waterland@Sun.COM 	nact.sa_flags = SA_RESTART;
10319781SMoriah.Waterland@Sun.COM 	(void) sigemptyset(&nact.sa_mask);
10329781SMoriah.Waterland@Sun.COM 
10339781SMoriah.Waterland@Sun.COM 	(void) sigaction(SIGINT, &nact, &oact);
10349781SMoriah.Waterland@Sun.COM 
10359781SMoriah.Waterland@Sun.COM 	/* connect quit.c:trap() to SIGHUP */
10369781SMoriah.Waterland@Sun.COM 
10379781SMoriah.Waterland@Sun.COM 	nact.sa_handler = quitGetTrapHandler();
10389781SMoriah.Waterland@Sun.COM 	nact.sa_flags = SA_RESTART;
10399781SMoriah.Waterland@Sun.COM 	(void) sigemptyset(&nact.sa_mask);
10409781SMoriah.Waterland@Sun.COM 
10419781SMoriah.Waterland@Sun.COM 	(void) sigaction(SIGHUP, &nact, &oact);
10429781SMoriah.Waterland@Sun.COM 
10439781SMoriah.Waterland@Sun.COM 	/* release hold on signals */
10449781SMoriah.Waterland@Sun.COM 
10459781SMoriah.Waterland@Sun.COM 	(void) sigrelse(SIGHUP);
10469781SMoriah.Waterland@Sun.COM 	(void) sigrelse(SIGINT);
10479781SMoriah.Waterland@Sun.COM 
10489781SMoriah.Waterland@Sun.COM 	/*
10499781SMoriah.Waterland@Sun.COM 	 * create required /var... directories if they do not exist;
10509781SMoriah.Waterland@Sun.COM 	 * this function will call quit(99) if any required path cannot
10519781SMoriah.Waterland@Sun.COM 	 * be created.
10529781SMoriah.Waterland@Sun.COM 	 */
10539781SMoriah.Waterland@Sun.COM 
10549781SMoriah.Waterland@Sun.COM 	ckdirs();
10559781SMoriah.Waterland@Sun.COM 
10569781SMoriah.Waterland@Sun.COM 	tzset();
10579781SMoriah.Waterland@Sun.COM 
10589781SMoriah.Waterland@Sun.COM 	/*
10599781SMoriah.Waterland@Sun.COM 	 * create path to temporary directory "installXXXXXX" - if TMPDIR
10609781SMoriah.Waterland@Sun.COM 	 * environment variable is set, create the directory in $TMPDIR;
10619781SMoriah.Waterland@Sun.COM 	 * otherwise, create the directory in P_tmpdir.
10629781SMoriah.Waterland@Sun.COM 	 */
10639781SMoriah.Waterland@Sun.COM 
10649781SMoriah.Waterland@Sun.COM 	pt = getenv("TMPDIR");
10659781SMoriah.Waterland@Sun.COM 	(void) snprintf(tmpdir, sizeof (tmpdir), "%s/installXXXXXX",
10669781SMoriah.Waterland@Sun.COM 		((pt != (char *)NULL) && (*pt != '\0')) ? pt : P_tmpdir);
10679781SMoriah.Waterland@Sun.COM 
10689781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_PKGINSTALL_TMPDIR, tmpdir);
10699781SMoriah.Waterland@Sun.COM 
10709781SMoriah.Waterland@Sun.COM 	if ((mktemp(tmpdir) == NULL) || mkdir(tmpdir, 0771)) {
10719781SMoriah.Waterland@Sun.COM 		progerr(ERR_MKDIR, tmpdir);
10729781SMoriah.Waterland@Sun.COM 		quit(99);
10739781SMoriah.Waterland@Sun.COM 		/*NOTREACHED*/
10749781SMoriah.Waterland@Sun.COM 	}
10759781SMoriah.Waterland@Sun.COM 
10769781SMoriah.Waterland@Sun.COM 	/*
10779781SMoriah.Waterland@Sun.COM 	 * if the package device is a file containing a package stream,
10789781SMoriah.Waterland@Sun.COM 	 * unpack the stream into a temporary directory
10799781SMoriah.Waterland@Sun.COM 	 */
10809781SMoriah.Waterland@Sun.COM 
10819781SMoriah.Waterland@Sun.COM 	if ((isdir(pkgdev.dirname) != 0) &&
10829781SMoriah.Waterland@Sun.COM 		(pkgdev.cdevice == (char *)NULL) &&
10839781SMoriah.Waterland@Sun.COM 		(pkgdev.bdevice == (char *)NULL) &&
10849781SMoriah.Waterland@Sun.COM 		(isfile((char *)NULL, pkgdev.dirname) == 0)) {
10859781SMoriah.Waterland@Sun.COM 
10869781SMoriah.Waterland@Sun.COM 		char		*idsName = (char *)NULL;
10879781SMoriah.Waterland@Sun.COM 		char		*pkgnames[2];
10889781SMoriah.Waterland@Sun.COM 		char		*device = pkgdev.dirname;
10899781SMoriah.Waterland@Sun.COM 		boolean_t	b;
10909781SMoriah.Waterland@Sun.COM 
10919781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_PKGINSTALL_DS_ISFILE, pkgdev.dirname);
10929781SMoriah.Waterland@Sun.COM 
10939781SMoriah.Waterland@Sun.COM 		/*
10949781SMoriah.Waterland@Sun.COM 		 * validate the package source device - return pkgdev info that
10959781SMoriah.Waterland@Sun.COM 		 * describes the package source device.
10969781SMoriah.Waterland@Sun.COM 		 */
10979781SMoriah.Waterland@Sun.COM 
10989781SMoriah.Waterland@Sun.COM 		if (devtype(device, &pkgdev)) {
10999781SMoriah.Waterland@Sun.COM 			progerr(ERR_BAD_DEVICE, device);
11009781SMoriah.Waterland@Sun.COM 			quit(99);
11019781SMoriah.Waterland@Sun.COM 			/* NOTREACHED */
11029781SMoriah.Waterland@Sun.COM 		}
11039781SMoriah.Waterland@Sun.COM 
11049781SMoriah.Waterland@Sun.COM 		/* generate the list of packages to verify */
11059781SMoriah.Waterland@Sun.COM 
11069781SMoriah.Waterland@Sun.COM 		pkgnames[0] = srcinst;
11079781SMoriah.Waterland@Sun.COM 		pkgnames[1] = (char *)NULL;
11089781SMoriah.Waterland@Sun.COM 
11099781SMoriah.Waterland@Sun.COM 		b = open_package_datastream(1, pkgnames, (char *)NULL,
11109781SMoriah.Waterland@Sun.COM 			pkgdev.dirname, (int *)NULL, &idsName, tmpdir, &pkgdev,
11119781SMoriah.Waterland@Sun.COM 			1);
11129781SMoriah.Waterland@Sun.COM 
11139781SMoriah.Waterland@Sun.COM 		if (b == B_FALSE) {
11149781SMoriah.Waterland@Sun.COM 			progerr(ERR_CANNOT_OPEN_PKG_STREAM,
11159781SMoriah.Waterland@Sun.COM 				pkgdev.dirname ? pkgdev.dirname : "?");
11169781SMoriah.Waterland@Sun.COM 			quit(99);
11179781SMoriah.Waterland@Sun.COM 			/*NOTREACHED*/
11189781SMoriah.Waterland@Sun.COM 		}
11199781SMoriah.Waterland@Sun.COM 
11209781SMoriah.Waterland@Sun.COM 		/* make sure temporary directory is removed on exit */
11219781SMoriah.Waterland@Sun.COM 
11229781SMoriah.Waterland@Sun.COM 		quitSetDstreamTmpdir(pkgdev.dirname);
11239781SMoriah.Waterland@Sun.COM 
11249781SMoriah.Waterland@Sun.COM 		/* unpack the package instance from the data stream */
11259781SMoriah.Waterland@Sun.COM 
11269781SMoriah.Waterland@Sun.COM 		b = unpack_package_from_stream(idsName, srcinst,
11279781SMoriah.Waterland@Sun.COM 							pkgdev.dirname);
11289781SMoriah.Waterland@Sun.COM 		if (b == B_FALSE) {
11299781SMoriah.Waterland@Sun.COM 			progerr(ERR_CANNOT_UNPACK_PKGSTRM,
11309781SMoriah.Waterland@Sun.COM 				srcinst ? srcinst : "?",
11319781SMoriah.Waterland@Sun.COM 				idsName ? idsName : "?",
11329781SMoriah.Waterland@Sun.COM 				pkgdev.dirname ? pkgdev.dirname : "?");
11339781SMoriah.Waterland@Sun.COM 			quit(99);
11349781SMoriah.Waterland@Sun.COM 			/*NOTREACHED*/
11359781SMoriah.Waterland@Sun.COM 		}
11369781SMoriah.Waterland@Sun.COM 
11379781SMoriah.Waterland@Sun.COM 		/* close the datastream - no longer needed */
11389781SMoriah.Waterland@Sun.COM 
11399781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_CLOSING_STREAM, idsName, pkgdev.dirname);
11409781SMoriah.Waterland@Sun.COM 		(void) ds_close(1);
11419781SMoriah.Waterland@Sun.COM 	}
11429781SMoriah.Waterland@Sun.COM 
11439781SMoriah.Waterland@Sun.COM 	if (snprintf(instdir, PATH_MAX, "%s/%s", pkgdev.dirname, srcinst)
11449781SMoriah.Waterland@Sun.COM 	    >= PATH_MAX) {
11459781SMoriah.Waterland@Sun.COM 		progerr(ERR_SNPRINTF, instdir);
11469781SMoriah.Waterland@Sun.COM 		quit(99);
11479781SMoriah.Waterland@Sun.COM 		/*NOTREACHED*/
11489781SMoriah.Waterland@Sun.COM 	}
11499781SMoriah.Waterland@Sun.COM 
11509781SMoriah.Waterland@Sun.COM 	zoneName = getenv(PKG_ZONENAME_VARIABLE);
11519781SMoriah.Waterland@Sun.COM 
11529781SMoriah.Waterland@Sun.COM 	/*
11539781SMoriah.Waterland@Sun.COM 	 * If the environment has a CLIENT_BASEDIR, that takes precedence
11549781SMoriah.Waterland@Sun.COM 	 * over anything we will construct. We need to save it here because
11559781SMoriah.Waterland@Sun.COM 	 * in three lines, the current environment goes away.
11569781SMoriah.Waterland@Sun.COM 	 */
11579781SMoriah.Waterland@Sun.COM 	(void) set_env_cbdir();	/* copy over environ */
11589781SMoriah.Waterland@Sun.COM 
11599781SMoriah.Waterland@Sun.COM 	getuserlocale();
11609781SMoriah.Waterland@Sun.COM 
11619781SMoriah.Waterland@Sun.COM 	/*
11629781SMoriah.Waterland@Sun.COM 	 * current environment has been read; clear environment out
11639781SMoriah.Waterland@Sun.COM 	 * so putparam() can be used to populate the new environment
11649781SMoriah.Waterland@Sun.COM 	 * to be passed to any executables/scripts.
11659781SMoriah.Waterland@Sun.COM 	 */
11669781SMoriah.Waterland@Sun.COM 
11679781SMoriah.Waterland@Sun.COM 	environ = NULL;
11689781SMoriah.Waterland@Sun.COM 
11699781SMoriah.Waterland@Sun.COM 	/* write parent condition information to environment */
11709781SMoriah.Waterland@Sun.COM 
11719781SMoriah.Waterland@Sun.COM 	putConditionInfo(parentZoneName, parentZoneType);
11729781SMoriah.Waterland@Sun.COM 
11739781SMoriah.Waterland@Sun.COM 	putuserlocale();
11749781SMoriah.Waterland@Sun.COM 
11759781SMoriah.Waterland@Sun.COM 	if (init_install) {
11769781SMoriah.Waterland@Sun.COM 		putparam("PKG_INIT_INSTALL", "TRUE");
11779781SMoriah.Waterland@Sun.COM 	}
11789781SMoriah.Waterland@Sun.COM 
11799781SMoriah.Waterland@Sun.COM 	if (is_an_inst_root()) {
11809781SMoriah.Waterland@Sun.COM 		export_client_env(get_inst_root());
11819781SMoriah.Waterland@Sun.COM 	}
11829781SMoriah.Waterland@Sun.COM 
11839781SMoriah.Waterland@Sun.COM 	if (zoneName != (char *)NULL) {
11849781SMoriah.Waterland@Sun.COM 		putparam(PKG_ZONENAME_VARIABLE, zoneName);
11859781SMoriah.Waterland@Sun.COM 	}
11869781SMoriah.Waterland@Sun.COM 
11879781SMoriah.Waterland@Sun.COM 	putparam("INST_DATADIR", pkgdev.dirname);
11889781SMoriah.Waterland@Sun.COM 
11899781SMoriah.Waterland@Sun.COM 	if (non_abi_scripts) {
11909781SMoriah.Waterland@Sun.COM 		putparam("NONABI_SCRIPTS", "TRUE");
11919781SMoriah.Waterland@Sun.COM 	}
11929781SMoriah.Waterland@Sun.COM 
11939781SMoriah.Waterland@Sun.COM 	if (nonABI_symlinks()) {
11949781SMoriah.Waterland@Sun.COM 		putparam("PKG_NONABI_SYMLINKS", "TRUE");
11959781SMoriah.Waterland@Sun.COM 	}
11969781SMoriah.Waterland@Sun.COM 
11979781SMoriah.Waterland@Sun.COM 	if (get_ABI_namelngth()) {
11989781SMoriah.Waterland@Sun.COM 		putparam("PKG_ABI_NAMELENGTH", "TRUE");
11999781SMoriah.Waterland@Sun.COM 	}
12009781SMoriah.Waterland@Sun.COM 
12019781SMoriah.Waterland@Sun.COM 	/* establish path and oambase */
12029781SMoriah.Waterland@Sun.COM 
12039781SMoriah.Waterland@Sun.COM 	if (cmdbin[0] == '\0') {
12049781SMoriah.Waterland@Sun.COM 		(void) strlcpy(cmdbin, PKGBIN, sizeof (cmdbin));
12059781SMoriah.Waterland@Sun.COM 	}
12069781SMoriah.Waterland@Sun.COM 
12079781SMoriah.Waterland@Sun.COM 	(void) snprintf(path, sizeof (path), "%s:%s", DEFPATH, cmdbin);
12089781SMoriah.Waterland@Sun.COM 
12099781SMoriah.Waterland@Sun.COM 	putparam("PATH", path);
12109781SMoriah.Waterland@Sun.COM 
12119781SMoriah.Waterland@Sun.COM 	putparam("OAMBASE", OAMBASE);
12129781SMoriah.Waterland@Sun.COM 
12139781SMoriah.Waterland@Sun.COM 	(void) snprintf(p_pkginfo, sizeof (p_pkginfo),
12149781SMoriah.Waterland@Sun.COM 			"%s/%s", instdir, PKGINFO);
12159781SMoriah.Waterland@Sun.COM 	(void) snprintf(p_pkgmap, sizeof (p_pkgmap),
12169781SMoriah.Waterland@Sun.COM 			"%s/%s", instdir, PKGMAP);
12179781SMoriah.Waterland@Sun.COM 
12189781SMoriah.Waterland@Sun.COM 	/* Read the environment (from pkginfo or '-e') ... */
12199781SMoriah.Waterland@Sun.COM 	abi_nm_ptr = getenv("PKG_ABI_NAMELENGTH");
12209781SMoriah.Waterland@Sun.COM 
12219781SMoriah.Waterland@Sun.COM 	/* Disable the 32 char name limit extension */
12229781SMoriah.Waterland@Sun.COM 	if (abi_nm_ptr && strncasecmp(abi_nm_ptr, "TRUE", 4) == 0) {
12239781SMoriah.Waterland@Sun.COM 		(void) set_ABI_namelngth();
12249781SMoriah.Waterland@Sun.COM 	}
12259781SMoriah.Waterland@Sun.COM 
12269781SMoriah.Waterland@Sun.COM 	/*
12279781SMoriah.Waterland@Sun.COM 	 * This tests the pkginfo and pkgmap files for validity and
12289781SMoriah.Waterland@Sun.COM 	 * puts all delivered pkginfo variables (except for PATH) into
12299781SMoriah.Waterland@Sun.COM 	 * our environment. This is where a delivered pkginfo BASEDIR
12309781SMoriah.Waterland@Sun.COM 	 * would come from. See set_basedirs() below.
12319781SMoriah.Waterland@Sun.COM 	 */
12329781SMoriah.Waterland@Sun.COM 
12339781SMoriah.Waterland@Sun.COM 	if (pkgenv(srcinst, p_pkginfo, p_pkgmap)) {
12349781SMoriah.Waterland@Sun.COM 		quit(1);
12359781SMoriah.Waterland@Sun.COM 		/*NOTREACHED*/
12369781SMoriah.Waterland@Sun.COM 	}
12379781SMoriah.Waterland@Sun.COM 
12389781SMoriah.Waterland@Sun.COM 	echo("\n%s(%s) %s", pkgname, pkgarch, pkgvers);
12399781SMoriah.Waterland@Sun.COM 
12409781SMoriah.Waterland@Sun.COM 	/*
12419781SMoriah.Waterland@Sun.COM 	 * If this script was invoked by 'pkgask', just
12429781SMoriah.Waterland@Sun.COM 	 * execute request script and quit (do_pkgask()).
12439781SMoriah.Waterland@Sun.COM 	 */
12449781SMoriah.Waterland@Sun.COM 
12459781SMoriah.Waterland@Sun.COM 	if (askflag) {
12469781SMoriah.Waterland@Sun.COM 		do_pkgask(run_request_as_root);
12479781SMoriah.Waterland@Sun.COM 	}
12489781SMoriah.Waterland@Sun.COM 
12499781SMoriah.Waterland@Sun.COM 	/* validate package contents file */
12509781SMoriah.Waterland@Sun.COM 
12519781SMoriah.Waterland@Sun.COM 	if (vcfile() == 0) {
12529781SMoriah.Waterland@Sun.COM 		quit(99);
12539781SMoriah.Waterland@Sun.COM 	}
12549781SMoriah.Waterland@Sun.COM 
12559781SMoriah.Waterland@Sun.COM 	/* if not in dryrun mode aquire packaging lock */
12569781SMoriah.Waterland@Sun.COM 
12579781SMoriah.Waterland@Sun.COM 	if (!in_dryrun_mode()) {
12589781SMoriah.Waterland@Sun.COM 		/* acquire the package lock - at install initialization */
12599781SMoriah.Waterland@Sun.COM 		if (!lockinst(get_prog_name(), srcinst, "install-initial")) {
12609781SMoriah.Waterland@Sun.COM 			quit(99);
12619781SMoriah.Waterland@Sun.COM 			/*NOTREACHED*/
12629781SMoriah.Waterland@Sun.COM 		}
12639781SMoriah.Waterland@Sun.COM 	}
12649781SMoriah.Waterland@Sun.COM 
12659781SMoriah.Waterland@Sun.COM 	/*
12669781SMoriah.Waterland@Sun.COM 	 * Now do all the various setups based on ABI compliance
12679781SMoriah.Waterland@Sun.COM 	 */
12689781SMoriah.Waterland@Sun.COM 
12699781SMoriah.Waterland@Sun.COM 	/* Read the environment (from pkginfo or '-o') ... */
12709781SMoriah.Waterland@Sun.COM 	abi_comp_ptr = getenv("NONABI_SCRIPTS");
12719781SMoriah.Waterland@Sun.COM 
12729781SMoriah.Waterland@Sun.COM 	/* Read the environment (from pkginfo or '-y') ... */
12739781SMoriah.Waterland@Sun.COM 	abi_sym_ptr = getenv("PKG_NONABI_SYMLINKS");
12749781SMoriah.Waterland@Sun.COM 
12759781SMoriah.Waterland@Sun.COM 	/* bug id 4244631, not ABI compliant */
12769781SMoriah.Waterland@Sun.COM 	if (abi_comp_ptr && strncasecmp(abi_comp_ptr, "TRUE", 4) == 0) {
12779781SMoriah.Waterland@Sun.COM 		script_in = PROC_XSTDIN;
12789781SMoriah.Waterland@Sun.COM 		non_abi_scripts = 1;
12799781SMoriah.Waterland@Sun.COM 	}
12809781SMoriah.Waterland@Sun.COM 
12819781SMoriah.Waterland@Sun.COM #ifdef	ALLOW_EXCEPTION_PKG_LIST
12829781SMoriah.Waterland@Sun.COM 	/*
12839781SMoriah.Waterland@Sun.COM 	 * *********************************************************************
12849781SMoriah.Waterland@Sun.COM 	 * this feature is removed starting with Solaris 10 - there is no built
12859781SMoriah.Waterland@Sun.COM 	 * in list of packages that should be run "the old way"
12869781SMoriah.Waterland@Sun.COM 	 * *********************************************************************
12879781SMoriah.Waterland@Sun.COM 	 */
12889781SMoriah.Waterland@Sun.COM 
12899781SMoriah.Waterland@Sun.COM 	else if (exception_pkg(srcinst, SCRIPT)) {
12909781SMoriah.Waterland@Sun.COM 		/*
12919781SMoriah.Waterland@Sun.COM 		 * Until on1095, set it from exception package names as
12929781SMoriah.Waterland@Sun.COM 		 * well.
12939781SMoriah.Waterland@Sun.COM 		 */
12949781SMoriah.Waterland@Sun.COM 		putparam("NONABI_SCRIPTS", "TRUE");
12959781SMoriah.Waterland@Sun.COM 		script_in = PROC_XSTDIN;
12969781SMoriah.Waterland@Sun.COM 		non_abi_scripts = 1;
12979781SMoriah.Waterland@Sun.COM 	}
12989781SMoriah.Waterland@Sun.COM #endif
12999781SMoriah.Waterland@Sun.COM 
13009781SMoriah.Waterland@Sun.COM 	/* Set symlinks to be processed the old way */
13019781SMoriah.Waterland@Sun.COM 	if (abi_sym_ptr && strncasecmp(abi_sym_ptr, "TRUE", 4) == 0) {
13029781SMoriah.Waterland@Sun.COM 		set_nonABI_symlinks();
13039781SMoriah.Waterland@Sun.COM 	}
13049781SMoriah.Waterland@Sun.COM 	/*
13059781SMoriah.Waterland@Sun.COM 	 * *********************************************************************
13069781SMoriah.Waterland@Sun.COM 	 * this feature is removed starting with Solaris 10 - there is no built
13079781SMoriah.Waterland@Sun.COM 	 * in list of packages that should be run "the old way"
13089781SMoriah.Waterland@Sun.COM 	 * *********************************************************************
13099781SMoriah.Waterland@Sun.COM 	 */
13109781SMoriah.Waterland@Sun.COM 
13119781SMoriah.Waterland@Sun.COM #ifdef	ALLOW_EXCEPTION_PKG_LIST
13129781SMoriah.Waterland@Sun.COM 	else if (exception_pkg(srcinst, LINK)) {
13139781SMoriah.Waterland@Sun.COM 		/* Until 2.9, set it from the execption list */
13149781SMoriah.Waterland@Sun.COM 		putparam("PKG_NONABI_SYMLINKS", "TRUE");
13159781SMoriah.Waterland@Sun.COM 		set_nonABI_symlinks();
13169781SMoriah.Waterland@Sun.COM 	}
13179781SMoriah.Waterland@Sun.COM #endif
13189781SMoriah.Waterland@Sun.COM 	/*
13199781SMoriah.Waterland@Sun.COM 	 * At this point, script_in, non_abi_scripts & the environment are
13209781SMoriah.Waterland@Sun.COM 	 * all set correctly for the ABI status of the package.
13219781SMoriah.Waterland@Sun.COM 	 */
13229781SMoriah.Waterland@Sun.COM 
13239781SMoriah.Waterland@Sun.COM 	if (pt = getenv("MAXINST")) {
13249781SMoriah.Waterland@Sun.COM 		maxinst = atol(pt);
13259781SMoriah.Waterland@Sun.COM 	}
13269781SMoriah.Waterland@Sun.COM 
13279781SMoriah.Waterland@Sun.COM 	/*
13289781SMoriah.Waterland@Sun.COM 	 * See if were are installing a package that only wants to update
13299781SMoriah.Waterland@Sun.COM 	 * the database or only install files associated with CAS's. We
13309781SMoriah.Waterland@Sun.COM 	 * only check the PKG_HOLLOW_VARIABLE variable if told to do so by
13319781SMoriah.Waterland@Sun.COM 	 * the caller.
13329781SMoriah.Waterland@Sun.COM 	 */
13339781SMoriah.Waterland@Sun.COM 
13349781SMoriah.Waterland@Sun.COM 	if (is_depend_pkginfo_DB()) {
13359781SMoriah.Waterland@Sun.COM 		pt = getenv(PKG_HOLLOW_VARIABLE);
13369781SMoriah.Waterland@Sun.COM 		if ((pt != NULL) && (strncasecmp(pt, "true", 4) == 0)) {
13379781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_PKGREMOVE_HOLLOW_ENABLED);
13389781SMoriah.Waterland@Sun.COM 			if (disableAttributes) {
13399781SMoriah.Waterland@Sun.COM 				disable_attribute_check();
13409781SMoriah.Waterland@Sun.COM 			}
13419781SMoriah.Waterland@Sun.COM 
13429781SMoriah.Waterland@Sun.COM 			/*
13439781SMoriah.Waterland@Sun.COM 			 * this is a hollow package and hollow package support
13449781SMoriah.Waterland@Sun.COM 			 * is enabled -- override admin settings to suppress
13459781SMoriah.Waterland@Sun.COM 			 * checks that do not make sense since no scripts will
13469781SMoriah.Waterland@Sun.COM 			 * be executed and no files will be installed.
13479781SMoriah.Waterland@Sun.COM 			 */
13489781SMoriah.Waterland@Sun.COM 
13499781SMoriah.Waterland@Sun.COM 			setadminSetting("conflict", "nocheck");
13509781SMoriah.Waterland@Sun.COM 			setadminSetting("setuid", "nocheck");
13519781SMoriah.Waterland@Sun.COM 			setadminSetting("action", "nocheck");
13529781SMoriah.Waterland@Sun.COM 			setadminSetting("partial", "nocheck");
13539781SMoriah.Waterland@Sun.COM 			setadminSetting("space", "nocheck");
13549781SMoriah.Waterland@Sun.COM 			setadminSetting("authentication", "nocheck");
13559781SMoriah.Waterland@Sun.COM 		} else {
13569781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_PKGREMOVE_HOLLOW_DISABLED);
13579781SMoriah.Waterland@Sun.COM 			set_depend_pkginfo_DB(B_FALSE);
13589781SMoriah.Waterland@Sun.COM 		}
13599781SMoriah.Waterland@Sun.COM 	}
13609781SMoriah.Waterland@Sun.COM 
13619781SMoriah.Waterland@Sun.COM 	/*
13629781SMoriah.Waterland@Sun.COM 	 * if performing a fresh install to a non-global zone, and doing
13639781SMoriah.Waterland@Sun.COM 	 * more than just updating the package database (that is, the
13649781SMoriah.Waterland@Sun.COM 	 * package to install is NOT "hollow"), then set the global flag
13659781SMoriah.Waterland@Sun.COM 	 * that directs installation is from partially spooled packages
13669781SMoriah.Waterland@Sun.COM 	 * (that is, packages installed in the global zone).
13679781SMoriah.Waterland@Sun.COM 	 */
13689781SMoriah.Waterland@Sun.COM 
13699781SMoriah.Waterland@Sun.COM 	if (saveSpoolInstall && (!is_depend_pkginfo_DB())) {
13709781SMoriah.Waterland@Sun.COM 		set_partial_inst();
13719781SMoriah.Waterland@Sun.COM 	} else {
13729781SMoriah.Waterland@Sun.COM 		saveSpoolInstall = 0;
13739781SMoriah.Waterland@Sun.COM 	}
13749781SMoriah.Waterland@Sun.COM 
13759781SMoriah.Waterland@Sun.COM 	/*
13769781SMoriah.Waterland@Sun.COM 	 * verify that we are not trying to install an
13779781SMoriah.Waterland@Sun.COM 	 * INTONLY package with no interaction
13789781SMoriah.Waterland@Sun.COM 	 */
13799781SMoriah.Waterland@Sun.COM 
13809781SMoriah.Waterland@Sun.COM 	if (pt = getenv("INTONLY")) {
13819781SMoriah.Waterland@Sun.COM 		if (askflag || nointeract) {
13829781SMoriah.Waterland@Sun.COM 			progerr(ERR_INTONLY, pkgabrv ? pkgabrv : "?");
13839781SMoriah.Waterland@Sun.COM 			quit(1);
13849781SMoriah.Waterland@Sun.COM 			/*NOTREACHED*/
13859781SMoriah.Waterland@Sun.COM 		}
13869781SMoriah.Waterland@Sun.COM 	}
13879781SMoriah.Waterland@Sun.COM 
13889781SMoriah.Waterland@Sun.COM 	if (!suppressCopyright && !pkgdev.cdevice) {
13899781SMoriah.Waterland@Sun.COM 		copyright();
13909781SMoriah.Waterland@Sun.COM 	}
13919781SMoriah.Waterland@Sun.COM 
13929781SMoriah.Waterland@Sun.COM 	/*
13939781SMoriah.Waterland@Sun.COM 	 * inspect the system to determine if any instances of the
13949781SMoriah.Waterland@Sun.COM 	 * package being installed already exist on the system
13959781SMoriah.Waterland@Sun.COM 	 */
13969781SMoriah.Waterland@Sun.COM 
13979781SMoriah.Waterland@Sun.COM 	prvinfo = (struct pkginfo *)calloc(MALSIZ, sizeof (struct pkginfo));
13989781SMoriah.Waterland@Sun.COM 	if (prvinfo == NULL) {
13999781SMoriah.Waterland@Sun.COM 		progerr(ERR_MEMORY, errno);
14009781SMoriah.Waterland@Sun.COM 		quit(99);
14019781SMoriah.Waterland@Sun.COM 		/*NOTREACHED*/
14029781SMoriah.Waterland@Sun.COM 	}
14039781SMoriah.Waterland@Sun.COM 
14049781SMoriah.Waterland@Sun.COM 	for (;;) {
14059781SMoriah.Waterland@Sun.COM 		if (pkginfo(&prvinfo[npkgs], pkgwild, NULL, NULL)) {
14069781SMoriah.Waterland@Sun.COM 			if ((errno == ESRCH) || (errno == ENOENT)) {
14079781SMoriah.Waterland@Sun.COM 				break;
14089781SMoriah.Waterland@Sun.COM 			}
14099781SMoriah.Waterland@Sun.COM 			progerr(ERR_SYSINFO, errno);
14109781SMoriah.Waterland@Sun.COM 			quit(99);
14119781SMoriah.Waterland@Sun.COM 			/*NOTREACHED*/
14129781SMoriah.Waterland@Sun.COM 		}
14139781SMoriah.Waterland@Sun.COM 		if ((++npkgs % MALSIZ) == 0) {
14149781SMoriah.Waterland@Sun.COM 			prvinfo = (struct pkginfo *)realloc(prvinfo,
14159781SMoriah.Waterland@Sun.COM 				(npkgs+MALSIZ) * sizeof (struct pkginfo));
14169781SMoriah.Waterland@Sun.COM 			if (prvinfo == NULL) {
14179781SMoriah.Waterland@Sun.COM 				progerr(ERR_MEMORY, errno);
14189781SMoriah.Waterland@Sun.COM 				quit(99);
14199781SMoriah.Waterland@Sun.COM 				/*NOTREACHED*/
14209781SMoriah.Waterland@Sun.COM 			}
14219781SMoriah.Waterland@Sun.COM 		}
14229781SMoriah.Waterland@Sun.COM 	}
14239781SMoriah.Waterland@Sun.COM 
14249781SMoriah.Waterland@Sun.COM 	/*
14259781SMoriah.Waterland@Sun.COM 	 * Determine the correct package instance based on how many packages are
14269781SMoriah.Waterland@Sun.COM 	 * already installed. If there are none (npkgs == 0), getinst() just
14279781SMoriah.Waterland@Sun.COM 	 * returns the package abbreviation. Otherwise, getinst() interacts with
14289781SMoriah.Waterland@Sun.COM 	 * the user (or reads the admin file) to determine if an instance which
14299781SMoriah.Waterland@Sun.COM 	 * is already installed should be overwritten, or possibly install a new
14309781SMoriah.Waterland@Sun.COM 	 * instance of this package
14319781SMoriah.Waterland@Sun.COM 	 */
14329781SMoriah.Waterland@Sun.COM 
14339781SMoriah.Waterland@Sun.COM 	pkginst = getinst(&update, prvinfo, npkgs, preinstallCheck);
14349781SMoriah.Waterland@Sun.COM 
14359781SMoriah.Waterland@Sun.COM 	/* set "update flag" if updating an existing instance of this package */
14369781SMoriah.Waterland@Sun.COM 
14379781SMoriah.Waterland@Sun.COM 	if (update) {
14389781SMoriah.Waterland@Sun.COM 		setUpdate();
14399781SMoriah.Waterland@Sun.COM 	}
14409781SMoriah.Waterland@Sun.COM 
14419781SMoriah.Waterland@Sun.COM 	/*
14429781SMoriah.Waterland@Sun.COM 	 * Need to force UPDATE to be NULL in case a patch has been applied
14439781SMoriah.Waterland@Sun.COM 	 * before creating a zone. Some pkgs (SUNWcsr) already spooled
14449781SMoriah.Waterland@Sun.COM 	 * to the zone, check the value of UPDATE in their postinstall script.
14459781SMoriah.Waterland@Sun.COM 	 * After a pkg has been patched UPDATE exists statically in the
14469781SMoriah.Waterland@Sun.COM 	 * pkginfo file and this value must be reset when installing a zone.
14479781SMoriah.Waterland@Sun.COM 	 */
14489781SMoriah.Waterland@Sun.COM 
14499781SMoriah.Waterland@Sun.COM 	if (saveSpoolInstall != 0 && !isPatchUpdate() && !isUpdate()) {
14509781SMoriah.Waterland@Sun.COM 		putparam("UPDATE", "");
14519781SMoriah.Waterland@Sun.COM 	}
14529781SMoriah.Waterland@Sun.COM 
14539781SMoriah.Waterland@Sun.COM 	/* inform quit() if updating existing or installing new instance */
14549781SMoriah.Waterland@Sun.COM 
14559781SMoriah.Waterland@Sun.COM 	quitSetUpdatingExisting(update ? B_TRUE : B_FALSE);
14569781SMoriah.Waterland@Sun.COM 
14579781SMoriah.Waterland@Sun.COM 	if (respfile) {
14589781SMoriah.Waterland@Sun.COM 		(void) set_respfile(respfile, pkginst, RESP_RO);
14599781SMoriah.Waterland@Sun.COM 	}
14609781SMoriah.Waterland@Sun.COM 
14619781SMoriah.Waterland@Sun.COM 	(void) snprintf(pkgloc, sizeof (pkgloc),
14629781SMoriah.Waterland@Sun.COM 			"%s/%s", get_PKGLOC(), pkginst);
14639781SMoriah.Waterland@Sun.COM 
14649781SMoriah.Waterland@Sun.COM 	(void) snprintf(pkgbin, sizeof (pkgbin),
14659781SMoriah.Waterland@Sun.COM 			"%s/install", pkgloc);
14669781SMoriah.Waterland@Sun.COM 
14679781SMoriah.Waterland@Sun.COM 	(void) snprintf(pkgsav, sizeof (pkgsav),
14689781SMoriah.Waterland@Sun.COM 			"%s/save", pkgloc);
14699781SMoriah.Waterland@Sun.COM 
14709781SMoriah.Waterland@Sun.COM 	if (snprintf(saveSpoolInstallDir, PATH_MAX, "%s/pspool/%s", pkgsav,
14719781SMoriah.Waterland@Sun.COM 			pkginst) < 0) {
14729781SMoriah.Waterland@Sun.COM 		progerr(ERR_SNPRINTF, saveSpoolInstallDir);
14739781SMoriah.Waterland@Sun.COM 		quit(99);
14749781SMoriah.Waterland@Sun.COM 		/*NOTREACHED*/
14759781SMoriah.Waterland@Sun.COM 	}
14769781SMoriah.Waterland@Sun.COM 
14779781SMoriah.Waterland@Sun.COM 	(void) snprintf(ilockfile, sizeof (ilockfile),
14789781SMoriah.Waterland@Sun.COM 			"%s/!I-Lock!", pkgloc);
14799781SMoriah.Waterland@Sun.COM 	(void) snprintf(rlockfile, sizeof (rlockfile),
14809781SMoriah.Waterland@Sun.COM 			"%s/!R-Lock!", pkgloc);
14819781SMoriah.Waterland@Sun.COM 	(void) snprintf(savlog, sizeof (savlog),
14829781SMoriah.Waterland@Sun.COM 			"%s/logs/%s", get_PKGADM(), pkginst);
14839781SMoriah.Waterland@Sun.COM 
14849781SMoriah.Waterland@Sun.COM 	putparam("PKGINST", pkginst);
14859781SMoriah.Waterland@Sun.COM 	putparam("PKGSAV", pkgsav);
14869781SMoriah.Waterland@Sun.COM 
14879781SMoriah.Waterland@Sun.COM 	/*
14889781SMoriah.Waterland@Sun.COM 	 * Be sure request script has access to PKG_INSTALL_ROOT if there is
14899781SMoriah.Waterland@Sun.COM 	 * one
14909781SMoriah.Waterland@Sun.COM 	 */
14919781SMoriah.Waterland@Sun.COM 
14929781SMoriah.Waterland@Sun.COM 	put_path_params();
14939781SMoriah.Waterland@Sun.COM 
14949781SMoriah.Waterland@Sun.COM 	if (!map_client) {
14959781SMoriah.Waterland@Sun.COM 		putparam("PKG_NO_UNIFIED", "TRUE");
14969781SMoriah.Waterland@Sun.COM 	}
14979781SMoriah.Waterland@Sun.COM 
14989781SMoriah.Waterland@Sun.COM 	/*
14999781SMoriah.Waterland@Sun.COM 	 * This maps the client filesystems into the server's space.
15009781SMoriah.Waterland@Sun.COM 	 */
15019781SMoriah.Waterland@Sun.COM 
15029781SMoriah.Waterland@Sun.COM 	if (map_client && !mount_client()) {
15039781SMoriah.Waterland@Sun.COM 		logerr(MSG_MANMOUNT);
15049781SMoriah.Waterland@Sun.COM 	}
15059781SMoriah.Waterland@Sun.COM 
15069781SMoriah.Waterland@Sun.COM 	/*
15079781SMoriah.Waterland@Sun.COM 	 * If this is an UPDATE then either this is exactly the same version
15089781SMoriah.Waterland@Sun.COM 	 * and architecture of an installed package or a different package is
15099781SMoriah.Waterland@Sun.COM 	 * intended to entirely replace an installed package of the same name
15109781SMoriah.Waterland@Sun.COM 	 * with a different VERSION or ARCH string.
15119781SMoriah.Waterland@Sun.COM 	 * Don't merge any databases if only gathering dependencies.
15129781SMoriah.Waterland@Sun.COM 	 */
15139781SMoriah.Waterland@Sun.COM 
15149781SMoriah.Waterland@Sun.COM 	if ((preinstallCheck == B_FALSE) && (update)) {
15159781SMoriah.Waterland@Sun.COM 		/*
15169781SMoriah.Waterland@Sun.COM 		 * If this version and architecture is already installed,
15179781SMoriah.Waterland@Sun.COM 		 * merge the installed and installing parameters and inform
15189781SMoriah.Waterland@Sun.COM 		 * all procedure scripts by defining UPDATE in the
15199781SMoriah.Waterland@Sun.COM 		 * environment.
15209781SMoriah.Waterland@Sun.COM 		 */
15219781SMoriah.Waterland@Sun.COM 
15229781SMoriah.Waterland@Sun.COM 		if (is_samepkg()) {
15239781SMoriah.Waterland@Sun.COM 			/*
15249781SMoriah.Waterland@Sun.COM 			 * If it's the same ARCH and VERSION, then a merge
15259781SMoriah.Waterland@Sun.COM 			 * and copy operation is necessary.
15269781SMoriah.Waterland@Sun.COM 			 */
15279781SMoriah.Waterland@Sun.COM 
15289781SMoriah.Waterland@Sun.COM 			if (n = merg_pkginfos(pclass, &mergd_pclass)) {
15299781SMoriah.Waterland@Sun.COM 				quit(n);
15309781SMoriah.Waterland@Sun.COM 				/*NOTREACHED*/
15319781SMoriah.Waterland@Sun.COM 			}
15329781SMoriah.Waterland@Sun.COM 
15339781SMoriah.Waterland@Sun.COM 			if (n = cp_pkgdirs()) {
15349781SMoriah.Waterland@Sun.COM 				quit(n);
15359781SMoriah.Waterland@Sun.COM 				/*NOTREACHED*/
15369781SMoriah.Waterland@Sun.COM 			}
15379781SMoriah.Waterland@Sun.COM 
15389781SMoriah.Waterland@Sun.COM 		} else {
15399781SMoriah.Waterland@Sun.COM 			/*
15409781SMoriah.Waterland@Sun.COM 			 * If it's a different ARCH and/or VERSION then this
15419781SMoriah.Waterland@Sun.COM 			 * is an "instance=overwrite" situation. The
15429781SMoriah.Waterland@Sun.COM 			 * installed base needs to be confirmed and the
15439781SMoriah.Waterland@Sun.COM 			 * package directories renamed.
15449781SMoriah.Waterland@Sun.COM 			 */
15459781SMoriah.Waterland@Sun.COM 
15469781SMoriah.Waterland@Sun.COM 			if (n = ck_instbase()) {
15479781SMoriah.Waterland@Sun.COM 				quit(n);
15489781SMoriah.Waterland@Sun.COM 				/*NOTREACHED*/
15499781SMoriah.Waterland@Sun.COM 			}
15509781SMoriah.Waterland@Sun.COM 
15519781SMoriah.Waterland@Sun.COM 			if (n = mv_pkgdirs()) {
15529781SMoriah.Waterland@Sun.COM 				quit(n);
15539781SMoriah.Waterland@Sun.COM 				/*NOTREACHED*/
15549781SMoriah.Waterland@Sun.COM 			}
15559781SMoriah.Waterland@Sun.COM 		}
15569781SMoriah.Waterland@Sun.COM 
15579781SMoriah.Waterland@Sun.COM 		putparam("UPDATE", "yes");
15589781SMoriah.Waterland@Sun.COM 
15599781SMoriah.Waterland@Sun.COM 	}
15609781SMoriah.Waterland@Sun.COM 
15619781SMoriah.Waterland@Sun.COM 	if (in_dryrun_mode()) {
15629781SMoriah.Waterland@Sun.COM 		set_dryrun_dir_loc();
15639781SMoriah.Waterland@Sun.COM 	}
15649781SMoriah.Waterland@Sun.COM 
15659781SMoriah.Waterland@Sun.COM 	if (preinstallCheck == B_FALSE) {
15669781SMoriah.Waterland@Sun.COM 		/*
15679781SMoriah.Waterland@Sun.COM 		 * Determine if the package has been partially installed on or
15689781SMoriah.Waterland@Sun.COM 		 * removed from this system.
15699781SMoriah.Waterland@Sun.COM 		 */
15709781SMoriah.Waterland@Sun.COM 		ck_w_dryrun(ckpartial, PARTIAL);
15719781SMoriah.Waterland@Sun.COM 
15729781SMoriah.Waterland@Sun.COM 		/*
15739781SMoriah.Waterland@Sun.COM 		 * make sure current runlevel is appropriate
15749781SMoriah.Waterland@Sun.COM 		 */
15759781SMoriah.Waterland@Sun.COM 		ck_w_dryrun(ckrunlevel, RUNLEVEL);
15769781SMoriah.Waterland@Sun.COM 	} else {
15779781SMoriah.Waterland@Sun.COM 		int	r;
15789781SMoriah.Waterland@Sun.COM 
15799781SMoriah.Waterland@Sun.COM 		/*
15809781SMoriah.Waterland@Sun.COM 		 * Just gathering dependencies - determine if the package has
15819781SMoriah.Waterland@Sun.COM 		 * been partially installed on or removed from this system and
15829781SMoriah.Waterland@Sun.COM 		 * output information to stdout
15839781SMoriah.Waterland@Sun.COM 		 */
15849781SMoriah.Waterland@Sun.COM 		r = ckpartial();
15859781SMoriah.Waterland@Sun.COM 		(void) fprintf(stdout, "ckpartialinstall=%d\n", r == 8 ? 1 : 0);
15869781SMoriah.Waterland@Sun.COM 		(void) fprintf(stdout, "ckpartialremove=%d\n", r == 9 ? 1 : 0);
15879781SMoriah.Waterland@Sun.COM 
15889781SMoriah.Waterland@Sun.COM 		/*
15899781SMoriah.Waterland@Sun.COM 		 * make sure current runlevel is appropriate
15909781SMoriah.Waterland@Sun.COM 		 */
15919781SMoriah.Waterland@Sun.COM 		r = ckrunlevel();
15929781SMoriah.Waterland@Sun.COM 		(void) fprintf(stdout, "ckrunlevel=%d\n", r);
15939781SMoriah.Waterland@Sun.COM 	}
15949781SMoriah.Waterland@Sun.COM 
15959781SMoriah.Waterland@Sun.COM 	if (pkgdev.cdevice) {
15969781SMoriah.Waterland@Sun.COM 		/* get first volume which contains info files */
15979781SMoriah.Waterland@Sun.COM 		unpack();
15989781SMoriah.Waterland@Sun.COM 		if (!suppressCopyright) {
15999781SMoriah.Waterland@Sun.COM 			copyright();
16009781SMoriah.Waterland@Sun.COM 		}
16019781SMoriah.Waterland@Sun.COM 	}
16029781SMoriah.Waterland@Sun.COM 
16039781SMoriah.Waterland@Sun.COM 	/* update the lock - at the request script */
16049781SMoriah.Waterland@Sun.COM 
16059781SMoriah.Waterland@Sun.COM 	lockupd("request");
16069781SMoriah.Waterland@Sun.COM 
16079781SMoriah.Waterland@Sun.COM 	/*
16089781SMoriah.Waterland@Sun.COM 	 * If no response file has been provided, initialize response file by
16099781SMoriah.Waterland@Sun.COM 	 * executing any request script provided by this package. Initialize
16109781SMoriah.Waterland@Sun.COM 	 * the response file if not gathering dependencies only.
16119781SMoriah.Waterland@Sun.COM 	 */
16129781SMoriah.Waterland@Sun.COM 
16139781SMoriah.Waterland@Sun.COM 	if ((!rdonly_respfile()) && (preinstallCheck == B_FALSE)) {
16149781SMoriah.Waterland@Sun.COM 		(void) snprintf(path, sizeof (path),
16159781SMoriah.Waterland@Sun.COM 			"%s/%s", instdir, REQUEST_FILE);
16169781SMoriah.Waterland@Sun.COM 		n = reqexec(update, path, non_abi_scripts,
16179781SMoriah.Waterland@Sun.COM 			run_request_as_root);
16189781SMoriah.Waterland@Sun.COM 		if (in_dryrun_mode()) {
16199781SMoriah.Waterland@Sun.COM 			set_dr_info(REQUESTEXITCODE, n);
16209781SMoriah.Waterland@Sun.COM 		}
16219781SMoriah.Waterland@Sun.COM 
16229781SMoriah.Waterland@Sun.COM 		ckreturn(n, ERR_REQUEST);
16239781SMoriah.Waterland@Sun.COM 	}
16249781SMoriah.Waterland@Sun.COM 
16259781SMoriah.Waterland@Sun.COM 	/*
16269781SMoriah.Waterland@Sun.COM 	 * Look for all parameters in response file which begin with a
16279781SMoriah.Waterland@Sun.COM 	 * capital letter, and place them in the environment.
16289781SMoriah.Waterland@Sun.COM 	 */
16299781SMoriah.Waterland@Sun.COM 
16309781SMoriah.Waterland@Sun.COM 	if ((is_a_respfile()) && (preinstallCheck == B_FALSE)) {
16319781SMoriah.Waterland@Sun.COM 		if (n = merg_respfile()) {
16329781SMoriah.Waterland@Sun.COM 			quit(n);
16339781SMoriah.Waterland@Sun.COM 			/*NOTREACHED*/
16349781SMoriah.Waterland@Sun.COM 		}
16359781SMoriah.Waterland@Sun.COM 	}
16369781SMoriah.Waterland@Sun.COM 
16379781SMoriah.Waterland@Sun.COM 	/*
16389781SMoriah.Waterland@Sun.COM 	 * Run a checkinstall script if one is provided by the package.
16399781SMoriah.Waterland@Sun.COM 	 * Don't execute checkinstall script if we are only updating the DB.
16409781SMoriah.Waterland@Sun.COM 	 * Don't execute checkinstall script if only gathering dependencies.
16419781SMoriah.Waterland@Sun.COM 	 */
16429781SMoriah.Waterland@Sun.COM 
16439781SMoriah.Waterland@Sun.COM 	/* update the lock - at the checkinstall script */
16449781SMoriah.Waterland@Sun.COM 	lockupd("checkinstall");
16459781SMoriah.Waterland@Sun.COM 
16469781SMoriah.Waterland@Sun.COM 	/* Execute checkinstall script if one is provided. */
16479781SMoriah.Waterland@Sun.COM 	(void) snprintf(script, sizeof (script), "%s/install/checkinstall",
16489781SMoriah.Waterland@Sun.COM 			instdir);
16499781SMoriah.Waterland@Sun.COM 	if (access(script, F_OK) != 0) {
16509781SMoriah.Waterland@Sun.COM 		/* no script present */
16519781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_PKGINSTALL_COC_NONE, pkginst, script,
16529781SMoriah.Waterland@Sun.COM 			zoneName ? zoneName : "global");
16539781SMoriah.Waterland@Sun.COM 	} else if (is_depend_pkginfo_DB()) {
16549781SMoriah.Waterland@Sun.COM 		/* updating db only: skip checkinstall script */
16559781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_PKGINSTALL_COC_DBUPD, pkginst, script,
16569781SMoriah.Waterland@Sun.COM 			zoneName ? zoneName : "global");
16579781SMoriah.Waterland@Sun.COM 	} else if (preinstallCheck == B_TRUE) {
16589781SMoriah.Waterland@Sun.COM 		/* only gathering dependencies: skip checkinstall script */
16599781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_PKGINSTALL_COC_NODEL, pkginst, script,
16609781SMoriah.Waterland@Sun.COM 			zoneName ? zoneName : "global");
16619781SMoriah.Waterland@Sun.COM 	} else {
16629781SMoriah.Waterland@Sun.COM 		/* script present and ok to run: run the script */
16639781SMoriah.Waterland@Sun.COM 		if (zoneName == (char *)NULL) {
16649781SMoriah.Waterland@Sun.COM 			echo(MSG_PKGINSTALL_EXECOC_GZ);
16659781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_PKGINSTALL_EXECOC_GZ, pkginst, script);
16669781SMoriah.Waterland@Sun.COM 		} else {
16679781SMoriah.Waterland@Sun.COM 			echo(MSG_PKGINSTALL_EXECOC_LZ, zoneName);
16689781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_PKGINSTALL_EXECOC_LZ, pkginst, script,
16699781SMoriah.Waterland@Sun.COM 				zoneName);
16709781SMoriah.Waterland@Sun.COM 		}
16719781SMoriah.Waterland@Sun.COM 		n = chkexec(update, script);
16729781SMoriah.Waterland@Sun.COM 		if (in_dryrun_mode()) {
16739781SMoriah.Waterland@Sun.COM 			set_dr_info(CHECKEXITCODE, n);
16749781SMoriah.Waterland@Sun.COM 		}
16759781SMoriah.Waterland@Sun.COM 
16769781SMoriah.Waterland@Sun.COM 		if (n == 3) {
16779781SMoriah.Waterland@Sun.COM 			echo(WRN_CHKINSTALL);
16789781SMoriah.Waterland@Sun.COM 			ckreturn(4, NULL);
16799781SMoriah.Waterland@Sun.COM 		} else if (n == 7) {
16809781SMoriah.Waterland@Sun.COM 			/* access returned error */
16819781SMoriah.Waterland@Sun.COM 			progerr(ERR_CHKINSTALL_NOSCRIPT, script);
16829781SMoriah.Waterland@Sun.COM 			ckreturn(4, ERR_CHKINSTALL);
16839781SMoriah.Waterland@Sun.COM 		} else {
16849781SMoriah.Waterland@Sun.COM 			ckreturn(n, ERR_CHKINSTALL);
16859781SMoriah.Waterland@Sun.COM 		}
16869781SMoriah.Waterland@Sun.COM 	}
16879781SMoriah.Waterland@Sun.COM 
16889781SMoriah.Waterland@Sun.COM 	/*
16899781SMoriah.Waterland@Sun.COM 	 * Now that the internal data structures are initialized, we can
16909781SMoriah.Waterland@Sun.COM 	 * initialize the dryrun files (which may be the same files).
16919781SMoriah.Waterland@Sun.COM 	 */
16929781SMoriah.Waterland@Sun.COM 
16939781SMoriah.Waterland@Sun.COM 	if (pkgdrtarg) {
16949781SMoriah.Waterland@Sun.COM 		init_dryrunfile(pkgdrtarg);
16959781SMoriah.Waterland@Sun.COM 	}
16969781SMoriah.Waterland@Sun.COM 
16979781SMoriah.Waterland@Sun.COM 	/*
16989781SMoriah.Waterland@Sun.COM 	 * Look for all parameters in response file which begin with a
16999781SMoriah.Waterland@Sun.COM 	 * capital letter, and place them in the environment.
17009781SMoriah.Waterland@Sun.COM 	 */
17019781SMoriah.Waterland@Sun.COM 	if (is_a_respfile()) {
17029781SMoriah.Waterland@Sun.COM 		if (n = merg_respfile()) {
17039781SMoriah.Waterland@Sun.COM 			quit(n);
17049781SMoriah.Waterland@Sun.COM 			/*NOTREACHED*/
17059781SMoriah.Waterland@Sun.COM 		}
17069781SMoriah.Waterland@Sun.COM 	}
17079781SMoriah.Waterland@Sun.COM 
17089781SMoriah.Waterland@Sun.COM 	/* update the lock - doing analysis */
17099781SMoriah.Waterland@Sun.COM 
17109781SMoriah.Waterland@Sun.COM 	lockupd("analysis");
17119781SMoriah.Waterland@Sun.COM 
17129781SMoriah.Waterland@Sun.COM 	/*
17139781SMoriah.Waterland@Sun.COM 	 * Determine package base directory and client base directory
17149781SMoriah.Waterland@Sun.COM 	 * if appropriate. Then encapsulate them for future retrieval.
17159781SMoriah.Waterland@Sun.COM 	 */
17169781SMoriah.Waterland@Sun.COM 	if ((err = set_basedirs(isreloc(instdir), adm.basedir, pkginst,
17179781SMoriah.Waterland@Sun.COM 		nointeract)) != 0) {
17189781SMoriah.Waterland@Sun.COM 		quit(err);
17199781SMoriah.Waterland@Sun.COM 		/*NOTREACHED*/
17209781SMoriah.Waterland@Sun.COM 	}
17219781SMoriah.Waterland@Sun.COM 
17229781SMoriah.Waterland@Sun.COM 	/*
17239781SMoriah.Waterland@Sun.COM 	 * Create the base directory if specified.
17249781SMoriah.Waterland@Sun.COM 	 * Don't create if we are only updating the DB.
17259781SMoriah.Waterland@Sun.COM 	 * Don't create if only gathering dependencies.
17269781SMoriah.Waterland@Sun.COM 	 */
17279781SMoriah.Waterland@Sun.COM 
17289781SMoriah.Waterland@Sun.COM 	if (!is_depend_pkginfo_DB() &&
17299781SMoriah.Waterland@Sun.COM 		!preinstallCheck && is_a_basedir()) {
17309781SMoriah.Waterland@Sun.COM 		mkbasedir(!nointeract, get_basedir());
17319781SMoriah.Waterland@Sun.COM 		echo(MSG_BASE_USED, get_basedir());
17329781SMoriah.Waterland@Sun.COM 	}
17339781SMoriah.Waterland@Sun.COM 
17349781SMoriah.Waterland@Sun.COM 	/*
17359781SMoriah.Waterland@Sun.COM 	 * Store PKG_INSTALL_ROOT, BASEDIR & CLIENT_BASEDIR in our
17369781SMoriah.Waterland@Sun.COM 	 * environment for later use by procedure scripts.
17379781SMoriah.Waterland@Sun.COM 	 */
17389781SMoriah.Waterland@Sun.COM 	put_path_params();
17399781SMoriah.Waterland@Sun.COM 
17409781SMoriah.Waterland@Sun.COM 	/*
17419781SMoriah.Waterland@Sun.COM 	 * the following two checks are done in the corresponding
17429781SMoriah.Waterland@Sun.COM 	 * ck() routine, but are repeated here to avoid re-processing
17439781SMoriah.Waterland@Sun.COM 	 * the database if we are administered to not include these
17449781SMoriah.Waterland@Sun.COM 	 * processes
17459781SMoriah.Waterland@Sun.COM 	 */
17469781SMoriah.Waterland@Sun.COM 	if (ADM(setuid, "nochange")) {
17479781SMoriah.Waterland@Sun.COM 		nosetuid++;	/* Clear setuid/gid bits. */
17489781SMoriah.Waterland@Sun.COM 	}
17499781SMoriah.Waterland@Sun.COM 
17509781SMoriah.Waterland@Sun.COM 	if (ADM(conflict, "nochange")) {
17519781SMoriah.Waterland@Sun.COM 		nocnflct++;	/* Don't install conflicting files. */
17529781SMoriah.Waterland@Sun.COM 	}
17539781SMoriah.Waterland@Sun.COM 
17549781SMoriah.Waterland@Sun.COM 	/*
17559781SMoriah.Waterland@Sun.COM 	 * Get the filesystem space information for the filesystem on which
17569781SMoriah.Waterland@Sun.COM 	 * the "contents" file resides.
17579781SMoriah.Waterland@Sun.COM 	 */
17589781SMoriah.Waterland@Sun.COM 
17599781SMoriah.Waterland@Sun.COM 	svfsb.f_bsize = 8192;
17609781SMoriah.Waterland@Sun.COM 	svfsb.f_frsize = 1024;
17619781SMoriah.Waterland@Sun.COM 
17629781SMoriah.Waterland@Sun.COM 	if (statvfs64(get_PKGADM(), &svfsb) == -1) {
17639781SMoriah.Waterland@Sun.COM 		int	lerrno = errno;
17649781SMoriah.Waterland@Sun.COM 		if (!access(get_PKGADM(), F_OK)) {
17659781SMoriah.Waterland@Sun.COM 			progerr(ERR_PKGINSTALL_STATVFS, get_PKGADM(),
17669781SMoriah.Waterland@Sun.COM 				strerror(errno));
17679781SMoriah.Waterland@Sun.COM 			logerr("(errno %d)", lerrno);
17689781SMoriah.Waterland@Sun.COM 			quit(99);
17699781SMoriah.Waterland@Sun.COM 			/*NOTREACHED*/
17709781SMoriah.Waterland@Sun.COM 		}
17719781SMoriah.Waterland@Sun.COM 	}
17729781SMoriah.Waterland@Sun.COM 
17739781SMoriah.Waterland@Sun.COM 	/*
17749781SMoriah.Waterland@Sun.COM 	 * Get the number of blocks used by the pkgmap, ocfile()
17759781SMoriah.Waterland@Sun.COM 	 * needs this to properly determine its space requirements.
17769781SMoriah.Waterland@Sun.COM 	 */
17779781SMoriah.Waterland@Sun.COM 
17789781SMoriah.Waterland@Sun.COM 	if (stat(p_pkgmap, &statb) == -1) {
17799781SMoriah.Waterland@Sun.COM 		progerr(ERR_PKGINSTALL_STATOF, p_pkgmap, strerror(errno));
17809781SMoriah.Waterland@Sun.COM 		quit(99);
17819781SMoriah.Waterland@Sun.COM 		/*NOTREACHED*/
17829781SMoriah.Waterland@Sun.COM 	}
17839781SMoriah.Waterland@Sun.COM 
17849781SMoriah.Waterland@Sun.COM 	pkgmap_blks = nblk(statb.st_size, svfsb.f_bsize, svfsb.f_frsize);
17859781SMoriah.Waterland@Sun.COM 
17869781SMoriah.Waterland@Sun.COM 	/*
17879781SMoriah.Waterland@Sun.COM 	 * Merge information in memory with the "contents" file; this creates
17889781SMoriah.Waterland@Sun.COM 	 * a temporary version of the "contents" file. Note that in dryrun
17899781SMoriah.Waterland@Sun.COM 	 * mode, we still need to record the contents file data somewhere,
17909781SMoriah.Waterland@Sun.COM 	 * but we do it in the dryrun directory.
17919781SMoriah.Waterland@Sun.COM 	 */
17929781SMoriah.Waterland@Sun.COM 
17939781SMoriah.Waterland@Sun.COM 	if (in_dryrun_mode()) {
17949781SMoriah.Waterland@Sun.COM 		if (n = set_cfdir(pkgdrtarg)) {
17959781SMoriah.Waterland@Sun.COM 			quit(n);
17969781SMoriah.Waterland@Sun.COM 			/*NOTREACHED*/
17979781SMoriah.Waterland@Sun.COM 		}
17989781SMoriah.Waterland@Sun.COM 	} else {
17999781SMoriah.Waterland@Sun.COM 		if (n = set_cfdir(NULL)) {
18009781SMoriah.Waterland@Sun.COM 			quit(n);
18019781SMoriah.Waterland@Sun.COM 			/*NOTREACHED*/
18029781SMoriah.Waterland@Sun.COM 		}
18039781SMoriah.Waterland@Sun.COM 	}
18049869SCasper.Dik@Sun.COM 	if (!ocfile(&pkgserver, &cfTmpVfp, pkgmap_blks)) {
18059781SMoriah.Waterland@Sun.COM 		quit(99);
18069781SMoriah.Waterland@Sun.COM 		/*NOTREACHED*/
18079781SMoriah.Waterland@Sun.COM 	}
18089781SMoriah.Waterland@Sun.COM 
18099781SMoriah.Waterland@Sun.COM 	/*
18109781SMoriah.Waterland@Sun.COM 	 * if cpio is being used,  tell pkgdbmerg since attributes will
18119781SMoriah.Waterland@Sun.COM 	 * have to be check and repaired on all file and directories
18129781SMoriah.Waterland@Sun.COM 	 */
18139781SMoriah.Waterland@Sun.COM 	for (np = cpio_names; *np != NULL; np++) {
18149781SMoriah.Waterland@Sun.COM 		(void) snprintf(path, sizeof (path),
18159781SMoriah.Waterland@Sun.COM 			"%s/%s", instdir, *np);
18169781SMoriah.Waterland@Sun.COM 		if (iscpio(path, &is_comp_arch)) {
18179781SMoriah.Waterland@Sun.COM 			is_WOS_arch();
18189781SMoriah.Waterland@Sun.COM 			break;
18199781SMoriah.Waterland@Sun.COM 		}
18209781SMoriah.Waterland@Sun.COM 	}
18219781SMoriah.Waterland@Sun.COM 
18229781SMoriah.Waterland@Sun.COM 	/* Establish the class list and the class attributes. */
18239781SMoriah.Waterland@Sun.COM 	cl_sets(getenv("CLASSES"));
18249781SMoriah.Waterland@Sun.COM 	find_CAS(I_ONLY, pkgbin, instdir);
18259781SMoriah.Waterland@Sun.COM 
18269781SMoriah.Waterland@Sun.COM 	if (vfpOpen(&pkgmapVfp, p_pkgmap, "r", VFP_NEEDNOW) != 0) {
18279781SMoriah.Waterland@Sun.COM 		progerr(ERR_PKGMAP, p_pkgmap);
18289781SMoriah.Waterland@Sun.COM 		quit(99);
18299781SMoriah.Waterland@Sun.COM 		/*NOTREACHED*/
18309781SMoriah.Waterland@Sun.COM 	}
18319781SMoriah.Waterland@Sun.COM 
18329781SMoriah.Waterland@Sun.COM 	/*
18339781SMoriah.Waterland@Sun.COM 	 * This modifies the path list entries in memory to reflect
18349781SMoriah.Waterland@Sun.COM 	 * how they should look after the merg is complete
18359781SMoriah.Waterland@Sun.COM 	 */
18369781SMoriah.Waterland@Sun.COM 
18379869SCasper.Dik@Sun.COM 	nparts = sortmap(&extlist, pkgmapVfp, pkgserver, cfTmpVfp, zoneName);
18389781SMoriah.Waterland@Sun.COM 
18399781SMoriah.Waterland@Sun.COM 	if ((n = files_installed()) > 0) {
18409781SMoriah.Waterland@Sun.COM 		if (n > 1) {
18419781SMoriah.Waterland@Sun.COM 			echo(MSG_INST_MANY, n);
18429781SMoriah.Waterland@Sun.COM 		} else {
18439781SMoriah.Waterland@Sun.COM 			echo(MSG_INST_ONE, n);
18449781SMoriah.Waterland@Sun.COM 		}
18459781SMoriah.Waterland@Sun.COM 	}
18469781SMoriah.Waterland@Sun.COM 
18479781SMoriah.Waterland@Sun.COM 	/*
18489781SMoriah.Waterland@Sun.COM 	 * Check ulimit requirement (provided in pkginfo). The purpose of
18499781SMoriah.Waterland@Sun.COM 	 * this limit is to terminate pathological file growth resulting from
18509781SMoriah.Waterland@Sun.COM 	 * file edits in scripts. It does not apply to files in the pkgmap
18519781SMoriah.Waterland@Sun.COM 	 * and it does not apply to any database files manipulated by the
18529781SMoriah.Waterland@Sun.COM 	 * installation service.
18539781SMoriah.Waterland@Sun.COM 	 */
18549781SMoriah.Waterland@Sun.COM 	if (pt = getenv("ULIMIT")) {
18559781SMoriah.Waterland@Sun.COM 		if (assign_ulimit(pt) == -1) {
18569781SMoriah.Waterland@Sun.COM 			progerr(ERR_BADULIMIT, pt);
18579781SMoriah.Waterland@Sun.COM 			quit(99);
18589781SMoriah.Waterland@Sun.COM 			/*NOTREACHED*/
18599781SMoriah.Waterland@Sun.COM 		}
18609781SMoriah.Waterland@Sun.COM 		putparam("PKG_ULIMIT", "TRUE");
18619781SMoriah.Waterland@Sun.COM 	}
18629781SMoriah.Waterland@Sun.COM 
18639781SMoriah.Waterland@Sun.COM 	/*
18649781SMoriah.Waterland@Sun.COM 	 * If only gathering dependencies, check and output status of all
18659781SMoriah.Waterland@Sun.COM 	 * remaining dependencies and exit.
18669781SMoriah.Waterland@Sun.COM 	 */
18679781SMoriah.Waterland@Sun.COM 
18689781SMoriah.Waterland@Sun.COM 	if (preinstallCheck == B_TRUE) {
18699781SMoriah.Waterland@Sun.COM 		/* update the lock file - final checking */
18709781SMoriah.Waterland@Sun.COM 
18719781SMoriah.Waterland@Sun.COM 		lockupd("preinstallcheck");
18729781SMoriah.Waterland@Sun.COM 
18739781SMoriah.Waterland@Sun.COM 		/* verify package information files are not corrupt */
18749781SMoriah.Waterland@Sun.COM 
18759781SMoriah.Waterland@Sun.COM 		(void) fprintf(stdout, "ckpkgfiles=%d\n", ckpkgfiles());
18769781SMoriah.Waterland@Sun.COM 
18779781SMoriah.Waterland@Sun.COM 		/* verify package dependencies */
18789781SMoriah.Waterland@Sun.COM 
18799781SMoriah.Waterland@Sun.COM 		(void) fprintf(stdout, "ckdepend=%d\n", ckdepend());
18809781SMoriah.Waterland@Sun.COM 
18819781SMoriah.Waterland@Sun.COM 		/* Check space requirements */
18829781SMoriah.Waterland@Sun.COM 
18839781SMoriah.Waterland@Sun.COM 		(void) fprintf(stdout, "ckspace=%d\n", ckspace());
18849781SMoriah.Waterland@Sun.COM 
18859781SMoriah.Waterland@Sun.COM 		/*
18869781SMoriah.Waterland@Sun.COM 		 * Determine if any objects provided by this package conflict
18879781SMoriah.Waterland@Sun.COM 		 * with the files of previously installed packages.
18889781SMoriah.Waterland@Sun.COM 		 */
18899781SMoriah.Waterland@Sun.COM 
18909781SMoriah.Waterland@Sun.COM 		(void) fprintf(stdout, "ckconflict=%d\n", ckconflct());
18919781SMoriah.Waterland@Sun.COM 
18929781SMoriah.Waterland@Sun.COM 		/*
18939781SMoriah.Waterland@Sun.COM 		 * Determine if any objects provided by this package will be
18949781SMoriah.Waterland@Sun.COM 		 * installed with setuid or setgid enabled.
18959781SMoriah.Waterland@Sun.COM 		 */
18969781SMoriah.Waterland@Sun.COM 
18979781SMoriah.Waterland@Sun.COM 		(void) fprintf(stdout, "cksetuid=%d\n", cksetuid());
18989781SMoriah.Waterland@Sun.COM 
18999781SMoriah.Waterland@Sun.COM 		/*
19009781SMoriah.Waterland@Sun.COM 		 * Determine if any packaging scripts provided with this package
19019781SMoriah.Waterland@Sun.COM 		 * will execute as a priviledged user.
19029781SMoriah.Waterland@Sun.COM 		 */
19039781SMoriah.Waterland@Sun.COM 
19049781SMoriah.Waterland@Sun.COM 		(void) fprintf(stdout, "ckpriv=%d\n", ckpriv());
19059781SMoriah.Waterland@Sun.COM 
19069781SMoriah.Waterland@Sun.COM 		/* Verify neccessary package installation directories exist */
19079781SMoriah.Waterland@Sun.COM 
19089781SMoriah.Waterland@Sun.COM 		(void) fprintf(stdout, "ckpkgdirs=%d\n", ckpkgdirs());
19099781SMoriah.Waterland@Sun.COM 
19109781SMoriah.Waterland@Sun.COM 		/*
19119781SMoriah.Waterland@Sun.COM 		 * ****** preinstall check done - exit ******
19129781SMoriah.Waterland@Sun.COM 		 */
19139781SMoriah.Waterland@Sun.COM 
19149781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_PKGINSTALL_PREINSCHK_OK);
19159781SMoriah.Waterland@Sun.COM 		quit(0);
19169781SMoriah.Waterland@Sun.COM 		/*NOTREACHED*/
19179781SMoriah.Waterland@Sun.COM 	}
19189781SMoriah.Waterland@Sun.COM 
19199781SMoriah.Waterland@Sun.COM 	/*
19209781SMoriah.Waterland@Sun.COM 	 * Not gathering dependencies only, proceed to check dependencies
19219781SMoriah.Waterland@Sun.COM 	 * and continue with the package installation operation.
19229781SMoriah.Waterland@Sun.COM 	 */
19239781SMoriah.Waterland@Sun.COM 
19249781SMoriah.Waterland@Sun.COM 	/*
19259781SMoriah.Waterland@Sun.COM 	 * verify package information files are not corrupt
19269781SMoriah.Waterland@Sun.COM 	 */
19279781SMoriah.Waterland@Sun.COM 	ck_w_dryrun(ckpkgfiles, PKGFILES);
19289781SMoriah.Waterland@Sun.COM 
19299781SMoriah.Waterland@Sun.COM 	/*
19309781SMoriah.Waterland@Sun.COM 	 * verify package dependencies
19319781SMoriah.Waterland@Sun.COM 	 */
19329781SMoriah.Waterland@Sun.COM 	ck_w_dryrun(ckdepend, DEPEND);
19339781SMoriah.Waterland@Sun.COM 
19349781SMoriah.Waterland@Sun.COM 	/*
19359781SMoriah.Waterland@Sun.COM 	 * Check space requirements.
19369781SMoriah.Waterland@Sun.COM 	 */
19379781SMoriah.Waterland@Sun.COM 	ck_w_dryrun(ckspace, SPACE);
19389781SMoriah.Waterland@Sun.COM 
19399781SMoriah.Waterland@Sun.COM 	/*
19409781SMoriah.Waterland@Sun.COM 	 * Determine if any objects provided by this package conflict with
19419781SMoriah.Waterland@Sun.COM 	 * the files of previously installed packages.
19429781SMoriah.Waterland@Sun.COM 	 */
19439781SMoriah.Waterland@Sun.COM 	ck_w_dryrun(ckconflct, CONFLICT);
19449781SMoriah.Waterland@Sun.COM 
19459781SMoriah.Waterland@Sun.COM 	/*
19469781SMoriah.Waterland@Sun.COM 	 * Determine if any objects provided by this package will be
19479781SMoriah.Waterland@Sun.COM 	 * installed with setuid or setgid enabled.
19489781SMoriah.Waterland@Sun.COM 	 */
19499781SMoriah.Waterland@Sun.COM 	ck_w_dryrun(cksetuid, SETUID);
19509781SMoriah.Waterland@Sun.COM 
19519781SMoriah.Waterland@Sun.COM 	/*
19529781SMoriah.Waterland@Sun.COM 	 * Determine if any packaging scripts provided with this package will
19539781SMoriah.Waterland@Sun.COM 	 * execute as a priviledged user.
19549781SMoriah.Waterland@Sun.COM 	 */
19559781SMoriah.Waterland@Sun.COM 	ck_w_dryrun(ckpriv, PRIV);
19569781SMoriah.Waterland@Sun.COM 
19579781SMoriah.Waterland@Sun.COM 	/*
19589781SMoriah.Waterland@Sun.COM 	 * Verify neccessary package installation directories exist.
19599781SMoriah.Waterland@Sun.COM 	 */
19609781SMoriah.Waterland@Sun.COM 	ck_w_dryrun(ckpkgdirs, PKGDIRS);
19619781SMoriah.Waterland@Sun.COM 
19629781SMoriah.Waterland@Sun.COM 	/*
19639781SMoriah.Waterland@Sun.COM 	 * If we have assumed that we were installing setuid or conflicting
19649781SMoriah.Waterland@Sun.COM 	 * files, and the user chose to do otherwise, we need to read in the
19659781SMoriah.Waterland@Sun.COM 	 * package map again and re-merg with the "contents" file
19669781SMoriah.Waterland@Sun.COM 	 */
19679781SMoriah.Waterland@Sun.COM 
19689781SMoriah.Waterland@Sun.COM 	if (rprcflag) {
19699869SCasper.Dik@Sun.COM 		nparts = sortmap(&extlist, pkgmapVfp, pkgserver,
19709781SMoriah.Waterland@Sun.COM 				cfTmpVfp, zoneName);
19719781SMoriah.Waterland@Sun.COM 	}
19729781SMoriah.Waterland@Sun.COM 
19739781SMoriah.Waterland@Sun.COM 	(void) vfpClose(&pkgmapVfp);
19749781SMoriah.Waterland@Sun.COM 
19759781SMoriah.Waterland@Sun.COM 	/* BEGIN INSTALLATION PHASE */
19769781SMoriah.Waterland@Sun.COM 	if (in_dryrun_mode()) {
19779781SMoriah.Waterland@Sun.COM 		echo(MSG_PKGINSTALL_DRYRUN, pkgname, pkginst);
19789781SMoriah.Waterland@Sun.COM 	} else if (zoneName == (char *)NULL) {
19799781SMoriah.Waterland@Sun.COM 		echo(MSG_PKGINSTALL_INSIN_GZ, pkgname, pkginst);
19809781SMoriah.Waterland@Sun.COM 	} else {
19819781SMoriah.Waterland@Sun.COM 		echo(MSG_PKGINSTALL_INSIN_LZ, pkgname, pkginst, zoneName);
19829781SMoriah.Waterland@Sun.COM 	}
19839781SMoriah.Waterland@Sun.COM 
19849781SMoriah.Waterland@Sun.COM 	/* inform quit that the install has started */
19859781SMoriah.Waterland@Sun.COM 
19869781SMoriah.Waterland@Sun.COM 	quitSetInstallStarted(B_TRUE);
19879781SMoriah.Waterland@Sun.COM 
19889781SMoriah.Waterland@Sun.COM 	/*
19899781SMoriah.Waterland@Sun.COM 	 * This replaces the contents file with recently created temp version
19909781SMoriah.Waterland@Sun.COM 	 * which contains information about the objects being installed.
19919781SMoriah.Waterland@Sun.COM 	 * Under old lock protocol it closes both files and releases the
19929781SMoriah.Waterland@Sun.COM 	 * locks. Beginning in Solaris 2.7, this lock method should be
19939781SMoriah.Waterland@Sun.COM 	 * reviewed.
19949781SMoriah.Waterland@Sun.COM 	 */
19959781SMoriah.Waterland@Sun.COM 
19969869SCasper.Dik@Sun.COM 	n = swapcfile(pkgserver, &cfTmpVfp, pkginst, dbchg);
19979781SMoriah.Waterland@Sun.COM 	if (n == RESULT_WRN) {
19989781SMoriah.Waterland@Sun.COM 		warnflag++;
19999781SMoriah.Waterland@Sun.COM 	} else if (n == RESULT_ERR) {
20009781SMoriah.Waterland@Sun.COM 		quit(99);
20019781SMoriah.Waterland@Sun.COM 		/*NOTREACHED*/
20029781SMoriah.Waterland@Sun.COM 	}
20039781SMoriah.Waterland@Sun.COM 
20049781SMoriah.Waterland@Sun.COM 	/*
20059781SMoriah.Waterland@Sun.COM 	 * Create install-specific lockfile to indicate start of
20069781SMoriah.Waterland@Sun.COM 	 * installation. This is really just an information file. If the
20079781SMoriah.Waterland@Sun.COM 	 * process dies, the initial lockfile (from lockinst(), is
20089781SMoriah.Waterland@Sun.COM 	 * relinquished by the kernel, but this one remains in support of the
20099781SMoriah.Waterland@Sun.COM 	 * post-mortem.
20109781SMoriah.Waterland@Sun.COM 	 */
20119781SMoriah.Waterland@Sun.COM 
20129781SMoriah.Waterland@Sun.COM 	if (access(ilockfile, F_OK) == 0) {
20139781SMoriah.Waterland@Sun.COM 		(void) remove(ilockfile);
20149781SMoriah.Waterland@Sun.COM 	}
20159781SMoriah.Waterland@Sun.COM 
20169781SMoriah.Waterland@Sun.COM 	if (open(ilockfile, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL, 0644) < 0) {
20179781SMoriah.Waterland@Sun.COM 		progerr(ERR_LOCKFILE, ilockfile);
20189781SMoriah.Waterland@Sun.COM 		quit(99);
20199781SMoriah.Waterland@Sun.COM 		/*NOTREACHED*/
20209781SMoriah.Waterland@Sun.COM 	}
20219781SMoriah.Waterland@Sun.COM 
20229781SMoriah.Waterland@Sun.COM 	(void) time(&clock);
202312222SNagaraj.Yedathore@Sun.COM 
202412222SNagaraj.Yedathore@Sun.COM 	/*
202512222SNagaraj.Yedathore@Sun.COM 	 * We do not want the time in locale in the pkginfo.
202612222SNagaraj.Yedathore@Sun.COM 	 * save the LC_TIME and set it to C. Reset it with saved one
202712222SNagaraj.Yedathore@Sun.COM 	 * after cftime().
202812222SNagaraj.Yedathore@Sun.COM 	 */
202912222SNagaraj.Yedathore@Sun.COM 	temp = setlocale(LC_TIME, NULL);
203012222SNagaraj.Yedathore@Sun.COM 	(void) setlocale(LC_TIME, "C");
203112222SNagaraj.Yedathore@Sun.COM 
20329781SMoriah.Waterland@Sun.COM 	/* LINTED warning: do not use cftime(); ... */
20339781SMoriah.Waterland@Sun.COM 	(void) cftime(cbuf, "%b %d \045Y \045H:\045M", &clock);
20349781SMoriah.Waterland@Sun.COM 	putparam("INSTDATE", qstrdup(cbuf));
203512222SNagaraj.Yedathore@Sun.COM 	(void) setlocale(LC_TIME, temp);
20369781SMoriah.Waterland@Sun.COM 
20379781SMoriah.Waterland@Sun.COM 	/*
20389781SMoriah.Waterland@Sun.COM 	 * Store information about package being installed;
20399781SMoriah.Waterland@Sun.COM 	 * modify installation parameters as neccessary and
20409781SMoriah.Waterland@Sun.COM 	 * copy contents of 'install' directory into $pkgloc
20419781SMoriah.Waterland@Sun.COM 	 */
20429781SMoriah.Waterland@Sun.COM 	merginfo(mergd_pclass, saveSpoolInstall);
20439781SMoriah.Waterland@Sun.COM 
20449781SMoriah.Waterland@Sun.COM 	/* If this was just a dryrun, then quit() will write out that file. */
20459781SMoriah.Waterland@Sun.COM 	if (in_dryrun_mode()) {
20469781SMoriah.Waterland@Sun.COM 		quit(0);
20479781SMoriah.Waterland@Sun.COM 		/*NOTREACHED*/
20489781SMoriah.Waterland@Sun.COM 	}
20499781SMoriah.Waterland@Sun.COM 
20509781SMoriah.Waterland@Sun.COM 	if (opresvr4) {
20519781SMoriah.Waterland@Sun.COM 		/*
20529781SMoriah.Waterland@Sun.COM 		 * we are overwriting a pre-svr4 package, so remove the file
20539781SMoriah.Waterland@Sun.COM 		 * in /usr/options now
20549781SMoriah.Waterland@Sun.COM 		 */
20559781SMoriah.Waterland@Sun.COM 		(void) snprintf(path, sizeof (path),
20569781SMoriah.Waterland@Sun.COM 			"%s/%s.name", get_PKGOLD(), pkginst);
20579781SMoriah.Waterland@Sun.COM 		if (remove(path) && (errno != ENOENT)) {
20589781SMoriah.Waterland@Sun.COM 			progerr(ERR_OPRESVR4, path);
20599781SMoriah.Waterland@Sun.COM 			warnflag++;
20609781SMoriah.Waterland@Sun.COM 		}
20619781SMoriah.Waterland@Sun.COM 	}
20629781SMoriah.Waterland@Sun.COM 
20639781SMoriah.Waterland@Sun.COM 	/*
20649781SMoriah.Waterland@Sun.COM 	 * Execute preinstall script, if one was provided with the
20659781SMoriah.Waterland@Sun.COM 	 * package. We check the package to avoid running an old
20669781SMoriah.Waterland@Sun.COM 	 * preinstall script if one was provided with a prior instance.
20679781SMoriah.Waterland@Sun.COM 	 * Don't execute preinstall script if we are only updating the DB.
20689781SMoriah.Waterland@Sun.COM 	 */
20699781SMoriah.Waterland@Sun.COM 
20709781SMoriah.Waterland@Sun.COM 	/* update the lock - at the preinstall altscript */
20719781SMoriah.Waterland@Sun.COM 	lockupd("preinstall");
20729781SMoriah.Waterland@Sun.COM 
20739781SMoriah.Waterland@Sun.COM 	/* preinstall script in the media (package source) */
20749781SMoriah.Waterland@Sun.COM 	(void) snprintf(altscript, sizeof (altscript), "%s/install/preinstall",
20759781SMoriah.Waterland@Sun.COM 			instdir);
20769781SMoriah.Waterland@Sun.COM 
20779781SMoriah.Waterland@Sun.COM 	/* preinstall script in the pkgbin instead of media */
20789781SMoriah.Waterland@Sun.COM 	(void) snprintf(script, sizeof (script), "%s/preinstall", pkgbin);
20799781SMoriah.Waterland@Sun.COM 
20809781SMoriah.Waterland@Sun.COM 	if (access(altscript, F_OK) != 0) {
20819781SMoriah.Waterland@Sun.COM 		/* no script present */
20829781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_PKGINSTALL_POCALT_NONE, pkginst, altscript,
20839781SMoriah.Waterland@Sun.COM 			zoneName ? zoneName : "global");
20849781SMoriah.Waterland@Sun.COM 	} else if (access(script, F_OK) != 0) {
20859781SMoriah.Waterland@Sun.COM 		/* no script present */
20869781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_PKGINSTALL_POC_NONE, pkginst, script,
20879781SMoriah.Waterland@Sun.COM 			zoneName ? zoneName : "global");
20889781SMoriah.Waterland@Sun.COM 	} else if (is_depend_pkginfo_DB()) {
20899781SMoriah.Waterland@Sun.COM 		/* updating db only: skip preinstall script */
20909781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_PKGINSTALL_POC_DBUPD, pkginst, script,
20919781SMoriah.Waterland@Sun.COM 			zoneName ? zoneName : "global");
20929781SMoriah.Waterland@Sun.COM 	} else {
20939781SMoriah.Waterland@Sun.COM 		/* script present and ok to run: run the script */
20949781SMoriah.Waterland@Sun.COM 		assert(preinstallCheck == B_FALSE);
20959781SMoriah.Waterland@Sun.COM 
20969781SMoriah.Waterland@Sun.COM 		set_ulimit("preinstall", ERR_PREINSTALL);
20979781SMoriah.Waterland@Sun.COM 		if (zoneName == (char *)NULL) {
20989781SMoriah.Waterland@Sun.COM 			echo(MSG_PKGINSTALL_EXEPOC_GZ);
20999781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_PKGINSTALL_EXEPOC_GZ, pkginst, script);
21009781SMoriah.Waterland@Sun.COM 		} else {
21019781SMoriah.Waterland@Sun.COM 			echo(MSG_PKGINSTALL_EXEPOC_LZ, zoneName);
21029781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_PKGINSTALL_EXEPOC_LZ, pkginst, script,
21039781SMoriah.Waterland@Sun.COM 				zoneName);
21049781SMoriah.Waterland@Sun.COM 		}
21059781SMoriah.Waterland@Sun.COM 		putparam("PKG_PROC_script", "preinstall");
21069781SMoriah.Waterland@Sun.COM 		if (pkgverbose) {
21079781SMoriah.Waterland@Sun.COM 			ckreturn(pkgexecl(script_in, PROC_STDOUT,
21089781SMoriah.Waterland@Sun.COM 				PROC_USER, PROC_GRP, SHELL, "-x",
21099781SMoriah.Waterland@Sun.COM 				script, NULL), ERR_PREINSTALL);
21109781SMoriah.Waterland@Sun.COM 		} else {
21119781SMoriah.Waterland@Sun.COM 			ckreturn(pkgexecl(script_in, PROC_STDOUT,
21129781SMoriah.Waterland@Sun.COM 				PROC_USER, PROC_GRP, SHELL, script,
21139781SMoriah.Waterland@Sun.COM 				NULL), ERR_PREINSTALL);
21149781SMoriah.Waterland@Sun.COM 		}
21159781SMoriah.Waterland@Sun.COM 
21169781SMoriah.Waterland@Sun.COM 		clr_ulimit();
21179781SMoriah.Waterland@Sun.COM 		(void) remove(script);	/* no longer needed. */
21189781SMoriah.Waterland@Sun.COM 	}
21199781SMoriah.Waterland@Sun.COM 
21209781SMoriah.Waterland@Sun.COM 	/*
21219781SMoriah.Waterland@Sun.COM 	 * Check delivered package for a postinstall script while
21229781SMoriah.Waterland@Sun.COM 	 * we're still on volume 1.
21239781SMoriah.Waterland@Sun.COM 	 */
21249781SMoriah.Waterland@Sun.COM 
21259781SMoriah.Waterland@Sun.COM 	(void) snprintf(script, sizeof (script),
21269781SMoriah.Waterland@Sun.COM 			"%s/install/postinstall", instdir);
21279781SMoriah.Waterland@Sun.COM 	if (access(script, F_OK) == 0) {
21289781SMoriah.Waterland@Sun.COM 		(void) snprintf(script, sizeof (script),
21299781SMoriah.Waterland@Sun.COM 					"%s/postinstall", pkgbin);
21309781SMoriah.Waterland@Sun.COM 	} else {
21319781SMoriah.Waterland@Sun.COM 		script[0] = '\0';
21329781SMoriah.Waterland@Sun.COM 	}
21339781SMoriah.Waterland@Sun.COM 
21349781SMoriah.Waterland@Sun.COM 	/* update the lock - at the install phase */
21359781SMoriah.Waterland@Sun.COM 
21369781SMoriah.Waterland@Sun.COM 	lockupd("install");
21379781SMoriah.Waterland@Sun.COM 
21389781SMoriah.Waterland@Sun.COM 	/*
21399781SMoriah.Waterland@Sun.COM 	 * install package one part (volume) at a time
21409781SMoriah.Waterland@Sun.COM 	 */
21419781SMoriah.Waterland@Sun.COM 
21429781SMoriah.Waterland@Sun.COM 	part = 1;
21439781SMoriah.Waterland@Sun.COM 	while (part <= nparts) {
21449781SMoriah.Waterland@Sun.COM 		if ((part > 1) && pkgdev.cdevice) {
21459781SMoriah.Waterland@Sun.COM 			unpack();
21469781SMoriah.Waterland@Sun.COM 		}
21479781SMoriah.Waterland@Sun.COM 
21489781SMoriah.Waterland@Sun.COM 		instvol(extlist, srcinst, part, nparts,
2149*12734Sgary.pennington@oracle.com 			pkgserver, &cfTmpVfp, &updated, zoneName);
21509781SMoriah.Waterland@Sun.COM 
21519781SMoriah.Waterland@Sun.COM 		if (part++ >= nparts) {
21529781SMoriah.Waterland@Sun.COM 			break;
21539781SMoriah.Waterland@Sun.COM 		}
21549781SMoriah.Waterland@Sun.COM 	}
21559781SMoriah.Waterland@Sun.COM 
21569781SMoriah.Waterland@Sun.COM 	z_destroyMountTable();
21579781SMoriah.Waterland@Sun.COM 
21589781SMoriah.Waterland@Sun.COM 	/*
21599781SMoriah.Waterland@Sun.COM 	 * Now that all install class action scripts have been used, we
21609781SMoriah.Waterland@Sun.COM 	 * delete them from the package directory.
21619781SMoriah.Waterland@Sun.COM 	 */
21629781SMoriah.Waterland@Sun.COM 	rm_icas(pkgbin);
21639781SMoriah.Waterland@Sun.COM 
21649781SMoriah.Waterland@Sun.COM 	if ((globalZoneOnly) && (!patchPkgInstall) && (!patchPkgRemoval)) {
21659781SMoriah.Waterland@Sun.COM 		boolean_t   b;
21669781SMoriah.Waterland@Sun.COM 		b = pkgAddPackageToGzonlyList(pkginst, get_inst_root());
21679781SMoriah.Waterland@Sun.COM 		if (b == B_FALSE) {
21689781SMoriah.Waterland@Sun.COM 			progerr(ERR_PKGINSTALL_GZONLY_ADD, pkginst);
21699781SMoriah.Waterland@Sun.COM 			ckreturn(1, NULL);
21709781SMoriah.Waterland@Sun.COM 		}
21719781SMoriah.Waterland@Sun.COM 	}
21729781SMoriah.Waterland@Sun.COM 
21739781SMoriah.Waterland@Sun.COM 	/*
21749781SMoriah.Waterland@Sun.COM 	 * Execute postinstall script, if any
21759781SMoriah.Waterland@Sun.COM 	 * Don't execute postinstall script if we are only updating the DB.
21769781SMoriah.Waterland@Sun.COM 	 */
21779781SMoriah.Waterland@Sun.COM 
21789781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_PKGINSTALL_INSDONE, is_depend_pkginfo_DB(),
21799781SMoriah.Waterland@Sun.COM 		is_depend_pkginfo_DB(), saveSpoolInstall,
21809781SMoriah.Waterland@Sun.COM 		updated ? updated : "",
21819781SMoriah.Waterland@Sun.COM 		script ? script : "",
21829781SMoriah.Waterland@Sun.COM 		script ? access(script, F_OK) : -1);
21839781SMoriah.Waterland@Sun.COM 
21849781SMoriah.Waterland@Sun.COM 	/* update the lock - at the postinstall script */
21859781SMoriah.Waterland@Sun.COM 	lockupd("postinstall");
21869781SMoriah.Waterland@Sun.COM 
21879781SMoriah.Waterland@Sun.COM 	if ((script == (char *)NULL) || (*script == '\0')) {
21889781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_PKGINSTALL_POIS_NOPATH, pkginst,
21899781SMoriah.Waterland@Sun.COM 			zoneName ? zoneName : "global");
21909781SMoriah.Waterland@Sun.COM 	} else if (access(script, F_OK) != 0) {
21919781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_PKGINSTALL_POIS_NONE, pkginst, script,
21929781SMoriah.Waterland@Sun.COM 			zoneName ? zoneName : "global");
21939781SMoriah.Waterland@Sun.COM 	} else if (is_depend_pkginfo_DB()) {
21949781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_PKGINSTALL_POIS_DBUPD, pkginst, script,
21959781SMoriah.Waterland@Sun.COM 			zoneName ? zoneName : "global");
2196*12734Sgary.pennington@oracle.com 	} else if ((saveSpoolInstall != 0) && (updated == (char *)NULL)) {
21979781SMoriah.Waterland@Sun.COM 		/*
21989781SMoriah.Waterland@Sun.COM 		 * fresh installing into non-global zone, no object was
2199*12734Sgary.pennington@oracle.com 		 * updated (installed/verified in area), so do not run
2200*12734Sgary.pennington@oracle.com 		 * the postinstall script.
22019781SMoriah.Waterland@Sun.COM 		 */
2202*12734Sgary.pennington@oracle.com 		echoDebug(DBG_PKGINSTALL_POIS_NOUPDATING,
22039781SMoriah.Waterland@Sun.COM 			zoneName ? zoneName : "global", pkginst, script);
22049781SMoriah.Waterland@Sun.COM 	} else {
22059781SMoriah.Waterland@Sun.COM 		/* script present and ok to run: run the script */
22069781SMoriah.Waterland@Sun.COM 		set_ulimit("postinstall", ERR_POSTINSTALL);
22079781SMoriah.Waterland@Sun.COM 		if (zoneName == (char *)NULL) {
22089781SMoriah.Waterland@Sun.COM 			echo(MSG_PKGINSTALL_EXEPIC_GZ);
22099781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_PKGINSTALL_EXEPIC_GZ, pkginst, script);
22109781SMoriah.Waterland@Sun.COM 		} else {
22119781SMoriah.Waterland@Sun.COM 			echo(MSG_PKGINSTALL_EXEPIC_LZ, zoneName);
22129781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_PKGINSTALL_EXEPIC_LZ, pkginst, script,
22139781SMoriah.Waterland@Sun.COM 				zoneName);
22149781SMoriah.Waterland@Sun.COM 		}
22159781SMoriah.Waterland@Sun.COM 		putparam("PKG_PROC_SCRIPT", "postinstall");
22169781SMoriah.Waterland@Sun.COM 		putparam("TMPDIR", tmpdir);
22179781SMoriah.Waterland@Sun.COM 		if (pkgverbose) {
22189781SMoriah.Waterland@Sun.COM 			ckreturn(pkgexecl(script_in, PROC_STDOUT,
22199781SMoriah.Waterland@Sun.COM 				PROC_USER, PROC_GRP, SHELL, "-x",
22209781SMoriah.Waterland@Sun.COM 				script, NULL), ERR_POSTINSTALL);
22219781SMoriah.Waterland@Sun.COM 		} else {
22229781SMoriah.Waterland@Sun.COM 			ckreturn(pkgexecl(script_in, PROC_STDOUT,
22239781SMoriah.Waterland@Sun.COM 				PROC_USER, PROC_GRP, SHELL, script,
22249781SMoriah.Waterland@Sun.COM 				NULL), ERR_POSTINSTALL);
22259781SMoriah.Waterland@Sun.COM 		}
22269781SMoriah.Waterland@Sun.COM 
22279781SMoriah.Waterland@Sun.COM 		clr_ulimit();
22289781SMoriah.Waterland@Sun.COM 		(void) remove(script);	/* no longer needed */
22299781SMoriah.Waterland@Sun.COM 	}
22309781SMoriah.Waterland@Sun.COM 
22319781SMoriah.Waterland@Sun.COM 	if (!warnflag && !failflag) {
22329781SMoriah.Waterland@Sun.COM 		if (pt = getenv("PREDEPEND"))
22339781SMoriah.Waterland@Sun.COM 			predepend(pt);
22349781SMoriah.Waterland@Sun.COM 		(void) remove(rlockfile);
22359781SMoriah.Waterland@Sun.COM 		(void) remove(ilockfile);
22369781SMoriah.Waterland@Sun.COM 		(void) remove(savlog);
22379781SMoriah.Waterland@Sun.COM 	}
22389781SMoriah.Waterland@Sun.COM 
22399781SMoriah.Waterland@Sun.COM 	/* release the generic package lock */
22409781SMoriah.Waterland@Sun.COM 
22419781SMoriah.Waterland@Sun.COM 	(void) unlockinst();
22429781SMoriah.Waterland@Sun.COM 
22439869SCasper.Dik@Sun.COM 	pkgcloseserver(pkgserver);
22449869SCasper.Dik@Sun.COM 
22459781SMoriah.Waterland@Sun.COM 	quit(0);
22469781SMoriah.Waterland@Sun.COM 	/* LINTED: no return */
22479781SMoriah.Waterland@Sun.COM }
22489781SMoriah.Waterland@Sun.COM 
22499781SMoriah.Waterland@Sun.COM /*
22509781SMoriah.Waterland@Sun.COM  * This function merges the environment data in the response file with the
22519781SMoriah.Waterland@Sun.COM  * current environment.
22529781SMoriah.Waterland@Sun.COM  */
22539781SMoriah.Waterland@Sun.COM static int
merg_respfile()22549781SMoriah.Waterland@Sun.COM merg_respfile()
22559781SMoriah.Waterland@Sun.COM {
22569781SMoriah.Waterland@Sun.COM 	int retcode = 0;
22579781SMoriah.Waterland@Sun.COM 	char *resppath = get_respfile();
22589781SMoriah.Waterland@Sun.COM 	char *locbasedir;
22599781SMoriah.Waterland@Sun.COM 	char param[MAX_PKG_PARAM_LENGTH], *value;
22609781SMoriah.Waterland@Sun.COM 	FILE *fp;
22619781SMoriah.Waterland@Sun.COM 
22629781SMoriah.Waterland@Sun.COM 	if ((fp = fopen(resppath, "r")) == NULL) {
22639781SMoriah.Waterland@Sun.COM 		progerr(ERR_RESPONSE, resppath);
22649781SMoriah.Waterland@Sun.COM 		return (99);
22659781SMoriah.Waterland@Sun.COM 	}
22669781SMoriah.Waterland@Sun.COM 
22679781SMoriah.Waterland@Sun.COM 	param[0] = '\0';
22689781SMoriah.Waterland@Sun.COM 
22699781SMoriah.Waterland@Sun.COM 	while (value = fpkgparam(fp, param)) {
22709781SMoriah.Waterland@Sun.COM 		if (!isupper(param[0])) {
22719781SMoriah.Waterland@Sun.COM 			param[0] = '\0';
22729781SMoriah.Waterland@Sun.COM 			continue;
22739781SMoriah.Waterland@Sun.COM 		}
22749781SMoriah.Waterland@Sun.COM 
22759781SMoriah.Waterland@Sun.COM 		if (rdonly(param)) {
22769781SMoriah.Waterland@Sun.COM 			progerr(ERR_RDONLY, param);
22779781SMoriah.Waterland@Sun.COM 			param[0] = '\0';
22789781SMoriah.Waterland@Sun.COM 			continue;
22799781SMoriah.Waterland@Sun.COM 		}
22809781SMoriah.Waterland@Sun.COM 
22819781SMoriah.Waterland@Sun.COM 		/*
22829781SMoriah.Waterland@Sun.COM 		 * If this is an update, and the response file
22839781SMoriah.Waterland@Sun.COM 		 * specifies the BASEDIR, make sure it matches the
22849781SMoriah.Waterland@Sun.COM 		 * existing installation base. If it doesn't, we have
22859781SMoriah.Waterland@Sun.COM 		 * to quit.
22869781SMoriah.Waterland@Sun.COM 		 */
22879781SMoriah.Waterland@Sun.COM 		if (update && strcmp("BASEDIR", param) == 0) {
22889781SMoriah.Waterland@Sun.COM 			locbasedir = getenv("BASEDIR");
22899781SMoriah.Waterland@Sun.COM 			if (locbasedir && strcmp(value, locbasedir) != 0) {
22909781SMoriah.Waterland@Sun.COM 				char *dotptr;
22919781SMoriah.Waterland@Sun.COM 				/* Get srcinst down to a name. */
22929781SMoriah.Waterland@Sun.COM 				if (dotptr = strchr(srcinst, '.'))
22939781SMoriah.Waterland@Sun.COM 					*dotptr = '\000';
22949781SMoriah.Waterland@Sun.COM 				progerr(ERR_NEWBD, srcinst,
22959781SMoriah.Waterland@Sun.COM 					locbasedir, value);
22969781SMoriah.Waterland@Sun.COM 				retcode = 99;
22979781SMoriah.Waterland@Sun.COM 			}
22989781SMoriah.Waterland@Sun.COM 		}
22999781SMoriah.Waterland@Sun.COM 
23009781SMoriah.Waterland@Sun.COM 		putparam(param, value);
23019781SMoriah.Waterland@Sun.COM 		param[0] = '\0';
23029781SMoriah.Waterland@Sun.COM 	}
23039781SMoriah.Waterland@Sun.COM 	(void) fclose(fp);
23049781SMoriah.Waterland@Sun.COM 
23059781SMoriah.Waterland@Sun.COM 	return (retcode);
23069781SMoriah.Waterland@Sun.COM }
23079781SMoriah.Waterland@Sun.COM 
23089781SMoriah.Waterland@Sun.COM /*
23099781SMoriah.Waterland@Sun.COM  * This scans the installed pkginfo file for the current BASEDIR. If this
23109781SMoriah.Waterland@Sun.COM  * BASEDIR is different from the current BASEDIR, there will definitely be
23119781SMoriah.Waterland@Sun.COM  * problems.
23129781SMoriah.Waterland@Sun.COM  */
23139781SMoriah.Waterland@Sun.COM static int
ck_instbase(void)23149781SMoriah.Waterland@Sun.COM ck_instbase(void)
23159781SMoriah.Waterland@Sun.COM {
23169781SMoriah.Waterland@Sun.COM 	int retcode = 0;
23179781SMoriah.Waterland@Sun.COM 	char param[MAX_PKG_PARAM_LENGTH], *value;
23189781SMoriah.Waterland@Sun.COM 	char pkginfo_path[PATH_MAX];
23199781SMoriah.Waterland@Sun.COM 	FILE *fp;
23209781SMoriah.Waterland@Sun.COM 
23219781SMoriah.Waterland@Sun.COM 	/* Open the old pkginfo file. */
23229781SMoriah.Waterland@Sun.COM 	(void) snprintf(pkginfo_path, sizeof (pkginfo_path),
23239781SMoriah.Waterland@Sun.COM 			"%s/%s", pkgloc, PKGINFO);
23249781SMoriah.Waterland@Sun.COM 	if ((fp = fopen(pkginfo_path, "r")) == NULL) {
23259781SMoriah.Waterland@Sun.COM 		progerr(ERR_PKGINFO, pkginfo_path);
23269781SMoriah.Waterland@Sun.COM 		return (99);
23279781SMoriah.Waterland@Sun.COM 	}
23289781SMoriah.Waterland@Sun.COM 
23299781SMoriah.Waterland@Sun.COM 	param[0] = '\000';
23309781SMoriah.Waterland@Sun.COM 
23319781SMoriah.Waterland@Sun.COM 	while (value = fpkgparam(fp, param)) {
23329781SMoriah.Waterland@Sun.COM 		if (strcmp("BASEDIR", param) == 0) {
23339781SMoriah.Waterland@Sun.COM 			if (adm.basedir && *(adm.basedir) &&
23349781SMoriah.Waterland@Sun.COM 				strchr("/$", *(adm.basedir))) {
23359781SMoriah.Waterland@Sun.COM 				char *dotptr;
23369781SMoriah.Waterland@Sun.COM 
23379781SMoriah.Waterland@Sun.COM 				/*
23389781SMoriah.Waterland@Sun.COM 				 * Get srcinst down to a name.
23399781SMoriah.Waterland@Sun.COM 				 */
23409781SMoriah.Waterland@Sun.COM 				if (dotptr = strchr(srcinst, '.'))
23419781SMoriah.Waterland@Sun.COM 					*dotptr = '\000';
23429781SMoriah.Waterland@Sun.COM 				if (strcmp(value,
23439781SMoriah.Waterland@Sun.COM 					adm.basedir) != 0) {
23449781SMoriah.Waterland@Sun.COM 					progerr(ERR_ADMBD, srcinst,
23459781SMoriah.Waterland@Sun.COM 						value, adm.basedir);
23469781SMoriah.Waterland@Sun.COM 					retcode = 4;
23479781SMoriah.Waterland@Sun.COM 					break;
23489781SMoriah.Waterland@Sun.COM 				}
23499781SMoriah.Waterland@Sun.COM 			} else if (ADM(basedir, "ask"))
23509781SMoriah.Waterland@Sun.COM 				/*
23519781SMoriah.Waterland@Sun.COM 				 * If it's going to ask later, let it know
23529781SMoriah.Waterland@Sun.COM 				 * that it *must* agree with the BASEDIR we
23539781SMoriah.Waterland@Sun.COM 				 * just picked up.
23549781SMoriah.Waterland@Sun.COM 				 */
23559781SMoriah.Waterland@Sun.COM 				adm.basedir = "update";
23569781SMoriah.Waterland@Sun.COM 
23579781SMoriah.Waterland@Sun.COM 			putparam(param, value);
23589781SMoriah.Waterland@Sun.COM 			break;
23599781SMoriah.Waterland@Sun.COM 		}
23609781SMoriah.Waterland@Sun.COM 
23619781SMoriah.Waterland@Sun.COM 		param[0] = '\0';
23629781SMoriah.Waterland@Sun.COM 	}
23639781SMoriah.Waterland@Sun.COM 	(void) fclose(fp);
23649781SMoriah.Waterland@Sun.COM 
23659781SMoriah.Waterland@Sun.COM 	return (retcode);
23669781SMoriah.Waterland@Sun.COM }
23679781SMoriah.Waterland@Sun.COM 
23689781SMoriah.Waterland@Sun.COM /*
23699781SMoriah.Waterland@Sun.COM  * Since this is an overwrite of a different version of the package, none of
23709781SMoriah.Waterland@Sun.COM  * the old files should remain, so we rename them.
23719781SMoriah.Waterland@Sun.COM  */
23729781SMoriah.Waterland@Sun.COM static int
mv_pkgdirs(void)23739781SMoriah.Waterland@Sun.COM mv_pkgdirs(void)
23749781SMoriah.Waterland@Sun.COM {
23759781SMoriah.Waterland@Sun.COM 	/*
23769781SMoriah.Waterland@Sun.COM 	 * If we're not in dryrun mode and we can find an old set of package
23779781SMoriah.Waterland@Sun.COM 	 * files over which the new ones will be written, do the rename.
23789781SMoriah.Waterland@Sun.COM 	 */
23799781SMoriah.Waterland@Sun.COM 	if (!in_dryrun_mode() && pkgloc[0] && !access(pkgloc, F_OK)) {
23809781SMoriah.Waterland@Sun.COM 		(void) snprintf(pkgloc_sav, sizeof (pkgloc_sav),
23819781SMoriah.Waterland@Sun.COM 			"%s/.save.%s", get_PKGLOC(),
23829781SMoriah.Waterland@Sun.COM 			pkginst);
23839781SMoriah.Waterland@Sun.COM 		if (pkgloc_sav[0] && !access(pkgloc_sav, F_OK)) {
23849781SMoriah.Waterland@Sun.COM 			(void) rrmdir(pkgloc_sav);
23859781SMoriah.Waterland@Sun.COM 		}
23869781SMoriah.Waterland@Sun.COM 
23879781SMoriah.Waterland@Sun.COM 		if (rename(pkgloc, pkgloc_sav) == -1) {
23889781SMoriah.Waterland@Sun.COM 			progerr(ERR_PKGBINREN, pkgloc, pkgloc_sav);
23899781SMoriah.Waterland@Sun.COM 			return (99);
23909781SMoriah.Waterland@Sun.COM 		}
23919781SMoriah.Waterland@Sun.COM 	}
23929781SMoriah.Waterland@Sun.COM 
23939781SMoriah.Waterland@Sun.COM 	return (0);
23949781SMoriah.Waterland@Sun.COM }
23959781SMoriah.Waterland@Sun.COM 
23969781SMoriah.Waterland@Sun.COM /*
23979781SMoriah.Waterland@Sun.COM  * Name:	merg_pkginfos
23989781SMoriah.Waterland@Sun.COM  * Description:	This function scans the installed pkginfo and merges that
23999781SMoriah.Waterland@Sun.COM  *		environment with the installing environment according to
24009781SMoriah.Waterland@Sun.COM  *		the following rules:
24019781SMoriah.Waterland@Sun.COM  *
24029781SMoriah.Waterland@Sun.COM  *		1. CLASSES is a union of the installed and installing CLASSES
24039781SMoriah.Waterland@Sun.COM  *			lists.
24049781SMoriah.Waterland@Sun.COM  *		2. The installed BASEDIR takes precedence. If it doesn't agree
24059781SMoriah.Waterland@Sun.COM  *		   with an administratively imposed BASEDIR, an ERROR is issued.
24069781SMoriah.Waterland@Sun.COM  *		3. All other installing parameters are preserved.
24079781SMoriah.Waterland@Sun.COM  *		4. All installed parameters are added if they do not overwrite
24089781SMoriah.Waterland@Sun.COM  *		   an existing installing parameter.
24099781SMoriah.Waterland@Sun.COM  *
24109781SMoriah.Waterland@Sun.COM  *		The current environment contains the pkginfo settings for the
24119781SMoriah.Waterland@Sun.COM  *		new package to be installed or to be updated.
24129781SMoriah.Waterland@Sun.COM  *
24139781SMoriah.Waterland@Sun.COM  * Arguments:	pclass - returned list of current classes involved in install
24149781SMoriah.Waterland@Sun.COM  *		mpclass - pointer to returned list of current install classes
24159781SMoriah.Waterland@Sun.COM  * Returns:	int
24169781SMoriah.Waterland@Sun.COM  *		== 0 - all OK
24179781SMoriah.Waterland@Sun.COM  *		!= 0 - an error code if a fatal error occurred
24189781SMoriah.Waterland@Sun.COM  */
24199781SMoriah.Waterland@Sun.COM 
24209781SMoriah.Waterland@Sun.COM static int
merg_pkginfos(struct cl_attr ** pclass,struct cl_attr *** mpclass)24219781SMoriah.Waterland@Sun.COM merg_pkginfos(struct cl_attr **pclass, struct cl_attr ***mpclass)
24229781SMoriah.Waterland@Sun.COM {
24239781SMoriah.Waterland@Sun.COM 	FILE	*fp;
24249781SMoriah.Waterland@Sun.COM 	char	SUNW_PKG_ALLZONES[MAX_PKG_PARAM_LENGTH] = {'\0'};
24259781SMoriah.Waterland@Sun.COM 	char	SUNW_PKG_HOLLOW[MAX_PKG_PARAM_LENGTH] = {'\0'};
24269781SMoriah.Waterland@Sun.COM 	char	SUNW_PKG_THISZONE[MAX_PKG_PARAM_LENGTH] = {'\0'};
24279781SMoriah.Waterland@Sun.COM 	char	*newValue;
24289781SMoriah.Waterland@Sun.COM 	char	*oldValue;
24299781SMoriah.Waterland@Sun.COM 	char	*pkgName;
24309781SMoriah.Waterland@Sun.COM 	char	*pkgVersion;
24319781SMoriah.Waterland@Sun.COM 	char	param[MAX_PKG_PARAM_LENGTH];
24329781SMoriah.Waterland@Sun.COM 	char	pkginfo_path[PATH_MAX];
24339781SMoriah.Waterland@Sun.COM 	int	retcode = 0;
24349781SMoriah.Waterland@Sun.COM 
24359781SMoriah.Waterland@Sun.COM 	/* obtain the name of the package (for error messages) */
24369781SMoriah.Waterland@Sun.COM 
24379781SMoriah.Waterland@Sun.COM 	pkgName = getenv("PKG");
24389781SMoriah.Waterland@Sun.COM 	if (pkgName == NULL) {
24399781SMoriah.Waterland@Sun.COM 		pkgName = "*current*";	/* default name */
24409781SMoriah.Waterland@Sun.COM 	}
24419781SMoriah.Waterland@Sun.COM 
24429781SMoriah.Waterland@Sun.COM 	/* obtain the version of the package (for error messages) */
24439781SMoriah.Waterland@Sun.COM 
24449781SMoriah.Waterland@Sun.COM 	pkgVersion = getenv("VERSION");
24459781SMoriah.Waterland@Sun.COM 	if (pkgVersion == NULL) {
24469781SMoriah.Waterland@Sun.COM 		pkgVersion = "*current*";	/* default version */
24479781SMoriah.Waterland@Sun.COM 	}
24489781SMoriah.Waterland@Sun.COM 
24499781SMoriah.Waterland@Sun.COM 	/* open installed package pkginfo file */
24509781SMoriah.Waterland@Sun.COM 
24519781SMoriah.Waterland@Sun.COM 	(void) snprintf(pkginfo_path, sizeof (pkginfo_path),
24529781SMoriah.Waterland@Sun.COM 			"%s/%s", pkgloc, PKGINFO);
24539781SMoriah.Waterland@Sun.COM 	if ((fp = fopen(pkginfo_path, "r")) == NULL) {
24549781SMoriah.Waterland@Sun.COM 		progerr(ERR_PKGINFO, pkginfo_path);
24559781SMoriah.Waterland@Sun.COM 		return (99);
24569781SMoriah.Waterland@Sun.COM 	}
24579781SMoriah.Waterland@Sun.COM 
24589781SMoriah.Waterland@Sun.COM 	/* entry debugging info */
24599781SMoriah.Waterland@Sun.COM 
24609781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_MERGINFOS_ENTRY, pkginfo_path);
24619781SMoriah.Waterland@Sun.COM 
24629781SMoriah.Waterland@Sun.COM 	/*
24639781SMoriah.Waterland@Sun.COM 	 * cycle through the currently installed package's pkginfo parameters
24649781SMoriah.Waterland@Sun.COM 	 * and let the currently installed package's settings survive if the
24659781SMoriah.Waterland@Sun.COM 	 * update to the package does not provide an overriding value
24669781SMoriah.Waterland@Sun.COM 	 */
24679781SMoriah.Waterland@Sun.COM 
24689781SMoriah.Waterland@Sun.COM 	for (param[0] = '\0'; (oldValue = fpkgparam(fp, param)) != NULL;
24699781SMoriah.Waterland@Sun.COM 		param[0] = '\0') {
24709781SMoriah.Waterland@Sun.COM 
24719781SMoriah.Waterland@Sun.COM 		boolean_t	setZoneAttribute = B_FALSE;
24729781SMoriah.Waterland@Sun.COM 
24739781SMoriah.Waterland@Sun.COM 		/* debug info - attribute currently set to value */
24749781SMoriah.Waterland@Sun.COM 
24759781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_MERGINFOS_SET_TO, param, oldValue);
24769781SMoriah.Waterland@Sun.COM 
24779781SMoriah.Waterland@Sun.COM 		/*
24789781SMoriah.Waterland@Sun.COM 		 * if zone package attribute is present in the currently
24799781SMoriah.Waterland@Sun.COM 		 * installed package, then remember the value for the
24809781SMoriah.Waterland@Sun.COM 		 * specific zone package attribute, and set the flag that
24819781SMoriah.Waterland@Sun.COM 		 * indicates a zone package attribute is being processed.
24829781SMoriah.Waterland@Sun.COM 		 */
24839781SMoriah.Waterland@Sun.COM 
24849781SMoriah.Waterland@Sun.COM 		if (strcmp(param, PKG_THISZONE_VARIABLE) == 0) {
24859781SMoriah.Waterland@Sun.COM 			/* SUNW_PKG_THISZONE currently set */
24869781SMoriah.Waterland@Sun.COM 			setZoneAttribute = B_TRUE;
24879781SMoriah.Waterland@Sun.COM 			(void) strlcpy(SUNW_PKG_THISZONE, oldValue,
24889781SMoriah.Waterland@Sun.COM 					sizeof (SUNW_PKG_THISZONE));
24899781SMoriah.Waterland@Sun.COM 		} else if (strcmp(param, PKG_ALLZONES_VARIABLE) == 0) {
24909781SMoriah.Waterland@Sun.COM 			/* SUNW_PKG_ALLZONES currently set */
24919781SMoriah.Waterland@Sun.COM 			setZoneAttribute = B_TRUE;
24929781SMoriah.Waterland@Sun.COM 			(void) strlcpy(SUNW_PKG_ALLZONES, oldValue,
24939781SMoriah.Waterland@Sun.COM 					sizeof (SUNW_PKG_ALLZONES));
24949781SMoriah.Waterland@Sun.COM 		} else if (strcmp(param, PKG_HOLLOW_VARIABLE) == 0) {
24959781SMoriah.Waterland@Sun.COM 			/* SUNW_PKG_THISZONE currently set */
24969781SMoriah.Waterland@Sun.COM 			setZoneAttribute = B_TRUE;
24979781SMoriah.Waterland@Sun.COM 			(void) strlcpy(SUNW_PKG_HOLLOW, oldValue,
24989781SMoriah.Waterland@Sun.COM 					sizeof (SUNW_PKG_HOLLOW));
24999781SMoriah.Waterland@Sun.COM 		}
25009781SMoriah.Waterland@Sun.COM 
25019781SMoriah.Waterland@Sun.COM 		/* handle CLASSES currently being set */
25029781SMoriah.Waterland@Sun.COM 
25039781SMoriah.Waterland@Sun.COM 		if (strcmp(param, "CLASSES") == 0) {
25049781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_MERGINFOS_SET_CLASSES, oldValue);
25059781SMoriah.Waterland@Sun.COM 			/* create a list of the current classes */
25069781SMoriah.Waterland@Sun.COM 			(void) setlist(&pclass, qstrdup(oldValue));
25079781SMoriah.Waterland@Sun.COM 			/* set pointer to list of current classes */
25089781SMoriah.Waterland@Sun.COM 			*mpclass = pclass;
25099781SMoriah.Waterland@Sun.COM 			continue;
25109781SMoriah.Waterland@Sun.COM 		}
25119781SMoriah.Waterland@Sun.COM 
25129781SMoriah.Waterland@Sun.COM 		/* handle BASEDIR currently being set */
25139781SMoriah.Waterland@Sun.COM 
25149781SMoriah.Waterland@Sun.COM 		if (strcmp("BASEDIR", param) == 0) {
25159781SMoriah.Waterland@Sun.COM 			if (adm.basedir && *(adm.basedir) &&
25169781SMoriah.Waterland@Sun.COM 				strchr("/$", *(adm.basedir))) {
25179781SMoriah.Waterland@Sun.COM 				char *dotptr;
25189781SMoriah.Waterland@Sun.COM 
25199781SMoriah.Waterland@Sun.COM 				/* Get srcinst down to a* name */
25209781SMoriah.Waterland@Sun.COM 
25219781SMoriah.Waterland@Sun.COM 				if (dotptr = strchr(srcinst, '.')) {
25229781SMoriah.Waterland@Sun.COM 					*dotptr = '\000';
25239781SMoriah.Waterland@Sun.COM 				}
25249781SMoriah.Waterland@Sun.COM 				if (strcmp(oldValue, adm.basedir) != 0) {
25259781SMoriah.Waterland@Sun.COM 					progerr(ERR_ADMBD, srcinst,
25269781SMoriah.Waterland@Sun.COM 						oldValue, adm.basedir);
25279781SMoriah.Waterland@Sun.COM 					/* administration */
25289781SMoriah.Waterland@Sun.COM 					retcode = 4;
25299781SMoriah.Waterland@Sun.COM 					break;
25309781SMoriah.Waterland@Sun.COM 				}
25319781SMoriah.Waterland@Sun.COM 			} else if (ADM(basedir, "ask")) {
25329781SMoriah.Waterland@Sun.COM 				/*
25339781SMoriah.Waterland@Sun.COM 				 * If it's going to ask
25349781SMoriah.Waterland@Sun.COM 				 * later, let it know that it
25359781SMoriah.Waterland@Sun.COM 				 * *must* agree with the
25369781SMoriah.Waterland@Sun.COM 				 * BASEDIR we just picked up.
25379781SMoriah.Waterland@Sun.COM 				 */
25389781SMoriah.Waterland@Sun.COM 				adm.basedir = "update";
25399781SMoriah.Waterland@Sun.COM 				echoDebug(DBG_MERGINFOS_ASK_BASEDIR);
25409781SMoriah.Waterland@Sun.COM 			}
25419781SMoriah.Waterland@Sun.COM 
25429781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_MERGINFOS_SET_BASEDIR, oldValue);
25439781SMoriah.Waterland@Sun.COM 			putparam(param, oldValue);
25449781SMoriah.Waterland@Sun.COM 			continue;
25459781SMoriah.Waterland@Sun.COM 		}
25469781SMoriah.Waterland@Sun.COM 
25479781SMoriah.Waterland@Sun.COM 		/*
25489781SMoriah.Waterland@Sun.COM 		 * determine if there is a new value for this attribute.
25499781SMoriah.Waterland@Sun.COM 		 */
25509781SMoriah.Waterland@Sun.COM 
25519781SMoriah.Waterland@Sun.COM 		newValue = getenv(param);
25529781SMoriah.Waterland@Sun.COM 
25539781SMoriah.Waterland@Sun.COM 		/*
25549781SMoriah.Waterland@Sun.COM 		 * If zone attributes of patch packages haven't been verified
25559781SMoriah.Waterland@Sun.COM 		 * by pdo, if there is no new value, and a zone attribute
25569781SMoriah.Waterland@Sun.COM 		 * is being changed, it is the same as setting the zone package
25579781SMoriah.Waterland@Sun.COM 		 * attribute to 'false' - make sure current setting is 'false'.
25589781SMoriah.Waterland@Sun.COM 		 */
25599781SMoriah.Waterland@Sun.COM 
25609781SMoriah.Waterland@Sun.COM 		if ((patchPkgInstall == B_FALSE) && (newValue == NULL) &&
25619781SMoriah.Waterland@Sun.COM 		    (setZoneAttribute == B_TRUE) &&
25629781SMoriah.Waterland@Sun.COM 		    (strcasecmp(oldValue, "false") != 0)) {
25639781SMoriah.Waterland@Sun.COM 
25649781SMoriah.Waterland@Sun.COM 			/* unset existing non-"false" zone pkg attr */
25659781SMoriah.Waterland@Sun.COM 			progerr(ERR_MERGINFOS_UNSET_ZONEATTR,
25669781SMoriah.Waterland@Sun.COM 				pkgName, pkgVersion, param, oldValue);
25679781SMoriah.Waterland@Sun.COM 			retcode = 1;
25689781SMoriah.Waterland@Sun.COM 			break;
25699781SMoriah.Waterland@Sun.COM 		}
25709781SMoriah.Waterland@Sun.COM 
25719781SMoriah.Waterland@Sun.COM 		/* retain old value if no new value specified */
25729781SMoriah.Waterland@Sun.COM 
25739781SMoriah.Waterland@Sun.COM 		if (newValue == NULL) {
25749781SMoriah.Waterland@Sun.COM 			/* no new value - retain the old value */
25759781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_MERGINFOS_RETAIN_OLD, param, oldValue);
25769781SMoriah.Waterland@Sun.COM 			putparam(param, oldValue);
25779781SMoriah.Waterland@Sun.COM 			continue;
25789781SMoriah.Waterland@Sun.COM 		}
25799781SMoriah.Waterland@Sun.COM 
25809781SMoriah.Waterland@Sun.COM 		/* note if the old and new values are the same */
25819781SMoriah.Waterland@Sun.COM 
25829781SMoriah.Waterland@Sun.COM 		if (strcmp(newValue, oldValue) == 0) {
25839781SMoriah.Waterland@Sun.COM 			/* set existing package parameter to same value */
25849781SMoriah.Waterland@Sun.COM 			echoDebug(DBG_MERGINFOS_SET_DUPLICATE, param, oldValue);
25859781SMoriah.Waterland@Sun.COM 			continue;
25869781SMoriah.Waterland@Sun.COM 		}
25879781SMoriah.Waterland@Sun.COM 
25889781SMoriah.Waterland@Sun.COM 		/*
25899781SMoriah.Waterland@Sun.COM 		 * If zone attributes of patch packages haven't been verified
25909781SMoriah.Waterland@Sun.COM 		 * by pdo, check if old and new values differ.
25919781SMoriah.Waterland@Sun.COM 		 * Error if zone parameter
25929781SMoriah.Waterland@Sun.COM 		 */
25939781SMoriah.Waterland@Sun.COM 
25949781SMoriah.Waterland@Sun.COM 		if ((patchPkgInstall == B_FALSE) &&
25959781SMoriah.Waterland@Sun.COM 		    (setZoneAttribute == B_TRUE)) {
25969781SMoriah.Waterland@Sun.COM 			/* illegal change to zone attribute */
25979781SMoriah.Waterland@Sun.COM 
25989781SMoriah.Waterland@Sun.COM 			progerr(ERR_MERGINFOS_CHANGE_ZONEATTR, pkgName,
25999781SMoriah.Waterland@Sun.COM 				pkgVersion, param, oldValue, newValue);
26009781SMoriah.Waterland@Sun.COM 
26019781SMoriah.Waterland@Sun.COM 			/* set return code to "fatal error" */
26029781SMoriah.Waterland@Sun.COM 			retcode = 1;
26039781SMoriah.Waterland@Sun.COM 			break;
26049781SMoriah.Waterland@Sun.COM 		}
26059781SMoriah.Waterland@Sun.COM 
26069781SMoriah.Waterland@Sun.COM 		/* note valid change to existing package parameter */
26079781SMoriah.Waterland@Sun.COM 
26089781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_MERGINFOS_SET_CHANGE, param,
26099781SMoriah.Waterland@Sun.COM 				oldValue, newValue);
26109781SMoriah.Waterland@Sun.COM 	}
26119781SMoriah.Waterland@Sun.COM 
26129781SMoriah.Waterland@Sun.COM 	/* close handle on currently installed package's pkginfo file */
26139781SMoriah.Waterland@Sun.COM 
26149781SMoriah.Waterland@Sun.COM 	(void) fclose(fp);
26159781SMoriah.Waterland@Sun.COM 
26169781SMoriah.Waterland@Sun.COM 	/* return error if not successful up to this point */
26179781SMoriah.Waterland@Sun.COM 
26189781SMoriah.Waterland@Sun.COM 	if (retcode != 0) {
26199781SMoriah.Waterland@Sun.COM 		echoDebug(DBG_MERGINFOS_EXIT, pkginfo_path, retcode);
26209781SMoriah.Waterland@Sun.COM 
26219781SMoriah.Waterland@Sun.COM 		return (retcode);
26229781SMoriah.Waterland@Sun.COM 	}
26239781SMoriah.Waterland@Sun.COM 
26249781SMoriah.Waterland@Sun.COM 	/*
26259781SMoriah.Waterland@Sun.COM 	 * Skip this if() section, if zone attributes of patch packages
26269781SMoriah.Waterland@Sun.COM 	 * have been verified by pdo.
26279781SMoriah.Waterland@Sun.COM 	 */
26289781SMoriah.Waterland@Sun.COM 
26299781SMoriah.Waterland@Sun.COM 	if (patchPkgInstall == B_FALSE) {
26309781SMoriah.Waterland@Sun.COM 
26319781SMoriah.Waterland@Sun.COM 		/*
26329781SMoriah.Waterland@Sun.COM 		 * verify that no zone attribute has been
26339781SMoriah.Waterland@Sun.COM 		 * set to an invalid value
26349781SMoriah.Waterland@Sun.COM 		 */
26359781SMoriah.Waterland@Sun.COM 
26369781SMoriah.Waterland@Sun.COM 		/* SUNW_PKG_ALLZONES */
26379781SMoriah.Waterland@Sun.COM 
26389781SMoriah.Waterland@Sun.COM 		newValue = getenv(PKG_ALLZONES_VARIABLE);
26399781SMoriah.Waterland@Sun.COM 
26409781SMoriah.Waterland@Sun.COM 		/*
26419781SMoriah.Waterland@Sun.COM 		 * complain if setting SUNW_PKG_ALLZONES to other than "false"
26429781SMoriah.Waterland@Sun.COM 		 */
26439781SMoriah.Waterland@Sun.COM 
26449781SMoriah.Waterland@Sun.COM 
26459781SMoriah.Waterland@Sun.COM 		if ((newValue != NULL) && (*SUNW_PKG_ALLZONES == '\0') &&
26469781SMoriah.Waterland@Sun.COM 		    (strcasecmp(newValue, "false") != 0)) {
26479781SMoriah.Waterland@Sun.COM 			/* change ALLZONES from "true" to "false" (unset) */
26489781SMoriah.Waterland@Sun.COM 			progerr(ERR_MERGINFOS_SET_ZONEATTR, pkgName,
26499781SMoriah.Waterland@Sun.COM 			    pkgVersion, PKG_ALLZONES_VARIABLE, newValue);
26509781SMoriah.Waterland@Sun.COM 			return (1);
26519781SMoriah.Waterland@Sun.COM 		}
26529781SMoriah.Waterland@Sun.COM 
26539781SMoriah.Waterland@Sun.COM 		/* SUNW_PKG_THISZONE */
26549781SMoriah.Waterland@Sun.COM 
26559781SMoriah.Waterland@Sun.COM 		newValue = getenv(PKG_THISZONE_VARIABLE);
26569781SMoriah.Waterland@Sun.COM 
26579781SMoriah.Waterland@Sun.COM 		/*
26589781SMoriah.Waterland@Sun.COM 		 * complain if setting SUNW_PKG_THISZONE to other than "false"
26599781SMoriah.Waterland@Sun.COM 		 */
26609781SMoriah.Waterland@Sun.COM 
26619781SMoriah.Waterland@Sun.COM 		if ((newValue != NULL) && (*SUNW_PKG_THISZONE == '\0') &&
26629781SMoriah.Waterland@Sun.COM 		    (strcasecmp(newValue, "false") != 0)) {
26639781SMoriah.Waterland@Sun.COM 			/* change THISZONE from "true" to "false" (unset) */
26649781SMoriah.Waterland@Sun.COM 			progerr(ERR_MERGINFOS_SET_ZONEATTR, pkgName,
26659781SMoriah.Waterland@Sun.COM 			    pkgVersion, PKG_THISZONE_VARIABLE, newValue);
26669781SMoriah.Waterland@Sun.COM 			return (1);
26679781SMoriah.Waterland@Sun.COM 		}
26689781SMoriah.Waterland@Sun.COM 
26699781SMoriah.Waterland@Sun.COM 		/* SUNW_PKG_HOLLOW */
26709781SMoriah.Waterland@Sun.COM 
26719781SMoriah.Waterland@Sun.COM 		newValue = getenv(PKG_HOLLOW_VARIABLE);
26729781SMoriah.Waterland@Sun.COM 
26739781SMoriah.Waterland@Sun.COM 		/* complain if setting SUNW_PKG_HOLLOW to other than "false" */
26749781SMoriah.Waterland@Sun.COM 
26759781SMoriah.Waterland@Sun.COM 		if ((newValue != NULL) && (*SUNW_PKG_HOLLOW == '\0') &&
26769781SMoriah.Waterland@Sun.COM 		    (strcasecmp(newValue, "false") != 0)) {
26779781SMoriah.Waterland@Sun.COM 			/* change HOLLOW from "true" to 'false" (unset) */
26789781SMoriah.Waterland@Sun.COM 			progerr(ERR_MERGINFOS_SET_ZONEATTR, pkgName,
26799781SMoriah.Waterland@Sun.COM 			    pkgVersion, PKG_HOLLOW_VARIABLE, newValue);
26809781SMoriah.Waterland@Sun.COM 			return (1);
26819781SMoriah.Waterland@Sun.COM 		}
26829781SMoriah.Waterland@Sun.COM 
26839781SMoriah.Waterland@Sun.COM 	}
26849781SMoriah.Waterland@Sun.COM 
26859781SMoriah.Waterland@Sun.COM 	/* return */
26869781SMoriah.Waterland@Sun.COM 
26879781SMoriah.Waterland@Sun.COM 	echoDebug(DBG_MERGINFOS_EXIT, pkginfo_path, 0);
26889781SMoriah.Waterland@Sun.COM 
26899781SMoriah.Waterland@Sun.COM 	return (0);
26909781SMoriah.Waterland@Sun.COM }
26919781SMoriah.Waterland@Sun.COM 
26929781SMoriah.Waterland@Sun.COM static void
set_dryrun_dir_loc(void)26939781SMoriah.Waterland@Sun.COM set_dryrun_dir_loc(void)
26949781SMoriah.Waterland@Sun.COM {
26959781SMoriah.Waterland@Sun.COM 	/* Set pkg location to the dryrun directory */
26969781SMoriah.Waterland@Sun.COM 	set_PKGLOC(pkgdrtarg);
26979781SMoriah.Waterland@Sun.COM 	(void) snprintf(pkgloc, sizeof (pkgloc),
26989781SMoriah.Waterland@Sun.COM 			"%s/%s", get_PKGLOC(), pkginst);
26999781SMoriah.Waterland@Sun.COM 	(void) snprintf(pkgbin, sizeof (pkgbin),
27009781SMoriah.Waterland@Sun.COM 			"%s/install", pkgloc);
27019781SMoriah.Waterland@Sun.COM 	(void) snprintf(pkgsav, sizeof (pkgsav),
27029781SMoriah.Waterland@Sun.COM 			"%s/save", pkgloc);
27039781SMoriah.Waterland@Sun.COM 	(void) snprintf(ilockfile, sizeof (ilockfile),
27049781SMoriah.Waterland@Sun.COM 			"%s/!I-Lock!", pkgloc);
27059781SMoriah.Waterland@Sun.COM 	(void) snprintf(rlockfile, sizeof (rlockfile),
27069781SMoriah.Waterland@Sun.COM 			"%s/!R-Lock!", pkgloc);
27079781SMoriah.Waterland@Sun.COM 	(void) snprintf(savlog, sizeof (savlog),
27089781SMoriah.Waterland@Sun.COM 			"%s/logs/%s", get_PKGADM(), pkginst);
27099781SMoriah.Waterland@Sun.COM }
27109781SMoriah.Waterland@Sun.COM 
27119781SMoriah.Waterland@Sun.COM /*
27129781SMoriah.Waterland@Sun.COM  * If we are updating a pkg, then we need to copy the "old" pkgloc so that
27139781SMoriah.Waterland@Sun.COM  * any scripts that got removed in the new version aren't left around.  So we
27149781SMoriah.Waterland@Sun.COM  * copy it here to .save.pkgloc, then in quit() we can restore our state, or
27159781SMoriah.Waterland@Sun.COM  * remove it.
27169781SMoriah.Waterland@Sun.COM  */
27179781SMoriah.Waterland@Sun.COM static int
cp_pkgdirs(void)27189781SMoriah.Waterland@Sun.COM cp_pkgdirs(void)
27199781SMoriah.Waterland@Sun.COM {
27209781SMoriah.Waterland@Sun.COM 	if (in_dryrun_mode()) {
27219781SMoriah.Waterland@Sun.COM 		set_dryrun_dir_loc();
27229781SMoriah.Waterland@Sun.COM 	}
27239781SMoriah.Waterland@Sun.COM 
27249781SMoriah.Waterland@Sun.COM 	/*
27259781SMoriah.Waterland@Sun.COM 	 * If we're not in dryrun mode and we can find an old set of package
27269781SMoriah.Waterland@Sun.COM 	 * files over which the new ones will be written, do the copy.
27279781SMoriah.Waterland@Sun.COM 	 */
27289781SMoriah.Waterland@Sun.COM 	if (!in_dryrun_mode() && pkgloc[0] && !access(pkgloc, F_OK)) {
27299781SMoriah.Waterland@Sun.COM 		int status;
27309781SMoriah.Waterland@Sun.COM 		int r;
27319781SMoriah.Waterland@Sun.COM 
27329781SMoriah.Waterland@Sun.COM 		(void) snprintf(pkgloc_sav, sizeof (pkgloc_sav), "%s/.save.%s",
27339781SMoriah.Waterland@Sun.COM 			get_PKGLOC(), pkginst);
27349781SMoriah.Waterland@Sun.COM 
27359781SMoriah.Waterland@Sun.COM 		/*
27369781SMoriah.Waterland@Sun.COM 		 * Even though it takes a while, we use a recursive copy here
27379781SMoriah.Waterland@Sun.COM 		 * because if the current pkgadd fails for any reason, we
27389781SMoriah.Waterland@Sun.COM 		 * don't want to lose this data.
27399781SMoriah.Waterland@Sun.COM 		 */
27409781SMoriah.Waterland@Sun.COM 		r = e_ExecCmdList(&status, (char **)NULL, (char *)NULL,
27419781SMoriah.Waterland@Sun.COM 			"/usr/bin/cp", "cp", "-r", pkgloc, pkgloc_sav,
27429781SMoriah.Waterland@Sun.COM 			(char *)NULL);
27439781SMoriah.Waterland@Sun.COM 
27449781SMoriah.Waterland@Sun.COM 		if ((r != 0) || (status == -1) || (WEXITSTATUS(status) != 0)) {
27459781SMoriah.Waterland@Sun.COM 			progerr(ERR_PKGBINCP, pkgloc, pkgloc_sav);
27469781SMoriah.Waterland@Sun.COM 			return (99);
27479781SMoriah.Waterland@Sun.COM 		}
27489781SMoriah.Waterland@Sun.COM 	}
27499781SMoriah.Waterland@Sun.COM 
27509781SMoriah.Waterland@Sun.COM 	return (0);
27519781SMoriah.Waterland@Sun.COM }
27529781SMoriah.Waterland@Sun.COM 
27539781SMoriah.Waterland@Sun.COM /*
27549781SMoriah.Waterland@Sun.COM  * This implements the pkgask function. It just executes the request script
27559781SMoriah.Waterland@Sun.COM  * and stores the results in a response file.
27569781SMoriah.Waterland@Sun.COM  */
27579781SMoriah.Waterland@Sun.COM static void
do_pkgask(boolean_t a_run_request_as_root)27589781SMoriah.Waterland@Sun.COM do_pkgask(boolean_t a_run_request_as_root)
27599781SMoriah.Waterland@Sun.COM {
27609781SMoriah.Waterland@Sun.COM 	if (pkgdev.cdevice) {
27619781SMoriah.Waterland@Sun.COM 		unpack();
27629781SMoriah.Waterland@Sun.COM 		if (!suppressCopyright) {
27639781SMoriah.Waterland@Sun.COM 			copyright();
27649781SMoriah.Waterland@Sun.COM 		}
27659781SMoriah.Waterland@Sun.COM 	}
27669781SMoriah.Waterland@Sun.COM 	(void) snprintf(path, sizeof (path), "%s/%s", instdir, REQUEST_FILE);
27679781SMoriah.Waterland@Sun.COM 	if (access(path, F_OK)) {
27689781SMoriah.Waterland@Sun.COM 		progerr(ERR_NOREQUEST);
27699781SMoriah.Waterland@Sun.COM 		quit(1);
27709781SMoriah.Waterland@Sun.COM 		/*NOTREACHED*/
27719781SMoriah.Waterland@Sun.COM 	}
27729781SMoriah.Waterland@Sun.COM 
27739781SMoriah.Waterland@Sun.COM 	(void) set_respfile(respfile, srcinst, RESP_WR);
27749781SMoriah.Waterland@Sun.COM 
27759781SMoriah.Waterland@Sun.COM 	if (is_a_respfile()) {
27769781SMoriah.Waterland@Sun.COM 		ckreturn(reqexec(update, path, non_abi_scripts,
27779781SMoriah.Waterland@Sun.COM 			a_run_request_as_root), ERR_REQUEST);
27789781SMoriah.Waterland@Sun.COM 	} else {
27799781SMoriah.Waterland@Sun.COM 		failflag++;
27809781SMoriah.Waterland@Sun.COM 	}
27819781SMoriah.Waterland@Sun.COM 
27829781SMoriah.Waterland@Sun.COM 	if (warnflag || failflag) {
27839781SMoriah.Waterland@Sun.COM 		(void) remove(respfile);
27849781SMoriah.Waterland@Sun.COM 		echo("\nResponse file <%s> was not created.",
27859781SMoriah.Waterland@Sun.COM 			get_respfile());
27869781SMoriah.Waterland@Sun.COM 	} else {
27879781SMoriah.Waterland@Sun.COM 		echo("\nResponse file <%s> was created.",
27889781SMoriah.Waterland@Sun.COM 			get_respfile());
27899781SMoriah.Waterland@Sun.COM 	}
27909781SMoriah.Waterland@Sun.COM 
27919781SMoriah.Waterland@Sun.COM 	quit(0);
27929781SMoriah.Waterland@Sun.COM 	/*NOTREACHED*/
27939781SMoriah.Waterland@Sun.COM }
27949781SMoriah.Waterland@Sun.COM 
27959781SMoriah.Waterland@Sun.COM /*
27969781SMoriah.Waterland@Sun.COM  * This function runs a check utility and acts appropriately based upon the
27979781SMoriah.Waterland@Sun.COM  * return code. It deals appropriately with the dryrun file if it is present.
27989781SMoriah.Waterland@Sun.COM  */
27999781SMoriah.Waterland@Sun.COM static void
ck_w_dryrun(int (* func)(),int type)28009781SMoriah.Waterland@Sun.COM ck_w_dryrun(int (*func)(), int type)
28019781SMoriah.Waterland@Sun.COM {
28029781SMoriah.Waterland@Sun.COM 	int n;
28039781SMoriah.Waterland@Sun.COM 
28049781SMoriah.Waterland@Sun.COM 	n = func();
28059781SMoriah.Waterland@Sun.COM 	if (in_dryrun_mode())
28069781SMoriah.Waterland@Sun.COM 		set_dr_info(type, !n);
28079781SMoriah.Waterland@Sun.COM 
28089781SMoriah.Waterland@Sun.COM 	if (n) {
28099781SMoriah.Waterland@Sun.COM 		quit(n);
28109781SMoriah.Waterland@Sun.COM 		/*NOTREACHED*/
28119781SMoriah.Waterland@Sun.COM 	}
28129781SMoriah.Waterland@Sun.COM }
28139781SMoriah.Waterland@Sun.COM 
28149781SMoriah.Waterland@Sun.COM /*
28159781SMoriah.Waterland@Sun.COM  * This function deletes all install class action scripts from the package
28169781SMoriah.Waterland@Sun.COM  * directory on the root filesystem.
28179781SMoriah.Waterland@Sun.COM  */
28189781SMoriah.Waterland@Sun.COM static void
rm_icas(char * cas_dir)28199781SMoriah.Waterland@Sun.COM rm_icas(char *cas_dir)
28209781SMoriah.Waterland@Sun.COM {
28219781SMoriah.Waterland@Sun.COM 	DIR	*pdirfp;
28229781SMoriah.Waterland@Sun.COM 	struct	dirent *dp;
28239781SMoriah.Waterland@Sun.COM 	char path[PATH_MAX];
28249781SMoriah.Waterland@Sun.COM 
28259781SMoriah.Waterland@Sun.COM 	if ((pdirfp = opendir(cas_dir)) == NULL)
28269781SMoriah.Waterland@Sun.COM 		return;
28279781SMoriah.Waterland@Sun.COM 
28289781SMoriah.Waterland@Sun.COM 	while ((dp = readdir(pdirfp)) != NULL) {
28299781SMoriah.Waterland@Sun.COM 		if (dp->d_name[0] == '.')
28309781SMoriah.Waterland@Sun.COM 			continue;
28319781SMoriah.Waterland@Sun.COM 
28329781SMoriah.Waterland@Sun.COM 		if (dp->d_name[0] == 'i' && dp->d_name[1] == '.') {
28339781SMoriah.Waterland@Sun.COM 			(void) snprintf(path, sizeof (path),
28349781SMoriah.Waterland@Sun.COM 				"%s/%s", cas_dir, dp->d_name);
28359781SMoriah.Waterland@Sun.COM 			(void) remove(path);
28369781SMoriah.Waterland@Sun.COM 		}
28379781SMoriah.Waterland@Sun.COM 	}
28389781SMoriah.Waterland@Sun.COM 	(void) closedir(pdirfp);
28399781SMoriah.Waterland@Sun.COM }
28409781SMoriah.Waterland@Sun.COM 
28419781SMoriah.Waterland@Sun.COM void
ckreturn(int retcode,char * msg)28429781SMoriah.Waterland@Sun.COM ckreturn(int retcode, char *msg)
28439781SMoriah.Waterland@Sun.COM {
28449781SMoriah.Waterland@Sun.COM 	switch (retcode) {
28459781SMoriah.Waterland@Sun.COM 		case 2:
28469781SMoriah.Waterland@Sun.COM 		case 12:
28479781SMoriah.Waterland@Sun.COM 		case 22:
28489781SMoriah.Waterland@Sun.COM 		warnflag++;
28499781SMoriah.Waterland@Sun.COM 		if (msg) {
28509781SMoriah.Waterland@Sun.COM 			progerr("%s", msg);
28519781SMoriah.Waterland@Sun.COM 		}
28529781SMoriah.Waterland@Sun.COM 		/*FALLTHRU*/
28539781SMoriah.Waterland@Sun.COM 		case 10:
28549781SMoriah.Waterland@Sun.COM 		case 20:
28559781SMoriah.Waterland@Sun.COM 		if (retcode >= 10 && retcode < 20) {
28569781SMoriah.Waterland@Sun.COM 			dreboot++;
28579781SMoriah.Waterland@Sun.COM 		}
28589781SMoriah.Waterland@Sun.COM 		if (retcode >= 20) {
28599781SMoriah.Waterland@Sun.COM 			ireboot++;
28609781SMoriah.Waterland@Sun.COM 		}
28619781SMoriah.Waterland@Sun.COM 		/*FALLTHRU*/
28629781SMoriah.Waterland@Sun.COM 		case 0:
28639781SMoriah.Waterland@Sun.COM 		break; /* okay */
28649781SMoriah.Waterland@Sun.COM 
28659781SMoriah.Waterland@Sun.COM 		case -1:
28669781SMoriah.Waterland@Sun.COM 		retcode = 99;
28679781SMoriah.Waterland@Sun.COM 		/*FALLTHRU*/
28689781SMoriah.Waterland@Sun.COM 		case 99:
28699781SMoriah.Waterland@Sun.COM 		case 1:
28709781SMoriah.Waterland@Sun.COM 		case 11:
28719781SMoriah.Waterland@Sun.COM 		case 21:
28729781SMoriah.Waterland@Sun.COM 		case 4:
28739781SMoriah.Waterland@Sun.COM 		case 14:
28749781SMoriah.Waterland@Sun.COM 		case 24:
28759781SMoriah.Waterland@Sun.COM 		case 5:
28769781SMoriah.Waterland@Sun.COM 		case 15:
28779781SMoriah.Waterland@Sun.COM 		case 25:
28789781SMoriah.Waterland@Sun.COM 		if (msg) {
28799781SMoriah.Waterland@Sun.COM 			progerr("%s", msg);
28809781SMoriah.Waterland@Sun.COM 		}
28819781SMoriah.Waterland@Sun.COM 		/*FALLTHRU*/
28829781SMoriah.Waterland@Sun.COM 		case 3:
28839781SMoriah.Waterland@Sun.COM 		case 13:
28849781SMoriah.Waterland@Sun.COM 		case 23:
28859781SMoriah.Waterland@Sun.COM 		quit(retcode);
28869781SMoriah.Waterland@Sun.COM 		/*NOTREACHED*/
28879781SMoriah.Waterland@Sun.COM 		default:
28889781SMoriah.Waterland@Sun.COM 		if (msg) {
28899781SMoriah.Waterland@Sun.COM 			progerr("%s", msg);
28909781SMoriah.Waterland@Sun.COM 		}
28919781SMoriah.Waterland@Sun.COM 		quit(1);
28929781SMoriah.Waterland@Sun.COM 		/*NOTREACHED*/
28939781SMoriah.Waterland@Sun.COM 	}
28949781SMoriah.Waterland@Sun.COM }
28959781SMoriah.Waterland@Sun.COM 
28969781SMoriah.Waterland@Sun.COM static void
copyright(void)28979781SMoriah.Waterland@Sun.COM copyright(void)
28989781SMoriah.Waterland@Sun.COM {
28999781SMoriah.Waterland@Sun.COM 	FILE	*fp;
29009781SMoriah.Waterland@Sun.COM 	char	line[LSIZE];
29019781SMoriah.Waterland@Sun.COM 	char	path[PATH_MAX];
29029781SMoriah.Waterland@Sun.COM 
29039781SMoriah.Waterland@Sun.COM 	/* Compose full path for copyright file */
29049781SMoriah.Waterland@Sun.COM 	(void) snprintf(path, sizeof (path), "%s/%s", instdir, COPYRIGHT_FILE);
29059781SMoriah.Waterland@Sun.COM 
29069781SMoriah.Waterland@Sun.COM 	if ((fp = fopen(path, "r")) == NULL) {
29079781SMoriah.Waterland@Sun.COM 		if (getenv("VENDOR") != NULL)
29089781SMoriah.Waterland@Sun.COM 			echo(getenv("VENDOR"));
29099781SMoriah.Waterland@Sun.COM 	} else {
29109781SMoriah.Waterland@Sun.COM 		while (fgets(line, LSIZE, fp))
29119781SMoriah.Waterland@Sun.COM 			(void) fprintf(stdout, "%s", line); /* bug #1083713 */
29129781SMoriah.Waterland@Sun.COM 		(void) fclose(fp);
29139781SMoriah.Waterland@Sun.COM 	}
29149781SMoriah.Waterland@Sun.COM }
29159781SMoriah.Waterland@Sun.COM 
29169781SMoriah.Waterland@Sun.COM static int
rdonly(char * p)29179781SMoriah.Waterland@Sun.COM rdonly(char *p)
29189781SMoriah.Waterland@Sun.COM {
29199781SMoriah.Waterland@Sun.COM 	int	i;
29209781SMoriah.Waterland@Sun.COM 
29219781SMoriah.Waterland@Sun.COM 	for (i = 0; ro_params[i]; i++) {
29229781SMoriah.Waterland@Sun.COM 		if (strcmp(p, ro_params[i]) == 0)
29239781SMoriah.Waterland@Sun.COM 			return (1);
29249781SMoriah.Waterland@Sun.COM 	}
29259781SMoriah.Waterland@Sun.COM 	return (0);
29269781SMoriah.Waterland@Sun.COM }
29279781SMoriah.Waterland@Sun.COM 
29289781SMoriah.Waterland@Sun.COM static void
unpack(void)29299781SMoriah.Waterland@Sun.COM unpack(void)
29309781SMoriah.Waterland@Sun.COM {
29319781SMoriah.Waterland@Sun.COM 	/*
29329781SMoriah.Waterland@Sun.COM 	 * read in next part from stream, even if we decide
29339781SMoriah.Waterland@Sun.COM 	 * later that we don't need it
29349781SMoriah.Waterland@Sun.COM 	 */
29359781SMoriah.Waterland@Sun.COM 	if (dparts < 1) {
29369781SMoriah.Waterland@Sun.COM 		progerr(ERR_DSTREAMCNT);
29379781SMoriah.Waterland@Sun.COM 		quit(99);
29389781SMoriah.Waterland@Sun.COM 		/*NOTREACHED*/
29399781SMoriah.Waterland@Sun.COM 	}
29409781SMoriah.Waterland@Sun.COM 	if ((access(instdir, F_OK) == 0) && rrmdir(instdir)) {
29419781SMoriah.Waterland@Sun.COM 		progerr(ERR_RMDIR, instdir);
29429781SMoriah.Waterland@Sun.COM 		quit(99);
29439781SMoriah.Waterland@Sun.COM 		/*NOTREACHED*/
29449781SMoriah.Waterland@Sun.COM 	}
29459781SMoriah.Waterland@Sun.COM 	if (mkdir(instdir, 0755)) {
29469781SMoriah.Waterland@Sun.COM 		progerr(ERR_MKDIR, instdir);
29479781SMoriah.Waterland@Sun.COM 		quit(99);
29489781SMoriah.Waterland@Sun.COM 		/*NOTREACHED*/
29499781SMoriah.Waterland@Sun.COM 	}
29509781SMoriah.Waterland@Sun.COM 	if (chdir(instdir)) {
29519781SMoriah.Waterland@Sun.COM 		progerr(ERR_CHDIR, instdir);
29529781SMoriah.Waterland@Sun.COM 		quit(99);
29539781SMoriah.Waterland@Sun.COM 		/*NOTREACHED*/
29549781SMoriah.Waterland@Sun.COM 	}
29559781SMoriah.Waterland@Sun.COM 	if (!ds_fd_open()) {
29569781SMoriah.Waterland@Sun.COM 		dparts = ds_findpkg(pkgdev.cdevice, srcinst);
29579781SMoriah.Waterland@Sun.COM 		if (dparts < 1) {
29589781SMoriah.Waterland@Sun.COM 			progerr(ERR_DSARCH, srcinst);
29599781SMoriah.Waterland@Sun.COM 			quit(99);
29609781SMoriah.Waterland@Sun.COM 			/*NOTREACHED*/
29619781SMoriah.Waterland@Sun.COM 		}
29629781SMoriah.Waterland@Sun.COM 	}
29639781SMoriah.Waterland@Sun.COM 
29649781SMoriah.Waterland@Sun.COM 	dparts--;
29659781SMoriah.Waterland@Sun.COM 
29669781SMoriah.Waterland@Sun.COM 	if (ds_next(pkgdev.cdevice, instdir)) {
29679781SMoriah.Waterland@Sun.COM 		progerr(ERR_DSTREAM);
29689781SMoriah.Waterland@Sun.COM 		quit(99);
29699781SMoriah.Waterland@Sun.COM 		/*NOTREACHED*/
29709781SMoriah.Waterland@Sun.COM 	}
29719781SMoriah.Waterland@Sun.COM 	if (chdir(get_PKGADM())) {
29729781SMoriah.Waterland@Sun.COM 		progerr(ERR_CHDIR, get_PKGADM());
29739781SMoriah.Waterland@Sun.COM 		quit(99);
29749781SMoriah.Waterland@Sun.COM 		/*NOTREACHED*/
29759781SMoriah.Waterland@Sun.COM 	}
29769781SMoriah.Waterland@Sun.COM 	ds_close(1);
29779781SMoriah.Waterland@Sun.COM }
29789781SMoriah.Waterland@Sun.COM 
29799781SMoriah.Waterland@Sun.COM static void
usage(void)29809781SMoriah.Waterland@Sun.COM usage(void)
29819781SMoriah.Waterland@Sun.COM {
29829781SMoriah.Waterland@Sun.COM 	(void) fprintf(stderr, ERR_USAGE_PKGINSTALL);
29839781SMoriah.Waterland@Sun.COM 	exit(1);
29849781SMoriah.Waterland@Sun.COM 	/*NOTREACHED*/
29859781SMoriah.Waterland@Sun.COM }
2986