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