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