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 32 #include <stdio.h> 33 #include <errno.h> 34 #include <stdarg.h> 35 #include <limits.h> 36 #include <stdlib.h> 37 #include <unistd.h> 38 #include <fcntl.h> 39 #include <ctype.h> 40 #include <string.h> 41 #include <sys/types.h> 42 #include <sys/param.h> 43 #include <sys/stat.h> 44 #include <sys/statvfs.h> 45 #include <sys/sysmacros.h> 46 #include <dirent.h> 47 #include <signal.h> 48 #include <devmgmt.h> 49 #include <openssl/pkcs12.h> 50 #include <openssl/x509.h> 51 #include <openssl/pkcs7.h> 52 #include <openssl/err.h> 53 #include <openssl/pem.h> 54 #include <note.h> 55 #include "pkginfo.h" 56 #include "pkgstrct.h" 57 #include "pkgtrans.h" 58 #include "pkgdev.h" 59 #include "pkglib.h" 60 #include "pkglibmsgs.h" 61 #include "keystore.h" 62 #include "pkglocale.h" 63 #include "pkgerr.h" 64 65 extern char *pkgdir; /* pkgparam.c */ 66 67 /* libadm.a */ 68 extern char *devattr(char *device, char *attribute); 69 extern char *fpkginst(char *pkg, ...); 70 extern int fpkginfo(struct pkginfo *info, char *pkginst); 71 extern int getvol(char *device, char *label, int options, char *prompt); 72 extern int _getvol(char *device, char *label, int options, char *prompt, 73 char *norewind); 74 75 /* dstream.c */ 76 extern int ds_ginit(char *device); 77 extern int ds_close(int pkgendflg); 78 79 #define CPIOPROC "/usr/bin/cpio" 80 81 #define CMDSIZE 512 /* command block size */ 82 83 #define BLK_SIZE 512 /* size of logical block */ 84 85 #define ENTRY_MAX 256 /* max size of entry for cpio cmd or header */ 86 87 #define PKGINFO "pkginfo" 88 #define PKGMAP "pkgmap" 89 #define MAP_STAT_SIZE 60 /* 1st line of pkgmap (3 numbers & a : */ 90 91 #define INSTALL "install" 92 #define RELOC "reloc" 93 #define ROOT "root" 94 #define ARCHIVE "archive" 95 96 static struct pkgdev srcdev, dstdev; 97 static char *tmpdir; 98 static char *tmppath; 99 static char *tmpsymdir = NULL; 100 static char dstinst[NON_ABI_NAMELNGTH]; 101 static char *ids_name, *ods_name; 102 static int ds_volcnt; 103 static int ds_volno; 104 static int compressedsize, has_comp_size; 105 106 static void (*sigintHandler)(); 107 static void (*sighupHandler)(); 108 static void cleanup(void); 109 static void sigtrap(int signo); 110 static int rd_map_size(FILE *fp, int *npts, int *maxpsz, int *cmpsize); 111 112 static int cat_and_count(struct dm_buf *, char *); 113 114 static int ckoverwrite(char *dir, char *inst, int options); 115 static int pkgxfer(char *srcinst, int options); 116 static int wdsheader(struct dm_buf *, char *src, char *device, 117 char **pkg, PKCS7 *); 118 static struct dm_buf *genheader(char *, char **); 119 120 static int dump_hdr_and_pkgs(BIO *, struct dm_buf *, char **); 121 122 extern int ds_fd; /* open file descriptor for data stream WHERE? */ 123 124 static char *root_names[] = { 125 "root", 126 "root.cpio", 127 "root.Z", 128 "root.cpio.Z", 129 0 130 }; 131 132 static char *reloc_names[] = { 133 "reloc", 134 "reloc.cpio", 135 "reloc.Z", 136 "reloc.cpio.Z", 137 0 138 }; 139 140 static int signal_received = 0; 141 142 char **xpkg; /* array of transferred packages */ 143 int nxpkg; 144 145 static char *allpkg[] = { 146 "all", 147 NULL 148 }; 149 150 static struct dm_buf hdrbuf; 151 static char *pinput, *nextpinput; 152 153 int 154 pkghead(char *device) 155 { 156 char *pt; 157 int n; 158 159 cleanup(); 160 161 162 if (device == NULL) 163 return (0); 164 else if ((device[0] == '/') && !isdir(device)) { 165 pkgdir = device; 166 return (0); 167 } else if ((pt = devattr(device, "pathname")) != NULL && !isdir(pt)) { 168 pkgdir = pt; 169 return (0); 170 } 171 172 /* check for datastream */ 173 if (n = pkgtrans(device, (char *)0, allpkg, PT_SILENT|PT_INFO_ONLY, 174 NULL, NULL)) { 175 cleanup(); 176 return (n); 177 } 178 /* pkgtrans has set pkgdir */ 179 return (0); 180 } 181 182 static char * 183 mgets(char *buf, int size) 184 { 185 nextpinput = strchr(pinput, '\n'); 186 if (nextpinput == NULL) 187 return (0); 188 *nextpinput = '\0'; 189 if ((int)strlen(pinput) > size) 190 return (0); 191 (void) strncpy(buf, pinput, strlen(pinput)); 192 buf[strlen(pinput)] = '\0'; 193 pinput = nextpinput + 1; 194 return (buf); 195 } 196 /* 197 * Here we construct the package size summaries for the headers. The 198 * pkgmap file associated with fp must be rewound to the beginning of the 199 * file. Note that we read three values from pkgmap first line in order 200 * to get the *actual* size if this package is compressed. 201 * This returns 202 * 0 : error 203 * 2 : not a compressed package 204 * 3 : compressed package 205 * and sets has_comp_size to indicate whether or not this is a compressed 206 * package. 207 */ 208 static int 209 rd_map_size(FILE *fp, int *npts, int *maxpsz, int *cmpsize) 210 { 211 int n; 212 char line_buffer[MAP_STAT_SIZE]; 213 214 /* First read the null terminated first line */ 215 if (fgets(line_buffer, MAP_STAT_SIZE, fp) == NULL) { 216 progerr(pkg_gt(ERR_TRANSFER)); 217 logerr(pkg_gt(MSG_NOSIZE)); 218 (void) fclose(fp); 219 ecleanup(); 220 return (0); 221 } 222 223 n = sscanf(line_buffer, ": %d %d %d", npts, maxpsz, cmpsize); 224 225 if (n == 3) /* A valid compressed package entry */ 226 has_comp_size = 1; 227 else if (n == 2) /* A valid standard package entry */ 228 has_comp_size = 0; 229 else { /* invalid entry */ 230 progerr(pkg_gt(ERR_TRANSFER)); 231 logerr(pkg_gt(MSG_NOSIZE)); 232 (void) fclose(fp); 233 ecleanup(); 234 return (0); 235 } 236 237 return (n); 238 } 239 240 /* will return 0, 1, 3, or 99 */ 241 static int 242 _pkgtrans(char *device1, char *device2, char **pkg, int options, 243 keystore_handle_t keystore, char *keystore_alias) 244 { 245 BIO *p7_bio = NULL; 246 EVP_PKEY *privkey = NULL; 247 PKCS7 *sec_pkcs7 = NULL; 248 PKCS7_SIGNER_INFO *sec_signerinfo = NULL; 249 PKG_ERR *err; 250 STACK_OF(X509) *cacerts = NULL; 251 STACK_OF(X509) *clcerts = NULL; 252 STACK_OF(X509) *sec_chain = NULL; 253 X509 *pubcert = NULL; 254 boolean_t making_sig = B_FALSE; 255 char *src, *dst; 256 int errflg, i, n; 257 struct dm_buf *hdr; 258 259 making_sig = (keystore != NULL) ? B_TRUE : B_FALSE; 260 261 if (making_sig) { 262 263 /* new error object */ 264 err = pkgerr_new(); 265 266 /* find matching cert and key */ 267 if (find_key_cert_pair(err, keystore, 268 keystore_alias, &privkey, &pubcert) != 0) { 269 pkgerr(err); 270 pkgerr_free(err); 271 return (1); 272 } 273 274 /* get CA certificates */ 275 if (find_ca_certs(err, keystore, &cacerts) != 0) { 276 pkgerr(err); 277 pkgerr_free(err); 278 return (1); 279 } 280 281 /* get CL (aka "chain") certificates */ 282 if (find_cl_certs(err, keystore, &clcerts) != 0) { 283 pkgerr(err); 284 pkgerr_free(err); 285 return (1); 286 } 287 288 /* initialize PKCS7 object to be filled in later */ 289 sec_pkcs7 = PKCS7_new(); 290 (void) PKCS7_set_type(sec_pkcs7, NID_pkcs7_signed); 291 sec_signerinfo = PKCS7_add_signature(sec_pkcs7, 292 pubcert, privkey, EVP_sha1()); 293 294 if (sec_signerinfo == NULL) { 295 progerr(gettext(ERR_SEC), keystore_alias); 296 ERR_print_errors_fp(stderr); 297 pkgerr_free(err); 298 return (1); 299 } 300 301 /* add signer cert into signature */ 302 (void) PKCS7_add_certificate(sec_pkcs7, pubcert); 303 304 /* attempt to resolve cert chain starting at the signer cert */ 305 if (get_cert_chain(err, pubcert, clcerts, cacerts, 306 &sec_chain) != 0) { 307 pkgerr(err); 308 pkgerr_free(err); 309 return (1); 310 } 311 312 /* 313 * add the verification chain of certs into the signature. 314 * The first cert is the user cert, which we don't need, 315 * since it's baked in already, so skip it 316 */ 317 for (i = 1; i < sk_X509_num(sec_chain); i++) { 318 (void) PKCS7_add_certificate(sec_pkcs7, 319 sk_X509_value(sec_chain, i)); 320 } 321 322 pkgerr_free(err); 323 err = NULL; 324 } 325 326 if (signal_received > 0) { 327 return (1); 328 } 329 330 /* transfer spool to appropriate device */ 331 if (devtype(device1, &srcdev)) { 332 progerr(pkg_gt(ERR_TRANSFER)); 333 logerr(pkg_gt(MSG_BADDEV), device1); 334 return (1); 335 } 336 srcdev.rdonly++; 337 338 /* check for datastream */ 339 ids_name = NULL; 340 if (srcdev.bdevice) { 341 if (n = _getvol(srcdev.bdevice, NULL, NULL, 342 pkg_gt("Insert %v into %p."), srcdev.norewind)) { 343 cleanup(); 344 if (n == 3) 345 return (3); 346 progerr(pkg_gt(ERR_TRANSFER)); 347 logerr(pkg_gt(MSG_GETVOL)); 348 return (1); 349 } 350 if (ds_readbuf(srcdev.cdevice)) 351 ids_name = srcdev.cdevice; 352 } 353 354 if (srcdev.cdevice && !srcdev.bdevice) 355 ids_name = srcdev.cdevice; 356 else if (srcdev.pathname) { 357 ids_name = srcdev.pathname; 358 if (access(ids_name, 0) == -1) { 359 progerr(ERR_TRANSFER); 360 logerr(pkg_gt(MSG_GETVOL)); 361 return (1); 362 } 363 } 364 365 if (!ids_name && device2 == (char *)0) { 366 if (n = pkgmount(&srcdev, NULL, 1, 0, 0)) { 367 cleanup(); 368 return (n); 369 } 370 if (srcdev.mount && *srcdev.mount) 371 pkgdir = strdup(srcdev.mount); 372 return (0); 373 } 374 375 if (ids_name && device2 == (char *)0) { 376 tmppath = tmpnam(NULL); 377 tmppath = strdup(tmppath); 378 if (tmppath == NULL) { 379 progerr(pkg_gt(ERR_TRANSFER)); 380 logerr(pkg_gt(MSG_MEM)); 381 return (1); 382 } 383 if (mkdir(tmppath, 0755)) { 384 progerr(pkg_gt(ERR_TRANSFER)); 385 logerr(pkg_gt(MSG_MKDIR), tmppath); 386 return (1); 387 } 388 device2 = tmppath; 389 } 390 391 if (devtype(device2, &dstdev)) { 392 progerr(pkg_gt(ERR_TRANSFER)); 393 logerr(pkg_gt(MSG_BADDEV), device2); 394 return (1); 395 } 396 397 if ((srcdev.cdevice && dstdev.cdevice) && 398 strcmp(srcdev.cdevice, dstdev.cdevice) == 0) { 399 progerr(pkg_gt(ERR_TRANSFER)); 400 logerr(pkg_gt(MSG_SAMEDEV)); 401 return (1); 402 } 403 404 ods_name = NULL; 405 if (dstdev.cdevice && !dstdev.bdevice || dstdev.pathname) 406 options |= PT_ODTSTREAM; 407 408 if (options & PT_ODTSTREAM) { 409 if (!((ods_name = dstdev.cdevice) != NULL || 410 (ods_name = dstdev.pathname) != NULL)) { 411 progerr(pkg_gt(ERR_TRANSFER)); 412 logerr(pkg_gt(MSG_BADDEV), device2); 413 return (1); 414 } 415 if (ids_name) { 416 progerr(pkg_gt(ERR_TRANSFER)); 417 logerr(pkg_gt(MSG_TWODSTREAM)); 418 return (1); 419 } 420 } else { 421 /* 422 * output device isn't a stream. If we're making a signed 423 * package, then fail, since we can't make signed, 424 * non-stream pkgs 425 */ 426 if (making_sig) { 427 progerr(pkg_gt(ERR_TRANSFER)); 428 logerr(pkg_gt(ERR_CANTSIGN)); 429 return (1); 430 } 431 } 432 433 if ((srcdev.dirname && dstdev.dirname) && 434 strcmp(srcdev.dirname, dstdev.dirname) == 0) { 435 progerr(pkg_gt(ERR_TRANSFER)); 436 logerr(pkg_gt(MSG_SAMEDEV)); 437 return (1); 438 } 439 440 if ((srcdev.pathname && dstdev.pathname) && 441 strcmp(srcdev.pathname, dstdev.pathname) == 0) { 442 progerr(pkg_gt(ERR_TRANSFER)); 443 logerr(pkg_gt(MSG_SAMEDEV)); 444 return (1); 445 } 446 447 if (signal_received > 0) { 448 return (1); 449 } 450 451 if (ids_name) { 452 if (srcdev.cdevice && !srcdev.bdevice && 453 (n = _getvol(srcdev.cdevice, NULL, NULL, NULL, 454 srcdev.norewind))) { 455 cleanup(); 456 if (n == 3) 457 return (3); 458 progerr(pkg_gt(ERR_TRANSFER)); 459 logerr(pkg_gt(MSG_GETVOL)); 460 return (1); 461 } 462 if (srcdev.dirname = tmpnam(NULL)) 463 tmpdir = srcdev.dirname = strdup(srcdev.dirname); 464 465 if ((srcdev.dirname == NULL) || mkdir(srcdev.dirname, 0755) || 466 chdir(srcdev.dirname)) { 467 progerr(pkg_gt(ERR_TRANSFER)); 468 logerr(pkg_gt(MSG_NOTEMP), srcdev.dirname); 469 cleanup(); 470 return (1); 471 } 472 if (ds_init(ids_name, pkg, srcdev.norewind)) { 473 cleanup(); 474 return (1); 475 } 476 } else if (srcdev.mount) { 477 if (n = pkgmount(&srcdev, NULL, 1, 0, 0)) { 478 cleanup(); 479 return (n); 480 } 481 } 482 483 src = srcdev.dirname; 484 dst = dstdev.dirname; 485 486 if (chdir(src)) { 487 progerr(pkg_gt(ERR_TRANSFER)); 488 logerr(pkg_gt(MSG_CHDIR), src); 489 cleanup(); 490 return (1); 491 } 492 493 if (signal_received > 0) { 494 return (1); 495 } 496 497 xpkg = pkg = gpkglist(src, pkg, NULL); 498 if (!pkg) { 499 progerr(pkg_gt(ERR_TRANSFER)); 500 logerr(pkg_gt(MSG_NOPKGS), src); 501 cleanup(); 502 return (1); 503 } 504 505 for (nxpkg = 0; pkg[nxpkg]; /* void */) { 506 nxpkg++; /* count */ 507 } 508 509 if (ids_name) { 510 ds_order(pkg); /* order requests */ 511 } 512 513 if (signal_received > 0) { 514 return (1); 515 } 516 517 if (options & PT_ODTSTREAM) { 518 char line[128]; 519 520 if (!dstdev.pathname && 521 (n = _getvol(ods_name, NULL, DM_FORMAT, NULL, 522 dstdev.norewind))) { 523 cleanup(); 524 if (n == 3) 525 return (3); 526 progerr(pkg_gt(ERR_TRANSFER)); 527 logerr(pkg_gt(MSG_GETVOL)); 528 return (1); 529 } 530 if ((hdr = genheader(src, pkg)) == NULL) { 531 cleanup(); 532 return (1); 533 } 534 if (making_sig) { 535 /* start up signature data stream */ 536 (void) PKCS7_content_new(sec_pkcs7, NID_pkcs7_data); 537 (void) PKCS7_set_detached(sec_pkcs7, 1); 538 p7_bio = PKCS7_dataInit(sec_pkcs7, NULL); 539 540 /* 541 * Here we generate all the data that will go into 542 * the package, and send it through the signature 543 * generator, essentially calculating the signature 544 * of the entire package so we can place it in the 545 * header. Otherwise we'd have to place it at the end 546 * of the pkg, which would break the ABI 547 */ 548 if (!(options & PT_SILENT)) { 549 (void) fprintf(stderr, pkg_gt(MSG_SIGNING), 550 get_subject_display_name(pubcert)); 551 } 552 if (dump_hdr_and_pkgs(p7_bio, hdr, pkg) != 0) { 553 progerr(gettext(ERR_NOGEN)); 554 logerr(pkg_gt(MSG_GETVOL)); 555 cleanup(); 556 return (1); 557 558 } 559 560 BIO_flush(p7_bio); 561 562 /* 563 * now generate PKCS7 signature 564 */ 565 if (!PKCS7_dataFinal(sec_pkcs7, p7_bio)) { 566 progerr(gettext(ERR_NOGEN)); 567 logerr(pkg_gt(MSG_GETVOL)); 568 cleanup(); 569 return (1); 570 } 571 572 (void) BIO_free(p7_bio); 573 } 574 575 /* write out header to stream, which includes signature */ 576 if (wdsheader(hdr, src, ods_name, pkg, sec_pkcs7)) { 577 cleanup(); 578 return (1); 579 } 580 581 if (sec_pkcs7 != NULL) { 582 /* nuke in-memory signature for safety */ 583 PKCS7_free(sec_pkcs7); 584 sec_pkcs7 = NULL; 585 } 586 587 ds_volno = 1; /* number of volumes in datastream */ 588 pinput = hdrbuf.text_buffer; 589 /* skip past first line in header */ 590 (void) mgets(line, 128); 591 } 592 593 if (signal_received > 0) { 594 return (1); 595 } 596 597 errflg = 0; 598 599 for (i = 0; pkg[i]; i++) { 600 601 if (signal_received > 0) { 602 return (1); 603 } 604 605 if (!(options & PT_ODTSTREAM) && dstdev.mount) { 606 if (n = pkgmount(&dstdev, NULL, 0, 0, 1)) { 607 cleanup(); 608 return (n); 609 } 610 } 611 if (errflg = pkgxfer(pkg[i], options)) { 612 pkg[i] = NULL; 613 if ((options & PT_ODTSTREAM) || (errflg != 2)) 614 break; 615 } else if (strcmp(dstinst, pkg[i])) 616 pkg[i] = strdup(dstinst); 617 } 618 619 if (!(options & PT_ODTSTREAM) && dst) { 620 pkgdir = strdup(dst); 621 } 622 623 /* 624 * No cleanup of temporary directories created in this 625 * function is done here. The calling function must do 626 * the cleanup. 627 */ 628 629 return (signal_received > 0 ? 1 : errflg); 630 } 631 632 int 633 pkgtrans(char *device1, char *device2, char **pkg, int options, 634 keystore_handle_t keystore, char *keystore_alias) 635 { 636 int r; 637 struct sigaction nact; 638 struct sigaction oact; 639 640 /* 641 * setup signal handlers for SIGINT and SIGHUP and release hold 642 */ 643 644 /* hold SIGINT/SIGHUP interrupts */ 645 646 (void) sighold(SIGHUP); 647 (void) sighold(SIGINT); 648 649 /* hook SIGINT to sigtrap */ 650 651 nact.sa_handler = sigtrap; 652 nact.sa_flags = SA_RESTART; 653 (void) sigemptyset(&nact.sa_mask); 654 655 if (sigaction(SIGINT, &nact, &oact) < 0) { 656 sigintHandler = SIG_DFL; 657 } else { 658 sigintHandler = oact.sa_handler; 659 } 660 661 /* hook SIGHUP to sigtrap */ 662 663 nact.sa_handler = sigtrap; 664 nact.sa_flags = SA_RESTART; 665 (void) sigemptyset(&nact.sa_mask); 666 667 if (sigaction(SIGHUP, &nact, &oact) < 0) { 668 sighupHandler = SIG_DFL; 669 } else { 670 sighupHandler = oact.sa_handler; 671 } 672 673 /* reset signal received count */ 674 675 signal_received = 0; 676 677 /* release hold on signals */ 678 679 (void) sigrelse(SIGHUP); 680 (void) sigrelse(SIGINT); 681 682 /* 683 * perform the package translation 684 */ 685 686 r = _pkgtrans(device1, device2, pkg, options, keystore, keystore_alias); 687 688 /* 689 * reset signal handlers 690 */ 691 692 /* hold SIGINT/SIGHUP interrupts */ 693 694 (void) sighold(SIGHUP); 695 (void) sighold(SIGINT); 696 697 /* reset SIGINT */ 698 699 nact.sa_handler = sigintHandler; 700 nact.sa_flags = SA_RESTART; 701 (void) sigemptyset(&nact.sa_mask); 702 703 (void) sigaction(SIGINT, &nact, (struct sigaction *)NULL); 704 705 /* reset SIGHUP */ 706 707 nact.sa_handler = sighupHandler; 708 nact.sa_flags = SA_RESTART; 709 (void) sigemptyset(&nact.sa_mask); 710 711 (void) sigaction(SIGHUP, &nact, (struct sigaction *)NULL); 712 713 /* if signal received and pkgtrans returned error, call cleanup */ 714 715 if (signal_received > 0) { 716 if (r != 0) { 717 cleanup(); 718 } 719 (void) kill(getpid(), SIGINT); 720 } 721 722 /* release hold on signals */ 723 724 (void) sigrelse(SIGHUP); 725 (void) sigrelse(SIGINT); 726 727 return (r); 728 } 729 730 /* 731 * This function concatenates append to the text described in the buf_ctrl 732 * structure. This code modifies data in this structure and handles all 733 * allocation issues. It returns '0' if everything was successful and '1' 734 * if not. 735 */ 736 static int 737 cat_and_count(struct dm_buf *buf_ctrl, char *append) 738 { 739 740 /* keep allocating until we have enough room to hold string */ 741 while ((buf_ctrl->offset + (int)strlen(append)) 742 >= buf_ctrl->allocation) { 743 /* reallocate (and maybe move) text buffer */ 744 if ((buf_ctrl->text_buffer = 745 (char *)realloc(buf_ctrl->text_buffer, 746 buf_ctrl->allocation + BLK_SIZE)) == NULL) { 747 progerr(pkg_gt(ERR_TRANSFER)); 748 logerr(pkg_gt(MSG_MEM)); 749 free(buf_ctrl->text_buffer); 750 return (1); 751 } 752 753 /* clear the new memory */ 754 (void) memset(buf_ctrl->text_buffer + 755 buf_ctrl->allocation, '\0', BLK_SIZE); 756 757 /* adjust total allocation */ 758 buf_ctrl->allocation += BLK_SIZE; 759 } 760 761 /* append new string to end of buffer */ 762 while (*append) { 763 *(buf_ctrl->text_buffer + buf_ctrl->offset) = *append++; 764 (buf_ctrl->offset)++; 765 } 766 767 return (0); 768 } 769 770 static struct dm_buf * 771 genheader(char *src, char **pkg) 772 { 773 774 FILE *fp; 775 char path[MAXPATHLEN], tmp_entry[ENTRY_MAX]; 776 int i, n, nparts, maxpsize; 777 int partcnt; 778 long totsize; 779 struct stat statbuf; 780 781 if ((hdrbuf.text_buffer = (char *)malloc(BLK_SIZE)) == NULL) { 782 progerr(pkg_gt(ERR_TRANSFER)); 783 logerr(pkg_gt(MSG_MEM)); 784 return (NULL); 785 } 786 787 /* clear the new memory */ 788 (void) memset(hdrbuf.text_buffer, '\0', BLK_SIZE); 789 790 /* set up the buffer control structure for the header */ 791 hdrbuf.offset = 0; 792 hdrbuf.allocation = BLK_SIZE; 793 794 (void) cat_and_count(&hdrbuf, HDR_PREFIX); 795 (void) cat_and_count(&hdrbuf, "\n"); 796 797 nparts = maxpsize = 0; 798 799 totsize = 0; 800 for (i = 0; pkg[i]; i++) { 801 (void) snprintf(path, MAXPATHLEN, "%s/%s/%s", 802 src, pkg[i], PKGINFO); 803 if (stat(path, &statbuf) < 0) { 804 progerr(pkg_gt(ERR_TRANSFER)); 805 logerr(pkg_gt(MSG_BADPKGINFO)); 806 ecleanup(); 807 return (NULL); 808 } 809 totsize += statbuf.st_size/BLK_SIZE + 1; 810 } 811 812 /* 813 * totsize contains number of blocks used by the pkginfo files 814 */ 815 totsize += i/4 + 1; 816 if (dstdev.capacity && totsize > dstdev.capacity) { 817 progerr(pkg_gt(ERR_TRANSFER)); 818 logerr(pkg_gt(MSG_NOSPACE), totsize, dstdev.capacity); 819 ecleanup(); 820 return (NULL); 821 } 822 823 ds_volcnt = 1; 824 for (i = 0; pkg[i]; i++) { 825 partcnt = 0; 826 (void) snprintf(path, MAXPATHLEN, "%s/%s/%s", 827 src, pkg[i], PKGMAP); 828 if ((fp = fopen(path, "r")) == NULL) { 829 progerr(pkg_gt(ERR_TRANSFER)); 830 logerr(pkg_gt(MSG_NOPKGMAP), pkg[i]); 831 ecleanup(); 832 return (NULL); 833 } 834 835 /* Evaluate the first entry in pkgmap */ 836 n = rd_map_size(fp, &nparts, &maxpsize, &compressedsize); 837 838 if (n == 3) /* It's a compressed package */ 839 /* The header needs the *real* size */ 840 maxpsize = compressedsize; 841 else if (n == 0) /* pkgmap is corrupt */ 842 return (NULL); 843 844 if (dstdev.capacity && maxpsize > dstdev.capacity) { 845 progerr(pkg_gt(ERR_TRANSFER)); 846 logerr(pkg_gt(MSG_NOSPACE), (long)maxpsize, 847 dstdev.capacity); 848 (void) fclose(fp); 849 ecleanup(); 850 return (NULL); 851 } 852 853 /* add pkg name, number of parts and the max part size */ 854 if (snprintf(tmp_entry, ENTRY_MAX, "%s %d %d", 855 pkg[i], nparts, maxpsize) >= ENTRY_MAX) { 856 progerr(pkg_gt(ERR_TRANSFER)); 857 logerr(pkg_gt(ERR_MEM)); 858 (void) fclose(fp); 859 ecleanup(); 860 return (NULL); 861 } 862 if (cat_and_count(&hdrbuf, tmp_entry)) { 863 progerr(pkg_gt(ERR_TRANSFER)); 864 logerr(pkg_gt(MSG_MEM)); 865 (void) fclose(fp); 866 ecleanup(); 867 return (NULL); 868 } 869 870 totsize += nparts * maxpsize; 871 if (dstdev.capacity && dstdev.capacity < totsize) { 872 int lastpartcnt = 0; 873 874 if (totsize) 875 totsize -= nparts * maxpsize; 876 while (partcnt < nparts) { 877 while (totsize <= dstdev.capacity && 878 partcnt <= nparts) { 879 totsize += maxpsize; 880 partcnt++; 881 } 882 /* partcnt == 0 means skip to next volume */ 883 if (partcnt) 884 partcnt--; 885 (void) snprintf(tmp_entry, ENTRY_MAX, 886 " %d", partcnt - lastpartcnt); 887 if (cat_and_count(&hdrbuf, tmp_entry)) { 888 progerr(pkg_gt(ERR_TRANSFER)); 889 logerr(pkg_gt(MSG_MEM)); 890 (void) fclose(fp); 891 ecleanup(); 892 return (NULL); 893 } 894 ds_volcnt++; 895 totsize = 0; 896 lastpartcnt = partcnt; 897 } 898 /* first parts/volume number does not count */ 899 ds_volcnt--; 900 } 901 902 if (cat_and_count(&hdrbuf, "\n")) { 903 progerr(pkg_gt(ERR_TRANSFER)); 904 logerr(pkg_gt(MSG_MEM)); 905 (void) fclose(fp); 906 ecleanup(); 907 return (NULL); 908 } 909 910 (void) fclose(fp); 911 } 912 913 if (cat_and_count(&hdrbuf, HDR_SUFFIX) || 914 cat_and_count(&hdrbuf, "\n")) { 915 progerr(pkg_gt(ERR_TRANSFER)); 916 logerr(pkg_gt(MSG_MEM)); 917 (void) fclose(fp); 918 ecleanup(); 919 return (NULL); 920 } 921 return (&hdrbuf); 922 } 923 924 static int 925 wdsheader(struct dm_buf *hdr, char *src, char *device, char **pkg, PKCS7 *sig) 926 { 927 FILE *fp; 928 char path[PATH_MAX], tmp_entry[ENTRY_MAX], 929 tmp_file[L_tmpnam+1]; 930 char srcpath[PATH_MAX]; 931 int i, n; 932 int list_fd; 933 int block_cnt; 934 int len; 935 char cwd[MAXPATHLEN + 1]; 936 boolean_t making_sig = B_FALSE; 937 938 making_sig = (sig != NULL) ? B_TRUE : B_FALSE; 939 940 (void) ds_close(0); 941 if (dstdev.pathname) 942 ds_fd = creat(device, 0644); 943 else 944 ds_fd = open(device, 1); 945 946 if (ds_fd < 0) { 947 progerr(pkg_gt(ERR_TRANSFER)); 948 logerr(pkg_gt(MSG_OPEN), device, errno); 949 return (1); 950 } 951 952 if (ds_ginit(device) < 0) { 953 progerr(pkg_gt(ERR_TRANSFER)); 954 logerr(pkg_gt(MSG_OPEN), device, errno); 955 (void) ds_close(0); 956 return (1); 957 } 958 959 /* 960 * The loop below assures compatibility with tapes that don't 961 * have a block size (e.g.: Exabyte) by forcing EOR at the end 962 * of each 512 bytes. 963 */ 964 for (block_cnt = 0; block_cnt < hdr->allocation; 965 block_cnt += BLK_SIZE) { 966 (void) write(ds_fd, (hdr->text_buffer + block_cnt), BLK_SIZE); 967 } 968 969 /* 970 * write the first cpio() archive to the datastream 971 * which should contain the pkginfo & pkgmap files 972 * for all packages 973 */ 974 (void) tmpnam(tmp_file); /* temporary file name */ 975 if ((list_fd = open(tmp_file, O_RDWR | O_CREAT, 0644)) == -1) { 976 progerr(pkg_gt(ERR_TRANSFER)); 977 logerr(pkg_gt(MSG_NOTMPFIL), tmp_file); 978 return (1); 979 } 980 981 /* 982 * Create a cpio-compatible list of the requisite files in 983 * the temporary file. 984 */ 985 if (!making_sig) { 986 for (i = 0; pkg[i]; i++) { 987 register ssize_t entry_size; 988 989 /* 990 * Copy pkginfo and pkgmap filenames into the 991 * temporary string allowing for the first line 992 * as a special case. 993 */ 994 entry_size = sprintf(tmp_entry, 995 (i == 0) ? "%s/%s\n%s/%s" : "\n%s/%s\n%s/%s", 996 pkg[i], PKGINFO, pkg[i], PKGMAP); 997 998 if (write(list_fd, tmp_entry, 999 entry_size) != entry_size) { 1000 progerr(pkg_gt(ERR_TRANSFER)); 1001 logerr(pkg_gt(MSG_NOTMPFIL), tmp_file); 1002 (void) close(list_fd); 1003 ecleanup(); 1004 return (1); 1005 } 1006 } 1007 1008 } else { 1009 register ssize_t entry_size; 1010 1011 /* 1012 * if we're making a signature, we must make a 1013 * temporary area full of symlinks to the requisite 1014 * files, plus an extra entry for the signature, so 1015 * that cpio will put all files and signature in the 1016 * same archive in a single invocation of cpio. 1017 */ 1018 tmpsymdir = xstrdup(tmpnam(NULL)); 1019 1020 if (mkdir(tmpsymdir, S_IRWXU)) { 1021 progerr(pkg_gt(ERR_TRANSFER)); 1022 logerr(pkg_gt(MSG_MKDIR), tmpsymdir); 1023 return (1); 1024 } 1025 1026 /* generate the signature */ 1027 if (((len = snprintf(path, PATH_MAX, "%s/%s", 1028 tmpsymdir, SIGNATURE_FILENAME)) >= PATH_MAX) || 1029 len < 0) { 1030 progerr(pkg_gt(ERR_TRANSFER)); 1031 logerr(pkg_gt(MSG_NOTMPFIL), tmpsymdir); 1032 cleanup(); 1033 return (1); 1034 } 1035 1036 if ((fp = fopen(path, "w")) == NULL) { 1037 progerr(pkg_gt(ERR_TRANSFER)); 1038 logerr(pkg_gt(MSG_NOTMPFIL), path); 1039 cleanup(); 1040 return (1); 1041 } 1042 (void) PEM_write_PKCS7(fp, sig); 1043 (void) fclose(fp); 1044 1045 for (i = 0; pkg[i]; i++) { 1046 (void) snprintf(path, sizeof (path), 1047 "%s/%s", tmpsymdir, pkg[i]); 1048 if (mkdir(path, 0755)) { 1049 progerr(pkg_gt(ERR_TRANSFER)); 1050 logerr(pkg_gt(MSG_MKDIR), path); 1051 cleanup(); 1052 return (1); 1053 } 1054 (void) snprintf(path, sizeof (path), 1055 "%s/%s/%s", tmpsymdir, pkg[i], PKGINFO); 1056 (void) snprintf(srcpath, sizeof (srcpath), 1057 "%s/%s/%s", src, pkg[i], PKGINFO); 1058 if (symlink(srcpath, path) != 0) { 1059 progerr(pkg_gt(ERR_TRANSFER)); 1060 logerr(pkg_gt(MSG_SYMLINK), path, srcpath); 1061 cleanup(); 1062 return (1); 1063 } 1064 1065 (void) snprintf(path, sizeof (path), 1066 "%s/%s/%s", tmpsymdir, pkg[i], PKGMAP); 1067 (void) snprintf(srcpath, sizeof (srcpath), 1068 "%s/%s/%s", src, pkg[i], PKGMAP); 1069 if (symlink(srcpath, path) != 0) { 1070 progerr(pkg_gt(ERR_TRANSFER)); 1071 logerr(pkg_gt(MSG_SYMLINK), path, srcpath); 1072 cleanup(); 1073 return (1); 1074 } 1075 1076 /* 1077 * Copy pkginfo and pkgmap filenames into the 1078 * temporary string allowing for the first line 1079 * as a special case. 1080 */ 1081 entry_size = snprintf(tmp_entry, sizeof (tmp_entry), 1082 (i == 0) ? "%s/%s\n%s/%s" : "\n%s/%s\n%s/%s", 1083 pkg[i], PKGINFO, pkg[i], PKGMAP); 1084 1085 if (write(list_fd, tmp_entry, 1086 entry_size) != entry_size) { 1087 progerr(pkg_gt(ERR_TRANSFER)); 1088 logerr(pkg_gt(MSG_NOTMPFIL), tmp_file); 1089 (void) close(list_fd); 1090 ecleanup(); 1091 cleanup(); 1092 return (1); 1093 } 1094 } 1095 1096 /* add signature to list of files */ 1097 entry_size = snprintf(tmp_entry, sizeof (tmp_entry), "\n%s", 1098 SIGNATURE_FILENAME); 1099 if (write(list_fd, tmp_entry, entry_size) != entry_size) { 1100 progerr(pkg_gt(ERR_TRANSFER)); 1101 logerr(pkg_gt(MSG_NOTMPFIL), tmp_file); 1102 (void) close(list_fd); 1103 ecleanup(); 1104 cleanup(); 1105 return (1); 1106 } 1107 } 1108 1109 (void) lseek(list_fd, 0, SEEK_SET); 1110 1111 if (!making_sig) { 1112 (void) snprintf(tmp_entry, sizeof (tmp_entry), 1113 "%s -ocD -C %d", CPIOPROC, (int)BLK_SIZE); 1114 } else { 1115 /* 1116 * when making a signature, we must make sure to follow 1117 * symlinks during the cpio so that we don't archive 1118 * the links themselves 1119 */ 1120 (void) snprintf(tmp_entry, sizeof (tmp_entry), 1121 "%s -ocDL -C %d", CPIOPROC, (int)BLK_SIZE); 1122 } 1123 1124 if (making_sig) { 1125 /* save cwd and change to symlink dir for cpio invocation */ 1126 if (getcwd(cwd, MAXPATHLEN + 1) == NULL) { 1127 logerr(pkg_gt(ERR_GETWD)); 1128 progerr(pkg_gt(ERR_TRANSFER)); 1129 cleanup(); 1130 return (1); 1131 } 1132 1133 if (chdir(tmpsymdir)) { 1134 progerr(pkg_gt(ERR_TRANSFER)); 1135 logerr(pkg_gt(MSG_CHDIR), tmpsymdir); 1136 cleanup(); 1137 return (1); 1138 } 1139 } 1140 1141 if (n = esystem(tmp_entry, list_fd, ds_fd)) { 1142 rpterr(); 1143 progerr(pkg_gt(ERR_TRANSFER)); 1144 logerr(pkg_gt(MSG_CMDFAIL), tmp_entry, n); 1145 (void) close(list_fd); 1146 (void) unlink(tmp_file); 1147 cleanup(); 1148 return (1); 1149 } 1150 1151 (void) close(list_fd); 1152 (void) unlink(tmp_file); 1153 1154 if (making_sig) { 1155 /* change to back to src dir for subsequent operations */ 1156 if (chdir(cwd)) { 1157 progerr(pkg_gt(ERR_TRANSFER)); 1158 logerr(pkg_gt(MSG_CHDIR), cwd); 1159 cleanup(); 1160 return (1); 1161 } 1162 } 1163 return (0); 1164 } 1165 1166 static int 1167 ckoverwrite(char *dir, char *inst, int options) 1168 { 1169 char path[PATH_MAX]; 1170 1171 (void) snprintf(path, sizeof (path), "%s/%s", dir, inst); 1172 if (access(path, 0) == 0) { 1173 if (options & PT_OVERWRITE) 1174 return (rrmdir(path)); 1175 progerr(pkg_gt(ERR_TRANSFER)); 1176 logerr(pkg_gt(MSG_EXISTS), path); 1177 return (1); 1178 } 1179 return (0); 1180 } 1181 1182 static int 1183 pkgxfer(char *srcinst, int options) 1184 { 1185 int r; 1186 struct pkginfo info; 1187 FILE *fp, *pp; 1188 char *pt, *src, *dst; 1189 char dstdir[PATH_MAX], 1190 temp[PATH_MAX], 1191 srcdir[PATH_MAX], 1192 cmd[CMDSIZE], 1193 pkgname[NON_ABI_NAMELNGTH]; 1194 int i, n, part, nparts, maxpartsize, curpartcnt, iscomp; 1195 char volnos[128], tmpvol[128]; 1196 struct statvfs64 svfsb; 1197 longlong_t free_blocks; 1198 struct stat srcstat; 1199 1200 info.pkginst = NULL; /* required initialization */ 1201 1202 /* 1203 * when this routine is entered, the first part of 1204 * the package to transfer is already available in 1205 * the directory indicated by 'src' --- unless the 1206 * source device is a datstream, in which case only 1207 * the pkginfo and pkgmap files are available in 'src' 1208 */ 1209 src = srcdev.dirname; 1210 dst = dstdev.dirname; 1211 1212 if (!(options & PT_SILENT)) 1213 (void) fprintf(stderr, pkg_gt(MSG_TRANSFER), srcinst); 1214 (void) strlcpy(dstinst, srcinst, sizeof (dstinst)); 1215 1216 if (!(options & PT_ODTSTREAM)) { 1217 /* destination is a (possibly mounted) directory */ 1218 (void) snprintf(dstdir, sizeof (dstdir), 1219 "%s/%s", dst, dstinst); 1220 1221 /* 1222 * need to check destination directory to assure 1223 * that we will not be duplicating a package which 1224 * already resides there (though we are allowed to 1225 * overwrite the same version) 1226 */ 1227 pkgdir = src; 1228 if (fpkginfo(&info, srcinst)) { 1229 progerr(pkg_gt(ERR_TRANSFER)); 1230 logerr(pkg_gt(MSG_NOEXISTS), srcinst); 1231 (void) fpkginfo(&info, NULL); 1232 return (1); 1233 } 1234 pkgdir = dst; 1235 1236 (void) strlcpy(temp, srcinst, sizeof (temp)); 1237 if (pt = strchr(temp, '.')) 1238 *pt = '\0'; 1239 (void) strlcat(temp, ".*", sizeof (temp)); 1240 1241 if (pt = fpkginst(temp, info.arch, info.version)) { 1242 /* 1243 * the same instance already exists, although 1244 * its pkgid might be different 1245 */ 1246 if (options & PT_OVERWRITE) { 1247 (void) strlcpy(dstinst, pt, sizeof (dstinst)); 1248 (void) snprintf(dstdir, sizeof (dstdir), 1249 "%s/%s", dst, dstinst); 1250 } else { 1251 progerr(pkg_gt(ERR_TRANSFER)); 1252 logerr(pkg_gt(MSG_DUPVERS), srcinst); 1253 (void) fpkginfo(&info, NULL); 1254 (void) fpkginst(NULL); 1255 return (2); 1256 } 1257 } else if (options & PT_RENAME) { 1258 /* 1259 * find next available instance by appending numbers 1260 * to the package abbreviation until the instance 1261 * does not exist in the destination directory 1262 */ 1263 if (pt = strchr(temp, '.')) 1264 *pt = '\0'; 1265 for (i = 2; (access(dstdir, 0) == 0); i++) { 1266 (void) snprintf(dstinst, sizeof (dstinst), 1267 "%s.%d", temp, i); 1268 (void) snprintf(dstdir, sizeof (dstdir), 1269 "%s/%s", dst, dstinst); 1270 } 1271 } else if (options & PT_OVERWRITE) { 1272 /* 1273 * we're allowed to overwrite, but there seems 1274 * to be no valid package to overwrite, and we are 1275 * not allowed to rename the destination, so act 1276 * as if we weren't given permission to overwrite 1277 * --- this keeps us from removing a destination 1278 * instance which is named the same as the source 1279 * instance, but really reflects a different pkg! 1280 */ 1281 options &= (~PT_OVERWRITE); 1282 } 1283 (void) fpkginfo(&info, NULL); 1284 (void) fpkginst(NULL); 1285 1286 if (ckoverwrite(dst, dstinst, options)) 1287 return (2); 1288 1289 if (isdir(dstdir) && mkdir(dstdir, 0755)) { 1290 progerr(pkg_gt(ERR_TRANSFER)); 1291 logerr(pkg_gt(MSG_MKDIR), dstdir); 1292 return (1); 1293 } 1294 1295 (void) snprintf(srcdir, sizeof (srcdir), 1296 "%s/%s", src, srcinst); 1297 if (stat(srcdir, &srcstat) != -1) { 1298 if (chmod(dstdir, (srcstat.st_mode & S_IAMB)) == -1) { 1299 progerr(pkg_gt(ERR_TRANSFER)); 1300 logerr(pkg_gt(MSG_CHMODDIR), dstdir); 1301 return (1); 1302 } 1303 } else { 1304 progerr(pkg_gt(ERR_TRANSFER)); 1305 logerr(pkg_gt(MSG_STATDIR), srcdir); 1306 return (1); 1307 } 1308 } 1309 1310 if (!(options & PT_SILENT) && strcmp(dstinst, srcinst)) 1311 (void) fprintf(stderr, pkg_gt(MSG_RENAME), dstinst); 1312 1313 (void) snprintf(srcdir, sizeof (srcdir), "%s/%s", src, srcinst); 1314 if (chdir(srcdir)) { 1315 progerr(pkg_gt(ERR_TRANSFER)); 1316 logerr(pkg_gt(MSG_CHDIR), srcdir); 1317 return (1); 1318 } 1319 1320 if (ids_name) { /* unpack the datatstream into a directory */ 1321 /* 1322 * transfer pkginfo & pkgmap first 1323 */ 1324 (void) snprintf(cmd, sizeof (cmd), 1325 "%s -pudm %s", CPIOPROC, dstdir); 1326 if ((pp = epopen(cmd, "w")) == NULL) { 1327 rpterr(); 1328 progerr(pkg_gt(ERR_TRANSFER)); 1329 logerr(pkg_gt(MSG_POPEN), cmd, errno); 1330 return (1); 1331 } 1332 (void) fprintf(pp, "%s\n%s\n", PKGINFO, PKGMAP); 1333 1334 (void) sighold(SIGINT); 1335 (void) sighold(SIGHUP); 1336 r = epclose(pp); 1337 (void) sigrelse(SIGINT); 1338 (void) sigrelse(SIGHUP); 1339 1340 if (r != 0) { 1341 rpterr(); 1342 progerr(pkg_gt(ERR_TRANSFER)); 1343 logerr(pkg_gt(MSG_PCLOSE), cmd, errno); 1344 return (1); 1345 } 1346 1347 if (options & PT_INFO_ONLY) 1348 return (0); /* don't transfer objects */ 1349 1350 if (chdir(dstdir)) { 1351 progerr(pkg_gt(ERR_TRANSFER)); 1352 logerr(pkg_gt(MSG_CHDIR), dstdir); 1353 return (1); 1354 } 1355 1356 /* 1357 * for each part of the package, use cpio() to 1358 * unpack the archive into the destination directory 1359 */ 1360 nparts = ds_findpkg(srcdev.cdevice, srcinst); 1361 if (nparts < 0) { 1362 progerr(pkg_gt(ERR_TRANSFER)); 1363 return (1); 1364 } 1365 for (part = 1; part <= nparts; /* void */) { 1366 if (ds_getpkg(srcdev.cdevice, part, dstdir)) { 1367 progerr(pkg_gt(ERR_TRANSFER)); 1368 return (1); 1369 } 1370 part++; 1371 if (dstdev.mount) { 1372 (void) chdir("/"); 1373 if (pkgumount(&dstdev)) 1374 return (1); 1375 if (part <= nparts) { 1376 if (n = pkgmount(&dstdev, NULL, part+1, 1377 nparts, 1)) 1378 return (n); 1379 if (ckoverwrite(dst, dstinst, options)) 1380 return (1); 1381 if (isdir(dstdir) && 1382 mkdir(dstdir, 0755)) { 1383 progerr( 1384 pkg_gt(ERR_TRANSFER)); 1385 logerr(pkg_gt(MSG_MKDIR), 1386 dstdir); 1387 return (1); 1388 } 1389 /* 1390 * since volume is removable, each part 1391 * must contain a duplicate of the 1392 * pkginfo file to properly identify the 1393 * volume 1394 */ 1395 if (chdir(srcdir)) { 1396 progerr( 1397 pkg_gt(ERR_TRANSFER)); 1398 logerr(pkg_gt(MSG_CHDIR), 1399 srcdir); 1400 return (1); 1401 } 1402 if ((pp = epopen(cmd, "w")) == NULL) { 1403 rpterr(); 1404 progerr( 1405 pkg_gt(ERR_TRANSFER)); 1406 logerr(pkg_gt(MSG_POPEN), 1407 cmd, errno); 1408 return (1); 1409 } 1410 (void) fprintf(pp, "pkginfo"); 1411 1412 (void) sighold(SIGINT); 1413 (void) sighold(SIGHUP); 1414 r = epclose(pp); 1415 (void) sigrelse(SIGINT); 1416 (void) sigrelse(SIGHUP); 1417 1418 if (r != 0) { 1419 rpterr(); 1420 progerr( 1421 pkg_gt(ERR_TRANSFER)); 1422 logerr(pkg_gt(MSG_PCLOSE), 1423 cmd, errno); 1424 return (1); 1425 } 1426 if (chdir(dstdir)) { 1427 progerr( 1428 pkg_gt(ERR_TRANSFER)); 1429 logerr(pkg_gt(MSG_CHDIR), 1430 dstdir); 1431 return (1); 1432 } 1433 } 1434 } 1435 } 1436 return (0); 1437 } 1438 1439 if ((fp = fopen(PKGMAP, "r")) == NULL) { 1440 progerr(pkg_gt(ERR_TRANSFER)); 1441 logerr(pkg_gt(MSG_NOPKGMAP), srcinst); 1442 return (1); 1443 } 1444 1445 nparts = 1; 1446 if (!rd_map_size(fp, &nparts, &maxpartsize, &compressedsize)) 1447 return (1); 1448 else 1449 (void) fclose(fp); 1450 1451 if (srcdev.mount) { 1452 if (ckvolseq(srcdir, 1, nparts)) { 1453 progerr(pkg_gt(ERR_TRANSFER)); 1454 logerr(pkg_gt(MSG_SEQUENCE)); 1455 return (1); 1456 } 1457 } 1458 1459 /* write each part of this package */ 1460 if (options & PT_ODTSTREAM) { 1461 char line[128]; 1462 (void) mgets(line, 128); 1463 curpartcnt = -1; 1464 /* LINTED E_SEC_SCANF_UNBOUNDED_COPY */ 1465 if (sscanf(line, "%s %d %d %[ 0-9]", pkgname, &nparts, 1466 &maxpartsize, volnos) == 4) { 1467 (void) sscanf(volnos, 1468 "%d %[ 0-9]", &curpartcnt, tmpvol); 1469 (void) strlcpy(volnos, tmpvol, sizeof (volnos)); 1470 } 1471 } 1472 1473 for (part = 1; part <= nparts; /* void */) { 1474 if (curpartcnt == 0 && (options & PT_ODTSTREAM)) { 1475 char prompt[128]; 1476 int index; 1477 ds_volno++; 1478 (void) ds_close(0); 1479 (void) sprintf(prompt, 1480 pkg_gt("Insert %%v %d of %d into %%p"), 1481 ds_volno, ds_volcnt); 1482 if (n = getvol(ods_name, NULL, DM_FORMAT, prompt)) 1483 return (n); 1484 if ((ds_fd = open(dstdev.cdevice, O_WRONLY)) < 0) { 1485 progerr(pkg_gt(ERR_TRANSFER)); 1486 logerr(pkg_gt(MSG_OPEN), dstdev.cdevice, 1487 errno); 1488 return (1); 1489 } 1490 if (ds_ginit(dstdev.cdevice) < 0) { 1491 progerr(pkg_gt(ERR_TRANSFER)); 1492 logerr(pkg_gt(MSG_OPEN), dstdev.cdevice, 1493 errno); 1494 (void) ds_close(0); 1495 return (1); 1496 } 1497 1498 (void) sscanf(volnos, "%d %[ 0-9]", &index, tmpvol); 1499 (void) strlcpy(volnos, tmpvol, sizeof (volnos)); 1500 curpartcnt += index; 1501 } 1502 1503 if (options & PT_INFO_ONLY) 1504 nparts = 0; 1505 1506 if (part == 1) { 1507 (void) snprintf(cmd, sizeof (cmd), 1508 "find %s %s", PKGINFO, PKGMAP); 1509 if (nparts && (isdir(INSTALL) == 0)) { 1510 (void) strlcat(cmd, " ", sizeof (cmd)); 1511 (void) strlcat(cmd, INSTALL, sizeof (cmd)); 1512 } 1513 } else 1514 (void) snprintf(cmd, sizeof (cmd), "find %s", PKGINFO); 1515 1516 if (nparts > 1) { 1517 (void) snprintf(temp, sizeof (temp), 1518 "%s.%d", RELOC, part); 1519 if (iscpio(temp, &iscomp) || isdir(temp) == 0) { 1520 (void) strlcat(cmd, " ", sizeof (cmd)); 1521 (void) strlcat(cmd, temp, sizeof (cmd)); 1522 } 1523 (void) snprintf(temp, sizeof (temp), 1524 "%s.%d", ROOT, part); 1525 if (iscpio(temp, &iscomp) || isdir(temp) == 0) { 1526 (void) strlcat(cmd, " ", sizeof (cmd)); 1527 (void) strlcat(cmd, temp, sizeof (cmd)); 1528 } 1529 (void) snprintf(temp, sizeof (temp), 1530 "%s.%d", ARCHIVE, part); 1531 if (isdir(temp) == 0) { 1532 (void) strlcat(cmd, " ", sizeof (cmd)); 1533 (void) strlcat(cmd, temp, sizeof (cmd)); 1534 } 1535 } else if (nparts) { 1536 for (i = 0; reloc_names[i] != NULL; i++) { 1537 if (iscpio(reloc_names[i], &iscomp) || 1538 isdir(reloc_names[i]) == 0) { 1539 (void) strlcat(cmd, " ", sizeof (cmd)); 1540 (void) strlcat(cmd, reloc_names[i], 1541 sizeof (cmd)); 1542 } 1543 } 1544 for (i = 0; root_names[i] != NULL; i++) { 1545 if (iscpio(root_names[i], &iscomp) || 1546 isdir(root_names[i]) == 0) { 1547 (void) strlcat(cmd, " ", sizeof (cmd)); 1548 (void) strlcat(cmd, root_names[i], 1549 sizeof (cmd)); 1550 } 1551 } 1552 if (isdir(ARCHIVE) == 0) { 1553 (void) strlcat(cmd, " ", sizeof (cmd)); 1554 (void) strlcat(cmd, ARCHIVE, sizeof (cmd)); 1555 } 1556 } 1557 if (options & PT_ODTSTREAM) { 1558 (void) snprintf(cmd + strlen(cmd), 1559 sizeof (cmd) - strlen(cmd), 1560 " -print | %s -ocD -C %d", 1561 CPIOPROC, (int)BLK_SIZE); 1562 } else { 1563 if (statvfs64(dstdir, &svfsb) == -1) { 1564 progerr(pkg_gt(ERR_TRANSFER)); 1565 logerr(pkg_gt(MSG_STATVFS), dstdir, errno); 1566 return (1); 1567 } 1568 1569 free_blocks = (((long)svfsb.f_frsize > 0) ? 1570 howmany(svfsb.f_frsize, DEV_BSIZE) : 1571 howmany(svfsb.f_bsize, DEV_BSIZE)) * svfsb.f_bavail; 1572 1573 if ((has_comp_size ? compressedsize : maxpartsize) > 1574 free_blocks) { 1575 progerr(pkg_gt(ERR_TRANSFER)); 1576 logerr(pkg_gt(MSG_NOSPACE), 1577 has_comp_size ? 1578 (long)compressedsize : (long)maxpartsize, 1579 free_blocks); 1580 return (1); 1581 } 1582 (void) snprintf(cmd + strlen(cmd), 1583 sizeof (cmd) - strlen(cmd), 1584 " -print | %s -pdum %s", 1585 CPIOPROC, dstdir); 1586 } 1587 1588 n = esystem(cmd, -1, (options & PT_ODTSTREAM) ? ds_fd : -1); 1589 if (n) { 1590 rpterr(); 1591 progerr(pkg_gt(ERR_TRANSFER)); 1592 logerr(pkg_gt(MSG_CMDFAIL), cmd, n); 1593 return (1); 1594 } 1595 1596 part++; 1597 if (srcdev.mount && (nparts > 1)) { 1598 /* unmount current source volume */ 1599 (void) chdir("/"); 1600 if (pkgumount(&srcdev)) 1601 return (1); 1602 /* loop until volume is mounted successfully */ 1603 while (part <= nparts) { 1604 /* read only */ 1605 n = pkgmount(&srcdev, NULL, part, nparts, 1); 1606 if (n) 1607 return (n); 1608 if (chdir(srcdir)) { 1609 progerr(pkg_gt(ERR_TRANSFER)); 1610 logerr(pkg_gt(MSG_CORRUPT)); 1611 (void) chdir("/"); 1612 (void) pkgumount(&srcdev); 1613 continue; 1614 } 1615 if (ckvolseq(srcdir, part, nparts)) { 1616 (void) chdir("/"); 1617 (void) pkgumount(&srcdev); 1618 continue; 1619 } 1620 break; 1621 } 1622 } 1623 if (!(options & PT_ODTSTREAM) && dstdev.mount) { 1624 /* unmount current volume */ 1625 if (pkgumount(&dstdev)) 1626 return (1); 1627 /* loop until next volume is mounted successfully */ 1628 while (part <= nparts) { 1629 /* writable */ 1630 n = pkgmount(&dstdev, NULL, part, nparts, 1); 1631 if (n) 1632 return (n); 1633 if (ckoverwrite(dst, dstinst, options)) 1634 continue; 1635 if (isdir(dstdir) && mkdir(dstdir, 0755)) { 1636 progerr(pkg_gt(ERR_TRANSFER)); 1637 logerr(pkg_gt(MSG_MKDIR), dstdir); 1638 continue; 1639 } 1640 break; 1641 } 1642 } 1643 1644 if ((options & PT_ODTSTREAM) && part <= nparts) { 1645 if (curpartcnt >= 0 && part > curpartcnt) { 1646 char prompt[128]; 1647 int index; 1648 ds_volno++; 1649 if (ds_close(0)) 1650 return (1); 1651 (void) sprintf(prompt, 1652 pkg_gt("Insert %%v %d of %d into %%p"), 1653 ds_volno, ds_volcnt); 1654 if (n = getvol(ods_name, NULL, DM_FORMAT, 1655 prompt)) 1656 return (n); 1657 if ((ds_fd = open(dstdev.cdevice, 1)) < 0) { 1658 progerr(pkg_gt(ERR_TRANSFER)); 1659 logerr(pkg_gt(MSG_OPEN), 1660 dstdev.cdevice, errno); 1661 return (1); 1662 } 1663 if (ds_ginit(dstdev.cdevice) < 0) { 1664 progerr(pkg_gt(ERR_TRANSFER)); 1665 logerr(pkg_gt(MSG_OPEN), 1666 dstdev.cdevice, errno); 1667 (void) ds_close(0); 1668 return (1); 1669 } 1670 1671 (void) sscanf(volnos, "%d %[ 0-9]", &index, 1672 tmpvol); 1673 (void) strlcpy(volnos, tmpvol, sizeof (volnos)); 1674 curpartcnt += index; 1675 } 1676 } 1677 1678 } 1679 return (0); 1680 } 1681 1682 /* 1683 * Name: pkgdump 1684 * Description: Dump a cpio archive of a package's contents to a BIO. 1685 * 1686 * Arguments: srcinst - Name of package, which resides on the 1687 * device pointed to by the static 'srcdev' variable, 1688 * to dump. 1689 * bio - BIO object to dump data to 1690 * 1691 * Returns : 0 - success 1692 * nonzero - failure. errors printed to screen. 1693 */ 1694 static int 1695 pkgdump(char *srcinst, BIO *bio) 1696 { 1697 FILE *fp; 1698 char *src; 1699 char temp[MAXPATHLEN], 1700 srcdir[MAXPATHLEN], 1701 cmd[CMDSIZE]; 1702 int i, n, part, nparts, maxpartsize, iscomp; 1703 1704 /* 1705 * when this routine is entered, the entire package 1706 * is already available at 'src' - including the 1707 * pkginfo/pkgmap files and the objects as well. 1708 */ 1709 1710 /* read the pkgmap to get it's size information */ 1711 if ((fp = fopen(PKGMAP, "r")) == NULL) { 1712 progerr(pkg_gt(ERR_TRANSFER)); 1713 logerr(pkg_gt(MSG_NOPKGMAP), srcinst); 1714 return (1); 1715 } 1716 1717 nparts = 1; 1718 if (!rd_map_size(fp, &nparts, &maxpartsize, &compressedsize)) 1719 return (1); 1720 else 1721 (void) fclose(fp); 1722 1723 /* make sure the first volume is available */ 1724 if (srcdev.mount) { 1725 src = srcdev.dirname; 1726 (void) snprintf(srcdir, MAXPATHLEN, "%s/%s", src, srcinst); 1727 if (ckvolseq(srcdir, 1, nparts)) { 1728 progerr(pkg_gt(ERR_TRANSFER)); 1729 logerr(pkg_gt(MSG_SEQUENCE)); 1730 return (1); 1731 } 1732 } 1733 1734 /* 1735 * form cpio command that will output the contents of all of 1736 * this package's parts 1737 */ 1738 for (part = 1; part <= nparts; /* void */) { 1739 1740 if (part == 1) { 1741 (void) snprintf(cmd, CMDSIZE, "find %s %s", 1742 PKGINFO, PKGMAP); 1743 if (nparts && (isdir(INSTALL) == 0)) { 1744 (void) strlcat(cmd, " ", sizeof (cmd)); 1745 (void) strlcat(cmd, INSTALL, sizeof (cmd)); 1746 } 1747 } else 1748 (void) snprintf(cmd, CMDSIZE, "find %s", PKGINFO); 1749 1750 if (nparts > 1) { 1751 (void) snprintf(temp, MAXPATHLEN, "%s.%d", RELOC, part); 1752 if (iscpio(temp, &iscomp) || isdir(temp) == 0) { 1753 (void) strlcat(cmd, " ", CMDSIZE); 1754 (void) strlcat(cmd, temp, CMDSIZE); 1755 } 1756 (void) snprintf(temp, MAXPATHLEN, "%s.%d", ROOT, part); 1757 if (iscpio(temp, &iscomp) || isdir(temp) == 0) { 1758 (void) strlcat(cmd, " ", CMDSIZE); 1759 (void) strlcat(cmd, temp, CMDSIZE); 1760 } 1761 (void) snprintf(temp, MAXPATHLEN, "%s.%d", 1762 ARCHIVE, part); 1763 if (isdir(temp) == 0) { 1764 (void) strlcat(cmd, " ", CMDSIZE); 1765 (void) strlcat(cmd, temp, CMDSIZE); 1766 } 1767 } else if (nparts) { 1768 for (i = 0; reloc_names[i] != NULL; i++) { 1769 if (iscpio(reloc_names[i], &iscomp) || 1770 isdir(reloc_names[i]) == 0) { 1771 (void) strlcat(cmd, " ", CMDSIZE); 1772 (void) strlcat(cmd, reloc_names[i], 1773 CMDSIZE); 1774 } 1775 } 1776 for (i = 0; root_names[i] != NULL; i++) { 1777 if (iscpio(root_names[i], &iscomp) || 1778 isdir(root_names[i]) == 0) { 1779 (void) strlcat(cmd, " ", CMDSIZE); 1780 (void) strlcat(cmd, root_names[i], 1781 CMDSIZE); 1782 } 1783 } 1784 if (isdir(ARCHIVE) == 0) { 1785 (void) strlcat(cmd, " ", CMDSIZE); 1786 (void) strlcat(cmd, ARCHIVE, CMDSIZE); 1787 } 1788 } 1789 1790 (void) snprintf(cmd + strlen(cmd), 1791 sizeof (cmd) - strlen(cmd), 1792 " -print | %s -ocD -C %d", 1793 CPIOPROC, (int)BLK_SIZE); 1794 /* 1795 * execute the command, dumping all standard output 1796 * to the BIO. 1797 */ 1798 n = BIO_dump_cmd(cmd, bio); 1799 if (n != 0) { 1800 rpterr(); 1801 progerr(pkg_gt(ERR_TRANSFER)); 1802 logerr(pkg_gt(MSG_CMDFAIL), cmd, n); 1803 return (1); 1804 } 1805 1806 part++; 1807 } 1808 return (0); 1809 } 1810 1811 static void 1812 sigtrap(int signo) 1813 { 1814 _NOTE(ARGUNUSED(signo)); 1815 signal_received++; 1816 } 1817 1818 static void 1819 cleanup(void) 1820 { 1821 (void) chdir("/"); 1822 if (tmpdir) { 1823 (void) rrmdir(tmpdir); 1824 free(tmpdir); 1825 tmpdir = NULL; 1826 } 1827 1828 if (tmppath) { 1829 /* remove any previous tmppath stuff */ 1830 (void) rrmdir(tmppath); 1831 free(tmppath); 1832 tmppath = NULL; 1833 } 1834 1835 if (tmpsymdir) { 1836 /* remove temp symbolic links made for signed pkg */ 1837 (void) rrmdir(tmpsymdir); 1838 free(tmpsymdir); 1839 tmpsymdir = NULL; 1840 } 1841 1842 if (srcdev.mount && !ids_name) 1843 (void) pkgumount(&srcdev); 1844 if (dstdev.mount && !ods_name) 1845 (void) pkgumount(&dstdev); 1846 (void) ds_close(1); 1847 } 1848 1849 /* 1850 * Name: dump_hdr_and_pkgs 1851 * Description: Dumps datastream header and each package's contents 1852 * to the supplied BIO 1853 * 1854 * Arguments: bio - BIO object to dump data to 1855 * hdr - Header for the datastream being dumped 1856 * pkglist - NULL-terminated list of packages 1857 * to dump. The location of the packages are stored 1858 * in the static 'srcdev' variable. 1859 * 1860 * Returns : 0 - success 1861 * nonzero - failure. errors printed to screen. 1862 */ 1863 static int 1864 dump_hdr_and_pkgs(BIO *bio, struct dm_buf *hdr, char **pkglist) 1865 { 1866 int block_cnt, i; 1867 char srcdir[MAXPATHLEN]; 1868 char cwd[MAXPATHLEN + 1]; 1869 char *src; 1870 1871 /* write out the header to the signature stream */ 1872 for (block_cnt = 0; block_cnt < hdr->allocation; 1873 block_cnt += BLK_SIZE) { 1874 (void) BIO_write(bio, (hdr->text_buffer + block_cnt), BLK_SIZE); 1875 } 1876 1877 /* save current directory */ 1878 if (getcwd(cwd, MAXPATHLEN + 1) == NULL) { 1879 logerr(pkg_gt(ERR_GETWD)); 1880 progerr(pkg_gt(ERR_TRANSFER)); 1881 return (1); 1882 } 1883 1884 /* now write out each package's contents */ 1885 for (i = 0; pkglist[i]; i++) { 1886 /* 1887 * change to the source dir, so we can find and dump 1888 * the package(s) bits into the BIO 1889 * 1890 */ 1891 src = srcdev.dirname; 1892 1893 /* change to the package source directory */ 1894 (void) snprintf(srcdir, MAXPATHLEN, "%s/%s", src, pkglist[i]); 1895 if (chdir(srcdir)) { 1896 progerr(pkg_gt(ERR_TRANSFER)); 1897 logerr(pkg_gt(MSG_CHDIR), srcdir); 1898 return (1); 1899 } 1900 1901 if (pkgdump(pkglist[i], bio)) { 1902 pkglist[i] = NULL; 1903 return (1); 1904 } 1905 } 1906 1907 /* change back to directory we were in upon entering this routine */ 1908 if (chdir(cwd)) { 1909 progerr(pkg_gt(ERR_TRANSFER)); 1910 logerr(pkg_gt(MSG_CHDIR), cwd); 1911 return (1); 1912 } 1913 1914 return (0); 1915 } 1916 1917 /* 1918 * Name: BIO_dump_cmd 1919 * Description: Dump the output of invoking a command 1920 * to a BIO. 1921 * 1922 * Arguments: cmd - Command to invoke 1923 * bio - BIO to dump output of command to 1924 * only 'stdout' is dumped. 1925 * Returns : 0 - success 1926 * nonzero - failure. errors printed to screen. 1927 */ 1928 int 1929 BIO_dump_cmd(char *cmd, BIO *bio) 1930 { 1931 char buf[BLK_SIZE]; 1932 FILE *fp; 1933 int rc; 1934 1935 /* start up the process */ 1936 if ((fp = epopen(cmd, "r")) == NULL) { 1937 rpterr(); 1938 return (1); 1939 } 1940 1941 /* read output in chunks, transfer to BIO */ 1942 while (fread(buf, BLK_SIZE, 1, fp) == 1) { 1943 if (BIO_write(bio, buf, BLK_SIZE) != BLK_SIZE) { 1944 (void) sighold(SIGINT); 1945 (void) sighold(SIGHUP); 1946 (void) epclose(fp); 1947 (void) sigrelse(SIGINT); 1948 (void) sigrelse(SIGHUP); 1949 rpterr(); 1950 return (1); 1951 } 1952 } 1953 1954 /* done with stream, make sure no errors were encountered */ 1955 if (ferror(fp)) { 1956 (void) epclose(fp); 1957 rpterr(); 1958 return (1); 1959 } 1960 1961 /* done, close stream, report any errors */ 1962 (void) sighold(SIGINT); 1963 (void) sighold(SIGHUP); 1964 rc = epclose(fp); 1965 (void) sigrelse(SIGINT); 1966 (void) sigrelse(SIGHUP); 1967 if (rc != 0) { 1968 rpterr(); 1969 return (1); 1970 } 1971 1972 return (rc); 1973 } 1974