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