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