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