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