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