8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / cmd / svr4pkg / pkginstall / main.c
blob297b05b6ca7d4c62ae96bb56690051cfbcc6eac6
1 /*
2 * CDDL HEADER START
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.
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.
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]
19 * CDDL HEADER END
23 * Copyright (c) 2017 Peter Tribble.
27 * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
30 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
31 /* All Rights Reserved */
34 #include <stdio.h>
35 #include <time.h>
36 #include <wait.h>
37 #include <stdlib.h>
38 #include <unistd.h>
39 #include <ulimit.h>
40 #include <sys/stat.h>
41 #include <sys/statvfs.h>
42 #include <fcntl.h>
43 #include <errno.h>
44 #include <ctype.h>
45 #include <dirent.h>
46 #include <string.h>
47 #include <signal.h>
48 #include <locale.h>
49 #include <libintl.h>
50 #include <pkgstrct.h>
51 #include <pkginfo.h>
52 #include <pkgdev.h>
53 #include <pkglocs.h>
54 #include <pwd.h>
55 #include <assert.h>
56 #include <instzones_api.h>
57 #include <pkglib.h>
58 #include <install.h>
59 #include <libinst.h>
60 #include <libadm.h>
61 #include <dryrun.h>
62 #include <messages.h>
63 #include "pkginstall.h"
65 /* imported globals */
67 extern char **environ;
68 extern char *pkgabrv;
69 extern char *pkgname;
70 extern char *pkgarch;
71 extern char *pkgvers;
72 extern char pkgwild[];
74 /* libadm(3LIB) */
76 extern char *get_install_root(void);
78 /* quit.c */
80 extern sighdlrFunc_t *quitGetTrapHandler(void);
81 extern void quitSetDstreamTmpdir(char *a_dstreamTempDir);
82 extern void quitSetInstallStarted(boolean_t a_installStarted);
83 extern void quitSetPkgask(boolean_t a_pkgaskFlag);
84 extern void quitSetSilentExit(boolean_t a_silentExit);
85 extern void quitSetUpdatingExisting(boolean_t a_updatingExisting);
86 extern void quitSetZoneName(char *a_zoneName);
89 /* static globals */
91 static char path[PATH_MAX];
92 static int ck_instbase(void);
93 static int cp_pkgdirs(void);
94 static int merg_pkginfos(struct cl_attr **pclass,
95 struct cl_attr ***mpclass);
96 static int merg_respfile(void);
97 static int mv_pkgdirs(void);
98 static int rdonly(char *p);
99 static void ck_w_dryrun(int (*func)(), int type);
100 static void copyright(void), usage(void);
101 static void do_pkgask(boolean_t a_run_request_as_root);
102 static void rm_icas(char *casdir);
103 static void set_dryrun_dir_loc(void);
104 static void unpack(void);
106 void ckreturn(int retcode, char *msg);
108 static char *ro_params[] = {
109 "PATH", "NAME", "PKG", "PKGINST",
110 "VERSION", "ARCH",
111 "INSTDATE", "CATEGORY",
112 NULL
116 * The following variable is the name of the device to which stdin
117 * is connected during execution of a procedure script. PROC_STDIN is
118 * correct for all ABI compliant packages. For non-ABI-compliant
119 * packages, the '-o' command line switch changes this to PROC_XSTDIN
120 * to allow user interaction during these scripts. -- JST
122 static char *script_in = PROC_STDIN; /* assume ABI compliance */
124 static char *pkgdrtarg = NULL;
125 static char *pkgcontsrc = NULL;
126 static int non_abi_scripts = 0;
127 static char *respfile = NULL;
128 static char *srcinst = NULL;
129 static int suppressCopyright = 0;
130 static int nointeract = 0;
132 /* exported globals */
134 char *msgtext;
135 char *pkginst = (char *)NULL;
136 char *rw_block_size = NULL;
137 char ilockfile[PATH_MAX];
138 char instdir[PATH_MAX];
139 char saveSpoolInstallDir[PATH_MAX];
140 char pkgbin[PATH_MAX];
141 char pkgloc[PATH_MAX];
142 char pkgloc_sav[PATH_MAX];
143 char pkgsav[PATH_MAX];
144 char rlockfile[PATH_MAX];
145 char savlog[PATH_MAX];
146 char tmpdir[PATH_MAX];
147 int dbchg;
148 int dparts = 0;
149 int dreboot = 0;
150 int failflag = 0;
151 static int askflag = 0; /* non-zero if invoked as "pkgask" */
152 int ireboot = 0;
153 int maxinst = 1;
154 int nocnflct;
155 int nosetuid;
156 int pkgverbose = 0;
157 int rprcflag;
158 int warnflag = 0;
159 struct admin adm;
160 struct cfextra **extlist; /* pkgmap structure and other path info */
161 struct pkgdev pkgdev;
162 fsblkcnt_t pkgmap_blks = 0LL;
165 * this global is referenced by:
166 * getinst - [RW] - incremented if:
167 * - installing same instance again
168 * - overwriting an existing instance
169 * - not installing a new instance
170 * quit - [RO] - if non-zero and started non-zero:
171 * - the new <PKGINST>/install directory and rename <PKGINST>/install.save
172 * - back to <PKGINST>/install
173 * main.c - [RO] - if non-zero:
174 * - alter manner in which parameters are setup for scripts
175 * - set UPDATE=yes in environment
177 static int update = 0;
179 /* Set by -O debug: debug output is enabled? */
181 static boolean_t debugFlag = B_FALSE;
183 /* Set by the -G option: install packages in global zone only */
185 static boolean_t globalZoneOnly = B_FALSE;
187 /* Set by -O preinstallcheck */
189 static boolean_t preinstallCheck = B_FALSE;
191 /* Set by -O parent-zone-name= */
193 static char *parentZoneName = (char *)NULL;
195 /* Set by -O parent-zone-type= */
197 static char *parentZoneType = (char *)NULL;
199 #define DEFPATH "/sbin:/usr/sbin:/usr/bin"
200 #define MALSIZ 4 /* best guess at likely maximum value of MAXINST */
201 #define LSIZE 256 /* maximum line size supported in copyright file */
203 #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */
204 #define TEXT_DOMAIN "SYS_TEST"
205 #endif
207 /* This is the text for the "-O parent-zone-name=" option */
209 #define PARENTZONENAME "parent-zone-name="
210 #define PARENTZONENAME_LEN ((sizeof (PARENTZONENAME))-1)
212 /* This is the text for the "-O parent-zone-type=" option */
214 #define PARENTZONETYPE "parent-zone-type="
215 #define PARENTZONETYPE_LEN ((sizeof (PARENTZONETYPE))-1)
217 static char *cpio_names[] = {
218 "root",
219 "root.cpio",
220 "reloc",
221 "reloc.cpio",
222 "root.Z",
223 "root.cpio.Z",
224 "reloc.Z",
225 "reloc.cpio.Z",
230 main(int argc, char *argv[])
232 VFP_T *cfTmpVfp = NULL; /* temporary */
233 VFP_T *pkgmapVfp; /* "../pkgmap" file */
234 boolean_t run_request_as_root = B_FALSE;
235 char **np;
236 char *abi_comp_ptr;
237 char *abi_nm_ptr;
238 char *abi_sym_ptr;
239 char *admnfile = NULL;
240 char *device;
241 char *p;
242 char *prog_full_name = NULL;
243 char *pt;
244 char *updated = (char *)NULL;
245 char *vfstab_file = NULL;
246 char *zoneName = (char *)NULL;
247 char cbuf[MAX_PKG_PARAM_LENGTH];
248 char cmdbin[PATH_MAX];
249 char p_pkginfo[PATH_MAX];
250 char p_pkgmap[PATH_MAX];
251 char param[MAX_PKG_PARAM_LENGTH];
252 char script[PATH_MAX];
253 char altscript[PATH_MAX];
254 char *temp;
255 int c;
256 int disableAttributes = 0;
257 int err;
258 int init_install = 0;
259 int is_comp_arch;
260 int live_continue = 0;
261 int map_client = 1;
262 int n;
263 int nparts;
264 int npkgs;
265 int part;
266 int saveSpoolInstall = 0;
267 boolean_t cont_file_read;
268 struct cl_attr **pclass = NULL;
269 struct cl_attr **mergd_pclass = NULL;
270 struct pkginfo *prvinfo;
271 struct sigaction nact;
272 struct sigaction oact;
273 struct stat statb;
274 struct statvfs64 svfsb;
275 time_t clock;
276 PKGserver pkgserver = NULL;
278 /* reset contents of all default paths */
280 (void) memset(path, '\0', sizeof (path));
281 (void) memset(cmdbin, '\0', sizeof (cmdbin));
282 (void) memset(script, '\0', sizeof (script));
283 (void) memset(cbuf, '\0', sizeof (cbuf));
284 (void) memset(param, '\0', sizeof (param));
286 /* initialize locale environment */
288 (void) setlocale(LC_ALL, "");
289 (void) textdomain(TEXT_DOMAIN);
291 /* initialize program name */
293 prog_full_name = argv[0];
294 (void) set_prog_name(argv[0]);
296 /* tell spmi zones interface how to access package output functions */
298 z_set_output_functions(echo, echoDebug, progerr);
300 /* exit if not root */
302 if (getuid()) {
303 progerr(ERR_NOT_ROOT, get_prog_name());
304 exit(1);
305 /* NOTREACHED */
309 * determine how pkgmap() deals with environment variables:
310 * - MAPALL - resolve all variables
311 * - MAPBUILD - map only build variables
312 * - MAPINSTALL - map only install variables
313 * - MAPNONE - map no variables
316 setmapmode(MAPINSTALL);
318 /* set sane umask */
320 (void) umask(0022);
322 /* initially no source "device" */
324 device = NULL;
326 /* reset npkgs (used as pkg remaining count in quit.c) */
328 npkgs = 0;
330 /* Read PKG_INSTALL_ROOT from the environment, if it's there. */
332 if (!set_inst_root(getenv("PKG_INSTALL_ROOT"))) {
333 progerr(ERR_ROOT_SET);
334 exit(1);
337 pkgserversetmode(DEFAULTMODE);
339 /* parse command line options */
341 while ((c = getopt(argc, argv,
342 "?Aa:B:b:Cc:D:d:eFf:GhIiMm:N:noO:p:R:r:StV:vyz")) != EOF) {
344 switch (c) {
347 * Same as pkgadd: This disables attribute checking.
348 * It speeds up installation a little bit.
350 case 'A':
351 disableAttributes++;
352 break;
355 * Same as pkgadd: Define an installation administration
356 * file, admin, to be used in place of the default
357 * administration file. The token none overrides the use
358 * of any admin file, and thus forces interaction with the
359 * user. Unless a full path name is given, pkgadd first
360 * looks in the current working directory for the
361 * administration file. If the specified administration
362 * file is not in the current working directory, pkgadd
363 * looks in the /var/sadm/install/admin directory for the
364 * administration file.
366 case 'a':
367 admnfile = flex_device(optarg, 0);
368 break;
371 * Same as pkgadd: control block size given to
372 * pkginstall - block size used in read()/write() loop;
373 * default is st_blksize from stat() of source file.
375 case 'B':
376 rw_block_size = optarg;
377 break;
380 * Same as pkgadd: location where executables needed
381 * by procedure scripts can be found
382 * default is /usr/sadm/install/bin.
384 case 'b':
385 if (!path_valid(optarg)) {
386 progerr(ERR_PATH, optarg);
387 exit(1);
389 if (isdir(optarg) != 0) {
390 char *p = strerror(errno);
391 progerr(ERR_CANNOT_USE_DIR, optarg, p);
392 exit(1);
394 (void) strlcpy(cmdbin, optarg, sizeof (cmdbin));
395 break;
398 * Same as pkgadd: This disables checksum tests on
399 * the source files. It speeds up installation a little bit.
401 case 'C':
402 (void) checksum_off();
403 break;
406 * Same as pkgadd: This allows designation of a
407 * continuation file. It is the same format as a dryrun file
408 * but it is used to take up where the dryrun left off.
410 case 'c':
411 pkgcontsrc = optarg;
412 set_continue_mode();
413 set_dr_info(DR_TYPE, INSTALL_TYPE);
414 init_contfile(pkgcontsrc);
415 break;
418 * Same as pkgadd: This allows designation of a
419 * dryrun file. This pkgadd will create dryrun files
420 * in the directory provided.
422 case 'D':
423 pkgdrtarg = optarg;
424 set_dryrun_mode();
425 set_dr_info(DR_TYPE, INSTALL_TYPE);
426 break;
429 * Same as pkgadd: Install or copy a package from
430 * device. device can be a full path name to a directory
431 * or the identifiers for tape, floppy disk, or removable
432 * disk - for example, /var/tmp or /floppy/floppy_name.
433 * It can also be a device alias - for example,
434 * /floppy/floppy0, or a datastream created by pkgtrans.
436 case 'd':
437 device = flex_device(optarg, 1);
438 break;
441 * Different from pkgadd: disable the 32 char name
442 * limit extension
444 case 'e':
445 (void) set_ABI_namelngth();
446 break;
449 * Different from pkgadd: specify file system type for
450 * the package device. Must be used with -m.
452 case 'f':
453 pkgdev.fstyp = optarg;
454 break;
457 * Same as pkgadd: install package in global zone only.
459 case 'G':
460 globalZoneOnly = B_TRUE;
461 break;
464 * Same as pkgadd: Enable hollow package support. When
465 * specified, for any package that has SUNW_PKG_HOLLOW=true:
466 * Do not calculate and verify package size against target.
467 * Do not run any package procedure or class action scripts.
468 * Do not create any target directories.
469 * Do not perform any script locking.
470 * Do not install any components of any package.
471 * Do not output any status or database update messages.
473 case 'h':
474 set_depend_pkginfo_DB(B_TRUE);
475 break;
478 * Same as pkgadd: Informs scripts that this is
479 * an initial install by setting the environment parameter
480 * PKG_INIT_INSTALL=TRUE for all scripts. They may use it as
481 * they see fit, safe in the knowledge that the target
482 * filesystem is tabula rasa.
484 case 'I':
485 init_install++;
486 break;
489 * Different from pkgadd: use by pkgask.
491 case 'i':
492 askflag++;
493 quitSetPkgask(B_TRUE);
494 break;
497 * Same as pkgadd: Instruct pkgadd not to use the
498 * $root_path/etc/vfstab file for determining the client's
499 * mount points. This option assumes the mount points are
500 * correct on the server and it behaves consistently with
501 * Solaris 2.5 and earlier releases.
503 case 'M':
504 map_client = 0;
505 break;
508 * Different from pkgadd: specify device to use for package
509 * source.
511 case 'm':
512 pkgdev.mount = optarg;
513 pkgdev.rdonly++;
514 pkgdev.mntflg++;
515 break;
518 * Different from pkgadd: specify program name to use
519 * for messages.
521 case 'N':
522 (void) set_prog_name(optarg);
523 break;
526 * Same as pkgadd: installation occurs in
527 * non-interactive mode. Suppress output of the list of
528 * installed files. The default mode is interactive.
530 case 'n':
531 nointeract++;
532 (void) echoSetFlag(B_FALSE);
533 break;
536 * Almost same as pkgadd: the -O option allows the behavior
537 * of the package tools to be modified. Recognized options:
538 * -> debug
539 * ---> enable debugging output
540 * -> preinstallcheck
541 * ---> perform a "pre installation" check of the specified
542 * ---> package - suppress all regular output and cause a
543 * ---> series of one or more "name=value" pair format lines
544 * ---> to be output that describes the "installability" of
545 * ---> the specified package
546 * -> enable-hollow-package-support
547 * --> Enable hollow package support. When specified, for any
548 * --> package that has SUNW_PKG_HOLLOW=true:
549 * --> Do not calculate and verify package size against target
550 * --> Do not run any package procedure or class action scripts
551 * --> Do not create or remove any target directories
552 * --> Do not perform any script locking
553 * --> Do not install or uninstall any components of any package
554 * --> Do not output any status or database update messages
556 case 'O':
557 for (p = strtok(optarg, ","); p != (char *)NULL;
558 p = strtok(NULL, ",")) {
560 /* process debug option */
562 if (strcmp(p, "debug") == 0) {
563 /* set debug flag/enable debug output */
564 if (debugFlag == B_TRUE) {
565 smlSetVerbose(B_TRUE);
567 debugFlag = B_TRUE;
568 (void) echoDebugSetFlag(debugFlag);
570 /* debug info on arguments to pkgadd */
571 for (n = 0; n < argc && argv[n]; n++) {
572 echoDebug(DBG_ARG, n, argv[n]);
575 continue;
578 /* process enable-hollow-package-support opt */
580 if (strcmp(p,
581 "enable-hollow-package-support") == 0) {
582 set_depend_pkginfo_DB(B_TRUE);
583 continue;
586 /* process preinstallcheck option */
588 if (strcmp(p, "preinstallcheck") == 0) {
589 preinstallCheck = B_TRUE;
590 nointeract++; /* -n */
591 suppressCopyright++; /* -S */
592 quitSetSilentExit(B_TRUE);
593 continue;
596 /* process addzonename option */
598 if (strcmp(p, "addzonename") == 0) {
600 * set zone name to add to messages;
601 * first look in the current environment
602 * and use the default package zone name
603 * if it is set; otherwise, use the name
604 * of the current zone
606 zoneName =
607 getenv(PKG_ZONENAME_VARIABLE);
609 if ((zoneName == (char *)NULL) ||
610 (*zoneName == '\0')) {
611 zoneName = z_get_zonename();
614 if (zoneName != (char *)NULL) {
615 if (*zoneName != '\0') {
616 quitSetZoneName(
617 zoneName);
618 } else {
619 zoneName = (char *)NULL;
622 continue;
625 /* process parent-zone-name option */
627 if (strncmp(p, PARENTZONENAME,
628 PARENTZONENAME_LEN) == 0) {
629 parentZoneName = p+PARENTZONENAME_LEN;
630 continue;
633 /* process parent-zone-type option */
635 if (strncmp(p, PARENTZONETYPE,
636 PARENTZONETYPE_LEN) == 0) {
637 parentZoneType = p+PARENTZONETYPE_LEN;
638 continue;
641 if (strncmp(p, PKGSERV_MODE,
642 PKGSERV_MODE_LEN) == 0) {
643 pkgserversetmode(pkgparsemode(p +
644 PKGSERV_MODE_LEN));
645 continue;
648 /* option not recognized - issue warning */
650 progerr(ERR_INVALID_O_OPTION, p);
651 continue;
654 break;
657 * Different from pkgadd: This is an old non-ABI package
659 case 'o':
660 non_abi_scripts++;
661 break;
664 * Different from pkgadd: specify number of parts to package.
666 case 'p':
667 dparts = ds_getinfo(optarg);
668 break;
671 * Same as pkgadd: Define the full path name of a
672 * directory to use as the root_path. All files,
673 * including package system information files, are
674 * relocated to a directory tree starting in the specified
675 * root_path. The root_path may be specified when
676 * installing to a client from a server (for example,
677 * /export/root/client1).
679 case 'R':
680 if (!set_inst_root(optarg)) {
681 progerr(ERR_ROOT_CMD);
682 exit(1);
684 break;
687 * Same as pkgadd: Identify a file or directory which
688 * contains output from a previous pkgask(1M)
689 * session. This file supplies the interaction responses
690 * that would be requested by the package in interactive
691 * mode. response must be a full pathname.
693 case 'r':
694 respfile = flex_device(optarg, 2);
695 break;
698 * Same as pkgadd: suppress copyright notice being
699 * output during installation.
701 case 'S':
702 suppressCopyright++;
703 break;
706 * Same as pkgadd: disable save spool area creation;
707 * do not spool any partial package contents, that is,
708 * suppress the creation and population of the package save
709 * spool area (var/sadm/pkg/PKG/save/pspool/PKG).
711 case 't':
712 disable_spool_create();
713 break;
716 * Same as pkgadd: Specify an alternative fs_file to map
717 * the client's file systems. For example, used in
718 * situations where the $root_path/etc/vfstab file is
719 * non-existent or unreliable. Informs the pkginstall
720 * portion to mount up a client filesystem based upon the
721 * supplied vfstab-like file of stable format.
723 case 'V':
724 vfstab_file = flex_device(optarg, 2);
725 map_client = 1;
726 break;
729 * Same as pkgadd: Trace all of the scripts that get
730 * executed by pkgadd, located in the pkginst/install
731 * directory. This option is used for debugging the
732 * procedural and non-procedural scripts
734 case 'v':
735 pkgverbose++;
736 break;
739 * Different from pkgadd: process this package using
740 * old non-ABI symlinks
742 case 'y':
743 set_nonABI_symlinks();
744 break;
747 * Same as pkgadd: perform fresh install from
748 * package save spool area. When set, the package contents
749 * are installed from the package spool save area instead
750 * of from the package root area, so that the original
751 * source packages are not required to install the
752 * package. If the -h option is also specified and the
753 * package is hollow, then this option is ignored. When -z
754 * is specified:
755 * - Editable files are installed from the package instance
756 * save area.
757 * - Volatile files are installed from the package instance
758 * save area.
759 * - Executable and data files are installed from the final
760 * installed location as specified in the pkgmap file.
761 * - Installation scripts are run from the package spool
762 * save area.
764 case 'z':
765 saveSpoolInstall++;
766 break;
769 * unrecognized option
771 default:
772 usage();
773 /*NOTREACHED*/
775 * Although usage() calls a noreturn function,
776 * needed to add return (1); so that main() would
777 * pass compilation checks. The statement below
778 * should never be executed.
780 return (1);
785 * ********************************************************************
786 * validate command line options
787 * ********************************************************************
790 /* set "debug echo" flag according to setting of "-O debug" option */
792 (void) echoDebugSetFlag(debugFlag);
793 (void) log_set_verbose(debugFlag);
795 /* output entry debugging information */
797 if (z_running_in_global_zone()) {
798 echoDebug(DBG_ENTRY_IN_GZ, prog_full_name);
799 } else {
800 echoDebug(DBG_ENTRY_IN_LZ, prog_full_name, getzoneid(),
801 z_get_zonename());
804 if (in_continue_mode() && !in_dryrun_mode()) {
805 progerr(ERR_LIVE_CONTINUE_NOT_SUPPORTED);
806 usage();
807 /*NOTREACHED*/
810 /* pkgask requires a response file */
812 if (askflag && (respfile == NULL)) {
813 usage();
814 /*NOTREACHED*/
817 /* if device specified, set appropriate device in pkgdev */
819 if (device) {
820 if (pkgdev.mount) {
821 pkgdev.bdevice = device;
822 } else {
823 pkgdev.cdevice = device;
827 /* if file system type specified, must have a device to mount */
829 if (pkgdev.fstyp && !pkgdev.mount) {
830 progerr(ERR_F_REQUIRES_M);
831 usage();
832 /*NOTREACHED*/
835 /* BEGIN DATA GATHERING PHASE */
838 * Get the mount table info and store internally.
840 cont_file_read = B_FALSE;
841 if (in_continue_mode()) {
842 int error;
843 cont_file_read = read_continuation(&error);
844 if (error == -1) {
845 quit(99);
846 /*NOTREACHED*/
848 if (!in_dryrun_mode()) {
849 live_continue = 1;
852 /* Read the mount table if not done in continuation mode */
853 if (!cont_file_read) {
854 if (get_mntinfo(map_client, vfstab_file)) {
855 quit(99);
856 /*NOTREACHED*/
861 * This function defines the standard /var/... directories used later
862 * to construct the paths to the various databases.
865 set_PKGpaths(get_inst_root());
868 * If this is being installed on a client whose /var filesystem is
869 * mounted in some odd way, remap the administrative paths to the
870 * real filesystem. This could be avoided by simply mounting up the
871 * client now; but we aren't yet to the point in the process where
872 * modification of the filesystem is permitted.
874 if (is_an_inst_root()) {
875 int fsys_value;
877 fsys_value = fsys(get_PKGLOC());
878 if (use_srvr_map_n(fsys_value))
879 set_PKGLOC(server_map(get_PKGLOC(), fsys_value));
881 fsys_value = fsys(get_PKGADM());
882 if (use_srvr_map_n(fsys_value))
883 set_PKGADM(server_map(get_PKGADM(), fsys_value));
887 * Initialize pkginfo PKGSAV entry, just in case we dryrun to
888 * somewhere else.
890 set_infoloc(get_PKGLOC());
892 /* pull off directory and package name from end of command line */
894 switch (argc-optind) {
895 case 0: /* missing directory and package instance */
896 progerr(ERR_MISSING_DIR_AND_PKG);
897 usage();
898 /*NOTREACHED*/
899 case 1: /* missing package instance */
900 progerr(ERR_MISSING_PKG_INSTANCE);
901 usage();
902 /*NOTREACHED*/
903 case 2: /* just right! */
904 pkgdev.dirname = argv[optind++];
905 srcinst = argv[optind++];
906 break;
907 default: /* too many args! */
908 progerr(ERR_TOO_MANY_CMD_ARGS);
909 usage();
910 break;
913 (void) pkgparam(NULL, NULL); /* close up prior pkg file if needed */
916 * Initialize installation admin parameters by reading
917 * the adminfile.
920 if (!askflag && !live_continue) {
921 echoDebug(DBG_PKGINSTALL_ADMINFILE, admnfile ? admnfile : "");
922 setadminFile(admnfile);
926 * about to perform first operation that could be modified by the
927 * preinstall check option - if preinstall check is selected (that is,
928 * only gathering dependencies), then output a debug message to
929 * indicate that the check is beginning. Also turn echo() output
930 * off and set various other flags.
933 if (preinstallCheck == B_TRUE) {
934 (void) echoSetFlag(B_FALSE);
935 echoDebug(DBG_PKGINSTALL_PREINSCHK,
936 pkginst ? pkginst : (srcinst ? srcinst : ""),
937 zoneName ? zoneName : "global");
938 cksetPreinstallCheck(B_TRUE);
939 cksetZoneName(zoneName);
940 /* inform quit that the install has started */
941 quitSetInstallStarted(B_TRUE);
945 * validate the "rscriptalt" admin file setting
946 * The rscriptalt admin file parameter may be set to either
947 * RSCRIPTALT_ROOT or RSCRIPTALT_NOACCESS:
948 * --> If rscriptalt is not set, or is set to RSCRIPTALT_NOACCESS,
949 * --> or is set to any value OTHER than RSCRIPTALT_ROOT, then
950 * --> assume that the parameter is set to RSCRIPTALT_NOACCESS
951 * If rscriptalt is set to RSCRIPTALT_ROOT, then run request scripts
952 * as the "root" user if user "install" is not defined.
953 * Otherwise, assume rscriptalt is set to RSCRIPTALT_NOACCESS, and run
954 * request scripts as the "alternative" user if user "install" is not
955 * defined, as appropriate for the current setting of the NONABI_SCRIPTS
956 * environment variable.
959 if (ADMSET(RSCRIPTALT)) {
960 p = adm.RSCRIPTALT;
961 echoDebug(DBG_PKGINSTALL_RSCRIPT_SET_TO, RSCRIPTALT_KEYWORD, p);
962 if (strcasecmp(p, RSCRIPTALT_ROOT) == 0) {
963 /* rscriptalt=root */
964 run_request_as_root = B_TRUE;
965 } else if (strcasecmp(p, RSCRIPTALT_NOACCESS) == 0) {
966 /* rscriptalt=noaccess */
967 run_request_as_root = B_FALSE;
968 } else {
969 /* rscriptalt=??? */
970 logerr(WRN_RSCRIPTALT_BAD, RSCRIPTALT_KEYWORD, p,
971 RSCRIPTALT_ROOT, RSCRIPTALT_NOACCESS);
972 logerr(WRN_RSCRIPTALT_USING, RSCRIPTALT_KEYWORD,
973 RSCRIPTALT_NOACCESS);
974 run_request_as_root = B_FALSE;
976 } else {
977 /* rscriptalt not set - assume rscriptalt=noaccess */
978 echoDebug(DBG_PKGINSTALL_RSCRIPT_NOT_SET, RSCRIPTALT_KEYWORD);
979 run_request_as_root = B_FALSE;
982 echoDebug(DBG_PKGINSTALL_RSCRIPT_IS_ROOT, run_request_as_root);
985 * hook SIGINT and SIGHUP interrupts into quit.c's trap handler
988 /* hold SIGINT/SIGHUP interrupts */
990 (void) sighold(SIGHUP);
991 (void) sighold(SIGINT);
993 /* connect quit.c:trap() to SIGINT */
995 nact.sa_handler = quitGetTrapHandler();
996 nact.sa_flags = SA_RESTART;
997 (void) sigemptyset(&nact.sa_mask);
999 (void) sigaction(SIGINT, &nact, &oact);
1001 /* connect quit.c:trap() to SIGHUP */
1003 nact.sa_handler = quitGetTrapHandler();
1004 nact.sa_flags = SA_RESTART;
1005 (void) sigemptyset(&nact.sa_mask);
1007 (void) sigaction(SIGHUP, &nact, &oact);
1009 /* release hold on signals */
1011 (void) sigrelse(SIGHUP);
1012 (void) sigrelse(SIGINT);
1015 * create required /var... directories if they do not exist;
1016 * this function will call quit(99) if any required path cannot
1017 * be created.
1020 ckdirs();
1022 tzset();
1025 * create path to temporary directory "installXXXXXX" - if TMPDIR
1026 * environment variable is set, create the directory in $TMPDIR;
1027 * otherwise, create the directory in P_tmpdir.
1030 pt = getenv("TMPDIR");
1031 (void) snprintf(tmpdir, sizeof (tmpdir), "%s/installXXXXXX",
1032 ((pt != (char *)NULL) && (*pt != '\0')) ? pt : P_tmpdir);
1034 echoDebug(DBG_PKGINSTALL_TMPDIR, tmpdir);
1036 if ((mktemp(tmpdir) == NULL) || mkdir(tmpdir, 0771)) {
1037 progerr(ERR_MKDIR, tmpdir);
1038 quit(99);
1039 /*NOTREACHED*/
1043 * if the package device is a file containing a package stream,
1044 * unpack the stream into a temporary directory
1047 if ((isdir(pkgdev.dirname) != 0) &&
1048 (pkgdev.cdevice == (char *)NULL) &&
1049 (pkgdev.bdevice == (char *)NULL) &&
1050 (isfile((char *)NULL, pkgdev.dirname) == 0)) {
1052 char *idsName = (char *)NULL;
1053 char *pkgnames[2];
1054 char *device = pkgdev.dirname;
1055 boolean_t b;
1057 echoDebug(DBG_PKGINSTALL_DS_ISFILE, pkgdev.dirname);
1060 * validate the package source device - return pkgdev info that
1061 * describes the package source device.
1064 if (devtype(device, &pkgdev)) {
1065 progerr(ERR_BAD_DEVICE, device);
1066 quit(99);
1067 /* NOTREACHED */
1070 /* generate the list of packages to verify */
1072 pkgnames[0] = srcinst;
1073 pkgnames[1] = (char *)NULL;
1075 b = open_package_datastream(1, pkgnames, (char *)NULL,
1076 pkgdev.dirname, (int *)NULL, &idsName, tmpdir, &pkgdev,
1079 if (b == B_FALSE) {
1080 progerr(ERR_CANNOT_OPEN_PKG_STREAM,
1081 pkgdev.dirname ? pkgdev.dirname : "?");
1082 quit(99);
1083 /*NOTREACHED*/
1086 /* make sure temporary directory is removed on exit */
1088 quitSetDstreamTmpdir(pkgdev.dirname);
1090 /* unpack the package instance from the data stream */
1092 b = unpack_package_from_stream(idsName, srcinst,
1093 pkgdev.dirname);
1094 if (b == B_FALSE) {
1095 progerr(ERR_CANNOT_UNPACK_PKGSTRM,
1096 srcinst ? srcinst : "?",
1097 idsName ? idsName : "?",
1098 pkgdev.dirname ? pkgdev.dirname : "?");
1099 quit(99);
1100 /*NOTREACHED*/
1103 /* close the datastream - no longer needed */
1105 echoDebug(DBG_CLOSING_STREAM, idsName, pkgdev.dirname);
1106 (void) ds_close(1);
1109 if (snprintf(instdir, PATH_MAX, "%s/%s", pkgdev.dirname, srcinst)
1110 >= PATH_MAX) {
1111 progerr(ERR_SNPRINTF, instdir);
1112 quit(99);
1113 /*NOTREACHED*/
1116 zoneName = getenv(PKG_ZONENAME_VARIABLE);
1119 * If the environment has a CLIENT_BASEDIR, that takes precedence
1120 * over anything we will construct. We need to save it here because
1121 * in three lines, the current environment goes away.
1123 (void) set_env_cbdir(); /* copy over environ */
1125 getuserlocale();
1128 * current environment has been read; clear environment out
1129 * so putparam() can be used to populate the new environment
1130 * to be passed to any executables/scripts.
1133 environ = NULL;
1135 /* write parent condition information to environment */
1137 putConditionInfo(parentZoneName, parentZoneType);
1139 putuserlocale();
1141 if (init_install) {
1142 putparam("PKG_INIT_INSTALL", "TRUE");
1145 if (is_an_inst_root()) {
1146 export_client_env(get_inst_root());
1149 if (zoneName != (char *)NULL) {
1150 putparam(PKG_ZONENAME_VARIABLE, zoneName);
1153 putparam("INST_DATADIR", pkgdev.dirname);
1155 if (non_abi_scripts) {
1156 putparam("NONABI_SCRIPTS", "TRUE");
1159 if (nonABI_symlinks()) {
1160 putparam("PKG_NONABI_SYMLINKS", "TRUE");
1163 if (get_ABI_namelngth()) {
1164 putparam("PKG_ABI_NAMELENGTH", "TRUE");
1167 /* establish path and oambase */
1169 if (cmdbin[0] == '\0') {
1170 (void) strlcpy(cmdbin, PKGBIN, sizeof (cmdbin));
1173 (void) snprintf(path, sizeof (path), "%s:%s", DEFPATH, cmdbin);
1175 putparam("PATH", path);
1177 putparam("OAMBASE", OAMBASE);
1179 (void) snprintf(p_pkginfo, sizeof (p_pkginfo),
1180 "%s/%s", instdir, PKGINFO);
1181 (void) snprintf(p_pkgmap, sizeof (p_pkgmap),
1182 "%s/%s", instdir, PKGMAP);
1184 /* Read the environment (from pkginfo or '-e') ... */
1185 abi_nm_ptr = getenv("PKG_ABI_NAMELENGTH");
1187 /* Disable the 32 char name limit extension */
1188 if (abi_nm_ptr && strncasecmp(abi_nm_ptr, "TRUE", 4) == 0) {
1189 (void) set_ABI_namelngth();
1193 * This tests the pkginfo and pkgmap files for validity and
1194 * puts all delivered pkginfo variables (except for PATH) into
1195 * our environment. This is where a delivered pkginfo BASEDIR
1196 * would come from. See set_basedirs() below.
1199 if (pkgenv(srcinst, p_pkginfo, p_pkgmap)) {
1200 quit(1);
1201 /*NOTREACHED*/
1204 echo("\n%s(%s) %s", pkgname, pkgarch, pkgvers);
1207 * If this script was invoked by 'pkgask', just
1208 * execute request script and quit (do_pkgask()).
1211 if (askflag) {
1212 do_pkgask(run_request_as_root);
1215 /* validate package contents file */
1217 if (vcfile() == 0) {
1218 quit(99);
1221 /* if not in dryrun mode aquire packaging lock */
1223 if (!in_dryrun_mode()) {
1224 /* acquire the package lock - at install initialization */
1225 if (!lockinst(get_prog_name(), srcinst, "install-initial")) {
1226 quit(99);
1227 /*NOTREACHED*/
1232 * Now do all the various setups based on ABI compliance
1235 /* Read the environment (from pkginfo or '-o') ... */
1236 abi_comp_ptr = getenv("NONABI_SCRIPTS");
1238 /* Read the environment (from pkginfo or '-y') ... */
1239 abi_sym_ptr = getenv("PKG_NONABI_SYMLINKS");
1241 /* bug id 4244631, not ABI compliant */
1242 if (abi_comp_ptr && strncasecmp(abi_comp_ptr, "TRUE", 4) == 0) {
1243 script_in = PROC_XSTDIN;
1244 non_abi_scripts = 1;
1247 /* Set symlinks to be processed the old way */
1248 if (abi_sym_ptr && strncasecmp(abi_sym_ptr, "TRUE", 4) == 0) {
1249 set_nonABI_symlinks();
1253 * At this point, script_in, non_abi_scripts & the environment are
1254 * all set correctly for the ABI status of the package.
1257 if (pt = getenv("MAXINST")) {
1258 maxinst = atol(pt);
1262 * See if were are installing a package that only wants to update
1263 * the database or only install files associated with CAS's. We
1264 * only check the PKG_HOLLOW_VARIABLE variable if told to do so by
1265 * the caller.
1268 if (is_depend_pkginfo_DB()) {
1269 pt = getenv(PKG_HOLLOW_VARIABLE);
1270 if ((pt != NULL) && (strncasecmp(pt, "true", 4) == 0)) {
1271 echoDebug(DBG_PKGREMOVE_HOLLOW_ENABLED);
1272 if (disableAttributes) {
1273 disable_attribute_check();
1277 * this is a hollow package and hollow package support
1278 * is enabled -- override admin settings to suppress
1279 * checks that do not make sense since no scripts will
1280 * be executed and no files will be installed.
1283 setadminSetting("conflict", "nocheck");
1284 setadminSetting("setuid", "nocheck");
1285 setadminSetting("action", "nocheck");
1286 setadminSetting("partial", "nocheck");
1287 setadminSetting("space", "nocheck");
1288 setadminSetting("authentication", "nocheck");
1289 } else {
1290 echoDebug(DBG_PKGREMOVE_HOLLOW_DISABLED);
1291 set_depend_pkginfo_DB(B_FALSE);
1296 * if performing a fresh install to a non-global zone, and doing
1297 * more than just updating the package database (that is, the
1298 * package to install is NOT "hollow"), then set the global flag
1299 * that directs installation is from partially spooled packages
1300 * (that is, packages installed in the global zone).
1303 if (saveSpoolInstall && (!is_depend_pkginfo_DB())) {
1304 set_partial_inst();
1305 } else {
1306 saveSpoolInstall = 0;
1310 * verify that we are not trying to install an
1311 * INTONLY package with no interaction
1314 if (pt = getenv("INTONLY")) {
1315 if (askflag || nointeract) {
1316 progerr(ERR_INTONLY, pkgabrv ? pkgabrv : "?");
1317 quit(1);
1318 /*NOTREACHED*/
1322 if (!suppressCopyright && !pkgdev.cdevice) {
1323 copyright();
1327 * inspect the system to determine if any instances of the
1328 * package being installed already exist on the system
1331 prvinfo = (struct pkginfo *)calloc(MALSIZ, sizeof (struct pkginfo));
1332 if (prvinfo == NULL) {
1333 progerr(ERR_MEMORY, errno);
1334 quit(99);
1335 /*NOTREACHED*/
1338 for (;;) {
1339 if (pkginfo(&prvinfo[npkgs], pkgwild, NULL, NULL)) {
1340 if ((errno == ESRCH) || (errno == ENOENT)) {
1341 break;
1343 progerr(ERR_SYSINFO, errno);
1344 quit(99);
1345 /*NOTREACHED*/
1347 if ((++npkgs % MALSIZ) == 0) {
1348 prvinfo = (struct pkginfo *)realloc(prvinfo,
1349 (npkgs+MALSIZ) * sizeof (struct pkginfo));
1350 if (prvinfo == NULL) {
1351 progerr(ERR_MEMORY, errno);
1352 quit(99);
1353 /*NOTREACHED*/
1359 * Determine the correct package instance based on how many packages are
1360 * already installed. If there are none (npkgs == 0), getinst() just
1361 * returns the package abbreviation. Otherwise, getinst() interacts with
1362 * the user (or reads the admin file) to determine if an instance which
1363 * is already installed should be overwritten, or possibly install a new
1364 * instance of this package
1367 pkginst = getinst(&update, prvinfo, npkgs, preinstallCheck);
1369 /* set "update flag" if updating an existing instance of this package */
1371 if (update) {
1372 setUpdate();
1376 * Some pkgs (SUNWcsr) already spooled to the zone, check the
1377 * value of UPDATE in their postinstall script. After a pkg
1378 * has been patched UPDATE exists statically in the pkginfo
1379 * file and this value must be reset when installing a zone.
1382 if (saveSpoolInstall != 0 && !isUpdate()) {
1383 putparam("UPDATE", "");
1386 /* inform quit() if updating existing or installing new instance */
1388 quitSetUpdatingExisting(update ? B_TRUE : B_FALSE);
1390 if (respfile) {
1391 (void) set_respfile(respfile, pkginst, RESP_RO);
1394 (void) snprintf(pkgloc, sizeof (pkgloc),
1395 "%s/%s", get_PKGLOC(), pkginst);
1397 (void) snprintf(pkgbin, sizeof (pkgbin),
1398 "%s/install", pkgloc);
1400 (void) snprintf(pkgsav, sizeof (pkgsav),
1401 "%s/save", pkgloc);
1403 if (snprintf(saveSpoolInstallDir, PATH_MAX, "%s/pspool/%s", pkgsav,
1404 pkginst) < 0) {
1405 progerr(ERR_SNPRINTF, saveSpoolInstallDir);
1406 quit(99);
1407 /*NOTREACHED*/
1410 (void) snprintf(ilockfile, sizeof (ilockfile),
1411 "%s/!I-Lock!", pkgloc);
1412 (void) snprintf(rlockfile, sizeof (rlockfile),
1413 "%s/!R-Lock!", pkgloc);
1414 (void) snprintf(savlog, sizeof (savlog),
1415 "%s/logs/%s", get_PKGADM(), pkginst);
1417 putparam("PKGINST", pkginst);
1418 putparam("PKGSAV", pkgsav);
1421 * Be sure request script has access to PKG_INSTALL_ROOT if there is
1422 * one
1425 put_path_params();
1427 if (!map_client) {
1428 putparam("PKG_NO_UNIFIED", "TRUE");
1432 * This maps the client filesystems into the server's space.
1435 if (map_client && !mount_client()) {
1436 logerr(MSG_MANMOUNT);
1440 * If this is an UPDATE then either this is exactly the same version
1441 * and architecture of an installed package or a different package is
1442 * intended to entirely replace an installed package of the same name
1443 * with a different VERSION or ARCH string.
1444 * Don't merge any databases if only gathering dependencies.
1447 if ((preinstallCheck == B_FALSE) && (update)) {
1449 * If this version and architecture is already installed,
1450 * merge the installed and installing parameters and inform
1451 * all procedure scripts by defining UPDATE in the
1452 * environment.
1455 if (is_samepkg()) {
1457 * If it's the same ARCH and VERSION, then a merge
1458 * and copy operation is necessary.
1461 if (n = merg_pkginfos(pclass, &mergd_pclass)) {
1462 quit(n);
1463 /*NOTREACHED*/
1466 if (n = cp_pkgdirs()) {
1467 quit(n);
1468 /*NOTREACHED*/
1471 } else {
1473 * If it's a different ARCH and/or VERSION then this
1474 * is an "instance=overwrite" situation. The
1475 * installed base needs to be confirmed and the
1476 * package directories renamed.
1479 if (n = ck_instbase()) {
1480 quit(n);
1481 /*NOTREACHED*/
1484 if (n = mv_pkgdirs()) {
1485 quit(n);
1486 /*NOTREACHED*/
1490 putparam("UPDATE", "yes");
1494 if (in_dryrun_mode()) {
1495 set_dryrun_dir_loc();
1498 if (preinstallCheck == B_FALSE) {
1500 * Determine if the package has been partially installed on or
1501 * removed from this system.
1503 ck_w_dryrun(ckpartial, PARTIAL);
1506 * make sure current runlevel is appropriate
1508 ck_w_dryrun(ckrunlevel, RUNLEVEL);
1509 } else {
1510 int r;
1513 * Just gathering dependencies - determine if the package has
1514 * been partially installed on or removed from this system and
1515 * output information to stdout
1517 r = ckpartial();
1518 (void) fprintf(stdout, "ckpartialinstall=%d\n", r == 8 ? 1 : 0);
1519 (void) fprintf(stdout, "ckpartialremove=%d\n", r == 9 ? 1 : 0);
1522 * make sure current runlevel is appropriate
1524 r = ckrunlevel();
1525 (void) fprintf(stdout, "ckrunlevel=%d\n", r);
1528 if (pkgdev.cdevice) {
1529 /* get first volume which contains info files */
1530 unpack();
1531 if (!suppressCopyright) {
1532 copyright();
1536 /* update the lock - at the request script */
1538 lockupd("request");
1541 * If no response file has been provided, initialize response file by
1542 * executing any request script provided by this package. Initialize
1543 * the response file if not gathering dependencies only.
1546 if ((!rdonly_respfile()) && (preinstallCheck == B_FALSE)) {
1547 (void) snprintf(path, sizeof (path),
1548 "%s/%s", instdir, REQUEST_FILE);
1549 n = reqexec(update, path, non_abi_scripts,
1550 run_request_as_root);
1551 if (in_dryrun_mode()) {
1552 set_dr_info(REQUESTEXITCODE, n);
1555 ckreturn(n, ERR_REQUEST);
1559 * Look for all parameters in response file which begin with a
1560 * capital letter, and place them in the environment.
1563 if ((is_a_respfile()) && (preinstallCheck == B_FALSE)) {
1564 if (n = merg_respfile()) {
1565 quit(n);
1566 /*NOTREACHED*/
1571 * Run a checkinstall script if one is provided by the package.
1572 * Don't execute checkinstall script if we are only updating the DB.
1573 * Don't execute checkinstall script if only gathering dependencies.
1576 /* update the lock - at the checkinstall script */
1577 lockupd("checkinstall");
1579 /* Execute checkinstall script if one is provided. */
1580 (void) snprintf(script, sizeof (script), "%s/install/checkinstall",
1581 instdir);
1582 if (access(script, F_OK) != 0) {
1583 /* no script present */
1584 echoDebug(DBG_PKGINSTALL_COC_NONE, pkginst, script,
1585 zoneName ? zoneName : "global");
1586 } else if (is_depend_pkginfo_DB()) {
1587 /* updating db only: skip checkinstall script */
1588 echoDebug(DBG_PKGINSTALL_COC_DBUPD, pkginst, script,
1589 zoneName ? zoneName : "global");
1590 } else if (preinstallCheck == B_TRUE) {
1591 /* only gathering dependencies: skip checkinstall script */
1592 echoDebug(DBG_PKGINSTALL_COC_NODEL, pkginst, script,
1593 zoneName ? zoneName : "global");
1594 } else {
1595 /* script present and ok to run: run the script */
1596 if (zoneName == (char *)NULL) {
1597 echo(MSG_PKGINSTALL_EXECOC_GZ);
1598 echoDebug(DBG_PKGINSTALL_EXECOC_GZ, pkginst, script);
1599 } else {
1600 echo(MSG_PKGINSTALL_EXECOC_LZ, zoneName);
1601 echoDebug(DBG_PKGINSTALL_EXECOC_LZ, pkginst, script,
1602 zoneName);
1604 n = chkexec(update, script);
1605 if (in_dryrun_mode()) {
1606 set_dr_info(CHECKEXITCODE, n);
1609 if (n == 3) {
1610 echo(WRN_CHKINSTALL);
1611 ckreturn(4, NULL);
1612 } else if (n == 7) {
1613 /* access returned error */
1614 progerr(ERR_CHKINSTALL_NOSCRIPT, script);
1615 ckreturn(4, ERR_CHKINSTALL);
1616 } else {
1617 ckreturn(n, ERR_CHKINSTALL);
1622 * Now that the internal data structures are initialized, we can
1623 * initialize the dryrun files (which may be the same files).
1626 if (pkgdrtarg) {
1627 init_dryrunfile(pkgdrtarg);
1631 * Look for all parameters in response file which begin with a
1632 * capital letter, and place them in the environment.
1634 if (is_a_respfile()) {
1635 if (n = merg_respfile()) {
1636 quit(n);
1637 /*NOTREACHED*/
1641 /* update the lock - doing analysis */
1643 lockupd("analysis");
1646 * Determine package base directory and client base directory
1647 * if appropriate. Then encapsulate them for future retrieval.
1649 if ((err = set_basedirs(isreloc(instdir), adm.basedir, pkginst,
1650 nointeract)) != 0) {
1651 quit(err);
1652 /*NOTREACHED*/
1656 * Create the base directory if specified.
1657 * Don't create if we are only updating the DB.
1658 * Don't create if only gathering dependencies.
1661 if (!is_depend_pkginfo_DB() &&
1662 !preinstallCheck && is_a_basedir()) {
1663 mkbasedir(!nointeract, get_basedir());
1664 echo(MSG_BASE_USED, get_basedir());
1668 * Store PKG_INSTALL_ROOT, BASEDIR & CLIENT_BASEDIR in our
1669 * environment for later use by procedure scripts.
1671 put_path_params();
1674 * the following two checks are done in the corresponding
1675 * ck() routine, but are repeated here to avoid re-processing
1676 * the database if we are administered to not include these
1677 * processes
1679 if (ADM(setuid, "nochange")) {
1680 nosetuid++; /* Clear setuid/gid bits. */
1683 if (ADM(conflict, "nochange")) {
1684 nocnflct++; /* Don't install conflicting files. */
1688 * Get the filesystem space information for the filesystem on which
1689 * the "contents" file resides.
1692 svfsb.f_bsize = 8192;
1693 svfsb.f_frsize = 1024;
1695 if (statvfs64(get_PKGADM(), &svfsb) == -1) {
1696 int lerrno = errno;
1697 if (!access(get_PKGADM(), F_OK)) {
1698 progerr(ERR_PKGINSTALL_STATVFS, get_PKGADM(),
1699 strerror(errno));
1700 logerr("(errno %d)", lerrno);
1701 quit(99);
1702 /*NOTREACHED*/
1707 * Get the number of blocks used by the pkgmap, ocfile()
1708 * needs this to properly determine its space requirements.
1711 if (stat(p_pkgmap, &statb) == -1) {
1712 progerr(ERR_PKGINSTALL_STATOF, p_pkgmap, strerror(errno));
1713 quit(99);
1714 /*NOTREACHED*/
1717 pkgmap_blks = nblk(statb.st_size, svfsb.f_bsize, svfsb.f_frsize);
1720 * Merge information in memory with the "contents" file; this creates
1721 * a temporary version of the "contents" file. Note that in dryrun
1722 * mode, we still need to record the contents file data somewhere,
1723 * but we do it in the dryrun directory.
1726 if (in_dryrun_mode()) {
1727 if (n = set_cfdir(pkgdrtarg)) {
1728 quit(n);
1729 /*NOTREACHED*/
1731 } else {
1732 if (n = set_cfdir(NULL)) {
1733 quit(n);
1734 /*NOTREACHED*/
1737 if (!ocfile(&pkgserver, &cfTmpVfp, pkgmap_blks)) {
1738 quit(99);
1739 /*NOTREACHED*/
1743 * if cpio is being used, tell pkgdbmerg since attributes will
1744 * have to be check and repaired on all file and directories
1746 for (np = cpio_names; *np != NULL; np++) {
1747 (void) snprintf(path, sizeof (path),
1748 "%s/%s", instdir, *np);
1749 if (iscpio(path, &is_comp_arch)) {
1750 is_WOS_arch();
1751 break;
1755 /* Establish the class list and the class attributes. */
1756 cl_sets(getenv("CLASSES"));
1757 find_CAS(I_ONLY, pkgbin, instdir);
1759 if (vfpOpen(&pkgmapVfp, p_pkgmap, "r", VFP_NEEDNOW) != 0) {
1760 progerr(ERR_PKGMAP, p_pkgmap);
1761 quit(99);
1762 /*NOTREACHED*/
1766 * This modifies the path list entries in memory to reflect
1767 * how they should look after the merg is complete
1770 nparts = sortmap(&extlist, pkgmapVfp, pkgserver, cfTmpVfp, zoneName);
1772 if ((n = files_installed()) > 0) {
1773 if (n > 1) {
1774 echo(MSG_INST_MANY, n);
1775 } else {
1776 echo(MSG_INST_ONE, n);
1781 * Check ulimit requirement (provided in pkginfo). The purpose of
1782 * this limit is to terminate pathological file growth resulting from
1783 * file edits in scripts. It does not apply to files in the pkgmap
1784 * and it does not apply to any database files manipulated by the
1785 * installation service.
1787 if (pt = getenv("ULIMIT")) {
1788 if (assign_ulimit(pt) == -1) {
1789 progerr(ERR_BADULIMIT, pt);
1790 quit(99);
1791 /*NOTREACHED*/
1793 putparam("PKG_ULIMIT", "TRUE");
1797 * If only gathering dependencies, check and output status of all
1798 * remaining dependencies and exit.
1801 if (preinstallCheck == B_TRUE) {
1802 /* update the lock file - final checking */
1804 lockupd("preinstallcheck");
1806 /* verify package information files are not corrupt */
1808 (void) fprintf(stdout, "ckpkgfiles=%d\n", ckpkgfiles());
1810 /* verify package dependencies */
1812 (void) fprintf(stdout, "ckdepend=%d\n", ckdepend());
1814 /* Check space requirements */
1816 (void) fprintf(stdout, "ckspace=%d\n", ckspace());
1819 * Determine if any objects provided by this package conflict
1820 * with the files of previously installed packages.
1823 (void) fprintf(stdout, "ckconflict=%d\n", ckconflct());
1826 * Determine if any objects provided by this package will be
1827 * installed with setuid or setgid enabled.
1830 (void) fprintf(stdout, "cksetuid=%d\n", cksetuid());
1833 * Determine if any packaging scripts provided with this package
1834 * will execute as a priviledged user.
1837 (void) fprintf(stdout, "ckpriv=%d\n", ckpriv());
1839 /* Verify neccessary package installation directories exist */
1841 (void) fprintf(stdout, "ckpkgdirs=%d\n", ckpkgdirs());
1844 * ****** preinstall check done - exit ******
1847 echoDebug(DBG_PKGINSTALL_PREINSCHK_OK);
1848 quit(0);
1849 /*NOTREACHED*/
1853 * Not gathering dependencies only, proceed to check dependencies
1854 * and continue with the package installation operation.
1858 * verify package information files are not corrupt
1860 ck_w_dryrun(ckpkgfiles, PKGFILES);
1863 * verify package dependencies
1865 ck_w_dryrun(ckdepend, DEPEND);
1868 * Check space requirements.
1870 ck_w_dryrun(ckspace, SPACE);
1873 * Determine if any objects provided by this package conflict with
1874 * the files of previously installed packages.
1876 ck_w_dryrun(ckconflct, CONFLICT);
1879 * Determine if any objects provided by this package will be
1880 * installed with setuid or setgid enabled.
1882 ck_w_dryrun(cksetuid, SETUID);
1885 * Determine if any packaging scripts provided with this package will
1886 * execute as a priviledged user.
1888 ck_w_dryrun(ckpriv, PRIV);
1891 * Verify neccessary package installation directories exist.
1893 ck_w_dryrun(ckpkgdirs, PKGDIRS);
1896 * If we have assumed that we were installing setuid or conflicting
1897 * files, and the user chose to do otherwise, we need to read in the
1898 * package map again and re-merg with the "contents" file
1901 if (rprcflag) {
1902 nparts = sortmap(&extlist, pkgmapVfp, pkgserver,
1903 cfTmpVfp, zoneName);
1906 (void) vfpClose(&pkgmapVfp);
1908 /* BEGIN INSTALLATION PHASE */
1909 if (in_dryrun_mode()) {
1910 echo(MSG_PKGINSTALL_DRYRUN, pkgname, pkginst);
1911 } else if (zoneName == (char *)NULL) {
1912 echo(MSG_PKGINSTALL_INSIN_GZ, pkgname, pkginst);
1913 } else {
1914 echo(MSG_PKGINSTALL_INSIN_LZ, pkgname, pkginst, zoneName);
1917 /* inform quit that the install has started */
1919 quitSetInstallStarted(B_TRUE);
1922 * This replaces the contents file with recently created temp version
1923 * which contains information about the objects being installed.
1924 * Under old lock protocol it closes both files and releases the
1925 * locks. Beginning in Solaris 2.7, this lock method should be
1926 * reviewed.
1929 n = swapcfile(pkgserver, &cfTmpVfp, pkginst, dbchg);
1930 if (n == RESULT_WRN) {
1931 warnflag++;
1932 } else if (n == RESULT_ERR) {
1933 quit(99);
1934 /*NOTREACHED*/
1938 * Create install-specific lockfile to indicate start of
1939 * installation. This is really just an information file. If the
1940 * process dies, the initial lockfile (from lockinst(), is
1941 * relinquished by the kernel, but this one remains in support of the
1942 * post-mortem.
1945 if (access(ilockfile, F_OK) == 0) {
1946 (void) remove(ilockfile);
1949 if (open(ilockfile, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL, 0644) < 0) {
1950 progerr(ERR_LOCKFILE, ilockfile);
1951 quit(99);
1952 /*NOTREACHED*/
1955 (void) time(&clock);
1958 * We do not want the time in locale in the pkginfo.
1959 * save the LC_TIME and set it to C. Reset it with saved one
1960 * after cftime().
1962 temp = setlocale(LC_TIME, NULL);
1963 (void) setlocale(LC_TIME, "C");
1965 /* LINTED warning: do not use cftime(); ... */
1966 (void) cftime(cbuf, "%b %d \045Y \045H:\045M", &clock);
1967 putparam("INSTDATE", qstrdup(cbuf));
1968 (void) setlocale(LC_TIME, temp);
1971 * Store information about package being installed;
1972 * modify installation parameters as neccessary and
1973 * copy contents of 'install' directory into $pkgloc
1975 merginfo(mergd_pclass, saveSpoolInstall);
1977 /* If this was just a dryrun, then quit() will write out that file. */
1978 if (in_dryrun_mode()) {
1979 quit(0);
1980 /*NOTREACHED*/
1984 * Execute preinstall script, if one was provided with the
1985 * package. We check the package to avoid running an old
1986 * preinstall script if one was provided with a prior instance.
1987 * Don't execute preinstall script if we are only updating the DB.
1990 /* update the lock - at the preinstall altscript */
1991 lockupd("preinstall");
1993 /* preinstall script in the media (package source) */
1994 (void) snprintf(altscript, sizeof (altscript), "%s/install/preinstall",
1995 instdir);
1997 /* preinstall script in the pkgbin instead of media */
1998 (void) snprintf(script, sizeof (script), "%s/preinstall", pkgbin);
2000 if (access(altscript, F_OK) != 0) {
2001 /* no script present */
2002 echoDebug(DBG_PKGINSTALL_POCALT_NONE, pkginst, altscript,
2003 zoneName ? zoneName : "global");
2004 } else if (access(script, F_OK) != 0) {
2005 /* no script present */
2006 echoDebug(DBG_PKGINSTALL_POC_NONE, pkginst, script,
2007 zoneName ? zoneName : "global");
2008 } else if (is_depend_pkginfo_DB()) {
2009 /* updating db only: skip preinstall script */
2010 echoDebug(DBG_PKGINSTALL_POC_DBUPD, pkginst, script,
2011 zoneName ? zoneName : "global");
2012 } else {
2013 /* script present and ok to run: run the script */
2014 assert(preinstallCheck == B_FALSE);
2016 set_ulimit("preinstall", ERR_PREINSTALL);
2017 if (zoneName == (char *)NULL) {
2018 echo(MSG_PKGINSTALL_EXEPOC_GZ);
2019 echoDebug(DBG_PKGINSTALL_EXEPOC_GZ, pkginst, script);
2020 } else {
2021 echo(MSG_PKGINSTALL_EXEPOC_LZ, zoneName);
2022 echoDebug(DBG_PKGINSTALL_EXEPOC_LZ, pkginst, script,
2023 zoneName);
2025 putparam("PKG_PROC_script", "preinstall");
2026 if (pkgverbose) {
2027 ckreturn(pkgexecl(script_in, PROC_STDOUT,
2028 PROC_USER, PROC_GRP, SHELL, "-x",
2029 script, NULL), ERR_PREINSTALL);
2030 } else {
2031 ckreturn(pkgexecl(script_in, PROC_STDOUT,
2032 PROC_USER, PROC_GRP, SHELL, script,
2033 NULL), ERR_PREINSTALL);
2036 clr_ulimit();
2037 (void) remove(script); /* no longer needed. */
2041 * Check delivered package for a postinstall script while
2042 * we're still on volume 1.
2045 (void) snprintf(script, sizeof (script),
2046 "%s/install/postinstall", instdir);
2047 if (access(script, F_OK) == 0) {
2048 (void) snprintf(script, sizeof (script),
2049 "%s/postinstall", pkgbin);
2050 } else {
2051 script[0] = '\0';
2054 /* update the lock - at the install phase */
2056 lockupd("install");
2059 * install package one part (volume) at a time
2062 part = 1;
2063 while (part <= nparts) {
2064 if ((part > 1) && pkgdev.cdevice) {
2065 unpack();
2068 instvol(extlist, srcinst, part, nparts,
2069 pkgserver, &cfTmpVfp, &updated, zoneName);
2071 if (part++ >= nparts) {
2072 break;
2076 z_destroyMountTable();
2079 * Now that all install class action scripts have been used, we
2080 * delete them from the package directory.
2082 rm_icas(pkgbin);
2084 if (globalZoneOnly) {
2085 boolean_t b;
2086 b = pkgAddPackageToGzonlyList(pkginst, get_inst_root());
2087 if (b == B_FALSE) {
2088 progerr(ERR_PKGINSTALL_GZONLY_ADD, pkginst);
2089 ckreturn(1, NULL);
2094 * Execute postinstall script, if any
2095 * Don't execute postinstall script if we are only updating the DB.
2098 echoDebug(DBG_PKGINSTALL_INSDONE, is_depend_pkginfo_DB(),
2099 is_depend_pkginfo_DB(), saveSpoolInstall,
2100 updated ? updated : "",
2101 script ? script : "",
2102 script ? access(script, F_OK) : -1);
2104 /* update the lock - at the postinstall script */
2105 lockupd("postinstall");
2107 if ((script == (char *)NULL) || (*script == '\0')) {
2108 echoDebug(DBG_PKGINSTALL_POIS_NOPATH, pkginst,
2109 zoneName ? zoneName : "global");
2110 } else if (access(script, F_OK) != 0) {
2111 echoDebug(DBG_PKGINSTALL_POIS_NONE, pkginst, script,
2112 zoneName ? zoneName : "global");
2113 } else if (is_depend_pkginfo_DB()) {
2114 echoDebug(DBG_PKGINSTALL_POIS_DBUPD, pkginst, script,
2115 zoneName ? zoneName : "global");
2116 } else if ((saveSpoolInstall != 0) && (updated == (char *)NULL)) {
2118 * fresh installing into non-global zone, no object was
2119 * updated (installed/verified in area), so do not run
2120 * the postinstall script.
2122 echoDebug(DBG_PKGINSTALL_POIS_NOUPDATING,
2123 zoneName ? zoneName : "global", pkginst, script);
2124 } else {
2125 /* script present and ok to run: run the script */
2126 set_ulimit("postinstall", ERR_POSTINSTALL);
2127 if (zoneName == (char *)NULL) {
2128 echo(MSG_PKGINSTALL_EXEPIC_GZ);
2129 echoDebug(DBG_PKGINSTALL_EXEPIC_GZ, pkginst, script);
2130 } else {
2131 echo(MSG_PKGINSTALL_EXEPIC_LZ, zoneName);
2132 echoDebug(DBG_PKGINSTALL_EXEPIC_LZ, pkginst, script,
2133 zoneName);
2135 putparam("PKG_PROC_SCRIPT", "postinstall");
2136 putparam("TMPDIR", tmpdir);
2137 if (pkgverbose) {
2138 ckreturn(pkgexecl(script_in, PROC_STDOUT,
2139 PROC_USER, PROC_GRP, SHELL, "-x",
2140 script, NULL), ERR_POSTINSTALL);
2141 } else {
2142 ckreturn(pkgexecl(script_in, PROC_STDOUT,
2143 PROC_USER, PROC_GRP, SHELL, script,
2144 NULL), ERR_POSTINSTALL);
2147 clr_ulimit();
2148 (void) remove(script); /* no longer needed */
2151 if (!warnflag && !failflag) {
2152 (void) remove(rlockfile);
2153 (void) remove(ilockfile);
2154 (void) remove(savlog);
2157 /* release the generic package lock */
2159 (void) unlockinst();
2161 pkgcloseserver(pkgserver);
2163 quit(0);
2164 /* LINTED: no return */
2168 * This function merges the environment data in the response file with the
2169 * current environment.
2171 static int
2172 merg_respfile()
2174 int retcode = 0;
2175 char *resppath = get_respfile();
2176 char *locbasedir;
2177 char param[MAX_PKG_PARAM_LENGTH], *value;
2178 FILE *fp;
2180 if ((fp = fopen(resppath, "r")) == NULL) {
2181 progerr(ERR_RESPONSE, resppath);
2182 return (99);
2185 param[0] = '\0';
2187 while (value = fpkgparam(fp, param)) {
2188 if (!isupper(param[0])) {
2189 param[0] = '\0';
2190 continue;
2193 if (rdonly(param)) {
2194 progerr(ERR_RDONLY, param);
2195 param[0] = '\0';
2196 continue;
2200 * If this is an update, and the response file
2201 * specifies the BASEDIR, make sure it matches the
2202 * existing installation base. If it doesn't, we have
2203 * to quit.
2205 if (update && strcmp("BASEDIR", param) == 0) {
2206 locbasedir = getenv("BASEDIR");
2207 if (locbasedir && strcmp(value, locbasedir) != 0) {
2208 char *dotptr;
2209 /* Get srcinst down to a name. */
2210 if (dotptr = strchr(srcinst, '.'))
2211 *dotptr = '\000';
2212 progerr(ERR_NEWBD, srcinst,
2213 locbasedir, value);
2214 retcode = 99;
2218 putparam(param, value);
2219 param[0] = '\0';
2221 (void) fclose(fp);
2223 return (retcode);
2227 * This scans the installed pkginfo file for the current BASEDIR. If this
2228 * BASEDIR is different from the current BASEDIR, there will definitely be
2229 * problems.
2231 static int
2232 ck_instbase(void)
2234 int retcode = 0;
2235 char param[MAX_PKG_PARAM_LENGTH], *value;
2236 char pkginfo_path[PATH_MAX];
2237 FILE *fp;
2239 /* Open the old pkginfo file. */
2240 (void) snprintf(pkginfo_path, sizeof (pkginfo_path),
2241 "%s/%s", pkgloc, PKGINFO);
2242 if ((fp = fopen(pkginfo_path, "r")) == NULL) {
2243 progerr(ERR_PKGINFO, pkginfo_path);
2244 return (99);
2247 param[0] = '\000';
2249 while (value = fpkgparam(fp, param)) {
2250 if (strcmp("BASEDIR", param) == 0) {
2251 if (adm.basedir && *(adm.basedir) &&
2252 strchr("/$", *(adm.basedir))) {
2253 char *dotptr;
2256 * Get srcinst down to a name.
2258 if (dotptr = strchr(srcinst, '.'))
2259 *dotptr = '\000';
2260 if (strcmp(value,
2261 adm.basedir) != 0) {
2262 progerr(ERR_ADMBD, srcinst,
2263 value, adm.basedir);
2264 retcode = 4;
2265 break;
2267 } else if (ADM(basedir, "ask"))
2269 * If it's going to ask later, let it know
2270 * that it *must* agree with the BASEDIR we
2271 * just picked up.
2273 adm.basedir = "update";
2275 putparam(param, value);
2276 break;
2279 param[0] = '\0';
2281 (void) fclose(fp);
2283 return (retcode);
2287 * Since this is an overwrite of a different version of the package, none of
2288 * the old files should remain, so we rename them.
2290 static int
2291 mv_pkgdirs(void)
2294 * If we're not in dryrun mode and we can find an old set of package
2295 * files over which the new ones will be written, do the rename.
2297 if (!in_dryrun_mode() && pkgloc[0] && !access(pkgloc, F_OK)) {
2298 (void) snprintf(pkgloc_sav, sizeof (pkgloc_sav),
2299 "%s/.save.%s", get_PKGLOC(),
2300 pkginst);
2301 if (pkgloc_sav[0] && !access(pkgloc_sav, F_OK)) {
2302 (void) rrmdir(pkgloc_sav);
2305 if (rename(pkgloc, pkgloc_sav) == -1) {
2306 progerr(ERR_PKGBINREN, pkgloc, pkgloc_sav);
2307 return (99);
2311 return (0);
2315 * Name: merg_pkginfos
2316 * Description: This function scans the installed pkginfo and merges that
2317 * environment with the installing environment according to
2318 * the following rules:
2320 * 1. CLASSES is a union of the installed and installing CLASSES
2321 * lists.
2322 * 2. The installed BASEDIR takes precedence. If it doesn't agree
2323 * with an administratively imposed BASEDIR, an ERROR is issued.
2324 * 3. All other installing parameters are preserved.
2325 * 4. All installed parameters are added if they do not overwrite
2326 * an existing installing parameter.
2328 * The current environment contains the pkginfo settings for the
2329 * new package to be installed or to be updated.
2331 * Arguments: pclass - returned list of current classes involved in install
2332 * mpclass - pointer to returned list of current install classes
2333 * Returns: int
2334 * == 0 - all OK
2335 * != 0 - an error code if a fatal error occurred
2338 static int
2339 merg_pkginfos(struct cl_attr **pclass, struct cl_attr ***mpclass)
2341 FILE *fp;
2342 char SUNW_PKG_ALLZONES[MAX_PKG_PARAM_LENGTH] = {'\0'};
2343 char SUNW_PKG_HOLLOW[MAX_PKG_PARAM_LENGTH] = {'\0'};
2344 char SUNW_PKG_THISZONE[MAX_PKG_PARAM_LENGTH] = {'\0'};
2345 char *newValue;
2346 char *oldValue;
2347 char *pkgName;
2348 char *pkgVersion;
2349 char param[MAX_PKG_PARAM_LENGTH];
2350 char pkginfo_path[PATH_MAX];
2351 int retcode = 0;
2353 /* obtain the name of the package (for error messages) */
2355 pkgName = getenv("PKG");
2356 if (pkgName == NULL) {
2357 pkgName = "*current*"; /* default name */
2360 /* obtain the version of the package (for error messages) */
2362 pkgVersion = getenv("VERSION");
2363 if (pkgVersion == NULL) {
2364 pkgVersion = "*current*"; /* default version */
2367 /* open installed package pkginfo file */
2369 (void) snprintf(pkginfo_path, sizeof (pkginfo_path),
2370 "%s/%s", pkgloc, PKGINFO);
2371 if ((fp = fopen(pkginfo_path, "r")) == NULL) {
2372 progerr(ERR_PKGINFO, pkginfo_path);
2373 return (99);
2376 /* entry debugging info */
2378 echoDebug(DBG_MERGINFOS_ENTRY, pkginfo_path);
2381 * cycle through the currently installed package's pkginfo parameters
2382 * and let the currently installed package's settings survive if the
2383 * update to the package does not provide an overriding value
2386 for (param[0] = '\0'; (oldValue = fpkgparam(fp, param)) != NULL;
2387 param[0] = '\0') {
2389 boolean_t setZoneAttribute = B_FALSE;
2391 /* debug info - attribute currently set to value */
2393 echoDebug(DBG_MERGINFOS_SET_TO, param, oldValue);
2396 * if zone package attribute is present in the currently
2397 * installed package, then remember the value for the
2398 * specific zone package attribute, and set the flag that
2399 * indicates a zone package attribute is being processed.
2402 if (strcmp(param, PKG_THISZONE_VARIABLE) == 0) {
2403 /* SUNW_PKG_THISZONE currently set */
2404 setZoneAttribute = B_TRUE;
2405 (void) strlcpy(SUNW_PKG_THISZONE, oldValue,
2406 sizeof (SUNW_PKG_THISZONE));
2407 } else if (strcmp(param, PKG_ALLZONES_VARIABLE) == 0) {
2408 /* SUNW_PKG_ALLZONES currently set */
2409 setZoneAttribute = B_TRUE;
2410 (void) strlcpy(SUNW_PKG_ALLZONES, oldValue,
2411 sizeof (SUNW_PKG_ALLZONES));
2412 } else if (strcmp(param, PKG_HOLLOW_VARIABLE) == 0) {
2413 /* SUNW_PKG_THISZONE currently set */
2414 setZoneAttribute = B_TRUE;
2415 (void) strlcpy(SUNW_PKG_HOLLOW, oldValue,
2416 sizeof (SUNW_PKG_HOLLOW));
2419 /* handle CLASSES currently being set */
2421 if (strcmp(param, "CLASSES") == 0) {
2422 echoDebug(DBG_MERGINFOS_SET_CLASSES, oldValue);
2423 /* create a list of the current classes */
2424 (void) setlist(&pclass, qstrdup(oldValue));
2425 /* set pointer to list of current classes */
2426 *mpclass = pclass;
2427 continue;
2430 /* handle BASEDIR currently being set */
2432 if (strcmp("BASEDIR", param) == 0) {
2433 if (adm.basedir && *(adm.basedir) &&
2434 strchr("/$", *(adm.basedir))) {
2435 char *dotptr;
2437 /* Get srcinst down to a* name */
2439 if (dotptr = strchr(srcinst, '.')) {
2440 *dotptr = '\000';
2442 if (strcmp(oldValue, adm.basedir) != 0) {
2443 progerr(ERR_ADMBD, srcinst,
2444 oldValue, adm.basedir);
2445 /* administration */
2446 retcode = 4;
2447 break;
2449 } else if (ADM(basedir, "ask")) {
2451 * If it's going to ask
2452 * later, let it know that it
2453 * *must* agree with the
2454 * BASEDIR we just picked up.
2456 adm.basedir = "update";
2457 echoDebug(DBG_MERGINFOS_ASK_BASEDIR);
2460 echoDebug(DBG_MERGINFOS_SET_BASEDIR, oldValue);
2461 putparam(param, oldValue);
2462 continue;
2466 * determine if there is a new value for this attribute.
2469 newValue = getenv(param);
2472 * If there is no new value, and a zone attribute
2473 * is being changed, it is the same as setting the zone package
2474 * attribute to 'false' - make sure current setting is 'false'.
2477 if ((newValue == NULL) &&
2478 (setZoneAttribute == B_TRUE) &&
2479 (strcasecmp(oldValue, "false") != 0)) {
2481 /* unset existing non-"false" zone pkg attr */
2482 progerr(ERR_MERGINFOS_UNSET_ZONEATTR,
2483 pkgName, pkgVersion, param, oldValue);
2484 retcode = 1;
2485 break;
2488 /* retain old value if no new value specified */
2490 if (newValue == NULL) {
2491 /* no new value - retain the old value */
2492 echoDebug(DBG_MERGINFOS_RETAIN_OLD, param, oldValue);
2493 putparam(param, oldValue);
2494 continue;
2497 /* note if the old and new values are the same */
2499 if (strcmp(newValue, oldValue) == 0) {
2500 /* set existing package parameter to same value */
2501 echoDebug(DBG_MERGINFOS_SET_DUPLICATE, param, oldValue);
2502 continue;
2506 * Check if old and new values differ.
2507 * Error if zone parameter
2510 if (setZoneAttribute == B_TRUE) {
2511 /* illegal change to zone attribute */
2513 progerr(ERR_MERGINFOS_CHANGE_ZONEATTR, pkgName,
2514 pkgVersion, param, oldValue, newValue);
2516 /* set return code to "fatal error" */
2517 retcode = 1;
2518 break;
2521 /* note valid change to existing package parameter */
2523 echoDebug(DBG_MERGINFOS_SET_CHANGE, param,
2524 oldValue, newValue);
2527 /* close handle on currently installed package's pkginfo file */
2529 (void) fclose(fp);
2531 /* return error if not successful up to this point */
2533 if (retcode != 0) {
2534 echoDebug(DBG_MERGINFOS_EXIT, pkginfo_path, retcode);
2536 return (retcode);
2540 * verify that no zone attribute has been
2541 * set to an invalid value
2544 /* SUNW_PKG_ALLZONES */
2546 newValue = getenv(PKG_ALLZONES_VARIABLE);
2549 * complain if setting SUNW_PKG_ALLZONES to other than "false"
2553 if ((newValue != NULL) && (*SUNW_PKG_ALLZONES == '\0') &&
2554 (strcasecmp(newValue, "false") != 0)) {
2555 /* change ALLZONES from "true" to "false" (unset) */
2556 progerr(ERR_MERGINFOS_SET_ZONEATTR, pkgName,
2557 pkgVersion, PKG_ALLZONES_VARIABLE, newValue);
2558 return (1);
2561 /* SUNW_PKG_THISZONE */
2563 newValue = getenv(PKG_THISZONE_VARIABLE);
2566 * complain if setting SUNW_PKG_THISZONE to other than "false"
2569 if ((newValue != NULL) && (*SUNW_PKG_THISZONE == '\0') &&
2570 (strcasecmp(newValue, "false") != 0)) {
2571 /* change THISZONE from "true" to "false" (unset) */
2572 progerr(ERR_MERGINFOS_SET_ZONEATTR, pkgName,
2573 pkgVersion, PKG_THISZONE_VARIABLE, newValue);
2574 return (1);
2577 /* SUNW_PKG_HOLLOW */
2579 newValue = getenv(PKG_HOLLOW_VARIABLE);
2581 /* complain if setting SUNW_PKG_HOLLOW to other than "false" */
2583 if ((newValue != NULL) && (*SUNW_PKG_HOLLOW == '\0') &&
2584 (strcasecmp(newValue, "false") != 0)) {
2585 /* change HOLLOW from "true" to 'false" (unset) */
2586 progerr(ERR_MERGINFOS_SET_ZONEATTR, pkgName,
2587 pkgVersion, PKG_HOLLOW_VARIABLE, newValue);
2588 return (1);
2591 echoDebug(DBG_MERGINFOS_EXIT, pkginfo_path, 0);
2593 return (0);
2596 static void
2597 set_dryrun_dir_loc(void)
2599 /* Set pkg location to the dryrun directory */
2600 set_PKGLOC(pkgdrtarg);
2601 (void) snprintf(pkgloc, sizeof (pkgloc),
2602 "%s/%s", get_PKGLOC(), pkginst);
2603 (void) snprintf(pkgbin, sizeof (pkgbin),
2604 "%s/install", pkgloc);
2605 (void) snprintf(pkgsav, sizeof (pkgsav),
2606 "%s/save", pkgloc);
2607 (void) snprintf(ilockfile, sizeof (ilockfile),
2608 "%s/!I-Lock!", pkgloc);
2609 (void) snprintf(rlockfile, sizeof (rlockfile),
2610 "%s/!R-Lock!", pkgloc);
2611 (void) snprintf(savlog, sizeof (savlog),
2612 "%s/logs/%s", get_PKGADM(), pkginst);
2616 * If we are updating a pkg, then we need to copy the "old" pkgloc so that
2617 * any scripts that got removed in the new version aren't left around. So we
2618 * copy it here to .save.pkgloc, then in quit() we can restore our state, or
2619 * remove it.
2621 static int
2622 cp_pkgdirs(void)
2624 if (in_dryrun_mode()) {
2625 set_dryrun_dir_loc();
2629 * If we're not in dryrun mode and we can find an old set of package
2630 * files over which the new ones will be written, do the copy.
2632 if (!in_dryrun_mode() && pkgloc[0] && !access(pkgloc, F_OK)) {
2633 int status;
2634 int r;
2636 (void) snprintf(pkgloc_sav, sizeof (pkgloc_sav), "%s/.save.%s",
2637 get_PKGLOC(), pkginst);
2640 * Even though it takes a while, we use a recursive copy here
2641 * because if the current pkgadd fails for any reason, we
2642 * don't want to lose this data.
2644 r = e_ExecCmdList(&status, (char **)NULL, (char *)NULL,
2645 "/usr/bin/cp", "cp", "-r", pkgloc, pkgloc_sav,
2646 (char *)NULL);
2648 if ((r != 0) || (status == -1) || (WEXITSTATUS(status) != 0)) {
2649 progerr(ERR_PKGBINCP, pkgloc, pkgloc_sav);
2650 return (99);
2654 return (0);
2658 * This implements the pkgask function. It just executes the request script
2659 * and stores the results in a response file.
2661 static void
2662 do_pkgask(boolean_t a_run_request_as_root)
2664 if (pkgdev.cdevice) {
2665 unpack();
2666 if (!suppressCopyright) {
2667 copyright();
2670 (void) snprintf(path, sizeof (path), "%s/%s", instdir, REQUEST_FILE);
2671 if (access(path, F_OK)) {
2672 progerr(ERR_NOREQUEST);
2673 quit(1);
2674 /*NOTREACHED*/
2677 (void) set_respfile(respfile, srcinst, RESP_WR);
2679 if (is_a_respfile()) {
2680 ckreturn(reqexec(update, path, non_abi_scripts,
2681 a_run_request_as_root), ERR_REQUEST);
2682 } else {
2683 failflag++;
2686 if (warnflag || failflag) {
2687 (void) remove(respfile);
2688 echo("\nResponse file <%s> was not created.",
2689 get_respfile());
2690 } else {
2691 echo("\nResponse file <%s> was created.",
2692 get_respfile());
2695 quit(0);
2696 /*NOTREACHED*/
2700 * This function runs a check utility and acts appropriately based upon the
2701 * return code. It deals appropriately with the dryrun file if it is present.
2703 static void
2704 ck_w_dryrun(int (*func)(), int type)
2706 int n;
2708 n = func();
2709 if (in_dryrun_mode())
2710 set_dr_info(type, !n);
2712 if (n) {
2713 quit(n);
2714 /*NOTREACHED*/
2719 * This function deletes all install class action scripts from the package
2720 * directory on the root filesystem.
2722 static void
2723 rm_icas(char *cas_dir)
2725 DIR *pdirfp;
2726 struct dirent *dp;
2727 char path[PATH_MAX];
2729 if ((pdirfp = opendir(cas_dir)) == NULL)
2730 return;
2732 while ((dp = readdir(pdirfp)) != NULL) {
2733 if (dp->d_name[0] == '.')
2734 continue;
2736 if (dp->d_name[0] == 'i' && dp->d_name[1] == '.') {
2737 (void) snprintf(path, sizeof (path),
2738 "%s/%s", cas_dir, dp->d_name);
2739 (void) remove(path);
2742 (void) closedir(pdirfp);
2745 void
2746 ckreturn(int retcode, char *msg)
2748 switch (retcode) {
2749 case 2:
2750 case 12:
2751 case 22:
2752 warnflag++;
2753 if (msg) {
2754 progerr("%s", msg);
2756 /*FALLTHRU*/
2757 case 10:
2758 case 20:
2759 if (retcode >= 10 && retcode < 20) {
2760 dreboot++;
2762 if (retcode >= 20) {
2763 ireboot++;
2765 /*FALLTHRU*/
2766 case 0:
2767 break; /* okay */
2769 case -1:
2770 retcode = 99;
2771 /*FALLTHRU*/
2772 case 99:
2773 case 1:
2774 case 11:
2775 case 21:
2776 case 4:
2777 case 14:
2778 case 24:
2779 case 5:
2780 case 15:
2781 case 25:
2782 if (msg) {
2783 progerr("%s", msg);
2785 /*FALLTHRU*/
2786 case 3:
2787 case 13:
2788 case 23:
2789 quit(retcode);
2790 /*NOTREACHED*/
2791 default:
2792 if (msg) {
2793 progerr("%s", msg);
2795 quit(1);
2796 /*NOTREACHED*/
2800 static void
2801 copyright(void)
2803 FILE *fp;
2804 char line[LSIZE];
2805 char path[PATH_MAX];
2807 /* Compose full path for copyright file */
2808 (void) snprintf(path, sizeof (path), "%s/%s", instdir, COPYRIGHT_FILE);
2810 if ((fp = fopen(path, "r")) == NULL) {
2811 if (getenv("VENDOR") != NULL)
2812 echo(getenv("VENDOR"));
2813 } else {
2814 while (fgets(line, LSIZE, fp))
2815 (void) fprintf(stdout, "%s", line); /* bug #1083713 */
2816 (void) fclose(fp);
2820 static int
2821 rdonly(char *p)
2823 int i;
2825 for (i = 0; ro_params[i]; i++) {
2826 if (strcmp(p, ro_params[i]) == 0)
2827 return (1);
2829 return (0);
2832 static void
2833 unpack(void)
2836 * read in next part from stream, even if we decide
2837 * later that we don't need it
2839 if (dparts < 1) {
2840 progerr(ERR_DSTREAMCNT);
2841 quit(99);
2842 /*NOTREACHED*/
2844 if ((access(instdir, F_OK) == 0) && rrmdir(instdir)) {
2845 progerr(ERR_RMDIR, instdir);
2846 quit(99);
2847 /*NOTREACHED*/
2849 if (mkdir(instdir, 0755)) {
2850 progerr(ERR_MKDIR, instdir);
2851 quit(99);
2852 /*NOTREACHED*/
2854 if (chdir(instdir)) {
2855 progerr(ERR_CHDIR, instdir);
2856 quit(99);
2857 /*NOTREACHED*/
2859 if (!ds_fd_open()) {
2860 dparts = ds_findpkg(pkgdev.cdevice, srcinst);
2861 if (dparts < 1) {
2862 progerr(ERR_DSARCH, srcinst);
2863 quit(99);
2864 /*NOTREACHED*/
2868 dparts--;
2870 if (ds_next(pkgdev.cdevice, instdir)) {
2871 progerr(ERR_DSTREAM);
2872 quit(99);
2873 /*NOTREACHED*/
2875 if (chdir(get_PKGADM())) {
2876 progerr(ERR_CHDIR, get_PKGADM());
2877 quit(99);
2878 /*NOTREACHED*/
2880 ds_close(1);
2883 static void
2884 usage(void)
2886 (void) fprintf(stderr, ERR_USAGE_PKGINSTALL);
2887 exit(1);
2888 /*NOTREACHED*/