15c51f124SMoriah Waterland /* 25c51f124SMoriah Waterland * CDDL HEADER START 35c51f124SMoriah Waterland * 45c51f124SMoriah Waterland * The contents of this file are subject to the terms of the 55c51f124SMoriah Waterland * Common Development and Distribution License (the "License"). 65c51f124SMoriah Waterland * You may not use this file except in compliance with the License. 75c51f124SMoriah Waterland * 85c51f124SMoriah Waterland * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 95c51f124SMoriah Waterland * or http://www.opensolaris.org/os/licensing. 105c51f124SMoriah Waterland * See the License for the specific language governing permissions 115c51f124SMoriah Waterland * and limitations under the License. 125c51f124SMoriah Waterland * 135c51f124SMoriah Waterland * When distributing Covered Code, include this CDDL HEADER in each 145c51f124SMoriah Waterland * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 155c51f124SMoriah Waterland * If applicable, add the following below this CDDL HEADER, with the 165c51f124SMoriah Waterland * fields enclosed by brackets "[]" replaced with your own identifying 175c51f124SMoriah Waterland * information: Portions Copyright [yyyy] [name of copyright owner] 185c51f124SMoriah Waterland * 195c51f124SMoriah Waterland * CDDL HEADER END 205c51f124SMoriah Waterland */ 215c51f124SMoriah Waterland 225c51f124SMoriah Waterland /* 235c51f124SMoriah Waterland * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 245c51f124SMoriah Waterland * Use is subject to license terms. 255c51f124SMoriah Waterland */ 265c51f124SMoriah Waterland 275c51f124SMoriah Waterland /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 285c51f124SMoriah Waterland /* All Rights Reserved */ 295c51f124SMoriah Waterland 305c51f124SMoriah Waterland 315c51f124SMoriah Waterland 325c51f124SMoriah Waterland #include <stdio.h> 335c51f124SMoriah Waterland #include <errno.h> 345c51f124SMoriah Waterland #include <stdarg.h> 355c51f124SMoriah Waterland #include <limits.h> 365c51f124SMoriah Waterland #include <stdlib.h> 375c51f124SMoriah Waterland #include <unistd.h> 385c51f124SMoriah Waterland #include <fcntl.h> 395c51f124SMoriah Waterland #include <ctype.h> 405c51f124SMoriah Waterland #include <string.h> 415c51f124SMoriah Waterland #include <sys/types.h> 425c51f124SMoriah Waterland #include <sys/param.h> 435c51f124SMoriah Waterland #include <sys/stat.h> 445c51f124SMoriah Waterland #include <sys/statvfs.h> 455c51f124SMoriah Waterland #include <sys/sysmacros.h> 465c51f124SMoriah Waterland #include <dirent.h> 475c51f124SMoriah Waterland #include <signal.h> 485c51f124SMoriah Waterland #include <devmgmt.h> 495c51f124SMoriah Waterland #include <openssl/pkcs12.h> 505c51f124SMoriah Waterland #include <openssl/x509.h> 515c51f124SMoriah Waterland #include <openssl/pkcs7.h> 525c51f124SMoriah Waterland #include <openssl/err.h> 535c51f124SMoriah Waterland #include <openssl/pem.h> 54*4656d474SGarrett D'Amore #include <note.h> 555c51f124SMoriah Waterland #include "pkginfo.h" 565c51f124SMoriah Waterland #include "pkgstrct.h" 575c51f124SMoriah Waterland #include "pkgtrans.h" 585c51f124SMoriah Waterland #include "pkgdev.h" 595c51f124SMoriah Waterland #include "pkglib.h" 605c51f124SMoriah Waterland #include "pkglibmsgs.h" 615c51f124SMoriah Waterland #include "keystore.h" 625c51f124SMoriah Waterland #include "pkglocale.h" 635c51f124SMoriah Waterland #include "pkgerr.h" 645c51f124SMoriah Waterland 655c51f124SMoriah Waterland extern char *pkgdir; /* pkgparam.c */ 665c51f124SMoriah Waterland 675c51f124SMoriah Waterland /* libadm.a */ 685c51f124SMoriah Waterland extern char *devattr(char *device, char *attribute); 695c51f124SMoriah Waterland extern char *fpkginst(char *pkg, ...); 705c51f124SMoriah Waterland extern int fpkginfo(struct pkginfo *info, char *pkginst); 715c51f124SMoriah Waterland extern int getvol(char *device, char *label, int options, char *prompt); 725c51f124SMoriah Waterland extern int _getvol(char *device, char *label, int options, char *prompt, 735c51f124SMoriah Waterland char *norewind); 745c51f124SMoriah Waterland 755c51f124SMoriah Waterland /* dstream.c */ 765c51f124SMoriah Waterland extern int ds_ginit(char *device); 775c51f124SMoriah Waterland extern int ds_close(int pkgendflg); 785c51f124SMoriah Waterland 795c51f124SMoriah Waterland #define CPIOPROC "/usr/bin/cpio" 805c51f124SMoriah Waterland 815c51f124SMoriah Waterland #define CMDSIZE 512 /* command block size */ 825c51f124SMoriah Waterland 835c51f124SMoriah Waterland #define BLK_SIZE 512 /* size of logical block */ 845c51f124SMoriah Waterland 855c51f124SMoriah Waterland #define ENTRY_MAX 256 /* max size of entry for cpio cmd or header */ 865c51f124SMoriah Waterland 875c51f124SMoriah Waterland #define PKGINFO "pkginfo" 885c51f124SMoriah Waterland #define PKGMAP "pkgmap" 895c51f124SMoriah Waterland #define MAP_STAT_SIZE 60 /* 1st line of pkgmap (3 numbers & a : */ 905c51f124SMoriah Waterland 915c51f124SMoriah Waterland #define INSTALL "install" 925c51f124SMoriah Waterland #define RELOC "reloc" 935c51f124SMoriah Waterland #define ROOT "root" 945c51f124SMoriah Waterland #define ARCHIVE "archive" 955c51f124SMoriah Waterland 965c51f124SMoriah Waterland static struct pkgdev srcdev, dstdev; 975c51f124SMoriah Waterland static char *tmpdir; 985c51f124SMoriah Waterland static char *tmppath; 995c51f124SMoriah Waterland static char *tmpsymdir = NULL; 1005c51f124SMoriah Waterland static char dstinst[NON_ABI_NAMELNGTH]; 1015c51f124SMoriah Waterland static char *ids_name, *ods_name; 1025c51f124SMoriah Waterland static int ds_volcnt; 1035c51f124SMoriah Waterland static int ds_volno; 1045c51f124SMoriah Waterland static int compressedsize, has_comp_size; 1055c51f124SMoriah Waterland 1065c51f124SMoriah Waterland static void (*sigintHandler)(); 1075c51f124SMoriah Waterland static void (*sighupHandler)(); 1085c51f124SMoriah Waterland static void cleanup(void); 1095c51f124SMoriah Waterland static void sigtrap(int signo); 1105c51f124SMoriah Waterland static int rd_map_size(FILE *fp, int *npts, int *maxpsz, int *cmpsize); 1115c51f124SMoriah Waterland 1125c51f124SMoriah Waterland static int cat_and_count(struct dm_buf *, char *); 1135c51f124SMoriah Waterland 1145c51f124SMoriah Waterland static int ckoverwrite(char *dir, char *inst, int options); 1155c51f124SMoriah Waterland static int pkgxfer(char *srcinst, int options); 1165c51f124SMoriah Waterland static int wdsheader(struct dm_buf *, char *src, char *device, 1175c51f124SMoriah Waterland char **pkg, PKCS7 *); 118*4656d474SGarrett D'Amore static struct dm_buf *genheader(char *, char **); 1195c51f124SMoriah Waterland 1205c51f124SMoriah Waterland static int dump_hdr_and_pkgs(BIO *, struct dm_buf *, char **); 1215c51f124SMoriah Waterland 1225c51f124SMoriah Waterland extern int ds_fd; /* open file descriptor for data stream WHERE? */ 1235c51f124SMoriah Waterland 1245c51f124SMoriah Waterland static char *root_names[] = { 1255c51f124SMoriah Waterland "root", 1265c51f124SMoriah Waterland "root.cpio", 1275c51f124SMoriah Waterland "root.Z", 1285c51f124SMoriah Waterland "root.cpio.Z", 1295c51f124SMoriah Waterland 0 1305c51f124SMoriah Waterland }; 1315c51f124SMoriah Waterland 1325c51f124SMoriah Waterland static char *reloc_names[] = { 1335c51f124SMoriah Waterland "reloc", 1345c51f124SMoriah Waterland "reloc.cpio", 1355c51f124SMoriah Waterland "reloc.Z", 1365c51f124SMoriah Waterland "reloc.cpio.Z", 1375c51f124SMoriah Waterland 0 1385c51f124SMoriah Waterland }; 1395c51f124SMoriah Waterland 1405c51f124SMoriah Waterland static int signal_received = 0; 1415c51f124SMoriah Waterland 1425c51f124SMoriah Waterland char **xpkg; /* array of transferred packages */ 1435c51f124SMoriah Waterland int nxpkg; 1445c51f124SMoriah Waterland 1455c51f124SMoriah Waterland static char *allpkg[] = { 1465c51f124SMoriah Waterland "all", 1475c51f124SMoriah Waterland NULL 1485c51f124SMoriah Waterland }; 1495c51f124SMoriah Waterland 1505c51f124SMoriah Waterland static struct dm_buf hdrbuf; 1515c51f124SMoriah Waterland static char *pinput, *nextpinput; 1525c51f124SMoriah Waterland 1535c51f124SMoriah Waterland int 1545c51f124SMoriah Waterland pkghead(char *device) 1555c51f124SMoriah Waterland { 1565c51f124SMoriah Waterland char *pt; 1575c51f124SMoriah Waterland int n; 1585c51f124SMoriah Waterland 1595c51f124SMoriah Waterland cleanup(); 1605c51f124SMoriah Waterland 1615c51f124SMoriah Waterland 1625c51f124SMoriah Waterland if (device == NULL) 1635c51f124SMoriah Waterland return (0); 1645c51f124SMoriah Waterland else if ((device[0] == '/') && !isdir(device)) { 1655c51f124SMoriah Waterland pkgdir = device; 1665c51f124SMoriah Waterland return (0); 1675c51f124SMoriah Waterland } else if ((pt = devattr(device, "pathname")) != NULL && !isdir(pt)) { 1685c51f124SMoriah Waterland pkgdir = pt; 1695c51f124SMoriah Waterland return (0); 1705c51f124SMoriah Waterland } 1715c51f124SMoriah Waterland 1725c51f124SMoriah Waterland /* check for datastream */ 1735c51f124SMoriah Waterland if (n = pkgtrans(device, (char *)0, allpkg, PT_SILENT|PT_INFO_ONLY, 1745c51f124SMoriah Waterland NULL, NULL)) { 1755c51f124SMoriah Waterland cleanup(); 1765c51f124SMoriah Waterland return (n); 1775c51f124SMoriah Waterland } 1785c51f124SMoriah Waterland /* pkgtrans has set pkgdir */ 1795c51f124SMoriah Waterland return (0); 1805c51f124SMoriah Waterland } 1815c51f124SMoriah Waterland 1825c51f124SMoriah Waterland static char * 1835c51f124SMoriah Waterland mgets(char *buf, int size) 1845c51f124SMoriah Waterland { 1855c51f124SMoriah Waterland nextpinput = strchr(pinput, '\n'); 1865c51f124SMoriah Waterland if (nextpinput == NULL) 1875c51f124SMoriah Waterland return (0); 1885c51f124SMoriah Waterland *nextpinput = '\0'; 1895c51f124SMoriah Waterland if ((int)strlen(pinput) > size) 1905c51f124SMoriah Waterland return (0); 1915c51f124SMoriah Waterland (void) strncpy(buf, pinput, strlen(pinput)); 1925c51f124SMoriah Waterland buf[strlen(pinput)] = '\0'; 1935c51f124SMoriah Waterland pinput = nextpinput + 1; 1945c51f124SMoriah Waterland return (buf); 1955c51f124SMoriah Waterland } 1965c51f124SMoriah Waterland /* 1975c51f124SMoriah Waterland * Here we construct the package size summaries for the headers. The 1985c51f124SMoriah Waterland * pkgmap file associated with fp must be rewound to the beginning of the 1995c51f124SMoriah Waterland * file. Note that we read three values from pkgmap first line in order 2005c51f124SMoriah Waterland * to get the *actual* size if this package is compressed. 2015c51f124SMoriah Waterland * This returns 2025c51f124SMoriah Waterland * 0 : error 2035c51f124SMoriah Waterland * 2 : not a compressed package 2045c51f124SMoriah Waterland * 3 : compressed package 2055c51f124SMoriah Waterland * and sets has_comp_size to indicate whether or not this is a compressed 2065c51f124SMoriah Waterland * package. 2075c51f124SMoriah Waterland */ 2085c51f124SMoriah Waterland static int 2095c51f124SMoriah Waterland rd_map_size(FILE *fp, int *npts, int *maxpsz, int *cmpsize) 2105c51f124SMoriah Waterland { 2115c51f124SMoriah Waterland int n; 2125c51f124SMoriah Waterland char line_buffer[MAP_STAT_SIZE]; 2135c51f124SMoriah Waterland 2145c51f124SMoriah Waterland /* First read the null terminated first line */ 2155c51f124SMoriah Waterland if (fgets(line_buffer, MAP_STAT_SIZE, fp) == NULL) { 2165c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER)); 2175c51f124SMoriah Waterland logerr(pkg_gt(MSG_NOSIZE)); 2185c51f124SMoriah Waterland (void) fclose(fp); 2195c51f124SMoriah Waterland ecleanup(); 2205c51f124SMoriah Waterland return (0); 2215c51f124SMoriah Waterland } 2225c51f124SMoriah Waterland 2235c51f124SMoriah Waterland n = sscanf(line_buffer, ": %d %d %d", npts, maxpsz, cmpsize); 2245c51f124SMoriah Waterland 2255c51f124SMoriah Waterland if (n == 3) /* A valid compressed package entry */ 2265c51f124SMoriah Waterland has_comp_size = 1; 2275c51f124SMoriah Waterland else if (n == 2) /* A valid standard package entry */ 2285c51f124SMoriah Waterland has_comp_size = 0; 2295c51f124SMoriah Waterland else { /* invalid entry */ 2305c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER)); 2315c51f124SMoriah Waterland logerr(pkg_gt(MSG_NOSIZE)); 2325c51f124SMoriah Waterland (void) fclose(fp); 2335c51f124SMoriah Waterland ecleanup(); 2345c51f124SMoriah Waterland return (0); 2355c51f124SMoriah Waterland } 2365c51f124SMoriah Waterland 2375c51f124SMoriah Waterland return (n); 2385c51f124SMoriah Waterland } 2395c51f124SMoriah Waterland 2405c51f124SMoriah Waterland /* will return 0, 1, 3, or 99 */ 2415c51f124SMoriah Waterland static int 2425c51f124SMoriah Waterland _pkgtrans(char *device1, char *device2, char **pkg, int options, 2435c51f124SMoriah Waterland keystore_handle_t keystore, char *keystore_alias) 2445c51f124SMoriah Waterland { 2455c51f124SMoriah Waterland BIO *p7_bio = NULL; 2465c51f124SMoriah Waterland EVP_PKEY *privkey = NULL; 2475c51f124SMoriah Waterland PKCS7 *sec_pkcs7 = NULL; 2485c51f124SMoriah Waterland PKCS7_SIGNER_INFO *sec_signerinfo = NULL; 2495c51f124SMoriah Waterland PKG_ERR *err; 2505c51f124SMoriah Waterland STACK_OF(X509) *cacerts = NULL; 2515c51f124SMoriah Waterland STACK_OF(X509) *clcerts = NULL; 2525c51f124SMoriah Waterland STACK_OF(X509) *sec_chain = NULL; 2535c51f124SMoriah Waterland X509 *pubcert = NULL; 2545c51f124SMoriah Waterland boolean_t making_sig = B_FALSE; 2555c51f124SMoriah Waterland char *src, *dst; 2565c51f124SMoriah Waterland int errflg, i, n; 2575c51f124SMoriah Waterland struct dm_buf *hdr; 2585c51f124SMoriah Waterland 2595c51f124SMoriah Waterland making_sig = (keystore != NULL) ? B_TRUE : B_FALSE; 2605c51f124SMoriah Waterland 2615c51f124SMoriah Waterland if (making_sig) { 2625c51f124SMoriah Waterland 2635c51f124SMoriah Waterland /* new error object */ 2645c51f124SMoriah Waterland err = pkgerr_new(); 2655c51f124SMoriah Waterland 2665c51f124SMoriah Waterland /* find matching cert and key */ 2675c51f124SMoriah Waterland if (find_key_cert_pair(err, keystore, 2685c51f124SMoriah Waterland keystore_alias, &privkey, &pubcert) != 0) { 2695c51f124SMoriah Waterland pkgerr(err); 2705c51f124SMoriah Waterland pkgerr_free(err); 2715c51f124SMoriah Waterland return (1); 2725c51f124SMoriah Waterland } 2735c51f124SMoriah Waterland 2745c51f124SMoriah Waterland /* get CA certificates */ 2755c51f124SMoriah Waterland if (find_ca_certs(err, keystore, &cacerts) != 0) { 2765c51f124SMoriah Waterland pkgerr(err); 2775c51f124SMoriah Waterland pkgerr_free(err); 2785c51f124SMoriah Waterland return (1); 2795c51f124SMoriah Waterland } 2805c51f124SMoriah Waterland 2815c51f124SMoriah Waterland /* get CL (aka "chain") certificates */ 2825c51f124SMoriah Waterland if (find_cl_certs(err, keystore, &clcerts) != 0) { 2835c51f124SMoriah Waterland pkgerr(err); 2845c51f124SMoriah Waterland pkgerr_free(err); 2855c51f124SMoriah Waterland return (1); 2865c51f124SMoriah Waterland } 2875c51f124SMoriah Waterland 2885c51f124SMoriah Waterland /* initialize PKCS7 object to be filled in later */ 2895c51f124SMoriah Waterland sec_pkcs7 = PKCS7_new(); 290*4656d474SGarrett D'Amore (void) PKCS7_set_type(sec_pkcs7, NID_pkcs7_signed); 2915c51f124SMoriah Waterland sec_signerinfo = PKCS7_add_signature(sec_pkcs7, 2925c51f124SMoriah Waterland pubcert, privkey, EVP_sha1()); 2935c51f124SMoriah Waterland 2945c51f124SMoriah Waterland if (sec_signerinfo == NULL) { 2955c51f124SMoriah Waterland progerr(gettext(ERR_SEC), keystore_alias); 2965c51f124SMoriah Waterland ERR_print_errors_fp(stderr); 2975c51f124SMoriah Waterland pkgerr_free(err); 2985c51f124SMoriah Waterland return (1); 2995c51f124SMoriah Waterland } 3005c51f124SMoriah Waterland 3015c51f124SMoriah Waterland /* add signer cert into signature */ 302*4656d474SGarrett D'Amore (void) PKCS7_add_certificate(sec_pkcs7, pubcert); 3035c51f124SMoriah Waterland 3045c51f124SMoriah Waterland /* attempt to resolve cert chain starting at the signer cert */ 3055c51f124SMoriah Waterland if (get_cert_chain(err, pubcert, clcerts, cacerts, 3065c51f124SMoriah Waterland &sec_chain) != 0) { 3075c51f124SMoriah Waterland pkgerr(err); 3085c51f124SMoriah Waterland pkgerr_free(err); 3095c51f124SMoriah Waterland return (1); 3105c51f124SMoriah Waterland } 3115c51f124SMoriah Waterland 3125c51f124SMoriah Waterland /* 3135c51f124SMoriah Waterland * add the verification chain of certs into the signature. 3145c51f124SMoriah Waterland * The first cert is the user cert, which we don't need, 3155c51f124SMoriah Waterland * since it's baked in already, so skip it 3165c51f124SMoriah Waterland */ 3175c51f124SMoriah Waterland for (i = 1; i < sk_X509_num(sec_chain); i++) { 318*4656d474SGarrett D'Amore (void) PKCS7_add_certificate(sec_pkcs7, 3195c51f124SMoriah Waterland sk_X509_value(sec_chain, i)); 3205c51f124SMoriah Waterland } 3215c51f124SMoriah Waterland 3225c51f124SMoriah Waterland pkgerr_free(err); 3235c51f124SMoriah Waterland err = NULL; 3245c51f124SMoriah Waterland } 3255c51f124SMoriah Waterland 3265c51f124SMoriah Waterland if (signal_received > 0) { 3275c51f124SMoriah Waterland return (1); 3285c51f124SMoriah Waterland } 3295c51f124SMoriah Waterland 3305c51f124SMoriah Waterland /* transfer spool to appropriate device */ 3315c51f124SMoriah Waterland if (devtype(device1, &srcdev)) { 3325c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER)); 3335c51f124SMoriah Waterland logerr(pkg_gt(MSG_BADDEV), device1); 3345c51f124SMoriah Waterland return (1); 3355c51f124SMoriah Waterland } 3365c51f124SMoriah Waterland srcdev.rdonly++; 3375c51f124SMoriah Waterland 3385c51f124SMoriah Waterland /* check for datastream */ 3395c51f124SMoriah Waterland ids_name = NULL; 3405c51f124SMoriah Waterland if (srcdev.bdevice) { 3415c51f124SMoriah Waterland if (n = _getvol(srcdev.bdevice, NULL, NULL, 3425c51f124SMoriah Waterland pkg_gt("Insert %v into %p."), srcdev.norewind)) { 3435c51f124SMoriah Waterland cleanup(); 3445c51f124SMoriah Waterland if (n == 3) 3455c51f124SMoriah Waterland return (3); 3465c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER)); 3475c51f124SMoriah Waterland logerr(pkg_gt(MSG_GETVOL)); 3485c51f124SMoriah Waterland return (1); 3495c51f124SMoriah Waterland } 3505c51f124SMoriah Waterland if (ds_readbuf(srcdev.cdevice)) 3515c51f124SMoriah Waterland ids_name = srcdev.cdevice; 3525c51f124SMoriah Waterland } 3535c51f124SMoriah Waterland 3545c51f124SMoriah Waterland if (srcdev.cdevice && !srcdev.bdevice) 3555c51f124SMoriah Waterland ids_name = srcdev.cdevice; 3565c51f124SMoriah Waterland else if (srcdev.pathname) { 3575c51f124SMoriah Waterland ids_name = srcdev.pathname; 3585c51f124SMoriah Waterland if (access(ids_name, 0) == -1) { 3595c51f124SMoriah Waterland progerr(ERR_TRANSFER); 3605c51f124SMoriah Waterland logerr(pkg_gt(MSG_GETVOL)); 3615c51f124SMoriah Waterland return (1); 3625c51f124SMoriah Waterland } 3635c51f124SMoriah Waterland } 3645c51f124SMoriah Waterland 3655c51f124SMoriah Waterland if (!ids_name && device2 == (char *)0) { 3665c51f124SMoriah Waterland if (n = pkgmount(&srcdev, NULL, 1, 0, 0)) { 3675c51f124SMoriah Waterland cleanup(); 3685c51f124SMoriah Waterland return (n); 3695c51f124SMoriah Waterland } 3705c51f124SMoriah Waterland if (srcdev.mount && *srcdev.mount) 3715c51f124SMoriah Waterland pkgdir = strdup(srcdev.mount); 3725c51f124SMoriah Waterland return (0); 3735c51f124SMoriah Waterland } 3745c51f124SMoriah Waterland 3755c51f124SMoriah Waterland if (ids_name && device2 == (char *)0) { 3765c51f124SMoriah Waterland tmppath = tmpnam(NULL); 3775c51f124SMoriah Waterland tmppath = strdup(tmppath); 3785c51f124SMoriah Waterland if (tmppath == NULL) { 3795c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER)); 3805c51f124SMoriah Waterland logerr(pkg_gt(MSG_MEM)); 3815c51f124SMoriah Waterland return (1); 3825c51f124SMoriah Waterland } 3835c51f124SMoriah Waterland if (mkdir(tmppath, 0755)) { 3845c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER)); 3855c51f124SMoriah Waterland logerr(pkg_gt(MSG_MKDIR), tmppath); 3865c51f124SMoriah Waterland return (1); 3875c51f124SMoriah Waterland } 3885c51f124SMoriah Waterland device2 = tmppath; 3895c51f124SMoriah Waterland } 3905c51f124SMoriah Waterland 3915c51f124SMoriah Waterland if (devtype(device2, &dstdev)) { 3925c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER)); 3935c51f124SMoriah Waterland logerr(pkg_gt(MSG_BADDEV), device2); 3945c51f124SMoriah Waterland return (1); 3955c51f124SMoriah Waterland } 3965c51f124SMoriah Waterland 3975c51f124SMoriah Waterland if ((srcdev.cdevice && dstdev.cdevice) && 3985c51f124SMoriah Waterland strcmp(srcdev.cdevice, dstdev.cdevice) == 0) { 3995c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER)); 4005c51f124SMoriah Waterland logerr(pkg_gt(MSG_SAMEDEV)); 4015c51f124SMoriah Waterland return (1); 4025c51f124SMoriah Waterland } 4035c51f124SMoriah Waterland 4045c51f124SMoriah Waterland ods_name = NULL; 4055c51f124SMoriah Waterland if (dstdev.cdevice && !dstdev.bdevice || dstdev.pathname) 4065c51f124SMoriah Waterland options |= PT_ODTSTREAM; 4075c51f124SMoriah Waterland 4085c51f124SMoriah Waterland if (options & PT_ODTSTREAM) { 4095c51f124SMoriah Waterland if (!((ods_name = dstdev.cdevice) != NULL || 4105c51f124SMoriah Waterland (ods_name = dstdev.pathname) != NULL)) { 4115c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER)); 4125c51f124SMoriah Waterland logerr(pkg_gt(MSG_BADDEV), device2); 4135c51f124SMoriah Waterland return (1); 4145c51f124SMoriah Waterland } 4155c51f124SMoriah Waterland if (ids_name) { 4165c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER)); 4175c51f124SMoriah Waterland logerr(pkg_gt(MSG_TWODSTREAM)); 4185c51f124SMoriah Waterland return (1); 4195c51f124SMoriah Waterland } 4205c51f124SMoriah Waterland } else { 4215c51f124SMoriah Waterland /* 4225c51f124SMoriah Waterland * output device isn't a stream. If we're making a signed 4235c51f124SMoriah Waterland * package, then fail, since we can't make signed, 4245c51f124SMoriah Waterland * non-stream pkgs 4255c51f124SMoriah Waterland */ 4265c51f124SMoriah Waterland if (making_sig) { 4275c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER)); 4285c51f124SMoriah Waterland logerr(pkg_gt(ERR_CANTSIGN)); 4295c51f124SMoriah Waterland return (1); 4305c51f124SMoriah Waterland } 4315c51f124SMoriah Waterland } 4325c51f124SMoriah Waterland 4335c51f124SMoriah Waterland if ((srcdev.dirname && dstdev.dirname) && 4345c51f124SMoriah Waterland strcmp(srcdev.dirname, dstdev.dirname) == 0) { 4355c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER)); 4365c51f124SMoriah Waterland logerr(pkg_gt(MSG_SAMEDEV)); 4375c51f124SMoriah Waterland return (1); 4385c51f124SMoriah Waterland } 4395c51f124SMoriah Waterland 4405c51f124SMoriah Waterland if ((srcdev.pathname && dstdev.pathname) && 4415c51f124SMoriah Waterland strcmp(srcdev.pathname, dstdev.pathname) == 0) { 4425c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER)); 4435c51f124SMoriah Waterland logerr(pkg_gt(MSG_SAMEDEV)); 4445c51f124SMoriah Waterland return (1); 4455c51f124SMoriah Waterland } 4465c51f124SMoriah Waterland 4475c51f124SMoriah Waterland if (signal_received > 0) { 4485c51f124SMoriah Waterland return (1); 4495c51f124SMoriah Waterland } 4505c51f124SMoriah Waterland 4515c51f124SMoriah Waterland if (ids_name) { 4525c51f124SMoriah Waterland if (srcdev.cdevice && !srcdev.bdevice && 4535c51f124SMoriah Waterland (n = _getvol(srcdev.cdevice, NULL, NULL, NULL, 4545c51f124SMoriah Waterland srcdev.norewind))) { 4555c51f124SMoriah Waterland cleanup(); 4565c51f124SMoriah Waterland if (n == 3) 4575c51f124SMoriah Waterland return (3); 4585c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER)); 4595c51f124SMoriah Waterland logerr(pkg_gt(MSG_GETVOL)); 4605c51f124SMoriah Waterland return (1); 4615c51f124SMoriah Waterland } 4625c51f124SMoriah Waterland if (srcdev.dirname = tmpnam(NULL)) 4635c51f124SMoriah Waterland tmpdir = srcdev.dirname = strdup(srcdev.dirname); 4645c51f124SMoriah Waterland 4655c51f124SMoriah Waterland if ((srcdev.dirname == NULL) || mkdir(srcdev.dirname, 0755) || 4665c51f124SMoriah Waterland chdir(srcdev.dirname)) { 4675c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER)); 4685c51f124SMoriah Waterland logerr(pkg_gt(MSG_NOTEMP), srcdev.dirname); 4695c51f124SMoriah Waterland cleanup(); 4705c51f124SMoriah Waterland return (1); 4715c51f124SMoriah Waterland } 4725c51f124SMoriah Waterland if (ds_init(ids_name, pkg, srcdev.norewind)) { 4735c51f124SMoriah Waterland cleanup(); 4745c51f124SMoriah Waterland return (1); 4755c51f124SMoriah Waterland } 4765c51f124SMoriah Waterland } else if (srcdev.mount) { 4775c51f124SMoriah Waterland if (n = pkgmount(&srcdev, NULL, 1, 0, 0)) { 4785c51f124SMoriah Waterland cleanup(); 4795c51f124SMoriah Waterland return (n); 4805c51f124SMoriah Waterland } 4815c51f124SMoriah Waterland } 4825c51f124SMoriah Waterland 4835c51f124SMoriah Waterland src = srcdev.dirname; 4845c51f124SMoriah Waterland dst = dstdev.dirname; 4855c51f124SMoriah Waterland 4865c51f124SMoriah Waterland if (chdir(src)) { 4875c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER)); 4885c51f124SMoriah Waterland logerr(pkg_gt(MSG_CHDIR), src); 4895c51f124SMoriah Waterland cleanup(); 4905c51f124SMoriah Waterland return (1); 4915c51f124SMoriah Waterland } 4925c51f124SMoriah Waterland 4935c51f124SMoriah Waterland if (signal_received > 0) { 4945c51f124SMoriah Waterland return (1); 4955c51f124SMoriah Waterland } 4965c51f124SMoriah Waterland 4975c51f124SMoriah Waterland xpkg = pkg = gpkglist(src, pkg, NULL); 4985c51f124SMoriah Waterland if (!pkg) { 4995c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER)); 5005c51f124SMoriah Waterland logerr(pkg_gt(MSG_NOPKGS), src); 5015c51f124SMoriah Waterland cleanup(); 5025c51f124SMoriah Waterland return (1); 5035c51f124SMoriah Waterland } 5045c51f124SMoriah Waterland 5055c51f124SMoriah Waterland for (nxpkg = 0; pkg[nxpkg]; /* void */) { 5065c51f124SMoriah Waterland nxpkg++; /* count */ 5075c51f124SMoriah Waterland } 5085c51f124SMoriah Waterland 5095c51f124SMoriah Waterland if (ids_name) { 5105c51f124SMoriah Waterland ds_order(pkg); /* order requests */ 5115c51f124SMoriah Waterland } 5125c51f124SMoriah Waterland 5135c51f124SMoriah Waterland if (signal_received > 0) { 5145c51f124SMoriah Waterland return (1); 5155c51f124SMoriah Waterland } 5165c51f124SMoriah Waterland 5175c51f124SMoriah Waterland if (options & PT_ODTSTREAM) { 5185c51f124SMoriah Waterland char line[128]; 5195c51f124SMoriah Waterland 5205c51f124SMoriah Waterland if (!dstdev.pathname && 5215c51f124SMoriah Waterland (n = _getvol(ods_name, NULL, DM_FORMAT, NULL, 5225c51f124SMoriah Waterland dstdev.norewind))) { 5235c51f124SMoriah Waterland cleanup(); 5245c51f124SMoriah Waterland if (n == 3) 5255c51f124SMoriah Waterland return (3); 5265c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER)); 5275c51f124SMoriah Waterland logerr(pkg_gt(MSG_GETVOL)); 5285c51f124SMoriah Waterland return (1); 5295c51f124SMoriah Waterland } 530*4656d474SGarrett D'Amore if ((hdr = genheader(src, pkg)) == NULL) { 5315c51f124SMoriah Waterland cleanup(); 5325c51f124SMoriah Waterland return (1); 5335c51f124SMoriah Waterland } 5345c51f124SMoriah Waterland if (making_sig) { 5355c51f124SMoriah Waterland /* start up signature data stream */ 536*4656d474SGarrett D'Amore (void) PKCS7_content_new(sec_pkcs7, NID_pkcs7_data); 537*4656d474SGarrett D'Amore (void) PKCS7_set_detached(sec_pkcs7, 1); 5385c51f124SMoriah Waterland p7_bio = PKCS7_dataInit(sec_pkcs7, NULL); 5395c51f124SMoriah Waterland 5405c51f124SMoriah Waterland /* 5415c51f124SMoriah Waterland * Here we generate all the data that will go into 5425c51f124SMoriah Waterland * the package, and send it through the signature 5435c51f124SMoriah Waterland * generator, essentially calculating the signature 5445c51f124SMoriah Waterland * of the entire package so we can place it in the 5455c51f124SMoriah Waterland * header. Otherwise we'd have to place it at the end 5465c51f124SMoriah Waterland * of the pkg, which would break the ABI 5475c51f124SMoriah Waterland */ 5485c51f124SMoriah Waterland if (!(options & PT_SILENT)) { 5495c51f124SMoriah Waterland (void) fprintf(stderr, pkg_gt(MSG_SIGNING), 5505c51f124SMoriah Waterland get_subject_display_name(pubcert)); 5515c51f124SMoriah Waterland } 5525c51f124SMoriah Waterland if (dump_hdr_and_pkgs(p7_bio, hdr, pkg) != 0) { 5535c51f124SMoriah Waterland progerr(gettext(ERR_NOGEN)); 5545c51f124SMoriah Waterland logerr(pkg_gt(MSG_GETVOL)); 5555c51f124SMoriah Waterland cleanup(); 5565c51f124SMoriah Waterland return (1); 5575c51f124SMoriah Waterland 5585c51f124SMoriah Waterland } 5595c51f124SMoriah Waterland 5605c51f124SMoriah Waterland BIO_flush(p7_bio); 5615c51f124SMoriah Waterland 5625c51f124SMoriah Waterland /* 5635c51f124SMoriah Waterland * now generate PKCS7 signature 5645c51f124SMoriah Waterland */ 5655c51f124SMoriah Waterland if (!PKCS7_dataFinal(sec_pkcs7, p7_bio)) { 5665c51f124SMoriah Waterland progerr(gettext(ERR_NOGEN)); 5675c51f124SMoriah Waterland logerr(pkg_gt(MSG_GETVOL)); 5685c51f124SMoriah Waterland cleanup(); 5695c51f124SMoriah Waterland return (1); 5705c51f124SMoriah Waterland } 5715c51f124SMoriah Waterland 572*4656d474SGarrett D'Amore (void) BIO_free(p7_bio); 5735c51f124SMoriah Waterland } 5745c51f124SMoriah Waterland 5755c51f124SMoriah Waterland /* write out header to stream, which includes signature */ 5765c51f124SMoriah Waterland if (wdsheader(hdr, src, ods_name, pkg, sec_pkcs7)) { 5775c51f124SMoriah Waterland cleanup(); 5785c51f124SMoriah Waterland return (1); 5795c51f124SMoriah Waterland } 5805c51f124SMoriah Waterland 5815c51f124SMoriah Waterland if (sec_pkcs7 != NULL) { 5825c51f124SMoriah Waterland /* nuke in-memory signature for safety */ 5835c51f124SMoriah Waterland PKCS7_free(sec_pkcs7); 5845c51f124SMoriah Waterland sec_pkcs7 = NULL; 5855c51f124SMoriah Waterland } 5865c51f124SMoriah Waterland 5875c51f124SMoriah Waterland ds_volno = 1; /* number of volumes in datastream */ 5885c51f124SMoriah Waterland pinput = hdrbuf.text_buffer; 5895c51f124SMoriah Waterland /* skip past first line in header */ 5905c51f124SMoriah Waterland (void) mgets(line, 128); 5915c51f124SMoriah Waterland } 5925c51f124SMoriah Waterland 5935c51f124SMoriah Waterland if (signal_received > 0) { 5945c51f124SMoriah Waterland return (1); 5955c51f124SMoriah Waterland } 5965c51f124SMoriah Waterland 5975c51f124SMoriah Waterland errflg = 0; 5985c51f124SMoriah Waterland 5995c51f124SMoriah Waterland for (i = 0; pkg[i]; i++) { 6005c51f124SMoriah Waterland 6015c51f124SMoriah Waterland if (signal_received > 0) { 6025c51f124SMoriah Waterland return (1); 6035c51f124SMoriah Waterland } 6045c51f124SMoriah Waterland 6055c51f124SMoriah Waterland if (!(options & PT_ODTSTREAM) && dstdev.mount) { 6065c51f124SMoriah Waterland if (n = pkgmount(&dstdev, NULL, 0, 0, 1)) { 6075c51f124SMoriah Waterland cleanup(); 6085c51f124SMoriah Waterland return (n); 6095c51f124SMoriah Waterland } 6105c51f124SMoriah Waterland } 6115c51f124SMoriah Waterland if (errflg = pkgxfer(pkg[i], options)) { 6125c51f124SMoriah Waterland pkg[i] = NULL; 6135c51f124SMoriah Waterland if ((options & PT_ODTSTREAM) || (errflg != 2)) 6145c51f124SMoriah Waterland break; 6155c51f124SMoriah Waterland } else if (strcmp(dstinst, pkg[i])) 6165c51f124SMoriah Waterland pkg[i] = strdup(dstinst); 6175c51f124SMoriah Waterland } 6185c51f124SMoriah Waterland 6195c51f124SMoriah Waterland if (!(options & PT_ODTSTREAM) && dst) { 6205c51f124SMoriah Waterland pkgdir = strdup(dst); 6215c51f124SMoriah Waterland } 6225c51f124SMoriah Waterland 6235c51f124SMoriah Waterland /* 6245c51f124SMoriah Waterland * No cleanup of temporary directories created in this 6255c51f124SMoriah Waterland * function is done here. The calling function must do 6265c51f124SMoriah Waterland * the cleanup. 6275c51f124SMoriah Waterland */ 6285c51f124SMoriah Waterland 6295c51f124SMoriah Waterland return (signal_received > 0 ? 1 : errflg); 6305c51f124SMoriah Waterland } 6315c51f124SMoriah Waterland 6325c51f124SMoriah Waterland int 6335c51f124SMoriah Waterland pkgtrans(char *device1, char *device2, char **pkg, int options, 6345c51f124SMoriah Waterland keystore_handle_t keystore, char *keystore_alias) 6355c51f124SMoriah Waterland { 6365c51f124SMoriah Waterland int r; 6375c51f124SMoriah Waterland struct sigaction nact; 6385c51f124SMoriah Waterland struct sigaction oact; 6395c51f124SMoriah Waterland 6405c51f124SMoriah Waterland /* 6415c51f124SMoriah Waterland * setup signal handlers for SIGINT and SIGHUP and release hold 6425c51f124SMoriah Waterland */ 6435c51f124SMoriah Waterland 6445c51f124SMoriah Waterland /* hold SIGINT/SIGHUP interrupts */ 6455c51f124SMoriah Waterland 6465c51f124SMoriah Waterland (void) sighold(SIGHUP); 6475c51f124SMoriah Waterland (void) sighold(SIGINT); 6485c51f124SMoriah Waterland 6495c51f124SMoriah Waterland /* hook SIGINT to sigtrap */ 6505c51f124SMoriah Waterland 6515c51f124SMoriah Waterland nact.sa_handler = sigtrap; 6525c51f124SMoriah Waterland nact.sa_flags = SA_RESTART; 6535c51f124SMoriah Waterland (void) sigemptyset(&nact.sa_mask); 6545c51f124SMoriah Waterland 6555c51f124SMoriah Waterland if (sigaction(SIGINT, &nact, &oact) < 0) { 6565c51f124SMoriah Waterland sigintHandler = SIG_DFL; 6575c51f124SMoriah Waterland } else { 6585c51f124SMoriah Waterland sigintHandler = oact.sa_handler; 6595c51f124SMoriah Waterland } 6605c51f124SMoriah Waterland 6615c51f124SMoriah Waterland /* hook SIGHUP to sigtrap */ 6625c51f124SMoriah Waterland 6635c51f124SMoriah Waterland nact.sa_handler = sigtrap; 6645c51f124SMoriah Waterland nact.sa_flags = SA_RESTART; 6655c51f124SMoriah Waterland (void) sigemptyset(&nact.sa_mask); 6665c51f124SMoriah Waterland 6675c51f124SMoriah Waterland if (sigaction(SIGHUP, &nact, &oact) < 0) { 6685c51f124SMoriah Waterland sighupHandler = SIG_DFL; 6695c51f124SMoriah Waterland } else { 6705c51f124SMoriah Waterland sighupHandler = oact.sa_handler; 6715c51f124SMoriah Waterland } 6725c51f124SMoriah Waterland 6735c51f124SMoriah Waterland /* reset signal received count */ 6745c51f124SMoriah Waterland 6755c51f124SMoriah Waterland signal_received = 0; 6765c51f124SMoriah Waterland 6775c51f124SMoriah Waterland /* release hold on signals */ 6785c51f124SMoriah Waterland 6795c51f124SMoriah Waterland (void) sigrelse(SIGHUP); 6805c51f124SMoriah Waterland (void) sigrelse(SIGINT); 6815c51f124SMoriah Waterland 6825c51f124SMoriah Waterland /* 6835c51f124SMoriah Waterland * perform the package translation 6845c51f124SMoriah Waterland */ 6855c51f124SMoriah Waterland 6865c51f124SMoriah Waterland r = _pkgtrans(device1, device2, pkg, options, keystore, keystore_alias); 6875c51f124SMoriah Waterland 6885c51f124SMoriah Waterland /* 6895c51f124SMoriah Waterland * reset signal handlers 6905c51f124SMoriah Waterland */ 6915c51f124SMoriah Waterland 6925c51f124SMoriah Waterland /* hold SIGINT/SIGHUP interrupts */ 6935c51f124SMoriah Waterland 6945c51f124SMoriah Waterland (void) sighold(SIGHUP); 6955c51f124SMoriah Waterland (void) sighold(SIGINT); 6965c51f124SMoriah Waterland 6975c51f124SMoriah Waterland /* reset SIGINT */ 6985c51f124SMoriah Waterland 6995c51f124SMoriah Waterland nact.sa_handler = sigintHandler; 7005c51f124SMoriah Waterland nact.sa_flags = SA_RESTART; 7015c51f124SMoriah Waterland (void) sigemptyset(&nact.sa_mask); 7025c51f124SMoriah Waterland 7035c51f124SMoriah Waterland (void) sigaction(SIGINT, &nact, (struct sigaction *)NULL); 7045c51f124SMoriah Waterland 7055c51f124SMoriah Waterland /* reset SIGHUP */ 7065c51f124SMoriah Waterland 7075c51f124SMoriah Waterland nact.sa_handler = sighupHandler; 7085c51f124SMoriah Waterland nact.sa_flags = SA_RESTART; 7095c51f124SMoriah Waterland (void) sigemptyset(&nact.sa_mask); 7105c51f124SMoriah Waterland 7115c51f124SMoriah Waterland (void) sigaction(SIGHUP, &nact, (struct sigaction *)NULL); 7125c51f124SMoriah Waterland 7135c51f124SMoriah Waterland /* if signal received and pkgtrans returned error, call cleanup */ 7145c51f124SMoriah Waterland 7155c51f124SMoriah Waterland if (signal_received > 0) { 7165c51f124SMoriah Waterland if (r != 0) { 7175c51f124SMoriah Waterland cleanup(); 7185c51f124SMoriah Waterland } 7195c51f124SMoriah Waterland (void) kill(getpid(), SIGINT); 7205c51f124SMoriah Waterland } 7215c51f124SMoriah Waterland 7225c51f124SMoriah Waterland /* release hold on signals */ 7235c51f124SMoriah Waterland 7245c51f124SMoriah Waterland (void) sigrelse(SIGHUP); 7255c51f124SMoriah Waterland (void) sigrelse(SIGINT); 7265c51f124SMoriah Waterland 7275c51f124SMoriah Waterland return (r); 7285c51f124SMoriah Waterland } 7295c51f124SMoriah Waterland 7305c51f124SMoriah Waterland /* 7315c51f124SMoriah Waterland * This function concatenates append to the text described in the buf_ctrl 7325c51f124SMoriah Waterland * structure. This code modifies data in this structure and handles all 7335c51f124SMoriah Waterland * allocation issues. It returns '0' if everything was successful and '1' 7345c51f124SMoriah Waterland * if not. 7355c51f124SMoriah Waterland */ 7365c51f124SMoriah Waterland static int 7375c51f124SMoriah Waterland cat_and_count(struct dm_buf *buf_ctrl, char *append) 7385c51f124SMoriah Waterland { 7395c51f124SMoriah Waterland 7405c51f124SMoriah Waterland /* keep allocating until we have enough room to hold string */ 7415c51f124SMoriah Waterland while ((buf_ctrl->offset + (int)strlen(append)) 7425c51f124SMoriah Waterland >= buf_ctrl->allocation) { 7435c51f124SMoriah Waterland /* reallocate (and maybe move) text buffer */ 7445c51f124SMoriah Waterland if ((buf_ctrl->text_buffer = 7455c51f124SMoriah Waterland (char *)realloc(buf_ctrl->text_buffer, 7465c51f124SMoriah Waterland buf_ctrl->allocation + BLK_SIZE)) == NULL) { 7475c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER)); 7485c51f124SMoriah Waterland logerr(pkg_gt(MSG_MEM)); 7495c51f124SMoriah Waterland free(buf_ctrl->text_buffer); 7505c51f124SMoriah Waterland return (1); 7515c51f124SMoriah Waterland } 7525c51f124SMoriah Waterland 7535c51f124SMoriah Waterland /* clear the new memory */ 7545c51f124SMoriah Waterland (void) memset(buf_ctrl->text_buffer + 7555c51f124SMoriah Waterland buf_ctrl->allocation, '\0', BLK_SIZE); 7565c51f124SMoriah Waterland 7575c51f124SMoriah Waterland /* adjust total allocation */ 7585c51f124SMoriah Waterland buf_ctrl->allocation += BLK_SIZE; 7595c51f124SMoriah Waterland } 7605c51f124SMoriah Waterland 7615c51f124SMoriah Waterland /* append new string to end of buffer */ 7625c51f124SMoriah Waterland while (*append) { 7635c51f124SMoriah Waterland *(buf_ctrl->text_buffer + buf_ctrl->offset) = *append++; 7645c51f124SMoriah Waterland (buf_ctrl->offset)++; 7655c51f124SMoriah Waterland } 7665c51f124SMoriah Waterland 7675c51f124SMoriah Waterland return (0); 7685c51f124SMoriah Waterland } 7695c51f124SMoriah Waterland 7705c51f124SMoriah Waterland static struct dm_buf * 771*4656d474SGarrett D'Amore genheader(char *src, char **pkg) 7725c51f124SMoriah Waterland { 7735c51f124SMoriah Waterland 7745c51f124SMoriah Waterland FILE *fp; 7755c51f124SMoriah Waterland char path[MAXPATHLEN], tmp_entry[ENTRY_MAX]; 7765c51f124SMoriah Waterland int i, n, nparts, maxpsize; 777*4656d474SGarrett D'Amore int partcnt; 778*4656d474SGarrett D'Amore long totsize; 7795c51f124SMoriah Waterland struct stat statbuf; 7805c51f124SMoriah Waterland 7815c51f124SMoriah Waterland if ((hdrbuf.text_buffer = (char *)malloc(BLK_SIZE)) == NULL) { 7825c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER)); 7835c51f124SMoriah Waterland logerr(pkg_gt(MSG_MEM)); 7845c51f124SMoriah Waterland return (NULL); 7855c51f124SMoriah Waterland } 7865c51f124SMoriah Waterland 7875c51f124SMoriah Waterland /* clear the new memory */ 7885c51f124SMoriah Waterland (void) memset(hdrbuf.text_buffer, '\0', BLK_SIZE); 7895c51f124SMoriah Waterland 7905c51f124SMoriah Waterland /* set up the buffer control structure for the header */ 7915c51f124SMoriah Waterland hdrbuf.offset = 0; 7925c51f124SMoriah Waterland hdrbuf.allocation = BLK_SIZE; 7935c51f124SMoriah Waterland 7945c51f124SMoriah Waterland (void) cat_and_count(&hdrbuf, HDR_PREFIX); 7955c51f124SMoriah Waterland (void) cat_and_count(&hdrbuf, "\n"); 7965c51f124SMoriah Waterland 7975c51f124SMoriah Waterland nparts = maxpsize = 0; 7985c51f124SMoriah Waterland 7995c51f124SMoriah Waterland totsize = 0; 8005c51f124SMoriah Waterland for (i = 0; pkg[i]; i++) { 8015c51f124SMoriah Waterland (void) snprintf(path, MAXPATHLEN, "%s/%s/%s", 8025c51f124SMoriah Waterland src, pkg[i], PKGINFO); 8035c51f124SMoriah Waterland if (stat(path, &statbuf) < 0) { 8045c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER)); 8055c51f124SMoriah Waterland logerr(pkg_gt(MSG_BADPKGINFO)); 8065c51f124SMoriah Waterland ecleanup(); 8075c51f124SMoriah Waterland return (NULL); 8085c51f124SMoriah Waterland } 8095c51f124SMoriah Waterland totsize += statbuf.st_size/BLK_SIZE + 1; 8105c51f124SMoriah Waterland } 8115c51f124SMoriah Waterland 8125c51f124SMoriah Waterland /* 8135c51f124SMoriah Waterland * totsize contains number of blocks used by the pkginfo files 8145c51f124SMoriah Waterland */ 8155c51f124SMoriah Waterland totsize += i/4 + 1; 8165c51f124SMoriah Waterland if (dstdev.capacity && totsize > dstdev.capacity) { 8175c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER)); 8185c51f124SMoriah Waterland logerr(pkg_gt(MSG_NOSPACE), totsize, dstdev.capacity); 8195c51f124SMoriah Waterland ecleanup(); 8205c51f124SMoriah Waterland return (NULL); 8215c51f124SMoriah Waterland } 8225c51f124SMoriah Waterland 8235c51f124SMoriah Waterland ds_volcnt = 1; 8245c51f124SMoriah Waterland for (i = 0; pkg[i]; i++) { 8255c51f124SMoriah Waterland partcnt = 0; 8265c51f124SMoriah Waterland (void) snprintf(path, MAXPATHLEN, "%s/%s/%s", 8275c51f124SMoriah Waterland src, pkg[i], PKGMAP); 8285c51f124SMoriah Waterland if ((fp = fopen(path, "r")) == NULL) { 8295c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER)); 8305c51f124SMoriah Waterland logerr(pkg_gt(MSG_NOPKGMAP), pkg[i]); 8315c51f124SMoriah Waterland ecleanup(); 8325c51f124SMoriah Waterland return (NULL); 8335c51f124SMoriah Waterland } 8345c51f124SMoriah Waterland 8355c51f124SMoriah Waterland /* Evaluate the first entry in pkgmap */ 8365c51f124SMoriah Waterland n = rd_map_size(fp, &nparts, &maxpsize, &compressedsize); 8375c51f124SMoriah Waterland 8385c51f124SMoriah Waterland if (n == 3) /* It's a compressed package */ 8395c51f124SMoriah Waterland /* The header needs the *real* size */ 8405c51f124SMoriah Waterland maxpsize = compressedsize; 8415c51f124SMoriah Waterland else if (n == 0) /* pkgmap is corrupt */ 8425c51f124SMoriah Waterland return (NULL); 8435c51f124SMoriah Waterland 8445c51f124SMoriah Waterland if (dstdev.capacity && maxpsize > dstdev.capacity) { 8455c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER)); 846*4656d474SGarrett D'Amore logerr(pkg_gt(MSG_NOSPACE), (long)maxpsize, 847*4656d474SGarrett D'Amore dstdev.capacity); 8485c51f124SMoriah Waterland (void) fclose(fp); 8495c51f124SMoriah Waterland ecleanup(); 8505c51f124SMoriah Waterland return (NULL); 8515c51f124SMoriah Waterland } 8525c51f124SMoriah Waterland 8535c51f124SMoriah Waterland /* add pkg name, number of parts and the max part size */ 8545c51f124SMoriah Waterland if (snprintf(tmp_entry, ENTRY_MAX, "%s %d %d", 8555c51f124SMoriah Waterland pkg[i], nparts, maxpsize) >= ENTRY_MAX) { 8565c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER)); 8575c51f124SMoriah Waterland logerr(pkg_gt(ERR_MEM)); 8585c51f124SMoriah Waterland (void) fclose(fp); 8595c51f124SMoriah Waterland ecleanup(); 8605c51f124SMoriah Waterland return (NULL); 8615c51f124SMoriah Waterland } 8625c51f124SMoriah Waterland if (cat_and_count(&hdrbuf, tmp_entry)) { 8635c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER)); 8645c51f124SMoriah Waterland logerr(pkg_gt(MSG_MEM)); 8655c51f124SMoriah Waterland (void) fclose(fp); 8665c51f124SMoriah Waterland ecleanup(); 8675c51f124SMoriah Waterland return (NULL); 8685c51f124SMoriah Waterland } 8695c51f124SMoriah Waterland 8705c51f124SMoriah Waterland totsize += nparts * maxpsize; 8715c51f124SMoriah Waterland if (dstdev.capacity && dstdev.capacity < totsize) { 8725c51f124SMoriah Waterland int lastpartcnt = 0; 8735c51f124SMoriah Waterland 8745c51f124SMoriah Waterland if (totsize) 8755c51f124SMoriah Waterland totsize -= nparts * maxpsize; 8765c51f124SMoriah Waterland while (partcnt < nparts) { 8775c51f124SMoriah Waterland while (totsize <= dstdev.capacity && 8785c51f124SMoriah Waterland partcnt <= nparts) { 8795c51f124SMoriah Waterland totsize += maxpsize; 8805c51f124SMoriah Waterland partcnt++; 8815c51f124SMoriah Waterland } 8825c51f124SMoriah Waterland /* partcnt == 0 means skip to next volume */ 8835c51f124SMoriah Waterland if (partcnt) 8845c51f124SMoriah Waterland partcnt--; 8855c51f124SMoriah Waterland (void) snprintf(tmp_entry, ENTRY_MAX, 8865c51f124SMoriah Waterland " %d", partcnt - lastpartcnt); 8875c51f124SMoriah Waterland if (cat_and_count(&hdrbuf, tmp_entry)) { 8885c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER)); 8895c51f124SMoriah Waterland logerr(pkg_gt(MSG_MEM)); 8905c51f124SMoriah Waterland (void) fclose(fp); 8915c51f124SMoriah Waterland ecleanup(); 8925c51f124SMoriah Waterland return (NULL); 8935c51f124SMoriah Waterland } 8945c51f124SMoriah Waterland ds_volcnt++; 8955c51f124SMoriah Waterland totsize = 0; 8965c51f124SMoriah Waterland lastpartcnt = partcnt; 8975c51f124SMoriah Waterland } 8985c51f124SMoriah Waterland /* first parts/volume number does not count */ 8995c51f124SMoriah Waterland ds_volcnt--; 9005c51f124SMoriah Waterland } 9015c51f124SMoriah Waterland 9025c51f124SMoriah Waterland if (cat_and_count(&hdrbuf, "\n")) { 9035c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER)); 9045c51f124SMoriah Waterland logerr(pkg_gt(MSG_MEM)); 9055c51f124SMoriah Waterland (void) fclose(fp); 9065c51f124SMoriah Waterland ecleanup(); 9075c51f124SMoriah Waterland return (NULL); 9085c51f124SMoriah Waterland } 9095c51f124SMoriah Waterland 9105c51f124SMoriah Waterland (void) fclose(fp); 9115c51f124SMoriah Waterland } 9125c51f124SMoriah Waterland 9135c51f124SMoriah Waterland if (cat_and_count(&hdrbuf, HDR_SUFFIX) || 9145c51f124SMoriah Waterland cat_and_count(&hdrbuf, "\n")) { 9155c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER)); 9165c51f124SMoriah Waterland logerr(pkg_gt(MSG_MEM)); 9175c51f124SMoriah Waterland (void) fclose(fp); 9185c51f124SMoriah Waterland ecleanup(); 9195c51f124SMoriah Waterland return (NULL); 9205c51f124SMoriah Waterland } 9215c51f124SMoriah Waterland return (&hdrbuf); 9225c51f124SMoriah Waterland } 9235c51f124SMoriah Waterland 9245c51f124SMoriah Waterland static int 9255c51f124SMoriah Waterland wdsheader(struct dm_buf *hdr, char *src, char *device, char **pkg, PKCS7 *sig) 9265c51f124SMoriah Waterland { 9275c51f124SMoriah Waterland FILE *fp; 9285c51f124SMoriah Waterland char path[PATH_MAX], tmp_entry[ENTRY_MAX], 9295c51f124SMoriah Waterland tmp_file[L_tmpnam+1]; 9305c51f124SMoriah Waterland char srcpath[PATH_MAX]; 9315c51f124SMoriah Waterland int i, n; 9325c51f124SMoriah Waterland int list_fd; 9335c51f124SMoriah Waterland int block_cnt; 9345c51f124SMoriah Waterland int len; 9355c51f124SMoriah Waterland char cwd[MAXPATHLEN + 1]; 9365c51f124SMoriah Waterland boolean_t making_sig = B_FALSE; 9375c51f124SMoriah Waterland 9385c51f124SMoriah Waterland making_sig = (sig != NULL) ? B_TRUE : B_FALSE; 9395c51f124SMoriah Waterland 9405c51f124SMoriah Waterland (void) ds_close(0); 9415c51f124SMoriah Waterland if (dstdev.pathname) 9425c51f124SMoriah Waterland ds_fd = creat(device, 0644); 9435c51f124SMoriah Waterland else 9445c51f124SMoriah Waterland ds_fd = open(device, 1); 9455c51f124SMoriah Waterland 9465c51f124SMoriah Waterland if (ds_fd < 0) { 9475c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER)); 9485c51f124SMoriah Waterland logerr(pkg_gt(MSG_OPEN), device, errno); 9495c51f124SMoriah Waterland return (1); 9505c51f124SMoriah Waterland } 9515c51f124SMoriah Waterland 9525c51f124SMoriah Waterland if (ds_ginit(device) < 0) { 9535c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER)); 9545c51f124SMoriah Waterland logerr(pkg_gt(MSG_OPEN), device, errno); 9555c51f124SMoriah Waterland (void) ds_close(0); 9565c51f124SMoriah Waterland return (1); 9575c51f124SMoriah Waterland } 9585c51f124SMoriah Waterland 9595c51f124SMoriah Waterland /* 9605c51f124SMoriah Waterland * The loop below assures compatibility with tapes that don't 9615c51f124SMoriah Waterland * have a block size (e.g.: Exabyte) by forcing EOR at the end 9625c51f124SMoriah Waterland * of each 512 bytes. 9635c51f124SMoriah Waterland */ 9645c51f124SMoriah Waterland for (block_cnt = 0; block_cnt < hdr->allocation; 9655c51f124SMoriah Waterland block_cnt += BLK_SIZE) { 966*4656d474SGarrett D'Amore (void) write(ds_fd, (hdr->text_buffer + block_cnt), BLK_SIZE); 9675c51f124SMoriah Waterland } 9685c51f124SMoriah Waterland 9695c51f124SMoriah Waterland /* 9705c51f124SMoriah Waterland * write the first cpio() archive to the datastream 9715c51f124SMoriah Waterland * which should contain the pkginfo & pkgmap files 9725c51f124SMoriah Waterland * for all packages 9735c51f124SMoriah Waterland */ 9745c51f124SMoriah Waterland (void) tmpnam(tmp_file); /* temporary file name */ 975*4656d474SGarrett D'Amore if ((list_fd = open(tmp_file, O_RDWR | O_CREAT, 0644)) == -1) { 9765c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER)); 977*4656d474SGarrett D'Amore logerr(pkg_gt(MSG_NOTMPFIL), tmp_file); 9785c51f124SMoriah Waterland return (1); 9795c51f124SMoriah Waterland } 9805c51f124SMoriah Waterland 9815c51f124SMoriah Waterland /* 9825c51f124SMoriah Waterland * Create a cpio-compatible list of the requisite files in 9835c51f124SMoriah Waterland * the temporary file. 9845c51f124SMoriah Waterland */ 9855c51f124SMoriah Waterland if (!making_sig) { 9865c51f124SMoriah Waterland for (i = 0; pkg[i]; i++) { 9875c51f124SMoriah Waterland register ssize_t entry_size; 9885c51f124SMoriah Waterland 9895c51f124SMoriah Waterland /* 9905c51f124SMoriah Waterland * Copy pkginfo and pkgmap filenames into the 9915c51f124SMoriah Waterland * temporary string allowing for the first line 9925c51f124SMoriah Waterland * as a special case. 9935c51f124SMoriah Waterland */ 9945c51f124SMoriah Waterland entry_size = sprintf(tmp_entry, 9955c51f124SMoriah Waterland (i == 0) ? "%s/%s\n%s/%s" : "\n%s/%s\n%s/%s", 9965c51f124SMoriah Waterland pkg[i], PKGINFO, pkg[i], PKGMAP); 9975c51f124SMoriah Waterland 9985c51f124SMoriah Waterland if (write(list_fd, tmp_entry, 9995c51f124SMoriah Waterland entry_size) != entry_size) { 10005c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER)); 1001*4656d474SGarrett D'Amore logerr(pkg_gt(MSG_NOTMPFIL), tmp_file); 10025c51f124SMoriah Waterland (void) close(list_fd); 10035c51f124SMoriah Waterland ecleanup(); 10045c51f124SMoriah Waterland return (1); 10055c51f124SMoriah Waterland } 10065c51f124SMoriah Waterland } 10075c51f124SMoriah Waterland 10085c51f124SMoriah Waterland } else { 10095c51f124SMoriah Waterland register ssize_t entry_size; 10105c51f124SMoriah Waterland 10115c51f124SMoriah Waterland /* 10125c51f124SMoriah Waterland * if we're making a signature, we must make a 10135c51f124SMoriah Waterland * temporary area full of symlinks to the requisite 10145c51f124SMoriah Waterland * files, plus an extra entry for the signature, so 10155c51f124SMoriah Waterland * that cpio will put all files and signature in the 10165c51f124SMoriah Waterland * same archive in a single invocation of cpio. 10175c51f124SMoriah Waterland */ 10185c51f124SMoriah Waterland tmpsymdir = xstrdup(tmpnam(NULL)); 10195c51f124SMoriah Waterland 10205c51f124SMoriah Waterland if (mkdir(tmpsymdir, S_IRWXU)) { 10215c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER)); 10225c51f124SMoriah Waterland logerr(pkg_gt(MSG_MKDIR), tmpsymdir); 10235c51f124SMoriah Waterland return (1); 10245c51f124SMoriah Waterland } 10255c51f124SMoriah Waterland 10265c51f124SMoriah Waterland /* generate the signature */ 10275c51f124SMoriah Waterland if (((len = snprintf(path, PATH_MAX, "%s/%s", 10285c51f124SMoriah Waterland tmpsymdir, SIGNATURE_FILENAME)) >= PATH_MAX) || 10295c51f124SMoriah Waterland len < 0) { 10305c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER)); 10315c51f124SMoriah Waterland logerr(pkg_gt(MSG_NOTMPFIL), tmpsymdir); 10325c51f124SMoriah Waterland cleanup(); 10335c51f124SMoriah Waterland return (1); 10345c51f124SMoriah Waterland } 10355c51f124SMoriah Waterland 10365c51f124SMoriah Waterland if ((fp = fopen(path, "w")) == NULL) { 10375c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER)); 10385c51f124SMoriah Waterland logerr(pkg_gt(MSG_NOTMPFIL), path); 10395c51f124SMoriah Waterland cleanup(); 10405c51f124SMoriah Waterland return (1); 10415c51f124SMoriah Waterland } 1042*4656d474SGarrett D'Amore (void) PEM_write_PKCS7(fp, sig); 10435c51f124SMoriah Waterland (void) fclose(fp); 10445c51f124SMoriah Waterland 10455c51f124SMoriah Waterland for (i = 0; pkg[i]; i++) { 1046*4656d474SGarrett D'Amore (void) snprintf(path, sizeof (path), 1047*4656d474SGarrett D'Amore "%s/%s", tmpsymdir, pkg[i]); 10485c51f124SMoriah Waterland if (mkdir(path, 0755)) { 10495c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER)); 10505c51f124SMoriah Waterland logerr(pkg_gt(MSG_MKDIR), path); 10515c51f124SMoriah Waterland cleanup(); 10525c51f124SMoriah Waterland return (1); 10535c51f124SMoriah Waterland } 1054*4656d474SGarrett D'Amore (void) snprintf(path, sizeof (path), 1055*4656d474SGarrett D'Amore "%s/%s/%s", tmpsymdir, pkg[i], PKGINFO); 1056*4656d474SGarrett D'Amore (void) snprintf(srcpath, sizeof (srcpath), 1057*4656d474SGarrett D'Amore "%s/%s/%s", src, pkg[i], PKGINFO); 10585c51f124SMoriah Waterland if (symlink(srcpath, path) != 0) { 10595c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER)); 10605c51f124SMoriah Waterland logerr(pkg_gt(MSG_SYMLINK), path, srcpath); 10615c51f124SMoriah Waterland cleanup(); 10625c51f124SMoriah Waterland return (1); 10635c51f124SMoriah Waterland } 10645c51f124SMoriah Waterland 1065*4656d474SGarrett D'Amore (void) snprintf(path, sizeof (path), 1066*4656d474SGarrett D'Amore "%s/%s/%s", tmpsymdir, pkg[i], PKGMAP); 1067*4656d474SGarrett D'Amore (void) snprintf(srcpath, sizeof (srcpath), 1068*4656d474SGarrett D'Amore "%s/%s/%s", src, pkg[i], PKGMAP); 10695c51f124SMoriah Waterland if (symlink(srcpath, path) != 0) { 10705c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER)); 10715c51f124SMoriah Waterland logerr(pkg_gt(MSG_SYMLINK), path, srcpath); 10725c51f124SMoriah Waterland cleanup(); 10735c51f124SMoriah Waterland return (1); 10745c51f124SMoriah Waterland } 10755c51f124SMoriah Waterland 10765c51f124SMoriah Waterland /* 10775c51f124SMoriah Waterland * Copy pkginfo and pkgmap filenames into the 10785c51f124SMoriah Waterland * temporary string allowing for the first line 10795c51f124SMoriah Waterland * as a special case. 10805c51f124SMoriah Waterland */ 1081*4656d474SGarrett D'Amore entry_size = snprintf(tmp_entry, sizeof (tmp_entry), 10825c51f124SMoriah Waterland (i == 0) ? "%s/%s\n%s/%s" : "\n%s/%s\n%s/%s", 10835c51f124SMoriah Waterland pkg[i], PKGINFO, pkg[i], PKGMAP); 10845c51f124SMoriah Waterland 10855c51f124SMoriah Waterland if (write(list_fd, tmp_entry, 10865c51f124SMoriah Waterland entry_size) != entry_size) { 10875c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER)); 1088*4656d474SGarrett D'Amore logerr(pkg_gt(MSG_NOTMPFIL), tmp_file); 10895c51f124SMoriah Waterland (void) close(list_fd); 10905c51f124SMoriah Waterland ecleanup(); 10915c51f124SMoriah Waterland cleanup(); 10925c51f124SMoriah Waterland return (1); 10935c51f124SMoriah Waterland } 10945c51f124SMoriah Waterland } 10955c51f124SMoriah Waterland 10965c51f124SMoriah Waterland /* add signature to list of files */ 1097*4656d474SGarrett D'Amore entry_size = snprintf(tmp_entry, sizeof (tmp_entry), "\n%s", 1098*4656d474SGarrett D'Amore SIGNATURE_FILENAME); 10995c51f124SMoriah Waterland if (write(list_fd, tmp_entry, entry_size) != entry_size) { 11005c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER)); 11015c51f124SMoriah Waterland logerr(pkg_gt(MSG_NOTMPFIL), tmp_file); 11025c51f124SMoriah Waterland (void) close(list_fd); 11035c51f124SMoriah Waterland ecleanup(); 11045c51f124SMoriah Waterland cleanup(); 11055c51f124SMoriah Waterland return (1); 11065c51f124SMoriah Waterland } 11075c51f124SMoriah Waterland } 11085c51f124SMoriah Waterland 11095c51f124SMoriah Waterland (void) lseek(list_fd, 0, SEEK_SET); 11105c51f124SMoriah Waterland 11115c51f124SMoriah Waterland if (!making_sig) { 1112*4656d474SGarrett D'Amore (void) snprintf(tmp_entry, sizeof (tmp_entry), 1113*4656d474SGarrett D'Amore "%s -ocD -C %d", CPIOPROC, (int)BLK_SIZE); 11145c51f124SMoriah Waterland } else { 11155c51f124SMoriah Waterland /* 11165c51f124SMoriah Waterland * when making a signature, we must make sure to follow 11175c51f124SMoriah Waterland * symlinks during the cpio so that we don't archive 11185c51f124SMoriah Waterland * the links themselves 11195c51f124SMoriah Waterland */ 1120*4656d474SGarrett D'Amore (void) snprintf(tmp_entry, sizeof (tmp_entry), 1121*4656d474SGarrett D'Amore "%s -ocDL -C %d", CPIOPROC, (int)BLK_SIZE); 11225c51f124SMoriah Waterland } 11235c51f124SMoriah Waterland 11245c51f124SMoriah Waterland if (making_sig) { 11255c51f124SMoriah Waterland /* save cwd and change to symlink dir for cpio invocation */ 11265c51f124SMoriah Waterland if (getcwd(cwd, MAXPATHLEN + 1) == NULL) { 11275c51f124SMoriah Waterland logerr(pkg_gt(ERR_GETWD)); 11285c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER)); 11295c51f124SMoriah Waterland cleanup(); 11305c51f124SMoriah Waterland return (1); 11315c51f124SMoriah Waterland } 11325c51f124SMoriah Waterland 11335c51f124SMoriah Waterland if (chdir(tmpsymdir)) { 11345c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER)); 11355c51f124SMoriah Waterland logerr(pkg_gt(MSG_CHDIR), tmpsymdir); 11365c51f124SMoriah Waterland cleanup(); 11375c51f124SMoriah Waterland return (1); 11385c51f124SMoriah Waterland } 11395c51f124SMoriah Waterland } 11405c51f124SMoriah Waterland 11415c51f124SMoriah Waterland if (n = esystem(tmp_entry, list_fd, ds_fd)) { 11425c51f124SMoriah Waterland rpterr(); 11435c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER)); 11445c51f124SMoriah Waterland logerr(pkg_gt(MSG_CMDFAIL), tmp_entry, n); 11455c51f124SMoriah Waterland (void) close(list_fd); 11465c51f124SMoriah Waterland (void) unlink(tmp_file); 11475c51f124SMoriah Waterland cleanup(); 11485c51f124SMoriah Waterland return (1); 11495c51f124SMoriah Waterland } 11505c51f124SMoriah Waterland 11515c51f124SMoriah Waterland (void) close(list_fd); 11525c51f124SMoriah Waterland (void) unlink(tmp_file); 11535c51f124SMoriah Waterland 11545c51f124SMoriah Waterland if (making_sig) { 11555c51f124SMoriah Waterland /* change to back to src dir for subsequent operations */ 11565c51f124SMoriah Waterland if (chdir(cwd)) { 11575c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER)); 11585c51f124SMoriah Waterland logerr(pkg_gt(MSG_CHDIR), cwd); 11595c51f124SMoriah Waterland cleanup(); 11605c51f124SMoriah Waterland return (1); 11615c51f124SMoriah Waterland } 11625c51f124SMoriah Waterland } 11635c51f124SMoriah Waterland return (0); 11645c51f124SMoriah Waterland } 11655c51f124SMoriah Waterland 11665c51f124SMoriah Waterland static int 11675c51f124SMoriah Waterland ckoverwrite(char *dir, char *inst, int options) 11685c51f124SMoriah Waterland { 11695c51f124SMoriah Waterland char path[PATH_MAX]; 11705c51f124SMoriah Waterland 1171*4656d474SGarrett D'Amore (void) snprintf(path, sizeof (path), "%s/%s", dir, inst); 11725c51f124SMoriah Waterland if (access(path, 0) == 0) { 11735c51f124SMoriah Waterland if (options & PT_OVERWRITE) 11745c51f124SMoriah Waterland return (rrmdir(path)); 11755c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER)); 11765c51f124SMoriah Waterland logerr(pkg_gt(MSG_EXISTS), path); 11775c51f124SMoriah Waterland return (1); 11785c51f124SMoriah Waterland } 11795c51f124SMoriah Waterland return (0); 11805c51f124SMoriah Waterland } 11815c51f124SMoriah Waterland 11825c51f124SMoriah Waterland static int 11835c51f124SMoriah Waterland pkgxfer(char *srcinst, int options) 11845c51f124SMoriah Waterland { 11855c51f124SMoriah Waterland int r; 11865c51f124SMoriah Waterland struct pkginfo info; 11875c51f124SMoriah Waterland FILE *fp, *pp; 11885c51f124SMoriah Waterland char *pt, *src, *dst; 11895c51f124SMoriah Waterland char dstdir[PATH_MAX], 11905c51f124SMoriah Waterland temp[PATH_MAX], 11915c51f124SMoriah Waterland srcdir[PATH_MAX], 11925c51f124SMoriah Waterland cmd[CMDSIZE], 11935c51f124SMoriah Waterland pkgname[NON_ABI_NAMELNGTH]; 11945c51f124SMoriah Waterland int i, n, part, nparts, maxpartsize, curpartcnt, iscomp; 11955c51f124SMoriah Waterland char volnos[128], tmpvol[128]; 11965c51f124SMoriah Waterland struct statvfs64 svfsb; 11975c51f124SMoriah Waterland longlong_t free_blocks; 11985c51f124SMoriah Waterland struct stat srcstat; 11995c51f124SMoriah Waterland 12005c51f124SMoriah Waterland info.pkginst = NULL; /* required initialization */ 12015c51f124SMoriah Waterland 12025c51f124SMoriah Waterland /* 12035c51f124SMoriah Waterland * when this routine is entered, the first part of 12045c51f124SMoriah Waterland * the package to transfer is already available in 12055c51f124SMoriah Waterland * the directory indicated by 'src' --- unless the 12065c51f124SMoriah Waterland * source device is a datstream, in which case only 12075c51f124SMoriah Waterland * the pkginfo and pkgmap files are available in 'src' 12085c51f124SMoriah Waterland */ 12095c51f124SMoriah Waterland src = srcdev.dirname; 12105c51f124SMoriah Waterland dst = dstdev.dirname; 12115c51f124SMoriah Waterland 12125c51f124SMoriah Waterland if (!(options & PT_SILENT)) 12135c51f124SMoriah Waterland (void) fprintf(stderr, pkg_gt(MSG_TRANSFER), srcinst); 1214*4656d474SGarrett D'Amore (void) strlcpy(dstinst, srcinst, sizeof (dstinst)); 12155c51f124SMoriah Waterland 12165c51f124SMoriah Waterland if (!(options & PT_ODTSTREAM)) { 12175c51f124SMoriah Waterland /* destination is a (possibly mounted) directory */ 1218*4656d474SGarrett D'Amore (void) snprintf(dstdir, sizeof (dstdir), 1219*4656d474SGarrett D'Amore "%s/%s", dst, dstinst); 12205c51f124SMoriah Waterland 12215c51f124SMoriah Waterland /* 12225c51f124SMoriah Waterland * need to check destination directory to assure 12235c51f124SMoriah Waterland * that we will not be duplicating a package which 12245c51f124SMoriah Waterland * already resides there (though we are allowed to 12255c51f124SMoriah Waterland * overwrite the same version) 12265c51f124SMoriah Waterland */ 12275c51f124SMoriah Waterland pkgdir = src; 12285c51f124SMoriah Waterland if (fpkginfo(&info, srcinst)) { 12295c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER)); 12305c51f124SMoriah Waterland logerr(pkg_gt(MSG_NOEXISTS), srcinst); 12315c51f124SMoriah Waterland (void) fpkginfo(&info, NULL); 12325c51f124SMoriah Waterland return (1); 12335c51f124SMoriah Waterland } 12345c51f124SMoriah Waterland pkgdir = dst; 12355c51f124SMoriah Waterland 1236*4656d474SGarrett D'Amore (void) strlcpy(temp, srcinst, sizeof (temp)); 12375c51f124SMoriah Waterland if (pt = strchr(temp, '.')) 12385c51f124SMoriah Waterland *pt = '\0'; 1239*4656d474SGarrett D'Amore (void) strlcat(temp, ".*", sizeof (temp)); 12405c51f124SMoriah Waterland 12415c51f124SMoriah Waterland if (pt = fpkginst(temp, info.arch, info.version)) { 12425c51f124SMoriah Waterland /* 12435c51f124SMoriah Waterland * the same instance already exists, although 12445c51f124SMoriah Waterland * its pkgid might be different 12455c51f124SMoriah Waterland */ 12465c51f124SMoriah Waterland if (options & PT_OVERWRITE) { 1247*4656d474SGarrett D'Amore (void) strlcpy(dstinst, pt, sizeof (dstinst)); 1248*4656d474SGarrett D'Amore (void) snprintf(dstdir, sizeof (dstdir), 1249*4656d474SGarrett D'Amore "%s/%s", dst, dstinst); 12505c51f124SMoriah Waterland } else { 12515c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER)); 12525c51f124SMoriah Waterland logerr(pkg_gt(MSG_DUPVERS), srcinst); 12535c51f124SMoriah Waterland (void) fpkginfo(&info, NULL); 12545c51f124SMoriah Waterland (void) fpkginst(NULL); 12555c51f124SMoriah Waterland return (2); 12565c51f124SMoriah Waterland } 12575c51f124SMoriah Waterland } else if (options & PT_RENAME) { 12585c51f124SMoriah Waterland /* 12595c51f124SMoriah Waterland * find next available instance by appending numbers 12605c51f124SMoriah Waterland * to the package abbreviation until the instance 12615c51f124SMoriah Waterland * does not exist in the destination directory 12625c51f124SMoriah Waterland */ 12635c51f124SMoriah Waterland if (pt = strchr(temp, '.')) 12645c51f124SMoriah Waterland *pt = '\0'; 12655c51f124SMoriah Waterland for (i = 2; (access(dstdir, 0) == 0); i++) { 1266*4656d474SGarrett D'Amore (void) snprintf(dstinst, sizeof (dstinst), 1267*4656d474SGarrett D'Amore "%s.%d", temp, i); 1268*4656d474SGarrett D'Amore (void) snprintf(dstdir, sizeof (dstdir), 1269*4656d474SGarrett D'Amore "%s/%s", dst, dstinst); 12705c51f124SMoriah Waterland } 12715c51f124SMoriah Waterland } else if (options & PT_OVERWRITE) { 12725c51f124SMoriah Waterland /* 12735c51f124SMoriah Waterland * we're allowed to overwrite, but there seems 12745c51f124SMoriah Waterland * to be no valid package to overwrite, and we are 12755c51f124SMoriah Waterland * not allowed to rename the destination, so act 12765c51f124SMoriah Waterland * as if we weren't given permission to overwrite 12775c51f124SMoriah Waterland * --- this keeps us from removing a destination 12785c51f124SMoriah Waterland * instance which is named the same as the source 12795c51f124SMoriah Waterland * instance, but really reflects a different pkg! 12805c51f124SMoriah Waterland */ 12815c51f124SMoriah Waterland options &= (~PT_OVERWRITE); 12825c51f124SMoriah Waterland } 12835c51f124SMoriah Waterland (void) fpkginfo(&info, NULL); 12845c51f124SMoriah Waterland (void) fpkginst(NULL); 12855c51f124SMoriah Waterland 12865c51f124SMoriah Waterland if (ckoverwrite(dst, dstinst, options)) 12875c51f124SMoriah Waterland return (2); 12885c51f124SMoriah Waterland 12895c51f124SMoriah Waterland if (isdir(dstdir) && mkdir(dstdir, 0755)) { 12905c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER)); 12915c51f124SMoriah Waterland logerr(pkg_gt(MSG_MKDIR), dstdir); 12925c51f124SMoriah Waterland return (1); 12935c51f124SMoriah Waterland } 12945c51f124SMoriah Waterland 1295*4656d474SGarrett D'Amore (void) snprintf(srcdir, sizeof (srcdir), 1296*4656d474SGarrett D'Amore "%s/%s", src, srcinst); 12975c51f124SMoriah Waterland if (stat(srcdir, &srcstat) != -1) { 12985c51f124SMoriah Waterland if (chmod(dstdir, (srcstat.st_mode & S_IAMB)) == -1) { 12995c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER)); 13005c51f124SMoriah Waterland logerr(pkg_gt(MSG_CHMODDIR), dstdir); 13015c51f124SMoriah Waterland return (1); 13025c51f124SMoriah Waterland } 13035c51f124SMoriah Waterland } else { 13045c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER)); 13055c51f124SMoriah Waterland logerr(pkg_gt(MSG_STATDIR), srcdir); 13065c51f124SMoriah Waterland return (1); 13075c51f124SMoriah Waterland } 13085c51f124SMoriah Waterland } 13095c51f124SMoriah Waterland 13105c51f124SMoriah Waterland if (!(options & PT_SILENT) && strcmp(dstinst, srcinst)) 13115c51f124SMoriah Waterland (void) fprintf(stderr, pkg_gt(MSG_RENAME), dstinst); 13125c51f124SMoriah Waterland 1313*4656d474SGarrett D'Amore (void) snprintf(srcdir, sizeof (srcdir), "%s/%s", src, srcinst); 13145c51f124SMoriah Waterland if (chdir(srcdir)) { 13155c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER)); 13165c51f124SMoriah Waterland logerr(pkg_gt(MSG_CHDIR), srcdir); 13175c51f124SMoriah Waterland return (1); 13185c51f124SMoriah Waterland } 13195c51f124SMoriah Waterland 13205c51f124SMoriah Waterland if (ids_name) { /* unpack the datatstream into a directory */ 13215c51f124SMoriah Waterland /* 13225c51f124SMoriah Waterland * transfer pkginfo & pkgmap first 13235c51f124SMoriah Waterland */ 1324*4656d474SGarrett D'Amore (void) snprintf(cmd, sizeof (cmd), 1325*4656d474SGarrett D'Amore "%s -pudm %s", CPIOPROC, dstdir); 13265c51f124SMoriah Waterland if ((pp = epopen(cmd, "w")) == NULL) { 13275c51f124SMoriah Waterland rpterr(); 13285c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER)); 13295c51f124SMoriah Waterland logerr(pkg_gt(MSG_POPEN), cmd, errno); 13305c51f124SMoriah Waterland return (1); 13315c51f124SMoriah Waterland } 13325c51f124SMoriah Waterland (void) fprintf(pp, "%s\n%s\n", PKGINFO, PKGMAP); 13335c51f124SMoriah Waterland 1334*4656d474SGarrett D'Amore (void) sighold(SIGINT); 1335*4656d474SGarrett D'Amore (void) sighold(SIGHUP); 13365c51f124SMoriah Waterland r = epclose(pp); 1337*4656d474SGarrett D'Amore (void) sigrelse(SIGINT); 1338*4656d474SGarrett D'Amore (void) sigrelse(SIGHUP); 13395c51f124SMoriah Waterland 13405c51f124SMoriah Waterland if (r != 0) { 13415c51f124SMoriah Waterland rpterr(); 13425c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER)); 13435c51f124SMoriah Waterland logerr(pkg_gt(MSG_PCLOSE), cmd, errno); 13445c51f124SMoriah Waterland return (1); 13455c51f124SMoriah Waterland } 13465c51f124SMoriah Waterland 13475c51f124SMoriah Waterland if (options & PT_INFO_ONLY) 13485c51f124SMoriah Waterland return (0); /* don't transfer objects */ 13495c51f124SMoriah Waterland 13505c51f124SMoriah Waterland if (chdir(dstdir)) { 13515c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER)); 13525c51f124SMoriah Waterland logerr(pkg_gt(MSG_CHDIR), dstdir); 13535c51f124SMoriah Waterland return (1); 13545c51f124SMoriah Waterland } 13555c51f124SMoriah Waterland 13565c51f124SMoriah Waterland /* 13575c51f124SMoriah Waterland * for each part of the package, use cpio() to 13585c51f124SMoriah Waterland * unpack the archive into the destination directory 13595c51f124SMoriah Waterland */ 13605c51f124SMoriah Waterland nparts = ds_findpkg(srcdev.cdevice, srcinst); 13615c51f124SMoriah Waterland if (nparts < 0) { 13625c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER)); 13635c51f124SMoriah Waterland return (1); 13645c51f124SMoriah Waterland } 13655c51f124SMoriah Waterland for (part = 1; part <= nparts; /* void */) { 13665c51f124SMoriah Waterland if (ds_getpkg(srcdev.cdevice, part, dstdir)) { 13675c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER)); 13685c51f124SMoriah Waterland return (1); 13695c51f124SMoriah Waterland } 13705c51f124SMoriah Waterland part++; 13715c51f124SMoriah Waterland if (dstdev.mount) { 13725c51f124SMoriah Waterland (void) chdir("/"); 13735c51f124SMoriah Waterland if (pkgumount(&dstdev)) 13745c51f124SMoriah Waterland return (1); 13755c51f124SMoriah Waterland if (part <= nparts) { 13765c51f124SMoriah Waterland if (n = pkgmount(&dstdev, NULL, part+1, 13775c51f124SMoriah Waterland nparts, 1)) 13785c51f124SMoriah Waterland return (n); 13795c51f124SMoriah Waterland if (ckoverwrite(dst, dstinst, options)) 13805c51f124SMoriah Waterland return (1); 13815c51f124SMoriah Waterland if (isdir(dstdir) && 13825c51f124SMoriah Waterland mkdir(dstdir, 0755)) { 13835c51f124SMoriah Waterland progerr( 13845c51f124SMoriah Waterland pkg_gt(ERR_TRANSFER)); 13855c51f124SMoriah Waterland logerr(pkg_gt(MSG_MKDIR), 13865c51f124SMoriah Waterland dstdir); 13875c51f124SMoriah Waterland return (1); 13885c51f124SMoriah Waterland } 13895c51f124SMoriah Waterland /* 13905c51f124SMoriah Waterland * since volume is removable, each part 13915c51f124SMoriah Waterland * must contain a duplicate of the 13925c51f124SMoriah Waterland * pkginfo file to properly identify the 13935c51f124SMoriah Waterland * volume 13945c51f124SMoriah Waterland */ 13955c51f124SMoriah Waterland if (chdir(srcdir)) { 13965c51f124SMoriah Waterland progerr( 13975c51f124SMoriah Waterland pkg_gt(ERR_TRANSFER)); 13985c51f124SMoriah Waterland logerr(pkg_gt(MSG_CHDIR), 13995c51f124SMoriah Waterland srcdir); 14005c51f124SMoriah Waterland return (1); 14015c51f124SMoriah Waterland } 14025c51f124SMoriah Waterland if ((pp = epopen(cmd, "w")) == NULL) { 14035c51f124SMoriah Waterland rpterr(); 14045c51f124SMoriah Waterland progerr( 14055c51f124SMoriah Waterland pkg_gt(ERR_TRANSFER)); 14065c51f124SMoriah Waterland logerr(pkg_gt(MSG_POPEN), 14075c51f124SMoriah Waterland cmd, errno); 14085c51f124SMoriah Waterland return (1); 14095c51f124SMoriah Waterland } 14105c51f124SMoriah Waterland (void) fprintf(pp, "pkginfo"); 14115c51f124SMoriah Waterland 1412*4656d474SGarrett D'Amore (void) sighold(SIGINT); 1413*4656d474SGarrett D'Amore (void) sighold(SIGHUP); 14145c51f124SMoriah Waterland r = epclose(pp); 1415*4656d474SGarrett D'Amore (void) sigrelse(SIGINT); 1416*4656d474SGarrett D'Amore (void) sigrelse(SIGHUP); 14175c51f124SMoriah Waterland 14185c51f124SMoriah Waterland if (r != 0) { 14195c51f124SMoriah Waterland rpterr(); 14205c51f124SMoriah Waterland progerr( 14215c51f124SMoriah Waterland pkg_gt(ERR_TRANSFER)); 14225c51f124SMoriah Waterland logerr(pkg_gt(MSG_PCLOSE), 14235c51f124SMoriah Waterland cmd, errno); 14245c51f124SMoriah Waterland return (1); 14255c51f124SMoriah Waterland } 14265c51f124SMoriah Waterland if (chdir(dstdir)) { 14275c51f124SMoriah Waterland progerr( 14285c51f124SMoriah Waterland pkg_gt(ERR_TRANSFER)); 14295c51f124SMoriah Waterland logerr(pkg_gt(MSG_CHDIR), 14305c51f124SMoriah Waterland dstdir); 14315c51f124SMoriah Waterland return (1); 14325c51f124SMoriah Waterland } 14335c51f124SMoriah Waterland } 14345c51f124SMoriah Waterland } 14355c51f124SMoriah Waterland } 14365c51f124SMoriah Waterland return (0); 14375c51f124SMoriah Waterland } 14385c51f124SMoriah Waterland 14395c51f124SMoriah Waterland if ((fp = fopen(PKGMAP, "r")) == NULL) { 14405c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER)); 14415c51f124SMoriah Waterland logerr(pkg_gt(MSG_NOPKGMAP), srcinst); 14425c51f124SMoriah Waterland return (1); 14435c51f124SMoriah Waterland } 14445c51f124SMoriah Waterland 14455c51f124SMoriah Waterland nparts = 1; 14465c51f124SMoriah Waterland if (!rd_map_size(fp, &nparts, &maxpartsize, &compressedsize)) 14475c51f124SMoriah Waterland return (1); 14485c51f124SMoriah Waterland else 14495c51f124SMoriah Waterland (void) fclose(fp); 14505c51f124SMoriah Waterland 14515c51f124SMoriah Waterland if (srcdev.mount) { 14525c51f124SMoriah Waterland if (ckvolseq(srcdir, 1, nparts)) { 14535c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER)); 14545c51f124SMoriah Waterland logerr(pkg_gt(MSG_SEQUENCE)); 14555c51f124SMoriah Waterland return (1); 14565c51f124SMoriah Waterland } 14575c51f124SMoriah Waterland } 14585c51f124SMoriah Waterland 14595c51f124SMoriah Waterland /* write each part of this package */ 14605c51f124SMoriah Waterland if (options & PT_ODTSTREAM) { 14615c51f124SMoriah Waterland char line[128]; 14625c51f124SMoriah Waterland (void) mgets(line, 128); 14635c51f124SMoriah Waterland curpartcnt = -1; 1464*4656d474SGarrett D'Amore /* LINTED E_SEC_SCANF_UNBOUNDED_COPY */ 1465*4656d474SGarrett D'Amore if (sscanf(line, "%s %d %d %[ 0-9]", pkgname, &nparts, 14665c51f124SMoriah Waterland &maxpartsize, volnos) == 4) { 1467*4656d474SGarrett D'Amore (void) sscanf(volnos, 1468*4656d474SGarrett D'Amore "%d %[ 0-9]", &curpartcnt, tmpvol); 1469*4656d474SGarrett D'Amore (void) strlcpy(volnos, tmpvol, sizeof (volnos)); 14705c51f124SMoriah Waterland } 14715c51f124SMoriah Waterland } 14725c51f124SMoriah Waterland 14735c51f124SMoriah Waterland for (part = 1; part <= nparts; /* void */) { 14745c51f124SMoriah Waterland if (curpartcnt == 0 && (options & PT_ODTSTREAM)) { 14755c51f124SMoriah Waterland char prompt[128]; 14765c51f124SMoriah Waterland int index; 14775c51f124SMoriah Waterland ds_volno++; 14785c51f124SMoriah Waterland (void) ds_close(0); 14795c51f124SMoriah Waterland (void) sprintf(prompt, 14805c51f124SMoriah Waterland pkg_gt("Insert %%v %d of %d into %%p"), 14815c51f124SMoriah Waterland ds_volno, ds_volcnt); 14825c51f124SMoriah Waterland if (n = getvol(ods_name, NULL, DM_FORMAT, prompt)) 14835c51f124SMoriah Waterland return (n); 14845c51f124SMoriah Waterland if ((ds_fd = open(dstdev.cdevice, O_WRONLY)) < 0) { 14855c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER)); 14865c51f124SMoriah Waterland logerr(pkg_gt(MSG_OPEN), dstdev.cdevice, 14875c51f124SMoriah Waterland errno); 14885c51f124SMoriah Waterland return (1); 14895c51f124SMoriah Waterland } 14905c51f124SMoriah Waterland if (ds_ginit(dstdev.cdevice) < 0) { 14915c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER)); 14925c51f124SMoriah Waterland logerr(pkg_gt(MSG_OPEN), dstdev.cdevice, 14935c51f124SMoriah Waterland errno); 14945c51f124SMoriah Waterland (void) ds_close(0); 14955c51f124SMoriah Waterland return (1); 14965c51f124SMoriah Waterland } 14975c51f124SMoriah Waterland 14985c51f124SMoriah Waterland (void) sscanf(volnos, "%d %[ 0-9]", &index, tmpvol); 1499*4656d474SGarrett D'Amore (void) strlcpy(volnos, tmpvol, sizeof (volnos)); 15005c51f124SMoriah Waterland curpartcnt += index; 15015c51f124SMoriah Waterland } 15025c51f124SMoriah Waterland 15035c51f124SMoriah Waterland if (options & PT_INFO_ONLY) 15045c51f124SMoriah Waterland nparts = 0; 15055c51f124SMoriah Waterland 15065c51f124SMoriah Waterland if (part == 1) { 1507*4656d474SGarrett D'Amore (void) snprintf(cmd, sizeof (cmd), 1508*4656d474SGarrett D'Amore "find %s %s", PKGINFO, PKGMAP); 15095c51f124SMoriah Waterland if (nparts && (isdir(INSTALL) == 0)) { 1510*4656d474SGarrett D'Amore (void) strlcat(cmd, " ", sizeof (cmd)); 1511*4656d474SGarrett D'Amore (void) strlcat(cmd, INSTALL, sizeof (cmd)); 15125c51f124SMoriah Waterland } 15135c51f124SMoriah Waterland } else 1514*4656d474SGarrett D'Amore (void) snprintf(cmd, sizeof (cmd), "find %s", PKGINFO); 15155c51f124SMoriah Waterland 15165c51f124SMoriah Waterland if (nparts > 1) { 1517*4656d474SGarrett D'Amore (void) snprintf(temp, sizeof (temp), 1518*4656d474SGarrett D'Amore "%s.%d", RELOC, part); 15195c51f124SMoriah Waterland if (iscpio(temp, &iscomp) || isdir(temp) == 0) { 1520*4656d474SGarrett D'Amore (void) strlcat(cmd, " ", sizeof (cmd)); 1521*4656d474SGarrett D'Amore (void) strlcat(cmd, temp, sizeof (cmd)); 15225c51f124SMoriah Waterland } 1523*4656d474SGarrett D'Amore (void) snprintf(temp, sizeof (temp), 1524*4656d474SGarrett D'Amore "%s.%d", ROOT, part); 15255c51f124SMoriah Waterland if (iscpio(temp, &iscomp) || isdir(temp) == 0) { 1526*4656d474SGarrett D'Amore (void) strlcat(cmd, " ", sizeof (cmd)); 1527*4656d474SGarrett D'Amore (void) strlcat(cmd, temp, sizeof (cmd)); 15285c51f124SMoriah Waterland } 1529*4656d474SGarrett D'Amore (void) snprintf(temp, sizeof (temp), 1530*4656d474SGarrett D'Amore "%s.%d", ARCHIVE, part); 15315c51f124SMoriah Waterland if (isdir(temp) == 0) { 1532*4656d474SGarrett D'Amore (void) strlcat(cmd, " ", sizeof (cmd)); 1533*4656d474SGarrett D'Amore (void) strlcat(cmd, temp, sizeof (cmd)); 15345c51f124SMoriah Waterland } 15355c51f124SMoriah Waterland } else if (nparts) { 15365c51f124SMoriah Waterland for (i = 0; reloc_names[i] != NULL; i++) { 15375c51f124SMoriah Waterland if (iscpio(reloc_names[i], &iscomp) || 15385c51f124SMoriah Waterland isdir(reloc_names[i]) == 0) { 1539*4656d474SGarrett D'Amore (void) strlcat(cmd, " ", sizeof (cmd)); 1540*4656d474SGarrett D'Amore (void) strlcat(cmd, reloc_names[i], 1541*4656d474SGarrett D'Amore sizeof (cmd)); 15425c51f124SMoriah Waterland } 15435c51f124SMoriah Waterland } 15445c51f124SMoriah Waterland for (i = 0; root_names[i] != NULL; i++) { 15455c51f124SMoriah Waterland if (iscpio(root_names[i], &iscomp) || 15465c51f124SMoriah Waterland isdir(root_names[i]) == 0) { 1547*4656d474SGarrett D'Amore (void) strlcat(cmd, " ", sizeof (cmd)); 1548*4656d474SGarrett D'Amore (void) strlcat(cmd, root_names[i], 1549*4656d474SGarrett D'Amore sizeof (cmd)); 15505c51f124SMoriah Waterland } 15515c51f124SMoriah Waterland } 15525c51f124SMoriah Waterland if (isdir(ARCHIVE) == 0) { 1553*4656d474SGarrett D'Amore (void) strlcat(cmd, " ", sizeof (cmd)); 1554*4656d474SGarrett D'Amore (void) strlcat(cmd, ARCHIVE, sizeof (cmd)); 15555c51f124SMoriah Waterland } 15565c51f124SMoriah Waterland } 15575c51f124SMoriah Waterland if (options & PT_ODTSTREAM) { 1558*4656d474SGarrett D'Amore (void) snprintf(cmd + strlen(cmd), 1559*4656d474SGarrett D'Amore sizeof (cmd) - strlen(cmd), 15605c51f124SMoriah Waterland " -print | %s -ocD -C %d", 15615c51f124SMoriah Waterland CPIOPROC, (int)BLK_SIZE); 15625c51f124SMoriah Waterland } else { 15635c51f124SMoriah Waterland if (statvfs64(dstdir, &svfsb) == -1) { 15645c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER)); 15655c51f124SMoriah Waterland logerr(pkg_gt(MSG_STATVFS), dstdir, errno); 15665c51f124SMoriah Waterland return (1); 15675c51f124SMoriah Waterland } 15685c51f124SMoriah Waterland 15695c51f124SMoriah Waterland free_blocks = (((long)svfsb.f_frsize > 0) ? 15705c51f124SMoriah Waterland howmany(svfsb.f_frsize, DEV_BSIZE) : 15715c51f124SMoriah Waterland howmany(svfsb.f_bsize, DEV_BSIZE)) * svfsb.f_bavail; 15725c51f124SMoriah Waterland 15735c51f124SMoriah Waterland if ((has_comp_size ? compressedsize : maxpartsize) > 15745c51f124SMoriah Waterland free_blocks) { 15755c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER)); 1576*4656d474SGarrett D'Amore logerr(pkg_gt(MSG_NOSPACE), 1577*4656d474SGarrett D'Amore has_comp_size ? 1578*4656d474SGarrett D'Amore (long)compressedsize : (long)maxpartsize, 1579*4656d474SGarrett D'Amore free_blocks); 15805c51f124SMoriah Waterland return (1); 15815c51f124SMoriah Waterland } 1582*4656d474SGarrett D'Amore (void) snprintf(cmd + strlen(cmd), 1583*4656d474SGarrett D'Amore sizeof (cmd) - strlen(cmd), 1584*4656d474SGarrett D'Amore " -print | %s -pdum %s", 15855c51f124SMoriah Waterland CPIOPROC, dstdir); 15865c51f124SMoriah Waterland } 15875c51f124SMoriah Waterland 15885c51f124SMoriah Waterland n = esystem(cmd, -1, (options & PT_ODTSTREAM) ? ds_fd : -1); 15895c51f124SMoriah Waterland if (n) { 15905c51f124SMoriah Waterland rpterr(); 15915c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER)); 15925c51f124SMoriah Waterland logerr(pkg_gt(MSG_CMDFAIL), cmd, n); 15935c51f124SMoriah Waterland return (1); 15945c51f124SMoriah Waterland } 15955c51f124SMoriah Waterland 15965c51f124SMoriah Waterland part++; 15975c51f124SMoriah Waterland if (srcdev.mount && (nparts > 1)) { 15985c51f124SMoriah Waterland /* unmount current source volume */ 15995c51f124SMoriah Waterland (void) chdir("/"); 16005c51f124SMoriah Waterland if (pkgumount(&srcdev)) 16015c51f124SMoriah Waterland return (1); 16025c51f124SMoriah Waterland /* loop until volume is mounted successfully */ 16035c51f124SMoriah Waterland while (part <= nparts) { 16045c51f124SMoriah Waterland /* read only */ 16055c51f124SMoriah Waterland n = pkgmount(&srcdev, NULL, part, nparts, 1); 16065c51f124SMoriah Waterland if (n) 16075c51f124SMoriah Waterland return (n); 16085c51f124SMoriah Waterland if (chdir(srcdir)) { 16095c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER)); 1610*4656d474SGarrett D'Amore logerr(pkg_gt(MSG_CORRUPT)); 16115c51f124SMoriah Waterland (void) chdir("/"); 1612*4656d474SGarrett D'Amore (void) pkgumount(&srcdev); 16135c51f124SMoriah Waterland continue; 16145c51f124SMoriah Waterland } 16155c51f124SMoriah Waterland if (ckvolseq(srcdir, part, nparts)) { 16165c51f124SMoriah Waterland (void) chdir("/"); 1617*4656d474SGarrett D'Amore (void) pkgumount(&srcdev); 16185c51f124SMoriah Waterland continue; 16195c51f124SMoriah Waterland } 16205c51f124SMoriah Waterland break; 16215c51f124SMoriah Waterland } 16225c51f124SMoriah Waterland } 16235c51f124SMoriah Waterland if (!(options & PT_ODTSTREAM) && dstdev.mount) { 16245c51f124SMoriah Waterland /* unmount current volume */ 16255c51f124SMoriah Waterland if (pkgumount(&dstdev)) 16265c51f124SMoriah Waterland return (1); 16275c51f124SMoriah Waterland /* loop until next volume is mounted successfully */ 16285c51f124SMoriah Waterland while (part <= nparts) { 16295c51f124SMoriah Waterland /* writable */ 16305c51f124SMoriah Waterland n = pkgmount(&dstdev, NULL, part, nparts, 1); 16315c51f124SMoriah Waterland if (n) 16325c51f124SMoriah Waterland return (n); 16335c51f124SMoriah Waterland if (ckoverwrite(dst, dstinst, options)) 16345c51f124SMoriah Waterland continue; 16355c51f124SMoriah Waterland if (isdir(dstdir) && mkdir(dstdir, 0755)) { 16365c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER)); 16375c51f124SMoriah Waterland logerr(pkg_gt(MSG_MKDIR), dstdir); 16385c51f124SMoriah Waterland continue; 16395c51f124SMoriah Waterland } 16405c51f124SMoriah Waterland break; 16415c51f124SMoriah Waterland } 16425c51f124SMoriah Waterland } 16435c51f124SMoriah Waterland 16445c51f124SMoriah Waterland if ((options & PT_ODTSTREAM) && part <= nparts) { 16455c51f124SMoriah Waterland if (curpartcnt >= 0 && part > curpartcnt) { 16465c51f124SMoriah Waterland char prompt[128]; 16475c51f124SMoriah Waterland int index; 16485c51f124SMoriah Waterland ds_volno++; 16495c51f124SMoriah Waterland if (ds_close(0)) 16505c51f124SMoriah Waterland return (1); 16515c51f124SMoriah Waterland (void) sprintf(prompt, 16525c51f124SMoriah Waterland pkg_gt("Insert %%v %d of %d into %%p"), 16535c51f124SMoriah Waterland ds_volno, ds_volcnt); 16545c51f124SMoriah Waterland if (n = getvol(ods_name, NULL, DM_FORMAT, 16555c51f124SMoriah Waterland prompt)) 16565c51f124SMoriah Waterland return (n); 16575c51f124SMoriah Waterland if ((ds_fd = open(dstdev.cdevice, 1)) < 0) { 16585c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER)); 16595c51f124SMoriah Waterland logerr(pkg_gt(MSG_OPEN), 16605c51f124SMoriah Waterland dstdev.cdevice, errno); 16615c51f124SMoriah Waterland return (1); 16625c51f124SMoriah Waterland } 16635c51f124SMoriah Waterland if (ds_ginit(dstdev.cdevice) < 0) { 16645c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER)); 16655c51f124SMoriah Waterland logerr(pkg_gt(MSG_OPEN), 16665c51f124SMoriah Waterland dstdev.cdevice, errno); 16675c51f124SMoriah Waterland (void) ds_close(0); 16685c51f124SMoriah Waterland return (1); 16695c51f124SMoriah Waterland } 16705c51f124SMoriah Waterland 16715c51f124SMoriah Waterland (void) sscanf(volnos, "%d %[ 0-9]", &index, 16725c51f124SMoriah Waterland tmpvol); 1673*4656d474SGarrett D'Amore (void) strlcpy(volnos, tmpvol, sizeof (volnos)); 16745c51f124SMoriah Waterland curpartcnt += index; 16755c51f124SMoriah Waterland } 16765c51f124SMoriah Waterland } 16775c51f124SMoriah Waterland 16785c51f124SMoriah Waterland } 16795c51f124SMoriah Waterland return (0); 16805c51f124SMoriah Waterland } 16815c51f124SMoriah Waterland 16825c51f124SMoriah Waterland /* 16835c51f124SMoriah Waterland * Name: pkgdump 16845c51f124SMoriah Waterland * Description: Dump a cpio archive of a package's contents to a BIO. 16855c51f124SMoriah Waterland * 16865c51f124SMoriah Waterland * Arguments: srcinst - Name of package, which resides on the 16875c51f124SMoriah Waterland * device pointed to by the static 'srcdev' variable, 16885c51f124SMoriah Waterland * to dump. 16895c51f124SMoriah Waterland * bio - BIO object to dump data to 16905c51f124SMoriah Waterland * 16915c51f124SMoriah Waterland * Returns : 0 - success 16925c51f124SMoriah Waterland * nonzero - failure. errors printed to screen. 16935c51f124SMoriah Waterland */ 16945c51f124SMoriah Waterland static int 16955c51f124SMoriah Waterland pkgdump(char *srcinst, BIO *bio) 16965c51f124SMoriah Waterland { 16975c51f124SMoriah Waterland FILE *fp; 16985c51f124SMoriah Waterland char *src; 16995c51f124SMoriah Waterland char temp[MAXPATHLEN], 17005c51f124SMoriah Waterland srcdir[MAXPATHLEN], 17015c51f124SMoriah Waterland cmd[CMDSIZE]; 17025c51f124SMoriah Waterland int i, n, part, nparts, maxpartsize, iscomp; 17035c51f124SMoriah Waterland 17045c51f124SMoriah Waterland /* 17055c51f124SMoriah Waterland * when this routine is entered, the entire package 17065c51f124SMoriah Waterland * is already available at 'src' - including the 17075c51f124SMoriah Waterland * pkginfo/pkgmap files and the objects as well. 17085c51f124SMoriah Waterland */ 17095c51f124SMoriah Waterland 17105c51f124SMoriah Waterland /* read the pkgmap to get it's size information */ 17115c51f124SMoriah Waterland if ((fp = fopen(PKGMAP, "r")) == NULL) { 17125c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER)); 17135c51f124SMoriah Waterland logerr(pkg_gt(MSG_NOPKGMAP), srcinst); 17145c51f124SMoriah Waterland return (1); 17155c51f124SMoriah Waterland } 17165c51f124SMoriah Waterland 17175c51f124SMoriah Waterland nparts = 1; 17185c51f124SMoriah Waterland if (!rd_map_size(fp, &nparts, &maxpartsize, &compressedsize)) 17195c51f124SMoriah Waterland return (1); 17205c51f124SMoriah Waterland else 17215c51f124SMoriah Waterland (void) fclose(fp); 17225c51f124SMoriah Waterland 17235c51f124SMoriah Waterland /* make sure the first volume is available */ 17245c51f124SMoriah Waterland if (srcdev.mount) { 17255c51f124SMoriah Waterland src = srcdev.dirname; 17265c51f124SMoriah Waterland (void) snprintf(srcdir, MAXPATHLEN, "%s/%s", src, srcinst); 17275c51f124SMoriah Waterland if (ckvolseq(srcdir, 1, nparts)) { 17285c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER)); 17295c51f124SMoriah Waterland logerr(pkg_gt(MSG_SEQUENCE)); 17305c51f124SMoriah Waterland return (1); 17315c51f124SMoriah Waterland } 17325c51f124SMoriah Waterland } 17335c51f124SMoriah Waterland 17345c51f124SMoriah Waterland /* 17355c51f124SMoriah Waterland * form cpio command that will output the contents of all of 17365c51f124SMoriah Waterland * this package's parts 17375c51f124SMoriah Waterland */ 17385c51f124SMoriah Waterland for (part = 1; part <= nparts; /* void */) { 17395c51f124SMoriah Waterland 17405c51f124SMoriah Waterland if (part == 1) { 17415c51f124SMoriah Waterland (void) snprintf(cmd, CMDSIZE, "find %s %s", 17425c51f124SMoriah Waterland PKGINFO, PKGMAP); 17435c51f124SMoriah Waterland if (nparts && (isdir(INSTALL) == 0)) { 1744*4656d474SGarrett D'Amore (void) strlcat(cmd, " ", sizeof (cmd)); 1745*4656d474SGarrett D'Amore (void) strlcat(cmd, INSTALL, sizeof (cmd)); 17465c51f124SMoriah Waterland } 17475c51f124SMoriah Waterland } else 17485c51f124SMoriah Waterland (void) snprintf(cmd, CMDSIZE, "find %s", PKGINFO); 17495c51f124SMoriah Waterland 17505c51f124SMoriah Waterland if (nparts > 1) { 17515c51f124SMoriah Waterland (void) snprintf(temp, MAXPATHLEN, "%s.%d", RELOC, part); 17525c51f124SMoriah Waterland if (iscpio(temp, &iscomp) || isdir(temp) == 0) { 17535c51f124SMoriah Waterland (void) strlcat(cmd, " ", CMDSIZE); 17545c51f124SMoriah Waterland (void) strlcat(cmd, temp, CMDSIZE); 17555c51f124SMoriah Waterland } 17565c51f124SMoriah Waterland (void) snprintf(temp, MAXPATHLEN, "%s.%d", ROOT, part); 17575c51f124SMoriah Waterland if (iscpio(temp, &iscomp) || isdir(temp) == 0) { 17585c51f124SMoriah Waterland (void) strlcat(cmd, " ", CMDSIZE); 17595c51f124SMoriah Waterland (void) strlcat(cmd, temp, CMDSIZE); 17605c51f124SMoriah Waterland } 17615c51f124SMoriah Waterland (void) snprintf(temp, MAXPATHLEN, "%s.%d", 17625c51f124SMoriah Waterland ARCHIVE, part); 17635c51f124SMoriah Waterland if (isdir(temp) == 0) { 17645c51f124SMoriah Waterland (void) strlcat(cmd, " ", CMDSIZE); 17655c51f124SMoriah Waterland (void) strlcat(cmd, temp, CMDSIZE); 17665c51f124SMoriah Waterland } 17675c51f124SMoriah Waterland } else if (nparts) { 17685c51f124SMoriah Waterland for (i = 0; reloc_names[i] != NULL; i++) { 17695c51f124SMoriah Waterland if (iscpio(reloc_names[i], &iscomp) || 17705c51f124SMoriah Waterland isdir(reloc_names[i]) == 0) { 17715c51f124SMoriah Waterland (void) strlcat(cmd, " ", CMDSIZE); 17725c51f124SMoriah Waterland (void) strlcat(cmd, reloc_names[i], 17735c51f124SMoriah Waterland CMDSIZE); 17745c51f124SMoriah Waterland } 17755c51f124SMoriah Waterland } 17765c51f124SMoriah Waterland for (i = 0; root_names[i] != NULL; i++) { 17775c51f124SMoriah Waterland if (iscpio(root_names[i], &iscomp) || 17785c51f124SMoriah Waterland isdir(root_names[i]) == 0) { 17795c51f124SMoriah Waterland (void) strlcat(cmd, " ", CMDSIZE); 17805c51f124SMoriah Waterland (void) strlcat(cmd, root_names[i], 17815c51f124SMoriah Waterland CMDSIZE); 17825c51f124SMoriah Waterland } 17835c51f124SMoriah Waterland } 17845c51f124SMoriah Waterland if (isdir(ARCHIVE) == 0) { 17855c51f124SMoriah Waterland (void) strlcat(cmd, " ", CMDSIZE); 17865c51f124SMoriah Waterland (void) strlcat(cmd, ARCHIVE, CMDSIZE); 17875c51f124SMoriah Waterland } 17885c51f124SMoriah Waterland } 17895c51f124SMoriah Waterland 1790*4656d474SGarrett D'Amore (void) snprintf(cmd + strlen(cmd), 1791*4656d474SGarrett D'Amore sizeof (cmd) - strlen(cmd), 17925c51f124SMoriah Waterland " -print | %s -ocD -C %d", 17935c51f124SMoriah Waterland CPIOPROC, (int)BLK_SIZE); 17945c51f124SMoriah Waterland /* 17955c51f124SMoriah Waterland * execute the command, dumping all standard output 17965c51f124SMoriah Waterland * to the BIO. 17975c51f124SMoriah Waterland */ 17985c51f124SMoriah Waterland n = BIO_dump_cmd(cmd, bio); 17995c51f124SMoriah Waterland if (n != 0) { 18005c51f124SMoriah Waterland rpterr(); 18015c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER)); 18025c51f124SMoriah Waterland logerr(pkg_gt(MSG_CMDFAIL), cmd, n); 18035c51f124SMoriah Waterland return (1); 18045c51f124SMoriah Waterland } 18055c51f124SMoriah Waterland 18065c51f124SMoriah Waterland part++; 18075c51f124SMoriah Waterland } 18085c51f124SMoriah Waterland return (0); 18095c51f124SMoriah Waterland } 18105c51f124SMoriah Waterland 18115c51f124SMoriah Waterland static void 18125c51f124SMoriah Waterland sigtrap(int signo) 18135c51f124SMoriah Waterland { 1814*4656d474SGarrett D'Amore _NOTE(ARGUNUSED(signo)); 18155c51f124SMoriah Waterland signal_received++; 18165c51f124SMoriah Waterland } 18175c51f124SMoriah Waterland 18185c51f124SMoriah Waterland static void 18195c51f124SMoriah Waterland cleanup(void) 18205c51f124SMoriah Waterland { 1821*4656d474SGarrett D'Amore (void) chdir("/"); 18225c51f124SMoriah Waterland if (tmpdir) { 1823*4656d474SGarrett D'Amore (void) rrmdir(tmpdir); 18245c51f124SMoriah Waterland free(tmpdir); 18255c51f124SMoriah Waterland tmpdir = NULL; 18265c51f124SMoriah Waterland } 18275c51f124SMoriah Waterland 18285c51f124SMoriah Waterland if (tmppath) { 18295c51f124SMoriah Waterland /* remove any previous tmppath stuff */ 1830*4656d474SGarrett D'Amore (void) rrmdir(tmppath); 18315c51f124SMoriah Waterland free(tmppath); 18325c51f124SMoriah Waterland tmppath = NULL; 18335c51f124SMoriah Waterland } 18345c51f124SMoriah Waterland 18355c51f124SMoriah Waterland if (tmpsymdir) { 18365c51f124SMoriah Waterland /* remove temp symbolic links made for signed pkg */ 1837*4656d474SGarrett D'Amore (void) rrmdir(tmpsymdir); 18385c51f124SMoriah Waterland free(tmpsymdir); 18395c51f124SMoriah Waterland tmpsymdir = NULL; 18405c51f124SMoriah Waterland } 18415c51f124SMoriah Waterland 18425c51f124SMoriah Waterland if (srcdev.mount && !ids_name) 1843*4656d474SGarrett D'Amore (void) pkgumount(&srcdev); 18445c51f124SMoriah Waterland if (dstdev.mount && !ods_name) 1845*4656d474SGarrett D'Amore (void) pkgumount(&dstdev); 18465c51f124SMoriah Waterland (void) ds_close(1); 18475c51f124SMoriah Waterland } 18485c51f124SMoriah Waterland 18495c51f124SMoriah Waterland /* 18505c51f124SMoriah Waterland * Name: dump_hdr_and_pkgs 18515c51f124SMoriah Waterland * Description: Dumps datastream header and each package's contents 18525c51f124SMoriah Waterland * to the supplied BIO 18535c51f124SMoriah Waterland * 18545c51f124SMoriah Waterland * Arguments: bio - BIO object to dump data to 18555c51f124SMoriah Waterland * hdr - Header for the datastream being dumped 18565c51f124SMoriah Waterland * pkglist - NULL-terminated list of packages 18575c51f124SMoriah Waterland * to dump. The location of the packages are stored 18585c51f124SMoriah Waterland * in the static 'srcdev' variable. 18595c51f124SMoriah Waterland * 18605c51f124SMoriah Waterland * Returns : 0 - success 18615c51f124SMoriah Waterland * nonzero - failure. errors printed to screen. 18625c51f124SMoriah Waterland */ 18635c51f124SMoriah Waterland static int 18645c51f124SMoriah Waterland dump_hdr_and_pkgs(BIO *bio, struct dm_buf *hdr, char **pkglist) 18655c51f124SMoriah Waterland { 18665c51f124SMoriah Waterland int block_cnt, i; 18675c51f124SMoriah Waterland char srcdir[MAXPATHLEN]; 18685c51f124SMoriah Waterland char cwd[MAXPATHLEN + 1]; 18695c51f124SMoriah Waterland char *src; 18705c51f124SMoriah Waterland 18715c51f124SMoriah Waterland /* write out the header to the signature stream */ 18725c51f124SMoriah Waterland for (block_cnt = 0; block_cnt < hdr->allocation; 18735c51f124SMoriah Waterland block_cnt += BLK_SIZE) { 1874*4656d474SGarrett D'Amore (void) BIO_write(bio, (hdr->text_buffer + block_cnt), BLK_SIZE); 18755c51f124SMoriah Waterland } 18765c51f124SMoriah Waterland 18775c51f124SMoriah Waterland /* save current directory */ 18785c51f124SMoriah Waterland if (getcwd(cwd, MAXPATHLEN + 1) == NULL) { 18795c51f124SMoriah Waterland logerr(pkg_gt(ERR_GETWD)); 18805c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER)); 18815c51f124SMoriah Waterland return (1); 18825c51f124SMoriah Waterland } 18835c51f124SMoriah Waterland 18845c51f124SMoriah Waterland /* now write out each package's contents */ 18855c51f124SMoriah Waterland for (i = 0; pkglist[i]; i++) { 18865c51f124SMoriah Waterland /* 18875c51f124SMoriah Waterland * change to the source dir, so we can find and dump 18885c51f124SMoriah Waterland * the package(s) bits into the BIO 18895c51f124SMoriah Waterland * 18905c51f124SMoriah Waterland */ 18915c51f124SMoriah Waterland src = srcdev.dirname; 18925c51f124SMoriah Waterland 18935c51f124SMoriah Waterland /* change to the package source directory */ 18945c51f124SMoriah Waterland (void) snprintf(srcdir, MAXPATHLEN, "%s/%s", src, pkglist[i]); 18955c51f124SMoriah Waterland if (chdir(srcdir)) { 18965c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER)); 18975c51f124SMoriah Waterland logerr(pkg_gt(MSG_CHDIR), srcdir); 18985c51f124SMoriah Waterland return (1); 18995c51f124SMoriah Waterland } 19005c51f124SMoriah Waterland 19015c51f124SMoriah Waterland if (pkgdump(pkglist[i], bio)) { 19025c51f124SMoriah Waterland pkglist[i] = NULL; 19035c51f124SMoriah Waterland return (1); 19045c51f124SMoriah Waterland } 19055c51f124SMoriah Waterland } 19065c51f124SMoriah Waterland 19075c51f124SMoriah Waterland /* change back to directory we were in upon entering this routine */ 19085c51f124SMoriah Waterland if (chdir(cwd)) { 19095c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER)); 19105c51f124SMoriah Waterland logerr(pkg_gt(MSG_CHDIR), cwd); 19115c51f124SMoriah Waterland return (1); 19125c51f124SMoriah Waterland } 19135c51f124SMoriah Waterland 19145c51f124SMoriah Waterland return (0); 19155c51f124SMoriah Waterland } 19165c51f124SMoriah Waterland 19175c51f124SMoriah Waterland /* 19185c51f124SMoriah Waterland * Name: BIO_dump_cmd 19195c51f124SMoriah Waterland * Description: Dump the output of invoking a command 19205c51f124SMoriah Waterland * to a BIO. 19215c51f124SMoriah Waterland * 19225c51f124SMoriah Waterland * Arguments: cmd - Command to invoke 19235c51f124SMoriah Waterland * bio - BIO to dump output of command to 19245c51f124SMoriah Waterland * only 'stdout' is dumped. 19255c51f124SMoriah Waterland * Returns : 0 - success 19265c51f124SMoriah Waterland * nonzero - failure. errors printed to screen. 19275c51f124SMoriah Waterland */ 19285c51f124SMoriah Waterland int 19295c51f124SMoriah Waterland BIO_dump_cmd(char *cmd, BIO *bio) 19305c51f124SMoriah Waterland { 19315c51f124SMoriah Waterland char buf[BLK_SIZE]; 19325c51f124SMoriah Waterland FILE *fp; 19335c51f124SMoriah Waterland int rc; 19345c51f124SMoriah Waterland 19355c51f124SMoriah Waterland /* start up the process */ 19365c51f124SMoriah Waterland if ((fp = epopen(cmd, "r")) == NULL) { 19375c51f124SMoriah Waterland rpterr(); 19385c51f124SMoriah Waterland return (1); 19395c51f124SMoriah Waterland } 19405c51f124SMoriah Waterland 19415c51f124SMoriah Waterland /* read output in chunks, transfer to BIO */ 19425c51f124SMoriah Waterland while (fread(buf, BLK_SIZE, 1, fp) == 1) { 19435c51f124SMoriah Waterland if (BIO_write(bio, buf, BLK_SIZE) != BLK_SIZE) { 1944*4656d474SGarrett D'Amore (void) sighold(SIGINT); 1945*4656d474SGarrett D'Amore (void) sighold(SIGHUP); 19465c51f124SMoriah Waterland (void) epclose(fp); 1947*4656d474SGarrett D'Amore (void) sigrelse(SIGINT); 1948*4656d474SGarrett D'Amore (void) sigrelse(SIGHUP); 19495c51f124SMoriah Waterland rpterr(); 19505c51f124SMoriah Waterland return (1); 19515c51f124SMoriah Waterland } 19525c51f124SMoriah Waterland } 19535c51f124SMoriah Waterland 19545c51f124SMoriah Waterland /* done with stream, make sure no errors were encountered */ 19555c51f124SMoriah Waterland if (ferror(fp)) { 19565c51f124SMoriah Waterland (void) epclose(fp); 19575c51f124SMoriah Waterland rpterr(); 19585c51f124SMoriah Waterland return (1); 19595c51f124SMoriah Waterland } 19605c51f124SMoriah Waterland 19615c51f124SMoriah Waterland /* done, close stream, report any errors */ 1962*4656d474SGarrett D'Amore (void) sighold(SIGINT); 1963*4656d474SGarrett D'Amore (void) sighold(SIGHUP); 19645c51f124SMoriah Waterland rc = epclose(fp); 1965*4656d474SGarrett D'Amore (void) sigrelse(SIGINT); 1966*4656d474SGarrett D'Amore (void) sigrelse(SIGHUP); 19675c51f124SMoriah Waterland if (rc != 0) { 19685c51f124SMoriah Waterland rpterr(); 19695c51f124SMoriah Waterland return (1); 19705c51f124SMoriah Waterland } 19715c51f124SMoriah Waterland 19725c51f124SMoriah Waterland return (rc); 19735c51f124SMoriah Waterland } 1974