15c51f124SMoriah Waterland /*
25c51f124SMoriah Waterland * CDDL HEADER START
35c51f124SMoriah Waterland *
45c51f124SMoriah Waterland * The contents of this file are subject to the terms of the
55c51f124SMoriah Waterland * Common Development and Distribution License (the "License").
65c51f124SMoriah Waterland * You may not use this file except in compliance with the License.
75c51f124SMoriah Waterland *
85c51f124SMoriah Waterland * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
95c51f124SMoriah Waterland * or http://www.opensolaris.org/os/licensing.
105c51f124SMoriah Waterland * See the License for the specific language governing permissions
115c51f124SMoriah Waterland * and limitations under the License.
125c51f124SMoriah Waterland *
135c51f124SMoriah Waterland * When distributing Covered Code, include this CDDL HEADER in each
145c51f124SMoriah Waterland * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
155c51f124SMoriah Waterland * If applicable, add the following below this CDDL HEADER, with the
165c51f124SMoriah Waterland * fields enclosed by brackets "[]" replaced with your own identifying
175c51f124SMoriah Waterland * information: Portions Copyright [yyyy] [name of copyright owner]
185c51f124SMoriah Waterland *
195c51f124SMoriah Waterland * CDDL HEADER END
205c51f124SMoriah Waterland */
215c51f124SMoriah Waterland
225c51f124SMoriah Waterland /*
235c51f124SMoriah Waterland * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
245c51f124SMoriah Waterland * Use is subject to license terms.
255c51f124SMoriah Waterland */
265c51f124SMoriah Waterland
275c51f124SMoriah Waterland /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
285c51f124SMoriah Waterland /* All Rights Reserved */
295c51f124SMoriah Waterland
305c51f124SMoriah Waterland
315c51f124SMoriah Waterland
325c51f124SMoriah Waterland #include <stdio.h>
335c51f124SMoriah Waterland #include <string.h>
345c51f124SMoriah Waterland #include <signal.h>
355c51f124SMoriah Waterland #include <stdlib.h>
365c51f124SMoriah Waterland #include <unistd.h>
375c51f124SMoriah Waterland #include <sys/types.h>
385c51f124SMoriah Waterland #include <sys/param.h>
395c51f124SMoriah Waterland #include <sys/sysmacros.h>
405c51f124SMoriah Waterland #include <errno.h>
415c51f124SMoriah Waterland #include <sys/types.h>
425c51f124SMoriah Waterland #include <sys/stat.h>
435c51f124SMoriah Waterland #include <sys/statvfs.h>
445c51f124SMoriah Waterland #include <fcntl.h>
455c51f124SMoriah Waterland #include <openssl/err.h>
465c51f124SMoriah Waterland #include "pkglib.h"
475c51f124SMoriah Waterland #include "pkglibmsgs.h"
485c51f124SMoriah Waterland #include "pkglocale.h"
495c51f124SMoriah Waterland
505c51f124SMoriah Waterland /* libadm.a */
515c51f124SMoriah Waterland extern char *devattr(char *device, char *attribute);
525c51f124SMoriah Waterland extern int pkgnmchk(register char *pkg, register char *spec,
535c51f124SMoriah Waterland int presvr4flg);
545c51f124SMoriah Waterland extern int getvol(char *device, char *label, int options, char *prompt);
555c51f124SMoriah Waterland
565c51f124SMoriah Waterland #define CMDSIZ 512
575c51f124SMoriah Waterland #define LSIZE 128
585c51f124SMoriah Waterland #define DDPROC "/usr/bin/dd"
595c51f124SMoriah Waterland #define CPIOPROC "/usr/bin/cpio"
605c51f124SMoriah Waterland
615c51f124SMoriah Waterland /* device types */
625c51f124SMoriah Waterland
635c51f124SMoriah Waterland #define G_TM_TAPE 1 /* Tapemaster controller */
645c51f124SMoriah Waterland #define G_XY_DISK 3 /* xy disks */
655c51f124SMoriah Waterland #define G_SD_DISK 7 /* scsi sd disk */
665c51f124SMoriah Waterland #define G_XT_TAPE 8 /* xt tapes */
675c51f124SMoriah Waterland #define G_SF_FLOPPY 9 /* sf floppy */
685c51f124SMoriah Waterland #define G_XD_DISK 10 /* xd disks */
695c51f124SMoriah Waterland #define G_ST_TAPE 11 /* scsi tape */
705c51f124SMoriah Waterland #define G_NS 12 /* noswap pseudo-dev */
715c51f124SMoriah Waterland #define G_RAM 13 /* ram pseudo-dev */
725c51f124SMoriah Waterland #define G_FT 14 /* tftp */
735c51f124SMoriah Waterland #define G_HD 15 /* 386 network disk */
745c51f124SMoriah Waterland #define G_FD 16 /* 386 AT disk */
755c51f124SMoriah Waterland #define G_FILE 28 /* file, not a device */
765c51f124SMoriah Waterland #define G_NO_DEV 29 /* device does not require special treatment */
775c51f124SMoriah Waterland #define G_DEV_MAX 30 /* last valid device type */
785c51f124SMoriah Waterland
795c51f124SMoriah Waterland struct dstoc {
805c51f124SMoriah Waterland int cnt;
815c51f124SMoriah Waterland char pkg[NON_ABI_NAMELNGTH];
825c51f124SMoriah Waterland int nparts;
835c51f124SMoriah Waterland long maxsiz;
845c51f124SMoriah Waterland char volnos[128];
855c51f124SMoriah Waterland struct dstoc *next;
865c51f124SMoriah Waterland } *ds_head, *ds_toc;
875c51f124SMoriah Waterland
885c51f124SMoriah Waterland #define ds_nparts ds_toc->nparts
895c51f124SMoriah Waterland #define ds_maxsiz ds_toc->maxsiz
905c51f124SMoriah Waterland
915c51f124SMoriah Waterland int ds_totread; /* total number of parts read */
925c51f124SMoriah Waterland int ds_fd = -1;
935c51f124SMoriah Waterland int ds_curpartcnt = -1;
945c51f124SMoriah Waterland
955c51f124SMoriah Waterland int ds_next(char *device, char *instdir);
965c51f124SMoriah Waterland int ds_ginit(char *device);
975c51f124SMoriah Waterland int ds_close(int pkgendflg);
985c51f124SMoriah Waterland
995c51f124SMoriah Waterland static FILE *ds_pp;
1005c51f124SMoriah Waterland static int ds_realfd = -1; /* file descriptor for real device */
1015c51f124SMoriah Waterland static int ds_read; /* number of parts read for current package */
1025c51f124SMoriah Waterland static int ds_volno; /* volume number of current volume */
1035c51f124SMoriah Waterland static int ds_volcnt; /* total number of volumes */
1045c51f124SMoriah Waterland static char ds_volnos[128]; /* parts/volume info */
1055c51f124SMoriah Waterland static char *ds_device;
1065c51f124SMoriah Waterland static int ds_volpart; /* number of parts read in current volume, */
1075c51f124SMoriah Waterland /* including skipped parts */
1085c51f124SMoriah Waterland static int ds_bufsize;
1095c51f124SMoriah Waterland static int ds_skippart; /* number of parts skipped in current volume */
1105c51f124SMoriah Waterland
1115c51f124SMoriah Waterland static int ds_getnextvol(char *device);
1125c51f124SMoriah Waterland static int ds_skip(char *device, int nskip);
1135c51f124SMoriah Waterland
1145c51f124SMoriah Waterland void
ds_order(char * list[])1155c51f124SMoriah Waterland ds_order(char *list[])
1165c51f124SMoriah Waterland {
1175c51f124SMoriah Waterland struct dstoc *toc_pt;
1185c51f124SMoriah Waterland register int j, n;
1195c51f124SMoriah Waterland char *pt;
1205c51f124SMoriah Waterland
1215c51f124SMoriah Waterland toc_pt = ds_head;
1225c51f124SMoriah Waterland n = 0;
1235c51f124SMoriah Waterland while (toc_pt) {
1245c51f124SMoriah Waterland for (j = n; list[j]; j++) {
1255c51f124SMoriah Waterland if (strcmp(list[j], toc_pt->pkg) == 0) {
1265c51f124SMoriah Waterland /* just swap places in the array */
1275c51f124SMoriah Waterland pt = list[n];
1285c51f124SMoriah Waterland list[n++] = list[j];
1295c51f124SMoriah Waterland list[j] = pt;
1305c51f124SMoriah Waterland }
1315c51f124SMoriah Waterland }
1325c51f124SMoriah Waterland toc_pt = toc_pt->next;
1335c51f124SMoriah Waterland }
1345c51f124SMoriah Waterland }
1355c51f124SMoriah Waterland
1365c51f124SMoriah Waterland static char *pds_header;
1375c51f124SMoriah Waterland static char *ds_header;
1385c51f124SMoriah Waterland static char *ds_header_raw;
1395c51f124SMoriah Waterland static int ds_headsize;
1405c51f124SMoriah Waterland
1415c51f124SMoriah Waterland static char *
ds_gets(char * buf,int size)1425c51f124SMoriah Waterland ds_gets(char *buf, int size)
1435c51f124SMoriah Waterland {
1445c51f124SMoriah Waterland int length;
1455c51f124SMoriah Waterland char *nextp;
1465c51f124SMoriah Waterland
1475c51f124SMoriah Waterland nextp = strchr(pds_header, '\n');
1485c51f124SMoriah Waterland if (nextp == NULL) {
1495c51f124SMoriah Waterland length = strlen(pds_header);
1505c51f124SMoriah Waterland if (length > size)
1515c51f124SMoriah Waterland return (0);
1525c51f124SMoriah Waterland if ((ds_header = (char *)realloc(ds_header,
1535c51f124SMoriah Waterland ds_headsize + BLK_SIZE)) == NULL)
1545c51f124SMoriah Waterland return (0);
1555c51f124SMoriah Waterland if (read(ds_fd, ds_header + ds_headsize, BLK_SIZE) < BLK_SIZE)
1565c51f124SMoriah Waterland return (0);
1575c51f124SMoriah Waterland ds_headsize += BLK_SIZE;
1585c51f124SMoriah Waterland nextp = strchr(pds_header, '\n');
1595c51f124SMoriah Waterland if (nextp == NULL)
1605c51f124SMoriah Waterland return (0);
1615c51f124SMoriah Waterland *nextp = '\0';
1625c51f124SMoriah Waterland if (length + (int)strlen(pds_header) > size)
1635c51f124SMoriah Waterland return (0);
1645c51f124SMoriah Waterland (void) strncpy(buf + length, pds_header, strlen(pds_header));
1655c51f124SMoriah Waterland buf[length + strlen(pds_header)] = '\0';
1665c51f124SMoriah Waterland pds_header = nextp + 1;
1675c51f124SMoriah Waterland return (buf);
1685c51f124SMoriah Waterland }
1695c51f124SMoriah Waterland *nextp = '\0';
1705c51f124SMoriah Waterland if ((int)strlen(pds_header) > size)
1715c51f124SMoriah Waterland return (0);
1725c51f124SMoriah Waterland (void) strncpy(buf, pds_header, strlen(pds_header));
1735c51f124SMoriah Waterland buf[strlen(pds_header)] = '\0';
1745c51f124SMoriah Waterland pds_header = nextp + 1;
1755c51f124SMoriah Waterland return (buf);
1765c51f124SMoriah Waterland }
1775c51f124SMoriah Waterland
1785c51f124SMoriah Waterland /*
1795c51f124SMoriah Waterland * function to determine if media is datastream or mounted
1805c51f124SMoriah Waterland * floppy
1815c51f124SMoriah Waterland */
1825c51f124SMoriah Waterland int
ds_readbuf(char * device)1835c51f124SMoriah Waterland ds_readbuf(char *device)
1845c51f124SMoriah Waterland {
1855c51f124SMoriah Waterland char buf[BLK_SIZE];
1865c51f124SMoriah Waterland
1875c51f124SMoriah Waterland if (ds_fd >= 0)
1885c51f124SMoriah Waterland (void) close(ds_fd);
1895c51f124SMoriah Waterland if ((ds_fd = open(device, O_RDONLY)) >= 0 &&
1905c51f124SMoriah Waterland read(ds_fd, buf, BLK_SIZE) == BLK_SIZE &&
1915c51f124SMoriah Waterland strncmp(buf, HDR_PREFIX, 20) == 0) {
1925c51f124SMoriah Waterland if ((ds_header = (char *)calloc(BLK_SIZE, 1)) == NULL) {
1935c51f124SMoriah Waterland progerr(pkg_gt(ERR_UNPACK));
1945c51f124SMoriah Waterland logerr(pkg_gt(MSG_MEM));
1955c51f124SMoriah Waterland (void) ds_close(0);
1965c51f124SMoriah Waterland return (0);
1975c51f124SMoriah Waterland }
198*4656d474SGarrett D'Amore (void) memcpy(ds_header, buf, BLK_SIZE);
1995c51f124SMoriah Waterland ds_headsize = BLK_SIZE;
2005c51f124SMoriah Waterland
2015c51f124SMoriah Waterland if (ds_ginit(device) < 0) {
2025c51f124SMoriah Waterland progerr(pkg_gt(ERR_UNPACK));
2035c51f124SMoriah Waterland logerr(pkg_gt(MSG_OPEN), device, errno);
2045c51f124SMoriah Waterland (void) ds_close(0);
2055c51f124SMoriah Waterland return (0);
2065c51f124SMoriah Waterland }
2075c51f124SMoriah Waterland return (1);
2085c51f124SMoriah Waterland } else if (ds_fd >= 0) {
2095c51f124SMoriah Waterland (void) close(ds_fd);
2105c51f124SMoriah Waterland ds_fd = -1;
2115c51f124SMoriah Waterland }
2125c51f124SMoriah Waterland return (0);
2135c51f124SMoriah Waterland }
2145c51f124SMoriah Waterland
2155c51f124SMoriah Waterland /*
2165c51f124SMoriah Waterland * Determine how many additional volumes are needed for current package.
2175c51f124SMoriah Waterland * Note: a 0 will occur as first volume number when the package begins
2185c51f124SMoriah Waterland * on the next volume.
2195c51f124SMoriah Waterland */
2205c51f124SMoriah Waterland static int
ds_volsum(struct dstoc * toc)2215c51f124SMoriah Waterland ds_volsum(struct dstoc *toc)
2225c51f124SMoriah Waterland {
2235c51f124SMoriah Waterland int curpartcnt, volcnt;
2245c51f124SMoriah Waterland char volnos[128], tmpvol[128];
2255c51f124SMoriah Waterland if (toc->volnos[0]) {
2265c51f124SMoriah Waterland int index, sum;
227*4656d474SGarrett D'Amore (void) sscanf(toc->volnos, "%d %[ 0-9]", &curpartcnt, volnos);
2285c51f124SMoriah Waterland volcnt = 0;
2295c51f124SMoriah Waterland sum = curpartcnt;
2305c51f124SMoriah Waterland while (sum < toc->nparts && sscanf(volnos, "%d %[ 0-9]",
2315c51f124SMoriah Waterland &index, tmpvol) >= 1) {
2325c51f124SMoriah Waterland (void) strcpy(volnos, tmpvol);
2335c51f124SMoriah Waterland volcnt++;
2345c51f124SMoriah Waterland sum += index;
2355c51f124SMoriah Waterland }
2365c51f124SMoriah Waterland /* side effect - set number of parts read on current volume */
2375c51f124SMoriah Waterland ds_volpart = index;
2385c51f124SMoriah Waterland return (volcnt);
2395c51f124SMoriah Waterland }
2405c51f124SMoriah Waterland ds_volpart += toc->nparts;
2415c51f124SMoriah Waterland return (0);
2425c51f124SMoriah Waterland }
2435c51f124SMoriah Waterland
2445c51f124SMoriah Waterland /* initialize ds_curpartcnt and ds_volnos */
2455c51f124SMoriah Waterland static void
ds_pkginit(void)2465c51f124SMoriah Waterland ds_pkginit(void)
2475c51f124SMoriah Waterland {
2485c51f124SMoriah Waterland if (ds_toc->volnos[0])
249*4656d474SGarrett D'Amore (void) sscanf(ds_toc->volnos, "%d %[ 0-9]", &ds_curpartcnt,
250*4656d474SGarrett D'Amore ds_volnos);
2515c51f124SMoriah Waterland else
2525c51f124SMoriah Waterland ds_curpartcnt = -1;
2535c51f124SMoriah Waterland }
2545c51f124SMoriah Waterland
2555c51f124SMoriah Waterland /*
2565c51f124SMoriah Waterland * functions to pass current package info to exec'ed program
2575c51f124SMoriah Waterland */
2585c51f124SMoriah Waterland void
ds_putinfo(char * buf,size_t sz)259*4656d474SGarrett D'Amore ds_putinfo(char *buf, size_t sz)
2605c51f124SMoriah Waterland {
261*4656d474SGarrett D'Amore (void) snprintf(buf, sz, "%d %d %d %d %d %d %d %d %d %d %s",
2625c51f124SMoriah Waterland ds_fd, ds_realfd, ds_volcnt, ds_volno, ds_totread, ds_volpart,
2635c51f124SMoriah Waterland ds_skippart, ds_bufsize, ds_toc->nparts, ds_toc->maxsiz,
2645c51f124SMoriah Waterland ds_toc->volnos);
2655c51f124SMoriah Waterland }
2665c51f124SMoriah Waterland
2675c51f124SMoriah Waterland int
ds_getinfo(char * string)2685c51f124SMoriah Waterland ds_getinfo(char *string)
2695c51f124SMoriah Waterland {
2705c51f124SMoriah Waterland ds_toc = (struct dstoc *)calloc(1, sizeof (struct dstoc));
2715c51f124SMoriah Waterland (void) sscanf(string, "%d %d %d %d %d %d %d %d %d %d %[ 0-9]",
2725c51f124SMoriah Waterland &ds_fd, &ds_realfd, &ds_volcnt, &ds_volno, &ds_totread,
2735c51f124SMoriah Waterland &ds_volpart, &ds_skippart, &ds_bufsize, &ds_toc->nparts,
2745c51f124SMoriah Waterland &ds_toc->maxsiz, ds_toc->volnos);
2755c51f124SMoriah Waterland ds_pkginit();
2765c51f124SMoriah Waterland return (ds_toc->nparts);
2775c51f124SMoriah Waterland }
2785c51f124SMoriah Waterland
2795c51f124SMoriah Waterland /*
2805c51f124SMoriah Waterland * Return true if the file descriptor (ds_fd) is open on the package stream.
2815c51f124SMoriah Waterland */
2825c51f124SMoriah Waterland boolean_t
ds_fd_open(void)2835c51f124SMoriah Waterland ds_fd_open(void)
2845c51f124SMoriah Waterland {
2855c51f124SMoriah Waterland return (ds_fd >= 0 ? B_TRUE : B_FALSE);
2865c51f124SMoriah Waterland }
2875c51f124SMoriah Waterland
2885c51f124SMoriah Waterland /*
2895c51f124SMoriah Waterland * Read the source device. Acquire the header data and check it for validity.
2905c51f124SMoriah Waterland */
2915c51f124SMoriah Waterland int
ds_init(char * device,char ** pkg,char * norewind)2925c51f124SMoriah Waterland ds_init(char *device, char **pkg, char *norewind)
2935c51f124SMoriah Waterland {
2945c51f124SMoriah Waterland struct dstoc *tail, *toc_pt;
2955c51f124SMoriah Waterland char *ret;
2965c51f124SMoriah Waterland char cmd[CMDSIZ];
2975c51f124SMoriah Waterland char line[LSIZE+1];
2985c51f124SMoriah Waterland int i, n, count = 0, header_size = BLK_SIZE;
2995c51f124SMoriah Waterland
3005c51f124SMoriah Waterland if (!ds_header) { /* If the header hasn't been read yet */
3015c51f124SMoriah Waterland if (ds_fd >= 0)
3025c51f124SMoriah Waterland (void) ds_close(0);
3035c51f124SMoriah Waterland
3045c51f124SMoriah Waterland /* always start with rewind device */
3055c51f124SMoriah Waterland if ((ds_fd = open(device, O_RDONLY)) < 0) {
3065c51f124SMoriah Waterland progerr(pkg_gt(ERR_UNPACK));
3075c51f124SMoriah Waterland logerr(pkg_gt(MSG_OPEN), device, errno);
3085c51f124SMoriah Waterland return (-1);
3095c51f124SMoriah Waterland }
3105c51f124SMoriah Waterland
3115c51f124SMoriah Waterland /* allocate room for the header equivalent to a block */
3125c51f124SMoriah Waterland if ((ds_header = (char *)calloc(BLK_SIZE, 1)) == NULL) {
3135c51f124SMoriah Waterland progerr(pkg_gt(ERR_UNPACK));
3145c51f124SMoriah Waterland logerr(pkg_gt(MSG_MEM));
3155c51f124SMoriah Waterland return (-1);
3165c51f124SMoriah Waterland }
3175c51f124SMoriah Waterland
3185c51f124SMoriah Waterland /* initialize the device */
3195c51f124SMoriah Waterland if (ds_ginit(device) < 0) {
3205c51f124SMoriah Waterland (void) ds_close(0);
3215c51f124SMoriah Waterland progerr(pkg_gt(ERR_UNPACK));
3225c51f124SMoriah Waterland logerr(pkg_gt(MSG_OPEN), device, errno);
3235c51f124SMoriah Waterland return (-1);
3245c51f124SMoriah Waterland }
3255c51f124SMoriah Waterland
3265c51f124SMoriah Waterland /* read a logical block from the source device */
3275c51f124SMoriah Waterland if (read(ds_fd, ds_header, BLK_SIZE) != BLK_SIZE) {
3285c51f124SMoriah Waterland rpterr();
3295c51f124SMoriah Waterland progerr(pkg_gt(ERR_UNPACK));
3305c51f124SMoriah Waterland logerr(pkg_gt(MSG_TOC));
3315c51f124SMoriah Waterland (void) ds_close(0);
3325c51f124SMoriah Waterland return (-1);
3335c51f124SMoriah Waterland }
3345c51f124SMoriah Waterland
3355c51f124SMoriah Waterland /*
3365c51f124SMoriah Waterland * This loop scans the medium for the start of the header.
3375c51f124SMoriah Waterland * If the above read worked, we skip this. If it did't, this
3385c51f124SMoriah Waterland * loop will retry the read ten times looking for the header
3395c51f124SMoriah Waterland * marker string.
3405c51f124SMoriah Waterland */
3415c51f124SMoriah Waterland while (strncmp(ds_header, HDR_PREFIX, 20) != 0) {
3425c51f124SMoriah Waterland /* only ten tries iff the device rewinds */
3435c51f124SMoriah Waterland if (!norewind || count++ > 10) {
3445c51f124SMoriah Waterland progerr(pkg_gt(ERR_UNPACK));
3455c51f124SMoriah Waterland logerr(pkg_gt(MSG_TOC));
3465c51f124SMoriah Waterland (void) ds_close(0);
3475c51f124SMoriah Waterland return (-1);
3485c51f124SMoriah Waterland }
3495c51f124SMoriah Waterland
3505c51f124SMoriah Waterland /* read through to the last block */
3515c51f124SMoriah Waterland if (count > 1)
3525c51f124SMoriah Waterland while (read(ds_fd, ds_header, BLK_SIZE) > 0)
3535c51f124SMoriah Waterland ;
3545c51f124SMoriah Waterland
3555c51f124SMoriah Waterland /* then close the device */
3565c51f124SMoriah Waterland (void) ds_close(0);
3575c51f124SMoriah Waterland
3585c51f124SMoriah Waterland /* and reopen it */
3595c51f124SMoriah Waterland if ((ds_fd = open(norewind, O_RDONLY)) < 0) {
3605c51f124SMoriah Waterland progerr(pkg_gt(ERR_UNPACK));
3615c51f124SMoriah Waterland logerr(pkg_gt(MSG_OPEN), device, errno);
3625c51f124SMoriah Waterland (void) free(ds_header);
3635c51f124SMoriah Waterland return (-1);
3645c51f124SMoriah Waterland }
3655c51f124SMoriah Waterland
3665c51f124SMoriah Waterland /* initialize the device */
3675c51f124SMoriah Waterland if (ds_ginit(device) < 0) {
3685c51f124SMoriah Waterland (void) ds_close(0);
3695c51f124SMoriah Waterland progerr(pkg_gt(ERR_UNPACK));
3705c51f124SMoriah Waterland logerr(pkg_gt(MSG_OPEN), device, errno);
3715c51f124SMoriah Waterland return (-1);
3725c51f124SMoriah Waterland }
3735c51f124SMoriah Waterland
3745c51f124SMoriah Waterland /* read the block again */
3755c51f124SMoriah Waterland if (read(ds_fd, ds_header, BLK_SIZE) != BLK_SIZE) {
3765c51f124SMoriah Waterland rpterr();
3775c51f124SMoriah Waterland progerr(pkg_gt(ERR_UNPACK));
3785c51f124SMoriah Waterland logerr(pkg_gt(MSG_TOC));
3795c51f124SMoriah Waterland (void) ds_close(0);
3805c51f124SMoriah Waterland return (-1);
3815c51f124SMoriah Waterland }
3825c51f124SMoriah Waterland }
3835c51f124SMoriah Waterland
3845c51f124SMoriah Waterland /* Now keep scanning until the whole header is in place. */
3855c51f124SMoriah Waterland while (strstr(ds_header, HDR_SUFFIX) == NULL) {
3865c51f124SMoriah Waterland /* We need a bigger buffer */
3875c51f124SMoriah Waterland if ((ds_header = (char *)realloc(ds_header,
3885c51f124SMoriah Waterland header_size + BLK_SIZE)) == NULL) {
3895c51f124SMoriah Waterland progerr(pkg_gt(ERR_UNPACK));
3905c51f124SMoriah Waterland logerr(pkg_gt(MSG_MEM));
3915c51f124SMoriah Waterland (void) ds_close(0);
3925c51f124SMoriah Waterland return (1);
3935c51f124SMoriah Waterland }
3945c51f124SMoriah Waterland
3955c51f124SMoriah Waterland /* clear the new memory */
3965c51f124SMoriah Waterland (void) memset(ds_header + header_size, '\0',
3975c51f124SMoriah Waterland BLK_SIZE);
3985c51f124SMoriah Waterland
3995c51f124SMoriah Waterland
4005c51f124SMoriah Waterland /* read a logical block from the source device */
4015c51f124SMoriah Waterland if (read(ds_fd, ds_header + header_size, BLK_SIZE) !=
4025c51f124SMoriah Waterland BLK_SIZE) {
4035c51f124SMoriah Waterland rpterr();
4045c51f124SMoriah Waterland progerr(pkg_gt(ERR_UNPACK));
4055c51f124SMoriah Waterland logerr(pkg_gt(MSG_TOC));
4065c51f124SMoriah Waterland (void) ds_close(0);
4075c51f124SMoriah Waterland return (-1);
4085c51f124SMoriah Waterland } else
4095c51f124SMoriah Waterland header_size += BLK_SIZE; /* new size */
4105c51f124SMoriah Waterland }
4115c51f124SMoriah Waterland
4125c51f124SMoriah Waterland /*
4135c51f124SMoriah Waterland * remember rewind device for ds_close to rewind at
4145c51f124SMoriah Waterland * close
4155c51f124SMoriah Waterland */
4165c51f124SMoriah Waterland if (count >= 1)
4175c51f124SMoriah Waterland ds_device = device;
4185c51f124SMoriah Waterland ds_headsize = header_size;
4195c51f124SMoriah Waterland
4205c51f124SMoriah Waterland }
4215c51f124SMoriah Waterland
4225c51f124SMoriah Waterland pds_header = ds_header;
4235c51f124SMoriah Waterland
4245c51f124SMoriah Waterland /* save raw copy of header for later use in BIO_dump_header */
4255c51f124SMoriah Waterland if ((ds_header_raw = (char *)malloc(header_size)) == NULL) {
4265c51f124SMoriah Waterland progerr(pkg_gt(ERR_UNPACK));
4275c51f124SMoriah Waterland logerr(pkg_gt(MSG_MEM));
4285c51f124SMoriah Waterland (void) ds_close(0);
4295c51f124SMoriah Waterland return (1);
4305c51f124SMoriah Waterland }
431*4656d474SGarrett D'Amore (void) memcpy(ds_header_raw, ds_header, header_size);
4325c51f124SMoriah Waterland
4335c51f124SMoriah Waterland /* read datastream table of contents */
4345c51f124SMoriah Waterland ds_head = tail = (struct dstoc *)0;
4355c51f124SMoriah Waterland ds_volcnt = 1;
4365c51f124SMoriah Waterland
4375c51f124SMoriah Waterland while (ret = ds_gets(line, LSIZE)) {
4385c51f124SMoriah Waterland if (strcmp(line, HDR_SUFFIX) == 0)
4395c51f124SMoriah Waterland break;
4405c51f124SMoriah Waterland if (!line[0] || line[0] == '#')
4415c51f124SMoriah Waterland continue;
4425c51f124SMoriah Waterland toc_pt = (struct dstoc *)calloc(1, sizeof (struct dstoc));
4435c51f124SMoriah Waterland if (!toc_pt) {
4445c51f124SMoriah Waterland progerr(pkg_gt(ERR_UNPACK));
4455c51f124SMoriah Waterland logerr(pkg_gt(MSG_MEM));
4465c51f124SMoriah Waterland ecleanup();
4475c51f124SMoriah Waterland (void) free(ds_header);
4485c51f124SMoriah Waterland return (-1);
4495c51f124SMoriah Waterland }
450*4656d474SGarrett D'Amore /* LINTED E_SEC_SCANF_UNBOUNDED_COPY */
4515c51f124SMoriah Waterland if (sscanf(line, "%s %d %d %[ 0-9]", toc_pt->pkg,
4525c51f124SMoriah Waterland &toc_pt->nparts, &toc_pt->maxsiz, toc_pt->volnos) < 3) {
4535c51f124SMoriah Waterland progerr(pkg_gt(ERR_UNPACK));
4545c51f124SMoriah Waterland logerr(pkg_gt(MSG_TOC));
4555c51f124SMoriah Waterland free(toc_pt);
4565c51f124SMoriah Waterland (void) free(ds_header);
4575c51f124SMoriah Waterland ecleanup();
4585c51f124SMoriah Waterland return (-1);
4595c51f124SMoriah Waterland }
4605c51f124SMoriah Waterland if (tail) {
4615c51f124SMoriah Waterland tail->next = toc_pt;
4625c51f124SMoriah Waterland tail = toc_pt;
4635c51f124SMoriah Waterland } else
4645c51f124SMoriah Waterland ds_head = tail = toc_pt;
4655c51f124SMoriah Waterland ds_volcnt += ds_volsum(toc_pt);
4665c51f124SMoriah Waterland }
4675c51f124SMoriah Waterland if (!ret) {
4685c51f124SMoriah Waterland progerr(pkg_gt(ERR_UNPACK));
4695c51f124SMoriah Waterland logerr(pkg_gt(MSG_TOC));
4705c51f124SMoriah Waterland (void) free(ds_header);
4715c51f124SMoriah Waterland return (-1);
4725c51f124SMoriah Waterland }
473*4656d474SGarrett D'Amore (void) sighold(SIGINT);
474*4656d474SGarrett D'Amore (void) sigrelse(SIGINT);
4755c51f124SMoriah Waterland if (!ds_head) {
4765c51f124SMoriah Waterland progerr(pkg_gt(ERR_UNPACK));
4775c51f124SMoriah Waterland logerr(pkg_gt(MSG_EMPTY));
4785c51f124SMoriah Waterland (void) free(ds_header);
4795c51f124SMoriah Waterland return (-1);
4805c51f124SMoriah Waterland }
4815c51f124SMoriah Waterland /* this could break, thanks to cpio command limit */
482*4656d474SGarrett D'Amore (void) snprintf(cmd, sizeof (cmd), "%s -icdumD -C %d",
483*4656d474SGarrett D'Amore CPIOPROC, (int)BLK_SIZE);
4845c51f124SMoriah Waterland n = 0;
4855c51f124SMoriah Waterland for (i = 0; pkg[i]; i++) {
4865c51f124SMoriah Waterland if (strcmp(pkg[i], "all") == 0)
4875c51f124SMoriah Waterland continue;
4885c51f124SMoriah Waterland if (n == 0) {
489*4656d474SGarrett D'Amore (void) strlcat(cmd, " ", CMDSIZ);
4905c51f124SMoriah Waterland n = 1;
4915c51f124SMoriah Waterland }
492*4656d474SGarrett D'Amore (void) strlcat(cmd, pkg[i], CMDSIZ);
493*4656d474SGarrett D'Amore (void) strlcat(cmd, "'/*' ", CMDSIZ);
4945c51f124SMoriah Waterland
4955c51f124SMoriah Waterland /* extract signature too, if present. */
496*4656d474SGarrett D'Amore (void) strlcat(cmd, SIGNATURE_FILENAME, CMDSIZ);
497*4656d474SGarrett D'Amore (void) strlcat(cmd, " ", CMDSIZ);
4985c51f124SMoriah Waterland }
4995c51f124SMoriah Waterland
5005c51f124SMoriah Waterland /*
5015c51f124SMoriah Waterland * if we are extracting all packages (pkgs == NULL),
5025c51f124SMoriah Waterland * signature will automatically be extracted
5035c51f124SMoriah Waterland */
5045c51f124SMoriah Waterland if (n = esystem(cmd, ds_fd, -1)) {
5055c51f124SMoriah Waterland rpterr();
5065c51f124SMoriah Waterland progerr(pkg_gt(ERR_UNPACK));
5075c51f124SMoriah Waterland logerr(pkg_gt(MSG_CMDFAIL), cmd, n);
5085c51f124SMoriah Waterland (void) free(ds_header);
5095c51f124SMoriah Waterland return (-1);
5105c51f124SMoriah Waterland }
5115c51f124SMoriah Waterland
5125c51f124SMoriah Waterland ds_toc = ds_head;
5135c51f124SMoriah Waterland ds_totread = 0;
5145c51f124SMoriah Waterland ds_volno = 1;
5155c51f124SMoriah Waterland return (0);
5165c51f124SMoriah Waterland }
5175c51f124SMoriah Waterland
5185c51f124SMoriah Waterland int
ds_findpkg(char * device,char * pkg)5195c51f124SMoriah Waterland ds_findpkg(char *device, char *pkg)
5205c51f124SMoriah Waterland {
5215c51f124SMoriah Waterland char *pkglist[2];
5225c51f124SMoriah Waterland int nskip, ods_volpart;
5235c51f124SMoriah Waterland
5245c51f124SMoriah Waterland if (ds_head == NULL) {
5255c51f124SMoriah Waterland pkglist[0] = pkg;
5265c51f124SMoriah Waterland pkglist[1] = NULL;
5275c51f124SMoriah Waterland if (ds_init(device, pkglist, NULL))
5285c51f124SMoriah Waterland return (-1);
5295c51f124SMoriah Waterland }
5305c51f124SMoriah Waterland
5315c51f124SMoriah Waterland if (!pkg || pkgnmchk(pkg, "all", 0)) {
5325c51f124SMoriah Waterland progerr(pkg_gt(ERR_UNPACK));
5335c51f124SMoriah Waterland logerr(pkg_gt(MSG_PKGNAME));
5345c51f124SMoriah Waterland return (-1);
5355c51f124SMoriah Waterland }
5365c51f124SMoriah Waterland
5375c51f124SMoriah Waterland nskip = 0;
5385c51f124SMoriah Waterland ds_volno = 1;
5395c51f124SMoriah Waterland ds_volpart = 0;
5405c51f124SMoriah Waterland ds_toc = ds_head;
5415c51f124SMoriah Waterland while (ds_toc) {
5425c51f124SMoriah Waterland if (strcmp(ds_toc->pkg, pkg) == 0)
5435c51f124SMoriah Waterland break;
5445c51f124SMoriah Waterland nskip += ds_toc->nparts;
5455c51f124SMoriah Waterland ds_volno += ds_volsum(ds_toc);
5465c51f124SMoriah Waterland ds_toc = ds_toc->next;
5475c51f124SMoriah Waterland }
5485c51f124SMoriah Waterland if (!ds_toc) {
5495c51f124SMoriah Waterland progerr(pkg_gt(ERR_UNPACK));
5505c51f124SMoriah Waterland logerr(pkg_gt(MSG_NOPKG), pkg);
5515c51f124SMoriah Waterland return (-1);
5525c51f124SMoriah Waterland }
5535c51f124SMoriah Waterland
5545c51f124SMoriah Waterland ds_pkginit();
5555c51f124SMoriah Waterland ds_skippart = 0;
5565c51f124SMoriah Waterland if (ds_curpartcnt > 0) {
5575c51f124SMoriah Waterland ods_volpart = ds_volpart;
5585c51f124SMoriah Waterland /*
5595c51f124SMoriah Waterland * skip past archives belonging to last package on current
5605c51f124SMoriah Waterland * volume
5615c51f124SMoriah Waterland */
5625c51f124SMoriah Waterland if (ds_volpart > 0 && ds_getnextvol(device))
5635c51f124SMoriah Waterland return (-1);
5645c51f124SMoriah Waterland ds_totread = nskip - ods_volpart;
5655c51f124SMoriah Waterland if (ds_skip(device, ods_volpart))
5665c51f124SMoriah Waterland return (-1);
5675c51f124SMoriah Waterland } else if (ds_curpartcnt < 0) {
5685c51f124SMoriah Waterland if (ds_skip(device, nskip - ds_totread))
5695c51f124SMoriah Waterland return (-1);
5705c51f124SMoriah Waterland } else
5715c51f124SMoriah Waterland ds_totread = nskip;
5725c51f124SMoriah Waterland ds_read = 0;
5735c51f124SMoriah Waterland return (ds_nparts);
5745c51f124SMoriah Waterland }
5755c51f124SMoriah Waterland
5765c51f124SMoriah Waterland /*
5775c51f124SMoriah Waterland * Get datastream part
5785c51f124SMoriah Waterland * Call for first part should be preceded by
5795c51f124SMoriah Waterland * call to ds_findpkg
5805c51f124SMoriah Waterland */
5815c51f124SMoriah Waterland
5825c51f124SMoriah Waterland int
ds_getpkg(char * device,int n,char * dstdir)5835c51f124SMoriah Waterland ds_getpkg(char *device, int n, char *dstdir)
5845c51f124SMoriah Waterland {
5855c51f124SMoriah Waterland struct statvfs64 svfsb;
5865c51f124SMoriah Waterland u_longlong_t free_blocks;
5875c51f124SMoriah Waterland
5885c51f124SMoriah Waterland if (ds_read >= ds_nparts)
5895c51f124SMoriah Waterland return (2);
5905c51f124SMoriah Waterland
5915c51f124SMoriah Waterland if (ds_read == n)
5925c51f124SMoriah Waterland return (0);
5935c51f124SMoriah Waterland else if ((ds_read > n) || (n > ds_nparts))
5945c51f124SMoriah Waterland return (2);
5955c51f124SMoriah Waterland
5965c51f124SMoriah Waterland if (ds_maxsiz > 0) {
5975c51f124SMoriah Waterland if (statvfs64(".", &svfsb)) {
5985c51f124SMoriah Waterland progerr(pkg_gt(ERR_UNPACK));
5995c51f124SMoriah Waterland logerr(pkg_gt(MSG_STATFS), errno);
6005c51f124SMoriah Waterland return (-1);
6015c51f124SMoriah Waterland }
6025c51f124SMoriah Waterland free_blocks = (((long)svfsb.f_frsize > 0) ?
6035c51f124SMoriah Waterland howmany(svfsb.f_frsize, DEV_BSIZE) :
6045c51f124SMoriah Waterland howmany(svfsb.f_bsize, DEV_BSIZE)) * svfsb.f_bfree;
6055c51f124SMoriah Waterland if ((ds_maxsiz + 50) > free_blocks) {
6065c51f124SMoriah Waterland progerr(pkg_gt(ERR_UNPACK));
6075c51f124SMoriah Waterland logerr(pkg_gt(MSG_NOSPACE), ds_maxsiz+50, free_blocks);
6085c51f124SMoriah Waterland return (-1);
6095c51f124SMoriah Waterland }
6105c51f124SMoriah Waterland }
6115c51f124SMoriah Waterland return (ds_next(device, dstdir));
6125c51f124SMoriah Waterland }
6135c51f124SMoriah Waterland
6145c51f124SMoriah Waterland static int
ds_getnextvol(char * device)6155c51f124SMoriah Waterland ds_getnextvol(char *device)
6165c51f124SMoriah Waterland {
6175c51f124SMoriah Waterland char prompt[128];
6185c51f124SMoriah Waterland int n;
6195c51f124SMoriah Waterland
6205c51f124SMoriah Waterland if (ds_close(0))
6215c51f124SMoriah Waterland return (-1);
6225c51f124SMoriah Waterland (void) sprintf(prompt,
6235c51f124SMoriah Waterland pkg_gt("Insert %%v %d of %d into %%p"),
6245c51f124SMoriah Waterland ds_volno, ds_volcnt);
6255c51f124SMoriah Waterland if (n = getvol(device, NULL, NULL, prompt))
6265c51f124SMoriah Waterland return (n);
6275c51f124SMoriah Waterland if ((ds_fd = open(device, O_RDONLY)) < 0)
6285c51f124SMoriah Waterland return (-1);
6295c51f124SMoriah Waterland if (ds_ginit(device) < 0) {
6305c51f124SMoriah Waterland (void) ds_close(0);
6315c51f124SMoriah Waterland return (-1);
6325c51f124SMoriah Waterland }
6335c51f124SMoriah Waterland ds_volpart = 0;
6345c51f124SMoriah Waterland return (0);
6355c51f124SMoriah Waterland }
6365c51f124SMoriah Waterland
6375c51f124SMoriah Waterland /*
6385c51f124SMoriah Waterland * called by ds_findpkg to skip past archives for unwanted packages
6395c51f124SMoriah Waterland * in current volume
6405c51f124SMoriah Waterland */
6415c51f124SMoriah Waterland static int
ds_skip(char * device,int nskip)6425c51f124SMoriah Waterland ds_skip(char *device, int nskip)
6435c51f124SMoriah Waterland {
6445c51f124SMoriah Waterland char cmd[CMDSIZ];
6455c51f124SMoriah Waterland int n, onskip = nskip;
6465c51f124SMoriah Waterland
6475c51f124SMoriah Waterland while (nskip--) {
6485c51f124SMoriah Waterland /* skip this one */
649*4656d474SGarrett D'Amore (void) snprintf(cmd, sizeof (cmd),
650*4656d474SGarrett D'Amore "%s -ictD -C %d > /dev/null", CPIOPROC, (int)BLK_SIZE);
6515c51f124SMoriah Waterland if (n = esystem(cmd, ds_fd, -1)) {
6525c51f124SMoriah Waterland rpterr();
6535c51f124SMoriah Waterland progerr(pkg_gt(ERR_UNPACK));
6545c51f124SMoriah Waterland logerr(pkg_gt(MSG_CMDFAIL), cmd, n);
6555c51f124SMoriah Waterland nskip = onskip;
6565c51f124SMoriah Waterland if (ds_volno == 1 || ds_volpart > 0)
6575c51f124SMoriah Waterland return (n);
6585c51f124SMoriah Waterland if (n = ds_getnextvol(device))
6595c51f124SMoriah Waterland return (n);
6605c51f124SMoriah Waterland }
6615c51f124SMoriah Waterland }
6625c51f124SMoriah Waterland ds_totread += onskip;
6635c51f124SMoriah Waterland ds_volpart = onskip;
6645c51f124SMoriah Waterland ds_skippart = onskip;
6655c51f124SMoriah Waterland return (0);
6665c51f124SMoriah Waterland }
6675c51f124SMoriah Waterland
6685c51f124SMoriah Waterland /* skip to end of package if necessary */
6695c51f124SMoriah Waterland void
ds_skiptoend(char * device)6705c51f124SMoriah Waterland ds_skiptoend(char *device)
6715c51f124SMoriah Waterland {
6725c51f124SMoriah Waterland if (ds_read < ds_nparts && ds_curpartcnt < 0)
6735c51f124SMoriah Waterland (void) ds_skip(device, ds_nparts - ds_read);
6745c51f124SMoriah Waterland }
6755c51f124SMoriah Waterland
6765c51f124SMoriah Waterland int
ds_next(char * device,char * instdir)6775c51f124SMoriah Waterland ds_next(char *device, char *instdir)
6785c51f124SMoriah Waterland {
6795c51f124SMoriah Waterland char cmd[CMDSIZ], tmpvol[128];
6805c51f124SMoriah Waterland int nparts, n, index;
6815c51f124SMoriah Waterland
6825c51f124SMoriah Waterland /*CONSTCOND*/
6835c51f124SMoriah Waterland while (1) {
6845c51f124SMoriah Waterland if (ds_read + 1 > ds_curpartcnt && ds_curpartcnt >= 0) {
6855c51f124SMoriah Waterland ds_volno++;
6865c51f124SMoriah Waterland if (n = ds_getnextvol(device))
6875c51f124SMoriah Waterland return (n);
6885c51f124SMoriah Waterland (void) sscanf(ds_volnos, "%d %[ 0-9]", &index, tmpvol);
6895c51f124SMoriah Waterland (void) strcpy(ds_volnos, tmpvol);
6905c51f124SMoriah Waterland ds_curpartcnt += index;
6915c51f124SMoriah Waterland }
692*4656d474SGarrett D'Amore (void) snprintf(cmd, sizeof (cmd), "%s -icdumD -C %d",
6935c51f124SMoriah Waterland CPIOPROC, (int)BLK_SIZE);
6945c51f124SMoriah Waterland if (n = esystem(cmd, ds_fd, -1)) {
6955c51f124SMoriah Waterland rpterr();
6965c51f124SMoriah Waterland progerr(pkg_gt(ERR_UNPACK));
6975c51f124SMoriah Waterland logerr(pkg_gt(MSG_CMDFAIL), cmd, n);
6985c51f124SMoriah Waterland }
6995c51f124SMoriah Waterland if (ds_read == 0)
7005c51f124SMoriah Waterland nparts = 0;
7015c51f124SMoriah Waterland else
7025c51f124SMoriah Waterland nparts = ds_toc->nparts;
7035c51f124SMoriah Waterland if (n || (n = ckvolseq(instdir, ds_read + 1, nparts))) {
7045c51f124SMoriah Waterland if (ds_volno == 1 || ds_volpart > ds_skippart)
7055c51f124SMoriah Waterland return (-1);
7065c51f124SMoriah Waterland
7075c51f124SMoriah Waterland if (n = ds_getnextvol(device))
7085c51f124SMoriah Waterland return (n);
7095c51f124SMoriah Waterland continue;
7105c51f124SMoriah Waterland }
7115c51f124SMoriah Waterland ds_read++;
7125c51f124SMoriah Waterland ds_totread++;
7135c51f124SMoriah Waterland ds_volpart++;
7145c51f124SMoriah Waterland
7155c51f124SMoriah Waterland return (0);
7165c51f124SMoriah Waterland }
7175c51f124SMoriah Waterland /*NOTREACHED*/
7185c51f124SMoriah Waterland }
7195c51f124SMoriah Waterland
7205c51f124SMoriah Waterland /*
7215c51f124SMoriah Waterland * Name: BIO_ds_dump
7225c51f124SMoriah Waterland * Description: Dumps all data from the static 'ds_fd' file handle into
7235c51f124SMoriah Waterland * the supplied BIO.
7245c51f124SMoriah Waterland *
7255c51f124SMoriah Waterland * Arguments: err - where to record any errors.
7265c51f124SMoriah Waterland * device - Description of device being dumped into,
7275c51f124SMoriah Waterland * for error reporting
7285c51f124SMoriah Waterland * bio - BIO object to dump data into
7295c51f124SMoriah Waterland *
7305c51f124SMoriah Waterland * Returns : zero - successfully dumped all data to EOF
7315c51f124SMoriah Waterland * non-zero - some failure occurred.
7325c51f124SMoriah Waterland */
7335c51f124SMoriah Waterland int
BIO_ds_dump(PKG_ERR * err,char * device,BIO * bio)7345c51f124SMoriah Waterland BIO_ds_dump(PKG_ERR *err, char *device, BIO *bio)
7355c51f124SMoriah Waterland {
7365c51f124SMoriah Waterland int amtread;
7375c51f124SMoriah Waterland char readbuf[BLK_SIZE];
7385c51f124SMoriah Waterland
7395c51f124SMoriah Waterland /*
7405c51f124SMoriah Waterland * note this will read to the end of the device, so it won't
7415c51f124SMoriah Waterland * work for character devices since we don't know when the
7425c51f124SMoriah Waterland * end of the CPIO archive is
7435c51f124SMoriah Waterland */
7445c51f124SMoriah Waterland while ((amtread = read(ds_fd, readbuf, BLK_SIZE)) != 0) {
7455c51f124SMoriah Waterland if (BIO_write(bio, readbuf, amtread) != amtread) {
7465c51f124SMoriah Waterland pkgerr_add(err, PKGERR_WRITE, ERR_WRITE, device,
7475c51f124SMoriah Waterland ERR_error_string(ERR_get_error(), NULL));
7485c51f124SMoriah Waterland return (1);
7495c51f124SMoriah Waterland }
7505c51f124SMoriah Waterland }
7515c51f124SMoriah Waterland
7525c51f124SMoriah Waterland return (0);
7535c51f124SMoriah Waterland /*NOTREACHED*/
7545c51f124SMoriah Waterland }
7555c51f124SMoriah Waterland
7565c51f124SMoriah Waterland
7575c51f124SMoriah Waterland /*
7585c51f124SMoriah Waterland * Name: BIO_ds_dump_header
7595c51f124SMoriah Waterland * Description: Dumps all ds_headsize bytes from the
7605c51f124SMoriah Waterland * static 'ds_header_raw' character array
7615c51f124SMoriah Waterland * to the supplied BIO.
7625c51f124SMoriah Waterland *
7635c51f124SMoriah Waterland * Arguments: err - where to record any errors.
7645c51f124SMoriah Waterland * bio - BIO object to dump data into
7655c51f124SMoriah Waterland *
7665c51f124SMoriah Waterland * Returns : zero - successfully dumped all raw
7675c51f124SMoriah Waterland * header characters
7685c51f124SMoriah Waterland * non-zero - some failure occurred.
7695c51f124SMoriah Waterland */
7705c51f124SMoriah Waterland int
BIO_ds_dump_header(PKG_ERR * err,BIO * bio)7715c51f124SMoriah Waterland BIO_ds_dump_header(PKG_ERR *err, BIO *bio)
7725c51f124SMoriah Waterland {
7735c51f124SMoriah Waterland
7745c51f124SMoriah Waterland char zeros[BLK_SIZE];
7755c51f124SMoriah Waterland
776*4656d474SGarrett D'Amore (void) memset(zeros, 0, BLK_SIZE);
7775c51f124SMoriah Waterland
7785c51f124SMoriah Waterland if (BIO_write(bio, ds_header_raw, ds_headsize) != ds_headsize) {
7795c51f124SMoriah Waterland pkgerr_add(err, PKGERR_WRITE, ERR_WRITE, "bio",
7805c51f124SMoriah Waterland ERR_error_string(ERR_get_error(), NULL));
7815c51f124SMoriah Waterland return (1);
7825c51f124SMoriah Waterland }
7835c51f124SMoriah Waterland
7845c51f124SMoriah Waterland return (0);
7855c51f124SMoriah Waterland }
7865c51f124SMoriah Waterland
7875c51f124SMoriah Waterland /*
7885c51f124SMoriah Waterland * ds_ginit: Determine the device being accessed, set the buffer size,
789*4656d474SGarrett D'Amore * and perform any device specific initialization.
7905c51f124SMoriah Waterland */
7915c51f124SMoriah Waterland
7925c51f124SMoriah Waterland int
ds_ginit(char * device)7935c51f124SMoriah Waterland ds_ginit(char *device)
7945c51f124SMoriah Waterland {
7955c51f124SMoriah Waterland int oflag;
7965c51f124SMoriah Waterland char *pbufsize, cmd[CMDSIZ];
7975c51f124SMoriah Waterland int fd2, fd;
7985c51f124SMoriah Waterland
7995c51f124SMoriah Waterland if ((pbufsize = devattr(device, "bufsize")) != NULL) {
8005c51f124SMoriah Waterland ds_bufsize = atoi(pbufsize);
8015c51f124SMoriah Waterland (void) free(pbufsize);
8025c51f124SMoriah Waterland } else
8035c51f124SMoriah Waterland ds_bufsize = BLK_SIZE;
8045c51f124SMoriah Waterland oflag = fcntl(ds_fd, F_GETFL, 0);
8055c51f124SMoriah Waterland
8065c51f124SMoriah Waterland if (ds_bufsize > BLK_SIZE) {
8075c51f124SMoriah Waterland if (oflag & O_WRONLY)
8085c51f124SMoriah Waterland fd = 1;
8095c51f124SMoriah Waterland else
8105c51f124SMoriah Waterland fd = 0;
8115c51f124SMoriah Waterland fd2 = fcntl(fd, F_DUPFD, fd);
8125c51f124SMoriah Waterland (void) close(fd);
813*4656d474SGarrett D'Amore (void) fcntl(ds_fd, F_DUPFD, fd);
8145c51f124SMoriah Waterland if (fd)
815*4656d474SGarrett D'Amore (void) snprintf(cmd, sizeof (cmd),
816*4656d474SGarrett D'Amore "%s obs=%d 2>/dev/null", DDPROC, ds_bufsize);
8175c51f124SMoriah Waterland else
818*4656d474SGarrett D'Amore (void) snprintf(cmd, sizeof (cmd),
819*4656d474SGarrett D'Amore "%s ibs=%d 2>/dev/null", DDPROC, ds_bufsize);
8205c51f124SMoriah Waterland if ((ds_pp = popen(cmd, fd ? "w" : "r")) == NULL) {
8215c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER));
8225c51f124SMoriah Waterland logerr(pkg_gt(MSG_POPEN), cmd, errno);
8235c51f124SMoriah Waterland return (-1);
8245c51f124SMoriah Waterland }
8255c51f124SMoriah Waterland (void) close(fd);
826*4656d474SGarrett D'Amore (void) fcntl(fd2, F_DUPFD, fd);
8275c51f124SMoriah Waterland (void) close(fd2);
8285c51f124SMoriah Waterland ds_realfd = ds_fd;
8295c51f124SMoriah Waterland ds_fd = fileno(ds_pp);
8305c51f124SMoriah Waterland }
8315c51f124SMoriah Waterland return (ds_bufsize);
8325c51f124SMoriah Waterland }
8335c51f124SMoriah Waterland
8345c51f124SMoriah Waterland int
ds_close(int pkgendflg)8355c51f124SMoriah Waterland ds_close(int pkgendflg)
8365c51f124SMoriah Waterland {
8375c51f124SMoriah Waterland int n, ret = 0;
8385c51f124SMoriah Waterland
8395c51f124SMoriah Waterland if (pkgendflg) {
8405c51f124SMoriah Waterland if (ds_header)
8415c51f124SMoriah Waterland (void) free(ds_header);
8425c51f124SMoriah Waterland ds_header = (char *)NULL;
8435c51f124SMoriah Waterland ds_totread = 0;
8445c51f124SMoriah Waterland }
8455c51f124SMoriah Waterland
8465c51f124SMoriah Waterland if (ds_pp) {
8475c51f124SMoriah Waterland (void) pclose(ds_pp);
8485c51f124SMoriah Waterland ds_pp = 0;
8495c51f124SMoriah Waterland (void) close(ds_realfd);
8505c51f124SMoriah Waterland ds_realfd = -1;
8515c51f124SMoriah Waterland ds_fd = -1;
8525c51f124SMoriah Waterland } else if (ds_fd >= 0) {
8535c51f124SMoriah Waterland (void) close(ds_fd);
8545c51f124SMoriah Waterland ds_fd = -1;
8555c51f124SMoriah Waterland }
8565c51f124SMoriah Waterland
8575c51f124SMoriah Waterland if (ds_device) {
8585c51f124SMoriah Waterland /* rewind device */
8595c51f124SMoriah Waterland if ((n = open(ds_device, 0)) >= 0)
8605c51f124SMoriah Waterland (void) close(n);
8615c51f124SMoriah Waterland ds_device = NULL;
8625c51f124SMoriah Waterland }
8635c51f124SMoriah Waterland return (ret);
8645c51f124SMoriah Waterland }
865