ar_io.c revision 114583
155714Skris/*-
255714Skris * Copyright (c) 1992 Keith Muller.
355714Skris * Copyright (c) 1992, 1993
455714Skris *	The Regents of the University of California.  All rights reserved.
555714Skris *
655714Skris * This code is derived from software contributed to Berkeley by
755714Skris * Keith Muller of the University of California, San Diego.
855714Skris *
955714Skris * Redistribution and use in source and binary forms, with or without
1055714Skris * modification, are permitted provided that the following conditions
1155714Skris * are met:
1255714Skris * 1. Redistributions of source code must retain the above copyright
1355714Skris *    notice, this list of conditions and the following disclaimer.
1455714Skris * 2. Redistributions in binary form must reproduce the above copyright
1555714Skris *    notice, this list of conditions and the following disclaimer in the
1655714Skris *    documentation and/or other materials provided with the distribution.
1755714Skris * 3. All advertising materials mentioning features or use of this software
1855714Skris *    must display the following acknowledgement:
1955714Skris *	This product includes software developed by the University of
2055714Skris *	California, Berkeley and its contributors.
2155714Skris * 4. Neither the name of the University nor the names of its contributors
2255714Skris *    may be used to endorse or promote products derived from this software
2355714Skris *    without specific prior written permission.
2455714Skris *
2555714Skris * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2655714Skris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2755714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2855714Skris * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2955714Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
3055714Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
3155714Skris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
3255714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3355714Skris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3455714Skris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3555714Skris * SUCH DAMAGE.
3655714Skris */
3755714Skris
3855714Skris#ifndef lint
3955714Skris#if 0
4055714Skrisstatic char sccsid[] = "@(#)ar_io.c	8.2 (Berkeley) 4/18/94";
4155714Skris#endif
4255714Skris#endif /* not lint */
4355714Skris#include <sys/cdefs.h>
4455714Skris__FBSDID("$FreeBSD: head/bin/pax/ar_io.c 114583 2003-05-03 16:39:34Z markm $");
4555714Skris
4655714Skris#include <sys/types.h>
4755714Skris#include <sys/ioctl.h>
4855714Skris#include <sys/mtio.h>
4955714Skris#include <sys/stat.h>
5055714Skris#include <sys/wait.h>
5155714Skris#include <err.h>
5255714Skris#include <errno.h>
5355714Skris#include <fcntl.h>
5455714Skris#include <signal.h>
5555714Skris#include <stdint.h>
5655714Skris#include <stdio.h>
5755714Skris#include <string.h>
5855714Skris#include <stdlib.h>
5955714Skris#include <unistd.h>
6055714Skris#include "pax.h"
61194206Ssimon#include "options.h"
62194206Ssimon#include "extern.h"
63194206Ssimon
6455714Skris/*
6555714Skris * Routines which deal directly with the archive I/O device/file.
66167612Ssimon */
6755714Skris
68194206Ssimon#define DMOD		0666		/* default mode of created archives */
69194206Ssimon#define EXT_MODE	O_RDONLY	/* open mode for list/extract */
70194206Ssimon#define AR_MODE		(O_WRONLY | O_CREAT | O_TRUNC)	/* mode for archive */
71194206Ssimon#define APP_MODE	O_RDWR		/* mode for append */
72194206Ssimon
73194206Ssimonstatic char none[] = "<NONE>";		/* pseudo name for no file */
74160814Ssimonstatic char stdo[] = "<STDOUT>";	/* pseudo name for stdout */
7555714Skrisstatic char stdn[] = "<STDIN>";		/* pseudo name for stdin */
7655714Skrisstatic int arfd = -1;			/* archive file descriptor */
7755714Skrisstatic int artyp = ISREG;		/* archive type: file/FIFO/tape */
7855714Skrisstatic int arvol = 1;			/* archive volume number */
7955714Skrisstatic int lstrval = -1;		/* return value from last i/o */
8055714Skrisstatic int io_ok;			/* i/o worked on volume after resync */
8155714Skrisstatic int did_io;			/* did i/o ever occur on volume? */
8255714Skrisstatic int done;			/* set via tty termination */
8355714Skrisstatic struct stat arsb;		/* stat of archive device at open */
8455714Skrisstatic int invld_rec;			/* tape has out of spec record size */
8555714Skrisstatic int wr_trail = 1;		/* trailer was rewritten in append */
8655714Skrisstatic int can_unlnk = 0;		/* do we unlink null archives?  */
8755714Skrisconst char *arcname;		  	/* printable name of archive */
88160814Ssimonconst char *gzip_program;		/* name of gzip program */
8955714Skrisstatic pid_t zpid = -1;			/* pid of child process */
9055714Skris
9155714Skrisstatic int get_phys(void);
9255714Skrisextern sigset_t s_mask;
9355714Skrisstatic void ar_start_gzip(int, const char *, int);
9455714Skris
95160814Ssimon/*
96160814Ssimon * ar_open()
97160814Ssimon *	Opens the next archive volume. Determines the type of the device and
98160814Ssimon *	sets up block sizes as required by the archive device and the format.
9955714Skris *	Note: we may be called with name == NULL on the first open only.
10055714Skris * Return:
10155714Skris *	-1 on failure, 0 otherwise
10255714Skris */
10355714Skris
10455714Skrisint
10555714Skrisar_open(const char *name)
10655714Skris{
10755714Skris	struct mtget mb;
10855714Skris
10955714Skris	if (arfd != -1)
11055714Skris		(void)close(arfd);
11155714Skris	arfd = -1;
11255714Skris	can_unlnk = did_io = io_ok = invld_rec = 0;
11355714Skris	artyp = ISREG;
11455714Skris	flcnt = 0;
11555714Skris
11655714Skris	/*
11755714Skris	 * open based on overall operation mode
11855714Skris	 */
11955714Skris	switch (act) {
12055714Skris	case LIST:
12155714Skris	case EXTRACT:
12255714Skris		if (name == NULL) {
12359191Skris			arfd = STDIN_FILENO;
12459191Skris			arcname = stdn;
12559191Skris		} else if ((arfd = open(name, EXT_MODE, DMOD)) < 0)
12659191Skris			syswarn(0, errno, "Failed open to read on %s", name);
12759191Skris		if (arfd != -1 && gzip_program != NULL)
12855714Skris			ar_start_gzip(arfd, gzip_program, 0);
129194206Ssimon		break;
130194206Ssimon	case ARCHIVE:
131194206Ssimon		if (name == NULL) {
132194206Ssimon			arfd = STDOUT_FILENO;
133194206Ssimon			arcname = stdo;
134194206Ssimon		} else if ((arfd = open(name, AR_MODE, DMOD)) < 0)
135194206Ssimon			syswarn(0, errno, "Failed open to write on %s", name);
136194206Ssimon		else
137194206Ssimon			can_unlnk = 1;
138194206Ssimon		if (arfd != -1 && gzip_program != NULL)
139194206Ssimon			ar_start_gzip(arfd, gzip_program, 1);
140194206Ssimon		break;
141194206Ssimon	case APPND:
142194206Ssimon		if (name == NULL) {
143194206Ssimon			arfd = STDOUT_FILENO;
144194206Ssimon			arcname = stdo;
145194206Ssimon		} else if ((arfd = open(name, APP_MODE, DMOD)) < 0)
146194206Ssimon			syswarn(0, errno, "Failed open to read/write on %s",
147194206Ssimon				name);
148194206Ssimon		break;
149194206Ssimon	case COPY:
150194206Ssimon		/*
151194206Ssimon		 * arfd not used in COPY mode
152194206Ssimon		 */
153194206Ssimon		arcname = none;
154194206Ssimon		lstrval = 1;
155194206Ssimon		return(0);
156194206Ssimon	}
157194206Ssimon	if (arfd < 0)
158194206Ssimon		return(-1);
159194206Ssimon
160194206Ssimon	if (chdname != NULL)
161194206Ssimon		if (chdir(chdname) != 0)
162194206Ssimon			syswarn(1, errno, "Failed chdir to %s", chdname);
163194206Ssimon	/*
164194206Ssimon	 * set up is based on device type
165194206Ssimon	 */
166194206Ssimon	if (fstat(arfd, &arsb) < 0) {
167194206Ssimon		syswarn(0, errno, "Failed stat on %s", arcname);
168194206Ssimon		(void)close(arfd);
169194206Ssimon		arfd = -1;
170194206Ssimon		can_unlnk = 0;
171194206Ssimon		return(-1);
172194206Ssimon	}
173194206Ssimon	if (S_ISDIR(arsb.st_mode)) {
174194206Ssimon		paxwarn(0, "Cannot write an archive on top of a directory %s",
175194206Ssimon		    arcname);
176194206Ssimon		(void)close(arfd);
177194206Ssimon		arfd = -1;
178194206Ssimon		can_unlnk = 0;
179194206Ssimon		return(-1);
180194206Ssimon	}
181194206Ssimon
182194206Ssimon	if (S_ISCHR(arsb.st_mode))
183194206Ssimon		artyp = ioctl(arfd, MTIOCGET, &mb) ? ISCHR : ISTAPE;
184194206Ssimon	else if (S_ISBLK(arsb.st_mode))
185194206Ssimon		artyp = ISBLK;
186194206Ssimon	else if ((lseek(arfd, (off_t)0L, SEEK_CUR) == -1) && (errno == ESPIPE))
187194206Ssimon		artyp = ISPIPE;
188194206Ssimon	else
189194206Ssimon		artyp = ISREG;
190194206Ssimon
191194206Ssimon	/*
192194206Ssimon	 * make sure we beyond any doubt that we only can unlink regular files
193194206Ssimon	 * we created
194194206Ssimon	 */
195194206Ssimon	if (artyp != ISREG)
196194206Ssimon		can_unlnk = 0;
197194206Ssimon	/*
198194206Ssimon	 * if we are writing, we are done
199194206Ssimon	 */
200194206Ssimon	if (act == ARCHIVE) {
201194206Ssimon		blksz = rdblksz = wrblksz;
202194206Ssimon		lstrval = 1;
203194206Ssimon		return(0);
204194206Ssimon	}
205194206Ssimon
206194206Ssimon	/*
207194206Ssimon	 * set default blksz on read. APPNDs writes rdblksz on the last volume
208194206Ssimon	 * On all new archive volumes, we shift to wrblksz (if the user
209194206Ssimon	 * specified one, otherwize we will continue to use rdblksz). We
210194206Ssimon	 * must to set blocksize based on what kind of device the archive is
211194206Ssimon	 * stored.
212194206Ssimon	 */
213194206Ssimon	switch(artyp) {
214194206Ssimon	case ISTAPE:
215194206Ssimon		/*
216194206Ssimon		 * Tape drives come in at least two flavors. Those that support
217194206Ssimon		 * variable sized records and those that have fixed sized
218194206Ssimon		 * records. They must be treated differently. For tape drives
219194206Ssimon		 * that support variable sized records, we must make large
220194206Ssimon		 * reads to make sure we get the entire record, otherwise we
221194206Ssimon		 * will just get the first part of the record (up to size we
222194206Ssimon		 * asked). Tapes with fixed sized records may or may not return
223194206Ssimon		 * multiple records in a single read. We really do not care
224194206Ssimon		 * what the physical record size is UNLESS we are going to
225194206Ssimon		 * append. (We will need the physical block size to rewrite
226194206Ssimon		 * the trailer). Only when we are appending do we go to the
227194206Ssimon		 * effort to figure out the true PHYSICAL record size.
228194206Ssimon		 */
229194206Ssimon		blksz = rdblksz = MAXBLK;
230194206Ssimon		break;
231194206Ssimon	case ISPIPE:
232194206Ssimon	case ISBLK:
233194206Ssimon	case ISCHR:
234194206Ssimon		/*
235194206Ssimon		 * Blocksize is not a major issue with these devices (but must
236194206Ssimon		 * be kept a multiple of 512). If the user specified a write
237194206Ssimon		 * block size, we use that to read. Under append, we must
238194206Ssimon		 * always keep blksz == rdblksz. Otherwise we go ahead and use
239194206Ssimon		 * the device optimal blocksize as (and if) returned by stat
240194206Ssimon		 * and if it is within pax specs.
241194206Ssimon		 */
242194206Ssimon		if ((act == APPND) && wrblksz) {
243194206Ssimon			blksz = rdblksz = wrblksz;
244194206Ssimon			break;
245194206Ssimon		}
246194206Ssimon
247194206Ssimon		if ((arsb.st_blksize > 0) && (arsb.st_blksize < MAXBLK) &&
248194206Ssimon		    ((arsb.st_blksize % BLKMULT) == 0))
249194206Ssimon			rdblksz = arsb.st_blksize;
250194206Ssimon		else
251194206Ssimon			rdblksz = DEVBLK;
252194206Ssimon		/*
253194206Ssimon		 * For performance go for large reads when we can without harm
254194206Ssimon		 */
255194206Ssimon		if ((act == APPND) || (artyp == ISCHR))
256194206Ssimon			blksz = rdblksz;
257194206Ssimon		else
258194206Ssimon			blksz = MAXBLK;
259194206Ssimon		break;
260194206Ssimon	case ISREG:
261194206Ssimon		/*
262194206Ssimon		 * if the user specified wrblksz works, use it. Under appends
263194206Ssimon		 * we must always keep blksz == rdblksz
264194206Ssimon		 */
265194206Ssimon		if ((act == APPND) && wrblksz && ((arsb.st_size%wrblksz)==0)){
266194206Ssimon			blksz = rdblksz = wrblksz;
267194206Ssimon			break;
268194206Ssimon		}
269194206Ssimon		/*
270194206Ssimon		 * See if we can find the blocking factor from the file size
271194206Ssimon		 */
272194206Ssimon		for (rdblksz = MAXBLK; rdblksz > 0; rdblksz -= BLKMULT)
273194206Ssimon			if ((arsb.st_size % rdblksz) == 0)
274194206Ssimon				break;
275194206Ssimon		/*
276194206Ssimon		 * When we cannot find a match, we may have a flawed archive.
277194206Ssimon		 */
278194206Ssimon		if (rdblksz <= 0)
279194206Ssimon			rdblksz = FILEBLK;
280194206Ssimon		/*
281194206Ssimon		 * for performance go for large reads when we can
282194206Ssimon		 */
283194206Ssimon		if (act == APPND)
284194206Ssimon			blksz = rdblksz;
285194206Ssimon		else
286194206Ssimon			blksz = MAXBLK;
287194206Ssimon		break;
288194206Ssimon	default:
289194206Ssimon		/*
290194206Ssimon		 * should never happen, worse case, slow...
291194206Ssimon		 */
292194206Ssimon		blksz = rdblksz = BLKMULT;
293194206Ssimon		break;
294194206Ssimon	}
295194206Ssimon	lstrval = 1;
296194206Ssimon	return(0);
297194206Ssimon}
298194206Ssimon
299194206Ssimon/*
300194206Ssimon * ar_close()
301194206Ssimon *	closes archive device, increments volume number, and prints i/o summary
302194206Ssimon */
303194206Ssimonvoid
304194206Ssimonar_close(void)
305194206Ssimon{
306194206Ssimon
307194206Ssimon	if (arfd < 0) {
308194206Ssimon		did_io = io_ok = flcnt = 0;
309194206Ssimon		return;
310194206Ssimon	}
311194206Ssimon
312194206Ssimon	/*
313194206Ssimon	 * Close archive file. This may take a LONG while on tapes (we may be
314194206Ssimon	 * forced to wait for the rewind to complete) so tell the user what is
315194206Ssimon	 * going on (this avoids the user hitting control-c thinking pax is
316194206Ssimon	 * broken).
317194206Ssimon	 */
318194206Ssimon	if (vflag && (artyp == ISTAPE)) {
319194206Ssimon		if (vfpart)
320194206Ssimon			(void)putc('\n', listf);
321194206Ssimon		(void)fprintf(listf,
322194206Ssimon			"%s: Waiting for tape drive close to complete...",
323194206Ssimon			argv0);
324194206Ssimon		(void)fflush(listf);
325194206Ssimon	}
326194206Ssimon
327194206Ssimon	/*
328194206Ssimon	 * if nothing was written to the archive (and we created it), we remove
329194206Ssimon	 * it
330194206Ssimon	 */
331194206Ssimon	if (can_unlnk && (fstat(arfd, &arsb) == 0) && (S_ISREG(arsb.st_mode)) &&
332194206Ssimon	    (arsb.st_size == 0)) {
333194206Ssimon		(void)unlink(arcname);
334194206Ssimon		can_unlnk = 0;
335194206Ssimon	}
336194206Ssimon
337194206Ssimon	/*
338194206Ssimon	 * for a quick extract/list, pax frequently exits before the child
339194206Ssimon	 * process is done
340194206Ssimon	 */
341194206Ssimon	if ((act == LIST || act == EXTRACT) && nflag && zpid > 0) {
342194206Ssimon		int status;
343194206Ssimon		kill(zpid, SIGINT);
344194206Ssimon		waitpid(zpid, &status, 0);
345194206Ssimon	}
346194206Ssimon
347194206Ssimon	(void)close(arfd);
348194206Ssimon
349194206Ssimon	if (vflag && (artyp == ISTAPE)) {
350194206Ssimon		(void)fputs("done.\n", listf);
351194206Ssimon		vfpart = 0;
352194206Ssimon		(void)fflush(listf);
353194206Ssimon	}
354194206Ssimon	arfd = -1;
355194206Ssimon
356194206Ssimon	if (!io_ok && !did_io) {
357194206Ssimon		flcnt = 0;
358194206Ssimon		return;
359194206Ssimon	}
360194206Ssimon	did_io = io_ok = 0;
361194206Ssimon
362194206Ssimon	/*
363194206Ssimon	 * The volume number is only increased when the last device has data
364194206Ssimon	 * and we have already determined the archive format.
365194206Ssimon	 */
366194206Ssimon	if (frmt != NULL)
367194206Ssimon		++arvol;
368194206Ssimon
369194206Ssimon	if (!vflag) {
370194206Ssimon		flcnt = 0;
371194206Ssimon		return;
372194206Ssimon	}
373194206Ssimon
374194206Ssimon	/*
375194206Ssimon	 * Print out a summary of I/O for this archive volume.
376194206Ssimon	 */
377194206Ssimon	if (vfpart) {
378194206Ssimon		(void)putc('\n', listf);
379194206Ssimon		vfpart = 0;
380194206Ssimon	}
381194206Ssimon
382194206Ssimon	/*
383194206Ssimon	 * If we have not determined the format yet, we just say how many bytes
384194206Ssimon	 * we have skipped over looking for a header to id. there is no way we
385194206Ssimon	 * could have written anything yet.
386194206Ssimon	 */
387194206Ssimon	if (frmt == NULL) {
388194206Ssimon#	ifdef NET2_STAT
389194206Ssimon		(void)fprintf(listf, "%s: unknown format, %lu bytes skipped.\n",
390194206Ssimon		    argv0, rdcnt);
391194206Ssimon#	else
392194206Ssimon		(void)fprintf(listf, "%s: unknown format, %ju bytes skipped.\n",
393194206Ssimon		    argv0, (uintmax_t)rdcnt);
394194206Ssimon#	endif
395194206Ssimon		(void)fflush(listf);
396194206Ssimon		flcnt = 0;
397194206Ssimon		return;
398194206Ssimon	}
399194206Ssimon
400194206Ssimon	if (strcmp(NM_CPIO, argv0) == 0)
401194206Ssimon		(void)fprintf(listf, "%llu blocks\n",
402194206Ssimon		    (unsigned long long)((rdcnt ? rdcnt : wrcnt) / 5120));
403194206Ssimon	else if (strcmp(NM_TAR, argv0) != 0)
404194206Ssimon		(void)fprintf(listf,
405194206Ssimon#	ifdef NET2_STAT
406194206Ssimon		    "%s: %s vol %d, %lu files, %lu bytes read, %lu bytes written.\n",
407194206Ssimon		    argv0, frmt->name, arvol-1, flcnt, rdcnt, wrcnt);
408194206Ssimon#	else
409194206Ssimon		    "%s: %s vol %d, %ju files, %ju bytes read, %ju bytes written.\n",
410194206Ssimon		    argv0, frmt->name, arvol-1, (uintmax_t)flcnt,
411194206Ssimon		    (uintmax_t)rdcnt, (uintmax_t)wrcnt);
412194206Ssimon#	endif
413194206Ssimon	(void)fflush(listf);
414194206Ssimon	flcnt = 0;
415194206Ssimon}
416194206Ssimon
417194206Ssimon/*
418194206Ssimon * ar_drain()
419194206Ssimon *	drain any archive format independent padding from an archive read
420194206Ssimon *	from a socket or a pipe. This is to prevent the process on the
421194206Ssimon *	other side of the pipe from getting a SIGPIPE (pax will stop
422194206Ssimon *	reading an archive once a format dependent trailer is detected).
423194206Ssimon */
424194206Ssimonvoid
425194206Ssimonar_drain(void)
426194206Ssimon{
427194206Ssimon	int res;
428194206Ssimon	char drbuf[MAXBLK];
429194206Ssimon
430194206Ssimon	/*
431194206Ssimon	 * we only drain from a pipe/socket. Other devices can be closed
432194206Ssimon	 * without reading up to end of file. We sure hope that pipe is closed
433194206Ssimon	 * on the other side so we will get an EOF.
434194206Ssimon	 */
435194206Ssimon	if ((artyp != ISPIPE) || (lstrval <= 0))
436194206Ssimon		return;
437194206Ssimon
438194206Ssimon	/*
439194206Ssimon	 * keep reading until pipe is drained
440194206Ssimon	 */
441194206Ssimon	while ((res = read(arfd, drbuf, sizeof(drbuf))) > 0)
442194206Ssimon		;
443194206Ssimon	lstrval = res;
444194206Ssimon}
445194206Ssimon
446194206Ssimon/*
447194206Ssimon * ar_set_wr()
448194206Ssimon *	Set up device right before switching from read to write in an append.
449194206Ssimon *	device dependent code (if required) to do this should be added here.
450194206Ssimon *	For all archive devices we are already positioned at the place we want
451194206Ssimon *	to start writing when this routine is called.
452194206Ssimon * Return:
453194206Ssimon *	0 if all ready to write, -1 otherwise
454194206Ssimon */
455194206Ssimon
456194206Ssimonint
457194206Ssimonar_set_wr(void)
458194206Ssimon{
459194206Ssimon	off_t cpos;
460194206Ssimon
461194206Ssimon	/*
462194206Ssimon	 * we must make sure the trailer is rewritten on append, ar_next()
463194206Ssimon	 * will stop us if the archive containing the trailer was not written
464194206Ssimon	 */
465194206Ssimon	wr_trail = 0;
466194206Ssimon
467194206Ssimon	/*
468194206Ssimon	 * Add any device dependent code as required here
469194206Ssimon	 */
470194206Ssimon	if (artyp != ISREG)
471194206Ssimon		return(0);
472194206Ssimon	/*
473194206Ssimon	 * Ok we have an archive in a regular file. If we were rewriting a
474194206Ssimon	 * file, we must get rid of all the stuff after the current offset
475194206Ssimon	 * (it was not written by pax).
476194206Ssimon	 */
477194206Ssimon	if (((cpos = lseek(arfd, (off_t)0L, SEEK_CUR)) < 0) ||
478194206Ssimon	    (ftruncate(arfd, cpos) < 0)) {
479194206Ssimon		syswarn(1, errno, "Unable to truncate archive file");
480194206Ssimon		return(-1);
481194206Ssimon	}
482194206Ssimon	return(0);
483194206Ssimon}
484194206Ssimon
485194206Ssimon/*
486194206Ssimon * ar_app_ok()
487194206Ssimon *	check if the last volume in the archive allows appends. We cannot check
488194206Ssimon *	this until we are ready to write since there is no spec that says all
489194206Ssimon *	volumes in a single archive have to be of the same type...
490194206Ssimon * Return:
491194206Ssimon *	0 if we can append, -1 otherwise.
492194206Ssimon */
493194206Ssimon
494194206Ssimonint
495194206Ssimonar_app_ok(void)
496194206Ssimon{
497194206Ssimon	if (artyp == ISPIPE) {
498194206Ssimon		paxwarn(1, "Cannot append to an archive obtained from a pipe.");
499194206Ssimon		return(-1);
500194206Ssimon	}
501194206Ssimon
502194206Ssimon	if (!invld_rec)
503194206Ssimon		return(0);
504194206Ssimon	paxwarn(1,"Cannot append, device record size %d does not support %s spec",
505194206Ssimon		rdblksz, argv0);
506194206Ssimon	return(-1);
507194206Ssimon}
508194206Ssimon
509194206Ssimon/*
510194206Ssimon * ar_read()
511194206Ssimon *	read up to a specified number of bytes from the archive into the
512194206Ssimon *	supplied buffer. When dealing with tapes we may not always be able to
513194206Ssimon *	read what we want.
514194206Ssimon * Return:
515194206Ssimon *	Number of bytes in buffer. 0 for end of file, -1 for a read error.
516194206Ssimon */
517194206Ssimon
518194206Ssimonint
519194206Ssimonar_read(char *buf, int cnt)
520194206Ssimon{
521194206Ssimon	int res = 0;
522194206Ssimon
523194206Ssimon	/*
524194206Ssimon	 * if last i/o was in error, no more reads until reset or new volume
525194206Ssimon	 */
526194206Ssimon	if (lstrval <= 0)
527194206Ssimon		return(lstrval);
528194206Ssimon
529194206Ssimon	/*
530194206Ssimon	 * how we read must be based on device type
531194206Ssimon	 */
532194206Ssimon	switch (artyp) {
533194206Ssimon	case ISTAPE:
534194206Ssimon		if ((res = read(arfd, buf, cnt)) > 0) {
535194206Ssimon			/*
536194206Ssimon			 * CAUTION: tape systems may not always return the same
537194206Ssimon			 * sized records so we leave blksz == MAXBLK. The
538194206Ssimon			 * physical record size that a tape drive supports is
539194206Ssimon			 * very hard to determine in a uniform and portable
540194206Ssimon			 * manner.
541194206Ssimon			 */
542194206Ssimon			io_ok = 1;
543194206Ssimon			if (res != rdblksz) {
544194206Ssimon				/*
545194206Ssimon				 * Record size changed. If this is happens on
546194206Ssimon				 * any record after the first, we probably have
547194206Ssimon				 * a tape drive which has a fixed record size
548194206Ssimon				 * we are getting multiple records in a single
549194206Ssimon				 * read). Watch out for record blocking that
550194206Ssimon				 * violates pax spec (must be a multiple of
551194206Ssimon				 * BLKMULT).
552194206Ssimon				 */
553194206Ssimon				rdblksz = res;
554194206Ssimon				if (rdblksz % BLKMULT)
555194206Ssimon					invld_rec = 1;
556194206Ssimon			}
557194206Ssimon			return(res);
558194206Ssimon		}
559194206Ssimon		break;
560194206Ssimon	case ISREG:
561194206Ssimon	case ISBLK:
562194206Ssimon	case ISCHR:
563194206Ssimon	case ISPIPE:
564194206Ssimon	default:
565194206Ssimon		/*
566194206Ssimon		 * Files are so easy to deal with. These other things cannot
567194206Ssimon		 * be trusted at all. So when we are dealing with character
568194206Ssimon		 * devices and pipes we just take what they have ready for us
569194206Ssimon		 * and return. Trying to do anything else with them runs the
570194206Ssimon		 * risk of failure.
571194206Ssimon		 */
572194206Ssimon		if ((res = read(arfd, buf, cnt)) > 0) {
573194206Ssimon			io_ok = 1;
574194206Ssimon			return(res);
575194206Ssimon		}
576194206Ssimon		break;
577194206Ssimon	}
578194206Ssimon
579194206Ssimon	/*
580194206Ssimon	 * We are in trouble at this point, something is broken...
581194206Ssimon	 */
582194206Ssimon	lstrval = res;
583194206Ssimon	if (res < 0)
584194206Ssimon		syswarn(1, errno, "Failed read on archive volume %d", arvol);
585194206Ssimon	else
586194206Ssimon		paxwarn(0, "End of archive volume %d reached", arvol);
587194206Ssimon	return(res);
588194206Ssimon}
589194206Ssimon
590194206Ssimon/*
591194206Ssimon * ar_write()
592194206Ssimon *	Write a specified number of bytes in supplied buffer to the archive
593194206Ssimon *	device so it appears as a single "block". Deals with errors and tries
594194206Ssimon *	to recover when faced with short writes.
595194206Ssimon * Return:
596194206Ssimon *	Number of bytes written. 0 indicates end of volume reached and with no
597194206Ssimon *	flaws (as best that can be detected). A -1 indicates an unrecoverable
598194206Ssimon *	error in the archive occured.
599194206Ssimon */
600194206Ssimon
601194206Ssimonint
602194206Ssimonar_write(char *buf, int bsz)
603194206Ssimon{
604194206Ssimon	int res;
605194206Ssimon	off_t cpos;
606194206Ssimon
607194206Ssimon	/*
608194206Ssimon	 * do not allow pax to create a "bad" archive. Once a write fails on
609194206Ssimon	 * an archive volume prevent further writes to it.
610194206Ssimon	 */
611194206Ssimon	if (lstrval <= 0)
612194206Ssimon		return(lstrval);
613194206Ssimon
614194206Ssimon	if ((res = write(arfd, buf, bsz)) == bsz) {
615194206Ssimon		wr_trail = 1;
616194206Ssimon		io_ok = 1;
617194206Ssimon		return(bsz);
618194206Ssimon	}
619194206Ssimon	/*
620194206Ssimon	 * write broke, see what we can do with it. We try to send any partial
621194206Ssimon	 * writes that may violate pax spec to the next archive volume.
622194206Ssimon	 */
623194206Ssimon	if (res < 0)
624194206Ssimon		lstrval = res;
625194206Ssimon	else
626194206Ssimon		lstrval = 0;
627194206Ssimon
628194206Ssimon	switch (artyp) {
629194206Ssimon	case ISREG:
630194206Ssimon		if ((res > 0) && (res % BLKMULT)) {
631194206Ssimon			/*
632194206Ssimon		 	 * try to fix up partial writes which are not BLKMULT
633194206Ssimon			 * in size by forcing the runt record to next archive
634194206Ssimon			 * volume
635194206Ssimon		 	 */
636194206Ssimon			if ((cpos = lseek(arfd, (off_t)0L, SEEK_CUR)) < 0)
637194206Ssimon				break;
638194206Ssimon			cpos -= (off_t)res;
639194206Ssimon			if (ftruncate(arfd, cpos) < 0)
640194206Ssimon				break;
641194206Ssimon			res = lstrval = 0;
642194206Ssimon			break;
643194206Ssimon		}
644194206Ssimon		if (res >= 0)
645194206Ssimon			break;
646194206Ssimon		/*
647194206Ssimon		 * if file is out of space, handle it like a return of 0
648194206Ssimon		 */
649194206Ssimon		if ((errno == ENOSPC) || (errno == EFBIG) || (errno == EDQUOT))
650194206Ssimon			res = lstrval = 0;
651194206Ssimon		break;
652194206Ssimon	case ISTAPE:
653194206Ssimon	case ISCHR:
654194206Ssimon	case ISBLK:
655194206Ssimon		if (res >= 0)
656194206Ssimon			break;
657194206Ssimon		if (errno == EACCES) {
658194206Ssimon			paxwarn(0, "Write failed, archive is write protected.");
659194206Ssimon			res = lstrval = 0;
660194206Ssimon			return(0);
661194206Ssimon		}
662194206Ssimon		/*
663194206Ssimon		 * see if we reached the end of media, if so force a change to
664194206Ssimon		 * the next volume
665194206Ssimon		 */
666194206Ssimon		if ((errno == ENOSPC) || (errno == EIO) || (errno == ENXIO))
667194206Ssimon			res = lstrval = 0;
668194206Ssimon		break;
669194206Ssimon	case ISPIPE:
670194206Ssimon	default:
671194206Ssimon		/*
672194206Ssimon		 * we cannot fix errors to these devices
673194206Ssimon		 */
674194206Ssimon		break;
675194206Ssimon	}
676194206Ssimon
677194206Ssimon	/*
678194206Ssimon	 * Better tell the user the bad news...
679194206Ssimon	 * if this is a block aligned archive format, we may have a bad archive
680194206Ssimon	 * if the format wants the header to start at a BLKMULT boundary. While
681194206Ssimon	 * we can deal with the mis-aligned data, it violates spec and other
682194206Ssimon	 * archive readers will likely fail. if the format is not block
683194206Ssimon	 * aligned, the user may be lucky (and the archive is ok).
684194206Ssimon	 */
685194206Ssimon	if (res >= 0) {
686194206Ssimon		if (res > 0)
687194206Ssimon			wr_trail = 1;
688194206Ssimon		io_ok = 1;
689194206Ssimon	}
690194206Ssimon
691194206Ssimon	/*
692194206Ssimon	 * If we were trying to rewrite the trailer and it didn't work, we
693194206Ssimon	 * must quit right away.
694194206Ssimon	 */
695194206Ssimon	if (!wr_trail && (res <= 0)) {
696194206Ssimon		paxwarn(1,"Unable to append, trailer re-write failed. Quitting.");
697194206Ssimon		return(res);
698194206Ssimon	}
699194206Ssimon
700194206Ssimon	if (res == 0)
701194206Ssimon		paxwarn(0, "End of archive volume %d reached", arvol);
702194206Ssimon	else if (res < 0)
703194206Ssimon		syswarn(1, errno, "Failed write to archive volume: %d", arvol);
704194206Ssimon	else if (!frmt->blkalgn || ((res % frmt->blkalgn) == 0))
705194206Ssimon		paxwarn(0,"WARNING: partial archive write. Archive MAY BE FLAWED");
706194206Ssimon	else
707194206Ssimon		paxwarn(1,"WARNING: partial archive write. Archive IS FLAWED");
708194206Ssimon	return(res);
709194206Ssimon}
710194206Ssimon
711194206Ssimon/*
712194206Ssimon * ar_rdsync()
713194206Ssimon *	Try to move past a bad spot on a flawed archive as needed to continue
714194206Ssimon *	I/O. Clears error flags to allow I/O to continue.
715194206Ssimon * Return:
716194206Ssimon *	0 when ok to try i/o again, -1 otherwise.
717194206Ssimon */
718194206Ssimon
719194206Ssimonint
720194206Ssimonar_rdsync(void)
721194206Ssimon{
722194206Ssimon	long fsbz;
723194206Ssimon	off_t cpos;
724194206Ssimon	off_t mpos;
725194206Ssimon	struct mtop mb;
726194206Ssimon
727194206Ssimon	/*
728194206Ssimon	 * Fail resync attempts at user request (done) or this is going to be
729194206Ssimon	 * an update/append to an existing archive. If last i/o hit media end,
730194206Ssimon	 * we need to go to the next volume not try a resync.
731194206Ssimon	 */
732194206Ssimon	if ((done > 0) || (lstrval == 0))
733194206Ssimon		return(-1);
734194206Ssimon
735194206Ssimon	if ((act == APPND) || (act == ARCHIVE)) {
736194206Ssimon		paxwarn(1, "Cannot allow updates to an archive with flaws.");
737194206Ssimon		return(-1);
738194206Ssimon	}
739194206Ssimon	if (io_ok)
740194206Ssimon		did_io = 1;
741194206Ssimon
742194206Ssimon	switch(artyp) {
743194206Ssimon	case ISTAPE:
744194206Ssimon		/*
745194206Ssimon		 * if the last i/o was a successful data transfer, we assume
746194206Ssimon		 * the fault is just a bad record on the tape that we are now
747194206Ssimon		 * past. If we did not get any data since the last resync try
748194206Ssimon		 * to move the tape forward one PHYSICAL record past any
749194206Ssimon		 * damaged tape section. Some tape drives are stubborn and need
750194206Ssimon		 * to be pushed.
751194206Ssimon		 */
752194206Ssimon		if (io_ok) {
753194206Ssimon			io_ok = 0;
754194206Ssimon			lstrval = 1;
755194206Ssimon			break;
756194206Ssimon		}
757194206Ssimon		mb.mt_op = MTFSR;
758194206Ssimon		mb.mt_count = 1;
759194206Ssimon		if (ioctl(arfd, MTIOCTOP, &mb) < 0)
760194206Ssimon			break;
761194206Ssimon		lstrval = 1;
762194206Ssimon		break;
763194206Ssimon	case ISREG:
764194206Ssimon	case ISCHR:
765194206Ssimon	case ISBLK:
766194206Ssimon		/*
767194206Ssimon		 * try to step over the bad part of the device.
768194206Ssimon		 */
769194206Ssimon		io_ok = 0;
770194206Ssimon		if (((fsbz = arsb.st_blksize) <= 0) || (artyp != ISREG))
771194206Ssimon			fsbz = BLKMULT;
772194206Ssimon		if ((cpos = lseek(arfd, (off_t)0L, SEEK_CUR)) < 0)
773194206Ssimon			break;
774194206Ssimon		mpos = fsbz - (cpos % (off_t)fsbz);
775194206Ssimon		if (lseek(arfd, mpos, SEEK_CUR) < 0)
776194206Ssimon			break;
777194206Ssimon		lstrval = 1;
778194206Ssimon		break;
779194206Ssimon	case ISPIPE:
780194206Ssimon	default:
781194206Ssimon		/*
782194206Ssimon		 * cannot recover on these archive device types
783194206Ssimon		 */
784194206Ssimon		io_ok = 0;
785194206Ssimon		break;
786194206Ssimon	}
787194206Ssimon	if (lstrval <= 0) {
788194206Ssimon		paxwarn(1, "Unable to recover from an archive read failure.");
789194206Ssimon		return(-1);
790194206Ssimon	}
791194206Ssimon	paxwarn(0, "Attempting to recover from an archive read failure.");
792194206Ssimon	return(0);
793194206Ssimon}
794194206Ssimon
795194206Ssimon/*
796194206Ssimon * ar_fow()
797194206Ssimon *	Move the I/O position within the archive foward the specified number of
798194206Ssimon *	bytes as supported by the device. If we cannot move the requested
799194206Ssimon *	number of bytes, return the actual number of bytes moved in skipped.
800194206Ssimon * Return:
801194206Ssimon *	0 if moved the requested distance, -1 on complete failure, 1 on
802194206Ssimon *	partial move (the amount moved is in skipped)
803194206Ssimon */
804194206Ssimon
805194206Ssimonint
806194206Ssimonar_fow(off_t sksz, off_t *skipped)
807194206Ssimon{
808194206Ssimon	off_t cpos;
809194206Ssimon	off_t mpos;
810194206Ssimon
811194206Ssimon	*skipped = 0;
812194206Ssimon	if (sksz <= 0)
813194206Ssimon		return(0);
814194206Ssimon
815194206Ssimon	/*
816194206Ssimon	 * we cannot move foward at EOF or error
817194206Ssimon	 */
818194206Ssimon	if (lstrval <= 0)
819194206Ssimon		return(lstrval);
820194206Ssimon
821194206Ssimon	/*
822194206Ssimon	 * Safer to read forward on devices where it is hard to find the end of
823194206Ssimon	 * the media without reading to it. With tapes we cannot be sure of the
824194206Ssimon	 * number of physical blocks to skip (we do not know physical block
825194206Ssimon	 * size at this point), so we must only read foward on tapes!
826194206Ssimon	 */
827194206Ssimon	if (artyp != ISREG)
828194206Ssimon		return(0);
829194206Ssimon
830194206Ssimon	/*
831194206Ssimon	 * figure out where we are in the archive
832194206Ssimon	 */
833194206Ssimon	if ((cpos = lseek(arfd, (off_t)0L, SEEK_CUR)) >= 0) {
834194206Ssimon		/*
835194206Ssimon	 	 * we can be asked to move farther than there are bytes in this
836194206Ssimon		 * volume, if so, just go to file end and let normal buf_fill()
837194206Ssimon		 * deal with the end of file (it will go to next volume by
838194206Ssimon		 * itself)
839194206Ssimon	 	 */
840194206Ssimon		if ((mpos = cpos + sksz) > arsb.st_size) {
841194206Ssimon			*skipped = arsb.st_size - cpos;
842194206Ssimon			mpos = arsb.st_size;
843194206Ssimon		} else
844194206Ssimon			*skipped = sksz;
845194206Ssimon		if (lseek(arfd, mpos, SEEK_SET) >= 0)
846194206Ssimon			return(0);
847194206Ssimon	}
848194206Ssimon	syswarn(1, errno, "Forward positioning operation on archive failed");
849194206Ssimon	lstrval = -1;
850194206Ssimon	return(-1);
851194206Ssimon}
852194206Ssimon
853194206Ssimon/*
854194206Ssimon * ar_rev()
855194206Ssimon *	move the i/o position within the archive backwards the specified byte
856194206Ssimon *	count as supported by the device. With tapes drives we RESET rdblksz to
857194206Ssimon *	the PHYSICAL blocksize.
858194206Ssimon *	NOTE: We should only be called to move backwards so we can rewrite the
859194206Ssimon *	last records (the trailer) of an archive (APPEND).
860194206Ssimon * Return:
861194206Ssimon *	0 if moved the requested distance, -1 on complete failure
862194206Ssimon */
863194206Ssimon
864194206Ssimonint
865194206Ssimonar_rev(off_t sksz)
866194206Ssimon{
867194206Ssimon	off_t cpos;
868194206Ssimon	struct mtop mb;
869194206Ssimon	int phyblk;
870194206Ssimon
871194206Ssimon	/*
872194206Ssimon	 * make sure we do not have try to reverse on a flawed archive
873194206Ssimon	 */
874194206Ssimon	if (lstrval < 0)
875194206Ssimon		return(lstrval);
876194206Ssimon
877194206Ssimon	switch(artyp) {
878194206Ssimon	case ISPIPE:
879		if (sksz <= 0)
880			break;
881		/*
882		 * cannot go backwards on these critters
883		 */
884		paxwarn(1, "Reverse positioning on pipes is not supported.");
885		lstrval = -1;
886		return(-1);
887	case ISREG:
888	case ISBLK:
889	case ISCHR:
890	default:
891		if (sksz <= 0)
892			break;
893
894		/*
895		 * For things other than files, backwards movement has a very
896		 * high probability of failure as we really do not know the
897		 * true attributes of the device we are talking to (the device
898		 * may not even have the ability to lseek() in any direction).
899		 * First we figure out where we are in the archive.
900		 */
901		if ((cpos = lseek(arfd, (off_t)0L, SEEK_CUR)) < 0) {
902			syswarn(1, errno,
903			   "Unable to obtain current archive byte offset");
904			lstrval = -1;
905			return(-1);
906		}
907
908		/*
909		 * we may try to go backwards past the start when the archive
910		 * is only a single record. If this hapens and we are on a
911		 * multi volume archive, we need to go to the end of the
912		 * previous volume and continue our movement backwards from
913		 * there.
914		 */
915		if ((cpos -= sksz) < (off_t)0L) {
916			if (arvol > 1) {
917				/*
918				 * this should never happen
919				 */
920				paxwarn(1,"Reverse position on previous volume.");
921				lstrval = -1;
922				return(-1);
923			}
924			cpos = (off_t)0L;
925		}
926		if (lseek(arfd, cpos, SEEK_SET) < 0) {
927			syswarn(1, errno, "Unable to seek archive backwards");
928			lstrval = -1;
929			return(-1);
930		}
931		break;
932	case ISTAPE:
933		/*
934	 	 * Calculate and move the proper number of PHYSICAL tape
935		 * blocks. If the sksz is not an even multiple of the physical
936		 * tape size, we cannot do the move (this should never happen).
937		 * (We also cannot handler trailers spread over two vols).
938		 * get_phys() also makes sure we are in front of the filemark.
939	 	 */
940		if ((phyblk = get_phys()) <= 0) {
941			lstrval = -1;
942			return(-1);
943		}
944
945		/*
946		 * make sure future tape reads only go by physical tape block
947		 * size (set rdblksz to the real size).
948		 */
949		rdblksz = phyblk;
950
951		/*
952		 * if no movement is required, just return (we must be after
953		 * get_phys() so the physical blocksize is properly set)
954		 */
955		if (sksz <= 0)
956			break;
957
958		/*
959		 * ok we have to move. Make sure the tape drive can do it.
960		 */
961		if (sksz % phyblk) {
962			paxwarn(1,
963			    "Tape drive unable to backspace requested amount");
964			lstrval = -1;
965			return(-1);
966		}
967
968		/*
969		 * move backwards the requested number of bytes
970		 */
971		mb.mt_op = MTBSR;
972		mb.mt_count = sksz/phyblk;
973		if (ioctl(arfd, MTIOCTOP, &mb) < 0) {
974			syswarn(1,errno, "Unable to backspace tape %d blocks.",
975			    mb.mt_count);
976			lstrval = -1;
977			return(-1);
978		}
979		break;
980	}
981	lstrval = 1;
982	return(0);
983}
984
985/*
986 * get_phys()
987 *	Determine the physical block size on a tape drive. We need the physical
988 *	block size so we know how many bytes we skip over when we move with
989 *	mtio commands. We also make sure we are BEFORE THE TAPE FILEMARK when
990 *	return.
991 *	This is one really SLOW routine...
992 * Return:
993 *	physical block size if ok (ok > 0), -1 otherwise
994 */
995
996static int
997get_phys(void)
998{
999	int padsz = 0;
1000	int res;
1001	int phyblk;
1002	struct mtop mb;
1003	char scbuf[MAXBLK];
1004
1005	/*
1006	 * move to the file mark, and then back up one record and read it.
1007	 * this should tell us the physical record size the tape is using.
1008	 */
1009	if (lstrval == 1) {
1010		/*
1011		 * we know we are at file mark when we get back a 0 from
1012		 * read()
1013		 */
1014		while ((res = read(arfd, scbuf, sizeof(scbuf))) > 0)
1015			padsz += res;
1016		if (res < 0) {
1017			syswarn(1, errno, "Unable to locate tape filemark.");
1018			return(-1);
1019		}
1020	}
1021
1022	/*
1023	 * move backwards over the file mark so we are at the end of the
1024	 * last record.
1025	 */
1026	mb.mt_op = MTBSF;
1027	mb.mt_count = 1;
1028	if (ioctl(arfd, MTIOCTOP, &mb) < 0) {
1029		syswarn(1, errno, "Unable to backspace over tape filemark.");
1030		return(-1);
1031	}
1032
1033	/*
1034	 * move backwards so we are in front of the last record and read it to
1035	 * get physical tape blocksize.
1036	 */
1037	mb.mt_op = MTBSR;
1038	mb.mt_count = 1;
1039	if (ioctl(arfd, MTIOCTOP, &mb) < 0) {
1040		syswarn(1, errno, "Unable to backspace over last tape block.");
1041		return(-1);
1042	}
1043	if ((phyblk = read(arfd, scbuf, sizeof(scbuf))) <= 0) {
1044		syswarn(1, errno, "Cannot determine archive tape blocksize.");
1045		return(-1);
1046	}
1047
1048	/*
1049	 * read foward to the file mark, then back up in front of the filemark
1050	 * (this is a bit paranoid, but should be safe to do).
1051	 */
1052	while ((res = read(arfd, scbuf, sizeof(scbuf))) > 0)
1053		;
1054	if (res < 0) {
1055		syswarn(1, errno, "Unable to locate tape filemark.");
1056		return(-1);
1057	}
1058	mb.mt_op = MTBSF;
1059	mb.mt_count = 1;
1060	if (ioctl(arfd, MTIOCTOP, &mb) < 0) {
1061		syswarn(1, errno, "Unable to backspace over tape filemark.");
1062		return(-1);
1063	}
1064
1065	/*
1066	 * set lstrval so we know that the filemark has not been seen
1067	 */
1068	lstrval = 1;
1069
1070	/*
1071	 * return if there was no padding
1072	 */
1073	if (padsz == 0)
1074		return(phyblk);
1075
1076	/*
1077	 * make sure we can move backwards over the padding. (this should
1078	 * never fail).
1079	 */
1080	if (padsz % phyblk) {
1081		paxwarn(1, "Tape drive unable to backspace requested amount");
1082		return(-1);
1083	}
1084
1085	/*
1086	 * move backwards over the padding so the head is where it was when
1087	 * we were first called (if required).
1088	 */
1089	mb.mt_op = MTBSR;
1090	mb.mt_count = padsz/phyblk;
1091	if (ioctl(arfd, MTIOCTOP, &mb) < 0) {
1092		syswarn(1,errno,"Unable to backspace tape over %d pad blocks",
1093		    mb.mt_count);
1094		return(-1);
1095	}
1096	return(phyblk);
1097}
1098
1099/*
1100 * ar_next()
1101 *	prompts the user for the next volume in this archive. For some devices
1102 *	we may allow the media to be changed. Otherwise a new archive is
1103 *	prompted for. By pax spec, if there is no controlling tty or an eof is
1104 *	read on tty input, we must quit pax.
1105 * Return:
1106 *	0 when ready to continue, -1 when all done
1107 */
1108
1109int
1110ar_next(void)
1111{
1112	char buf[PAXPATHLEN+2];
1113	static int freeit = 0;
1114	sigset_t o_mask;
1115
1116	/*
1117	 * WE MUST CLOSE THE DEVICE. A lot of devices must see last close, (so
1118	 * things like writing EOF etc will be done) (Watch out ar_close() can
1119	 * also be called via a signal handler, so we must prevent a race.
1120	 */
1121	if (sigprocmask(SIG_BLOCK, &s_mask, &o_mask) < 0)
1122		syswarn(0, errno, "Unable to set signal mask");
1123	ar_close();
1124	if (sigprocmask(SIG_SETMASK, &o_mask, NULL) < 0)
1125		syswarn(0, errno, "Unable to restore signal mask");
1126
1127	if (done || !wr_trail || strcmp(NM_TAR, argv0) == 0)
1128		return(-1);
1129
1130	tty_prnt("\nATTENTION! %s archive volume change required.\n", argv0);
1131
1132	/*
1133	 * if i/o is on stdin or stdout, we cannot reopen it (we do not know
1134	 * the name), the user will be forced to type it in.
1135	 */
1136	if (strcmp(arcname, stdo) && strcmp(arcname, stdn) && (artyp != ISREG)
1137	    && (artyp != ISPIPE)) {
1138		if (artyp == ISTAPE) {
1139			tty_prnt("%s ready for archive tape volume: %d\n",
1140				arcname, arvol);
1141			tty_prnt("Load the NEXT TAPE on the tape drive");
1142		} else {
1143			tty_prnt("%s ready for archive volume: %d\n",
1144				arcname, arvol);
1145			tty_prnt("Load the NEXT STORAGE MEDIA (if required)");
1146		}
1147
1148		if ((act == ARCHIVE) || (act == APPND))
1149			tty_prnt(" and make sure it is WRITE ENABLED.\n");
1150		else
1151			tty_prnt("\n");
1152
1153		for(;;) {
1154			tty_prnt("Type \"y\" to continue, \".\" to quit %s,",
1155				argv0);
1156			tty_prnt(" or \"s\" to switch to new device.\nIf you");
1157			tty_prnt(" cannot change storage media, type \"s\"\n");
1158			tty_prnt("Is the device ready and online? > ");
1159
1160			if ((tty_read(buf,sizeof(buf))<0) || !strcmp(buf,".")){
1161				done = 1;
1162				lstrval = -1;
1163				tty_prnt("Quitting %s!\n", argv0);
1164				vfpart = 0;
1165				return(-1);
1166			}
1167
1168			if ((buf[0] == '\0') || (buf[1] != '\0')) {
1169				tty_prnt("%s unknown command, try again\n",buf);
1170				continue;
1171			}
1172
1173			switch (buf[0]) {
1174			case 'y':
1175			case 'Y':
1176				/*
1177				 * we are to continue with the same device
1178				 */
1179				if (ar_open(arcname) >= 0)
1180					return(0);
1181				tty_prnt("Cannot re-open %s, try again\n",
1182					arcname);
1183				continue;
1184			case 's':
1185			case 'S':
1186				/*
1187				 * user wants to open a different device
1188				 */
1189				tty_prnt("Switching to a different archive\n");
1190				break;
1191			default:
1192				tty_prnt("%s unknown command, try again\n",buf);
1193				continue;
1194			}
1195			break;
1196		}
1197	} else
1198		tty_prnt("Ready for archive volume: %d\n", arvol);
1199
1200	/*
1201	 * have to go to a different archive
1202	 */
1203	for (;;) {
1204		tty_prnt("Input archive name or \".\" to quit %s.\n", argv0);
1205		tty_prnt("Archive name > ");
1206
1207		if ((tty_read(buf, sizeof(buf)) < 0) || !strcmp(buf, ".")) {
1208			done = 1;
1209			lstrval = -1;
1210			tty_prnt("Quitting %s!\n", argv0);
1211			vfpart = 0;
1212			return(-1);
1213		}
1214		if (buf[0] == '\0') {
1215			tty_prnt("Empty file name, try again\n");
1216			continue;
1217		}
1218		if (!strcmp(buf, "..")) {
1219			tty_prnt("Illegal file name: .. try again\n");
1220			continue;
1221		}
1222		if (strlen(buf) > PAXPATHLEN) {
1223			tty_prnt("File name too long, try again\n");
1224			continue;
1225		}
1226
1227		/*
1228		 * try to open new archive
1229		 */
1230		if (ar_open(buf) >= 0) {
1231			if (freeit) {
1232				(void)free((char *)(uintptr_t)arcname);
1233				freeit = 0;
1234			}
1235			if ((arcname = strdup(buf)) == NULL) {
1236				done = 1;
1237				lstrval = -1;
1238				paxwarn(0, "Cannot save archive name.");
1239				return(-1);
1240			}
1241			freeit = 1;
1242			break;
1243		}
1244		tty_prnt("Cannot open %s, try again\n", buf);
1245		continue;
1246	}
1247	return(0);
1248}
1249
1250/*
1251 * ar_start_gzip()
1252 * starts the gzip compression/decompression process as a child, using magic
1253 * to keep the fd the same in the calling function (parent).
1254 */
1255void
1256ar_start_gzip(int fd, const char *gzip_prog, int wr)
1257{
1258	int fds[2];
1259	const char *gzip_flags;
1260
1261	if (pipe(fds) < 0)
1262		err(1, "could not pipe");
1263	zpid = fork();
1264	if (zpid < 0)
1265		err(1, "could not fork");
1266
1267	/* parent */
1268	if (zpid) {
1269		if (wr)
1270			dup2(fds[1], fd);
1271		else
1272			dup2(fds[0], fd);
1273		close(fds[0]);
1274		close(fds[1]);
1275	} else {
1276		if (wr) {
1277			dup2(fds[0], STDIN_FILENO);
1278			dup2(fd, STDOUT_FILENO);
1279			gzip_flags = "-c";
1280		} else {
1281			dup2(fds[1], STDOUT_FILENO);
1282			dup2(fd, STDIN_FILENO);
1283			gzip_flags = "-dc";
1284		}
1285		close(fds[0]);
1286		close(fds[1]);
1287		if (execlp(gzip_prog, gzip_prog, gzip_flags,
1288		    (char *)NULL) < 0)
1289			err(1, "could not exec");
1290		/* NOTREACHED */
1291	}
1292}
1293