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