1*9781SMoriah.Waterland@Sun.COM /* 2*9781SMoriah.Waterland@Sun.COM * CDDL HEADER START 3*9781SMoriah.Waterland@Sun.COM * 4*9781SMoriah.Waterland@Sun.COM * The contents of this file are subject to the terms of the 5*9781SMoriah.Waterland@Sun.COM * Common Development and Distribution License (the "License"). 6*9781SMoriah.Waterland@Sun.COM * You may not use this file except in compliance with the License. 7*9781SMoriah.Waterland@Sun.COM * 8*9781SMoriah.Waterland@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*9781SMoriah.Waterland@Sun.COM * or http://www.opensolaris.org/os/licensing. 10*9781SMoriah.Waterland@Sun.COM * See the License for the specific language governing permissions 11*9781SMoriah.Waterland@Sun.COM * and limitations under the License. 12*9781SMoriah.Waterland@Sun.COM * 13*9781SMoriah.Waterland@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each 14*9781SMoriah.Waterland@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*9781SMoriah.Waterland@Sun.COM * If applicable, add the following below this CDDL HEADER, with the 16*9781SMoriah.Waterland@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying 17*9781SMoriah.Waterland@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner] 18*9781SMoriah.Waterland@Sun.COM * 19*9781SMoriah.Waterland@Sun.COM * CDDL HEADER END 20*9781SMoriah.Waterland@Sun.COM */ 21*9781SMoriah.Waterland@Sun.COM 22*9781SMoriah.Waterland@Sun.COM /* 23*9781SMoriah.Waterland@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24*9781SMoriah.Waterland@Sun.COM * Use is subject to license terms. 25*9781SMoriah.Waterland@Sun.COM */ 26*9781SMoriah.Waterland@Sun.COM 27*9781SMoriah.Waterland@Sun.COM /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 28*9781SMoriah.Waterland@Sun.COM /* All Rights Reserved */ 29*9781SMoriah.Waterland@Sun.COM 30*9781SMoriah.Waterland@Sun.COM 31*9781SMoriah.Waterland@Sun.COM 32*9781SMoriah.Waterland@Sun.COM #include <stdio.h> 33*9781SMoriah.Waterland@Sun.COM #include <string.h> 34*9781SMoriah.Waterland@Sun.COM #include <signal.h> 35*9781SMoriah.Waterland@Sun.COM #include <stdlib.h> 36*9781SMoriah.Waterland@Sun.COM #include <unistd.h> 37*9781SMoriah.Waterland@Sun.COM #include <sys/types.h> 38*9781SMoriah.Waterland@Sun.COM #include <sys/param.h> 39*9781SMoriah.Waterland@Sun.COM #include <sys/sysmacros.h> 40*9781SMoriah.Waterland@Sun.COM #include <errno.h> 41*9781SMoriah.Waterland@Sun.COM #include <sys/types.h> 42*9781SMoriah.Waterland@Sun.COM #include <sys/stat.h> 43*9781SMoriah.Waterland@Sun.COM #include <sys/statvfs.h> 44*9781SMoriah.Waterland@Sun.COM #include <fcntl.h> 45*9781SMoriah.Waterland@Sun.COM #ifdef u3b2 46*9781SMoriah.Waterland@Sun.COM #include <sys/sys3b.h> 47*9781SMoriah.Waterland@Sun.COM #endif /* u3b2 */ 48*9781SMoriah.Waterland@Sun.COM #include <openssl/err.h> 49*9781SMoriah.Waterland@Sun.COM #include "pkglib.h" 50*9781SMoriah.Waterland@Sun.COM #include "pkglibmsgs.h" 51*9781SMoriah.Waterland@Sun.COM #include "pkglocale.h" 52*9781SMoriah.Waterland@Sun.COM #ifdef u3b2 53*9781SMoriah.Waterland@Sun.COM static 54*9781SMoriah.Waterland@Sun.COM struct stat orig_st_buf; /* Stat structure of original file (3B2/CTC) */ 55*9781SMoriah.Waterland@Sun.COM static char ds_ctcflg; 56*9781SMoriah.Waterland@Sun.COM #endif /* u3b2 */ 57*9781SMoriah.Waterland@Sun.COM 58*9781SMoriah.Waterland@Sun.COM /* libadm.a */ 59*9781SMoriah.Waterland@Sun.COM extern char *devattr(char *device, char *attribute); 60*9781SMoriah.Waterland@Sun.COM extern int pkgnmchk(register char *pkg, register char *spec, 61*9781SMoriah.Waterland@Sun.COM int presvr4flg); 62*9781SMoriah.Waterland@Sun.COM extern int getvol(char *device, char *label, int options, char *prompt); 63*9781SMoriah.Waterland@Sun.COM 64*9781SMoriah.Waterland@Sun.COM #define CMDSIZ 512 65*9781SMoriah.Waterland@Sun.COM #define LSIZE 128 66*9781SMoriah.Waterland@Sun.COM #define DDPROC "/usr/bin/dd" 67*9781SMoriah.Waterland@Sun.COM #define CPIOPROC "/usr/bin/cpio" 68*9781SMoriah.Waterland@Sun.COM 69*9781SMoriah.Waterland@Sun.COM /* device types */ 70*9781SMoriah.Waterland@Sun.COM 71*9781SMoriah.Waterland@Sun.COM #define G_TM_TAPE 1 /* Tapemaster controller */ 72*9781SMoriah.Waterland@Sun.COM #define G_XY_DISK 3 /* xy disks */ 73*9781SMoriah.Waterland@Sun.COM #define G_SD_DISK 7 /* scsi sd disk */ 74*9781SMoriah.Waterland@Sun.COM #define G_XT_TAPE 8 /* xt tapes */ 75*9781SMoriah.Waterland@Sun.COM #define G_SF_FLOPPY 9 /* sf floppy */ 76*9781SMoriah.Waterland@Sun.COM #define G_XD_DISK 10 /* xd disks */ 77*9781SMoriah.Waterland@Sun.COM #define G_ST_TAPE 11 /* scsi tape */ 78*9781SMoriah.Waterland@Sun.COM #define G_NS 12 /* noswap pseudo-dev */ 79*9781SMoriah.Waterland@Sun.COM #define G_RAM 13 /* ram pseudo-dev */ 80*9781SMoriah.Waterland@Sun.COM #define G_FT 14 /* tftp */ 81*9781SMoriah.Waterland@Sun.COM #define G_HD 15 /* 386 network disk */ 82*9781SMoriah.Waterland@Sun.COM #define G_FD 16 /* 386 AT disk */ 83*9781SMoriah.Waterland@Sun.COM #define G_FILE 28 /* file, not a device */ 84*9781SMoriah.Waterland@Sun.COM #define G_NO_DEV 29 /* device does not require special treatment */ 85*9781SMoriah.Waterland@Sun.COM #define G_DEV_MAX 30 /* last valid device type */ 86*9781SMoriah.Waterland@Sun.COM 87*9781SMoriah.Waterland@Sun.COM struct dstoc { 88*9781SMoriah.Waterland@Sun.COM int cnt; 89*9781SMoriah.Waterland@Sun.COM char pkg[NON_ABI_NAMELNGTH]; 90*9781SMoriah.Waterland@Sun.COM int nparts; 91*9781SMoriah.Waterland@Sun.COM long maxsiz; 92*9781SMoriah.Waterland@Sun.COM char volnos[128]; 93*9781SMoriah.Waterland@Sun.COM struct dstoc *next; 94*9781SMoriah.Waterland@Sun.COM } *ds_head, *ds_toc; 95*9781SMoriah.Waterland@Sun.COM 96*9781SMoriah.Waterland@Sun.COM #define ds_nparts ds_toc->nparts 97*9781SMoriah.Waterland@Sun.COM #define ds_maxsiz ds_toc->maxsiz 98*9781SMoriah.Waterland@Sun.COM 99*9781SMoriah.Waterland@Sun.COM int ds_totread; /* total number of parts read */ 100*9781SMoriah.Waterland@Sun.COM int ds_fd = -1; 101*9781SMoriah.Waterland@Sun.COM int ds_curpartcnt = -1; 102*9781SMoriah.Waterland@Sun.COM 103*9781SMoriah.Waterland@Sun.COM int ds_next(char *device, char *instdir); 104*9781SMoriah.Waterland@Sun.COM int ds_ginit(char *device); 105*9781SMoriah.Waterland@Sun.COM int ds_close(int pkgendflg); 106*9781SMoriah.Waterland@Sun.COM 107*9781SMoriah.Waterland@Sun.COM static FILE *ds_pp; 108*9781SMoriah.Waterland@Sun.COM static int ds_realfd = -1; /* file descriptor for real device */ 109*9781SMoriah.Waterland@Sun.COM static int ds_read; /* number of parts read for current package */ 110*9781SMoriah.Waterland@Sun.COM static int ds_volno; /* volume number of current volume */ 111*9781SMoriah.Waterland@Sun.COM static int ds_volcnt; /* total number of volumes */ 112*9781SMoriah.Waterland@Sun.COM static char ds_volnos[128]; /* parts/volume info */ 113*9781SMoriah.Waterland@Sun.COM static char *ds_device; 114*9781SMoriah.Waterland@Sun.COM static int ds_volpart; /* number of parts read in current volume, */ 115*9781SMoriah.Waterland@Sun.COM /* including skipped parts */ 116*9781SMoriah.Waterland@Sun.COM static int ds_bufsize; 117*9781SMoriah.Waterland@Sun.COM static int ds_skippart; /* number of parts skipped in current volume */ 118*9781SMoriah.Waterland@Sun.COM 119*9781SMoriah.Waterland@Sun.COM static int ds_getnextvol(char *device); 120*9781SMoriah.Waterland@Sun.COM static int ds_skip(char *device, int nskip); 121*9781SMoriah.Waterland@Sun.COM 122*9781SMoriah.Waterland@Sun.COM void 123*9781SMoriah.Waterland@Sun.COM ds_order(char *list[]) 124*9781SMoriah.Waterland@Sun.COM { 125*9781SMoriah.Waterland@Sun.COM struct dstoc *toc_pt; 126*9781SMoriah.Waterland@Sun.COM register int j, n; 127*9781SMoriah.Waterland@Sun.COM char *pt; 128*9781SMoriah.Waterland@Sun.COM 129*9781SMoriah.Waterland@Sun.COM toc_pt = ds_head; 130*9781SMoriah.Waterland@Sun.COM n = 0; 131*9781SMoriah.Waterland@Sun.COM while (toc_pt) { 132*9781SMoriah.Waterland@Sun.COM for (j = n; list[j]; j++) { 133*9781SMoriah.Waterland@Sun.COM if (strcmp(list[j], toc_pt->pkg) == 0) { 134*9781SMoriah.Waterland@Sun.COM /* just swap places in the array */ 135*9781SMoriah.Waterland@Sun.COM pt = list[n]; 136*9781SMoriah.Waterland@Sun.COM list[n++] = list[j]; 137*9781SMoriah.Waterland@Sun.COM list[j] = pt; 138*9781SMoriah.Waterland@Sun.COM } 139*9781SMoriah.Waterland@Sun.COM } 140*9781SMoriah.Waterland@Sun.COM toc_pt = toc_pt->next; 141*9781SMoriah.Waterland@Sun.COM } 142*9781SMoriah.Waterland@Sun.COM } 143*9781SMoriah.Waterland@Sun.COM 144*9781SMoriah.Waterland@Sun.COM static char *pds_header; 145*9781SMoriah.Waterland@Sun.COM static char *ds_header; 146*9781SMoriah.Waterland@Sun.COM static char *ds_header_raw; 147*9781SMoriah.Waterland@Sun.COM static int ds_headsize; 148*9781SMoriah.Waterland@Sun.COM 149*9781SMoriah.Waterland@Sun.COM static char * 150*9781SMoriah.Waterland@Sun.COM ds_gets(char *buf, int size) 151*9781SMoriah.Waterland@Sun.COM { 152*9781SMoriah.Waterland@Sun.COM int length; 153*9781SMoriah.Waterland@Sun.COM char *nextp; 154*9781SMoriah.Waterland@Sun.COM 155*9781SMoriah.Waterland@Sun.COM nextp = strchr(pds_header, '\n'); 156*9781SMoriah.Waterland@Sun.COM if (nextp == NULL) { 157*9781SMoriah.Waterland@Sun.COM length = strlen(pds_header); 158*9781SMoriah.Waterland@Sun.COM if (length > size) 159*9781SMoriah.Waterland@Sun.COM return (0); 160*9781SMoriah.Waterland@Sun.COM if ((ds_header = (char *)realloc(ds_header, 161*9781SMoriah.Waterland@Sun.COM ds_headsize + BLK_SIZE)) == NULL) 162*9781SMoriah.Waterland@Sun.COM return (0); 163*9781SMoriah.Waterland@Sun.COM if (read(ds_fd, ds_header + ds_headsize, BLK_SIZE) < BLK_SIZE) 164*9781SMoriah.Waterland@Sun.COM return (0); 165*9781SMoriah.Waterland@Sun.COM ds_headsize += BLK_SIZE; 166*9781SMoriah.Waterland@Sun.COM nextp = strchr(pds_header, '\n'); 167*9781SMoriah.Waterland@Sun.COM if (nextp == NULL) 168*9781SMoriah.Waterland@Sun.COM return (0); 169*9781SMoriah.Waterland@Sun.COM *nextp = '\0'; 170*9781SMoriah.Waterland@Sun.COM if (length + (int)strlen(pds_header) > size) 171*9781SMoriah.Waterland@Sun.COM return (0); 172*9781SMoriah.Waterland@Sun.COM (void) strncpy(buf + length, pds_header, strlen(pds_header)); 173*9781SMoriah.Waterland@Sun.COM buf[length + strlen(pds_header)] = '\0'; 174*9781SMoriah.Waterland@Sun.COM pds_header = nextp + 1; 175*9781SMoriah.Waterland@Sun.COM return (buf); 176*9781SMoriah.Waterland@Sun.COM } 177*9781SMoriah.Waterland@Sun.COM *nextp = '\0'; 178*9781SMoriah.Waterland@Sun.COM if ((int)strlen(pds_header) > size) 179*9781SMoriah.Waterland@Sun.COM return (0); 180*9781SMoriah.Waterland@Sun.COM (void) strncpy(buf, pds_header, strlen(pds_header)); 181*9781SMoriah.Waterland@Sun.COM buf[strlen(pds_header)] = '\0'; 182*9781SMoriah.Waterland@Sun.COM pds_header = nextp + 1; 183*9781SMoriah.Waterland@Sun.COM return (buf); 184*9781SMoriah.Waterland@Sun.COM } 185*9781SMoriah.Waterland@Sun.COM 186*9781SMoriah.Waterland@Sun.COM /* 187*9781SMoriah.Waterland@Sun.COM * function to determine if media is datastream or mounted 188*9781SMoriah.Waterland@Sun.COM * floppy 189*9781SMoriah.Waterland@Sun.COM */ 190*9781SMoriah.Waterland@Sun.COM int 191*9781SMoriah.Waterland@Sun.COM ds_readbuf(char *device) 192*9781SMoriah.Waterland@Sun.COM { 193*9781SMoriah.Waterland@Sun.COM char buf[BLK_SIZE]; 194*9781SMoriah.Waterland@Sun.COM 195*9781SMoriah.Waterland@Sun.COM if (ds_fd >= 0) 196*9781SMoriah.Waterland@Sun.COM (void) close(ds_fd); 197*9781SMoriah.Waterland@Sun.COM if ((ds_fd = open(device, O_RDONLY)) >= 0 && 198*9781SMoriah.Waterland@Sun.COM read(ds_fd, buf, BLK_SIZE) == BLK_SIZE && 199*9781SMoriah.Waterland@Sun.COM strncmp(buf, HDR_PREFIX, 20) == 0) { 200*9781SMoriah.Waterland@Sun.COM if ((ds_header = (char *)calloc(BLK_SIZE, 1)) == NULL) { 201*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_UNPACK)); 202*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_MEM)); 203*9781SMoriah.Waterland@Sun.COM (void) ds_close(0); 204*9781SMoriah.Waterland@Sun.COM return (0); 205*9781SMoriah.Waterland@Sun.COM } 206*9781SMoriah.Waterland@Sun.COM memcpy(ds_header, buf, BLK_SIZE); 207*9781SMoriah.Waterland@Sun.COM ds_headsize = BLK_SIZE; 208*9781SMoriah.Waterland@Sun.COM 209*9781SMoriah.Waterland@Sun.COM if (ds_ginit(device) < 0) { 210*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_UNPACK)); 211*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_OPEN), device, errno); 212*9781SMoriah.Waterland@Sun.COM (void) ds_close(0); 213*9781SMoriah.Waterland@Sun.COM return (0); 214*9781SMoriah.Waterland@Sun.COM } 215*9781SMoriah.Waterland@Sun.COM return (1); 216*9781SMoriah.Waterland@Sun.COM } else if (ds_fd >= 0) { 217*9781SMoriah.Waterland@Sun.COM (void) close(ds_fd); 218*9781SMoriah.Waterland@Sun.COM ds_fd = -1; 219*9781SMoriah.Waterland@Sun.COM } 220*9781SMoriah.Waterland@Sun.COM return (0); 221*9781SMoriah.Waterland@Sun.COM } 222*9781SMoriah.Waterland@Sun.COM 223*9781SMoriah.Waterland@Sun.COM /* 224*9781SMoriah.Waterland@Sun.COM * Determine how many additional volumes are needed for current package. 225*9781SMoriah.Waterland@Sun.COM * Note: a 0 will occur as first volume number when the package begins 226*9781SMoriah.Waterland@Sun.COM * on the next volume. 227*9781SMoriah.Waterland@Sun.COM */ 228*9781SMoriah.Waterland@Sun.COM static int 229*9781SMoriah.Waterland@Sun.COM ds_volsum(struct dstoc *toc) 230*9781SMoriah.Waterland@Sun.COM { 231*9781SMoriah.Waterland@Sun.COM int curpartcnt, volcnt; 232*9781SMoriah.Waterland@Sun.COM char volnos[128], tmpvol[128]; 233*9781SMoriah.Waterland@Sun.COM if (toc->volnos[0]) { 234*9781SMoriah.Waterland@Sun.COM int index, sum; 235*9781SMoriah.Waterland@Sun.COM sscanf(toc->volnos, "%d %[ 0-9]", &curpartcnt, volnos); 236*9781SMoriah.Waterland@Sun.COM volcnt = 0; 237*9781SMoriah.Waterland@Sun.COM sum = curpartcnt; 238*9781SMoriah.Waterland@Sun.COM while (sum < toc->nparts && sscanf(volnos, "%d %[ 0-9]", 239*9781SMoriah.Waterland@Sun.COM &index, tmpvol) >= 1) { 240*9781SMoriah.Waterland@Sun.COM (void) strcpy(volnos, tmpvol); 241*9781SMoriah.Waterland@Sun.COM volcnt++; 242*9781SMoriah.Waterland@Sun.COM sum += index; 243*9781SMoriah.Waterland@Sun.COM } 244*9781SMoriah.Waterland@Sun.COM /* side effect - set number of parts read on current volume */ 245*9781SMoriah.Waterland@Sun.COM ds_volpart = index; 246*9781SMoriah.Waterland@Sun.COM return (volcnt); 247*9781SMoriah.Waterland@Sun.COM } 248*9781SMoriah.Waterland@Sun.COM ds_volpart += toc->nparts; 249*9781SMoriah.Waterland@Sun.COM return (0); 250*9781SMoriah.Waterland@Sun.COM } 251*9781SMoriah.Waterland@Sun.COM 252*9781SMoriah.Waterland@Sun.COM /* initialize ds_curpartcnt and ds_volnos */ 253*9781SMoriah.Waterland@Sun.COM static void 254*9781SMoriah.Waterland@Sun.COM ds_pkginit(void) 255*9781SMoriah.Waterland@Sun.COM { 256*9781SMoriah.Waterland@Sun.COM if (ds_toc->volnos[0]) 257*9781SMoriah.Waterland@Sun.COM sscanf(ds_toc->volnos, "%d %[ 0-9]", &ds_curpartcnt, ds_volnos); 258*9781SMoriah.Waterland@Sun.COM else 259*9781SMoriah.Waterland@Sun.COM ds_curpartcnt = -1; 260*9781SMoriah.Waterland@Sun.COM } 261*9781SMoriah.Waterland@Sun.COM 262*9781SMoriah.Waterland@Sun.COM /* 263*9781SMoriah.Waterland@Sun.COM * functions to pass current package info to exec'ed program 264*9781SMoriah.Waterland@Sun.COM */ 265*9781SMoriah.Waterland@Sun.COM void 266*9781SMoriah.Waterland@Sun.COM ds_putinfo(char *buf) 267*9781SMoriah.Waterland@Sun.COM { 268*9781SMoriah.Waterland@Sun.COM (void) sprintf(buf, "%d %d %d %d %d %d %d %d %d %d %s", 269*9781SMoriah.Waterland@Sun.COM ds_fd, ds_realfd, ds_volcnt, ds_volno, ds_totread, ds_volpart, 270*9781SMoriah.Waterland@Sun.COM ds_skippart, ds_bufsize, ds_toc->nparts, ds_toc->maxsiz, 271*9781SMoriah.Waterland@Sun.COM ds_toc->volnos); 272*9781SMoriah.Waterland@Sun.COM } 273*9781SMoriah.Waterland@Sun.COM 274*9781SMoriah.Waterland@Sun.COM int 275*9781SMoriah.Waterland@Sun.COM ds_getinfo(char *string) 276*9781SMoriah.Waterland@Sun.COM { 277*9781SMoriah.Waterland@Sun.COM ds_toc = (struct dstoc *)calloc(1, sizeof (struct dstoc)); 278*9781SMoriah.Waterland@Sun.COM (void) sscanf(string, "%d %d %d %d %d %d %d %d %d %d %[ 0-9]", 279*9781SMoriah.Waterland@Sun.COM &ds_fd, &ds_realfd, &ds_volcnt, &ds_volno, &ds_totread, 280*9781SMoriah.Waterland@Sun.COM &ds_volpart, &ds_skippart, &ds_bufsize, &ds_toc->nparts, 281*9781SMoriah.Waterland@Sun.COM &ds_toc->maxsiz, ds_toc->volnos); 282*9781SMoriah.Waterland@Sun.COM ds_pkginit(); 283*9781SMoriah.Waterland@Sun.COM return (ds_toc->nparts); 284*9781SMoriah.Waterland@Sun.COM } 285*9781SMoriah.Waterland@Sun.COM 286*9781SMoriah.Waterland@Sun.COM /* 287*9781SMoriah.Waterland@Sun.COM * Return true if the file descriptor (ds_fd) is open on the package stream. 288*9781SMoriah.Waterland@Sun.COM */ 289*9781SMoriah.Waterland@Sun.COM boolean_t 290*9781SMoriah.Waterland@Sun.COM ds_fd_open(void) 291*9781SMoriah.Waterland@Sun.COM { 292*9781SMoriah.Waterland@Sun.COM return (ds_fd >= 0 ? B_TRUE : B_FALSE); 293*9781SMoriah.Waterland@Sun.COM } 294*9781SMoriah.Waterland@Sun.COM 295*9781SMoriah.Waterland@Sun.COM /* 296*9781SMoriah.Waterland@Sun.COM * Read the source device. Acquire the header data and check it for validity. 297*9781SMoriah.Waterland@Sun.COM */ 298*9781SMoriah.Waterland@Sun.COM int 299*9781SMoriah.Waterland@Sun.COM ds_init(char *device, char **pkg, char *norewind) 300*9781SMoriah.Waterland@Sun.COM { 301*9781SMoriah.Waterland@Sun.COM struct dstoc *tail, *toc_pt; 302*9781SMoriah.Waterland@Sun.COM char *ret; 303*9781SMoriah.Waterland@Sun.COM char cmd[CMDSIZ]; 304*9781SMoriah.Waterland@Sun.COM char line[LSIZE+1]; 305*9781SMoriah.Waterland@Sun.COM int i, n, count = 0, header_size = BLK_SIZE; 306*9781SMoriah.Waterland@Sun.COM 307*9781SMoriah.Waterland@Sun.COM if (!ds_header) { /* If the header hasn't been read yet */ 308*9781SMoriah.Waterland@Sun.COM if (ds_fd >= 0) 309*9781SMoriah.Waterland@Sun.COM (void) ds_close(0); 310*9781SMoriah.Waterland@Sun.COM 311*9781SMoriah.Waterland@Sun.COM /* always start with rewind device */ 312*9781SMoriah.Waterland@Sun.COM if ((ds_fd = open(device, O_RDONLY)) < 0) { 313*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_UNPACK)); 314*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_OPEN), device, errno); 315*9781SMoriah.Waterland@Sun.COM return (-1); 316*9781SMoriah.Waterland@Sun.COM } 317*9781SMoriah.Waterland@Sun.COM 318*9781SMoriah.Waterland@Sun.COM /* allocate room for the header equivalent to a block */ 319*9781SMoriah.Waterland@Sun.COM if ((ds_header = (char *)calloc(BLK_SIZE, 1)) == NULL) { 320*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_UNPACK)); 321*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_MEM)); 322*9781SMoriah.Waterland@Sun.COM return (-1); 323*9781SMoriah.Waterland@Sun.COM } 324*9781SMoriah.Waterland@Sun.COM 325*9781SMoriah.Waterland@Sun.COM /* initialize the device */ 326*9781SMoriah.Waterland@Sun.COM if (ds_ginit(device) < 0) { 327*9781SMoriah.Waterland@Sun.COM (void) ds_close(0); 328*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_UNPACK)); 329*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_OPEN), device, errno); 330*9781SMoriah.Waterland@Sun.COM return (-1); 331*9781SMoriah.Waterland@Sun.COM } 332*9781SMoriah.Waterland@Sun.COM 333*9781SMoriah.Waterland@Sun.COM /* read a logical block from the source device */ 334*9781SMoriah.Waterland@Sun.COM if (read(ds_fd, ds_header, BLK_SIZE) != BLK_SIZE) { 335*9781SMoriah.Waterland@Sun.COM rpterr(); 336*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_UNPACK)); 337*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_TOC)); 338*9781SMoriah.Waterland@Sun.COM (void) ds_close(0); 339*9781SMoriah.Waterland@Sun.COM return (-1); 340*9781SMoriah.Waterland@Sun.COM } 341*9781SMoriah.Waterland@Sun.COM 342*9781SMoriah.Waterland@Sun.COM /* 343*9781SMoriah.Waterland@Sun.COM * This loop scans the medium for the start of the header. 344*9781SMoriah.Waterland@Sun.COM * If the above read worked, we skip this. If it did't, this 345*9781SMoriah.Waterland@Sun.COM * loop will retry the read ten times looking for the header 346*9781SMoriah.Waterland@Sun.COM * marker string. 347*9781SMoriah.Waterland@Sun.COM */ 348*9781SMoriah.Waterland@Sun.COM while (strncmp(ds_header, HDR_PREFIX, 20) != 0) { 349*9781SMoriah.Waterland@Sun.COM /* only ten tries iff the device rewinds */ 350*9781SMoriah.Waterland@Sun.COM if (!norewind || count++ > 10) { 351*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_UNPACK)); 352*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_TOC)); 353*9781SMoriah.Waterland@Sun.COM (void) ds_close(0); 354*9781SMoriah.Waterland@Sun.COM return (-1); 355*9781SMoriah.Waterland@Sun.COM } 356*9781SMoriah.Waterland@Sun.COM 357*9781SMoriah.Waterland@Sun.COM /* read through to the last block */ 358*9781SMoriah.Waterland@Sun.COM if (count > 1) 359*9781SMoriah.Waterland@Sun.COM while (read(ds_fd, ds_header, BLK_SIZE) > 0) 360*9781SMoriah.Waterland@Sun.COM ; 361*9781SMoriah.Waterland@Sun.COM 362*9781SMoriah.Waterland@Sun.COM /* then close the device */ 363*9781SMoriah.Waterland@Sun.COM (void) ds_close(0); 364*9781SMoriah.Waterland@Sun.COM 365*9781SMoriah.Waterland@Sun.COM /* and reopen it */ 366*9781SMoriah.Waterland@Sun.COM if ((ds_fd = open(norewind, O_RDONLY)) < 0) { 367*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_UNPACK)); 368*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_OPEN), device, errno); 369*9781SMoriah.Waterland@Sun.COM (void) free(ds_header); 370*9781SMoriah.Waterland@Sun.COM return (-1); 371*9781SMoriah.Waterland@Sun.COM } 372*9781SMoriah.Waterland@Sun.COM 373*9781SMoriah.Waterland@Sun.COM /* initialize the device */ 374*9781SMoriah.Waterland@Sun.COM if (ds_ginit(device) < 0) { 375*9781SMoriah.Waterland@Sun.COM (void) ds_close(0); 376*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_UNPACK)); 377*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_OPEN), device, errno); 378*9781SMoriah.Waterland@Sun.COM return (-1); 379*9781SMoriah.Waterland@Sun.COM } 380*9781SMoriah.Waterland@Sun.COM 381*9781SMoriah.Waterland@Sun.COM /* read the block again */ 382*9781SMoriah.Waterland@Sun.COM if (read(ds_fd, ds_header, BLK_SIZE) != BLK_SIZE) { 383*9781SMoriah.Waterland@Sun.COM rpterr(); 384*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_UNPACK)); 385*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_TOC)); 386*9781SMoriah.Waterland@Sun.COM (void) ds_close(0); 387*9781SMoriah.Waterland@Sun.COM return (-1); 388*9781SMoriah.Waterland@Sun.COM } 389*9781SMoriah.Waterland@Sun.COM } 390*9781SMoriah.Waterland@Sun.COM 391*9781SMoriah.Waterland@Sun.COM /* Now keep scanning until the whole header is in place. */ 392*9781SMoriah.Waterland@Sun.COM while (strstr(ds_header, HDR_SUFFIX) == NULL) { 393*9781SMoriah.Waterland@Sun.COM /* We need a bigger buffer */ 394*9781SMoriah.Waterland@Sun.COM if ((ds_header = (char *)realloc(ds_header, 395*9781SMoriah.Waterland@Sun.COM header_size + BLK_SIZE)) == NULL) { 396*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_UNPACK)); 397*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_MEM)); 398*9781SMoriah.Waterland@Sun.COM (void) ds_close(0); 399*9781SMoriah.Waterland@Sun.COM return (1); 400*9781SMoriah.Waterland@Sun.COM } 401*9781SMoriah.Waterland@Sun.COM 402*9781SMoriah.Waterland@Sun.COM /* clear the new memory */ 403*9781SMoriah.Waterland@Sun.COM (void) memset(ds_header + header_size, '\0', 404*9781SMoriah.Waterland@Sun.COM BLK_SIZE); 405*9781SMoriah.Waterland@Sun.COM 406*9781SMoriah.Waterland@Sun.COM 407*9781SMoriah.Waterland@Sun.COM /* read a logical block from the source device */ 408*9781SMoriah.Waterland@Sun.COM if (read(ds_fd, ds_header + header_size, BLK_SIZE) != 409*9781SMoriah.Waterland@Sun.COM BLK_SIZE) { 410*9781SMoriah.Waterland@Sun.COM rpterr(); 411*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_UNPACK)); 412*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_TOC)); 413*9781SMoriah.Waterland@Sun.COM (void) ds_close(0); 414*9781SMoriah.Waterland@Sun.COM return (-1); 415*9781SMoriah.Waterland@Sun.COM } else 416*9781SMoriah.Waterland@Sun.COM header_size += BLK_SIZE; /* new size */ 417*9781SMoriah.Waterland@Sun.COM } 418*9781SMoriah.Waterland@Sun.COM 419*9781SMoriah.Waterland@Sun.COM /* 420*9781SMoriah.Waterland@Sun.COM * remember rewind device for ds_close to rewind at 421*9781SMoriah.Waterland@Sun.COM * close 422*9781SMoriah.Waterland@Sun.COM */ 423*9781SMoriah.Waterland@Sun.COM if (count >= 1) 424*9781SMoriah.Waterland@Sun.COM ds_device = device; 425*9781SMoriah.Waterland@Sun.COM ds_headsize = header_size; 426*9781SMoriah.Waterland@Sun.COM 427*9781SMoriah.Waterland@Sun.COM } 428*9781SMoriah.Waterland@Sun.COM 429*9781SMoriah.Waterland@Sun.COM pds_header = ds_header; 430*9781SMoriah.Waterland@Sun.COM 431*9781SMoriah.Waterland@Sun.COM /* save raw copy of header for later use in BIO_dump_header */ 432*9781SMoriah.Waterland@Sun.COM if ((ds_header_raw = (char *)malloc(header_size)) == NULL) { 433*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_UNPACK)); 434*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_MEM)); 435*9781SMoriah.Waterland@Sun.COM (void) ds_close(0); 436*9781SMoriah.Waterland@Sun.COM return (1); 437*9781SMoriah.Waterland@Sun.COM } 438*9781SMoriah.Waterland@Sun.COM memcpy(ds_header_raw, ds_header, header_size); 439*9781SMoriah.Waterland@Sun.COM 440*9781SMoriah.Waterland@Sun.COM /* read datastream table of contents */ 441*9781SMoriah.Waterland@Sun.COM ds_head = tail = (struct dstoc *)0; 442*9781SMoriah.Waterland@Sun.COM ds_volcnt = 1; 443*9781SMoriah.Waterland@Sun.COM 444*9781SMoriah.Waterland@Sun.COM while (ret = ds_gets(line, LSIZE)) { 445*9781SMoriah.Waterland@Sun.COM if (strcmp(line, HDR_SUFFIX) == 0) 446*9781SMoriah.Waterland@Sun.COM break; 447*9781SMoriah.Waterland@Sun.COM if (!line[0] || line[0] == '#') 448*9781SMoriah.Waterland@Sun.COM continue; 449*9781SMoriah.Waterland@Sun.COM toc_pt = (struct dstoc *)calloc(1, sizeof (struct dstoc)); 450*9781SMoriah.Waterland@Sun.COM if (!toc_pt) { 451*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_UNPACK)); 452*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_MEM)); 453*9781SMoriah.Waterland@Sun.COM ecleanup(); 454*9781SMoriah.Waterland@Sun.COM (void) free(ds_header); 455*9781SMoriah.Waterland@Sun.COM return (-1); 456*9781SMoriah.Waterland@Sun.COM } 457*9781SMoriah.Waterland@Sun.COM if (sscanf(line, "%s %d %d %[ 0-9]", toc_pt->pkg, 458*9781SMoriah.Waterland@Sun.COM &toc_pt->nparts, &toc_pt->maxsiz, toc_pt->volnos) < 3) { 459*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_UNPACK)); 460*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_TOC)); 461*9781SMoriah.Waterland@Sun.COM free(toc_pt); 462*9781SMoriah.Waterland@Sun.COM (void) free(ds_header); 463*9781SMoriah.Waterland@Sun.COM ecleanup(); 464*9781SMoriah.Waterland@Sun.COM return (-1); 465*9781SMoriah.Waterland@Sun.COM } 466*9781SMoriah.Waterland@Sun.COM if (tail) { 467*9781SMoriah.Waterland@Sun.COM tail->next = toc_pt; 468*9781SMoriah.Waterland@Sun.COM tail = toc_pt; 469*9781SMoriah.Waterland@Sun.COM } else 470*9781SMoriah.Waterland@Sun.COM ds_head = tail = toc_pt; 471*9781SMoriah.Waterland@Sun.COM ds_volcnt += ds_volsum(toc_pt); 472*9781SMoriah.Waterland@Sun.COM } 473*9781SMoriah.Waterland@Sun.COM if (!ret) { 474*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_UNPACK)); 475*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_TOC)); 476*9781SMoriah.Waterland@Sun.COM (void) free(ds_header); 477*9781SMoriah.Waterland@Sun.COM return (-1); 478*9781SMoriah.Waterland@Sun.COM } 479*9781SMoriah.Waterland@Sun.COM sighold(SIGINT); 480*9781SMoriah.Waterland@Sun.COM sigrelse(SIGINT); 481*9781SMoriah.Waterland@Sun.COM if (!ds_head) { 482*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_UNPACK)); 483*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_EMPTY)); 484*9781SMoriah.Waterland@Sun.COM (void) free(ds_header); 485*9781SMoriah.Waterland@Sun.COM return (-1); 486*9781SMoriah.Waterland@Sun.COM } 487*9781SMoriah.Waterland@Sun.COM /* this could break, thanks to cpio command limit */ 488*9781SMoriah.Waterland@Sun.COM #ifndef SUNOS41 489*9781SMoriah.Waterland@Sun.COM (void) sprintf(cmd, "%s -icdumD -C %d", CPIOPROC, (int)BLK_SIZE); 490*9781SMoriah.Waterland@Sun.COM #else 491*9781SMoriah.Waterland@Sun.COM (void) sprintf(cmd, "%s -icdum -C %d", CPIOPROC, (int)BLK_SIZE); 492*9781SMoriah.Waterland@Sun.COM #endif 493*9781SMoriah.Waterland@Sun.COM n = 0; 494*9781SMoriah.Waterland@Sun.COM for (i = 0; pkg[i]; i++) { 495*9781SMoriah.Waterland@Sun.COM if (strcmp(pkg[i], "all") == 0) 496*9781SMoriah.Waterland@Sun.COM continue; 497*9781SMoriah.Waterland@Sun.COM if (n == 0) { 498*9781SMoriah.Waterland@Sun.COM strcat(cmd, " "); 499*9781SMoriah.Waterland@Sun.COM n = 1; 500*9781SMoriah.Waterland@Sun.COM } 501*9781SMoriah.Waterland@Sun.COM strlcat(cmd, pkg[i], CMDSIZ); 502*9781SMoriah.Waterland@Sun.COM strlcat(cmd, "'/*' ", CMDSIZ); 503*9781SMoriah.Waterland@Sun.COM 504*9781SMoriah.Waterland@Sun.COM /* extract signature too, if present. */ 505*9781SMoriah.Waterland@Sun.COM strlcat(cmd, SIGNATURE_FILENAME, CMDSIZ); 506*9781SMoriah.Waterland@Sun.COM strlcat(cmd, " ", CMDSIZ); 507*9781SMoriah.Waterland@Sun.COM } 508*9781SMoriah.Waterland@Sun.COM 509*9781SMoriah.Waterland@Sun.COM /* 510*9781SMoriah.Waterland@Sun.COM * if we are extracting all packages (pkgs == NULL), 511*9781SMoriah.Waterland@Sun.COM * signature will automatically be extracted 512*9781SMoriah.Waterland@Sun.COM */ 513*9781SMoriah.Waterland@Sun.COM if (n = esystem(cmd, ds_fd, -1)) { 514*9781SMoriah.Waterland@Sun.COM rpterr(); 515*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_UNPACK)); 516*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_CMDFAIL), cmd, n); 517*9781SMoriah.Waterland@Sun.COM (void) free(ds_header); 518*9781SMoriah.Waterland@Sun.COM return (-1); 519*9781SMoriah.Waterland@Sun.COM } 520*9781SMoriah.Waterland@Sun.COM 521*9781SMoriah.Waterland@Sun.COM ds_toc = ds_head; 522*9781SMoriah.Waterland@Sun.COM ds_totread = 0; 523*9781SMoriah.Waterland@Sun.COM ds_volno = 1; 524*9781SMoriah.Waterland@Sun.COM return (0); 525*9781SMoriah.Waterland@Sun.COM } 526*9781SMoriah.Waterland@Sun.COM 527*9781SMoriah.Waterland@Sun.COM int 528*9781SMoriah.Waterland@Sun.COM ds_findpkg(char *device, char *pkg) 529*9781SMoriah.Waterland@Sun.COM { 530*9781SMoriah.Waterland@Sun.COM char *pkglist[2]; 531*9781SMoriah.Waterland@Sun.COM int nskip, ods_volpart; 532*9781SMoriah.Waterland@Sun.COM 533*9781SMoriah.Waterland@Sun.COM if (ds_head == NULL) { 534*9781SMoriah.Waterland@Sun.COM pkglist[0] = pkg; 535*9781SMoriah.Waterland@Sun.COM pkglist[1] = NULL; 536*9781SMoriah.Waterland@Sun.COM if (ds_init(device, pkglist, NULL)) 537*9781SMoriah.Waterland@Sun.COM return (-1); 538*9781SMoriah.Waterland@Sun.COM } 539*9781SMoriah.Waterland@Sun.COM 540*9781SMoriah.Waterland@Sun.COM if (!pkg || pkgnmchk(pkg, "all", 0)) { 541*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_UNPACK)); 542*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_PKGNAME)); 543*9781SMoriah.Waterland@Sun.COM return (-1); 544*9781SMoriah.Waterland@Sun.COM } 545*9781SMoriah.Waterland@Sun.COM 546*9781SMoriah.Waterland@Sun.COM nskip = 0; 547*9781SMoriah.Waterland@Sun.COM ds_volno = 1; 548*9781SMoriah.Waterland@Sun.COM ds_volpart = 0; 549*9781SMoriah.Waterland@Sun.COM ds_toc = ds_head; 550*9781SMoriah.Waterland@Sun.COM while (ds_toc) { 551*9781SMoriah.Waterland@Sun.COM if (strcmp(ds_toc->pkg, pkg) == 0) 552*9781SMoriah.Waterland@Sun.COM break; 553*9781SMoriah.Waterland@Sun.COM nskip += ds_toc->nparts; 554*9781SMoriah.Waterland@Sun.COM ds_volno += ds_volsum(ds_toc); 555*9781SMoriah.Waterland@Sun.COM ds_toc = ds_toc->next; 556*9781SMoriah.Waterland@Sun.COM } 557*9781SMoriah.Waterland@Sun.COM if (!ds_toc) { 558*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_UNPACK)); 559*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_NOPKG), pkg); 560*9781SMoriah.Waterland@Sun.COM return (-1); 561*9781SMoriah.Waterland@Sun.COM } 562*9781SMoriah.Waterland@Sun.COM 563*9781SMoriah.Waterland@Sun.COM ds_pkginit(); 564*9781SMoriah.Waterland@Sun.COM ds_skippart = 0; 565*9781SMoriah.Waterland@Sun.COM if (ds_curpartcnt > 0) { 566*9781SMoriah.Waterland@Sun.COM ods_volpart = ds_volpart; 567*9781SMoriah.Waterland@Sun.COM /* 568*9781SMoriah.Waterland@Sun.COM * skip past archives belonging to last package on current 569*9781SMoriah.Waterland@Sun.COM * volume 570*9781SMoriah.Waterland@Sun.COM */ 571*9781SMoriah.Waterland@Sun.COM if (ds_volpart > 0 && ds_getnextvol(device)) 572*9781SMoriah.Waterland@Sun.COM return (-1); 573*9781SMoriah.Waterland@Sun.COM ds_totread = nskip - ods_volpart; 574*9781SMoriah.Waterland@Sun.COM if (ds_skip(device, ods_volpart)) 575*9781SMoriah.Waterland@Sun.COM return (-1); 576*9781SMoriah.Waterland@Sun.COM } else if (ds_curpartcnt < 0) { 577*9781SMoriah.Waterland@Sun.COM if (ds_skip(device, nskip - ds_totread)) 578*9781SMoriah.Waterland@Sun.COM return (-1); 579*9781SMoriah.Waterland@Sun.COM } else 580*9781SMoriah.Waterland@Sun.COM ds_totread = nskip; 581*9781SMoriah.Waterland@Sun.COM ds_read = 0; 582*9781SMoriah.Waterland@Sun.COM return (ds_nparts); 583*9781SMoriah.Waterland@Sun.COM } 584*9781SMoriah.Waterland@Sun.COM 585*9781SMoriah.Waterland@Sun.COM /* 586*9781SMoriah.Waterland@Sun.COM * Get datastream part 587*9781SMoriah.Waterland@Sun.COM * Call for first part should be preceded by 588*9781SMoriah.Waterland@Sun.COM * call to ds_findpkg 589*9781SMoriah.Waterland@Sun.COM */ 590*9781SMoriah.Waterland@Sun.COM 591*9781SMoriah.Waterland@Sun.COM int 592*9781SMoriah.Waterland@Sun.COM ds_getpkg(char *device, int n, char *dstdir) 593*9781SMoriah.Waterland@Sun.COM { 594*9781SMoriah.Waterland@Sun.COM struct statvfs64 svfsb; 595*9781SMoriah.Waterland@Sun.COM u_longlong_t free_blocks; 596*9781SMoriah.Waterland@Sun.COM 597*9781SMoriah.Waterland@Sun.COM if (ds_read >= ds_nparts) 598*9781SMoriah.Waterland@Sun.COM return (2); 599*9781SMoriah.Waterland@Sun.COM 600*9781SMoriah.Waterland@Sun.COM if (ds_read == n) 601*9781SMoriah.Waterland@Sun.COM return (0); 602*9781SMoriah.Waterland@Sun.COM else if ((ds_read > n) || (n > ds_nparts)) 603*9781SMoriah.Waterland@Sun.COM return (2); 604*9781SMoriah.Waterland@Sun.COM 605*9781SMoriah.Waterland@Sun.COM if (ds_maxsiz > 0) { 606*9781SMoriah.Waterland@Sun.COM if (statvfs64(".", &svfsb)) { 607*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_UNPACK)); 608*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_STATFS), errno); 609*9781SMoriah.Waterland@Sun.COM return (-1); 610*9781SMoriah.Waterland@Sun.COM } 611*9781SMoriah.Waterland@Sun.COM #ifdef SUNOS41 612*9781SMoriah.Waterland@Sun.COM free_blocks = svfsb.f_bfree * howmany(svfsb.f_bsize, DEV_BSIZE); 613*9781SMoriah.Waterland@Sun.COM #else /* !SUNOS41 */ 614*9781SMoriah.Waterland@Sun.COM free_blocks = (((long)svfsb.f_frsize > 0) ? 615*9781SMoriah.Waterland@Sun.COM howmany(svfsb.f_frsize, DEV_BSIZE) : 616*9781SMoriah.Waterland@Sun.COM howmany(svfsb.f_bsize, DEV_BSIZE)) * svfsb.f_bfree; 617*9781SMoriah.Waterland@Sun.COM #endif /* SUNOS41 */ 618*9781SMoriah.Waterland@Sun.COM if ((ds_maxsiz + 50) > free_blocks) { 619*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_UNPACK)); 620*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_NOSPACE), ds_maxsiz+50, free_blocks); 621*9781SMoriah.Waterland@Sun.COM return (-1); 622*9781SMoriah.Waterland@Sun.COM } 623*9781SMoriah.Waterland@Sun.COM } 624*9781SMoriah.Waterland@Sun.COM return (ds_next(device, dstdir)); 625*9781SMoriah.Waterland@Sun.COM } 626*9781SMoriah.Waterland@Sun.COM 627*9781SMoriah.Waterland@Sun.COM static int 628*9781SMoriah.Waterland@Sun.COM ds_getnextvol(char *device) 629*9781SMoriah.Waterland@Sun.COM { 630*9781SMoriah.Waterland@Sun.COM char prompt[128]; 631*9781SMoriah.Waterland@Sun.COM int n; 632*9781SMoriah.Waterland@Sun.COM 633*9781SMoriah.Waterland@Sun.COM if (ds_close(0)) 634*9781SMoriah.Waterland@Sun.COM return (-1); 635*9781SMoriah.Waterland@Sun.COM (void) sprintf(prompt, 636*9781SMoriah.Waterland@Sun.COM pkg_gt("Insert %%v %d of %d into %%p"), 637*9781SMoriah.Waterland@Sun.COM ds_volno, ds_volcnt); 638*9781SMoriah.Waterland@Sun.COM if (n = getvol(device, NULL, NULL, prompt)) 639*9781SMoriah.Waterland@Sun.COM return (n); 640*9781SMoriah.Waterland@Sun.COM if ((ds_fd = open(device, O_RDONLY)) < 0) 641*9781SMoriah.Waterland@Sun.COM return (-1); 642*9781SMoriah.Waterland@Sun.COM if (ds_ginit(device) < 0) { 643*9781SMoriah.Waterland@Sun.COM (void) ds_close(0); 644*9781SMoriah.Waterland@Sun.COM return (-1); 645*9781SMoriah.Waterland@Sun.COM } 646*9781SMoriah.Waterland@Sun.COM ds_volpart = 0; 647*9781SMoriah.Waterland@Sun.COM return (0); 648*9781SMoriah.Waterland@Sun.COM } 649*9781SMoriah.Waterland@Sun.COM 650*9781SMoriah.Waterland@Sun.COM /* 651*9781SMoriah.Waterland@Sun.COM * called by ds_findpkg to skip past archives for unwanted packages 652*9781SMoriah.Waterland@Sun.COM * in current volume 653*9781SMoriah.Waterland@Sun.COM */ 654*9781SMoriah.Waterland@Sun.COM static int 655*9781SMoriah.Waterland@Sun.COM ds_skip(char *device, int nskip) 656*9781SMoriah.Waterland@Sun.COM { 657*9781SMoriah.Waterland@Sun.COM char cmd[CMDSIZ]; 658*9781SMoriah.Waterland@Sun.COM int n, onskip = nskip; 659*9781SMoriah.Waterland@Sun.COM 660*9781SMoriah.Waterland@Sun.COM while (nskip--) { 661*9781SMoriah.Waterland@Sun.COM /* skip this one */ 662*9781SMoriah.Waterland@Sun.COM #ifndef SUNOS41 663*9781SMoriah.Waterland@Sun.COM (void) sprintf(cmd, "%s -ictD -C %d > /dev/null", 664*9781SMoriah.Waterland@Sun.COM #else 665*9781SMoriah.Waterland@Sun.COM (void) sprintf(cmd, "%s -ict -C %d > /dev/null", 666*9781SMoriah.Waterland@Sun.COM #endif 667*9781SMoriah.Waterland@Sun.COM CPIOPROC, (int)BLK_SIZE); 668*9781SMoriah.Waterland@Sun.COM if (n = esystem(cmd, ds_fd, -1)) { 669*9781SMoriah.Waterland@Sun.COM rpterr(); 670*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_UNPACK)); 671*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_CMDFAIL), cmd, n); 672*9781SMoriah.Waterland@Sun.COM nskip = onskip; 673*9781SMoriah.Waterland@Sun.COM if (ds_volno == 1 || ds_volpart > 0) 674*9781SMoriah.Waterland@Sun.COM return (n); 675*9781SMoriah.Waterland@Sun.COM if (n = ds_getnextvol(device)) 676*9781SMoriah.Waterland@Sun.COM return (n); 677*9781SMoriah.Waterland@Sun.COM } 678*9781SMoriah.Waterland@Sun.COM } 679*9781SMoriah.Waterland@Sun.COM ds_totread += onskip; 680*9781SMoriah.Waterland@Sun.COM ds_volpart = onskip; 681*9781SMoriah.Waterland@Sun.COM ds_skippart = onskip; 682*9781SMoriah.Waterland@Sun.COM return (0); 683*9781SMoriah.Waterland@Sun.COM } 684*9781SMoriah.Waterland@Sun.COM 685*9781SMoriah.Waterland@Sun.COM /* skip to end of package if necessary */ 686*9781SMoriah.Waterland@Sun.COM void 687*9781SMoriah.Waterland@Sun.COM ds_skiptoend(char *device) 688*9781SMoriah.Waterland@Sun.COM { 689*9781SMoriah.Waterland@Sun.COM if (ds_read < ds_nparts && ds_curpartcnt < 0) 690*9781SMoriah.Waterland@Sun.COM (void) ds_skip(device, ds_nparts - ds_read); 691*9781SMoriah.Waterland@Sun.COM } 692*9781SMoriah.Waterland@Sun.COM 693*9781SMoriah.Waterland@Sun.COM int 694*9781SMoriah.Waterland@Sun.COM ds_next(char *device, char *instdir) 695*9781SMoriah.Waterland@Sun.COM { 696*9781SMoriah.Waterland@Sun.COM char cmd[CMDSIZ], tmpvol[128]; 697*9781SMoriah.Waterland@Sun.COM int nparts, n, index; 698*9781SMoriah.Waterland@Sun.COM 699*9781SMoriah.Waterland@Sun.COM /*CONSTCOND*/ 700*9781SMoriah.Waterland@Sun.COM while (1) { 701*9781SMoriah.Waterland@Sun.COM if (ds_read + 1 > ds_curpartcnt && ds_curpartcnt >= 0) { 702*9781SMoriah.Waterland@Sun.COM ds_volno++; 703*9781SMoriah.Waterland@Sun.COM if (n = ds_getnextvol(device)) 704*9781SMoriah.Waterland@Sun.COM return (n); 705*9781SMoriah.Waterland@Sun.COM (void) sscanf(ds_volnos, "%d %[ 0-9]", &index, tmpvol); 706*9781SMoriah.Waterland@Sun.COM (void) strcpy(ds_volnos, tmpvol); 707*9781SMoriah.Waterland@Sun.COM ds_curpartcnt += index; 708*9781SMoriah.Waterland@Sun.COM } 709*9781SMoriah.Waterland@Sun.COM #ifndef SUNOS41 710*9781SMoriah.Waterland@Sun.COM (void) sprintf(cmd, "%s -icdumD -C %d", 711*9781SMoriah.Waterland@Sun.COM #else 712*9781SMoriah.Waterland@Sun.COM (void) sprintf(cmd, "%s -icdum -C %d", 713*9781SMoriah.Waterland@Sun.COM #endif 714*9781SMoriah.Waterland@Sun.COM CPIOPROC, (int)BLK_SIZE); 715*9781SMoriah.Waterland@Sun.COM if (n = esystem(cmd, ds_fd, -1)) { 716*9781SMoriah.Waterland@Sun.COM rpterr(); 717*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_UNPACK)); 718*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_CMDFAIL), cmd, n); 719*9781SMoriah.Waterland@Sun.COM } 720*9781SMoriah.Waterland@Sun.COM if (ds_read == 0) 721*9781SMoriah.Waterland@Sun.COM nparts = 0; 722*9781SMoriah.Waterland@Sun.COM else 723*9781SMoriah.Waterland@Sun.COM nparts = ds_toc->nparts; 724*9781SMoriah.Waterland@Sun.COM if (n || (n = ckvolseq(instdir, ds_read + 1, nparts))) { 725*9781SMoriah.Waterland@Sun.COM if (ds_volno == 1 || ds_volpart > ds_skippart) 726*9781SMoriah.Waterland@Sun.COM return (-1); 727*9781SMoriah.Waterland@Sun.COM 728*9781SMoriah.Waterland@Sun.COM if (n = ds_getnextvol(device)) 729*9781SMoriah.Waterland@Sun.COM return (n); 730*9781SMoriah.Waterland@Sun.COM continue; 731*9781SMoriah.Waterland@Sun.COM } 732*9781SMoriah.Waterland@Sun.COM ds_read++; 733*9781SMoriah.Waterland@Sun.COM ds_totread++; 734*9781SMoriah.Waterland@Sun.COM ds_volpart++; 735*9781SMoriah.Waterland@Sun.COM 736*9781SMoriah.Waterland@Sun.COM return (0); 737*9781SMoriah.Waterland@Sun.COM } 738*9781SMoriah.Waterland@Sun.COM /*NOTREACHED*/ 739*9781SMoriah.Waterland@Sun.COM } 740*9781SMoriah.Waterland@Sun.COM 741*9781SMoriah.Waterland@Sun.COM /* 742*9781SMoriah.Waterland@Sun.COM * Name: BIO_ds_dump 743*9781SMoriah.Waterland@Sun.COM * Description: Dumps all data from the static 'ds_fd' file handle into 744*9781SMoriah.Waterland@Sun.COM * the supplied BIO. 745*9781SMoriah.Waterland@Sun.COM * 746*9781SMoriah.Waterland@Sun.COM * Arguments: err - where to record any errors. 747*9781SMoriah.Waterland@Sun.COM * device - Description of device being dumped into, 748*9781SMoriah.Waterland@Sun.COM * for error reporting 749*9781SMoriah.Waterland@Sun.COM * bio - BIO object to dump data into 750*9781SMoriah.Waterland@Sun.COM * 751*9781SMoriah.Waterland@Sun.COM * Returns : zero - successfully dumped all data to EOF 752*9781SMoriah.Waterland@Sun.COM * non-zero - some failure occurred. 753*9781SMoriah.Waterland@Sun.COM */ 754*9781SMoriah.Waterland@Sun.COM int 755*9781SMoriah.Waterland@Sun.COM BIO_ds_dump(PKG_ERR *err, char *device, BIO *bio) 756*9781SMoriah.Waterland@Sun.COM { 757*9781SMoriah.Waterland@Sun.COM int amtread; 758*9781SMoriah.Waterland@Sun.COM char readbuf[BLK_SIZE]; 759*9781SMoriah.Waterland@Sun.COM 760*9781SMoriah.Waterland@Sun.COM /* 761*9781SMoriah.Waterland@Sun.COM * note this will read to the end of the device, so it won't 762*9781SMoriah.Waterland@Sun.COM * work for character devices since we don't know when the 763*9781SMoriah.Waterland@Sun.COM * end of the CPIO archive is 764*9781SMoriah.Waterland@Sun.COM */ 765*9781SMoriah.Waterland@Sun.COM while ((amtread = read(ds_fd, readbuf, BLK_SIZE)) != 0) { 766*9781SMoriah.Waterland@Sun.COM if (BIO_write(bio, readbuf, amtread) != amtread) { 767*9781SMoriah.Waterland@Sun.COM pkgerr_add(err, PKGERR_WRITE, ERR_WRITE, device, 768*9781SMoriah.Waterland@Sun.COM ERR_error_string(ERR_get_error(), NULL)); 769*9781SMoriah.Waterland@Sun.COM return (1); 770*9781SMoriah.Waterland@Sun.COM } 771*9781SMoriah.Waterland@Sun.COM } 772*9781SMoriah.Waterland@Sun.COM 773*9781SMoriah.Waterland@Sun.COM return (0); 774*9781SMoriah.Waterland@Sun.COM /*NOTREACHED*/ 775*9781SMoriah.Waterland@Sun.COM } 776*9781SMoriah.Waterland@Sun.COM 777*9781SMoriah.Waterland@Sun.COM 778*9781SMoriah.Waterland@Sun.COM /* 779*9781SMoriah.Waterland@Sun.COM * Name: BIO_ds_dump_header 780*9781SMoriah.Waterland@Sun.COM * Description: Dumps all ds_headsize bytes from the 781*9781SMoriah.Waterland@Sun.COM * static 'ds_header_raw' character array 782*9781SMoriah.Waterland@Sun.COM * to the supplied BIO. 783*9781SMoriah.Waterland@Sun.COM * 784*9781SMoriah.Waterland@Sun.COM * Arguments: err - where to record any errors. 785*9781SMoriah.Waterland@Sun.COM * bio - BIO object to dump data into 786*9781SMoriah.Waterland@Sun.COM * 787*9781SMoriah.Waterland@Sun.COM * Returns : zero - successfully dumped all raw 788*9781SMoriah.Waterland@Sun.COM * header characters 789*9781SMoriah.Waterland@Sun.COM * non-zero - some failure occurred. 790*9781SMoriah.Waterland@Sun.COM */ 791*9781SMoriah.Waterland@Sun.COM int 792*9781SMoriah.Waterland@Sun.COM BIO_ds_dump_header(PKG_ERR *err, BIO *bio) 793*9781SMoriah.Waterland@Sun.COM { 794*9781SMoriah.Waterland@Sun.COM 795*9781SMoriah.Waterland@Sun.COM char zeros[BLK_SIZE]; 796*9781SMoriah.Waterland@Sun.COM 797*9781SMoriah.Waterland@Sun.COM memset(zeros, 0, BLK_SIZE); 798*9781SMoriah.Waterland@Sun.COM 799*9781SMoriah.Waterland@Sun.COM if (BIO_write(bio, ds_header_raw, ds_headsize) != ds_headsize) { 800*9781SMoriah.Waterland@Sun.COM pkgerr_add(err, PKGERR_WRITE, ERR_WRITE, "bio", 801*9781SMoriah.Waterland@Sun.COM ERR_error_string(ERR_get_error(), NULL)); 802*9781SMoriah.Waterland@Sun.COM return (1); 803*9781SMoriah.Waterland@Sun.COM } 804*9781SMoriah.Waterland@Sun.COM 805*9781SMoriah.Waterland@Sun.COM return (0); 806*9781SMoriah.Waterland@Sun.COM } 807*9781SMoriah.Waterland@Sun.COM 808*9781SMoriah.Waterland@Sun.COM /* 809*9781SMoriah.Waterland@Sun.COM * ds_ginit: Determine the device being accessed, set the buffer size, 810*9781SMoriah.Waterland@Sun.COM * and perform any device specific initialization. For the 3B2, 811*9781SMoriah.Waterland@Sun.COM * a device with major number of 17 (0x11) is an internal hard disk, 812*9781SMoriah.Waterland@Sun.COM * unless the minor number is 128 (0x80) in which case it is an internal 813*9781SMoriah.Waterland@Sun.COM * floppy disk. Otherwise, get the system configuration 814*9781SMoriah.Waterland@Sun.COM * table and check it by comparing slot numbers to major numbers. 815*9781SMoriah.Waterland@Sun.COM * For the special case of the 3B2 CTC several unusual things must be done. 816*9781SMoriah.Waterland@Sun.COM * To enable 817*9781SMoriah.Waterland@Sun.COM * streaming mode on the CTC, the file descriptor must be closed, re-opened 818*9781SMoriah.Waterland@Sun.COM * (with O_RDWR and O_CTSPECIAL flags set), the STREAMON ioctl(2) command 819*9781SMoriah.Waterland@Sun.COM * issued, and the file descriptor re-re-opened either read-only or write_only. 820*9781SMoriah.Waterland@Sun.COM */ 821*9781SMoriah.Waterland@Sun.COM 822*9781SMoriah.Waterland@Sun.COM int 823*9781SMoriah.Waterland@Sun.COM ds_ginit(char *device) 824*9781SMoriah.Waterland@Sun.COM { 825*9781SMoriah.Waterland@Sun.COM #ifdef u3b2 826*9781SMoriah.Waterland@Sun.COM major_t maj; 827*9781SMoriah.Waterland@Sun.COM minor_t min; 828*9781SMoriah.Waterland@Sun.COM int nflag, i, count, size; 829*9781SMoriah.Waterland@Sun.COM struct s3bconf *buffer; 830*9781SMoriah.Waterland@Sun.COM struct s3bc *table; 831*9781SMoriah.Waterland@Sun.COM struct stat st_buf; 832*9781SMoriah.Waterland@Sun.COM int devtype; 833*9781SMoriah.Waterland@Sun.COM char buf[BLK_SIZE]; 834*9781SMoriah.Waterland@Sun.COM int fd2, fd; 835*9781SMoriah.Waterland@Sun.COM #endif /* u3b2 */ 836*9781SMoriah.Waterland@Sun.COM int oflag; 837*9781SMoriah.Waterland@Sun.COM char *pbufsize, cmd[CMDSIZ]; 838*9781SMoriah.Waterland@Sun.COM int fd2, fd; 839*9781SMoriah.Waterland@Sun.COM 840*9781SMoriah.Waterland@Sun.COM if ((pbufsize = devattr(device, "bufsize")) != NULL) { 841*9781SMoriah.Waterland@Sun.COM ds_bufsize = atoi(pbufsize); 842*9781SMoriah.Waterland@Sun.COM (void) free(pbufsize); 843*9781SMoriah.Waterland@Sun.COM } else 844*9781SMoriah.Waterland@Sun.COM ds_bufsize = BLK_SIZE; 845*9781SMoriah.Waterland@Sun.COM oflag = fcntl(ds_fd, F_GETFL, 0); 846*9781SMoriah.Waterland@Sun.COM #ifdef u3b2 847*9781SMoriah.Waterland@Sun.COM devtype = G_NO_DEV; 848*9781SMoriah.Waterland@Sun.COM if (fstat(ds_fd, &st_buf) == -1) 849*9781SMoriah.Waterland@Sun.COM return (-1); 850*9781SMoriah.Waterland@Sun.COM if (!S_ISCHR(st_buf.st_mode) && !S_ISBLK(st_buf.st_mode)) 851*9781SMoriah.Waterland@Sun.COM goto lab; 852*9781SMoriah.Waterland@Sun.COM 853*9781SMoriah.Waterland@Sun.COM /* 854*9781SMoriah.Waterland@Sun.COM * We'll have to add a remote attribute to stat but this should 855*9781SMoriah.Waterland@Sun.COM * work for now. 856*9781SMoriah.Waterland@Sun.COM */ 857*9781SMoriah.Waterland@Sun.COM else if (st_buf.st_dev & 0x8000) /* if remote rdev */ 858*9781SMoriah.Waterland@Sun.COM goto lab; 859*9781SMoriah.Waterland@Sun.COM 860*9781SMoriah.Waterland@Sun.COM maj = major(st_buf.st_rdev); 861*9781SMoriah.Waterland@Sun.COM min = minor(st_buf.st_rdev); 862*9781SMoriah.Waterland@Sun.COM if (maj == 0x11) { /* internal hard or floppy disk */ 863*9781SMoriah.Waterland@Sun.COM if (min & 0x80) 864*9781SMoriah.Waterland@Sun.COM devtype = G_3B2_FD; /* internal floppy disk */ 865*9781SMoriah.Waterland@Sun.COM else 866*9781SMoriah.Waterland@Sun.COM devtype = G_3B2_HD; /* internal hard disk */ 867*9781SMoriah.Waterland@Sun.COM } else { 868*9781SMoriah.Waterland@Sun.COM if (sys3b(S3BCONF, (struct s3bconf *)&count, sizeof (count)) == 869*9781SMoriah.Waterland@Sun.COM -1) 870*9781SMoriah.Waterland@Sun.COM return (-1); 871*9781SMoriah.Waterland@Sun.COM size = sizeof (int) + (count * sizeof (struct s3bconf)); 872*9781SMoriah.Waterland@Sun.COM buffer = (struct s3bconf *)malloc((unsigned)size); 873*9781SMoriah.Waterland@Sun.COM if (sys3b(S3BCONF, buffer, size) == -1) 874*9781SMoriah.Waterland@Sun.COM return (-1); 875*9781SMoriah.Waterland@Sun.COM table = (struct s3bc *)((char *)buffer + sizeof (int)); 876*9781SMoriah.Waterland@Sun.COM for (i = 0; i < count; i++) { 877*9781SMoriah.Waterland@Sun.COM if (maj == (int)table->board) { 878*9781SMoriah.Waterland@Sun.COM if (strncmp(table->name, "CTC", 3) == 0) { 879*9781SMoriah.Waterland@Sun.COM devtype = G_3B2_CTC; 880*9781SMoriah.Waterland@Sun.COM break; 881*9781SMoriah.Waterland@Sun.COM } else if (strncmp(table->name, "TAPE", 4) 882*9781SMoriah.Waterland@Sun.COM == 0) { 883*9781SMoriah.Waterland@Sun.COM devtype = G_TAPE; 884*9781SMoriah.Waterland@Sun.COM break; 885*9781SMoriah.Waterland@Sun.COM } 886*9781SMoriah.Waterland@Sun.COM /* other possible devices can go here */ 887*9781SMoriah.Waterland@Sun.COM } 888*9781SMoriah.Waterland@Sun.COM table++; 889*9781SMoriah.Waterland@Sun.COM } 890*9781SMoriah.Waterland@Sun.COM } 891*9781SMoriah.Waterland@Sun.COM switch (devtype) { 892*9781SMoriah.Waterland@Sun.COM case G_3B2_CTC: /* do special CTC initialization */ 893*9781SMoriah.Waterland@Sun.COM ds_bufsize = pbufsize ? ds_bufsize : 15872; 894*9781SMoriah.Waterland@Sun.COM if (fstat(ds_fd, &orig_st_buf) < 0) { 895*9781SMoriah.Waterland@Sun.COM ds_bufsize = -1; 896*9781SMoriah.Waterland@Sun.COM break; 897*9781SMoriah.Waterland@Sun.COM } 898*9781SMoriah.Waterland@Sun.COM nflag = (O_RDWR | O_CTSPECIAL); 899*9781SMoriah.Waterland@Sun.COM (void) close(ds_fd); 900*9781SMoriah.Waterland@Sun.COM if ((ds_fd = open(device, nflag, 0666)) != -1) { 901*9781SMoriah.Waterland@Sun.COM if (ioctl(ds_fd, STREAMON) != -1) { 902*9781SMoriah.Waterland@Sun.COM (void) close(ds_fd); 903*9781SMoriah.Waterland@Sun.COM nflag = (oflag == O_WRONLY) ? 904*9781SMoriah.Waterland@Sun.COM O_WRONLY : O_RDONLY; 905*9781SMoriah.Waterland@Sun.COM if ((ds_fd = 906*9781SMoriah.Waterland@Sun.COM open(device, nflag, 0666)) == -1) { 907*9781SMoriah.Waterland@Sun.COM rpterr(); 908*9781SMoriah.Waterland@Sun.COM progerr( 909*9781SMoriah.Waterland@Sun.COM pkg_gt(ERR_TRANSFER)); 910*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_OPEN), 911*9781SMoriah.Waterland@Sun.COM device, errno); 912*9781SMoriah.Waterland@Sun.COM return (-1); 913*9781SMoriah.Waterland@Sun.COM } 914*9781SMoriah.Waterland@Sun.COM ds_bufsize = 15872; 915*9781SMoriah.Waterland@Sun.COM } 916*9781SMoriah.Waterland@Sun.COM } else 917*9781SMoriah.Waterland@Sun.COM ds_bufsize = -1; 918*9781SMoriah.Waterland@Sun.COM if (oflag == O_RDONLY && ds_header && ds_totread == 0) 919*9781SMoriah.Waterland@Sun.COM /* Have already read in first block of header */ 920*9781SMoriah.Waterland@Sun.COM read(ds_fd, buf, BLK_SIZE); 921*9781SMoriah.Waterland@Sun.COM ds_ctcflg = 1; 922*9781SMoriah.Waterland@Sun.COM 923*9781SMoriah.Waterland@Sun.COM break; 924*9781SMoriah.Waterland@Sun.COM case G_NO_DEV: 925*9781SMoriah.Waterland@Sun.COM case G_3B2_HD: 926*9781SMoriah.Waterland@Sun.COM case G_3B2_FD: 927*9781SMoriah.Waterland@Sun.COM case G_TAPE: 928*9781SMoriah.Waterland@Sun.COM case G_SCSI_HD: /* not developed yet */ 929*9781SMoriah.Waterland@Sun.COM case G_SCSI_FD: 930*9781SMoriah.Waterland@Sun.COM case G_SCSI_9T: 931*9781SMoriah.Waterland@Sun.COM case G_SCSI_Q24: 932*9781SMoriah.Waterland@Sun.COM case G_SCSI_Q120: 933*9781SMoriah.Waterland@Sun.COM case G_386_HD: 934*9781SMoriah.Waterland@Sun.COM case G_386_FD: 935*9781SMoriah.Waterland@Sun.COM case G_386_Q24: 936*9781SMoriah.Waterland@Sun.COM ds_bufsize = pbufsize ? ds_bufsize : BLK_SIZE; 937*9781SMoriah.Waterland@Sun.COM break; 938*9781SMoriah.Waterland@Sun.COM default: 939*9781SMoriah.Waterland@Sun.COM ds_bufsize = -1; 940*9781SMoriah.Waterland@Sun.COM errno = ENODEV; 941*9781SMoriah.Waterland@Sun.COM } /* devtype */ 942*9781SMoriah.Waterland@Sun.COM lab: 943*9781SMoriah.Waterland@Sun.COM #endif /* u3b2 */ 944*9781SMoriah.Waterland@Sun.COM if (ds_bufsize > BLK_SIZE) { 945*9781SMoriah.Waterland@Sun.COM if (oflag & O_WRONLY) 946*9781SMoriah.Waterland@Sun.COM fd = 1; 947*9781SMoriah.Waterland@Sun.COM else 948*9781SMoriah.Waterland@Sun.COM fd = 0; 949*9781SMoriah.Waterland@Sun.COM fd2 = fcntl(fd, F_DUPFD, fd); 950*9781SMoriah.Waterland@Sun.COM (void) close(fd); 951*9781SMoriah.Waterland@Sun.COM fcntl(ds_fd, F_DUPFD, fd); 952*9781SMoriah.Waterland@Sun.COM if (fd) 953*9781SMoriah.Waterland@Sun.COM sprintf(cmd, "%s obs=%d 2>/dev/null", DDPROC, 954*9781SMoriah.Waterland@Sun.COM ds_bufsize); 955*9781SMoriah.Waterland@Sun.COM else 956*9781SMoriah.Waterland@Sun.COM sprintf(cmd, "%s ibs=%d 2>/dev/null", DDPROC, 957*9781SMoriah.Waterland@Sun.COM ds_bufsize); 958*9781SMoriah.Waterland@Sun.COM if ((ds_pp = popen(cmd, fd ? "w" : "r")) == NULL) { 959*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_TRANSFER)); 960*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_POPEN), cmd, errno); 961*9781SMoriah.Waterland@Sun.COM return (-1); 962*9781SMoriah.Waterland@Sun.COM } 963*9781SMoriah.Waterland@Sun.COM (void) close(fd); 964*9781SMoriah.Waterland@Sun.COM fcntl(fd2, F_DUPFD, fd); 965*9781SMoriah.Waterland@Sun.COM (void) close(fd2); 966*9781SMoriah.Waterland@Sun.COM ds_realfd = ds_fd; 967*9781SMoriah.Waterland@Sun.COM ds_fd = fileno(ds_pp); 968*9781SMoriah.Waterland@Sun.COM } 969*9781SMoriah.Waterland@Sun.COM return (ds_bufsize); 970*9781SMoriah.Waterland@Sun.COM } 971*9781SMoriah.Waterland@Sun.COM 972*9781SMoriah.Waterland@Sun.COM int 973*9781SMoriah.Waterland@Sun.COM ds_close(int pkgendflg) 974*9781SMoriah.Waterland@Sun.COM { 975*9781SMoriah.Waterland@Sun.COM #ifdef u3b2 976*9781SMoriah.Waterland@Sun.COM int cnt, mode; 977*9781SMoriah.Waterland@Sun.COM char *ptr; 978*9781SMoriah.Waterland@Sun.COM struct stat statbuf; 979*9781SMoriah.Waterland@Sun.COM #endif /* u3b2 */ 980*9781SMoriah.Waterland@Sun.COM int n, ret = 0; 981*9781SMoriah.Waterland@Sun.COM 982*9781SMoriah.Waterland@Sun.COM #ifdef u3b2 983*9781SMoriah.Waterland@Sun.COM if (ds_pp && ds_ctcflg) { 984*9781SMoriah.Waterland@Sun.COM ds_ctcflg = 0; 985*9781SMoriah.Waterland@Sun.COM if ((mode = fcntl(ds_realfd, F_GETFL, 0)) < 0) { 986*9781SMoriah.Waterland@Sun.COM ret = -1; 987*9781SMoriah.Waterland@Sun.COM } else if (mode & O_WRONLY) { 988*9781SMoriah.Waterland@Sun.COM /* 989*9781SMoriah.Waterland@Sun.COM * pipe to dd write process, 990*9781SMoriah.Waterland@Sun.COM * make sure one more buffer 991*9781SMoriah.Waterland@Sun.COM * gets written out 992*9781SMoriah.Waterland@Sun.COM */ 993*9781SMoriah.Waterland@Sun.COM if ((ptr = calloc(BLK_SIZE, 1)) == NULL) { 994*9781SMoriah.Waterland@Sun.COM ret = -1; 995*9781SMoriah.Waterland@Sun.COM /* pad to bufsize */ 996*9781SMoriah.Waterland@Sun.COM } else { 997*9781SMoriah.Waterland@Sun.COM cnt = ds_bufsize; 998*9781SMoriah.Waterland@Sun.COM while (cnt > 0) { 999*9781SMoriah.Waterland@Sun.COM if ((n = write(ds_fd, ptr, 1000*9781SMoriah.Waterland@Sun.COM BLK_SIZE)) < 0) { 1001*9781SMoriah.Waterland@Sun.COM ret = -1; 1002*9781SMoriah.Waterland@Sun.COM break; 1003*9781SMoriah.Waterland@Sun.COM } 1004*9781SMoriah.Waterland@Sun.COM cnt -= n; 1005*9781SMoriah.Waterland@Sun.COM } 1006*9781SMoriah.Waterland@Sun.COM (void) free(ptr); 1007*9781SMoriah.Waterland@Sun.COM } 1008*9781SMoriah.Waterland@Sun.COM } 1009*9781SMoriah.Waterland@Sun.COM } 1010*9781SMoriah.Waterland@Sun.COM #endif 1011*9781SMoriah.Waterland@Sun.COM if (pkgendflg) { 1012*9781SMoriah.Waterland@Sun.COM if (ds_header) 1013*9781SMoriah.Waterland@Sun.COM (void) free(ds_header); 1014*9781SMoriah.Waterland@Sun.COM ds_header = (char *)NULL; 1015*9781SMoriah.Waterland@Sun.COM ds_totread = 0; 1016*9781SMoriah.Waterland@Sun.COM } 1017*9781SMoriah.Waterland@Sun.COM 1018*9781SMoriah.Waterland@Sun.COM if (ds_pp) { 1019*9781SMoriah.Waterland@Sun.COM (void) pclose(ds_pp); 1020*9781SMoriah.Waterland@Sun.COM ds_pp = 0; 1021*9781SMoriah.Waterland@Sun.COM (void) close(ds_realfd); 1022*9781SMoriah.Waterland@Sun.COM ds_realfd = -1; 1023*9781SMoriah.Waterland@Sun.COM ds_fd = -1; 1024*9781SMoriah.Waterland@Sun.COM } else if (ds_fd >= 0) { 1025*9781SMoriah.Waterland@Sun.COM (void) close(ds_fd); 1026*9781SMoriah.Waterland@Sun.COM ds_fd = -1; 1027*9781SMoriah.Waterland@Sun.COM } 1028*9781SMoriah.Waterland@Sun.COM 1029*9781SMoriah.Waterland@Sun.COM if (ds_device) { 1030*9781SMoriah.Waterland@Sun.COM /* rewind device */ 1031*9781SMoriah.Waterland@Sun.COM if ((n = open(ds_device, 0)) >= 0) 1032*9781SMoriah.Waterland@Sun.COM (void) close(n); 1033*9781SMoriah.Waterland@Sun.COM ds_device = NULL; 1034*9781SMoriah.Waterland@Sun.COM } 1035*9781SMoriah.Waterland@Sun.COM return (ret); 1036*9781SMoriah.Waterland@Sun.COM } 1037