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