/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
*/
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/sysmacros.h>
#include <errno.h>
#include <fcntl.h>
#ifdef u3b2
#endif /* u3b2 */
#include "pkglib.h"
#include "pkglibmsgs.h"
#include "pkglocale.h"
#ifdef u3b2
static
static char ds_ctcflg;
#endif /* u3b2 */
/* libadm.a */
int presvr4flg);
/* device types */
struct dstoc {
int cnt;
int nparts;
long maxsiz;
static char *ds_device;
/* including skipped parts */
static int ds_bufsize;
static int ds_getnextvol(char *device);
void
{
ds_totread += parts;
}
void
{
register int j, n;
char *pt;
n = 0;
while (toc_pt) {
for (j = n; list[j]; j++) {
/* just swap places in the array */
}
}
}
}
static char *pds_header;
static char *ds_header;
static char *ds_header_raw;
static int ds_headsize;
static char *
{
int length;
char *nextp;
return (0);
return (0);
return (0);
ds_headsize += BLK_SIZE;
return (0);
*nextp = '\0';
return (0);
return (buf);
}
*nextp = '\0';
return (0);
return (buf);
}
/*
* function to determine if media is datastream or mounted
* floppy
*/
int
{
if (ds_fd >= 0)
(void) ds_close(0);
return (0);
}
(void) ds_close(0);
return (0);
}
return (1);
} else if (ds_fd >= 0) {
ds_fd = -1;
}
return (0);
}
/*
* Determine how many additional volumes are needed for current package.
* Note: a 0 will occur as first volume number when the package begins
* on the next volume.
*/
static int
{
volcnt = 0;
sum = curpartcnt;
volcnt++;
}
/* side effect - set number of parts read on current volume */
ds_volpart = index;
return (volcnt);
}
return (0);
}
/* initialize ds_curpartcnt and ds_volnos */
static void
ds_pkginit(void)
{
else
ds_curpartcnt = -1;
}
/*
* functions to pass current package info to exec'ed program
*/
void
{
}
int
{
ds_pkginit();
}
/*
* Return true if the file descriptor (ds_fd) is open on the package stream.
*/
ds_fd_open(void)
{
}
/*
* Read the source device. Acquire the header data and check it for validity.
*/
int
{
char *ret;
if (!ds_header) { /* If the header hasn't been read yet */
if (ds_fd >= 0)
(void) ds_close(0);
/* always start with rewind device */
return (-1);
}
/* allocate room for the header equivalent to a block */
return (-1);
}
/* initialize the device */
(void) ds_close(0);
return (-1);
}
/* read a logical block from the source device */
rpterr();
(void) ds_close(0);
return (-1);
}
/*
* This loop scans the medium for the start of the header.
* If the above read worked, we skip this. If it did't, this
* loop will retry the read ten times looking for the header
* marker string.
*/
/* only ten tries iff the device rewinds */
(void) ds_close(0);
return (-1);
}
/* read through to the last block */
if (count > 1)
;
/* then close the device */
(void) ds_close(0);
/* and reopen it */
return (-1);
}
/* initialize the device */
(void) ds_close(0);
return (-1);
}
/* read the block again */
rpterr();
(void) ds_close(0);
return (-1);
}
}
/* Now keep scanning until the whole header is in place. */
/* We need a bigger buffer */
(void) ds_close(0);
return (1);
}
/* clear the new memory */
BLK_SIZE);
/* read a logical block from the source device */
BLK_SIZE) {
rpterr();
(void) ds_close(0);
return (-1);
} else
}
/*
* remember rewind device for ds_close to rewind at
* close
*/
if (count >= 1)
}
/* save raw copy of header for later use in BIO_dump_header */
(void) ds_close(0);
return (1);
}
/* read datastream table of contents */
ds_volcnt = 1;
break;
continue;
if (!toc_pt) {
ecleanup();
return (-1);
}
ecleanup();
return (-1);
}
if (tail) {
} else
}
if (!ret) {
return (-1);
}
if (!ds_head) {
return (-1);
}
/* this could break, thanks to cpio command limit */
#ifndef SUNOS41
#else
#endif
n = 0;
for (i = 0; pkg[i]; i++) {
continue;
if (n == 0) {
n = 1;
}
/* extract signature too, if present. */
}
/*
* if we are extracting all packages (pkgs == NULL),
* signature will automatically be extracted
*/
rpterr();
return (-1);
}
ds_totread = 0;
ds_volno = 1;
return (0);
}
int
{
return (-1);
}
return (-1);
}
nskip = 0;
ds_volno = 1;
ds_volpart = 0;
while (ds_toc) {
break;
}
if (!ds_toc) {
return (-1);
}
ds_pkginit();
ds_skippart = 0;
if (ds_curpartcnt > 0) {
/*
* skip past archives belonging to last package on current
* volume
*/
return (-1);
return (-1);
} else if (ds_curpartcnt < 0) {
return (-1);
} else
ds_totread = nskip;
ds_read = 0;
return (ds_nparts);
}
/*
* Get datastream part
* Call for first part should be preceded by
* call to ds_findpkg
*/
int
{
return (2);
if (ds_read == n)
return (0);
return (2);
if (ds_maxsiz > 0) {
return (-1);
}
#ifdef SUNOS41
#else /* !SUNOS41 */
#endif /* SUNOS41 */
return (-1);
}
}
}
static int
{
int n;
if (ds_close(0))
return (-1);
pkg_gt("Insert %%v %d of %d into %%p"),
return (n);
return (-1);
(void) ds_close(0);
return (-1);
}
ds_volpart = 0;
return (0);
}
/*
* called by ds_findpkg to skip past archives for unwanted packages
* in current volume
*/
static int
{
while (nskip--) {
/* skip this one */
rpterr();
return (n);
if (n = ds_getnextvol(device))
return (n);
}
}
ds_totread += onskip;
ds_volpart = onskip;
return (0);
}
/* skip to end of package if necessary */
void
{
}
int
{
/*CONSTCOND*/
while (1) {
ds_volno++;
if (n = ds_getnextvol(device))
return (n);
ds_curpartcnt += index;
}
rpterr();
}
if (ds_read == 0)
nparts = 0;
else
return (-1);
if (n = ds_getnextvol(device))
return (n);
continue;
}
ds_read++;
ds_totread++;
ds_volpart++;
return (0);
}
/*NOTREACHED*/
}
/*
* Name: BIO_ds_dump
* Description: Dumps all data from the static 'ds_fd' file handle into
* the supplied BIO.
*
* Arguments: err - where to record any errors.
* device - Description of device being dumped into,
* for error reporting
* bio - BIO object to dump data into
*
* Returns : zero - successfully dumped all data to EOF
* non-zero - some failure occurred.
*/
int
{
int amtread;
/*
* note this will read to the end of the device, so it won't
* work for character devices since we don't know when the
* end of the CPIO archive is
*/
return (1);
}
}
return (0);
/*NOTREACHED*/
}
/*
* Name: BIO_ds_dump_header
* Description: Dumps all ds_headsize bytes from the
* static 'ds_header_raw' character array
* to the supplied BIO.
*
* Arguments: err - where to record any errors.
* bio - BIO object to dump data into
*
* Returns : zero - successfully dumped all raw
* header characters
* non-zero - some failure occurred.
*/
int
{
return (1);
}
return (0);
}
/*
* ds_ginit: Determine the device being accessed, set the buffer size,
* and perform any device specific initialization. For the 3B2,
* a device with major number of 17 (0x11) is an internal hard disk,
* unless the minor number is 128 (0x80) in which case it is an internal
* floppy disk. Otherwise, get the system configuration
* table and check it by comparing slot numbers to major numbers.
* For the special case of the 3B2 CTC several unusual things must be done.
* To enable
* streaming mode on the CTC, the file descriptor must be closed, re-opened
* (with O_RDWR and O_CTSPECIAL flags set), the STREAMON ioctl(2) command
* issued, and the file descriptor re-re-opened either read-only or write_only.
*/
int
{
#ifdef u3b2
int devtype;
#endif /* u3b2 */
int oflag;
} else
#ifdef u3b2
return (-1);
goto lab;
/*
* We'll have to add a remote attribute to stat but this should
* work for now.
*/
goto lab;
if (min & 0x80)
else
} else {
-1)
return (-1);
return (-1);
for (i = 0; i < count; i++) {
break;
== 0) {
break;
}
/* other possible devices can go here */
}
table++;
}
}
switch (devtype) {
case G_3B2_CTC: /* do special CTC initialization */
ds_bufsize = -1;
break;
}
if ((ds_fd =
rpterr();
return (-1);
}
ds_bufsize = 15872;
}
} else
ds_bufsize = -1;
/* Have already read in first block of header */
ds_ctcflg = 1;
break;
case G_NO_DEV:
case G_3B2_HD:
case G_3B2_FD:
case G_TAPE:
case G_SCSI_HD: /* not developed yet */
case G_SCSI_FD:
case G_SCSI_9T:
case G_SCSI_Q24:
case G_SCSI_Q120:
case G_386_HD:
case G_386_FD:
case G_386_Q24:
break;
default:
ds_bufsize = -1;
} /* devtype */
lab:
#endif /* u3b2 */
if (ds_bufsize > BLK_SIZE) {
fd = 1;
else
fd = 0;
if (fd)
else
return (-1);
}
}
return (ds_bufsize);
}
int
{
#ifdef u3b2
char *ptr;
#endif /* u3b2 */
int n, ret = 0;
#ifdef u3b2
ds_ctcflg = 0;
ret = -1;
/*
* pipe to dd write process,
* make sure one more buffer
* gets written out
*/
ret = -1;
/* pad to bufsize */
} else {
cnt = ds_bufsize;
while (cnt > 0) {
BLK_SIZE)) < 0) {
ret = -1;
break;
}
cnt -= n;
}
}
}
}
#endif
if (pkgendflg) {
if (ds_header)
ds_totread = 0;
}
if (ds_pp) {
ds_pp = 0;
ds_realfd = -1;
ds_fd = -1;
} else if (ds_fd >= 0) {
ds_fd = -1;
}
if (ds_device) {
/* rewind device */
(void) close(n);
}
return (ret);
}