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