5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * CDDL HEADER START
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * The contents of this file are subject to the terms of the
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Common Development and Distribution License (the "License").
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * You may not use this file except in compliance with the License.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * or http://www.opensolaris.org/os/licensing.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * See the License for the specific language governing permissions
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * and limitations under the License.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * When distributing Covered Code, include this CDDL HEADER in each
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * If applicable, add the following below this CDDL HEADER, with the
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * fields enclosed by brackets "[]" replaced with your own identifying
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * information: Portions Copyright [yyyy] [name of copyright owner]
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * CDDL HEADER END
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Use is subject to license terms.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/* All Rights Reserved */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <stdio.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <string.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <signal.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <stdlib.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <unistd.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <sys/types.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <sys/param.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <sys/sysmacros.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <errno.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <sys/types.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <sys/stat.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <sys/statvfs.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <fcntl.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <openssl/err.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include "pkglib.h"
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include "pkglibmsgs.h"
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include "pkglocale.h"
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/* libadm.a */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandextern char *devattr(char *device, char *attribute);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandextern int pkgnmchk(register char *pkg, register char *spec,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int presvr4flg);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandextern int getvol(char *device, char *label, int options, char *prompt);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define CMDSIZ 512
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define LSIZE 128
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define DDPROC "/usr/bin/dd"
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define CPIOPROC "/usr/bin/cpio"
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/* device types */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define G_TM_TAPE 1 /* Tapemaster controller */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define G_XY_DISK 3 /* xy disks */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define G_SD_DISK 7 /* scsi sd disk */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define G_XT_TAPE 8 /* xt tapes */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define G_SF_FLOPPY 9 /* sf floppy */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define G_XD_DISK 10 /* xd disks */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define G_ST_TAPE 11 /* scsi tape */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define G_NS 12 /* noswap pseudo-dev */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define G_RAM 13 /* ram pseudo-dev */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define G_FT 14 /* tftp */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define G_HD 15 /* 386 network disk */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define G_FD 16 /* 386 AT disk */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define G_FILE 28 /* file, not a device */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define G_NO_DEV 29 /* device does not require special treatment */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define G_DEV_MAX 30 /* last valid device type */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstruct dstoc {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int cnt;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland char pkg[NON_ABI_NAMELNGTH];
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int nparts;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland long maxsiz;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland char volnos[128];
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland struct dstoc *next;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland} *ds_head, *ds_toc;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define ds_nparts ds_toc->nparts
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define ds_maxsiz ds_toc->maxsiz
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandint ds_totread; /* total number of parts read */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandint ds_fd = -1;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandint ds_curpartcnt = -1;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandint ds_next(char *device, char *instdir);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandint ds_ginit(char *device);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandint ds_close(int pkgendflg);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic FILE *ds_pp;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic int ds_realfd = -1; /* file descriptor for real device */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic int ds_read; /* number of parts read for current package */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic int ds_volno; /* volume number of current volume */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic int ds_volcnt; /* total number of volumes */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic char ds_volnos[128]; /* parts/volume info */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic char *ds_device;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic int ds_volpart; /* number of parts read in current volume, */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* including skipped parts */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic int ds_bufsize;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic int ds_skippart; /* number of parts skipped in current volume */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic int ds_getnextvol(char *device);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic int ds_skip(char *device, int nskip);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandvoid
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandds_order(char *list[])
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland struct dstoc *toc_pt;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland register int j, n;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland char *pt;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland toc_pt = ds_head;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland n = 0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland while (toc_pt) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland for (j = n; list[j]; j++) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (strcmp(list[j], toc_pt->pkg) == 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* just swap places in the array */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland pt = list[n];
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland list[n++] = list[j];
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland list[j] = pt;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland toc_pt = toc_pt->next;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic char *pds_header;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic char *ds_header;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic char *ds_header_raw;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic int ds_headsize;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic char *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandds_gets(char *buf, int size)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int length;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland char *nextp;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland nextp = strchr(pds_header, '\n');
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (nextp == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland length = strlen(pds_header);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (length > size)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (0);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if ((ds_header = (char *)realloc(ds_header,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ds_headsize + BLK_SIZE)) == NULL)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (0);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (read(ds_fd, ds_header + ds_headsize, BLK_SIZE) < BLK_SIZE)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (0);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ds_headsize += BLK_SIZE;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland nextp = strchr(pds_header, '\n');
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (nextp == NULL)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (0);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *nextp = '\0';
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (length + (int)strlen(pds_header) > size)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (0);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) strncpy(buf + length, pds_header, strlen(pds_header));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland buf[length + strlen(pds_header)] = '\0';
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland pds_header = nextp + 1;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (buf);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *nextp = '\0';
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if ((int)strlen(pds_header) > size)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (0);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) strncpy(buf, pds_header, strlen(pds_header));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland buf[strlen(pds_header)] = '\0';
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland pds_header = nextp + 1;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (buf);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * function to determine if media is datastream or mounted
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * floppy
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandint
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandds_readbuf(char *device)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland char buf[BLK_SIZE];
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (ds_fd >= 0)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) close(ds_fd);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if ((ds_fd = open(device, O_RDONLY)) >= 0 &&
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland read(ds_fd, buf, BLK_SIZE) == BLK_SIZE &&
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland strncmp(buf, HDR_PREFIX, 20) == 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if ((ds_header = (char *)calloc(BLK_SIZE, 1)) == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland progerr(pkg_gt(ERR_UNPACK));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland logerr(pkg_gt(MSG_MEM));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) ds_close(0);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (0);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
4656d4747c8743290bfbe910c64cd75eb4e4af8dGarrett D'Amore (void) memcpy(ds_header, buf, BLK_SIZE);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ds_headsize = BLK_SIZE;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (ds_ginit(device) < 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland progerr(pkg_gt(ERR_UNPACK));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland logerr(pkg_gt(MSG_OPEN), device, errno);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) ds_close(0);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (0);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland } else if (ds_fd >= 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) close(ds_fd);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ds_fd = -1;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (0);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Determine how many additional volumes are needed for current package.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Note: a 0 will occur as first volume number when the package begins
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * on the next volume.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic int
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandds_volsum(struct dstoc *toc)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int curpartcnt, volcnt;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland char volnos[128], tmpvol[128];
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (toc->volnos[0]) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int index, sum;
4656d4747c8743290bfbe910c64cd75eb4e4af8dGarrett D'Amore (void) sscanf(toc->volnos, "%d %[ 0-9]", &curpartcnt, volnos);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland volcnt = 0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland sum = curpartcnt;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland while (sum < toc->nparts && sscanf(volnos, "%d %[ 0-9]",
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland &index, tmpvol) >= 1) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) strcpy(volnos, tmpvol);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland volcnt++;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland sum += index;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* side effect - set number of parts read on current volume */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ds_volpart = index;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (volcnt);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ds_volpart += toc->nparts;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (0);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/* initialize ds_curpartcnt and ds_volnos */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic void
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandds_pkginit(void)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (ds_toc->volnos[0])
4656d4747c8743290bfbe910c64cd75eb4e4af8dGarrett D'Amore (void) sscanf(ds_toc->volnos, "%d %[ 0-9]", &ds_curpartcnt,
4656d4747c8743290bfbe910c64cd75eb4e4af8dGarrett D'Amore ds_volnos);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland else
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ds_curpartcnt = -1;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * functions to pass current package info to exec'ed program
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandvoid
4656d4747c8743290bfbe910c64cd75eb4e4af8dGarrett D'Amoreds_putinfo(char *buf, size_t sz)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
4656d4747c8743290bfbe910c64cd75eb4e4af8dGarrett D'Amore (void) snprintf(buf, sz, "%d %d %d %d %d %d %d %d %d %d %s",
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ds_fd, ds_realfd, ds_volcnt, ds_volno, ds_totread, ds_volpart,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ds_skippart, ds_bufsize, ds_toc->nparts, ds_toc->maxsiz,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ds_toc->volnos);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandint
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandds_getinfo(char *string)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ds_toc = (struct dstoc *)calloc(1, sizeof (struct dstoc));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) sscanf(string, "%d %d %d %d %d %d %d %d %d %d %[ 0-9]",
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland &ds_fd, &ds_realfd, &ds_volcnt, &ds_volno, &ds_totread,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland &ds_volpart, &ds_skippart, &ds_bufsize, &ds_toc->nparts,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland &ds_toc->maxsiz, ds_toc->volnos);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ds_pkginit();
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (ds_toc->nparts);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Return true if the file descriptor (ds_fd) is open on the package stream.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandboolean_t
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandds_fd_open(void)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (ds_fd >= 0 ? B_TRUE : B_FALSE);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Read the source device. Acquire the header data and check it for validity.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandint
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandds_init(char *device, char **pkg, char *norewind)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland struct dstoc *tail, *toc_pt;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland char *ret;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland char cmd[CMDSIZ];
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland char line[LSIZE+1];
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int i, n, count = 0, header_size = BLK_SIZE;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (!ds_header) { /* If the header hasn't been read yet */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (ds_fd >= 0)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) ds_close(0);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* always start with rewind device */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if ((ds_fd = open(device, O_RDONLY)) < 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland progerr(pkg_gt(ERR_UNPACK));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland logerr(pkg_gt(MSG_OPEN), device, errno);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (-1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* allocate room for the header equivalent to a block */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if ((ds_header = (char *)calloc(BLK_SIZE, 1)) == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland progerr(pkg_gt(ERR_UNPACK));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland logerr(pkg_gt(MSG_MEM));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (-1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* initialize the device */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (ds_ginit(device) < 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) ds_close(0);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland progerr(pkg_gt(ERR_UNPACK));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland logerr(pkg_gt(MSG_OPEN), device, errno);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (-1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* read a logical block from the source device */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (read(ds_fd, ds_header, BLK_SIZE) != BLK_SIZE) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland rpterr();
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland progerr(pkg_gt(ERR_UNPACK));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland logerr(pkg_gt(MSG_TOC));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) ds_close(0);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (-1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * This loop scans the medium for the start of the header.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * If the above read worked, we skip this. If it did't, this
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * loop will retry the read ten times looking for the header
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * marker string.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland while (strncmp(ds_header, HDR_PREFIX, 20) != 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* only ten tries iff the device rewinds */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (!norewind || count++ > 10) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland progerr(pkg_gt(ERR_UNPACK));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland logerr(pkg_gt(MSG_TOC));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) ds_close(0);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (-1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* read through to the last block */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (count > 1)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland while (read(ds_fd, ds_header, BLK_SIZE) > 0)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* then close the device */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) ds_close(0);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* and reopen it */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if ((ds_fd = open(norewind, O_RDONLY)) < 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland progerr(pkg_gt(ERR_UNPACK));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland logerr(pkg_gt(MSG_OPEN), device, errno);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) free(ds_header);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (-1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* initialize the device */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (ds_ginit(device) < 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) ds_close(0);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland progerr(pkg_gt(ERR_UNPACK));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland logerr(pkg_gt(MSG_OPEN), device, errno);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (-1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* read the block again */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (read(ds_fd, ds_header, BLK_SIZE) != BLK_SIZE) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland rpterr();
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland progerr(pkg_gt(ERR_UNPACK));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland logerr(pkg_gt(MSG_TOC));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) ds_close(0);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (-1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* Now keep scanning until the whole header is in place. */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland while (strstr(ds_header, HDR_SUFFIX) == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* We need a bigger buffer */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if ((ds_header = (char *)realloc(ds_header,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland header_size + BLK_SIZE)) == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland progerr(pkg_gt(ERR_UNPACK));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland logerr(pkg_gt(MSG_MEM));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) ds_close(0);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* clear the new memory */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) memset(ds_header + header_size, '\0',
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland BLK_SIZE);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* read a logical block from the source device */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (read(ds_fd, ds_header + header_size, BLK_SIZE) !=
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland BLK_SIZE) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland rpterr();
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland progerr(pkg_gt(ERR_UNPACK));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland logerr(pkg_gt(MSG_TOC));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) ds_close(0);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (-1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland } else
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland header_size += BLK_SIZE; /* new size */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * remember rewind device for ds_close to rewind at
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * close
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (count >= 1)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ds_device = device;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ds_headsize = header_size;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland pds_header = ds_header;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* save raw copy of header for later use in BIO_dump_header */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if ((ds_header_raw = (char *)malloc(header_size)) == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland progerr(pkg_gt(ERR_UNPACK));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland logerr(pkg_gt(MSG_MEM));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) ds_close(0);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
4656d4747c8743290bfbe910c64cd75eb4e4af8dGarrett D'Amore (void) memcpy(ds_header_raw, ds_header, header_size);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* read datastream table of contents */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ds_head = tail = (struct dstoc *)0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ds_volcnt = 1;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland while (ret = ds_gets(line, LSIZE)) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (strcmp(line, HDR_SUFFIX) == 0)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland break;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (!line[0] || line[0] == '#')
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland continue;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland toc_pt = (struct dstoc *)calloc(1, sizeof (struct dstoc));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (!toc_pt) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland progerr(pkg_gt(ERR_UNPACK));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland logerr(pkg_gt(MSG_MEM));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ecleanup();
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) free(ds_header);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (-1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
4656d4747c8743290bfbe910c64cd75eb4e4af8dGarrett D'Amore /* LINTED E_SEC_SCANF_UNBOUNDED_COPY */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (sscanf(line, "%s %d %d %[ 0-9]", toc_pt->pkg,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland &toc_pt->nparts, &toc_pt->maxsiz, toc_pt->volnos) < 3) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland progerr(pkg_gt(ERR_UNPACK));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland logerr(pkg_gt(MSG_TOC));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland free(toc_pt);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) free(ds_header);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ecleanup();
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (-1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (tail) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland tail->next = toc_pt;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland tail = toc_pt;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland } else
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ds_head = tail = toc_pt;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ds_volcnt += ds_volsum(toc_pt);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (!ret) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland progerr(pkg_gt(ERR_UNPACK));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland logerr(pkg_gt(MSG_TOC));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) free(ds_header);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (-1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
4656d4747c8743290bfbe910c64cd75eb4e4af8dGarrett D'Amore (void) sighold(SIGINT);
4656d4747c8743290bfbe910c64cd75eb4e4af8dGarrett D'Amore (void) sigrelse(SIGINT);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (!ds_head) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland progerr(pkg_gt(ERR_UNPACK));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland logerr(pkg_gt(MSG_EMPTY));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) free(ds_header);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (-1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* this could break, thanks to cpio command limit */
4656d4747c8743290bfbe910c64cd75eb4e4af8dGarrett D'Amore (void) snprintf(cmd, sizeof (cmd), "%s -icdumD -C %d",
4656d4747c8743290bfbe910c64cd75eb4e4af8dGarrett D'Amore CPIOPROC, (int)BLK_SIZE);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland n = 0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland for (i = 0; pkg[i]; i++) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (strcmp(pkg[i], "all") == 0)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland continue;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (n == 0) {
4656d4747c8743290bfbe910c64cd75eb4e4af8dGarrett D'Amore (void) strlcat(cmd, " ", CMDSIZ);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland n = 1;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
4656d4747c8743290bfbe910c64cd75eb4e4af8dGarrett D'Amore (void) strlcat(cmd, pkg[i], CMDSIZ);
4656d4747c8743290bfbe910c64cd75eb4e4af8dGarrett D'Amore (void) strlcat(cmd, "'/*' ", CMDSIZ);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* extract signature too, if present. */
4656d4747c8743290bfbe910c64cd75eb4e4af8dGarrett D'Amore (void) strlcat(cmd, SIGNATURE_FILENAME, CMDSIZ);
4656d4747c8743290bfbe910c64cd75eb4e4af8dGarrett D'Amore (void) strlcat(cmd, " ", CMDSIZ);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * if we are extracting all packages (pkgs == NULL),
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * signature will automatically be extracted
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (n = esystem(cmd, ds_fd, -1)) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland rpterr();
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland progerr(pkg_gt(ERR_UNPACK));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland logerr(pkg_gt(MSG_CMDFAIL), cmd, n);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) free(ds_header);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (-1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ds_toc = ds_head;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ds_totread = 0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ds_volno = 1;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (0);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandint
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandds_findpkg(char *device, char *pkg)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland char *pkglist[2];
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int nskip, ods_volpart;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (ds_head == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland pkglist[0] = pkg;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland pkglist[1] = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (ds_init(device, pkglist, NULL))
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (-1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (!pkg || pkgnmchk(pkg, "all", 0)) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland progerr(pkg_gt(ERR_UNPACK));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland logerr(pkg_gt(MSG_PKGNAME));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (-1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland nskip = 0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ds_volno = 1;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ds_volpart = 0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ds_toc = ds_head;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland while (ds_toc) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (strcmp(ds_toc->pkg, pkg) == 0)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland break;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland nskip += ds_toc->nparts;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ds_volno += ds_volsum(ds_toc);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ds_toc = ds_toc->next;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (!ds_toc) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland progerr(pkg_gt(ERR_UNPACK));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland logerr(pkg_gt(MSG_NOPKG), pkg);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (-1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ds_pkginit();
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ds_skippart = 0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (ds_curpartcnt > 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ods_volpart = ds_volpart;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * skip past archives belonging to last package on current
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * volume
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (ds_volpart > 0 && ds_getnextvol(device))
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (-1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ds_totread = nskip - ods_volpart;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (ds_skip(device, ods_volpart))
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (-1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland } else if (ds_curpartcnt < 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (ds_skip(device, nskip - ds_totread))
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (-1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland } else
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ds_totread = nskip;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ds_read = 0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (ds_nparts);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Get datastream part
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Call for first part should be preceded by
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * call to ds_findpkg
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandint
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandds_getpkg(char *device, int n, char *dstdir)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland struct statvfs64 svfsb;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland u_longlong_t free_blocks;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (ds_read >= ds_nparts)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (2);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (ds_read == n)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (0);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland else if ((ds_read > n) || (n > ds_nparts))
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (2);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (ds_maxsiz > 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (statvfs64(".", &svfsb)) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland progerr(pkg_gt(ERR_UNPACK));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland logerr(pkg_gt(MSG_STATFS), errno);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (-1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland free_blocks = (((long)svfsb.f_frsize > 0) ?
4656d4747c8743290bfbe910c64cd75eb4e4af8dGarrett D'Amore howmany(svfsb.f_frsize, DEV_BSIZE) :
4656d4747c8743290bfbe910c64cd75eb4e4af8dGarrett D'Amore howmany(svfsb.f_bsize, DEV_BSIZE)) * svfsb.f_bfree;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if ((ds_maxsiz + 50) > free_blocks) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland progerr(pkg_gt(ERR_UNPACK));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland logerr(pkg_gt(MSG_NOSPACE), ds_maxsiz+50, free_blocks);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (-1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (ds_next(device, dstdir));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic int
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandds_getnextvol(char *device)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland char prompt[128];
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int n;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (ds_close(0))
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (-1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) sprintf(prompt,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland pkg_gt("Insert %%v %d of %d into %%p"),
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ds_volno, ds_volcnt);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (n = getvol(device, NULL, NULL, prompt))
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (n);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if ((ds_fd = open(device, O_RDONLY)) < 0)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (-1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (ds_ginit(device) < 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) ds_close(0);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (-1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ds_volpart = 0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (0);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * called by ds_findpkg to skip past archives for unwanted packages
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * in current volume
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic int
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandds_skip(char *device, int nskip)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland char cmd[CMDSIZ];
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int n, onskip = nskip;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland while (nskip--) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* skip this one */
4656d4747c8743290bfbe910c64cd75eb4e4af8dGarrett D'Amore (void) snprintf(cmd, sizeof (cmd),
4656d4747c8743290bfbe910c64cd75eb4e4af8dGarrett D'Amore "%s -ictD -C %d > /dev/null", CPIOPROC, (int)BLK_SIZE);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (n = esystem(cmd, ds_fd, -1)) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland rpterr();
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland progerr(pkg_gt(ERR_UNPACK));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland logerr(pkg_gt(MSG_CMDFAIL), cmd, n);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland nskip = onskip;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (ds_volno == 1 || ds_volpart > 0)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (n);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (n = ds_getnextvol(device))
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (n);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ds_totread += onskip;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ds_volpart = onskip;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ds_skippart = onskip;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (0);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/* skip to end of package if necessary */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandvoid
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandds_skiptoend(char *device)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (ds_read < ds_nparts && ds_curpartcnt < 0)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) ds_skip(device, ds_nparts - ds_read);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandint
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandds_next(char *device, char *instdir)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland char cmd[CMDSIZ], tmpvol[128];
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int nparts, n, index;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*CONSTCOND*/
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland while (1) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (ds_read + 1 > ds_curpartcnt && ds_curpartcnt >= 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ds_volno++;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (n = ds_getnextvol(device))
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (n);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) sscanf(ds_volnos, "%d %[ 0-9]", &index, tmpvol);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) strcpy(ds_volnos, tmpvol);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ds_curpartcnt += index;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
4656d4747c8743290bfbe910c64cd75eb4e4af8dGarrett D'Amore (void) snprintf(cmd, sizeof (cmd), "%s -icdumD -C %d",
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland CPIOPROC, (int)BLK_SIZE);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (n = esystem(cmd, ds_fd, -1)) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland rpterr();
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland progerr(pkg_gt(ERR_UNPACK));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland logerr(pkg_gt(MSG_CMDFAIL), cmd, n);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (ds_read == 0)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland nparts = 0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland else
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland nparts = ds_toc->nparts;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (n || (n = ckvolseq(instdir, ds_read + 1, nparts))) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (ds_volno == 1 || ds_volpart > ds_skippart)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (-1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (n = ds_getnextvol(device))
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (n);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland continue;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ds_read++;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ds_totread++;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ds_volpart++;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (0);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*NOTREACHED*/
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Name: BIO_ds_dump
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Description: Dumps all data from the static 'ds_fd' file handle into
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * the supplied BIO.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Arguments: err - where to record any errors.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * device - Description of device being dumped into,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * for error reporting
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * bio - BIO object to dump data into
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Returns : zero - successfully dumped all data to EOF
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * non-zero - some failure occurred.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandint
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah WaterlandBIO_ds_dump(PKG_ERR *err, char *device, BIO *bio)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int amtread;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland char readbuf[BLK_SIZE];
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * note this will read to the end of the device, so it won't
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * work for character devices since we don't know when the
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * end of the CPIO archive is
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland while ((amtread = read(ds_fd, readbuf, BLK_SIZE)) != 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (BIO_write(bio, readbuf, amtread) != amtread) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland pkgerr_add(err, PKGERR_WRITE, ERR_WRITE, device,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ERR_error_string(ERR_get_error(), NULL));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (0);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*NOTREACHED*/
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Name: BIO_ds_dump_header
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Description: Dumps all ds_headsize bytes from the
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * static 'ds_header_raw' character array
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * to the supplied BIO.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Arguments: err - where to record any errors.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * bio - BIO object to dump data into
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Returns : zero - successfully dumped all raw
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * header characters
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * non-zero - some failure occurred.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandint
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah WaterlandBIO_ds_dump_header(PKG_ERR *err, BIO *bio)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland char zeros[BLK_SIZE];
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
4656d4747c8743290bfbe910c64cd75eb4e4af8dGarrett D'Amore (void) memset(zeros, 0, BLK_SIZE);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (BIO_write(bio, ds_header_raw, ds_headsize) != ds_headsize) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland pkgerr_add(err, PKGERR_WRITE, ERR_WRITE, "bio",
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ERR_error_string(ERR_get_error(), NULL));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (0);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * ds_ginit: Determine the device being accessed, set the buffer size,
4656d4747c8743290bfbe910c64cd75eb4e4af8dGarrett D'Amore * and perform any device specific initialization.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandint
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandds_ginit(char *device)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int oflag;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland char *pbufsize, cmd[CMDSIZ];
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int fd2, fd;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if ((pbufsize = devattr(device, "bufsize")) != NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ds_bufsize = atoi(pbufsize);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) free(pbufsize);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland } else
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ds_bufsize = BLK_SIZE;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland oflag = fcntl(ds_fd, F_GETFL, 0);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (ds_bufsize > BLK_SIZE) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (oflag & O_WRONLY)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland fd = 1;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland else
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland fd = 0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland fd2 = fcntl(fd, F_DUPFD, fd);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) close(fd);
4656d4747c8743290bfbe910c64cd75eb4e4af8dGarrett D'Amore (void) fcntl(ds_fd, F_DUPFD, fd);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (fd)
4656d4747c8743290bfbe910c64cd75eb4e4af8dGarrett D'Amore (void) snprintf(cmd, sizeof (cmd),
4656d4747c8743290bfbe910c64cd75eb4e4af8dGarrett D'Amore "%s obs=%d 2>/dev/null", DDPROC, ds_bufsize);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland else
4656d4747c8743290bfbe910c64cd75eb4e4af8dGarrett D'Amore (void) snprintf(cmd, sizeof (cmd),
4656d4747c8743290bfbe910c64cd75eb4e4af8dGarrett D'Amore "%s ibs=%d 2>/dev/null", DDPROC, ds_bufsize);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if ((ds_pp = popen(cmd, fd ? "w" : "r")) == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland progerr(pkg_gt(ERR_TRANSFER));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland logerr(pkg_gt(MSG_POPEN), cmd, errno);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (-1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) close(fd);
4656d4747c8743290bfbe910c64cd75eb4e4af8dGarrett D'Amore (void) fcntl(fd2, F_DUPFD, fd);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) close(fd2);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ds_realfd = ds_fd;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ds_fd = fileno(ds_pp);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (ds_bufsize);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandint
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandds_close(int pkgendflg)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int n, ret = 0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (pkgendflg) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (ds_header)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) free(ds_header);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ds_header = (char *)NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ds_totread = 0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (ds_pp) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) pclose(ds_pp);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ds_pp = 0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) close(ds_realfd);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ds_realfd = -1;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ds_fd = -1;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland } else if (ds_fd >= 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) close(ds_fd);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ds_fd = -1;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (ds_device) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* rewind device */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if ((n = open(ds_device, 0)) >= 0)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) close(n);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ds_device = NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (ret);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}