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