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