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) 2018 Peter Tribble.
24 */
25
26/*
27 * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
28 */
29
30/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
31/* All Rights Reserved */
32
33
34/*
35 * Program:	pkgadd / pkgask
36 *
37 * Function:	public command and private utility functions that
38 *		implement the package add and package ask operations.
39 *
40 */
41
42/*
43 * System includes
44 */
45
46#include <stdio.h>
47#include <limits.h>
48#include <stdlib.h>
49#include <unistd.h>
50#include <string.h>
51#include <fcntl.h>
52#include <sys/types.h>
53#include <sys/stat.h>
54#include <signal.h>
55#include <errno.h>
56#include <pkgdev.h>
57#include <pkginfo.h>
58#include <pkglocs.h>
59#include <locale.h>
60#include <libintl.h>
61#include <pkgtrans.h>
62#include <assert.h>
63
64/*
65 * consolidation pkg command library includes
66 */
67#include <pkglib.h>
68
69#include <instzones_api.h>
70
71/*
72 * local pkg command library includes
73 */
74#include <install.h>
75#include <libinst.h>
76#include <libadm.h>
77#include <messages.h>
78
79
80/*
81 * pkgadd local includes
82 */
83
84#include "quit.h"
85
86/*
87 * imported global variables/functions
88 */
89
90/* check.c */
91extern int	preinstall_verify(char **a_pkgList, zoneList_t a_zlst,
92			char *a_zoneTempDir);
93
94/*
95 * ckquit is a global that controls 'ckyorn' (defined in libadm)
96 * If ckquit is non-zero, then "quit" is allowed as an answer when
97 * ckyorn is called. If is it zero, then "quit" is not an allowed answer.
98 */
99extern int	ckquit;
100
101/*
102 * exported global variables
103 */
104
105/* these globals are set by ckreturn and used by quit.c */
106
107int	admnflag = 0;	/* != 0 if any pkg op admin setting failure (4) */
108int	doreboot = 0;	/* != 0 if reboot required after installation */
109int	failflag = 0;	/* != 0 if fatal error has occurred (1) */
110int	intrflag = 0;	/* != 0 if user selected quit (3) */
111int	ireboot = 0;	/* != 0 if immediate reboot required */
112int	nullflag = 0;	/* != 0 if admin interaction required (5) */
113int	warnflag = 0;	/* != 0 if non-fatal error has occurred (2) */
114
115/* imported by quit.c */
116int	npkgs = 0;	/* the number of packages yet to be installed */
117
118/* imported by various (many) */
119char	*respfile = NULL;	/* response pathname (or NULL) */
120char	*tmpdir = NULL;		/* location to place temporary files */
121
122struct admin	adm;		/* holds info about installation admin */
123struct pkgdev	pkgdev;		/* holds info about the installation device */
124
125/*
126 * internal global variables
127 */
128
129static char	*admnfile = NULL;	/* file to use for installation admin */
130static char	*ids_name = NULL;	/* name of data stream device */
131static char	*pkgcontsrc = NULL;	/* continuation file (-c option) */
132static char	*pkgdrtarg = NULL;	/* dry run file (-D option) */
133static char	*pkginst = NULL;	/* current pkg/src instance 2 process */
134static char	*respdir = NULL;	/* respfile is a directory spec */
135static char	*rw_block_size = NULL;
136static char	*vfstab_file = NULL;
137static int	askflag = 0;		/* non-zero if invoked as "pkgask" */
138static int	disableAttributes = 0;	/* Disabling attribute checking */
139static int	disableChecksum = 0;	/* Disable checksumming */
140static int	disableSaveSpool = 0;	/* Disable partial spool dir create */
141static int	init_install = 0;	/* inform scripts initial install */
142static int	no_map_client = 0;	/* do not map from vfstab file */
143static int	nointeract = 0;		/* non-zero - no user interaction */
144static int	pkgverbose = 0;		/* non-zero if verbose mode selected */
145static int	saveSpoolInstall = 0;	/* installing from save spool dir */
146static int	suppressCopyright = 0;	/* suppress copyright notices */
147
148/* set by ckreturn() */
149
150static int	interrupted = 0;	/* last pkg op was quit (1,2,3,4,5) */
151static int	needconsult = 0;	/* essential ask admin now (1,2,3,5) */
152
153/* Set by -O nozones: do not process any zones */
154
155static boolean_t	noZones = B_FALSE;
156
157/* Set by -O zonelist=<names...>: process only named zones */
158
159static boolean_t	usedZoneList = B_FALSE;
160
161/* Set by -O debug: debug output is enabled? */
162
163static boolean_t	debugFlag = B_FALSE;
164
165/* Set by the -G option: install packages in global zone only */
166
167static boolean_t	globalZoneOnly = B_FALSE;
168
169/*
170 * Assume the package is ABI and POSIX compliant as regards user
171 * interactiion during procedure scripts.
172 */
173
174static int	old_pkg = 0;
175
176/* Assume pkg should be installed according to the ABI */
177
178static int	old_symlinks = 0;
179
180/*
181 * Default name length will be 32 chars - if this is set,
182 * disable the 32 char name limit extension
183 */
184
185static int	ABI_namelength = 0;
186
187#if	!defined(TEXT_DOMAIN)	/* Should be defined by cc -D */
188#define	TEXT_DOMAIN	"SYS_TEST"
189#endif
190
191/* printable string - if string is null results in ??? */
192
193#define	PSTR(STR) (((STR) == (char *)NULL) ? "???" : (STR))
194
195#define	MAX_FDS	20
196
197/*
198 * forward declarations
199 */
200
201static int		boot_and_pkginstall_check_in_zones(zoneList_t a_zlst,
202				char *a_idsName, char *a_altBinDir,
203				char *a_zoneAdminFile, char *a_zoneTempDir);
204static int		boot_and_install_in_zones(zoneList_t a_zlst,
205				char *a_idsName, char *a_altBinDir,
206				char *a_zoneAdminFile, char *a_zoneTempDir);
207static void		pkginstall_check_in_one_zone(char *a_zoneName,
208				char *a_idsName, char *a_zoneAdminFile,
209				char *a_zoneTempDir, char *a_altBinDir,
210				char *a_scratchName, zone_state_t a_zoneState,
211				boolean_t a_tmpzn);
212static void		ckreturn(int retcode);
213static void		create_zone_adminfile(char **r_zoneAdminFile,
214				char *a_zoneTempDir, char *a_admnfile);
215static void		create_zone_tempdir(char **r_zoneTempDir,
216				char *a_tmpdir);
217static void		install_in_one_zone(char *a_zoneName, char *a_idsName,
218				char *a_zoneAdminFile, char *a_zoneTempDir,
219				char *a_altBinDir, zone_state_t a_zoneState,
220				boolean_t a_tmpzn);
221static int		pkginstall_check_in_zones(zoneList_t a_zlst,
222				char *a_idsName, char *a_altBinDir,
223				char *a_zoneAdminFile, char *a_zoneTempDir);
224static int		install_in_zones(zoneList_t a_zlst, char *a_idsName,
225				char *a_altBinDir, char *a_zoneAdminFile,
226				char *a_zoneTempDir);
227static int		pkgInstall(char *ir, char *a_idsName, char *a_pkgDir,
228				char *a_altBinDir);
229static int		pkgZoneCheckInstall(char *a_zoneName,
230				zone_state_t a_zoneState,
231				char *a_idsName, char *a_altBinDir,
232				char *a_adminFile, char *a_stdoutPath,
233				boolean_t a_tmpzn);
234static int		pkgZoneInstall(char *a_zoneName,
235				zone_state_t a_zoneState,
236				char *a_idsName, char *a_altBinDir,
237				char *a_adminFile, boolean_t a_tmpzn);
238static void		resetreturn();
239static void		usage(void);
240static boolean_t	add_packages(char **a_pkgList,
241				char *a_idsName, int a_repeat,
242				char *a_altBinDir, char *a_device,
243				boolean_t a_noZones);
244static boolean_t	add_packages_in_global_no_zones(char **a_pkgList,
245				char *a_idsName, int a_repeat,
246				char *a_altBinDir, char *a_device);
247static boolean_t	add_packages_in_global_with_zones(char **a_pkgList,
248				char *a_idsName, int a_repeat,
249				char *a_altBinDir, char *a_device,
250				zoneList_t a_zlst);
251static boolean_t	add_packages_in_nonglobal_zone(char **a_pkgList,
252				char *a_idsName, int a_repeat,
253				char *a_altBinDir, char *a_device);
254static boolean_t	check_applicability(char *a_packageDir,
255				char *a_pkgInst, char *a_rootPath,
256				CAF_T a_flags);
257static boolean_t	get_package_list(char ***r_pkgList, char **a_argv,
258				char *a_categories, char **a_categoryList,
259				char *a_idsName, int *r_repeat);
260static boolean_t	continue_installation(void);
261static boolean_t	unpack_and_check_packages(char **a_pkgList,
262				char *a_idsName, char *a_packageDir);
263/*
264 * *****************************************************************************
265 * global external (public) functions
266 * *****************************************************************************
267 */
268
269/*
270 * Name:	main
271 * Description:	main entry point for pkgadd/pkgask
272 * Returns:	int
273 *   0        Successful completion
274 *   1        Fatal error.
275 *   2        Warning.
276 *   3        Interruption.
277 *   4        Administration.
278 *   5        Administration. Interaction is required. Do not use pkgadd -n.
279 * In addition, one of the following values may be added to the previous value
280 * as appropriate:
281 *  10       Reboot after installation of all packages.
282 *  20       Reboot after installation of this package.
283 * For example, "14" would indicate both "administration" and "reboot after
284 * installation of all packages".
285 */
286
287int
288main(int argc, char **argv)
289{
290	char			**category = NULL;
291	char			*abiPtr;
292	char			*altBinDir = (char *)NULL;
293	char			*catg_arg = NULL;
294	char			*device = NULL;		/* dev pkg stored on */
295	char			*p;
296	char			*q;
297	char			*prog;
298	char			*prog_full_name = NULL;
299	char			*spoolDir = NULL;	/* specified with -s */
300	char			Rpath[PATH_MAX+1] = {'\0'};
301	int			c;
302	int			n;
303	int			repeat;
304	struct sigaction	nact;
305	struct sigaction	oact;
306
307	/* initialize locale environment */
308
309	(void) setlocale(LC_ALL, "");
310	(void) textdomain(TEXT_DOMAIN);
311
312	/* initialize program name */
313
314	prog_full_name = argv[0];
315	prog = set_prog_name(argv[0]);
316
317	/* tell spmi zones interface how to access package output functions */
318
319	z_set_output_functions(echo, echoDebug, progerr);
320
321	askflag = (strcmp(prog, "pkgask") == 0);
322
323	/* set sane umask */
324
325	(void) umask(0022);
326
327	/* tell quit which ckreturn function to call */
328
329	quitSetCkreturnFunc(&ckreturn);
330
331	/* initially no source "device" */
332
333	device = NULL;
334
335	/* reset npkgs (used as pkg remaining count in quit.c) */
336
337	npkgs = 0;
338
339	if (z_running_in_global_zone() && !enable_local_fs()) {
340		progerr(ERR_CANNOT_ENABLE_LOCAL_FS);
341	}
342
343	pkgserversetmode(DEFAULTMODE);
344
345	/*
346	 * ********************************************************************
347	 * parse command line options
348	 * ********************************************************************
349	 */
350
351	while ((c = getopt(argc, argv,
352	    "?Aa:b:B:Cc:D:d:GhIMnO:R:r:Ss:tV:vY:z")) != EOF) {
353		switch (c) {
354
355		/*
356		 * Not a public interface: This disables attribute checking.
357		 * It speeds up installation a little bit.
358		 */
359		case 'A':
360			disableAttributes++;
361			break;
362
363		/*
364		 * Public interface: Define an installation administration
365		 * file, admin, to be used in place of the default
366		 * administration file.	 The token none overrides the use
367		 * of any admin file, and thus forces interaction with the
368		 * user. Unless a full path name is given, pkgadd first
369		 * looks in the current working directory for the
370		 * administration file.	 If the specified administration
371		 * file is not in the current working directory, pkgadd
372		 * looks in the /var/sadm/install/admin directory for the
373		 * administration file.
374		 */
375		case 'a':
376			admnfile = flex_device(optarg, 0);
377			break;
378
379		/*
380		 * Not a public interface: control block size given to
381		 * pkginstall - block size used in read()/write() loop;
382		 * default is st_blksize from stat() of source file.
383		 */
384		case 'B':
385			if (optarg[0] == '-') {
386				usage();
387				quit(1);
388			}
389			rw_block_size = optarg;
390			break;
391
392		/*
393		 * Not a public interface:  location where package executables
394		 * can be found - default is /usr/sadm/install/bin.
395		 */
396		case 'b':
397			if (optarg[0] == '-') {
398				usage();
399				quit(1);
400			}
401			if (!path_valid(optarg)) {
402				progerr(ERR_PATH, optarg);
403				quit(1);
404			}
405			if (isdir(optarg) != 0) {
406				p = strerror(errno);
407				progerr(ERR_CANNOT_USE_DIR, optarg, p);
408				quit(1);
409			}
410			altBinDir = optarg;
411			break;
412
413		/*
414		 * Not a public interface: This disables checksum tests on
415		 * the source files. It speeds up installation a little bit.
416		 */
417		case 'C':
418			disableChecksum++;
419			break;
420
421		/*
422		 * Not a public interface: This allows designation of a
423		 * continuation file. It is the same format as a dryrun file
424		 * but it is used to take up where the dryrun left off.
425		 */
426		case 'c':
427			pkgcontsrc = flex_device(optarg, 0);
428			break;
429
430		/*
431		 * Not a public interface: This allows designation of a
432		 * dryrun file. This pkgadd will create dryrun files
433		 * in the directory provided.
434		 */
435		case 'D':
436			if (optarg[0] == '-') {
437				usage();
438				quit(1);
439			}
440			pkgdrtarg = flex_device(optarg, 0);
441			break;
442
443		/*
444		 * Public interface: 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			if (optarg[0] == '-') {
453				usage();
454				quit(1);
455			}
456			if (!path_valid(optarg)) {
457				progerr(ERR_PATH, optarg);
458				quit(1);
459				/* NOTREACHED */
460			}
461
462			device = flex_device(optarg, 1);
463			break;
464
465		/*
466		 * Public interface: install package in global zone only.
467		 */
468		case 'G':
469			globalZoneOnly = B_TRUE;
470			break;
471
472		/*
473		 * Not a public interface: Enable hollow package support. When
474		 * specified, for any package that has SUNW_PKG_HOLLOW=true:
475		 *  Do not calculate and verify package size against target.
476		 *  Do not run any package procedure or class action scripts.
477		 *  Do not create any target directories.
478		 *  Do not perform any script locking.
479		 *  Do not install any components of any package.
480		 *  Do not output any status or database update messages.
481		 */
482		case 'h':
483			set_depend_pkginfo_DB(B_TRUE);
484			break;
485
486		/*
487		 * Not a public interface: Informs scripts that this is
488		 * an initial install by setting the environment parameter
489		 * PKG_INIT_INSTALL=TRUE for all scripts. They may use it as
490		 * they see fit, safe in the knowledge that the target
491		 * filesystem is tabula rasa.
492		 */
493		case 'I':
494			init_install++;
495			break;
496
497		/*
498		 * Public interface: Instruct pkgadd not to use the
499		 * $root_path/etc/vfstab file for determining the client's
500		 * mount points. This option assumes the mount points are
501		 * correct on the server and it behaves consistently with
502		 * Solaris 2.5 and earlier releases.
503		 */
504		case 'M':
505			no_map_client = 1;
506			break;
507
508		/*
509		 * Not a public interface: the -O option allows the behavior
510		 * of the package tools to be modified. Recognized options:
511		 * -> debug
512		 * ---> enable debugging output
513		 * -> addzonename
514		 * ---> add zone name to appropriate messages
515		 * -> nozones
516		 * ---> act as though in global zone with no non-global zones
517		 * -> enable-hollow-package-support
518		 * ---> Enable hollow package support. When specified, for any
519		 * ---> package that has SUNW_PKG_HOLLOW=true:
520		 * ---> Do not calculate and verify package size against target
521		 * ---> Do not run any package procedure or class action scripts
522		 * ---> Do not create any target directories
523		 * ---> Do not perform any script locking
524		 * ---> Do not install any components of any package
525		 * ---> Do not output any status or database update messages
526		 * -> zonelist="<names...>"
527		 * ---> add package to space/colon separated list of zones only
528		 */
529
530		case 'O':
531			for (p = strtok(optarg, ","); p != (char *)NULL;
532			    p = strtok(NULL, ",")) {
533
534				if (strcmp(p, "debug") == 0) {
535					/* set debug flag/enable debug output */
536					debugFlag = B_TRUE;
537					(void) echoDebugSetFlag(debugFlag);
538
539					/* debug info on arguments to pkgadd */
540					for (n = 0; n < argc && argv[n]; n++) {
541						echoDebug(DBG_ARG, n, argv[n]);
542					}
543
544					continue;
545				}
546
547				if (strcmp(p,
548				    "enable-hollow-package-support") == 0) {
549					set_depend_pkginfo_DB(B_TRUE);
550					continue;
551				}
552
553				if (strcmp(p, "addzonename") == 0) {
554					quitSetZoneName(z_get_zonename());
555					continue;
556				}
557
558				if (strcmp(p, "nozones") == 0) {
559					noZones = B_TRUE;
560					continue;
561				}
562
563				if (strncmp(p, "zonelist=", 9) == 0) {
564					/*
565					 * If colons used as separators,
566					 * convert to spaces.
567					 */
568					q = p + 9;
569					while (*q != '\0') {
570						if (*q == ':') {
571							*q = ' ';
572						}
573						q++;
574					}
575
576					if (z_set_zone_spec(p + 9) == -1)
577						quit(1);
578					usedZoneList = B_TRUE;
579					continue;
580				}
581
582				progerr(ERR_INVALID_O_OPTION, p);
583				continue;
584			}
585			break;
586
587		/*
588		 * Public interface: installation occurs in
589		 * non-interactive mode.  Suppress output of the list of
590		 * installed files. The default mode is interactive.
591		 */
592		case 'n':
593			nointeract++;
594			(void) echoSetFlag(B_FALSE);
595			break;
596
597		/*
598		 * Public interface: Define the full path name of a
599		 * directory to use as the root_path.  All files,
600		 * including package system information files, are
601		 * relocated to a directory tree starting in the specified
602		 * root_path. The root_path may be specified when
603		 * installing to a client from a server (for example,
604		 * /export/root/client1).
605		 */
606		case 'R':
607			if (optarg[0] == '-') {
608				usage();
609				quit(1);
610			}
611			/* determine the real path specified */
612
613			n = resolvepath(optarg, Rpath, sizeof (Rpath)-1);
614
615			/* use supplied path if not resolvable */
616
617			if (n == -1) {
618				(void) strlcpy(Rpath, optarg, sizeof (Rpath));
619			} else {
620				/* null terminate string */
621				Rpath[n] = '\0';
622			}
623
624			/* set the alternative root path */
625
626			if (!set_inst_root(Rpath)) {
627				progerr(ERR_ROOT_CMD);
628				exit(1);
629			}
630			break;
631
632		/*
633		 * Public interface: Identify a file or directory which
634		 * contains output from a previous pkgask(1M)
635		 * session. This file supplies the interaction responses
636		 * that would be requested by the package in interactive
637		 * mode. response must be a full pathname.
638		 */
639		case 'r':
640			if (optarg[0] == '-') {
641				usage();
642				quit(1);
643			}
644			respfile = flex_device(optarg, 2);
645			if (isdir(respfile) == 0)
646				respdir = respfile;
647			break;
648
649		/*
650		 * Not a public interface: suppress copyright notice being
651		 * output during installation.
652		 */
653		case 'S':
654			suppressCopyright++;
655			break;
656
657		/*
658		 * Public interface: Write the package into the directory
659		 * spool instead of installing it. The default directory
660		 * for spooled packages is /var/sadm/pkg.
661		 */
662		case 's':
663			spoolDir = flex_device(optarg, 1);
664			break;
665
666		/*
667		 * Not a public interface: disable save spool area creation;
668		 * suppress the creation and population of the package save
669		 * spool area (var/sadm/pkg/PKG/save/pspool/PKG).
670		 */
671		case 't':
672			disableSaveSpool++;
673			break;
674
675		/*
676		 * Public interface: Specify an alternative fs_file to map
677		 * the client's file systems.  For example, used in
678		 * situations where the $root_path/etc/vfstab file is
679		 * non-existent or unreliable. Informs the pkginstall
680		 * portion to mount up a client filesystem based upon the
681		 * supplied vfstab-like file of stable format.
682		 */
683		case 'V':
684			vfstab_file = flex_device(optarg, 2);
685			no_map_client = 0;
686			break;
687
688		/*
689		 * Public interface: Trace all of the scripts that get
690		 * executed by pkgadd, located in the pkginst/install
691		 * directory. This option is used for debugging the
692		 * procedural and non-procedural scripts
693		 */
694		case 'v':
695			pkgverbose++;
696			break;
697
698		/*
699		 * Public interface: Install packages based on the value
700		 * of the CATEGORY parameter stored in the package's
701		 * pkginfo(4) file. All packages on the source medium
702		 * whose CATEGORY matches one of the specified categories
703		 * will be selected for installation or spooling. Install
704		 * packages that contain the same CATEGORY as the one
705		 * provided on the command line.
706		 */
707		case 'Y':
708			if (optarg[0] == '-') {
709				usage();
710				quit(1);
711			}
712			catg_arg = strdup(optarg);
713
714			if ((category = get_categories(catg_arg)) == NULL) {
715				progerr(ERR_CAT_INV, catg_arg);
716				exit(1);
717			} else if (is_not_valid_length(category)) {
718				progerr(ERR_CAT_LNGTH);
719				exit(1);
720			}
721			break;
722
723		/*
724		 * Not a public interface: perform fresh install from
725		 * package save spool area. When set, the package contents
726		 * are installed from the package spool save area instead
727		 * of from the package root area, so that the original
728		 * source packages are not required to install the
729		 * package. If the -h option is also specified and the
730		 * package is hollow, then this option is ignored. When -z
731		 * is specified:
732		 *  - Editable files are installed from the package instance
733		 *    save area.
734		 *  - Volatile files are installed from the package instance
735		 *    save area.
736		 *  - Executable and data files are installed from the final
737		 *    installed location as specified in the pkgmap file.
738		 *  - Installation scripts are run from the package spool
739		 *    save area.
740		 */
741		case 'z':
742			saveSpoolInstall++;
743			break;
744
745		/*
746		 * unrecognized option
747		 */
748
749		default:
750			usage();
751			return (1);
752		}
753	}
754
755	/*
756	 * ********************************************************************
757	 * validate command line options
758	 * ********************************************************************
759	 */
760
761	/* set "debug echo" flag according to setting of "-O debug" option */
762
763	(void) echoDebugSetFlag(debugFlag);
764
765	/* output entry debugging information */
766
767	if (z_running_in_global_zone()) {
768		echoDebug(DBG_ENTRY_IN_GZ, prog_full_name);
769	} else {
770		echoDebug(DBG_ENTRY_IN_LZ, prog_full_name, getzoneid(),
771		    z_get_zonename());
772	}
773
774	/*
775	 * Later, it may be decided to pursue this ability to continue to an
776	 * actual installation based only on the dryrun data. At this time,
777	 * it is too risky.
778	 */
779
780	if (pkgcontsrc && !pkgdrtarg) {
781		progerr(ERR_NO_LIVE_MODE);
782		usage();
783		return (1);
784	}
785
786	/* ignore -G option if not used in the global zone */
787
788	if (!z_running_in_global_zone()) {
789		globalZoneOnly = B_FALSE;
790	}
791
792	/* if zonelist used, must be in global zone */
793
794	if (usedZoneList && !z_running_in_global_zone()) {
795		progerr(ERR_Z_USED_IN_NONGLOBAL_ZONE);
796		return (1);
797	}
798
799	/* -G and zonelist cannot be used together */
800
801	if (globalZoneOnly && usedZoneList) {
802		progerr(ERR_GZ_USED_TOGETHER);
803		usage();
804		return (1);
805	}
806
807	/* -s cannot be used with either -G or zonelist */
808
809	if (spoolDir != NULL) {
810		if (globalZoneOnly) {
811			progerr(ERR_SPOOLDIR_USED_WITH_G);
812			usage();
813			return (1);
814		}
815		if (usedZoneList) {
816			progerr(ERR_SPOOLDIR_USED_WITH_Z);
817			usage();
818			return (1);
819		}
820		if (strcmp(spoolDir, "/var/sadm/pkg") == 0) {
821			progerr(ERR_SPOOLDIR_CANNOT_BE_SYS, "/var/sadm/pkg");
822			usage();
823			return (1);
824		}
825	}
826
827	/* pkgask does not support the same options as pkgadd */
828
829	if (askflag && spoolDir) {
830		progerr(ERR_PKGASK_AND_SPOOLDIR);
831		usage();
832		return (1);
833	}
834
835	if (askflag && nointeract) {
836		progerr(ERR_PKGASK_AND_NOINTERACT);
837		usage();
838		return (1);
839	}
840
841	/* cannot use response file/not-interactive and spool-to directory */
842
843	if (spoolDir && nointeract) {
844		progerr(ERR_SPOOLDIR_AND_NOINTERACT);
845		usage();
846		return (1);
847	}
848
849	if (spoolDir && respfile) {
850		progerr(ERR_SPOOLDIR_AND_RESPFILE);
851		usage();
852		return (1);
853	}
854
855	if (usedZoneList) {
856		/* Verify supplied zone list valid for the target */
857		if (z_verify_zone_spec() == -1)
858			return (1);
859
860		/* -z zonelist=global is logically the same as -G */
861		if (z_global_only() && z_running_in_global_zone())
862			globalZoneOnly = B_TRUE;
863	}
864
865	/*
866	 * hook SIGINT and SIGHUP interrupts into quit.c's trap handler
867	 */
868
869	/* hold SIGINT/SIGHUP interrupts */
870
871	(void) sighold(SIGHUP);
872	(void) sighold(SIGINT);
873
874	/* connect quit.c:trap() to SIGINT */
875
876	nact.sa_handler = quitGetTrapHandler();
877	nact.sa_flags = SA_RESTART;
878	(void) sigemptyset(&nact.sa_mask);
879
880	(void) sigaction(SIGINT, &nact, &oact);
881
882	/* connect quit.c:trap() to SIGHUP */
883
884	nact.sa_handler = quitGetTrapHandler();
885	nact.sa_flags = SA_RESTART;
886	(void) sigemptyset(&nact.sa_mask);
887
888	(void) sigaction(SIGHUP, &nact, &oact);
889
890	/* release hold on signals */
891
892	(void) sigrelse(SIGHUP);
893	(void) sigrelse(SIGINT);
894
895	/*
896	 * This function is in the libadm library; it sets:
897	 * -> get_PKGLOC() = <install_root>/var/sadm/pkg
898	 * -> get_PKGADM() = <install_root>/var/sadm/install
899	 * -> pkgdir = <install_root>/var/sadm/pkg
900	 * -> pkg_install_root = <install_root>
901	 * This controls operations of libadm functions such as:
902	 * -> pkginfofind, pkginfopen, fpkgparam, pkgparam, get_PKGLOC,
903	 * -> get_PKGADM, get_install_root
904	 */
905
906	set_PKGpaths(get_inst_root());
907	echoDebug(DBG_PKGADD_PKGPATHS,
908	    get_PKGLOC() ? get_PKGLOC() : "",
909	    get_PKGADM() ? get_PKGADM() : "");
910
911	/*
912	 * This function is in the libinst library; it reads the specified
913	 * admin(4) file and, using fpkgparam(), sets the global "adm" structure
914	 * values to match what is in the specified admin file.
915	 */
916
917	echoDebug(DBG_PKGADD_ADMINFILE, admnfile ? admnfile : "");
918	setadminFile(admnfile);
919
920	/*
921	 * if running in the global zone, and non-global zones exist, then
922	 * enable hollow package support so that any packages that are marked
923	 * SUNW_PKG_HOLLOW=true will be correctly installed in non-global zones
924	 * when added directly in the global zone by the global zone admin.
925	 */
926
927	if (is_depend_pkginfo_DB()) {
928		echoDebug(DBG_PKGADD_HOLLOW_ENABLED);
929	} else if ((z_running_in_global_zone() == B_TRUE) &&
930	    (z_non_global_zones_exist() == B_TRUE)) {
931		echoDebug(DBG_PKGADD_ENABLING_HOLLOW);
932		set_depend_pkginfo_DB(B_TRUE);
933	}
934
935	/* if no device, get and validate default device */
936
937	if (device == NULL) {
938		device = devattr("spool", "pathname");
939		if (device == NULL) {
940			progerr(ERR_NODEVICE);
941			quit(1);
942			/* NOTREACHED */
943		}
944	}
945
946	/* must be root if not directing results to spool directory */
947
948	if ((getuid() != 0) && (spoolDir == NULL)) {
949		progerr(ERR_NOT_ROOT, prog);
950		exit(1);
951	}
952
953	/*
954	 * process response file argument
955	 */
956
957	if (respfile) {
958		echoDebug(DBG_PKGADD_RESPFILE,
959		    respfile, respdir ? respdir : "");
960
961		if (respfile[0] != '/') {
962			progerr(ERR_RSP_FILE_NOTFULLPATH, respfile);
963			quit(1);
964			/* NOTREACHED */
965		}
966		if (respdir == NULL) {
967			if (askflag) {
968				if (access(respfile, F_OK) == 0) {
969					progerr(ERR_NORESP, respfile);
970					quit(1);
971					/* NOTREACHED */
972				}
973			} else if (access(respfile, F_OK) != 0) {
974				progerr(ERR_ACCRESP, respfile);
975				quit(1);
976				/* NOTREACHED */
977			}
978		}
979	} else if (askflag) {
980		progerr(ERR_RSP_FILE_NOT_GIVEN);
981		usage();
982		quit(1);
983		/* NOTREACHED */
984	}
985
986	/* establish temporary directory to use */
987
988	if ((tmpdir = getenv("TMPDIR")) == NULL) {
989		/* use default - no override specified */
990		tmpdir = P_tmpdir;
991	}
992
993	echoDebug(DBG_PKGADD_TMPDIR, tmpdir);
994
995	/*
996	 * See if user wants this to be handled as an old style pkg.
997	 * NOTE : the ``exception_pkg()'' stuff is to be used only
998	 * through on495. This function comes out for on1095. See
999	 * PSARC 1993-546. -- JST
1000	 */
1001
1002	if (getenv("NONABI_SCRIPTS") != NULL) {
1003		old_pkg = 1;
1004	}
1005
1006	/*
1007	 * See if the user wants to process symlinks consistent with
1008	 * the old behavior.
1009	 */
1010
1011	if (getenv("PKG_NONABI_SYMLINKS") != NULL) {
1012		old_symlinks = 1;
1013	}
1014
1015	/*
1016	 * See if the user wants the package name length restricted.
1017	 */
1018
1019	abiPtr = getenv("PKG_ABI_NAMELENGTH");
1020	if (abiPtr && strncasecmp(abiPtr, "TRUE", 4) == 0) {
1021		ABI_namelength = 1;
1022	}
1023
1024	/*
1025	 * validate the package source device - return pkgdev info that
1026	 * describes the package source device.
1027	 */
1028
1029	if (devtype(device, &pkgdev)) {
1030		progerr(ERR_BAD_DEVICE, device);
1031		quit(1);
1032		/* NOTREACHED */
1033	}
1034
1035	/*
1036	 * If writing the packages into a spool directory instead of
1037	 * installing the packages, open the package datastream and
1038	 * invoke pkgtrans to perform the conversion and exit.
1039	 */
1040
1041	if (spoolDir != (char *)NULL) {
1042		boolean_t	b;
1043		int		n;
1044
1045		echoDebug(DBG_INSTALLING_TO_SPOOL, spoolDir);
1046
1047		b = open_package_datastream(argc, argv, spoolDir, device,
1048		    &repeat, &ids_name, tmpdir,
1049		    &pkgdev, optind);
1050
1051		quitSetIdsName(ids_name);
1052
1053		if (b != B_TRUE) {
1054			progerr(ERR_CANNOT_OPEN_PKG_STREAM, PSTR(device));
1055			quit(1);
1056		}
1057
1058		n = pkgtrans(device, spoolDir, &argv[optind], 0);
1059		quit(n);
1060		/* NOTREACHED */
1061	}
1062
1063	/*
1064	 * error if there are packages on the command line and a category
1065	 * was specified
1066	 */
1067
1068	if ((optind < argc) && (catg_arg != NULL)) {
1069		progerr(ERR_PKGS_AND_CAT_PKGADD);
1070		usage();
1071		quit(1);
1072		/* NOTREACHED */
1073	}
1074
1075	/*
1076	 * ********************************************************************
1077	 * main package processing "loop"
1078	 * ********************************************************************
1079	 */
1080
1081	ids_name = NULL;
1082	quitSetIdsName(ids_name);
1083
1084	for (;;) {
1085		boolean_t	b;
1086		char		**pkglist;	/* points to array of pkgs */
1087
1088		/*
1089		 * open next package data stream
1090		 */
1091
1092		b = open_package_datastream(argc, argv, spoolDir, device,
1093		    &repeat, &ids_name, tmpdir,
1094		    &pkgdev, optind);
1095
1096		quitSetIdsName(ids_name);
1097
1098		if (b == B_FALSE) {
1099			echoDebug(ERR_CANNOT_OPEN_PKG_STREAM, PSTR(device));
1100			continue;
1101		}
1102
1103		/*
1104		 * package source data stream open - get the package list
1105		 */
1106
1107		b = get_package_list(&pkglist, argv, catg_arg, category,
1108		    ids_name, &repeat);
1109
1110		if (b == B_FALSE) {
1111			echoDebug(DBG_CANNOT_GET_PKGLIST);
1112
1113			progerr(ERR_NOPKGS, pkgdev.dirname);
1114			quit(1);
1115			/* NOTREACHED */
1116		}
1117
1118		/*
1119		 * count the number of packages to install
1120		 * NOTE: npkgs is a global variable that is referenced by quit.c
1121		 * when error messages are generated - it is referenced directly
1122		 * by the other functions called below...
1123		 */
1124
1125		for (npkgs = 0; pkglist[npkgs] != (char *)NULL; /* void */) {
1126			echoDebug(DBG_PKG_SELECTED, npkgs, pkglist[npkgs]);
1127			npkgs++;
1128		}
1129
1130		/* output number of packages to be added */
1131
1132		echoDebug(DBG_NUM_PKGS_TO_ADD, npkgs);
1133
1134		/*
1135		 * if pkgask and response container is a file (not a directory),
1136		 * and there is more than one package to install, then it is an
1137		 * error - too many packages to install when response container
1138		 * is a file.
1139		 */
1140
1141		if ((askflag != 0) && (respdir == (char *)NULL) &&
1142		    (npkgs > 1)) {
1143			progerr(ERR_TOO_MANY_PKGS);
1144			quit(1);
1145			/* NOTREACHED */
1146		}
1147
1148		/*
1149		 * package list generated - add packages
1150		 */
1151
1152		b = add_packages(pkglist, ids_name, repeat,
1153		    altBinDir, device, noZones);
1154
1155		/*
1156		 * close open input data stream (source package) if left open.
1157		 */
1158
1159		if (ids_name) {
1160			echoDebug(DBG_CLOSING_STREAM, ids_name,
1161			    PSTR(pkgdev.dirname));
1162			(void) ds_close(1);
1163			rrmdir(pkgdev.dirname);
1164			ids_name = NULL;
1165			quitSetIdsName(ids_name);
1166		}
1167
1168		/*
1169		 * continue with next sequence of packages if continue set
1170		 */
1171
1172		if (b == B_TRUE) {
1173			continue;
1174		}
1175
1176		/*
1177		 * not continuing - quit with 0 exit code
1178		 */
1179
1180		quit(0);
1181		/* NOTREACHED */
1182	}
1183
1184	/* NOTREACHED */
1185}
1186
1187/*
1188 * *****************************************************************************
1189 * static internal (private) functions
1190 * *****************************************************************************
1191 */
1192
1193/*
1194 * Name:	pkgZoneCheckInstall
1195 * Description:	Invoke pkginstall in a specified zone to perform a preinstall
1196 *		check of the a single package in the specified zone
1197 * Arguments:	a_zoneName - pointer to string representing the name of the
1198 *			zone to check install the package in.
1199 *		a_zoneState - current state of the zone; must be mounted or
1200 *			running.
1201 *		a_idsName - pointer to string representing the data stream
1202 *			device (input data stream) containing the package to
1203 *			be check installed.
1204 *		a_altBinDir - pointer to string representing an alternative
1205 *			binary location directory to pass to pkginstall.
1206 *			If this is == NULL no alternative binary location is
1207 *			passed to pkginstall.
1208 *		a_adminFile - pointer to string representing the admin
1209 *			file to pass to pkginstall when installing the package.
1210 *			If this is == NULL no admin file is given to pkginstall.
1211 *		a_stdoutPath - pointer to string representing the local path
1212 *			into which all output written by pkginstall to stdout
1213 *			is stored.
1214 *			If this is == NULL stdout is redirected to /dev/null
1215 *		a_tmpzn - B_TRUE when this zone is booted by the package
1216 *			command or B_FALSE if it was running before.
1217 * Returns:	int	(see ckreturn() function for details)
1218 *		0 - success
1219 *		1 - package operation failed (fatal error)
1220 *		2 - non-fatal error (warning)
1221 *		3 - user selected quit (operation interrupted)
1222 *		4 - admin settings prevented operation
1223 *		5 - interaction required and -n (non-interactive) specified
1224 *		"10" will be added to indicate "immediate reboot required"
1225 *		"20" will be added to indicate "reboot after install required"
1226 */
1227
1228static int
1229pkgZoneCheckInstall(char *a_zoneName, zone_state_t a_zoneState,
1230    char *a_idsName, char *a_altBinDir, char *a_adminFile,
1231    char *a_stdoutPath, boolean_t a_tmpzn)
1232{
1233	char	*arg[MAXARGS];
1234	char	*p;
1235	char	adminfd_path[PATH_MAX];
1236	char	path[PATH_MAX];
1237	char	pkgstreamfd_path[PATH_MAX];
1238	int	fds[MAX_FDS];
1239	int	maxfds;
1240	int	n;
1241	int	nargs;
1242
1243	/* entry assertions */
1244
1245	assert(a_zoneName != (char *)NULL);
1246	assert(*a_zoneName != '\0');
1247
1248	/* entry debugging info */
1249
1250	echoDebug(DBG_PKGZONECHECKINSTALL_ENTRY);
1251	echoDebug(DBG_PKGZONECHECKINSTALL_ARGS, a_zoneName, PSTR(pkginst),
1252	    PSTR(pkgdev.dirname), PSTR(pkgdev.mount), PSTR(pkgdev.bdevice),
1253	    a_zoneState == ZONE_STATE_MOUNTED ? "/a" : "/",
1254	    PSTR(a_idsName), PSTR(a_adminFile), PSTR(a_stdoutPath));
1255
1256	/* generate full path to 'phatinstall' to run in zone */
1257
1258	(void) snprintf(path, sizeof (path), "%s/pkginstall",
1259	    "/usr/sadm/install/bin");
1260
1261	/* start at first file descriptor */
1262
1263	maxfds = 0;
1264
1265	/*
1266	 * generate argument list for call to pkginstall
1267	 */
1268
1269	/* start at argument 0 */
1270
1271	nargs = 0;
1272
1273	/* first argument is always: full path to executable */
1274
1275	arg[nargs++] = path;
1276
1277	/*
1278	 * second argument is always: pass -O debug to pkginstall: debug mode
1279	 */
1280	if (debugFlag == B_TRUE) {
1281		arg[nargs++] = "-O";
1282		arg[nargs++] = "debug";
1283	}
1284
1285	/* pkgadd -G: pass -G to pkginstall */
1286
1287	if (globalZoneOnly == B_TRUE) {
1288		arg[nargs++] = "-G";
1289	}
1290
1291	/* pkgadd -b dir: pass -b to pkginstall */
1292
1293	if (a_altBinDir != (char *)NULL) {
1294		arg[nargs++] = "-b";
1295		arg[nargs++] = a_altBinDir;
1296	}
1297
1298	/* pkgadd -C: pass -C to pkginstall: disable checksum */
1299
1300	if (disableChecksum) {
1301		arg[nargs++] = "-C";
1302	}
1303
1304	/* pkgadd -A: pass -A to pkginstall: disable attribute checking */
1305
1306	if (disableAttributes) {
1307		arg[nargs++] = "-A";
1308	}
1309
1310	/*
1311	 * NONABI_SCRIPTS defined: pass -o to pkginstall; refers to a
1312	 * pkg requiring operator interaction during a procedure script
1313	 * (common before on1093)
1314	 */
1315
1316	if (old_pkg) {
1317		arg[nargs++] = "-o";
1318	}
1319
1320	/*
1321	 * PKG_NONABI_SYMLINKS defined: pass -y to pkginstall; process
1322	 * symlinks consistent with old behavior
1323	 */
1324
1325	if (old_symlinks) {
1326		arg[nargs++] = "-y";
1327	}
1328
1329	/*
1330	 * PKG_ABI_NAMELENGTH defined: pass -e to pkginstall; causes
1331	 * package name length to be restricted
1332	 */
1333
1334	if (ABI_namelength) {
1335		arg[nargs++] = "-e";
1336	}
1337
1338	/* pkgadd -S: pass -S to pkginstall: suppress copyright notices */
1339
1340	arg[nargs++] = "-S";
1341
1342	/* pkgadd -M: pass -M to pkginstall: dont mount client file systems */
1343
1344	arg[nargs++] = "-M";
1345
1346	/* pkgadd -v: pass -v to pkginstall: never trace scripts */
1347
1348	/* if running pkgask, pass -i to pkginstall: running pkgask */
1349
1350	if (askflag) {
1351		return (0);
1352	}
1353
1354	/* pass "-O enable-hollow-package-support" */
1355
1356	if (is_depend_pkginfo_DB()) {
1357		arg[nargs++] = "-O";
1358		arg[nargs++] = "enable-hollow-package-support";
1359	}
1360
1361	/* check is always in non-interactive mode */
1362
1363	arg[nargs++] = "-n";
1364
1365	/* pkgadd -a admin: pass -a admin to pkginstall in zone: admin file */
1366
1367	if (a_adminFile) {
1368		int fd;
1369		fd = openLocal(a_adminFile, O_RDONLY, tmpdir);
1370		if (fd < 0) {
1371			progerr(ERR_CANNOT_COPY_LOCAL, a_adminFile,
1372			    errno, strerror(errno));
1373			return (1);
1374		}
1375		(void) snprintf(adminfd_path, sizeof (adminfd_path),
1376		    "/proc/self/fd/%d", fd);
1377		fds[maxfds++] = fd;
1378		arg[nargs++] = "-a";
1379		arg[nargs++] = adminfd_path;
1380	}
1381
1382	/* pkgadd -R root: pass -R /a to pkginstall when zone is mounted */
1383
1384	if (a_zoneState == ZONE_STATE_MOUNTED) {
1385		arg[nargs++] = "-R";
1386		arg[nargs++] = "/a";
1387	}
1388
1389	/* pass -N to pkginstall: program name to report */
1390
1391	arg[nargs++] = "-N";
1392	arg[nargs++] = get_prog_name();
1393
1394	/* pass "-O preinstallcheck" */
1395
1396	arg[nargs++] = "-O";
1397	arg[nargs++] = "preinstallcheck";
1398
1399	/* add "-O addzonename" */
1400
1401	arg[nargs++] = "-O";
1402	arg[nargs++] = "addzonename";
1403
1404	/*
1405	 * add parent zone info/type
1406	 */
1407
1408	p = z_get_zonename();
1409	if ((p != NULL) && (*p != '\0')) {
1410			char	zn[MAXPATHLEN];
1411			(void) snprintf(zn, sizeof (zn),
1412			    "parent-zone-name=%s", p);
1413			arg[nargs++] = "-O";
1414			arg[nargs++] = strdup(zn);
1415	}
1416
1417	/* current zone type */
1418
1419	arg[nargs++] = "-O";
1420	if (z_running_in_global_zone() == B_TRUE) {
1421			char	zn[MAXPATHLEN];
1422			(void) snprintf(zn, sizeof (zn),
1423			    "parent-zone-type=%s",
1424			    TAG_VALUE_GLOBAL_ZONE);
1425			arg[nargs++] = strdup(zn);
1426	} else {
1427			char	zn[MAXPATHLEN];
1428			(void) snprintf(zn, sizeof (zn),
1429			    "parent-zone-type=%s",
1430			    TAG_VALUE_NONGLOBAL_ZONE);
1431			arg[nargs++] = strdup(zn);
1432	}
1433
1434	/* Add the pkgserv options */
1435	arg[nargs++] = "-O";
1436	arg[nargs++] = pkgmodeargument(a_tmpzn ? RUN_ONCE : pkgservergetmode());
1437
1438	/* add in the package stream file */
1439
1440	if (a_idsName != NULL) {
1441		int fd;
1442		fd = openLocal(a_idsName, O_RDONLY, tmpdir);
1443		if (fd < 0) {
1444			progerr(ERR_STREAM_UNAVAILABLE, a_idsName,
1445			    pkginst, strerror(errno));
1446			quit(1);
1447		}
1448		(void) snprintf(pkgstreamfd_path, sizeof (pkgstreamfd_path),
1449		    "/proc/self/fd/%d", fd);
1450		fds[maxfds++] = fd;
1451		arg[nargs++] = pkgstreamfd_path;
1452	} else {
1453		progerr(ERR_PKGZONEINSTALL_NO_STREAM);
1454		quit(1);
1455	}
1456
1457	/* add package instance name */
1458
1459	arg[nargs++] = pkginst;
1460
1461	/* terminate the argument list */
1462
1463	arg[nargs++] = NULL;
1464
1465	/*
1466	 * run the appropriate pkginstall command in the specified zone
1467	 */
1468
1469	if (debugFlag == B_TRUE) {
1470		echoDebug(DBG_ZONE_EXEC_ENTER, a_zoneName, arg[0]);
1471		for (n = 0; arg[n]; n++) {
1472			echoDebug(DBG_ARG, n, arg[n]);
1473		}
1474	}
1475
1476	/* terminate file descriptor list */
1477
1478	fds[maxfds] = -1;
1479
1480	/* exec command in zone */
1481
1482	n = z_zone_exec(a_zoneName, path, arg, a_stdoutPath, (char *)NULL, fds);
1483
1484	echoDebug(DBG_ZONE_EXEC_EXIT, a_zoneName, arg[0], n,
1485	    PSTR(a_stdoutPath));
1486
1487	/*
1488	 * close any files that were opened for use by the
1489	 * /proc/self/fd interface so they could be passed to programs
1490	 * via the z_zone_exec() interface
1491	 */
1492
1493	for (; maxfds > 0; maxfds--) {
1494		(void) close(fds[maxfds-1]);
1495	}
1496
1497	/* return results of pkginstall in zone execution */
1498
1499	return (n);
1500}
1501
1502/*
1503 * Name:	pkgZoneInstall
1504 * Description:	Invoke pkginstall in a specified zone to perform an install
1505 *		of a single package in the specified zone
1506 * Arguments:	a_zoneName - pointer to string representing the name of the
1507 *			zone to install the package in.
1508 *		a_zoneState - current state of the zone; must be mounted or
1509 *			running.
1510 *		a_idsName - pointer to string representing the data stream
1511 *			device (input data stream) containing the package to
1512 *			be installed.
1513 *		a_altBinDir - pointer to string representing an alternative
1514 *			binary location directory to pass to pkginstall.
1515 *			If this is == NULL no alternative binary location is
1516 *			passed to pkginstall.
1517 *		a_adminFile - pointer to string representing the admin
1518 *			file to pass to pkginstall when installing the package.
1519 *			If this is == NULL no admin file is given to pkginstall.
1520 *		a_stdoutPath - pointer to string representing the local path
1521 *			into which all output written by pkginstall to stdout
1522 *			is stored.
1523 *			If this is == NULL stdout is redirected to /dev/null
1524 *		a_tmpzn - B_TRUE when this zone is booted by the package
1525 *			command or B_FALSE if it was running before.
1526 * Returns:	int	(see ckreturn() function for details)
1527 *		0 - success
1528 *		1 - package operation failed (fatal error)
1529 *		2 - non-fatal error (warning)
1530 *		3 - user selected quit (operation interrupted)
1531 *		4 - admin settings prevented operation
1532 *		5 - interaction required and -n (non-interactive) specified
1533 *		"10" will be added to indicate "immediate reboot required"
1534 *		"20" will be added to indicate "reboot after install required"
1535 */
1536
1537static int
1538pkgZoneInstall(char *a_zoneName, zone_state_t a_zoneState, char *a_idsName,
1539    char *a_altBinDir, char *a_adminFile, boolean_t a_tmpzn)
1540{
1541	char	*arg[MAXARGS];
1542	char	*p;
1543	char	adminfd_path[PATH_MAX];
1544	char	path[PATH_MAX];
1545	char	pkgstreamfd_path[PATH_MAX];
1546	char	respfilefd_path[PATH_MAX];
1547	int	fds[MAX_FDS];
1548	int	maxfds;
1549	int	n;
1550	int	nargs;
1551
1552	/* entry assertions */
1553
1554	assert(a_zoneName != (char *)NULL);
1555	assert(*a_zoneName != '\0');
1556
1557	/* entry debugging info */
1558
1559	echoDebug(DBG_PKGZONEINSTALL_ENTRY);
1560	echoDebug(DBG_PKGZONEINSTALL_ARGS, a_zoneName, PSTR(pkginst),
1561	    PSTR(pkgdev.dirname), PSTR(pkgdev.mount), PSTR(pkgdev.bdevice),
1562	    a_zoneState == ZONE_STATE_MOUNTED ? "/a" : "", PSTR(a_idsName),
1563	    a_adminFile);
1564
1565	/* generate path to pkginstall */
1566
1567	(void) snprintf(path, sizeof (path), "%s/pkginstall", PKGBIN);
1568
1569	/* start at first file descriptor */
1570
1571	maxfds = 0;
1572
1573	/*
1574	 * generate argument list for call to pkginstall
1575	 */
1576
1577	/* start at argument 0 */
1578
1579	nargs = 0;
1580
1581	/* first argument is path to executable */
1582
1583	arg[nargs++] = path;
1584
1585	/*
1586	 * second argument is always: pass -O debug to pkginstall: debug mode
1587	 */
1588	if (debugFlag == B_TRUE) {
1589		arg[nargs++] = "-O";
1590		arg[nargs++] = "debug";
1591	}
1592
1593	/* pkgadd -G: pass -G to pkginstall */
1594
1595	if (globalZoneOnly == B_TRUE) {
1596		arg[nargs++] = "-G";
1597	}
1598
1599	/* pkgadd -b dir: pass -b to pkginstall in zone */
1600
1601	if (a_altBinDir != (char *)NULL) {
1602		arg[nargs++] = "-b";
1603		arg[nargs++] = a_altBinDir;
1604	}
1605
1606	/* pkgadd -B blocksize: pass -B to pkginstall in zone */
1607
1608	if (rw_block_size != NULL) {
1609		arg[nargs++] = "-B";
1610		arg[nargs++] = rw_block_size;
1611	}
1612
1613	/* pkgadd -C: pass -C to pkgadd in zone: disable checksum */
1614
1615	if (disableChecksum) {
1616		arg[nargs++] = "-C";
1617	}
1618
1619	/* pkgadd -A: pass -A to pkgadd in zone: disable attribute checking */
1620
1621	if (disableAttributes) {
1622		arg[nargs++] = "-A";
1623	}
1624
1625	/* pkgadd -S: pass -S to pkgadd in zone: suppress copyright notices */
1626
1627	arg[nargs++] = "-S";
1628
1629	/* pkgadd -I: pass -I to pkgadd in zone: initial install */
1630
1631	if (init_install) {
1632		arg[nargs++] = "-I";
1633	}
1634
1635	/* pkgadd -M: pass -M to pkgadd in zone: dont mount client file sys */
1636
1637	arg[nargs++] = "-M";
1638
1639	/* pkgadd -v: pass -v to pkgadd in zone: trace scripts */
1640
1641	if (pkgverbose) {
1642		arg[nargs++] = "-v";
1643	}
1644
1645	/* pkgadd -z: pass -z to pkgadd in zone fresh inst from pkg save area */
1646
1647	if (saveSpoolInstall) {
1648		arg[nargs++] = "-z";
1649	}
1650
1651	/* pass "-O enable-hollow-package-support" */
1652
1653	if (is_depend_pkginfo_DB()) {
1654		arg[nargs++] = "-O";
1655		arg[nargs++] = "enable-hollow-package-support";
1656	}
1657
1658	/* pkgadd -t pass -t to pkgadd in zone disable save spool area create */
1659
1660	if (disableSaveSpool) {
1661		arg[nargs++] = "-t";
1662	}
1663
1664	/* if running pkgask, pass -i to pkgadd in zone: running pkgask */
1665
1666	if (askflag) {
1667		echo(MSG_BYPASSING_ZONE, a_zoneName);
1668		return (0);
1669	}
1670
1671	/*
1672	 * pkgadd -n (not pkgask): pass -n to pkginstall: noninteractive mode
1673	 */
1674	if (nointeract && !askflag) {
1675		arg[nargs++] = "-n";
1676	}
1677
1678	/* pkgadd -a admin: pass -a admin to pkginstall in zone: admin file */
1679
1680	if (a_adminFile) {
1681		int fd;
1682		fd = openLocal(a_adminFile, O_RDONLY, tmpdir);
1683		if (fd < 0) {
1684			progerr(ERR_CANNOT_COPY_LOCAL, a_adminFile,
1685			    errno, strerror(errno));
1686			return (1);
1687		}
1688		(void) snprintf(adminfd_path, sizeof (adminfd_path),
1689		    "/proc/self/fd/%d", fd);
1690		fds[maxfds++] = fd;
1691		arg[nargs++] = "-a";
1692		arg[nargs++] = adminfd_path;
1693	}
1694
1695	/* pkgadd -R root: pass -R /a to pkginstall when zone is mounted */
1696	if (a_zoneState == ZONE_STATE_MOUNTED) {
1697		arg[nargs++] = "-R";
1698		arg[nargs++] = "/a";
1699	}
1700
1701	/*
1702	 * pkgadd -D arg: pass -D dryrun to pkginstall in zone: dryrun
1703	 * mode/file
1704	 */
1705	if (pkgdrtarg) {
1706		arg[nargs++] = "-D";
1707		arg[nargs++] = pkgdrtarg;
1708	}
1709
1710	/*
1711	 * pkgadd -c cont: pass -c cont to pkginstall in zone: continuation
1712	 * file
1713	 */
1714	if (pkgcontsrc) {
1715		arg[nargs++] = "-c";
1716		arg[nargs++] = pkgcontsrc;
1717	}
1718
1719	/* pkgadd -r resp: pass -r resp to pkginstall in zone: response file */
1720
1721	if (respfile) {
1722		int fd;
1723		fd = openLocal(respfile, O_RDONLY, tmpdir);
1724		if (fd < 0) {
1725			progerr(ERR_CANNOT_COPY_LOCAL, a_adminFile,
1726			    errno, strerror(errno));
1727			return (1);
1728		}
1729		(void) snprintf(respfilefd_path,
1730		    sizeof (respfilefd_path),
1731		    "/proc/self/fd/%d", fd);
1732		fds[maxfds++] = fd;
1733		arg[nargs++] = "-r";
1734		arg[nargs++] = respfilefd_path;
1735	}
1736
1737	/* add "-O addzonename" */
1738
1739	arg[nargs++] = "-O";
1740	arg[nargs++] = "addzonename";
1741
1742	/*
1743	 * add parent zone info/type
1744	 */
1745
1746	p = z_get_zonename();
1747	if ((p != NULL) && (*p != '\0')) {
1748			char	zn[MAXPATHLEN];
1749			(void) snprintf(zn, sizeof (zn),
1750			    "parent-zone-name=%s", p);
1751			arg[nargs++] = "-O";
1752			arg[nargs++] = strdup(zn);
1753	}
1754
1755	/* current zone type */
1756
1757	arg[nargs++] = "-O";
1758	if (z_running_in_global_zone() == B_TRUE) {
1759			char	zn[MAXPATHLEN];
1760			(void) snprintf(zn, sizeof (zn),
1761			    "parent-zone-type=%s",
1762			    TAG_VALUE_GLOBAL_ZONE);
1763			arg[nargs++] = strdup(zn);
1764	} else {
1765			char	zn[MAXPATHLEN];
1766			(void) snprintf(zn, sizeof (zn),
1767			    "parent-zone-type=%s",
1768			    TAG_VALUE_NONGLOBAL_ZONE);
1769			arg[nargs++] = strdup(zn);
1770	}
1771
1772	/* Add the pkgserv options */
1773	arg[nargs++] = "-O";
1774	arg[nargs++] = pkgmodeargument(a_tmpzn ? RUN_ONCE : pkgservergetmode());
1775
1776	/* add in the package stream file */
1777
1778	if (a_idsName != NULL) {
1779		int fd;
1780		fd = openLocal(a_idsName, O_RDONLY, tmpdir);
1781		if (fd < 0) {
1782			progerr(ERR_STREAM_UNAVAILABLE, a_idsName,
1783			    pkginst, strerror(errno));
1784			quit(1);
1785		}
1786		(void) snprintf(pkgstreamfd_path, sizeof (pkgstreamfd_path),
1787		    "/proc/self/fd/%d", fd);
1788		fds[maxfds++] = fd;
1789		arg[nargs++] = pkgstreamfd_path;
1790	} else {
1791		progerr(ERR_PKGZONEINSTALL_NO_STREAM);
1792		quit(1);
1793	}
1794
1795	/* add package instance name */
1796
1797	arg[nargs++] = pkginst;
1798
1799	/* terminate the argument list */
1800
1801	arg[nargs++] = NULL;
1802
1803	/*
1804	 * run the appropriate pkginstall command in the specified zone
1805	 */
1806
1807	if (debugFlag == B_TRUE) {
1808		echoDebug(DBG_ZONE_EXEC_ENTER, a_zoneName, arg[0]);
1809		for (n = 0; arg[n]; n++) {
1810			echoDebug(DBG_ARG, n, arg[n]);
1811		}
1812	}
1813
1814	/* terminate file descriptor list */
1815
1816	fds[maxfds] = -1;
1817
1818	/* exec command in zone */
1819
1820	n = z_zone_exec(a_zoneName, path, arg, (char *)NULL, (char *)NULL, fds);
1821
1822	echoDebug(DBG_ZONE_EXEC_EXIT, a_zoneName, arg[0], n, "");
1823
1824	/*
1825	 * close any files that were opened for use by the
1826	 * /proc/self/fd interface so they could be passed to programs
1827	 * via the z_zone_exec() interface
1828	 */
1829
1830	for (; maxfds > 0; maxfds--) {
1831		(void) close(fds[maxfds-1]);
1832	}
1833
1834	/* return results of pkginstall in zone execution */
1835
1836	return (n);
1837}
1838
1839/*
1840 * Name:	pkgInstall
1841 * Description:	Invoke pkginstall in the current zone to perform an install
1842 *		of a single package to the current zone or standalone system
1843 * Arguments:	a_altRoot - pointer to string representing the alternative
1844 *			root to use for the install
1845 *		a_idsName - pointer to string representing the data stream
1846 *			device (input data stream) containing the package to
1847 *			be installed.
1848 *		a_pkgDir - pointer to string representing the path to the
1849 *			directory containing the package
1850 *		a_altBinDir - pointer to string representing location of the
1851 *			pkginstall executable to run. If not NULL, then pass
1852 *			the path specified to the -b option to pkginstall.
1853 * Returns:	int	(see ckreturn() function for details)
1854 *		0 - success
1855 *		1 - package operation failed (fatal error)
1856 *		2 - non-fatal error (warning)
1857 *		3 - user selected quit (operation interrupted)
1858 *		4 - admin settings prevented operation
1859 *		5 - interaction required and -n (non-interactive) specified
1860 *		"10" will be added to indicate "immediate reboot required"
1861 *		"20" will be added to indicate "reboot after install required"
1862 * NOTE:	Both a_idsName and a_pkgDir are used to determine where the
1863 *		package to be installed is located. If a_idsName is != NULL
1864 *		then it must be the path to a device containing a package
1865 *		stream that contains the package to be installed. If a_idsName
1866 *		is == NULL then a_pkgDir must contain a full path to a directory
1867 *		that contains the package to be installed.
1868 */
1869
1870static int
1871pkgInstall(char *a_altRoot, char *a_idsName, char *a_pkgDir, char *a_altBinDir)
1872{
1873	char	*arg[MAXARGS];
1874	char	*p;
1875	char	path[PATH_MAX];
1876	char	buffer[256];
1877	int	n, nargs;
1878
1879	/* entry debugging info */
1880
1881	echoDebug(DBG_PKGINSTALL_ENTRY);
1882	echoDebug(DBG_PKGINSTALL_ARGS, PSTR(pkginst), PSTR(pkgdev.dirname),
1883	    PSTR(pkgdev.mount), PSTR(pkgdev.bdevice), PSTR(a_altRoot),
1884	    PSTR(a_idsName), PSTR(a_pkgDir));
1885
1886	/* generate full path to 'pkginstall' to run in zone */
1887
1888	(void) snprintf(path, sizeof (path), "%s/pkginstall",
1889	    a_altBinDir == (char *)NULL ? PKGBIN : a_altBinDir);
1890	/*
1891	 * generate argument list for call to pkginstall
1892	 */
1893
1894	/* start at argument 0 */
1895
1896	nargs = 0;
1897
1898	/* first argument is path to executable */
1899
1900	arg[nargs++] = path;
1901
1902	/*
1903	 * second argument is always: pass -O debug to pkginstall: debug mode
1904	 */
1905	if (debugFlag == B_TRUE) {
1906		arg[nargs++] = "-O";
1907		arg[nargs++] = "debug";
1908	}
1909
1910	arg[nargs++] = "-O";
1911	arg[nargs++] = pkgmodeargument(pkgservergetmode());
1912
1913	/*
1914	 * pkgadd -G: pass -G to pkginstall if:
1915	 *  - the -G option is specified on the pkgadd command line
1916	 *  - this package is marked 'this zone only':
1917	 *  -- package has SUNW_PKG_THISZONE=true, or
1918	 *  -- package has a request script
1919	 * Setting -G for pkginstall causes pkginstall to install the package
1920	 * in the target zone. If running in the global zone, will install the
1921	 * package and mark the package as installed "in the global zone only".
1922	 * If running in a non-global zone, will just install the package.
1923	 */
1924
1925	if (globalZoneOnly == B_TRUE) {
1926		arg[nargs++] = "-G";
1927	} else if (pkgPackageIsThisZone(pkginst) == B_TRUE) {
1928		arg[nargs++] = "-G";
1929	}
1930
1931	/* pkgadd -b dir: pass -b to pkginstall */
1932
1933	if (a_altBinDir != (char *)NULL) {
1934		arg[nargs++] = "-b";
1935		arg[nargs++] = a_altBinDir;
1936	}
1937
1938	/* pkgadd -B blocksize: pass -B to pkginstall */
1939
1940	if (rw_block_size != NULL) {
1941		arg[nargs++] = "-B";
1942		arg[nargs++] = rw_block_size;
1943	}
1944
1945	/* pkgadd -C: pass -C to pkginstall: disable checksum */
1946
1947	if (disableChecksum) {
1948		arg[nargs++] = "-C";
1949	}
1950
1951	/* pkgadd -A: pass -A to pkginstall: disable attribute checking */
1952
1953	if (disableAttributes) {
1954		arg[nargs++] = "-A";
1955	}
1956
1957	/*
1958	 * NONABI_SCRIPTS defined: pass -o to pkginstall; refers to a
1959	 * pkg requiring operator interaction during a procedure script
1960	 * (common before on1093)
1961	 */
1962
1963	if (old_pkg) {
1964		arg[nargs++] = "-o";
1965	}
1966
1967	/*
1968	 * PKG_NONABI_SYMLINKS defined: pass -y to pkginstall; process
1969	 * symlinks consistent with old behavior
1970	 */
1971
1972	if (old_symlinks) {
1973		arg[nargs++] = "-y";
1974	}
1975
1976	/*
1977	 * PKG_ABI_NAMELENGTH defined: pass -e to pkginstall; causes
1978	 * package name length to be restricted
1979	 */
1980
1981	if (ABI_namelength) {
1982		arg[nargs++] = "-e";
1983	}
1984
1985	/* pkgadd -S: pass -S to pkginstall: suppress copyright notices */
1986
1987	if (suppressCopyright) {
1988		arg[nargs++] = "-S";
1989	}
1990
1991	/* pkgadd -I: pass -I to pkginstall: initial install being performed */
1992
1993	if (init_install) {
1994		arg[nargs++] = "-I";
1995	}
1996
1997	/* pkgadd -M: pass -M to pkginstall: dont mount client file systems */
1998
1999	if (no_map_client) {
2000		arg[nargs++] = "-M";
2001	}
2002
2003	/* pkgadd -v: pass -v to pkginstall: trace scripts */
2004
2005	if (pkgverbose) {
2006		arg[nargs++] = "-v";
2007	}
2008
2009	/* pkgadd -z: pass -z to pkginstall: fresh install from pkg save area */
2010
2011	if (saveSpoolInstall) {
2012		arg[nargs++] = "-z";
2013	}
2014
2015	/*
2016	 * if running in a non-global zone and the 'hollow' attribute is
2017	 * passed in, then pass -h to pkginstall so that it knows how to
2018	 * handle hollow packages for this local zone.
2019	 */
2020
2021	if (!z_running_in_global_zone() && is_depend_pkginfo_DB()) {
2022		arg[nargs++] = "-h";
2023	}
2024
2025	/* pkgadd -t: pass -t to pkginstall: disable save spool area creation */
2026
2027	if (disableSaveSpool) {
2028		arg[nargs++] = "-t";
2029	}
2030
2031	/* if running pkgask, pass -i to pkginstall: running pkgask */
2032
2033	if (askflag) {
2034		arg[nargs++] = "-i";
2035	}
2036
2037	/* pkgadd -n (not pkgask): pass -n to pkginstall: noninteractive mode */
2038
2039	if (nointeract && !askflag) {
2040		arg[nargs++] = "-n";
2041	}
2042
2043	/* pkgadd -a admin: pass -a admin to pkginstall: admin file */
2044
2045	if (admnfile) {
2046		arg[nargs++] = "-a";
2047		arg[nargs++] = admnfile;
2048	}
2049
2050	/* pkgadd -D dryrun: pass -D dryrun to pkginstall: dryrun mode/file */
2051
2052	if (pkgdrtarg) {
2053		arg[nargs++] = "-D";
2054		arg[nargs++] = pkgdrtarg;
2055	}
2056
2057	/* pkgadd -c cont: pass -c cont to pkginstall: continuation file */
2058
2059	if (pkgcontsrc) {
2060		arg[nargs++] = "-c";
2061		arg[nargs++] = pkgcontsrc;
2062	}
2063
2064	/* pkgadd -V vfstab: pass -V vfstab to pkginstall: alternate vfstab */
2065
2066	if (vfstab_file) {
2067		arg[nargs++] = "-V";
2068		arg[nargs++] = vfstab_file;
2069	}
2070
2071	/* pkgadd -r resp: pass -r resp to pkginstall: response file */
2072
2073	if (respfile) {
2074		arg[nargs++] = "-r";
2075		arg[nargs++] = respfile;
2076	}
2077
2078	/* pkgadd -R root: pass -R root to pkginstall: alternative root */
2079
2080	if (a_altRoot && *a_altRoot) {
2081		arg[nargs++] = "-R";
2082		arg[nargs++] = a_altRoot;
2083	}
2084
2085	/*
2086	 * If input data stream is available,
2087	 * - add: -d ids_name -p number_of_parts
2088	 * else,
2089	 * - add: -d device -m mount [-f type]
2090	 */
2091
2092	if (a_idsName != NULL) {
2093		arg[nargs++] = "-d";
2094		arg[nargs++] = a_idsName;
2095		arg[nargs++] = "-p";
2096		ds_close(1);
2097		ds_putinfo(buffer, sizeof (buffer));
2098		arg[nargs++] = buffer;
2099	} else if (pkgdev.mount != NULL) {
2100		arg[nargs++] = "-d";
2101		arg[nargs++] = pkgdev.bdevice;
2102		arg[nargs++] = "-m";
2103		arg[nargs++] = pkgdev.mount;
2104		if (pkgdev.fstyp != NULL) {
2105			arg[nargs++] = "-f";
2106			arg[nargs++] = pkgdev.fstyp;
2107		}
2108	}
2109
2110	/*
2111	 * add parent zone info/type
2112	 */
2113
2114	p = z_get_zonename();
2115	if ((p != NULL) && (*p != '\0')) {
2116			char	zn[MAXPATHLEN];
2117			(void) snprintf(zn, sizeof (zn),
2118			    "parent-zone-name=%s", p);
2119			arg[nargs++] = "-O";
2120			arg[nargs++] = strdup(zn);
2121	}
2122
2123	/* current zone type */
2124
2125	arg[nargs++] = "-O";
2126	if (z_running_in_global_zone() == B_TRUE) {
2127			char	zn[MAXPATHLEN];
2128			(void) snprintf(zn, sizeof (zn),
2129			    "parent-zone-type=%s",
2130			    TAG_VALUE_GLOBAL_ZONE);
2131			arg[nargs++] = strdup(zn);
2132	} else {
2133			char	zn[MAXPATHLEN];
2134			(void) snprintf(zn, sizeof (zn),
2135			    "parent-zone-type=%s",
2136			    TAG_VALUE_NONGLOBAL_ZONE);
2137			arg[nargs++] = strdup(zn);
2138	}
2139
2140	/* pass -N to pkginstall: program name to report */
2141
2142	arg[nargs++] = "-N";
2143	arg[nargs++] = get_prog_name();
2144
2145	/* add package directory name */
2146
2147	arg[nargs++] = a_pkgDir;
2148
2149	/* add package instance name */
2150
2151	arg[nargs++] = pkginst;
2152
2153	/* terminate the argument list */
2154
2155	arg[nargs++] = NULL;
2156
2157	/*
2158	 * run the appropriate pkginstall command in the specified zone
2159	 */
2160
2161	if (debugFlag == B_TRUE) {
2162		echoDebug(DBG_ZONE_EXEC_ENTER, "global", arg[0]);
2163		for (n = 0; arg[n]; n++) {
2164			echoDebug(DBG_ARG, n, arg[n]);
2165		}
2166	}
2167
2168	/* execute pkginstall command */
2169
2170	n = pkgexecv(NULL, NULL, NULL, NULL, arg);
2171
2172	/* return results of pkginstall execution */
2173
2174	return (n);
2175}
2176
2177/*
2178 *  function to clear out any exisiting error return conditions that may have
2179 *  been set by previous calls to ckreturn()
2180 */
2181static void
2182resetreturn()
2183{
2184	admnflag = 0;	/* != 0 if any pkg op admin setting failure (4) */
2185	doreboot = 0;	/* != 0 if reboot required after installation (>= 10) */
2186	failflag = 0;	/* != 0 if fatal error has occurred (1) */
2187	intrflag = 0;	/* != 0 if user selected quit (3) */
2188	ireboot = 0;	/* != 0 if immediate reboot required (>= 20) */
2189	nullflag = 0;	/* != 0 if admin interaction required (5) */
2190	warnflag = 0;	/* != 0 if non-fatal error has occurred (2) */
2191	interrupted = 0;	/* last pkg op was quit (1,2,3,4,5) */
2192	needconsult = 0;	/* essential ask admin now (1,2,3,5) */
2193}
2194
2195/*
2196 *  function which checks the indicated return value
2197 *  and indicates disposition of installation
2198 */
2199static void
2200ckreturn(int retcode)
2201{
2202	/*
2203	 * entry debugging info
2204	 */
2205
2206	echoDebug(DBG_PKGADD_CKRETURN, retcode, PSTR(pkginst));
2207
2208	/* reset needconsult so it only reflects this call to ckreturn */
2209	needconsult = 0;
2210
2211	switch (retcode) {
2212	case  0:	/* successful */
2213	case 10:
2214	case 20:
2215		break; /* empty case */
2216
2217	case  1:	/* package operation failed (fatal error) */
2218	case 11:
2219	case 21:
2220		failflag++;
2221		interrupted++;
2222		needconsult++;
2223		break;
2224
2225	case  2:	/* non-fatal error (warning) */
2226	case 12:
2227	case 22:
2228		warnflag++;
2229		interrupted++;
2230		needconsult++;
2231		break;
2232
2233	case  3:	/* user selected quit; operation interrupted */
2234	case 13:
2235	case 23:
2236		intrflag++;
2237		interrupted++;
2238		needconsult++;
2239		break;
2240
2241	case  4:	/* admin settings prevented operation */
2242	case 14:
2243	case 24:
2244		admnflag++;
2245		interrupted++;
2246		break;
2247
2248	case  5:	/* administration: interaction req (no -n) */
2249	case 15:
2250	case 25:
2251		nullflag++;
2252		interrupted++;
2253		needconsult++;
2254		break;
2255
2256	default:
2257		failflag++;
2258		interrupted++;
2259		needconsult++;
2260		return;
2261	}
2262
2263	if (retcode >= 20) {
2264		ireboot++;
2265	} else if (retcode >= 10) {
2266		doreboot++;
2267	}
2268}
2269
2270static void
2271usage(void)
2272{
2273	char *prog = get_prog_name();
2274
2275	if (askflag) {
2276		(void) fprintf(stderr, ERR_USAGE_PKGASK, prog);
2277	} else if (z_running_in_global_zone() == B_FALSE) {
2278		(void) fprintf(stderr, ERR_USAGE_PKGADD_NONGLOBALZONE,
2279		    prog, prog);
2280	} else {
2281		(void) fprintf(stderr, ERR_USAGE_PKGADD_GLOBALZONE,
2282		    prog, prog);
2283	}
2284}
2285
2286/*
2287 * Name:	check_applicability
2288 * Description:	determine if a package is installable in this zone; that is,
2289 *		does the scope of install conflict with existing installation
2290 *		or can the package be installed
2291 * Arguments:	a_packageDir - [RO, *RO] - (char *)
2292 *			Pointer to string representing the directory where the
2293 *			package is located
2294 *		a_pkgInst - [RO, *RO] - (char *)
2295 *			Pointer to string representing the name of the package
2296 *			to check
2297 *		a_rootPath - [RO, *RO] - (char *)
2298 *			Pointer to string representing path to the root of the
2299 *			file system where the package is to be installed - this
2300 *			is usually the same as the "-R" argument to pkgadd
2301 *		a_flags - [RO, *RO] - (CAF_T)
2302 *			Flags set by the caller to indicate the conditions
2303 *			under which the package is to be installed:
2304 *				CAF_IN_GLOBAL_ZONE - in global zone
2305 *				CAF_SCOPE_GLOBAL - -G specified
2306 * Returns:	boolean_t
2307 *			B_TRUE - the package can be installed
2308 *			B_FALSE - the package can not be installed
2309 */
2310
2311static boolean_t
2312check_applicability(char *a_packageDir, char *a_pkgInst, char *a_rootPath,
2313    CAF_T a_flags)
2314{
2315	FILE		*pkginfoFP;
2316	FILE		*pkgmapFP;
2317	boolean_t	all_zones;	/* pkg is "all zones" only */
2318	boolean_t	in_gz_only;	/* pkg installed in global zone only */
2319	boolean_t	is_hollow;	/* pkg is "hollow" */
2320	boolean_t	pkg_installed;	/* pkg is installed */
2321	boolean_t	this_zone;	/* pkg is "this zone" only */
2322	boolean_t	reqfile_found = B_FALSE;
2323	char		instPkg[PKGSIZ+1];	/* installed pkg instance nam */
2324	char		instPkgPath[PATH_MAX];	/* installed pkg toplevel dir */
2325	char		pkginfoPath[PATH_MAX];	/* pkg 2 install pkginfo file */
2326	char		pkgmapPath[PATH_MAX];	/* pkg 2 install pkgmap file */
2327	char		pkgpath[PATH_MAX];	/* pkg 2 install toplevel dir */
2328	int		len;
2329	char		line[LINE_MAX];
2330
2331	/* entry assertions */
2332
2333	assert(a_packageDir != (char *)NULL);
2334	assert(*a_packageDir != '\0');
2335	assert(a_pkgInst != (char *)NULL);
2336	assert(*a_pkgInst != '\0');
2337
2338	/* normalize root path */
2339
2340	if (a_rootPath == (char *)NULL) {
2341		a_rootPath = "";
2342	}
2343
2344	/* entry debugging info */
2345
2346	echoDebug(DBG_CHECKAPP_ENTRY);
2347	echoDebug(DBG_CHECKAPP_ARGS, a_pkgInst, a_packageDir, a_rootPath);
2348
2349	/*
2350	 * calculate paths to various objects
2351	 */
2352
2353	/* path to package to be installed top level (main) directory */
2354
2355	len = snprintf(pkgpath, sizeof (pkgpath), "%s/%s", a_packageDir,
2356	    a_pkgInst);
2357	if (len > sizeof (pkgpath)) {
2358		progerr(ERR_CREATE_PATH_2, a_packageDir, a_pkgInst);
2359		return (B_FALSE);
2360	}
2361
2362	/* error if package top level directory does not exist */
2363
2364	if (isdir(pkgpath) != 0) {
2365		progerr(ERR_NO_PKGDIR, pkgpath, a_pkgInst, strerror(errno));
2366		return (B_FALSE);
2367	}
2368
2369	/* path to pkginfo file within the package to be installed */
2370
2371	len = snprintf(pkginfoPath, sizeof (pkginfoPath), "%s/pkginfo",
2372	    pkgpath);
2373	if (len > sizeof (pkginfoPath)) {
2374		progerr(ERR_CREATE_PATH_2, pkgpath, "pkginfo");
2375		return (B_FALSE);
2376	}
2377
2378	/* path to highest instance of package currently installed */
2379
2380	pkgLocateHighestInst(instPkgPath, sizeof (instPkgPath),
2381	    instPkg, sizeof (instPkg), a_rootPath, a_pkgInst);
2382
2383	/*
2384	 * gather information from this package's pkginfo file
2385	 */
2386
2387	pkginfoFP = fopen(pkginfoPath, "r");
2388
2389	if (pkginfoFP == (FILE *)NULL) {
2390		progerr(ERR_NO_PKG_INFOFILE, a_pkgInst, pkginfoPath,
2391		    strerror(errno));
2392		return (B_FALSE);
2393	}
2394
2395	/* determine "HOLLOW" setting for this package */
2396
2397	is_hollow = pkginfoParamTruth(pkginfoFP, PKG_HOLLOW_VARIABLE,
2398	    "true", B_FALSE);
2399
2400	/* determine "ALLZONES" setting for this package */
2401
2402	all_zones = pkginfoParamTruth(pkginfoFP, PKG_ALLZONES_VARIABLE,
2403	    "true", B_FALSE);
2404
2405	/* determine "THISZONE" setting for this package */
2406
2407	this_zone = pkginfoParamTruth(pkginfoFP, PKG_THISZONE_VARIABLE,
2408	    "true", B_FALSE);
2409
2410	/* close pkginfo file */
2411
2412	(void) fclose(pkginfoFP);
2413
2414	/*
2415	 * If request file is not found, it may be in the datastream which
2416	 * is not yet unpacked. Check in the pkgmap file.
2417	 */
2418	if (isfile(pkgpath, REQUEST_FILE) != 0) {
2419
2420		/* path to pkgmap file within the package to be installed */
2421		(void) snprintf(pkgmapPath, sizeof (pkgmapPath), "%s/pkgmap",
2422		    pkgpath);
2423
2424		pkgmapFP = fopen(pkgmapPath, "r");
2425
2426		if (pkgmapFP == NULL) {
2427			progerr(ERR_NO_PKG_MAPFILE, a_pkgInst,
2428			    pkgmapPath, strerror(errno));
2429			return (B_FALSE);
2430		}
2431
2432		while (fgets(line, LINE_MAX, pkgmapFP) != NULL) {
2433			if (strstr(line, " i request") != NULL) {
2434				reqfile_found = B_TRUE;
2435				break;
2436			}
2437		}
2438		(void) fclose(pkgmapFP);
2439	} else {
2440		reqfile_found = B_TRUE;
2441	}
2442
2443	/*
2444	 * If this package is not marked for installation in this zone only,
2445	 * check to see if this package has a request script. If this package
2446	 * does have a request script, then mark the package for installation
2447	 * in this zone only. Any package with a request script cannot be
2448	 * installed outside of the zone the pkgadd command is being run in,
2449	 * nor can such a package be installed as part of a new zone install.
2450	 * A new zone install must be non-interactive, which is required
2451	 * by all packages integrated into the Solaris WOS.
2452	 */
2453
2454	if ((!this_zone) && (reqfile_found)) {
2455		if (a_flags & CAF_IN_GLOBAL_ZONE) {
2456			echoDebug(DBG_CHECKAPP_THISZONE_REQUEST, a_pkgInst);
2457		}
2458		this_zone = B_TRUE;
2459	}
2460
2461	/*
2462	 * If this package is already installed, see if the current installation
2463	 * of the package has a request file - if it does, then act as though
2464	 * the current package to be added has a request file - install the
2465	 * package in the current zone only.
2466	 */
2467
2468	if ((!this_zone) && (instPkgPath[0] != '\0') &&
2469	    (isfile(instPkgPath, REQUEST_FILE) == 0)) {
2470		if (a_flags & CAF_IN_GLOBAL_ZONE) {
2471			echoDebug(DBG_CHECKAPP_THISZONE_INSTREQ,
2472			    a_pkgInst, instPkg);
2473		}
2474		this_zone = B_TRUE;
2475	}
2476
2477	/* gather information from the global zone only file */
2478
2479	in_gz_only = B_FALSE;
2480	if (a_flags & CAF_IN_GLOBAL_ZONE) {
2481		in_gz_only = pkgIsPkgInGzOnly(a_rootPath, a_pkgInst);
2482	}
2483
2484	/* determine if this package is currently installed */
2485
2486	pkg_installed = pkginfoIsPkgInstalled((struct pkginfo **)NULL,
2487	    a_pkgInst);
2488
2489	/*
2490	 * verify package applicability based on information gathered,
2491	 * and validate the three SUNW_PKG_ options:
2492	 *
2493	 * -----------|--------------|-------------|-------------|-----------
2494	 * - - - - - -| GLOBAL ZONE -| GLOBAL ZONE | LOCAL ZONE	 | LOCAL ZONE
2495	 * - - - - - -|	- - pkgadd - | pkgadd -G   | pkgadd	 | pkgadd -G
2496	 * ----1------|--------------|-------------|-------------|------------
2497	 * ALLZONES f | add to gz    | add to gz   | add to ls	 | add to ls
2498	 * HOLLOW   f | current lz   | not to curr | only - - - -| only - - -
2499	 * THISZONE f | futr lz - - -| or futr lz  | - - - - - - | - - - - - -
2500	 * ----2------|--------------|-------------|-------------|------------
2501	 * ALLZONES T | add to gz    | operation   | operation	 | operation
2502	 * HOLLOW   f | current lz   | not allowed | not allowed | not allowed
2503	 * THISZONE f | future lz    | - - - - - - | - - - - - - | - - - - - -
2504	 * ----3------|--------------|-------------|-------------|------------
2505	 * ALLZONES T | add to gz    | operation   | operation	 | operation
2506	 * HOLLOW   T | pkg db only  | not allowed | not allowed | not allowed
2507	 * THISZONE f | curr/futr lz | - - - - - - | - - - - - - | - - - - - -
2508	 * ----4------|--------------|-------------|-------------|------------
2509	 * ALLZONES T | bad option   | bad option  | bad option	 | bad option
2510	 * HOLLOW   * | combo - - - -| combo - - - | combo - - - | combo - -
2511	 * THISZONE T |	- - - - - - -|- - - - - - -|- - - - - - -|- - - - - -
2512	 * ----5------|--------------|-------------|-------------|------------
2513	 * ALLZONES f | bad option   | bad option  | bad option	 | bad option
2514	 * HOLLOW   T | combo - - - -| combo - - - | combo - - - | combo - - -
2515	 * THISZONE * | - - - - - - -| - - - - - - | - - - - - - | - - - - - -
2516	 * ----6------|--------------|-------------|-------------|------------
2517	 * ALLZONES f | add to gz    | add to gz   | add to lz	 | add to lz
2518	 * HOLLOW   f | not current  | not current | only - - -	 | only - - -
2519	 * THISZONE T | or future lz | or futr lz  | - - - - - - | - - - - - -
2520	 * -----------|--------------|-------------|-------------|-----------
2521	 */
2522
2523	/* pkg "all zones" && "this zone" (#4) */
2524
2525	if (all_zones && this_zone) {
2526		progerr(ERR_ALLZONES_AND_THISZONE, a_pkgInst,
2527		    PKG_ALLZONES_VARIABLE, PKG_THISZONE_VARIABLE);
2528		return (B_FALSE);
2529	}
2530
2531	/* pkg "!all zones" && "hollow" (#5) */
2532
2533	if ((!all_zones) && is_hollow) {
2534		progerr(ERR_NOW_ALLZONES_AND_HOLLOW, a_pkgInst,
2535		    PKG_ALLZONES_VARIABLE, PKG_HOLLOW_VARIABLE);
2536		return (B_FALSE);
2537	}
2538
2539	/* pkg ALLZONES=true & not running in global zone (#2/#3) */
2540
2541	if (all_zones && (!(a_flags & CAF_IN_GLOBAL_ZONE))) {
2542		progerr(ERR_ALLZONES_AND_IN_LZ, a_pkgInst);
2543		return (B_FALSE);
2544	}
2545
2546	/* pkg "in gz only" & pkg "NOT installed" */
2547
2548	if (in_gz_only && (!pkg_installed)) {
2549		/* MAKE A WARNING */
2550		echo(ERR_IN_GZ_AND_NOT_INSTALLED, a_pkgInst,
2551		    pkgGetGzOnlyPath());
2552	}
2553
2554	/* pkg ALLZONES=true & pkg "in gz only" & pkg "is installed" */
2555
2556	if (all_zones && in_gz_only && pkg_installed) {
2557		progerr(ERR_IN_GZ_AND_ALLZONES_AND_INSTALLED, a_pkgInst);
2558		return (B_FALSE);
2559	}
2560
2561	/* pkg ALLZONES=true && -G specified (#2/#3) */
2562
2563	if (all_zones && (a_flags & CAF_SCOPE_GLOBAL)) {
2564		progerr(ERR_ALLZONES_AND_G_USED, a_pkgInst);
2565		return (B_FALSE);
2566	}
2567
2568	/* pkg "!this zone" && "in gz only" & -G not specified */
2569
2570	if ((!this_zone) && in_gz_only && (!(a_flags & CAF_SCOPE_GLOBAL))) {
2571		progerr(ERR_IN_GZ_AND_NO_G_USED, a_pkgInst);
2572		return (B_FALSE);
2573	}
2574
2575	/*
2576	 * If this package is marked 'this zone only', then mark the package
2577	 * as "add to this zone only". This is referenced by the various
2578	 * add_package_... functions to determine if the package should be
2579	 * added to the current zone, or to all zones, depending on the
2580	 * zone in which the command is being run.
2581	 */
2582
2583	if (this_zone) {
2584		pkgAddThisZonePackage(a_pkgInst);
2585	}
2586
2587	return (B_TRUE);
2588}
2589
2590/*
2591 * Name:	create_zone_adminfile
2592 * Description: Given a zone temporary directory and optionally an existing
2593 *		administration file, generate an administration file that
2594 *		can be used to perform "non-interactive" operations in a
2595 *		non-global zone.
2596 * Arguments:	r_zoneAdminFile - pointer to handle that will contain a
2597 *			string representing the path to the temporary
2598 *			administration file created - this must be NULL
2599 *			before the first call to this function - on
2600 *			subsequent calls if the pointer is NOT null then
2601 *			the existing string will NOT be overwritten.
2602 *		a_zoneTempDir - pointer to string representing the path
2603 *			to the zone temporary directory to create the
2604 *			temporary administration file in
2605 *		a_admnfile - pointer to string representing the path to
2606 *			an existing "user" administration file - the
2607 *			administration file created will contain the
2608 *			settings contained in this file, modified as
2609 *			appropriate to supress any interaction;
2610 *			If this is == NULL then the administration file
2611 *			created will not contain any extra settings
2612 * Returns:	void
2613 * NOTE:	Any string returned is placed in new storage for the
2614 *		calling method. The caller must use 'free' to dispose
2615 *		of the storage once the string is no longer needed.
2616 * NOTE:	On any error this function will call 'quit(1)'
2617 */
2618
2619static void
2620create_zone_adminfile(char **r_zoneAdminFile, char *a_zoneTempDir,
2621    char *a_admnfile)
2622{
2623	boolean_t	b;
2624
2625	/* entry assertions */
2626
2627	assert(r_zoneAdminFile != (char **)NULL);
2628	assert(a_zoneTempDir != (char *)NULL);
2629	assert(*a_zoneTempDir != '\0');
2630
2631	/* entry debugging info */
2632
2633	echoDebug(DBG_CREATE_ZONE_ADMINFILE, a_zoneTempDir, PSTR(a_admnfile));
2634
2635	/* if temporary name already exists, do not overwrite */
2636
2637	if (*r_zoneAdminFile != (char *)NULL) {
2638		return;
2639	}
2640
2641	/* create temporary name */
2642
2643	*r_zoneAdminFile = tempnam(a_zoneTempDir, "zadmn");
2644	b = z_create_zone_admin_file(*r_zoneAdminFile, a_admnfile);
2645	if (b == B_FALSE) {
2646		progerr(ERR_CREATE_TMPADMIN, *r_zoneAdminFile,
2647		    strerror(errno));
2648		quit(1);
2649		/* NOTREACHED */
2650	}
2651
2652	echoDebug(DBG_CREATED_ZONE_ADMINFILE, *r_zoneAdminFile);
2653}
2654
2655/*
2656 * Name:	create_zone_tempdir
2657 * Description: Given a system temporary directory, create a "zone" specific
2658 *		temporary directory and return the path to the directory
2659 *		created.
2660 * Arguments:	r_zoneTempDir - pointer to handle that will contain a
2661 *			string representing the path to the temporary
2662 *			directory created - this must be NULL before the
2663 *			first call to this function - on subsequent calls
2664 *			if the pointer is NOT null then the existing string
2665 *			will NOT be overwritten.
2666 *		a_zoneTempDir - pointer to string representing the path
2667 *			to the system temporary directory to create the
2668 *			temporary zone directory in
2669 * Returns:	void
2670 * NOTE:	Any string returned is placed in new storage for the
2671 *		calling method. The caller must use 'free' to dispose
2672 *		of the storage once the string is no longer needed.
2673 * NOTE:	On any error this function will call 'quit(1)'
2674 * NOTE:	This function calls "quitSetZoneTmpdir" on success to
2675 *		register the directory created with quit() so that the
2676 *		directory will be automatically deleted on exit.
2677 */
2678
2679static void
2680create_zone_tempdir(char **r_zoneTempDir, char *a_tmpdir)
2681{
2682	boolean_t	b;
2683
2684	/* entry assertions */
2685
2686	assert(r_zoneTempDir != (char **)NULL);
2687	assert(a_tmpdir != (char *)NULL);
2688	assert(*a_tmpdir != '\0');
2689
2690	/* entry debugging info */
2691
2692	echoDebug(DBG_CREATE_ZONE_TEMPDIR, a_tmpdir);
2693
2694	/* if temporary directory already exists, do not overwrite */
2695
2696	if (*r_zoneTempDir != (char *)NULL) {
2697		return;
2698	}
2699
2700	/* create temporary directory */
2701
2702	b = setup_temporary_directory(r_zoneTempDir, a_tmpdir, "ztemp");
2703	if (b == B_FALSE) {
2704		progerr(ERR_ZONETEMPDIR, a_tmpdir, strerror(errno));
2705		quit(1);
2706		/* NOTREACHED */
2707	}
2708
2709	/* register with quit() so directory is removed on exit */
2710
2711	quitSetZoneTmpdir(*r_zoneTempDir);
2712
2713	/* exit debugging info */
2714
2715	echoDebug(DBG_CREATED_ZONE_TEMPDIR, *r_zoneTempDir);
2716}
2717
2718/*
2719 * Name:	continue_installation
2720 * Description: Called from within a loop that is installing packages,
2721 *		this function examines various global variables and decides
2722 *		whether or not to ask an appropriate question, and wait for
2723 *		and appropriate reply.
2724 * Arguments:	<<global variables>>
2725 * Returns:	B_TRUE - continue processing with next package
2726 *		B_FALSE - do not continue processing with next package
2727 */
2728
2729static boolean_t
2730continue_installation(void)
2731{
2732	char	ans[MAX_INPUT];
2733	int	n;
2734
2735	/* return TRUE if not interrupted */
2736
2737	if (!interrupted) {
2738		return (B_TRUE);
2739	}
2740
2741	/*
2742	 * process interrupted - determine whether or not to continue
2743	 */
2744
2745	/* output appropriate interrupted message */
2746
2747	if (askflag) {
2748		echo(npkgs == 1 ? MSG_1MORE_PROC : MSG_MORE_PROC, npkgs);
2749	} else {
2750		echo(npkgs == 1 ? MSG_1MORE_INST : MSG_MORE_INST, npkgs);
2751	}
2752
2753	/* if running with no interaction (-n) do not ask question */
2754
2755	if (nointeract) {
2756		/* if admin required return 'dont continue' */
2757		if (needconsult) {
2758			return (B_FALSE);
2759		}
2760		ckquit = 1;
2761		return (B_TRUE);
2762	}
2763
2764	/* interaction possible: ask question */
2765
2766	ckquit = 0;
2767	n = ckyorn(ans, NULL, NULL, NULL, ASK_CONTINUE_ADD);
2768	if (n != 0) {
2769		quit(n);
2770		/* NOTREACHED */
2771	}
2772	ckquit = 1;
2773	if (strchr("yY", *ans) == NULL) {
2774		return (B_FALSE);
2775	}
2776	return (B_TRUE);
2777}
2778
2779/*
2780 * package can be in a number of formats:
2781 * - file containing package stream (pkgadd -d file [pkgs])
2782 * - directory containing packages (pkgadd -d /dir [pkgs])
2783 * - device containing packages (pkgadd -d diskette1 [pkgs])
2784 * non-global zones can be passed open files and strings as arguments
2785 * - for file containing package stream
2786 * -- the stream can be passed directly to the non-global zone
2787 * - for directory
2788 * -- convert packages to datastream to pass to the non-global zone
2789 * - for device
2790 * -- ?
2791 */
2792
2793static boolean_t
2794unpack_and_check_packages(char **a_pkgList, char *a_idsName, char *a_packageDir)
2795{
2796	int	savenpkgs = npkgs;
2797	int	i;
2798	CAF_T	flags = 0;
2799
2800	/* entry assertions */
2801
2802	assert(a_pkgList != (char **)NULL);
2803
2804	/* entry debugging info */
2805
2806	echoDebug(DBG_UNPACKCHECK_ENTRY);
2807	echoDebug(DBG_UNPACKCHECK_ARGS, PSTR(a_idsName), PSTR(a_packageDir));
2808
2809	/*
2810	 * set flags for applicability check
2811	 */
2812
2813	/* determine if running in the global zone */
2814
2815	if (z_running_in_global_zone() == B_TRUE) {
2816		flags |= CAF_IN_GLOBAL_ZONE;
2817	}
2818
2819	/* set -G flag */
2820
2821	if (globalZoneOnly == B_TRUE) {
2822		flags |= CAF_SCOPE_GLOBAL;
2823	}
2824
2825	/*
2826	 * for each package to install:
2827	 * - if packages from datastream, unpack package into package dir
2828	 * - check applicability of installing package on this system/zone
2829	 */
2830
2831	for (i = 0; (pkginst = a_pkgList[i]) != NULL; i++) {
2832		if (a_idsName != (char *)NULL) {
2833			/* create stream out of package if not already one */
2834			if (unpack_package_from_stream(a_idsName, pkginst,
2835			    a_packageDir) == B_FALSE) {
2836				progerr(ERR_CANNOT_UNPACK_PKGSTRM,
2837				    PSTR(pkginst), PSTR(a_idsName),
2838				    PSTR(a_packageDir));
2839
2840				npkgs = savenpkgs;
2841				return (B_FALSE);
2842			}
2843		} else {
2844			echoDebug(DBG_PKG_IN_DIR, pkginst, a_packageDir);
2845		}
2846
2847		/* check package applicability */
2848		if (check_applicability(a_packageDir,
2849		    pkginst, get_inst_root(), flags) == B_FALSE) {
2850			progerr(ERR_PKG_NOT_INSTALLABLE, pkginst);
2851			npkgs = savenpkgs;
2852			return (B_FALSE);
2853		}
2854		npkgs--;
2855	}
2856
2857	npkgs = savenpkgs;
2858	return (B_TRUE);
2859}
2860
2861/*
2862 * returns:
2863 *	B_TRUE - package list generated
2864 *	B_FALSE - failed to generate package list
2865 *	Will call quit(n) on fatal error.
2866 */
2867
2868static boolean_t
2869get_package_list(char ***r_pkgList, char **a_argv, char *a_categories,
2870    char **a_categoryList, char *a_idsName, int *r_repeat)
2871{
2872	int		n;
2873
2874	/* entry assertions */
2875
2876	assert(r_repeat != (int *)NULL);
2877
2878	/* entry debugging info */
2879
2880	echoDebug(DBG_GETPKGLIST_ENTRY);
2881	echoDebug(DBG_GETPKGLIST_ARGS, PSTR(a_idsName), PSTR(pkgdev.dirname),
2882	    *r_repeat);
2883
2884	/*
2885	 * get the list of the packages to add
2886	 */
2887
2888	n = pkgGetPackageList(r_pkgList, a_argv, optind, a_categories,
2889	    a_categoryList, &pkgdev);
2890
2891	switch (n) {
2892		case -1:	/* no packages found */
2893			echoDebug(DBG_PKGLIST_NONFOUND, PSTR(a_idsName),
2894			    pkgdev.dirname);
2895			return (B_FALSE);
2896
2897		case 0:		/* packages found */
2898			break;
2899
2900		default:	/* "quit" error */
2901			echoDebug(DBG_PKGLIST_ERROR, PSTR(a_idsName),
2902			    pkgdev.dirname, n);
2903			quit(n);
2904			/* NOTREACHED */
2905	}
2906
2907	/* order package list if input data stream specified */
2908
2909	if (a_idsName) {
2910		ds_order(*r_pkgList);
2911	}
2912
2913	return (B_TRUE);
2914}
2915
2916/*
2917 * Name:	install_in_one_zone
2918 * Description:	Install a single package in a single zone
2919 * Arguments:	a_zoneName - pointer to string representing the name of the
2920 *			zone to install the package into.
2921 *		a_idsName - pointer to string representing the data stream
2922 *			device (input data stream) containing the package to
2923 *			be installed.
2924 *			If this is == NULL the package is assumed to be
2925 *			spooled in the zone temporary directory.
2926 *		a_zoneAdminFile - pointer to string representing the admin
2927 *			file to pass to pkginstall when installing the package.
2928 *			If this is == NULL no admin file is given to pkginstall.
2929 *		a_zoneTempDir - pointer to string representing the temporary
2930 *			directory in which spooled packages can be found if
2931 *			a_idsName is == NULL.
2932 *		a_altBinDir - pointer to string representing an alternative
2933 *			binary location directory to pass to pkginstall.
2934 *			If this is == NULL no alternative binary location is
2935 *			passed to pkginstall.
2936 *		a_scratchName - pointer to string representing the name of the
2937 *			scratch zone to use for installation.
2938 *		a_zoneState - state of the zone; must be mounted or running.
2939 *		a_tmpzn - B_TRUE when this zone is booted by the package
2940 *			command or B_FALSE if it was running before.
2941 * Returns:	void
2942 * NOTE:	As a side effect, "ckreturn" is called on the result returned
2943 *		from running 'pkginstall' in the zone; this sets several global
2944 *		variables which allows the caller to determine the result of
2945 *		the installation operation.
2946 */
2947
2948static void
2949install_in_one_zone(char *a_zoneName, char *a_idsName,
2950    char *a_zoneAdminFile, char *a_zoneTempDir,
2951    char *a_altBinDir, zone_state_t a_zoneState, boolean_t a_tmpzn)
2952{
2953	char	zoneStreamName[PATH_MAX] = {'\0'};
2954	int	n;
2955
2956	/* entry assertions */
2957
2958	assert(a_zoneName != (char *)NULL);
2959	assert(*a_zoneName != '\0');
2960
2961	/* entry debugging info */
2962
2963	echoDebug(DBG_INSTINONEZONE_ENTRY);
2964	echoDebug(DBG_INSTINONEZONE_ARGS, a_zoneName, PSTR(a_idsName),
2965	    PSTR(a_zoneAdminFile), PSTR(a_zoneTempDir),
2966	    PSTR(a_altBinDir));
2967
2968	/* echo operation to perform to stdout */
2969
2970	echo(MSG_INSTALL_PKG_IN_ZONE, pkginst, a_zoneName);
2971
2972	/* determine path to the package stream */
2973
2974	if (a_idsName == (char *)NULL) {
2975		/* locate temp stream created earlier */
2976		(void) snprintf(zoneStreamName, sizeof (zoneStreamName),
2977		    "%s/%s.dstream", a_zoneTempDir, pkginst);
2978	} else {
2979		/* use stream passed in on command line */
2980		(void) snprintf(zoneStreamName, sizeof (zoneStreamName),
2981		    "%s", a_idsName);
2982	}
2983
2984	echoDebug(DBG_INSTALL_IN_ZONE, pkginst, a_zoneName, zoneStreamName);
2985
2986	n = pkgZoneInstall(a_zoneName, a_zoneState, zoneStreamName,
2987	    a_altBinDir, a_zoneAdminFile, a_tmpzn);
2988
2989	/* set success/fail condition variables */
2990
2991	ckreturn(n);
2992
2993	/* exit debugging info */
2994
2995	echoDebug(DBG_INSTALL_FLAG_VALUES, "after install", admnflag, doreboot,
2996	    failflag, interrupted, intrflag, ireboot, needconsult,
2997	    nullflag, warnflag);
2998}
2999
3000/*
3001 * Name:	install_in_zones
3002 * Description:	Install a single package in the zones that are running from
3003 *		a list of zones
3004 * Arguments:	a_zlst - list of zones to install the package into
3005 *		a_idsName - pointer to string representing the data stream
3006 *			device (input data stream) containing the package to
3007 *			be installed.
3008 *			If this is == NULL the package is assumed to be
3009 *			spooled in the zone temporary directory.
3010 *		a_altBinDir - pointer to string representing an alternative
3011 *			binary location directory to pass to pkginstall.
3012 *			If this is == NULL no alternative binary location is
3013 *			passed to pkginstall.
3014 *		a_zoneAdminFile - pointer to string representing the admin
3015 *			file to pass to pkginstall when installing the package.
3016 *			If this is == NULL no admin file is given to pkginstall.
3017 *		a_zoneTempDir - pointer to string representing the temporary
3018 *			directory in which spooled packages can be found if
3019 *			a_idsName is == NULL.
3020 */
3021
3022static int
3023install_in_zones(zoneList_t a_zlst, char *a_idsName, char *a_altBinDir,
3024    char *a_zoneAdminFile, char *a_zoneTempDir)
3025{
3026	char		*zoneName;
3027	int		zoneIndex;
3028	int		zonesSkipped = 0;
3029	zone_state_t	zst;
3030
3031	/* entry assertions */
3032
3033	assert(a_zlst != (zoneList_t)NULL);
3034
3035	/* entry debugging info */
3036
3037	echoDebug(DBG_INSTALLINZONES_ENTRY);
3038	echoDebug(DBG_INSTALLINZONES_ARGS, PSTR(a_idsName),
3039	    PSTR(a_zoneAdminFile), PSTR(a_zoneTempDir));
3040
3041	/* process each zone in the list */
3042
3043	for (zoneIndex = 0;
3044	    (zoneName = z_zlist_get_zonename(a_zlst, zoneIndex)) != NULL;
3045	    zoneIndex++) {
3046
3047		/* skip the zone if it is NOT running */
3048
3049		zst = z_zlist_get_current_state(a_zlst, zoneIndex);
3050		if (zst != ZONE_STATE_RUNNING && zst != ZONE_STATE_MOUNTED) {
3051			zonesSkipped++;
3052			echoDebug(DBG_SKIPPING_ZONE, zoneName);
3053			continue;
3054		}
3055
3056		/* install the package in this zone */
3057
3058		install_in_one_zone(z_zlist_get_scratch(a_zlst, zoneIndex),
3059		    a_idsName, a_zoneAdminFile, a_zoneTempDir, a_altBinDir,
3060		    zst, B_FALSE);
3061	}
3062
3063	return (zonesSkipped);
3064}
3065
3066/*
3067 * Name:	boot_and_install_in_zones
3068 * Description:	Install a single package in the zones that are NOT running from
3069 *		a list of zones - each zone is booted, the package installed,
3070 *		and the zone is halted
3071 * Arguments:	a_zlst - list of zones to install the package into
3072 *		a_idsName - pointer to string representing the data stream
3073 *			device (input data stream) containing the package to
3074 *			be installed.
3075 *			If this is == NULL the package is assumed to be
3076 *			spooled in the zone temporary directory.
3077 *		a_altBinDir - pointer to string representing an alternative
3078 *			binary location directory to pass to pkginstall.
3079 *			If this is == NULL no alternative binary location is
3080 *			passed to pkginstall.
3081 *		a_zoneAdminFile - pointer to string representing the admin
3082 *			file to pass to pkginstall when installing the package.
3083 *			If this is == NULL no admin file is given to pkginstall.
3084 *		a_zoneTempDir - pointer to string representing the temporary
3085 *			directory in which spooled packages can be found if
3086 *			a_idsName is == NULL.
3087 */
3088
3089static int
3090boot_and_install_in_zones(zoneList_t a_zlst, char *a_idsName, char *a_altBinDir,
3091    char *a_zoneAdminFile, char *a_zoneTempDir)
3092{
3093	boolean_t	b;
3094	char		*zoneName;
3095	int		zoneIndex;
3096	int		zonesSkipped = 0;
3097	zone_state_t	zst;
3098
3099	/* entry assertions */
3100
3101	assert(a_zlst != (zoneList_t)NULL);
3102
3103	/* entry debugging info */
3104
3105	echoDebug(DBG_BOOTINSTALLINZONES_ENTRY);
3106	echoDebug(DBG_BOOTINSTALLINZONES_ARGS, PSTR(a_idsName),
3107	    PSTR(a_zoneAdminFile), PSTR(a_zoneTempDir));
3108
3109	/* process each zone in the list */
3110
3111	for (zoneIndex = 0;
3112	    (zoneName = z_zlist_get_zonename(a_zlst, zoneIndex)) != NULL;
3113	    zoneIndex++) {
3114
3115		/* skip the zone if it IS running */
3116
3117		zst = z_zlist_get_current_state(a_zlst, zoneIndex);
3118		if (zst == ZONE_STATE_RUNNING || zst == ZONE_STATE_MOUNTED) {
3119			echoDebug(DBG_SKIPPING_ZONE_BOOT, zoneName);
3120			continue;
3121		}
3122
3123		/* skip the zone if it is NOT bootable */
3124
3125		if (z_zlist_is_zone_runnable(a_zlst, zoneIndex) == B_FALSE) {
3126			echo(MSG_SKIPPING_ZONE_NOT_RUNNABLE, zoneName);
3127			echoDebug(DBG_SKIPPING_ZONE_NOT_RUNNABLE, zoneName);
3128			continue;
3129		}
3130
3131		/* mount up the zone */
3132
3133		echo(MSG_BOOTING_ZONE, zoneName);
3134		echoDebug(DBG_BOOTING_ZONE, zoneName);
3135
3136		b = z_zlist_change_zone_state(a_zlst, zoneIndex,
3137		    ZONE_STATE_MOUNTED);
3138		if (b == B_FALSE) {
3139			progerr(ERR_CANNOT_BOOT_ZONE, zoneName);
3140			/* set fatal error return condition */
3141			ckreturn(1);
3142			zonesSkipped++;
3143			continue;
3144		}
3145
3146		/* install the package in this zone */
3147
3148		install_in_one_zone(z_zlist_get_scratch(a_zlst, zoneIndex),
3149		    a_idsName, a_zoneAdminFile, a_zoneTempDir, a_altBinDir,
3150		    ZONE_STATE_MOUNTED, B_TRUE);
3151
3152		/* restore original state of zone */
3153
3154		echo(MSG_RESTORE_ZONE_STATE, zoneName);
3155		echoDebug(DBG_RESTORE_ZONE_STATE, zoneName);
3156
3157		b = z_zlist_restore_zone_state(a_zlst, zoneIndex);
3158	}
3159
3160	return (zonesSkipped);
3161}
3162
3163/*
3164 * Name:	pkginstall_check_in_one_zone
3165 * Description:	Do a pre install check of a single package in a single zone
3166 * Arguments:	a_zoneName - pointer to string representing the name of the
3167 *			zone to check install the package in.
3168 *		a_idsName - pointer to string representing the data stream
3169 *			device (input data stream) containing the package to
3170 *			be check installed.
3171 *			If this is == NULL the package is assumed to be
3172 *			spooled in the zone temporary directory.
3173 *		a_zoneAdminFile - pointer to string representing the admin
3174 *			file to pass to pkginstall when installing the package.
3175 *			If this is == NULL no admin file is given to pkginstall.
3176 *		a_zoneTempDir - pointer to string representing the temporary
3177 *			directory in which spooled packages can be found if
3178 *			a_idsName is == NULL.
3179 *		a_altBinDir - pointer to string representing an alternative
3180 *			binary location directory to pass to pkginstall.
3181 *			If this is == NULL no alternative binary location is
3182 *			passed to pkginstall.
3183 *		a_scratchName - pointer to string representing the name of the
3184 *			scratch zone to use for installation.
3185 *		a_zoneState - state of the zone; must be mounted or running.
3186 *		a_tmpzn - B_TRUE when this zone is booted by the package
3187 *			command or B_FALSE if it was running before.
3188 * Returns:	void
3189 * NOTE:	As a side effect, "ckreturn" is called on the result returned
3190 *		from running 'pkginstall' in the zone; this sets several global
3191 *		variables which allows the caller to determine the result of
3192 *		the pre installation check operation.
3193 */
3194
3195static void
3196pkginstall_check_in_one_zone(char *a_zoneName,
3197    char *a_idsName, char *a_zoneAdminFile, char *a_zoneTempDir,
3198    char *a_altBinDir, char *a_scratchName, zone_state_t a_zoneState,
3199    boolean_t a_tmpzn)
3200{
3201	char	preinstallcheckPath[PATH_MAX+1];
3202	char	zoneStreamName[PATH_MAX] = {'\0'};
3203	int	n;
3204
3205	echo(MSG_CHECKINSTALL_PKG_IN_ZONE, pkginst, a_zoneName);
3206	echoDebug(MSG_CHECKINSTALL_PKG_IN_ZONE, pkginst, a_zoneName);
3207
3208	(void) snprintf(preinstallcheckPath, sizeof (preinstallcheckPath),
3209	    "%s/%s.%s.preinstallcheck.txt", a_zoneTempDir, pkginst,
3210	    a_zoneName);
3211
3212	if (a_idsName == (char *)NULL) {
3213		/* locate temporary stream created earlier */
3214		(void) snprintf(zoneStreamName, sizeof (zoneStreamName),
3215		    "%s/%s.dstream", a_zoneTempDir, pkginst);
3216	} else {
3217		(void) snprintf(zoneStreamName, sizeof (zoneStreamName),
3218		    "%s", a_idsName);
3219	}
3220
3221	echoDebug(DBG_CHECKINSTALL_IN_ZONE, pkginst, a_zoneName,
3222	    zoneStreamName);
3223
3224	n = pkgZoneCheckInstall(a_scratchName, a_zoneState, zoneStreamName,
3225	    a_altBinDir, a_zoneAdminFile, preinstallcheckPath, a_tmpzn);
3226
3227	/* set success/fail condition variables */
3228
3229	ckreturn(n);
3230
3231	echoDebug(DBG_INSTALL_FLAG_VALUES, "after preinstall check",
3232	    admnflag, doreboot, failflag, interrupted, intrflag,
3233	    ireboot, needconsult, nullflag, warnflag);
3234}
3235
3236/*
3237 * Name:	pkginstall_check_in_zones
3238 * Description:	Check installation of a single package in the zones that
3239 *		are running from a list of zones
3240 * Arguments:	a_zlst - list of zones to check install the package
3241 *		a_idsName - pointer to string representing the data stream
3242 *			device (input data stream) containing the package to
3243 *			be check installed.
3244 *			If this is == NULL the package is assumed to be
3245 *			spooled in the zone temporary directory.
3246 *		a_altBinDir - pointer to string representing an alternative
3247 *			binary location directory to pass to pkginstall.
3248 *			If this is == NULL no alternative binary location is
3249 *			passed to pkginstall.
3250 *		a_zoneAdminFile - pointer to string representing the admin
3251 *			file to pass to pkginstall when checking the installing
3252 *			of the package.
3253 *			If this is == NULL no admin file is given to pkginstall.
3254 *		a_zoneTempDir - pointer to string representing the temporary
3255 *			directory in which spooled packages can be found if
3256 *			a_idsName is == NULL.
3257 */
3258
3259static int
3260pkginstall_check_in_zones(zoneList_t a_zlst, char *a_idsName, char *a_altBinDir,
3261    char *a_zoneAdminFile, char *a_zoneTempDir)
3262{
3263	char		*zoneName;
3264	int		zoneIndex;
3265	int		zonesSkipped = 0;
3266	zone_state_t	zst;
3267
3268	for (zoneIndex = 0;
3269	    (zoneName = z_zlist_get_zonename(a_zlst, zoneIndex)) != NULL;
3270	    zoneIndex++) {
3271
3272		zst = z_zlist_get_current_state(a_zlst, zoneIndex);
3273		if (zst != ZONE_STATE_RUNNING && zst != ZONE_STATE_MOUNTED) {
3274			zonesSkipped++;
3275			echoDebug(DBG_SKIPPING_ZONE, zoneName);
3276			continue;
3277		}
3278
3279		pkginstall_check_in_one_zone(zoneName, a_idsName,
3280		    a_zoneAdminFile, a_zoneTempDir, a_altBinDir,
3281		    z_zlist_get_scratch(a_zlst, zoneIndex), zst, B_FALSE);
3282	}
3283
3284	return (zonesSkipped);
3285}
3286
3287/*
3288 * Name:	boot_and_pkginstall_check_in_zones
3289 * Description:	Check installation of a single package in the zones that
3290 *		are NOT running from a list of zones - each zone is booted,
3291 *		the package installation is checked, and the zone is halted.
3292 * Arguments:	a_zlst - list of zones to install the package into
3293 *		a_idsName - pointer to string representing the data stream
3294 *			device (input data stream) containing the package to
3295 *			be check installed.
3296 *			If this is == NULL the package is assumed to be
3297 *			spooled in the zone temporary directory.
3298 *		a_altBinDir - pointer to string representing an alternative
3299 *			binary location directory to pass to pkginstall.
3300 *			If this is == NULL no alternative binary location is
3301 *			passed to pkginstall.
3302 *		a_zoneAdminFile - pointer to string representing the admin
3303 *			file to pass to pkginstall when check installing the
3304 *			package.
3305 *			If this is == NULL no admin file is given to pkginstall.
3306 *		a_zoneTempDir - pointer to string representing the temporary
3307 *			directory in which spooled packages can be found if
3308 *			a_idsName is == NULL.
3309 */
3310
3311static int
3312boot_and_pkginstall_check_in_zones(zoneList_t a_zlst, char *a_idsName,
3313    char *a_altBinDir, char *a_zoneAdminFile, char *a_zoneTempDir)
3314{
3315	int		zoneIndex;
3316	int		zonesSkipped = 0;
3317	char		*zoneName;
3318	boolean_t	b;
3319	zone_state_t	zst;
3320
3321	/* entry assertions */
3322
3323	assert(a_zlst != (zoneList_t)NULL);
3324
3325	/* entry debugging info */
3326
3327	echoDebug(DBG_BOOTCHECKINSTALLINZONES_ENTRY);
3328	echoDebug(DBG_BOOTCHECKINSTALLINZONES_ARGS, PSTR(a_idsName),
3329	    PSTR(a_zoneAdminFile), PSTR(a_zoneTempDir));
3330
3331	/* process each zone in the list */
3332
3333	for (zoneIndex = 0;
3334	    (zoneName = z_zlist_get_zonename(a_zlst, zoneIndex)) != NULL;
3335	    zoneIndex++) {
3336
3337		/* skip the zone if it IS running */
3338
3339		zst = z_zlist_get_current_state(a_zlst, zoneIndex);
3340		if (zst == ZONE_STATE_RUNNING || zst == ZONE_STATE_MOUNTED) {
3341			echoDebug(DBG_SKIPPING_ZONE_BOOT, zoneName);
3342			continue;
3343		}
3344
3345		/* skip the zone if it is NOT bootable */
3346
3347		if (z_zlist_is_zone_runnable(a_zlst, zoneIndex) == B_FALSE) {
3348			echo(MSG_SKIPPING_ZONE_NOT_RUNNABLE, zoneName);
3349			echoDebug(DBG_SKIPPING_ZONE_NOT_RUNNABLE, zoneName);
3350			continue;
3351		}
3352
3353		/* mount up the zone */
3354
3355		echo(MSG_BOOTING_ZONE, zoneName);
3356		echoDebug(DBG_BOOTING_ZONE, zoneName);
3357
3358		b = z_zlist_change_zone_state(a_zlst, zoneIndex,
3359		    ZONE_STATE_MOUNTED);
3360		if (b == B_FALSE) {
3361			progerr(ERR_CANNOT_BOOT_ZONE, zoneName);
3362			/* set fatal error return condition */
3363			ckreturn(1);
3364			zonesSkipped++;
3365			continue;
3366		}
3367
3368		/* pre-installation check of the package in this zone */
3369
3370		pkginstall_check_in_one_zone(zoneName, a_idsName,
3371		    a_zoneAdminFile, a_zoneTempDir, a_altBinDir,
3372		    z_zlist_get_scratch(a_zlst, zoneIndex),
3373		    ZONE_STATE_MOUNTED, B_TRUE);
3374
3375		/* restore original state of zone */
3376
3377		echo(MSG_RESTORE_ZONE_STATE, zoneName);
3378		echoDebug(DBG_RESTORE_ZONE_STATE, zoneName);
3379
3380		b = z_zlist_restore_zone_state(a_zlst, zoneIndex);
3381	}
3382
3383	return (zonesSkipped);
3384}
3385
3386/*
3387 * Function:	add_packages_in_global_with_zones
3388 * Description: call this function to add a list of packages in the global zone
3389 *		when one or more non-global zones exist
3390 * returns:
3391 *	B_TRUE to process next data stream
3392 *	B_FALSE to exit
3393 */
3394
3395static boolean_t
3396add_packages_in_global_with_zones(char **a_pkgList,
3397    char *a_idsName, int a_repeat, char *a_altBinDir,
3398    char *a_device, zoneList_t a_zlst)
3399{
3400static	char		*zoneTempDir = (char *)NULL;
3401static	char		*zoneAdminFile = (char *)NULL;
3402
3403	boolean_t	b;
3404	char		*packageDir;
3405	char		instdir[PATH_MAX];
3406	char		respfile_path[PATH_MAX];
3407	char		zoneStreamName[PATH_MAX] = {'\0'};
3408	int		i;
3409	int		n;
3410	int		savenpkgs = npkgs;
3411	int		zonesSkipped;
3412	boolean_t	globalPresent;
3413
3414	/* entry assertions */
3415
3416	assert(a_pkgList != (char **)NULL);
3417	assert(a_zlst != (zoneList_t)NULL);
3418
3419	echoDebug(DBG_ADDPACKAGES_GZ_W_LZ_ENTRY);
3420	echoDebug(DBG_ADDPACKAGES_GZ_W_LZ_ARGS, npkgs,
3421	    PSTR(a_idsName), a_repeat, PSTR(a_device));
3422
3423	/* create temporary directory for use by zone operations */
3424
3425	create_zone_tempdir(&zoneTempDir, tmpdir);
3426
3427	/* create hands off settings admin file for use in a non-global zone */
3428
3429	create_zone_adminfile(&zoneAdminFile, zoneTempDir, admnfile);
3430
3431	/* determine directory where packages can be found */
3432
3433	if (a_idsName == (char *)NULL) {
3434		/* no stream - directory containing packages provided */
3435		packageDir = pkgdev.dirname;
3436	} else {
3437		packageDir = zoneTempDir;
3438	}
3439
3440	/* unpack and check all packages */
3441
3442	b = unpack_and_check_packages(a_pkgList, a_idsName, packageDir);
3443	if (b != B_TRUE) {
3444		quit(1);
3445	}
3446
3447	/*
3448	 * if the packages are contained in a directory, convert the
3449	 * packages into individual streams because pkgZoneInstall is only able
3450	 * to pass a stream to the non-global zone's pkginstall command.
3451	 * After this code is executed:
3452	 * if the original input was a datastream:
3453	 * -> that datastream has been unpacked into "instdir"
3454	 * if the original input was a directory with packages in it:
3455	 * -> those packages have been placed into a single datastream
3456	 */
3457
3458	if (a_idsName == (char *)NULL) {
3459		for (i = 0; (pkginst = a_pkgList[i]) != NULL; i++) {
3460			char	*pkgs[2];
3461
3462			/* package is not a stream - create one */
3463
3464			(void) snprintf(zoneStreamName, sizeof (zoneStreamName),
3465			    "%s/%s.dstream", zoneTempDir, pkginst);
3466
3467			echoDebug(DBG_CONVERTING_PKG, packageDir, pkginst,
3468			    zoneStreamName);
3469
3470			/* set up list of packages to be this package only */
3471
3472			pkgs[0] = pkginst;
3473			pkgs[1] = (char *)NULL;
3474
3475			n = pkgtrans(packageDir, zoneStreamName, pkgs,
3476			    PT_SILENT|PT_ODTSTREAM);
3477			if (n != 0) {
3478				progerr(ERR_CANNOT_CONVERT_PKGSTRM,
3479				    pkginst, packageDir, zoneStreamName);
3480				quit(1);
3481			}
3482			npkgs--;
3483		}
3484		npkgs = savenpkgs;
3485	}
3486
3487	/*
3488	 * Phase I - run collect dependency information for all packages for all
3489	 * zones - this involves running pkginstall with the "preinstallcheck"
3490	 * option which causes all dependency checks to be performed without
3491	 * actually doing the installation of the packages. This information is
3492	 * gathered in the zone temporary directory and is used later to present
3493	 * the dependency check results to the system administrator depending
3494	 * on the administration settings.
3495	 */
3496
3497	for (i = 0; (pkginst = a_pkgList[i]) != NULL; i++) {
3498
3499		/* reset interrupted flag before calling pkginstall */
3500
3501		interrupted = 0;	/* last action was NOT quit */
3502
3503		/*
3504		 * if this package is marked "install in this zone only", then
3505		 * do not check dependencies in any other zone
3506		 */
3507
3508		if (pkgPackageIsThisZone(pkginst) == B_TRUE) {
3509			echoDebug(DBG_VERIFY_SKIP_THISZONE, pkginst);
3510			npkgs--;
3511			continue;
3512		}
3513
3514		/*
3515		 * if operation failed in global zone do not propagate
3516		 * to any non-global zones
3517		 */
3518
3519		if (interrupted != 0) {
3520			echo(MSG_CHECKINSTALL_INTERRUPT_B4_Z, pkginst);
3521			echoDebug(MSG_CHECKINSTALL_INTERRUPT_B4_Z, pkginst);
3522			break;
3523		}
3524
3525		echoDebug(DBG_INSTALL_FLAG_VALUES, "after pkginstall",
3526		    admnflag, doreboot, failflag, interrupted, intrflag,
3527		    ireboot, needconsult, nullflag, warnflag);
3528
3529		/*
3530		 * call pkginstall to verify this package for all non-global
3531		 * zones that are currently booted
3532		 */
3533
3534		zonesSkipped = pkginstall_check_in_zones(a_zlst, a_idsName,
3535		    a_altBinDir, admnfile, zoneTempDir);
3536
3537		/*
3538		 * if any zones were skipped (becuase they are not currently
3539		 * booted), boot each zone one at a time and call pkginstall
3540		 * to verify this package for each such non-global zone
3541		 */
3542
3543		if (zonesSkipped > 0) {
3544			echoDebug(DBG_ZONES_SKIPPED, zonesSkipped);
3545
3546			zonesSkipped =
3547			    boot_and_pkginstall_check_in_zones(a_zlst,
3548			    a_idsName, a_altBinDir, admnfile,
3549			    zoneTempDir);
3550
3551			if (zonesSkipped > 0) {
3552				progerr(ERR_INSTALL_ZONES_SKIPPED,
3553				    zonesSkipped);
3554			}
3555		}
3556
3557		npkgs--;
3558	}
3559
3560	/*
3561	 * At this point, all of the dependency information has been gathered
3562	 * and is ready to be analyzed. This function processes all of that
3563	 * dependency information and presents the results to the system
3564	 * administrator, depending on the current administration settings.
3565	 */
3566
3567	i = preinstall_verify(a_pkgList, a_zlst, zoneTempDir);
3568	if (i != 0) {
3569		/* dependency checks failed - exit */
3570		quit(i);
3571	}
3572
3573	npkgs = savenpkgs;
3574
3575	/*
3576	 * reset all error return condition variables that may have been
3577	 * set during package installation dependency checking so that they
3578	 * do not reflect on the success/failure of the actual package
3579	 * installation operations
3580	 */
3581
3582	resetreturn();
3583
3584	/*
3585	 * At this point, all of the dependency checking is completed, and
3586	 * the installation of the packages can proceed. Install each package
3587	 * one at a time, starting with the global zone, and the for each
3588	 * non-global zone that is booted, and then for each non-global zone
3589	 * that is not currently booted.
3590	 */
3591
3592	globalPresent = z_on_zone_spec(GLOBAL_ZONENAME);
3593
3594	for (i = 0; (pkginst = a_pkgList[i]) != NULL; i++) {
3595		/*
3596		 * if immediate reboot required from last package and this is
3597		 * not 'pkgask' then suspend installation of remaining packages
3598		 */
3599
3600		if ((ireboot != 0) && (askflag == 0)) {
3601			ptext(stderr, MSG_SUSPEND_ADD, pkginst);
3602				continue;
3603		}
3604
3605		/*
3606		 * handle interrupt if the previous pkginstall was interrupted
3607		 */
3608
3609		if (continue_installation() == B_FALSE) {
3610			return (B_FALSE);
3611		}
3612
3613		/*
3614		 * if pkgask, handle response file creation:
3615		 * - if the response file is a directory, then create a path to
3616		 * -- a package instance within the response file directory.
3617		 * - If the response file is NOT a directory, if more than one
3618		 * -- package is to be installed.
3619		 */
3620
3621		if ((askflag != 0) && (respdir != (char *)NULL)) {
3622			(void) snprintf(respfile_path, sizeof (respfile_path),
3623			    "%s/%s", respdir, pkginst);
3624			respfile = respfile_path;
3625		}
3626
3627		echo(MSG_PROC_INST, pkginst, a_device);
3628
3629		/*
3630		 * If we're installing another package in the same
3631		 * session, the second through nth pkginstall, must
3632		 * continue from where the prior one left off. For this
3633		 * reason, the continuation feature (implied by the
3634		 * nature of the command) is used for the remaining
3635		 * packages.
3636		 */
3637
3638		if ((i == 1) && (pkgdrtarg != (char *)NULL)) {
3639			pkgcontsrc = pkgdrtarg;
3640		}
3641
3642		if (globalPresent) {
3643			/*
3644			 * call pkginstall for this package for the global zone
3645			 */
3646
3647			echo(MSG_INSTALLING_PKG_IN_GZ, pkginst);
3648
3649			/* reset interrupted flag before calling pkginstall */
3650
3651			interrupted = 0;	/* last action was NOT quit */
3652
3653			n = pkgInstall(get_inst_root(), NULL, packageDir,
3654			    a_altBinDir);
3655
3656			/* set success/fail condition variables */
3657
3658			ckreturn(n);
3659
3660			/*
3661			 * if operation failed in global zone do not propagate
3662			 * to any non-global zones
3663			 */
3664
3665			if (interrupted != 0) {
3666				echo(MSG_INSTALL_INTERRUPT_B4_ZONES, pkginst);
3667				echoDebug(MSG_INSTALL_INTERRUPT_B4_ZONES,
3668				    pkginst);
3669				break;
3670			}
3671		}
3672
3673		/*
3674		 * if this package is marked "install in this zone only",
3675		 * then only need to install the package in the global zone;
3676		 * skip installation in any non-global zones.
3677		 */
3678
3679		if (pkgPackageIsThisZone(pkginst) == B_TRUE) {
3680			echoDebug(DBG_INSTALL_SKIP_THISZONE, pkginst);
3681			npkgs--;
3682			continue;
3683		}
3684
3685		echoDebug(DBG_INSTALL_FLAG_VALUES, "install in running zones",
3686		    admnflag, doreboot, failflag, interrupted, intrflag,
3687		    ireboot, needconsult, nullflag, warnflag);
3688
3689		/* install package in currently booted zones */
3690
3691		zonesSkipped = install_in_zones(a_zlst, a_idsName, a_altBinDir,
3692		    zoneAdminFile, zoneTempDir);
3693
3694		/* install package in zones that are not currently booted */
3695
3696		if (zonesSkipped > 0) {
3697			echoDebug(DBG_ZONES_SKIPPED, zonesSkipped);
3698
3699			zonesSkipped = boot_and_install_in_zones(a_zlst,
3700			    a_idsName, a_altBinDir, zoneAdminFile,
3701			    zoneTempDir);
3702
3703			if (zonesSkipped > 0) {
3704				progerr(ERR_INSTALL_ZONES_SKIPPED,
3705				    zonesSkipped);
3706			}
3707		}
3708
3709		/*
3710		 * package completely installed - remove any temporary stream
3711		 * of the package that might have been created
3712		 */
3713
3714		if (a_idsName == (char *)NULL) {
3715			/* locate temporary stream created earlier */
3716			(void) snprintf(zoneStreamName, sizeof (zoneStreamName),
3717			    "%s/%s.dstream", zoneTempDir, pkginst);
3718			/* remove stream - no longer needed */
3719			echoDebug(DBG_REMOVING_DSTREAM_PKGDIR, zoneStreamName,
3720			    pkginst);
3721			(void) remove(zoneStreamName);
3722		} else {
3723			/* remove package - no longer needed */
3724			if (snprintf(instdir, sizeof (instdir), "%s/%s",
3725			    zoneTempDir, pkginst) >= PATH_MAX) {
3726				progerr(ERR_CANNOT_CREATE_PKGPATH, tmpdir);
3727				quit(1);
3728			}
3729			echoDebug(DBG_REMOVING_PKG_TMPDIR, instdir, pkginst);
3730			(void) remove(instdir);
3731		}
3732
3733		/* decrement number of packages left to install */
3734
3735		npkgs--;
3736
3737		/*
3738		 * if no packages left to install, unmount package source
3739		 * device if appropriate
3740		 */
3741
3742		if ((npkgs <= 0) && (pkgdev.mount || a_idsName)) {
3743			(void) chdir("/");
3744			if (!a_idsName) {
3745				echoDebug(DBG_UNMOUNTING_DEV,
3746				    PSTR(pkgdev.mount));
3747				(void) pkgumount(&pkgdev);
3748			}
3749		}
3750	}
3751
3752	/*
3753	 * all packages in the package list have been installed.
3754	 * Continue with installation if:
3755	 * -- immediate reboot is NOT required
3756	 * -- there are more packages to install
3757	 * -- the package source is a path to a file
3758	 * else return do NOT continue.
3759	 */
3760
3761	if ((ireboot == 0) && (a_repeat != 0) &&
3762	    (pkgdev.pathname == (char *)NULL)) {
3763		return (B_TRUE);
3764	}
3765
3766	/* return 'dont continue' */
3767
3768	return (B_FALSE);
3769}
3770
3771/*
3772 * Function:	add_packages_in_nonglobal_zone
3773 * Description: call this function to add a list of packages in a non-global
3774 *		zone
3775 * returns:
3776 *	B_TRUE to process next data stream
3777 *	B_FALSE to exit
3778 */
3779
3780static boolean_t
3781add_packages_in_nonglobal_zone(char **a_pkgList,
3782    char *a_idsName, int a_repeat, char *a_altBinDir, char *a_device)
3783{
3784static	char		*zoneTempDir = (char *)NULL;
3785
3786	char		*packageDir;
3787	char		respfile_path[PATH_MAX];
3788	int		i;
3789	int		n;
3790	boolean_t	b;
3791	int		savenpkgs = npkgs;
3792
3793	/* entry assertions */
3794
3795	assert(a_pkgList != (char **)NULL);
3796
3797	/* entry debugging info */
3798
3799	echoDebug(DBG_ADDPACKAGES_LZ_ENTRY);
3800	echoDebug(DBG_ADDPACKAGES_LZ_ARGS, npkgs, PSTR(a_idsName),
3801	    a_repeat, PSTR(a_device));
3802
3803	/* create temporary directory for use by zone operations */
3804
3805	create_zone_tempdir(&zoneTempDir, tmpdir);
3806
3807	/*
3808	 * package can be in a number of formats:
3809	 * - file containing package stream (pkgadd -d file [pkgs])
3810	 * - directory containing packages (pkgadd -d /dir [pkgs])
3811	 * - device containing packages (pkgadd -d diskette1 [pkgs])
3812	 * non-global zones can be passed open file drescriptors and
3813	 * strings as arguments
3814	 * - for file containing package stream
3815	 * -- the stream can be passed directly to the non-global zone
3816	 * - for directory
3817	 * -- convert packages to datastream to pass to the non-global zone
3818	 * - for device
3819	 */
3820
3821	/* determine directory where packages can be found */
3822
3823	if (a_idsName == (char *)NULL) {
3824		/* no stream - directory containing packages provided */
3825		packageDir = pkgdev.dirname;
3826	} else {
3827		packageDir = zoneTempDir;
3828	}
3829
3830	b = unpack_and_check_packages(a_pkgList, a_idsName, packageDir);
3831	if (b != B_TRUE) {
3832		quit(1);
3833	}
3834
3835	/*
3836	 * this is the main loop where all of the packages (as listed in the
3837	 * package list) are added one at a time.
3838	 */
3839
3840	for (i = 0; (pkginst = a_pkgList[i]) != NULL; i++) {
3841		npkgs--;
3842	}
3843
3844	npkgs = savenpkgs;
3845
3846	/*
3847	 * this is the main loop where all of the packages (as listed in the
3848	 * package list) are added one at a time.
3849	 */
3850
3851	for (i = 0; (pkginst = a_pkgList[i]) != NULL; i++) {
3852		/*
3853		 * if immediate reboot required from last package and this is
3854		 * not 'pkgask' then suspend installation of remaining packages
3855		 */
3856
3857		if ((ireboot != 0) && (askflag == 0)) {
3858			ptext(stderr, MSG_SUSPEND_ADD, pkginst);
3859				continue;
3860		}
3861
3862		/*
3863		 * handle interrupt if the previous pkginstall was interrupted
3864		 */
3865
3866		if (continue_installation() == B_FALSE) {
3867			return (B_FALSE);
3868		}
3869
3870		/*
3871		 * if pkgask, handle response file creation:
3872		 * - if the response file is a directory, then create a path to
3873		 * -- a package instance within the response file directory.
3874		 * - If the response file is NOT a directory, if more than one
3875		 * -- package is to be installed.
3876		 */
3877
3878		if ((askflag != 0) && (respdir != (char *)NULL)) {
3879			(void) snprintf(respfile_path, sizeof (respfile_path),
3880			    "%s/%s", respdir, pkginst);
3881			respfile = respfile_path;
3882		}
3883
3884		echo(MSG_PROC_INST, pkginst, a_device);
3885
3886		/*
3887		 * If we're installing another package in the same
3888		 * session, the second through nth pkginstall, must
3889		 * continue from where the prior one left off. For this
3890		 * reason, the continuation feature (implied by the
3891		 * nature of the command) is used for the remaining
3892		 * packages.
3893		 */
3894
3895		if ((i == 1) && (pkgdrtarg != (char *)NULL)) {
3896			pkgcontsrc = pkgdrtarg;
3897		}
3898
3899		/* reset interrupted flag before calling pkginstall */
3900
3901		interrupted = 0;	/* last action was NOT quit */
3902
3903		/* call pkginstall for this package */
3904
3905		n = pkgInstall(get_inst_root(), NULL,
3906		    packageDir, a_altBinDir);
3907
3908		/* set success/fail condition variables */
3909
3910		ckreturn(n);
3911
3912		/* decrement number of packages left to install */
3913
3914		npkgs--;
3915
3916		/*
3917		 * if no packages left to install, unmount package source
3918		 * device if appropriate
3919		 */
3920
3921		if ((npkgs <= 0) && (pkgdev.mount || a_idsName)) {
3922			(void) chdir("/");
3923			if (!a_idsName) {
3924				(void) pkgumount(&pkgdev);
3925			}
3926		}
3927	}
3928
3929	/*
3930	 * all packages in the package list have been installed.
3931	 * Continue with installation if:
3932	 * -- immediate reboot is NOT required
3933	 * -- there are more packages to install
3934	 * -- the package source is a path to a file
3935	 * else return do NOT continue.
3936	 */
3937
3938	if ((ireboot == 0) && (a_repeat != 0) &&
3939	    (pkgdev.pathname == (char *)NULL)) {
3940		return (B_TRUE);
3941	}
3942
3943	/* return 'dont continue' */
3944
3945	return (B_FALSE);
3946}
3947
3948/*
3949 * Function:	add_packages_in_global_no_zones
3950 * Description: call this function to add a list of packages in the global zone
3951 *		when no non-global zones exist
3952 * returns:
3953 *	B_TRUE to process next data stream
3954 *	B_FALSE to exit
3955 */
3956
3957static boolean_t
3958add_packages_in_global_no_zones(char **a_pkgList,
3959    char *a_idsName, int a_repeat, char *a_altBinDir, char *a_device)
3960{
3961	int		n;
3962	int		i;
3963	char		respfile_path[PATH_MAX];
3964	CAF_T		flags = 0;
3965
3966	/* entry assertions */
3967
3968	assert(a_pkgList != (char **)NULL);
3969
3970	echoDebug(DBG_ADDPACKAGES_GZ_NO_LZ_ENTRY);
3971	echoDebug(DBG_ADDPACKAGES_GZ_NO_LZ_ARGS, npkgs,
3972	    PSTR(a_idsName), a_repeat, PSTR(a_device));
3973
3974	/*
3975	 * set flags for applicability check
3976	 */
3977
3978	/* in the global zone */
3979
3980	flags |= CAF_IN_GLOBAL_ZONE;
3981
3982	/* set -G flag */
3983
3984	if (globalZoneOnly == B_TRUE) {
3985		flags |= CAF_SCOPE_GLOBAL;
3986	}
3987
3988	/*
3989	 * this is the main loop where all of the packages (as listed in the
3990	 * package list) are added one at a time.
3991	 */
3992
3993	for (i = 0; (pkginst = a_pkgList[i]) != NULL; i++) {
3994		/*
3995		 * if immediate reboot required from last package and this is
3996		 * not 'pkgask' then suspend installation of remaining packages
3997		 */
3998
3999		if ((ireboot != 0) && (askflag == 0)) {
4000			ptext(stderr, MSG_SUSPEND_ADD, pkginst);
4001				continue;
4002		}
4003
4004		/*
4005		 * handle interrupt if the previous pkginstall was interrupted
4006		 */
4007
4008		if (continue_installation() == B_FALSE) {
4009			return (B_FALSE);
4010		}
4011
4012		/*
4013		 * check package applicability to install in this context
4014		 */
4015
4016		if (check_applicability(pkgdev.dirname,
4017		    pkginst, get_inst_root(), flags) == B_FALSE) {
4018			progerr(ERR_PKG_NOT_APPLICABLE, pkginst);
4019			quit(1);
4020		}
4021
4022		/*
4023		 * if pkgask, handle response file creation:
4024		 * - if the response file is a directory, then create a path to
4025		 * -- a package instance within the response file directory.
4026		 * - If the response file is NOT a directory, if more than one
4027		 * -- package is to be installed.
4028		 */
4029
4030		if ((askflag != 0) && (respdir != (char *)NULL)) {
4031			(void) snprintf(respfile_path, sizeof (respfile_path),
4032			    "%s/%s", respdir, pkginst);
4033			respfile = respfile_path;
4034		}
4035
4036		echo(MSG_PROC_INST, pkginst, a_device);
4037
4038		/*
4039		 * If we're installing another package in the same
4040		 * session, the second through nth pkginstall, must
4041		 * continue from where the prior one left off. For this
4042		 * reason, the continuation feature (implied by the
4043		 * nature of the command) is used for the remaining
4044		 * packages.
4045		 */
4046
4047		if ((i == 1) && (pkgdrtarg != (char *)NULL)) {
4048			pkgcontsrc = pkgdrtarg;
4049		}
4050
4051		/* reset interrupted flag before calling pkginstall */
4052
4053		interrupted = 0;	/* last action was NOT quit */
4054
4055		/* call pkginstall for this package */
4056
4057		n = pkgInstall(get_inst_root(), a_idsName,
4058		    pkgdev.dirname, a_altBinDir);
4059
4060		/* set success/fail condition variables */
4061
4062		ckreturn(n);
4063
4064		/* decrement number of packages left to install */
4065
4066		npkgs--;
4067
4068		/*
4069		 * if no packages left to install, unmount package source
4070		 * device if appropriate
4071		 */
4072
4073		if ((npkgs <= 0) && (pkgdev.mount || a_idsName)) {
4074			(void) chdir("/");
4075			if (!a_idsName) {
4076				(void) pkgumount(&pkgdev);
4077			}
4078		}
4079	}
4080
4081	/*
4082	 * all packages in the package list have been installed.
4083	 * Continue with installation if:
4084	 * -- immediate reboot is NOT required
4085	 * -- there are more packages to install
4086	 * -- the package source is a path to a file
4087	 * else return do NOT continue.
4088	 */
4089
4090	if ((ireboot == 0) && (a_repeat != 0) &&
4091	    (pkgdev.pathname == (char *)NULL)) {
4092		return (B_TRUE);
4093	}
4094
4095	/* return 'dont continue' */
4096
4097	return (B_FALSE);
4098}
4099
4100/*
4101 * returns:
4102 *	B_TRUE to process next data stream
4103 *	B_FALSE to exit
4104 */
4105
4106static boolean_t
4107add_packages(char **a_pkgList,
4108    char *a_idsName, int a_repeat, char *a_altBinDir, char *a_device,
4109    boolean_t a_noZones)
4110{
4111	zoneList_t	zlst;
4112	boolean_t	b;
4113
4114	/* entry assertions */
4115
4116	assert(a_pkgList != (char **)NULL);
4117
4118	echoDebug(DBG_ADDPACKAGES_ENTRY);
4119	echoDebug(DBG_ADDPACKAGES_ARGS, npkgs, PSTR(a_idsName),
4120	    a_repeat, PSTR(a_altBinDir), PSTR(a_device));
4121
4122	/*
4123	 * if running in the global zone AND one or more non-global
4124	 * zones exist, add packages in a 'zones aware' manner, else
4125	 * add packages in the standard 'non-zones aware' manner.
4126	 */
4127
4128	if ((a_noZones == B_FALSE) && (z_running_in_global_zone() == B_FALSE)) {
4129		/* in non-global zone */
4130
4131		echoDebug(DBG_IN_LZ);
4132
4133		b = z_lock_this_zone(ZLOCKS_PKG_ADMIN);
4134		if (b != B_TRUE) {
4135			progerr(ERR_CANNOT_LOCK_THIS_ZONE);
4136			/* set fatal error return condition */
4137			ckreturn(1);
4138			return (B_FALSE);
4139		}
4140
4141		b = add_packages_in_nonglobal_zone(a_pkgList, a_idsName,
4142		    a_repeat, a_altBinDir, a_device);
4143
4144		(void) z_unlock_this_zone(ZLOCKS_ALL);
4145
4146		return (B_FALSE);
4147	}
4148
4149	/* running in the global zone */
4150
4151	b = z_non_global_zones_exist();
4152	if ((a_noZones == B_FALSE) && (b == B_TRUE) &&
4153	    (globalZoneOnly == B_FALSE)) {
4154
4155		echoDebug(DBG_IN_GZ_WITH_LZ);
4156
4157		/* error if -V specified - what to use in non-global zone? */
4158
4159		if (vfstab_file) {
4160			progerr(ERR_V_USED_WITH_GZS);
4161			quit(1);
4162		}
4163
4164		/* get a list of all non-global zones */
4165		zlst = z_get_nonglobal_zone_list();
4166		if (zlst == (zoneList_t)NULL) {
4167			progerr(ERR_CANNOT_GET_ZONE_LIST);
4168			quit(1);
4169		}
4170
4171		/* need to lock all of the zones */
4172
4173		quitSetZonelist(zlst);
4174		b = z_lock_zones(zlst, ZLOCKS_PKG_ADMIN);
4175		if (b == B_FALSE) {
4176			z_free_zone_list(zlst);
4177			progerr(ERR_CANNOT_LOCK_ZONES);
4178			/* set fatal error return condition */
4179			ckreturn(1);
4180			return (B_FALSE);
4181		}
4182
4183		/* add packages to all zones */
4184
4185		b = add_packages_in_global_with_zones(a_pkgList,
4186		    a_idsName, a_repeat, a_altBinDir, a_device, zlst);
4187
4188		/* unlock all zones */
4189
4190		(void) z_unlock_zones(zlst, ZLOCKS_ALL);
4191		quitSetZonelist((zoneList_t)NULL);
4192
4193		/* free list of all non-global zones */
4194
4195		z_free_zone_list(zlst);
4196
4197		return (B_FALSE);
4198	}
4199
4200	/* in global zone no non-global zones */
4201
4202	echoDebug(DBG_IN_GZ_NO_LZ);
4203
4204	b = z_lock_this_zone(ZLOCKS_PKG_ADMIN);
4205	if (b != B_TRUE) {
4206		progerr(ERR_CANNOT_LOCK_THIS_ZONE);
4207		/* set fatal error return condition */
4208		ckreturn(1);
4209		return (B_FALSE);
4210	}
4211
4212	b = add_packages_in_global_no_zones(a_pkgList, a_idsName,
4213	    a_repeat, a_altBinDir, a_device);
4214
4215	(void) z_unlock_this_zone(ZLOCKS_ALL);
4216
4217	return (B_FALSE);
4218}
4219