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), 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); 105 106 void ckreturn(int retcode, char *msg); 107 108 static char *ro_params[] = { 109 "PATH", "NAME", "PKG", "PKGINST", 110 "VERSION", "ARCH", 111 "INSTDATE", "CATEGORY", 112 NULL 113 }; 114 115 /* 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 121 */ 122 static char *script_in = PROC_STDIN; /* assume ABI compliance */ 123 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; 131 132 /* exported globals */ 133 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; 163 164 /* 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 176 */ 177 static int update = 0; 178 179 /* Set by -O debug: debug output is enabled? */ 180 181 static boolean_t debugFlag = B_FALSE; 182 183 /* Set by the -G option: install packages in global zone only */ 184 185 static boolean_t globalZoneOnly = B_FALSE; 186 187 /* Set by -O preinstallcheck */ 188 189 static boolean_t preinstallCheck = B_FALSE; 190 191 /* Set by -O parent-zone-name= */ 192 193 static char *parentZoneName = (char *)NULL; 194 195 /* Set by -O parent-zone-type= */ 196 197 static char *parentZoneType = (char *)NULL; 198 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 */ 202 203 #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */ 204 #define TEXT_DOMAIN "SYS_TEST" 205 #endif 206 207 /* This is the text for the "-O parent-zone-name=" option */ 208 209 #define PARENTZONENAME "parent-zone-name=" 210 #define PARENTZONENAME_LEN ((sizeof (PARENTZONENAME))-1) 211 212 /* This is the text for the "-O parent-zone-type=" option */ 213 214 #define PARENTZONETYPE "parent-zone-type=" 215 #define PARENTZONETYPE_LEN ((sizeof (PARENTZONETYPE))-1) 216 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", 226 0 227 }; 228 229 int 230 main(int argc, char *argv[]) 231 { 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; 277 278 /* reset contents of all default paths */ 279 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)); 285 286 /* initialize locale environment */ 287 288 (void) setlocale(LC_ALL, ""); 289 (void) textdomain(TEXT_DOMAIN); 290 291 /* initialize program name */ 292 293 prog_full_name = argv[0]; 294 (void) set_prog_name(argv[0]); 295 296 /* tell spmi zones interface how to access package output functions */ 297 298 z_set_output_functions(echo, echoDebug, progerr); 299 300 /* exit if not root */ 301 302 if (getuid()) { 303 progerr(ERR_NOT_ROOT, get_prog_name()); 304 exit(1); 305 /* NOTREACHED */ 306 } 307 308 /* 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 314 */ 315 316 setmapmode(MAPINSTALL); 317 318 /* set sane umask */ 319 320 (void) umask(0022); 321 322 /* initially no source "device" */ 323 324 device = NULL; 325 326 /* reset npkgs (used as pkg remaining count in quit.c) */ 327 328 npkgs = 0; 329 330 /* Read PKG_INSTALL_ROOT from the environment, if it's there. */ 331 332 if (!set_inst_root(getenv("PKG_INSTALL_ROOT"))) { 333 progerr(ERR_ROOT_SET); 334 exit(1); 335 } 336 337 pkgserversetmode(DEFAULTMODE); 338 339 /* parse command line options */ 340 341 while ((c = getopt(argc, argv, 342 "?Aa:B:b:Cc:D:d:eFf:GhIiMm:N:noO:p:R:r:StV:vyz")) != EOF) { 343 344 switch (c) { 345 346 /* 347 * Same as pkgadd: This disables attribute checking. 348 * It speeds up installation a little bit. 349 */ 350 case 'A': 351 disableAttributes++; 352 break; 353 354 /* 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. 365 */ 366 case 'a': 367 admnfile = flex_device(optarg, 0); 368 break; 369 370 /* 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. 374 */ 375 case 'B': 376 rw_block_size = optarg; 377 break; 378 379 /* 380 * Same as pkgadd: location where executables needed 381 * by procedure scripts can be found 382 * default is /usr/sadm/install/bin. 383 */ 384 case 'b': 385 if (!path_valid(optarg)) { 386 progerr(ERR_PATH, optarg); 387 exit(1); 388 } 389 if (isdir(optarg) != 0) { 390 char *p = strerror(errno); 391 progerr(ERR_CANNOT_USE_DIR, optarg, p); 392 exit(1); 393 } 394 (void) strlcpy(cmdbin, optarg, sizeof (cmdbin)); 395 break; 396 397 /* 398 * Same as pkgadd: This disables checksum tests on 399 * the source files. It speeds up installation a little bit. 400 */ 401 case 'C': 402 (void) checksum_off(); 403 break; 404 405 /* 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. 409 */ 410 case 'c': 411 pkgcontsrc = optarg; 412 set_continue_mode(); 413 set_dr_info(DR_TYPE, INSTALL_TYPE); 414 init_contfile(pkgcontsrc); 415 break; 416 417 /* 418 * Same as pkgadd: This allows designation of a 419 * dryrun file. This pkgadd will create dryrun files 420 * in the directory provided. 421 */ 422 case 'D': 423 pkgdrtarg = optarg; 424 set_dryrun_mode(); 425 set_dr_info(DR_TYPE, INSTALL_TYPE); 426 break; 427 428 /* 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. 435 */ 436 case 'd': 437 device = flex_device(optarg, 1); 438 break; 439 440 /* 441 * Different from pkgadd: disable the 32 char name 442 * limit extension 443 */ 444 case 'e': 445 (void) set_ABI_namelngth(); 446 break; 447 448 /* 449 * Different from pkgadd: specify file system type for 450 * the package device. Must be used with -m. 451 */ 452 case 'f': 453 pkgdev.fstyp = optarg; 454 break; 455 456 /* 457 * Same as pkgadd: install package in global zone only. 458 */ 459 case 'G': 460 globalZoneOnly = B_TRUE; 461 break; 462 463 /* 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. 472 */ 473 case 'h': 474 set_depend_pkginfo_DB(B_TRUE); 475 break; 476 477 /* 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. 483 */ 484 case 'I': 485 init_install++; 486 break; 487 488 /* 489 * Different from pkgadd: use by pkgask. 490 */ 491 case 'i': 492 askflag++; 493 quitSetPkgask(B_TRUE); 494 break; 495 496 /* 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. 502 */ 503 case 'M': 504 map_client = 0; 505 break; 506 507 /* 508 * Different from pkgadd: specify device to use for package 509 * source. 510 */ 511 case 'm': 512 pkgdev.mount = optarg; 513 pkgdev.rdonly++; 514 pkgdev.mntflg++; 515 break; 516 517 /* 518 * Different from pkgadd: specify program name to use 519 * for messages. 520 */ 521 case 'N': 522 (void) set_prog_name(optarg); 523 break; 524 525 /* 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. 529 */ 530 case 'n': 531 nointeract++; 532 (void) echoSetFlag(B_FALSE); 533 break; 534 535 /* 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 555 */ 556 case 'O': 557 for (p = strtok(optarg, ","); p != (char *)NULL; 558 p = strtok(NULL, ",")) { 559 560 /* process debug option */ 561 562 if (strcmp(p, "debug") == 0) { 563 /* set debug flag/enable debug output */ 564 if (debugFlag == B_TRUE) { 565 smlSetVerbose(B_TRUE); 566 } 567 debugFlag = B_TRUE; 568 (void) echoDebugSetFlag(debugFlag); 569 570 /* debug info on arguments to pkgadd */ 571 for (n = 0; n < argc && argv[n]; n++) { 572 echoDebug(DBG_ARG, n, argv[n]); 573 } 574 575 continue; 576 } 577 578 /* process enable-hollow-package-support opt */ 579 580 if (strcmp(p, 581 "enable-hollow-package-support") == 0) { 582 set_depend_pkginfo_DB(B_TRUE); 583 continue; 584 } 585 586 /* process preinstallcheck option */ 587 588 if (strcmp(p, "preinstallcheck") == 0) { 589 preinstallCheck = B_TRUE; 590 nointeract++; /* -n */ 591 suppressCopyright++; /* -S */ 592 quitSetSilentExit(B_TRUE); 593 continue; 594 } 595 596 /* process addzonename option */ 597 598 if (strcmp(p, "addzonename") == 0) { 599 /* 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 605 */ 606 zoneName = 607 getenv(PKG_ZONENAME_VARIABLE); 608 609 if ((zoneName == (char *)NULL) || 610 (*zoneName == '\0')) { 611 zoneName = z_get_zonename(); 612 } 613 614 if (zoneName != (char *)NULL) { 615 if (*zoneName != '\0') { 616 quitSetZoneName( 617 zoneName); 618 } else { 619 zoneName = (char *)NULL; 620 } 621 } 622 continue; 623 } 624 625 /* process parent-zone-name option */ 626 627 if (strncmp(p, PARENTZONENAME, 628 PARENTZONENAME_LEN) == 0) { 629 parentZoneName = p+PARENTZONENAME_LEN; 630 continue; 631 } 632 633 /* process parent-zone-type option */ 634 635 if (strncmp(p, PARENTZONETYPE, 636 PARENTZONETYPE_LEN) == 0) { 637 parentZoneType = p+PARENTZONETYPE_LEN; 638 continue; 639 } 640 641 if (strncmp(p, PKGSERV_MODE, 642 PKGSERV_MODE_LEN) == 0) { 643 pkgserversetmode(pkgparsemode(p + 644 PKGSERV_MODE_LEN)); 645 continue; 646 } 647 648 /* option not recognized - issue warning */ 649 650 progerr(ERR_INVALID_O_OPTION, p); 651 continue; 652 653 } 654 break; 655 656 /* 657 * Different from pkgadd: This is an old non-ABI package 658 */ 659 case 'o': 660 non_abi_scripts++; 661 break; 662 663 /* 664 * Different from pkgadd: specify number of parts to package. 665 */ 666 case 'p': 667 dparts = ds_getinfo(optarg); 668 break; 669 670 /* 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). 678 */ 679 case 'R': 680 if (!set_inst_root(optarg)) { 681 progerr(ERR_ROOT_CMD); 682 exit(1); 683 } 684 break; 685 686 /* 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. 692 */ 693 case 'r': 694 respfile = flex_device(optarg, 2); 695 break; 696 697 /* 698 * Same as pkgadd: suppress copyright notice being 699 * output during installation. 700 */ 701 case 'S': 702 suppressCopyright++; 703 break; 704 705 /* 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). 710 */ 711 case 't': 712 disable_spool_create(); 713 break; 714 715 /* 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. 722 */ 723 case 'V': 724 vfstab_file = flex_device(optarg, 2); 725 map_client = 1; 726 break; 727 728 /* 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 733 */ 734 case 'v': 735 pkgverbose++; 736 break; 737 738 /* 739 * Different from pkgadd: process this package using 740 * old non-ABI symlinks 741 */ 742 case 'y': 743 set_nonABI_symlinks(); 744 break; 745 746 /* 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. 763 */ 764 case 'z': 765 saveSpoolInstall++; 766 break; 767 768 /* 769 * unrecognized option 770 */ 771 default: 772 usage(); 773 /*NOTREACHED*/ 774 /* 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. 779 */ 780 return (1); 781 } 782 } 783 784 /* 785 * ******************************************************************** 786 * validate command line options 787 * ******************************************************************** 788 */ 789 790 /* set "debug echo" flag according to setting of "-O debug" option */ 791 792 (void) echoDebugSetFlag(debugFlag); 793 (void) log_set_verbose(debugFlag); 794 795 /* output entry debugging information */ 796 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()); 802 } 803 804 if (in_continue_mode() && !in_dryrun_mode()) { 805 progerr(ERR_LIVE_CONTINUE_NOT_SUPPORTED); 806 usage(); 807 /*NOTREACHED*/ 808 } 809 810 /* pkgask requires a response file */ 811 812 if (askflag && (respfile == NULL)) { 813 usage(); 814 /*NOTREACHED*/ 815 } 816 817 /* if device specified, set appropriate device in pkgdev */ 818 819 if (device) { 820 if (pkgdev.mount) { 821 pkgdev.bdevice = device; 822 } else { 823 pkgdev.cdevice = device; 824 } 825 } 826 827 /* if file system type specified, must have a device to mount */ 828 829 if (pkgdev.fstyp && !pkgdev.mount) { 830 progerr(ERR_F_REQUIRES_M); 831 usage(); 832 /*NOTREACHED*/ 833 } 834 835 /* BEGIN DATA GATHERING PHASE */ 836 837 /* 838 * Get the mount table info and store internally. 839 */ 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*/ 847 } 848 if (!in_dryrun_mode()) { 849 live_continue = 1; 850 } 851 } 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*/ 857 } 858 } 859 860 /* 861 * This function defines the standard /var/... directories used later 862 * to construct the paths to the various databases. 863 */ 864 865 set_PKGpaths(get_inst_root()); 866 867 /* 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. 873 */ 874 if (is_an_inst_root()) { 875 int fsys_value; 876 877 fsys_value = fsys(get_PKGLOC()); 878 if (use_srvr_map_n(fsys_value)) 879 set_PKGLOC(server_map(get_PKGLOC(), fsys_value)); 880 881 fsys_value = fsys(get_PKGADM()); 882 if (use_srvr_map_n(fsys_value)) 883 set_PKGADM(server_map(get_PKGADM(), fsys_value)); 884 } 885 886 /* 887 * Initialize pkginfo PKGSAV entry, just in case we dryrun to 888 * somewhere else. 889 */ 890 set_infoloc(get_PKGLOC()); 891 892 /* pull off directory and package name from end of command line */ 893 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; 911 } 912 913 (void) pkgparam(NULL, NULL); /* close up prior pkg file if needed */ 914 915 /* 916 * Initialize installation admin parameters by reading 917 * the adminfile. 918 */ 919 920 if (!askflag && !live_continue) { 921 echoDebug(DBG_PKGINSTALL_ADMINFILE, admnfile ? admnfile : ""); 922 setadminFile(admnfile); 923 } 924 925 /* 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. 931 */ 932 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); 942 } 943 944 /* 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. 957 */ 958 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; 975 } 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; 980 } 981 982 echoDebug(DBG_PKGINSTALL_RSCRIPT_IS_ROOT, run_request_as_root); 983 984 /* 985 * hook SIGINT and SIGHUP interrupts into quit.c's trap handler 986 */ 987 988 /* hold SIGINT/SIGHUP interrupts */ 989 990 (void) sighold(SIGHUP); 991 (void) sighold(SIGINT); 992 993 /* connect quit.c:trap() to SIGINT */ 994 995 nact.sa_handler = quitGetTrapHandler(); 996 nact.sa_flags = SA_RESTART; 997 (void) sigemptyset(&nact.sa_mask); 998 999 (void) sigaction(SIGINT, &nact, &oact); 1000 1001 /* connect quit.c:trap() to SIGHUP */ 1002 1003 nact.sa_handler = quitGetTrapHandler(); 1004 nact.sa_flags = SA_RESTART; 1005 (void) sigemptyset(&nact.sa_mask); 1006 1007 (void) sigaction(SIGHUP, &nact, &oact); 1008 1009 /* release hold on signals */ 1010 1011 (void) sigrelse(SIGHUP); 1012 (void) sigrelse(SIGINT); 1013 1014 /* 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. 1018 */ 1019 1020 ckdirs(); 1021 1022 tzset(); 1023 1024 /* 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. 1028 */ 1029 1030 pt = getenv("TMPDIR"); 1031 (void) snprintf(tmpdir, sizeof (tmpdir), "%s/installXXXXXX", 1032 ((pt != (char *)NULL) && (*pt != '\0')) ? pt : P_tmpdir); 1033 1034 echoDebug(DBG_PKGINSTALL_TMPDIR, tmpdir); 1035 1036 if ((mktemp(tmpdir) == NULL) || mkdir(tmpdir, 0771)) { 1037 progerr(ERR_MKDIR, tmpdir); 1038 quit(99); 1039 /*NOTREACHED*/ 1040 } 1041 1042 /* 1043 * if the package device is a file containing a package stream, 1044 * unpack the stream into a temporary directory 1045 */ 1046 1047 if ((isdir(pkgdev.dirname) != 0) && 1048 (pkgdev.cdevice == (char *)NULL) && 1049 (pkgdev.bdevice == (char *)NULL) && 1050 (isfile((char *)NULL, pkgdev.dirname) == 0)) { 1051 1052 char *idsName = (char *)NULL; 1053 char *pkgnames[2]; 1054 char *device = pkgdev.dirname; 1055 boolean_t b; 1056 1057 echoDebug(DBG_PKGINSTALL_DS_ISFILE, pkgdev.dirname); 1058 1059 /* 1060 * validate the package source device - return pkgdev info that 1061 * describes the package source device. 1062 */ 1063 1064 if (devtype(device, &pkgdev)) { 1065 progerr(ERR_BAD_DEVICE, device); 1066 quit(99); 1067 /* NOTREACHED */ 1068 } 1069 1070 /* generate the list of packages to verify */ 1071 1072 pkgnames[0] = srcinst; 1073 pkgnames[1] = (char *)NULL; 1074 1075 b = open_package_datastream(1, pkgnames, (char *)NULL, 1076 pkgdev.dirname, (int *)NULL, &idsName, tmpdir, &pkgdev, 1077 1); 1078 1079 if (b == B_FALSE) { 1080 progerr(ERR_CANNOT_OPEN_PKG_STREAM, 1081 pkgdev.dirname ? pkgdev.dirname : "?"); 1082 quit(99); 1083 /*NOTREACHED*/ 1084 } 1085 1086 /* make sure temporary directory is removed on exit */ 1087 1088 quitSetDstreamTmpdir(pkgdev.dirname); 1089 1090 /* unpack the package instance from the data stream */ 1091 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*/ 1101 } 1102 1103 /* close the datastream - no longer needed */ 1104 1105 echoDebug(DBG_CLOSING_STREAM, idsName, pkgdev.dirname); 1106 (void) ds_close(1); 1107 } 1108 1109 if (snprintf(instdir, PATH_MAX, "%s/%s", pkgdev.dirname, srcinst) 1110 >= PATH_MAX) { 1111 progerr(ERR_SNPRINTF, instdir); 1112 quit(99); 1113 /*NOTREACHED*/ 1114 } 1115 1116 zoneName = getenv(PKG_ZONENAME_VARIABLE); 1117 1118 /* 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. 1122 */ 1123 (void) set_env_cbdir(); /* copy over environ */ 1124 1125 getuserlocale(); 1126 1127 /* 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. 1131 */ 1132 1133 environ = NULL; 1134 1135 /* write parent condition information to environment */ 1136 1137 putConditionInfo(parentZoneName, parentZoneType); 1138 1139 putuserlocale(); 1140 1141 if (init_install) { 1142 putparam("PKG_INIT_INSTALL", "TRUE"); 1143 } 1144 1145 if (is_an_inst_root()) { 1146 export_client_env(get_inst_root()); 1147 } 1148 1149 if (zoneName != (char *)NULL) { 1150 putparam(PKG_ZONENAME_VARIABLE, zoneName); 1151 } 1152 1153 putparam("INST_DATADIR", pkgdev.dirname); 1154 1155 if (non_abi_scripts) { 1156 putparam("NONABI_SCRIPTS", "TRUE"); 1157 } 1158 1159 if (nonABI_symlinks()) { 1160 putparam("PKG_NONABI_SYMLINKS", "TRUE"); 1161 } 1162 1163 if (get_ABI_namelngth()) { 1164 putparam("PKG_ABI_NAMELENGTH", "TRUE"); 1165 } 1166 1167 /* establish path and oambase */ 1168 1169 if (cmdbin[0] == '\0') { 1170 (void) strlcpy(cmdbin, PKGBIN, sizeof (cmdbin)); 1171 } 1172 1173 (void) snprintf(path, sizeof (path), "%s:%s", DEFPATH, cmdbin); 1174 1175 putparam("PATH", path); 1176 1177 putparam("OAMBASE", OAMBASE); 1178 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); 1183 1184 /* Read the environment (from pkginfo or '-e') ... */ 1185 abi_nm_ptr = getenv("PKG_ABI_NAMELENGTH"); 1186 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(); 1190 } 1191 1192 /* 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. 1197 */ 1198 1199 if (pkgenv(srcinst, p_pkginfo, p_pkgmap)) { 1200 quit(1); 1201 /*NOTREACHED*/ 1202 } 1203 1204 echo("\n%s(%s) %s", pkgname, pkgarch, pkgvers); 1205 1206 /* 1207 * If this script was invoked by 'pkgask', just 1208 * execute request script and quit (do_pkgask()). 1209 */ 1210 1211 if (askflag) { 1212 do_pkgask(run_request_as_root); 1213 } 1214 1215 /* validate package contents file */ 1216 1217 if (vcfile() == 0) { 1218 quit(99); 1219 } 1220 1221 /* if not in dryrun mode aquire packaging lock */ 1222 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*/ 1228 } 1229 } 1230 1231 /* 1232 * Now do all the various setups based on ABI compliance 1233 */ 1234 1235 /* Read the environment (from pkginfo or '-o') ... */ 1236 abi_comp_ptr = getenv("NONABI_SCRIPTS"); 1237 1238 /* Read the environment (from pkginfo or '-y') ... */ 1239 abi_sym_ptr = getenv("PKG_NONABI_SYMLINKS"); 1240 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; 1245 } 1246 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(); 1250 } 1251 1252 /* 1253 * At this point, script_in, non_abi_scripts & the environment are 1254 * all set correctly for the ABI status of the package. 1255 */ 1256 1257 if (pt = getenv("MAXINST")) { 1258 maxinst = atol(pt); 1259 } 1260 1261 /* 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. 1266 */ 1267 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(); 1274 } 1275 1276 /* 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. 1281 */ 1282 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); 1292 } 1293 } 1294 1295 /* 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). 1301 */ 1302 1303 if (saveSpoolInstall && (!is_depend_pkginfo_DB())) { 1304 set_partial_inst(); 1305 } else { 1306 saveSpoolInstall = 0; 1307 } 1308 1309 /* 1310 * verify that we are not trying to install an 1311 * INTONLY package with no interaction 1312 */ 1313 1314 if (pt = getenv("INTONLY")) { 1315 if (askflag || nointeract) { 1316 progerr(ERR_INTONLY, pkgabrv ? pkgabrv : "?"); 1317 quit(1); 1318 /*NOTREACHED*/ 1319 } 1320 } 1321 1322 if (!suppressCopyright && !pkgdev.cdevice) { 1323 copyright(); 1324 } 1325 1326 /* 1327 * inspect the system to determine if any instances of the 1328 * package being installed already exist on the system 1329 */ 1330 1331 prvinfo = (struct pkginfo *)calloc(MALSIZ, sizeof (struct pkginfo)); 1332 if (prvinfo == NULL) { 1333 progerr(ERR_MEMORY, errno); 1334 quit(99); 1335 /*NOTREACHED*/ 1336 } 1337 1338 for (;;) { 1339 if (pkginfo(&prvinfo[npkgs], pkgwild, NULL, NULL)) { 1340 if ((errno == ESRCH) || (errno == ENOENT)) { 1341 break; 1342 } 1343 progerr(ERR_SYSINFO, errno); 1344 quit(99); 1345 /*NOTREACHED*/ 1346 } 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*/ 1354 } 1355 } 1356 } 1357 1358 /* 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 1365 */ 1366 1367 pkginst = getinst(&update, prvinfo, npkgs, preinstallCheck); 1368 1369 /* set "update flag" if updating an existing instance of this package */ 1370 1371 if (update) { 1372 setUpdate(); 1373 } 1374 1375 /* 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. 1380 */ 1381 1382 if (saveSpoolInstall != 0 && !isUpdate()) { 1383 putparam("UPDATE", ""); 1384 } 1385 1386 /* inform quit() if updating existing or installing new instance */ 1387 1388 quitSetUpdatingExisting(update ? B_TRUE : B_FALSE); 1389 1390 if (respfile) { 1391 (void) set_respfile(respfile, pkginst, RESP_RO); 1392 } 1393 1394 (void) snprintf(pkgloc, sizeof (pkgloc), 1395 "%s/%s", get_PKGLOC(), pkginst); 1396 1397 (void) snprintf(pkgbin, sizeof (pkgbin), 1398 "%s/install", pkgloc); 1399 1400 (void) snprintf(pkgsav, sizeof (pkgsav), 1401 "%s/save", pkgloc); 1402 1403 if (snprintf(saveSpoolInstallDir, PATH_MAX, "%s/pspool/%s", pkgsav, 1404 pkginst) < 0) { 1405 progerr(ERR_SNPRINTF, saveSpoolInstallDir); 1406 quit(99); 1407 /*NOTREACHED*/ 1408 } 1409 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); 1416 1417 putparam("PKGINST", pkginst); 1418 putparam("PKGSAV", pkgsav); 1419 1420 /* 1421 * Be sure request script has access to PKG_INSTALL_ROOT if there is 1422 * one 1423 */ 1424 1425 put_path_params(); 1426 1427 if (!map_client) { 1428 putparam("PKG_NO_UNIFIED", "TRUE"); 1429 } 1430 1431 /* 1432 * This maps the client filesystems into the server's space. 1433 */ 1434 1435 if (map_client && !mount_client()) { 1436 logerr(MSG_MANMOUNT); 1437 } 1438 1439 /* 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. 1445 */ 1446 1447 if ((preinstallCheck == B_FALSE) && (update)) { 1448 /* 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. 1453 */ 1454 1455 if (is_samepkg()) { 1456 /* 1457 * If it's the same ARCH and VERSION, then a merge 1458 * and copy operation is necessary. 1459 */ 1460 1461 if (n = merg_pkginfos(pclass, &mergd_pclass)) { 1462 quit(n); 1463 /*NOTREACHED*/ 1464 } 1465 1466 if (n = cp_pkgdirs()) { 1467 quit(n); 1468 /*NOTREACHED*/ 1469 } 1470 1471 } else { 1472 /* 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. 1477 */ 1478 1479 if (n = ck_instbase()) { 1480 quit(n); 1481 /*NOTREACHED*/ 1482 } 1483 1484 if (n = mv_pkgdirs()) { 1485 quit(n); 1486 /*NOTREACHED*/ 1487 } 1488 } 1489 1490 putparam("UPDATE", "yes"); 1491 1492 } 1493 1494 if (in_dryrun_mode()) { 1495 set_dryrun_dir_loc(); 1496 } 1497 1498 if (preinstallCheck == B_FALSE) { 1499 /* 1500 * Determine if the package has been partially installed on or 1501 * removed from this system. 1502 */ 1503 ck_w_dryrun(ckpartial, PARTIAL); 1504 1505 /* 1506 * make sure current runlevel is appropriate 1507 */ 1508 ck_w_dryrun(ckrunlevel, RUNLEVEL); 1509 } else { 1510 int r; 1511 1512 /* 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 1516 */ 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); 1520 1521 /* 1522 * make sure current runlevel is appropriate 1523 */ 1524 r = ckrunlevel(); 1525 (void) fprintf(stdout, "ckrunlevel=%d\n", r); 1526 } 1527 1528 if (pkgdev.cdevice) { 1529 /* get first volume which contains info files */ 1530 unpack(); 1531 if (!suppressCopyright) { 1532 copyright(); 1533 } 1534 } 1535 1536 /* update the lock - at the request script */ 1537 1538 lockupd("request"); 1539 1540 /* 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. 1544 */ 1545 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); 1553 } 1554 1555 ckreturn(n, ERR_REQUEST); 1556 } 1557 1558 /* 1559 * Look for all parameters in response file which begin with a 1560 * capital letter, and place them in the environment. 1561 */ 1562 1563 if ((is_a_respfile()) && (preinstallCheck == B_FALSE)) { 1564 if (n = merg_respfile()) { 1565 quit(n); 1566 /*NOTREACHED*/ 1567 } 1568 } 1569 1570 /* 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. 1574 */ 1575 1576 /* update the lock - at the checkinstall script */ 1577 lockupd("checkinstall"); 1578 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); 1603 } 1604 n = chkexec(update, script); 1605 if (in_dryrun_mode()) { 1606 set_dr_info(CHECKEXITCODE, n); 1607 } 1608 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); 1618 } 1619 } 1620 1621 /* 1622 * Now that the internal data structures are initialized, we can 1623 * initialize the dryrun files (which may be the same files). 1624 */ 1625 1626 if (pkgdrtarg) { 1627 init_dryrunfile(pkgdrtarg); 1628 } 1629 1630 /* 1631 * Look for all parameters in response file which begin with a 1632 * capital letter, and place them in the environment. 1633 */ 1634 if (is_a_respfile()) { 1635 if (n = merg_respfile()) { 1636 quit(n); 1637 /*NOTREACHED*/ 1638 } 1639 } 1640 1641 /* update the lock - doing analysis */ 1642 1643 lockupd("analysis"); 1644 1645 /* 1646 * Determine package base directory and client base directory 1647 * if appropriate. Then encapsulate them for future retrieval. 1648 */ 1649 if ((err = set_basedirs(isreloc(instdir), adm.basedir, pkginst, 1650 nointeract)) != 0) { 1651 quit(err); 1652 /*NOTREACHED*/ 1653 } 1654 1655 /* 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. 1659 */ 1660 1661 if (!is_depend_pkginfo_DB() && 1662 !preinstallCheck && is_a_basedir()) { 1663 mkbasedir(!nointeract, get_basedir()); 1664 echo(MSG_BASE_USED, get_basedir()); 1665 } 1666 1667 /* 1668 * Store PKG_INSTALL_ROOT, BASEDIR & CLIENT_BASEDIR in our 1669 * environment for later use by procedure scripts. 1670 */ 1671 put_path_params(); 1672 1673 /* 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 1678 */ 1679 if (ADM(setuid, "nochange")) { 1680 nosetuid++; /* Clear setuid/gid bits. */ 1681 } 1682 1683 if (ADM(conflict, "nochange")) { 1684 nocnflct++; /* Don't install conflicting files. */ 1685 } 1686 1687 /* 1688 * Get the filesystem space information for the filesystem on which 1689 * the "contents" file resides. 1690 */ 1691 1692 svfsb.f_bsize = 8192; 1693 svfsb.f_frsize = 1024; 1694 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*/ 1703 } 1704 } 1705 1706 /* 1707 * Get the number of blocks used by the pkgmap, ocfile() 1708 * needs this to properly determine its space requirements. 1709 */ 1710 1711 if (stat(p_pkgmap, &statb) == -1) { 1712 progerr(ERR_PKGINSTALL_STATOF, p_pkgmap, strerror(errno)); 1713 quit(99); 1714 /*NOTREACHED*/ 1715 } 1716 1717 pkgmap_blks = nblk(statb.st_size, svfsb.f_bsize, svfsb.f_frsize); 1718 1719 /* 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. 1724 */ 1725 1726 if (in_dryrun_mode()) { 1727 if (n = set_cfdir(pkgdrtarg)) { 1728 quit(n); 1729 /*NOTREACHED*/ 1730 } 1731 } else { 1732 if (n = set_cfdir(NULL)) { 1733 quit(n); 1734 /*NOTREACHED*/ 1735 } 1736 } 1737 if (!ocfile(&pkgserver, &cfTmpVfp, pkgmap_blks)) { 1738 quit(99); 1739 /*NOTREACHED*/ 1740 } 1741 1742 /* 1743 * if cpio is being used, tell pkgdbmerg since attributes will 1744 * have to be check and repaired on all file and directories 1745 */ 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; 1752 } 1753 } 1754 1755 /* Establish the class list and the class attributes. */ 1756 cl_sets(getenv("CLASSES")); 1757 find_CAS(I_ONLY, pkgbin, instdir); 1758 1759 if (vfpOpen(&pkgmapVfp, p_pkgmap, "r", VFP_NEEDNOW) != 0) { 1760 progerr(ERR_PKGMAP, p_pkgmap); 1761 quit(99); 1762 /*NOTREACHED*/ 1763 } 1764 1765 /* 1766 * This modifies the path list entries in memory to reflect 1767 * how they should look after the merg is complete 1768 */ 1769 1770 nparts = sortmap(&extlist, pkgmapVfp, pkgserver, cfTmpVfp, zoneName); 1771 1772 if ((n = files_installed()) > 0) { 1773 if (n > 1) { 1774 echo(MSG_INST_MANY, n); 1775 } else { 1776 echo(MSG_INST_ONE, n); 1777 } 1778 } 1779 1780 /* 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. 1786 */ 1787 if (pt = getenv("ULIMIT")) { 1788 if (assign_ulimit(pt) == -1) { 1789 progerr(ERR_BADULIMIT, pt); 1790 quit(99); 1791 /*NOTREACHED*/ 1792 } 1793 putparam("PKG_ULIMIT", "TRUE"); 1794 } 1795 1796 /* 1797 * If only gathering dependencies, check and output status of all 1798 * remaining dependencies and exit. 1799 */ 1800 1801 if (preinstallCheck == B_TRUE) { 1802 /* update the lock file - final checking */ 1803 1804 lockupd("preinstallcheck"); 1805 1806 /* verify package information files are not corrupt */ 1807 1808 (void) fprintf(stdout, "ckpkgfiles=%d\n", ckpkgfiles()); 1809 1810 /* verify package dependencies */ 1811 1812 (void) fprintf(stdout, "ckdepend=%d\n", ckdepend()); 1813 1814 /* Check space requirements */ 1815 1816 (void) fprintf(stdout, "ckspace=%d\n", ckspace()); 1817 1818 /* 1819 * Determine if any objects provided by this package conflict 1820 * with the files of previously installed packages. 1821 */ 1822 1823 (void) fprintf(stdout, "ckconflict=%d\n", ckconflct()); 1824 1825 /* 1826 * Determine if any objects provided by this package will be 1827 * installed with setuid or setgid enabled. 1828 */ 1829 1830 (void) fprintf(stdout, "cksetuid=%d\n", cksetuid()); 1831 1832 /* 1833 * Determine if any packaging scripts provided with this package 1834 * will execute as a priviledged user. 1835 */ 1836 1837 (void) fprintf(stdout, "ckpriv=%d\n", ckpriv()); 1838 1839 /* Verify neccessary package installation directories exist */ 1840 1841 (void) fprintf(stdout, "ckpkgdirs=%d\n", ckpkgdirs()); 1842 1843 /* 1844 * ****** preinstall check done - exit ****** 1845 */ 1846 1847 echoDebug(DBG_PKGINSTALL_PREINSCHK_OK); 1848 quit(0); 1849 /*NOTREACHED*/ 1850 } 1851 1852 /* 1853 * Not gathering dependencies only, proceed to check dependencies 1854 * and continue with the package installation operation. 1855 */ 1856 1857 /* 1858 * verify package information files are not corrupt 1859 */ 1860 ck_w_dryrun(ckpkgfiles, PKGFILES); 1861 1862 /* 1863 * verify package dependencies 1864 */ 1865 ck_w_dryrun(ckdepend, DEPEND); 1866 1867 /* 1868 * Check space requirements. 1869 */ 1870 ck_w_dryrun(ckspace, SPACE); 1871 1872 /* 1873 * Determine if any objects provided by this package conflict with 1874 * the files of previously installed packages. 1875 */ 1876 ck_w_dryrun(ckconflct, CONFLICT); 1877 1878 /* 1879 * Determine if any objects provided by this package will be 1880 * installed with setuid or setgid enabled. 1881 */ 1882 ck_w_dryrun(cksetuid, SETUID); 1883 1884 /* 1885 * Determine if any packaging scripts provided with this package will 1886 * execute as a priviledged user. 1887 */ 1888 ck_w_dryrun(ckpriv, PRIV); 1889 1890 /* 1891 * Verify neccessary package installation directories exist. 1892 */ 1893 ck_w_dryrun(ckpkgdirs, PKGDIRS); 1894 1895 /* 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 1899 */ 1900 1901 if (rprcflag) { 1902 nparts = sortmap(&extlist, pkgmapVfp, pkgserver, 1903 cfTmpVfp, zoneName); 1904 } 1905 1906 (void) vfpClose(&pkgmapVfp); 1907 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); 1915 } 1916 1917 /* inform quit that the install has started */ 1918 1919 quitSetInstallStarted(B_TRUE); 1920 1921 /* 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. 1927 */ 1928 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*/ 1935 } 1936 1937 /* 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. 1943 */ 1944 1945 if (access(ilockfile, F_OK) == 0) { 1946 (void) remove(ilockfile); 1947 } 1948 1949 if (open(ilockfile, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL, 0644) < 0) { 1950 progerr(ERR_LOCKFILE, ilockfile); 1951 quit(99); 1952 /*NOTREACHED*/ 1953 } 1954 1955 (void) time(&clock); 1956 1957 /* 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(). 1961 */ 1962 temp = setlocale(LC_TIME, NULL); 1963 (void) setlocale(LC_TIME, "C"); 1964 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); 1969 1970 /* 1971 * Store information about package being installed; 1972 * modify installation parameters as neccessary and 1973 * copy contents of 'install' directory into $pkgloc 1974 */ 1975 merginfo(mergd_pclass, saveSpoolInstall); 1976 1977 /* If this was just a dryrun, then quit() will write out that file. */ 1978 if (in_dryrun_mode()) { 1979 quit(0); 1980 /*NOTREACHED*/ 1981 } 1982 1983 /* 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. 1988 */ 1989 1990 /* update the lock - at the preinstall altscript */ 1991 lockupd("preinstall"); 1992 1993 /* preinstall script in the media (package source) */ 1994 (void) snprintf(altscript, sizeof (altscript), "%s/install/preinstall", 1995 instdir); 1996 1997 /* preinstall script in the pkgbin instead of media */ 1998 (void) snprintf(script, sizeof (script), "%s/preinstall", pkgbin); 1999 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); 2015 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); 2024 } 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); 2034 } 2035 2036 clr_ulimit(); 2037 (void) remove(script); /* no longer needed. */ 2038 } 2039 2040 /* 2041 * Check delivered package for a postinstall script while 2042 * we're still on volume 1. 2043 */ 2044 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'; 2052 } 2053 2054 /* update the lock - at the install phase */ 2055 2056 lockupd("install"); 2057 2058 /* 2059 * install package one part (volume) at a time 2060 */ 2061 2062 part = 1; 2063 while (part <= nparts) { 2064 if ((part > 1) && pkgdev.cdevice) { 2065 unpack(); 2066 } 2067 2068 instvol(extlist, srcinst, part, nparts, 2069 pkgserver, &cfTmpVfp, &updated, zoneName); 2070 2071 if (part++ >= nparts) { 2072 break; 2073 } 2074 } 2075 2076 z_destroyMountTable(); 2077 2078 /* 2079 * Now that all install class action scripts have been used, we 2080 * delete them from the package directory. 2081 */ 2082 rm_icas(pkgbin); 2083 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); 2090 } 2091 } 2092 2093 /* 2094 * Execute postinstall script, if any 2095 * Don't execute postinstall script if we are only updating the DB. 2096 */ 2097 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); 2103 2104 /* update the lock - at the postinstall script */ 2105 lockupd("postinstall"); 2106 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)) { 2117 /* 2118 * fresh installing into non-global zone, no object was 2119 * updated (installed/verified in area), so do not run 2120 * the postinstall script. 2121 */ 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); 2134 } 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); 2145 } 2146 2147 clr_ulimit(); 2148 (void) remove(script); /* no longer needed */ 2149 } 2150 2151 if (!warnflag && !failflag) { 2152 (void) remove(rlockfile); 2153 (void) remove(ilockfile); 2154 (void) remove(savlog); 2155 } 2156 2157 /* release the generic package lock */ 2158 2159 (void) unlockinst(); 2160 2161 pkgcloseserver(pkgserver); 2162 2163 quit(0); 2164 /* LINTED: no return */ 2165 } 2166 2167 /* 2168 * This function merges the environment data in the response file with the 2169 * current environment. 2170 */ 2171 static int 2172 merg_respfile() 2173 { 2174 int retcode = 0; 2175 char *resppath = get_respfile(); 2176 char *locbasedir; 2177 char param[MAX_PKG_PARAM_LENGTH], *value; 2178 FILE *fp; 2179 2180 if ((fp = fopen(resppath, "r")) == NULL) { 2181 progerr(ERR_RESPONSE, resppath); 2182 return (99); 2183 } 2184 2185 param[0] = '\0'; 2186 2187 while (value = fpkgparam(fp, param)) { 2188 if (!isupper(param[0])) { 2189 param[0] = '\0'; 2190 continue; 2191 } 2192 2193 if (rdonly(param)) { 2194 progerr(ERR_RDONLY, param); 2195 param[0] = '\0'; 2196 continue; 2197 } 2198 2199 /* 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. 2204 */ 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; 2215 } 2216 } 2217 2218 putparam(param, value); 2219 param[0] = '\0'; 2220 } 2221 (void) fclose(fp); 2222 2223 return (retcode); 2224 } 2225 2226 /* 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. 2230 */ 2231 static int 2232 ck_instbase(void) 2233 { 2234 int retcode = 0; 2235 char param[MAX_PKG_PARAM_LENGTH], *value; 2236 char pkginfo_path[PATH_MAX]; 2237 FILE *fp; 2238 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); 2245 } 2246 2247 param[0] = '\000'; 2248 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; 2254 2255 /* 2256 * Get srcinst down to a name. 2257 */ 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; 2266 } 2267 } else if (ADM(basedir, "ask")) 2268 /* 2269 * If it's going to ask later, let it know 2270 * that it *must* agree with the BASEDIR we 2271 * just picked up. 2272 */ 2273 adm.basedir = "update"; 2274 2275 putparam(param, value); 2276 break; 2277 } 2278 2279 param[0] = '\0'; 2280 } 2281 (void) fclose(fp); 2282 2283 return (retcode); 2284 } 2285 2286 /* 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. 2289 */ 2290 static int 2291 mv_pkgdirs(void) 2292 { 2293 /* 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. 2296 */ 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); 2303 } 2304 2305 if (rename(pkgloc, pkgloc_sav) == -1) { 2306 progerr(ERR_PKGBINREN, pkgloc, pkgloc_sav); 2307 return (99); 2308 } 2309 } 2310 2311 return (0); 2312 } 2313 2314 /* 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: 2319 * 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. 2327 * 2328 * The current environment contains the pkginfo settings for the 2329 * new package to be installed or to be updated. 2330 * 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 2336 */ 2337 2338 static int 2339 merg_pkginfos(struct cl_attr **pclass, struct cl_attr ***mpclass) 2340 { 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; 2352 2353 /* obtain the name of the package (for error messages) */ 2354 2355 pkgName = getenv("PKG"); 2356 if (pkgName == NULL) { 2357 pkgName = "*current*"; /* default name */ 2358 } 2359 2360 /* obtain the version of the package (for error messages) */ 2361 2362 pkgVersion = getenv("VERSION"); 2363 if (pkgVersion == NULL) { 2364 pkgVersion = "*current*"; /* default version */ 2365 } 2366 2367 /* open installed package pkginfo file */ 2368 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); 2374 } 2375 2376 /* entry debugging info */ 2377 2378 echoDebug(DBG_MERGINFOS_ENTRY, pkginfo_path); 2379 2380 /* 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 2384 */ 2385 2386 for (param[0] = '\0'; (oldValue = fpkgparam(fp, param)) != NULL; 2387 param[0] = '\0') { 2388 2389 boolean_t setZoneAttribute = B_FALSE; 2390 2391 /* debug info - attribute currently set to value */ 2392 2393 echoDebug(DBG_MERGINFOS_SET_TO, param, oldValue); 2394 2395 /* 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. 2400 */ 2401 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)); 2417 } 2418 2419 /* handle CLASSES currently being set */ 2420 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; 2428 } 2429 2430 /* handle BASEDIR currently being set */ 2431 2432 if (strcmp("BASEDIR", param) == 0) { 2433 if (adm.basedir && *(adm.basedir) && 2434 strchr("/$", *(adm.basedir))) { 2435 char *dotptr; 2436 2437 /* Get srcinst down to a* name */ 2438 2439 if (dotptr = strchr(srcinst, '.')) { 2440 *dotptr = '\000'; 2441 } 2442 if (strcmp(oldValue, adm.basedir) != 0) { 2443 progerr(ERR_ADMBD, srcinst, 2444 oldValue, adm.basedir); 2445 /* administration */ 2446 retcode = 4; 2447 break; 2448 } 2449 } else if (ADM(basedir, "ask")) { 2450 /* 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. 2455 */ 2456 adm.basedir = "update"; 2457 echoDebug(DBG_MERGINFOS_ASK_BASEDIR); 2458 } 2459 2460 echoDebug(DBG_MERGINFOS_SET_BASEDIR, oldValue); 2461 putparam(param, oldValue); 2462 continue; 2463 } 2464 2465 /* 2466 * determine if there is a new value for this attribute. 2467 */ 2468 2469 newValue = getenv(param); 2470 2471 /* 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'. 2475 */ 2476 2477 if ((newValue == NULL) && 2478 (setZoneAttribute == B_TRUE) && 2479 (strcasecmp(oldValue, "false") != 0)) { 2480 2481 /* unset existing non-"false" zone pkg attr */ 2482 progerr(ERR_MERGINFOS_UNSET_ZONEATTR, 2483 pkgName, pkgVersion, param, oldValue); 2484 retcode = 1; 2485 break; 2486 } 2487 2488 /* retain old value if no new value specified */ 2489 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; 2495 } 2496 2497 /* note if the old and new values are the same */ 2498 2499 if (strcmp(newValue, oldValue) == 0) { 2500 /* set existing package parameter to same value */ 2501 echoDebug(DBG_MERGINFOS_SET_DUPLICATE, param, oldValue); 2502 continue; 2503 } 2504 2505 /* 2506 * Check if old and new values differ. 2507 * Error if zone parameter 2508 */ 2509 2510 if (setZoneAttribute == B_TRUE) { 2511 /* illegal change to zone attribute */ 2512 2513 progerr(ERR_MERGINFOS_CHANGE_ZONEATTR, pkgName, 2514 pkgVersion, param, oldValue, newValue); 2515 2516 /* set return code to "fatal error" */ 2517 retcode = 1; 2518 break; 2519 } 2520 2521 /* note valid change to existing package parameter */ 2522 2523 echoDebug(DBG_MERGINFOS_SET_CHANGE, param, 2524 oldValue, newValue); 2525 } 2526 2527 /* close handle on currently installed package's pkginfo file */ 2528 2529 (void) fclose(fp); 2530 2531 /* return error if not successful up to this point */ 2532 2533 if (retcode != 0) { 2534 echoDebug(DBG_MERGINFOS_EXIT, pkginfo_path, retcode); 2535 2536 return (retcode); 2537 } 2538 2539 /* 2540 * verify that no zone attribute has been 2541 * set to an invalid value 2542 */ 2543 2544 /* SUNW_PKG_ALLZONES */ 2545 2546 newValue = getenv(PKG_ALLZONES_VARIABLE); 2547 2548 /* 2549 * complain if setting SUNW_PKG_ALLZONES to other than "false" 2550 */ 2551 2552 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); 2559 } 2560 2561 /* SUNW_PKG_THISZONE */ 2562 2563 newValue = getenv(PKG_THISZONE_VARIABLE); 2564 2565 /* 2566 * complain if setting SUNW_PKG_THISZONE to other than "false" 2567 */ 2568 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); 2575 } 2576 2577 /* SUNW_PKG_HOLLOW */ 2578 2579 newValue = getenv(PKG_HOLLOW_VARIABLE); 2580 2581 /* complain if setting SUNW_PKG_HOLLOW to other than "false" */ 2582 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); 2589 } 2590 2591 echoDebug(DBG_MERGINFOS_EXIT, pkginfo_path, 0); 2592 2593 return (0); 2594 } 2595 2596 static void 2597 set_dryrun_dir_loc(void) 2598 { 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); 2613 } 2614 2615 /* 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. 2620 */ 2621 static int 2622 cp_pkgdirs(void) 2623 { 2624 if (in_dryrun_mode()) { 2625 set_dryrun_dir_loc(); 2626 } 2627 2628 /* 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. 2631 */ 2632 if (!in_dryrun_mode() && pkgloc[0] && !access(pkgloc, F_OK)) { 2633 int status; 2634 int r; 2635 2636 (void) snprintf(pkgloc_sav, sizeof (pkgloc_sav), "%s/.save.%s", 2637 get_PKGLOC(), pkginst); 2638 2639 /* 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. 2643 */ 2644 r = e_ExecCmdList(&status, (char **)NULL, (char *)NULL, 2645 "/usr/bin/cp", "cp", "-r", pkgloc, pkgloc_sav, 2646 (char *)NULL); 2647 2648 if ((r != 0) || (status == -1) || (WEXITSTATUS(status) != 0)) { 2649 progerr(ERR_PKGBINCP, pkgloc, pkgloc_sav); 2650 return (99); 2651 } 2652 } 2653 2654 return (0); 2655 } 2656 2657 /* 2658 * This implements the pkgask function. It just executes the request script 2659 * and stores the results in a response file. 2660 */ 2661 static void 2662 do_pkgask(boolean_t a_run_request_as_root) 2663 { 2664 if (pkgdev.cdevice) { 2665 unpack(); 2666 if (!suppressCopyright) { 2667 copyright(); 2668 } 2669 } 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*/ 2675 } 2676 2677 (void) set_respfile(respfile, srcinst, RESP_WR); 2678 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++; 2684 } 2685 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()); 2693 } 2694 2695 quit(0); 2696 /*NOTREACHED*/ 2697 } 2698 2699 /* 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. 2702 */ 2703 static void 2704 ck_w_dryrun(int (*func)(), int type) 2705 { 2706 int n; 2707 2708 n = func(); 2709 if (in_dryrun_mode()) 2710 set_dr_info(type, !n); 2711 2712 if (n) { 2713 quit(n); 2714 /*NOTREACHED*/ 2715 } 2716 } 2717 2718 /* 2719 * This function deletes all install class action scripts from the package 2720 * directory on the root filesystem. 2721 */ 2722 static void 2723 rm_icas(char *cas_dir) 2724 { 2725 DIR *pdirfp; 2726 struct dirent *dp; 2727 char path[PATH_MAX]; 2728 2729 if ((pdirfp = opendir(cas_dir)) == NULL) 2730 return; 2731 2732 while ((dp = readdir(pdirfp)) != NULL) { 2733 if (dp->d_name[0] == '.') 2734 continue; 2735 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); 2740 } 2741 } 2742 (void) closedir(pdirfp); 2743 } 2744 2745 void 2746 ckreturn(int retcode, char *msg) 2747 { 2748 switch (retcode) { 2749 case 2: 2750 case 12: 2751 case 22: 2752 warnflag++; 2753 if (msg) { 2754 progerr("%s", msg); 2755 } 2756 /*FALLTHRU*/ 2757 case 10: 2758 case 20: 2759 if (retcode >= 10 && retcode < 20) { 2760 dreboot++; 2761 } 2762 if (retcode >= 20) { 2763 ireboot++; 2764 } 2765 /*FALLTHRU*/ 2766 case 0: 2767 break; /* okay */ 2768 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); 2784 } 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); 2794 } 2795 quit(1); 2796 /*NOTREACHED*/ 2797 } 2798 } 2799 2800 static void 2801 copyright(void) 2802 { 2803 FILE *fp; 2804 char line[LSIZE]; 2805 char path[PATH_MAX]; 2806 2807 /* Compose full path for copyright file */ 2808 (void) snprintf(path, sizeof (path), "%s/%s", instdir, COPYRIGHT_FILE); 2809 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); 2817 } 2818 } 2819 2820 static int 2821 rdonly(char *p) 2822 { 2823 int i; 2824 2825 for (i = 0; ro_params[i]; i++) { 2826 if (strcmp(p, ro_params[i]) == 0) 2827 return (1); 2828 } 2829 return (0); 2830 } 2831 2832 static void 2833 unpack(void) 2834 { 2835 /* 2836 * read in next part from stream, even if we decide 2837 * later that we don't need it 2838 */ 2839 if (dparts < 1) { 2840 progerr(ERR_DSTREAMCNT); 2841 quit(99); 2842 /*NOTREACHED*/ 2843 } 2844 if ((access(instdir, F_OK) == 0) && rrmdir(instdir)) { 2845 progerr(ERR_RMDIR, instdir); 2846 quit(99); 2847 /*NOTREACHED*/ 2848 } 2849 if (mkdir(instdir, 0755)) { 2850 progerr(ERR_MKDIR, instdir); 2851 quit(99); 2852 /*NOTREACHED*/ 2853 } 2854 if (chdir(instdir)) { 2855 progerr(ERR_CHDIR, instdir); 2856 quit(99); 2857 /*NOTREACHED*/ 2858 } 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*/ 2865 } 2866 } 2867 2868 dparts--; 2869 2870 if (ds_next(pkgdev.cdevice, instdir)) { 2871 progerr(ERR_DSTREAM); 2872 quit(99); 2873 /*NOTREACHED*/ 2874 } 2875 if (chdir(get_PKGADM())) { 2876 progerr(ERR_CHDIR, get_PKGADM()); 2877 quit(99); 2878 /*NOTREACHED*/ 2879 } 2880 ds_close(1); 2881 } 2882 2883 static void 2884 usage(void) 2885 { 2886 (void) fprintf(stderr, ERR_USAGE_PKGINSTALL); 2887 exit(1); 2888 /*NOTREACHED*/ 2889 } 2890