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