xref: /csrg-svn/bin/pax/ar_io.c (revision 66890)
157193Smuller /*-
257193Smuller  * Copyright (c) 1992 Keith Muller.
360675Sbostic  * Copyright (c) 1992, 1993
460675Sbostic  *	The Regents of the University of California.  All rights reserved.
557193Smuller  *
657193Smuller  * This code is derived from software contributed to Berkeley by
757193Smuller  * Keith Muller of the University of California, San Diego.
857193Smuller  *
957193Smuller  * %sccs.include.redist.c%
1057193Smuller  */
1157193Smuller 
1257193Smuller #ifndef lint
13*66890Sbostic static char sccsid[] = "@(#)ar_io.c	8.2 (Berkeley) 04/18/94";
1457193Smuller #endif /* not lint */
1557193Smuller 
1657193Smuller #include <sys/types.h>
1757193Smuller #include <sys/time.h>
1857193Smuller #include <sys/stat.h>
1957193Smuller #include <sys/ioctl.h>
2057193Smuller #include <sys/mtio.h>
2157193Smuller #include <sys/param.h>
2257193Smuller #include <signal.h>
2357193Smuller #include <string.h>
2457193Smuller #include <fcntl.h>
2557193Smuller #include <unistd.h>
2657193Smuller #include <stdio.h>
2757193Smuller #include <ctype.h>
2857193Smuller #include <errno.h>
2957193Smuller #include <stdlib.h>
3057193Smuller #include "pax.h"
3157193Smuller #include "extern.h"
3257193Smuller 
3357193Smuller /*
3457535Smuller  * Routines which deal directly with the archive I/O device/file.
3557193Smuller  */
3657193Smuller 
3757193Smuller #define DMOD		0666		/* default mode of created archives */
3857193Smuller #define EXT_MODE	O_RDONLY	/* open mode for list/extract */
3957193Smuller #define AR_MODE		(O_WRONLY | O_CREAT | O_TRUNC)	/* mode for archive */
4057193Smuller #define APP_MODE	O_RDWR		/* mode for append */
4157193Smuller #define STDO		"<STDOUT>"	/* psuedo name for stdout */
4257193Smuller #define STDN		"<STDIN>"	/* psuedo name for stdin */
4357193Smuller static int arfd = -1;			/* archive file descriptor */
4457584Smuller static int artyp = ISREG;		/* archive type: file/FIFO/tape */
4557193Smuller static int arvol = 1;			/* archive volume number */
4657193Smuller static int lstrval = -1;		/* return value from last i/o */
4757193Smuller static int io_ok;			/* i/o worked on volume after resync */
4857535Smuller static int did_io;			/* did i/o ever occur on volume? */
4957193Smuller static int done;			/* set via tty termination */
5057193Smuller static struct stat arsb;		/* stat of archive device at open */
5157193Smuller static int invld_rec;			/* tape has out of spec record size */
5257578Smuller static int wr_trail = 1;		/* trailer was rewritten in append */
5357584Smuller static int can_unlnk = 0;		/* do we unlink null archives?  */
5457193Smuller char *arcname;                  	/* printable name of archive */
5557193Smuller 
5657193Smuller static int get_phys __P((void));
5757193Smuller extern sigset_t s_mask;
5857193Smuller 
5957193Smuller /*
6057193Smuller  * ar_open()
6157193Smuller  *	Opens the next archive volume. Determines the type of the device and
6257193Smuller  *	sets up block sizes as required by the archive device and the format.
6357193Smuller  *	Note: we may be called with name == NULL on the first open only.
6457193Smuller  * Return:
6557193Smuller  *	-1 on failure, 0 otherwise
6657193Smuller  */
6757193Smuller 
6857193Smuller #if __STDC__
6957193Smuller int
ar_open(char * name)7057193Smuller ar_open(char *name)
7157193Smuller #else
7257193Smuller int
7357193Smuller ar_open(name)
7457193Smuller 	char *name;
7557193Smuller #endif
7657193Smuller {
7757193Smuller         struct mtget mb;
7857193Smuller 
7957193Smuller 	if (arfd != -1)
8057193Smuller 		(void)close(arfd);
8157193Smuller 	arfd = -1;
8257794Smuller 	can_unlnk = did_io = io_ok = invld_rec = 0;
8357584Smuller 	artyp = ISREG;
8457193Smuller 	flcnt = 0;
8557193Smuller 
8657193Smuller 	/*
8757193Smuller 	 * open based on overall operation mode
8857193Smuller 	 */
8957193Smuller 	switch (act) {
9057193Smuller 	case LIST:
9157193Smuller 	case EXTRACT:
9257193Smuller 		if (name == NULL) {
9357193Smuller 			arfd = STDIN_FILENO;
9457193Smuller 			arcname = STDN;
9557193Smuller 		} else if ((arfd = open(name, EXT_MODE, DMOD)) < 0)
9657535Smuller 			syswarn(0, errno, "Failed open to read on %s", name);
9757193Smuller 		break;
9857193Smuller 	case ARCHIVE:
9957193Smuller 		if (name == NULL) {
10057193Smuller 			arfd = STDOUT_FILENO;
10157193Smuller 			arcname = STDO;
10257193Smuller 		} else if ((arfd = open(name, AR_MODE, DMOD)) < 0)
10357535Smuller 			syswarn(0, errno, "Failed open to write on %s", name);
10457584Smuller 		else
10557584Smuller 			can_unlnk = 1;
10657193Smuller 		break;
10757193Smuller 	case APPND:
10857193Smuller 		if (name == NULL) {
10957193Smuller 			arfd = STDOUT_FILENO;
11057193Smuller 			arcname = STDO;
11157193Smuller 		} else if ((arfd = open(name, APP_MODE, DMOD)) < 0)
11257535Smuller 			syswarn(0, errno, "Failed open to read/write on %s",
11357193Smuller 				name);
11457193Smuller 		break;
11557193Smuller 	case COPY:
11657193Smuller 		/*
11757193Smuller 		 * arfd not used in COPY mode
11857193Smuller 		 */
11957193Smuller 		arcname = "<NONE>";
12057193Smuller 		lstrval = 1;
12157193Smuller 		return(0);
12257193Smuller 	}
12357193Smuller 	if (arfd < 0)
12457193Smuller 		return(-1);
12557193Smuller 
12657193Smuller 	/*
12757193Smuller 	 * set up is based on device type
12857193Smuller 	 */
12957193Smuller 	if (fstat(arfd, &arsb) < 0) {
13057535Smuller 		syswarn(0, errno, "Failed stat on %s", arcname);
13157584Smuller 		(void)close(arfd);
13257584Smuller 		arfd = -1;
13357584Smuller 		can_unlnk = 0;
13457193Smuller 		return(-1);
13557193Smuller 	}
13657193Smuller 	if (S_ISDIR(arsb.st_mode)) {
13757535Smuller 		warn(0, "Cannot write an archive on top of a directory %s",
13857193Smuller 		    arcname);
13957584Smuller 		(void)close(arfd);
14057584Smuller 		arfd = -1;
14157584Smuller 		can_unlnk = 0;
14257193Smuller 		return(-1);
14357193Smuller 	}
14457584Smuller 
14557193Smuller 	if (S_ISCHR(arsb.st_mode))
14657193Smuller 		artyp = ioctl(arfd, MTIOCGET, &mb) ? ISCHR : ISTAPE;
14757193Smuller 	else if (S_ISBLK(arsb.st_mode))
14857193Smuller 		artyp = ISBLK;
14957193Smuller 	else if ((lseek(arfd, (off_t)0L, SEEK_CUR) == -1) && (errno == ESPIPE))
15057193Smuller 		artyp = ISPIPE;
15157193Smuller 	else
15257193Smuller 		artyp = ISREG;
15357193Smuller 
15457193Smuller 	/*
15557584Smuller 	 * make sure we beyond any doubt that we only can unlink regular files
15657584Smuller 	 * we created
15757584Smuller 	 */
15857584Smuller 	if (artyp != ISREG)
15957584Smuller 		can_unlnk = 0;
16057584Smuller 	/*
16157535Smuller 	 * if we are writing, we are done
16257193Smuller 	 */
16357193Smuller 	if (act == ARCHIVE) {
16457193Smuller 		blksz = rdblksz = wrblksz;
16557193Smuller 		lstrval = 1;
16657193Smuller 		return(0);
16757193Smuller 	}
16857193Smuller 
16957193Smuller 	/*
17057193Smuller 	 * set default blksz on read. APPNDs writes rdblksz on the last volume
17157193Smuller 	 * On all new archive volumes, we shift to wrblksz (if the user
17257193Smuller 	 * specified one, otherwize we will continue to use rdblksz). We
17357193Smuller 	 * must to set blocksize based on what kind of device the archive is
17457193Smuller 	 * stored.
17557193Smuller 	 */
17657193Smuller 	switch(artyp) {
17757193Smuller 	case ISTAPE:
17857193Smuller 		/*
17957193Smuller 		 * Tape drives come in at least two flavors. Those that support
18057193Smuller 		 * variable sized records and those that have fixed sized
18157193Smuller 		 * records. They must be treated differently. For tape drives
18257193Smuller 		 * that support variable sized records, we must make large
18357193Smuller 		 * reads to make sure we get the entire record, otherwise we
18457193Smuller 		 * will just get the first part of the record (up to size we
18557193Smuller 		 * asked). Tapes with fixed sized records may or may not return
18657193Smuller 		 * multiple records in a single read. We really do not care
18757193Smuller 		 * what the physical record size is UNLESS we are going to
18857193Smuller 		 * append. (We will need the physical block size to rewrite
18957193Smuller 		 * the trailer). Only when we are appending do we go to the
19057535Smuller 		 * effort to figure out the true PHYSICAL record size.
19157193Smuller 		 */
19257193Smuller 		blksz = rdblksz = MAXBLK;
19357193Smuller 		break;
19457193Smuller 	case ISPIPE:
19557193Smuller 	case ISBLK:
19657193Smuller 	case ISCHR:
19757193Smuller 		/*
19857193Smuller 		 * Blocksize is not a major issue with these devices (but must
19957193Smuller 		 * be kept a multiple of 512). If the user specified a write
20057193Smuller 		 * block size, we use that to read. Under append, we must
20157193Smuller 		 * always keep blksz == rdblksz. Otherwise we go ahead and use
20257193Smuller 		 * the device optimal blocksize as (and if) returned by stat
20357193Smuller 		 * and if it is within pax specs.
20457193Smuller 		 */
20557193Smuller 		if ((act == APPND) && wrblksz) {
20657193Smuller 			blksz = rdblksz = wrblksz;
20757193Smuller 			break;
20857193Smuller 		}
20957193Smuller 
21057193Smuller 		if ((arsb.st_blksize > 0) && (arsb.st_blksize < MAXBLK) &&
21157193Smuller 		    ((arsb.st_blksize % BLKMULT) == 0))
21257193Smuller 			rdblksz = arsb.st_blksize;
21357193Smuller 		else
21457193Smuller 			rdblksz = DEVBLK;
21557193Smuller 		/*
21657193Smuller 		 * For performance go for large reads when we can without harm
21757193Smuller 		 */
21857193Smuller 		if ((act == APPND) || (artyp == ISCHR))
21957193Smuller 			blksz = rdblksz;
22057193Smuller 		else
22157193Smuller 			blksz = MAXBLK;
22257193Smuller 		break;
22357193Smuller 	case ISREG:
22457193Smuller 		/*
22557193Smuller 		 * if the user specified wrblksz works, use it. Under appends
22657193Smuller 		 * we must always keep blksz == rdblksz
22757193Smuller 		 */
22857193Smuller 		if ((act == APPND) && wrblksz && ((arsb.st_size%wrblksz)==0)){
22957193Smuller 			blksz = rdblksz = wrblksz;
23057193Smuller 			break;
23157193Smuller 		}
23257193Smuller 		/*
23357193Smuller 		 * See if we can find the blocking factor from the file size
23457193Smuller 		 */
23557193Smuller 		for (rdblksz = MAXBLK; rdblksz > 0; rdblksz -= BLKMULT)
23657193Smuller 			if ((arsb.st_size % rdblksz) == 0)
23757193Smuller 				break;
23857193Smuller 		/*
23957193Smuller 		 * When we cannont find a match, we may have a flawed archive.
24057193Smuller 		 */
24157193Smuller 		if (rdblksz <= 0)
24257193Smuller 			rdblksz = FILEBLK;
24357193Smuller 		/*
24457193Smuller 		 * for performance go for large reads when we can
24557193Smuller 		 */
24657193Smuller 		if (act == APPND)
24757193Smuller 			blksz = rdblksz;
24857193Smuller 		else
24957193Smuller 			blksz = MAXBLK;
25057193Smuller 		break;
25157193Smuller 	default:
25257193Smuller 		/*
25357193Smuller 		 * should never happen, worse case, slow...
25457193Smuller 		 */
25557193Smuller 		blksz = rdblksz = BLKMULT;
25657193Smuller 		break;
25757193Smuller 	}
25857193Smuller 	lstrval = 1;
25957193Smuller 	return(0);
26057193Smuller }
26157193Smuller 
26257193Smuller /*
26357193Smuller  * ar_close()
26457193Smuller  *	closes archive device, increments volume number, and prints i/o summary
26557193Smuller  */
26657193Smuller #if __STDC__
26757193Smuller void
ar_close(void)26857193Smuller ar_close(void)
26957193Smuller #else
27057193Smuller void
27157193Smuller ar_close()
27257193Smuller #endif
27357193Smuller {
27457193Smuller 	FILE *outf;
27557193Smuller 
27657578Smuller 	if (arfd < 0) {
27757578Smuller 		did_io = io_ok = flcnt = 0;
27857578Smuller 		return;
27957578Smuller 	}
28057578Smuller 
28157535Smuller 	if (act == LIST)
28257535Smuller 		outf = stdout;
28357535Smuller 	else
28457535Smuller 		outf = stderr;
28557535Smuller 
28657535Smuller 	/*
28757535Smuller 	 * Close archive file. This may take a LONG while on tapes (we may be
28857535Smuller 	 * forced to wait for the rewind to complete) so tell the user what is
28957535Smuller 	 * going on (this avoids the user hitting control-c thinking pax is
29057535Smuller 	 * broken).
29157535Smuller 	 */
29257578Smuller 	if (vflag && (artyp == ISTAPE)) {
29357578Smuller 		if (vfpart)
29457535Smuller 			(void)putc('\n', outf);
295*66890Sbostic 		(void)fprintf(outf,
296*66890Sbostic 			"%s: Waiting for tape drive close to complete...",
297*66890Sbostic 			argv0);
29857535Smuller 		(void)fflush(outf);
29957535Smuller 	}
30057535Smuller 
30157584Smuller 	/*
30257584Smuller 	 * if nothing was written to the archive (and we created it), we remove
30357584Smuller 	 * it
30457584Smuller 	 */
30557584Smuller 	if (can_unlnk && (fstat(arfd, &arsb) == 0) && (S_ISREG(arsb.st_mode)) &&
30657584Smuller 	    (arsb.st_size == 0)) {
30757584Smuller 		(void)unlink(arcname);
30857584Smuller 		can_unlnk = 0;
30957584Smuller 	}
31057584Smuller 
31157193Smuller 	(void)close(arfd);
31257535Smuller 
31357578Smuller 	if (vflag && (artyp == ISTAPE)) {
31457535Smuller 		(void)fputs("done.\n", outf);
31557578Smuller 		vfpart = 0;
31657535Smuller 		(void)fflush(outf);
31757535Smuller 	}
31857193Smuller 	arfd = -1;
31957535Smuller 
32057193Smuller 	if (!io_ok && !did_io) {
32157193Smuller 		flcnt = 0;
32257193Smuller 		return;
32357193Smuller 	}
32457193Smuller 	did_io = io_ok = 0;
32557193Smuller 
32657193Smuller 	/*
32757193Smuller 	 * The volume number is only increased when the last device has data
32857535Smuller 	 * and we have already determined the archive format.
32957193Smuller 	 */
33057535Smuller 	if (frmt != NULL)
33157535Smuller 		++arvol;
33257535Smuller 
33357193Smuller 	if (!vflag) {
33457193Smuller 		flcnt = 0;
33557193Smuller 		return;
33657193Smuller 	}
33757193Smuller 
33857193Smuller 	/*
33957193Smuller 	 * Print out a summary of I/O for this archive volume.
34057193Smuller 	 */
34157193Smuller 	if (vfpart) {
34257193Smuller 		(void)putc('\n', outf);
34357193Smuller 		vfpart = 0;
34457193Smuller 	}
34557193Smuller 
34657535Smuller 	/*
34757535Smuller 	 * If we have not determined the format yet, we just say how many bytes
34857535Smuller 	 * we have skipped over looking for a header to id. there is no way we
34957535Smuller 	 * could have written anything yet.
35057535Smuller 	 */
35157535Smuller 	if (frmt == NULL) {
35257535Smuller #	ifdef NET2_STAT
353*66890Sbostic 		(void)fprintf(outf, "%s: unknown format, %lu bytes skipped.\n",
35457535Smuller #	else
355*66890Sbostic 		(void)fprintf(outf, "%s: unknown format, %qu bytes skipped.\n",
35657535Smuller #	endif
357*66890Sbostic 		    argv0, rdcnt);
35857535Smuller 		(void)fflush(outf);
35957535Smuller 		flcnt = 0;
36057535Smuller 		return;
36157535Smuller 	}
36257535Smuller 
36357193Smuller 	(void)fprintf(outf,
36457193Smuller #	ifdef NET2_STAT
365*66890Sbostic 	    "%s: %s vol %d, %lu files, %lu bytes read, %lu bytes written.\n",
36657193Smuller #	else
367*66890Sbostic 	    "%s: %s vol %d, %lu files, %qu bytes read, %qu bytes written.\n",
36857193Smuller #	endif
369*66890Sbostic 	    argv0, frmt->name, arvol-1, flcnt, rdcnt, wrcnt);
37057193Smuller 	(void)fflush(outf);
37157193Smuller 	flcnt = 0;
37257193Smuller }
37357193Smuller 
37457193Smuller /*
37558651Smuller  * ar_drain()
37658651Smuller  *	drain any archive format independent padding from an archive read
37758651Smuller  *	from a socket or a pipe. This is to prevent the process on the
37858651Smuller  *	other side of the pipe from getting a SIGPIPE (pax will stop
37958651Smuller  *	reading an archive once a format dependent trailer is detected).
38058651Smuller  */
38158651Smuller #if __STDC__
38258651Smuller void
ar_drain(void)38358651Smuller ar_drain(void)
38458651Smuller #else
38558651Smuller void
38658651Smuller ar_drain()
38758651Smuller #endif
38858651Smuller {
38958651Smuller 	register int res;
39058651Smuller 	char drbuf[MAXBLK];
39158651Smuller 
39258651Smuller 	/*
39358651Smuller 	 * we only drain from a pipe/socket. Other devices can be closed
39458651Smuller 	 * without reading up to end of file. We sure hope that pipe is closed
39558651Smuller 	 * on the other side so we will get an EOF.
39658651Smuller 	 */
39758651Smuller 	if ((artyp != ISPIPE) || (lstrval <= 0))
39858651Smuller 		return;
39958651Smuller 
40058651Smuller 	/*
40158651Smuller 	 * keep reading until pipe is drained
40258651Smuller 	 */
40358651Smuller 	while ((res = read(arfd, drbuf, sizeof(drbuf))) > 0)
40458651Smuller 		;
40558651Smuller 	lstrval = res;
40658651Smuller }
40758651Smuller 
40858651Smuller /*
40957193Smuller  * ar_set_wr()
41057578Smuller  *	Set up device right before switching from read to write in an append.
41157578Smuller  *	device dependent code (if required) to do this should be added here.
41257578Smuller  *	For all archive devices we are already positioned at the place we want
41357578Smuller  *	to start writing when this routine is called.
41457193Smuller  * Return:
41557193Smuller  *	0 if all ready to write, -1 otherwise
41657193Smuller  */
41757193Smuller 
41857193Smuller #if __STDC__
41957193Smuller int
ar_set_wr(void)42057193Smuller ar_set_wr(void)
42157193Smuller #else
42257193Smuller int
42357193Smuller ar_set_wr()
42457193Smuller #endif
42557193Smuller {
42657193Smuller 	off_t cpos;
42757193Smuller 
42857578Smuller 	/*
42957578Smuller 	 * we must make sure the trailer is rewritten on append, ar_next()
43057578Smuller 	 * will stop us if the archive containing the trailer was not written
43157578Smuller 	 */
43257578Smuller 	wr_trail = 0;
43357578Smuller 
43457193Smuller 	/*
43557193Smuller 	 * Add any device dependent code as required here
43657193Smuller 	 */
43757193Smuller 	if (artyp != ISREG)
43857193Smuller 		return(0);
43957193Smuller 	/*
44057535Smuller 	 * Ok we have an archive in a regular file. If we were rewriting a
44157535Smuller 	 * file, we must get rid of all the stuff after the current offset
44257535Smuller 	 * (it was not written by pax).
44357193Smuller 	 */
44457193Smuller 	if (((cpos = lseek(arfd, (off_t)0L, SEEK_CUR)) < 0) ||
44557578Smuller 	    (ftruncate(arfd, cpos) < 0)) {
44657578Smuller 		syswarn(1, errno, "Unable to truncate archive file");
44757193Smuller 		return(-1);
44857578Smuller 	}
44957193Smuller 	return(0);
45057193Smuller }
45157193Smuller 
45257193Smuller /*
45357193Smuller  * ar_app_ok()
45457193Smuller  *	check if the last volume in the archive allows appends. We cannot check
45557193Smuller  *	this until we are ready to write since there is no spec that says all
45657193Smuller  *	volumes in a single archive have to be of the same type...
45757193Smuller  * Return:
45857193Smuller  *	0 if we can append, -1 otherwise.
45957193Smuller  */
46057193Smuller 
46157193Smuller #if __STDC__
46257193Smuller int
ar_app_ok(void)46357193Smuller ar_app_ok(void)
46457193Smuller #else
46557193Smuller int
46657193Smuller ar_app_ok()
46757193Smuller #endif
46857193Smuller {
46957193Smuller 	if (artyp == ISPIPE) {
47057193Smuller 		warn(1, "Cannot append to an archive obtained from a pipe.");
47157193Smuller 		return(-1);
47257193Smuller 	}
47357193Smuller 
47457193Smuller 	if (!invld_rec)
47557193Smuller 		return(0);
476*66890Sbostic 	warn(1,"Cannot append, device record size %d does not support %s spec",
477*66890Sbostic 		rdblksz, argv0);
47857193Smuller 	return(-1);
47957193Smuller }
48057193Smuller 
48157193Smuller /*
48257193Smuller  * ar_read()
48357193Smuller  *	read up to a specified number of bytes from the archive into the
48457193Smuller  *	supplied buffer. When dealing with tapes we may not always be able to
48557193Smuller  *	read what we want.
48657193Smuller  * Return:
48757193Smuller  *	Number of bytes in buffer. 0 for end of file, -1 for a read error.
48857193Smuller  */
48957193Smuller 
49057193Smuller #if __STDC__
49157193Smuller int
ar_read(register char * buf,register int cnt)49257193Smuller ar_read(register char *buf, register int cnt)
49357193Smuller #else
49457193Smuller int
49557193Smuller ar_read(buf, cnt)
49657193Smuller 	register char *buf;
49757193Smuller 	register int cnt;
49857193Smuller #endif
49957193Smuller {
50057193Smuller 	register int res = 0;
50157193Smuller 
50257193Smuller 	/*
50357193Smuller 	 * if last i/o was in error, no more reads until reset or new volume
50457193Smuller 	 */
50557193Smuller 	if (lstrval <= 0)
50657193Smuller 		return(lstrval);
50757193Smuller 
50857193Smuller 	/*
50957193Smuller 	 * how we read must be based on device type
51057193Smuller 	 */
51157193Smuller 	switch (artyp) {
51257193Smuller 	case ISTAPE:
51357193Smuller 		if ((res = read(arfd, buf, cnt)) > 0) {
51457193Smuller 			/*
51557193Smuller 			 * CAUTION: tape systems may not always return the same
51657193Smuller 			 * sized records so we leave blksz == MAXBLK. The
51757193Smuller 			 * physical record size that a tape drive supports is
51857193Smuller 			 * very hard to determine in a uniform and portable
51957193Smuller 			 * manner.
52057193Smuller 			 */
52157193Smuller 			io_ok = 1;
52257193Smuller 			if (res != rdblksz) {
52357193Smuller 				/*
52457193Smuller 				 * Record size changed. If this is happens on
52557535Smuller 				 * any record after the first, we probably have
52657535Smuller 				 * a tape drive which has a fixed record size
52757535Smuller 				 * we are getting multiple records in a single
52857535Smuller 				 * read). Watch out for record blocking that
52957535Smuller 				 * violates pax spec (must be a multiple of
53057535Smuller 				 * BLKMULT).
53157193Smuller 				 */
53257193Smuller 				rdblksz = res;
53357193Smuller 				if (rdblksz % BLKMULT)
53457193Smuller 					invld_rec = 1;
53557193Smuller 			}
53657193Smuller 			return(res);
53757193Smuller 		}
53857193Smuller 		break;
53957193Smuller 	case ISREG:
54057193Smuller 	case ISBLK:
54157193Smuller 	case ISCHR:
54257193Smuller 	case ISPIPE:
54357193Smuller 	default:
54457193Smuller 		/*
54557193Smuller 		 * Files are so easy to deal with. These other things cannot
54657193Smuller 		 * be trusted at all. So when we are dealing with character
54757193Smuller 		 * devices and pipes we just take what they have ready for us
54857193Smuller 		 * and return. Trying to do anything else with them runs the
54957193Smuller 		 * risk of failure.
55057193Smuller 		 */
55157193Smuller 		if ((res = read(arfd, buf, cnt)) > 0) {
55257193Smuller 			io_ok = 1;
55357193Smuller 			return(res);
55457193Smuller 		}
55557193Smuller 		break;
55657193Smuller 	}
55757193Smuller 
55857193Smuller 	/*
55957193Smuller 	 * We are in trouble at this point, something is broken...
56057193Smuller 	 */
56157193Smuller 	lstrval = res;
56257193Smuller 	if (res < 0)
56357193Smuller 		syswarn(1, errno, "Failed read on archive volume %d", arvol);
56457193Smuller 	else
56557193Smuller 		warn(0, "End of archive volume %d reached", arvol);
56657193Smuller 	return(res);
56757193Smuller }
56857193Smuller 
56957193Smuller /*
57057193Smuller  * ar_write()
57157193Smuller  *	Write a specified number of bytes in supplied buffer to the archive
57257193Smuller  *	device so it appears as a single "block". Deals with errors and tries
57357193Smuller  *	to recover when faced with short writes.
57457193Smuller  * Return:
57557193Smuller  *	Number of bytes written. 0 indicates end of volume reached and with no
57657193Smuller  *	flaws (as best that can be detected). A -1 indicates an unrecoverable
57757193Smuller  *	error in the archive occured.
57857193Smuller  */
57957193Smuller 
58057193Smuller #if __STDC__
58157193Smuller int
ar_write(register char * buf,register int bsz)58257193Smuller ar_write(register char *buf, register int bsz)
58357193Smuller #else
58457193Smuller int
58557193Smuller ar_write(buf, bsz)
58657193Smuller 	register char *buf;
58757193Smuller 	register int bsz;
58857193Smuller #endif
58957193Smuller {
59057193Smuller 	register int res;
59157193Smuller 	off_t cpos;
59257193Smuller 
59357193Smuller 	/*
59457193Smuller 	 * do not allow pax to create a "bad" archive. Once a write fails on
59557193Smuller 	 * an archive volume prevent further writes to it.
59657193Smuller 	 */
59757193Smuller 	if (lstrval <= 0)
59857193Smuller 		return(lstrval);
59957193Smuller 
60057193Smuller 	if ((res = write(arfd, buf, bsz)) == bsz) {
60157578Smuller 		wr_trail = 1;
60257193Smuller 		io_ok = 1;
60357193Smuller 		return(bsz);
60457193Smuller 	}
60557193Smuller 	/*
60657193Smuller 	 * write broke, see what we can do with it. We try to send any partial
60757535Smuller 	 * writes that may violate pax spec to the next archive volume.
60857193Smuller 	 */
60957193Smuller 	if (res < 0)
61057193Smuller 		lstrval = res;
61157193Smuller 	else
61257193Smuller 		lstrval = 0;
61357193Smuller 
61457193Smuller 	switch (artyp) {
61557193Smuller 	case ISREG:
61657193Smuller 		if ((res > 0) && (res % BLKMULT)) {
61757193Smuller 			/*
61857193Smuller 		 	 * try to fix up partial writes which are not BLKMULT
61957193Smuller 			 * in size by forcing the runt record to next archive
62057193Smuller 			 * volume
62157193Smuller 		 	 */
62257193Smuller 			if ((cpos = lseek(arfd, (off_t)0L, SEEK_CUR)) < 0)
62357193Smuller 				break;
62457193Smuller 			cpos -= (off_t)res;
62557193Smuller 			if (ftruncate(arfd, cpos) < 0)
62657193Smuller 				break;
62757193Smuller 			res = lstrval = 0;
62857193Smuller 			break;
62957193Smuller 		}
63057193Smuller 		if (res >= 0)
63157193Smuller 			break;
63257193Smuller 		/*
63357193Smuller 		 * if file is out of space, handle it like a return of 0
63457193Smuller 		 */
63557193Smuller 		if ((errno == ENOSPC) || (errno == EFBIG) || (errno == EDQUOT))
63657193Smuller 			res = lstrval = 0;
63757193Smuller 		break;
63857193Smuller 	case ISTAPE:
63957193Smuller 	case ISCHR:
64057193Smuller 	case ISBLK:
64157193Smuller 		if (res >= 0)
64257193Smuller 			break;
64357193Smuller 		if (errno == EACCES) {
64457193Smuller 			warn(0, "Write failed, archive is write protected.");
64557193Smuller 			res = lstrval = 0;
64657193Smuller 			return(0);
64757193Smuller 		}
64857193Smuller 		/*
64957193Smuller 		 * see if we reached the end of media, if so force a change to
65057193Smuller 		 * the next volume
65157193Smuller 		 */
65257193Smuller 		if ((errno == ENOSPC) || (errno == EIO) || (errno == ENXIO))
65357193Smuller 			res = lstrval = 0;
65457193Smuller 		break;
65557193Smuller 	case ISPIPE:
65657193Smuller 	default:
65757193Smuller 		/*
65857193Smuller 		 * we cannot fix errors to these devices
65957193Smuller 		 */
66057193Smuller 		break;
66157193Smuller 	}
66257193Smuller 
66357193Smuller 	/*
66457193Smuller 	 * Better tell the user the bad news...
66557535Smuller 	 * if this is a block aligned archive format, we may have a bad archive
66657535Smuller 	 * if the format wants the header to start at a BLKMULT boundry. While
66757193Smuller 	 * we can deal with the mis-aligned data, it violates spec and other
66857193Smuller 	 * archive readers will likely fail. if the format is not block
66957535Smuller 	 * aligned, the user may be lucky (and the archive is ok).
67057193Smuller 	 */
67157578Smuller 	if (res >= 0) {
67257578Smuller 		if (res > 0)
67357578Smuller 			wr_trail = 1;
67457193Smuller 		io_ok = 1;
67557578Smuller 	}
67657578Smuller 
67757578Smuller 	/*
67857578Smuller 	 * If we were trying to rewrite the trailer and it didn't work, we
67957578Smuller 	 * must quit right away.
68057578Smuller 	 */
68157578Smuller 	if (!wr_trail && (res <= 0)) {
68257578Smuller 		warn(1,"Unable to append, trailer re-write failed. Quitting.");
68357578Smuller 		return(res);
68457578Smuller 	}
68557578Smuller 
68657578Smuller 	if (res == 0)
68757193Smuller 		warn(0, "End of archive volume %d reached", arvol);
68857193Smuller 	else if (res < 0)
68957193Smuller 		syswarn(1, errno, "Failed write to archive volume: %d", arvol);
69057193Smuller 	else if (!frmt->blkalgn || ((res % frmt->blkalgn) == 0))
69157193Smuller 		warn(0,"WARNING: partial archive write. Archive MAY BE FLAWED");
69257193Smuller 	else
69357193Smuller 		warn(1,"WARNING: partial archive write. Archive IS FLAWED");
69457193Smuller 	return(res);
69557193Smuller }
69657193Smuller 
69757193Smuller /*
69857193Smuller  * ar_rdsync()
69957193Smuller  *	Try to move past a bad spot on a flawed archive as needed to continue
70057193Smuller  *	I/O. Clears error flags to allow I/O to continue.
70157193Smuller  * Return:
70257193Smuller  *	0 when ok to try i/o again, -1 otherwise.
70357193Smuller  */
70457193Smuller 
70557193Smuller #if __STDC__
70657193Smuller int
ar_rdsync(void)70757193Smuller ar_rdsync(void)
70857193Smuller #else
70957193Smuller int
71057193Smuller ar_rdsync()
71157193Smuller #endif
71257193Smuller {
71357193Smuller 	long fsbz;
71457193Smuller 	off_t cpos;
71557193Smuller 	off_t mpos;
71657193Smuller         struct mtop mb;
71757193Smuller 
71857193Smuller 	/*
71957193Smuller 	 * Fail resync attempts at user request (done) or this is going to be
72057193Smuller 	 * an update/append to a existing archive. if last i/o hit media end,
72157193Smuller 	 * we need to go to the next volume not try a resync
72257193Smuller 	 */
72357193Smuller 	if ((done > 0) || (lstrval == 0))
72457193Smuller 		return(-1);
72557193Smuller 
72657193Smuller 	if ((act == APPND) || (act == ARCHIVE)) {
72757193Smuller 		warn(1, "Cannot allow updates to an archive with flaws.");
72857193Smuller 		return(-1);
72957193Smuller 	}
73057193Smuller 	if (io_ok)
73157193Smuller 		did_io = 1;
73257193Smuller 
73357193Smuller 	switch(artyp) {
73457193Smuller 	case ISTAPE:
73557193Smuller 		/*
73657193Smuller 		 * if the last i/o was a successful data transfer, we assume
73757193Smuller 		 * the fault is just a bad record on the tape that we are now
73857193Smuller 		 * past. If we did not get any data since the last resync try
73957193Smuller 		 * to move the tape foward one PHYSICAL record past any
74057193Smuller 		 * damaged tape section. Some tape drives are stubborn and need
74157193Smuller 		 * to be pushed.
74257193Smuller 		 */
74357193Smuller 		if (io_ok) {
74457193Smuller 			io_ok = 0;
74557193Smuller 			lstrval = 1;
74657193Smuller 			break;
74757193Smuller 		}
74857193Smuller 		mb.mt_op = MTFSR;
74957193Smuller 		mb.mt_count = 1;
75057193Smuller 		if (ioctl(arfd, MTIOCTOP, &mb) < 0)
75157193Smuller 			break;
75257193Smuller 		lstrval = 1;
75357193Smuller 		break;
75457193Smuller 	case ISREG:
75557193Smuller 	case ISCHR:
75657193Smuller 	case ISBLK:
75757193Smuller 		/*
75857193Smuller 		 * try to step over the bad part of the device.
75957193Smuller 		 */
76057193Smuller 		io_ok = 0;
76157193Smuller 		if (((fsbz = arsb.st_blksize) <= 0) || (artyp != ISREG))
76257193Smuller 			fsbz = BLKMULT;
76357193Smuller 		if ((cpos = lseek(arfd, (off_t)0L, SEEK_CUR)) < 0)
76457193Smuller 			break;
76557193Smuller 		mpos = fsbz - (cpos % (off_t)fsbz);
76657193Smuller 		if (lseek(arfd, mpos, SEEK_CUR) < 0)
76757193Smuller 			break;
76857193Smuller 		lstrval = 1;
76957193Smuller 		break;
77057193Smuller 	case ISPIPE:
77157193Smuller 	default:
77257193Smuller 		/*
77357193Smuller 		 * cannot recover on these archive device types
77457193Smuller 		 */
77557193Smuller 		io_ok = 0;
77657193Smuller 		break;
77757193Smuller 	}
77857193Smuller 	if (lstrval <= 0) {
77957535Smuller 		warn(1, "Unable to recover from an archive read failure.");
78057193Smuller 		return(-1);
78157193Smuller 	}
78257193Smuller 	warn(0, "Attempting to recover from an archive read failure.");
78357193Smuller 	return(0);
78457193Smuller }
78557193Smuller 
78657193Smuller /*
78757193Smuller  * ar_fow()
78857193Smuller  *	Move the I/O position within the archive foward the specified number of
78957193Smuller  *	bytes as supported by the device. If we cannot move the requested
79057193Smuller  *	number of bytes, return the actual number of bytes moved in skipped.
79157193Smuller  * Return:
79257193Smuller  *	0 if moved the requested distance, -1 on complete failure, 1 on
79357193Smuller  *	partial move (the amount moved is in skipped)
79457193Smuller  */
79557193Smuller 
79657193Smuller #if __STDC__
79757193Smuller int
ar_fow(off_t sksz,off_t * skipped)79857193Smuller ar_fow(off_t sksz, off_t *skipped)
79957193Smuller #else
80057193Smuller int
80157193Smuller ar_fow(sksz, skipped)
80257193Smuller 	off_t sksz;
80357193Smuller 	off_t *skipped;
80457193Smuller #endif
80557193Smuller {
80657193Smuller 	off_t cpos;
80757193Smuller 	off_t mpos;
80857193Smuller 
80957193Smuller 	*skipped = 0;
81057193Smuller 	if (sksz <= 0)
81157193Smuller 		return(0);
81257193Smuller 
81357193Smuller 	/*
81457193Smuller 	 * we cannot move foward at EOF or error
81557193Smuller 	 */
81657193Smuller 	if (lstrval <= 0)
81757193Smuller 		return(lstrval);
81857193Smuller 
81957193Smuller 	/*
82057193Smuller 	 * Safer to read forward on devices where it is hard to find the end of
82157193Smuller 	 * the media without reading to it. With tapes we cannot be sure of the
82257193Smuller 	 * number of physical blocks to skip (we do not know physical block
82357193Smuller 	 * size at this point), so we must only read foward on tapes!
82457193Smuller 	 */
82557193Smuller 	if (artyp != ISREG)
82657193Smuller 		return(0);
82757193Smuller 
82857193Smuller 	/*
82957193Smuller 	 * figure out where we are in the archive
83057193Smuller 	 */
83157193Smuller 	if ((cpos = lseek(arfd, (off_t)0L, SEEK_CUR)) >= 0) {
83257193Smuller 		/*
83357193Smuller 	 	 * we can be asked to move farther than there are bytes in this
83457193Smuller 		 * volume, if so, just go to file end and let normal buf_fill()
83557193Smuller 		 * deal with the end of file (it will go to next volume by
83657193Smuller 		 * itself)
83757193Smuller 	 	 */
83857193Smuller 		if ((mpos = cpos + sksz) > arsb.st_size) {
83957193Smuller 			*skipped = arsb.st_size - cpos;
84057193Smuller 			mpos = arsb.st_size;
84157193Smuller 		} else
84257193Smuller 			*skipped = sksz;
84357193Smuller 		if (lseek(arfd, mpos, SEEK_SET) >= 0)
84457193Smuller 			return(0);
84557193Smuller 	}
84657193Smuller 	syswarn(1, errno, "Foward positioning operation on archive failed");
84757193Smuller 	lstrval = -1;
84857193Smuller 	return(-1);
84957193Smuller }
85057193Smuller 
85157193Smuller /*
85257193Smuller  * ar_rev()
85357193Smuller  *	move the i/o position within the archive backwards the specified byte
85457193Smuller  *	count as supported by the device. With tapes drives we RESET rdblksz to
85557193Smuller  *	the PHYSICAL blocksize.
85657193Smuller  *	NOTE: We should only be called to move backwards so we can rewrite the
85757193Smuller  *	last records (the trailer) of an archive (APPEND).
85857193Smuller  * Return:
85957193Smuller  *	0 if moved the requested distance, -1 on complete failure
86057193Smuller  */
86157193Smuller 
86257193Smuller #if __STDC__
86357193Smuller int
ar_rev(off_t sksz)86457193Smuller ar_rev(off_t sksz)
86557193Smuller #else
86657193Smuller int
86757193Smuller ar_rev(sksz)
86857193Smuller 	off_t sksz;
86957193Smuller #endif
87057193Smuller {
87157193Smuller 	off_t cpos;
87257193Smuller         struct mtop mb;
873*66890Sbostic 	register int phyblk;
87457193Smuller 
87557193Smuller 	/*
87657578Smuller 	 * make sure we do not have try to reverse on a flawed archive
87757193Smuller 	 */
87857193Smuller 	if (lstrval < 0)
87957193Smuller 		return(lstrval);
88057193Smuller 
88157193Smuller 	switch(artyp) {
88257193Smuller 	case ISPIPE:
88357578Smuller 		if (sksz <= 0)
88457578Smuller 			break;
88557193Smuller 		/*
88657193Smuller 		 * cannot go backwards on these critters
88757193Smuller 		 */
88857578Smuller 		warn(1, "Reverse positioning on pipes is not supported.");
88957578Smuller 		lstrval = -1;
89057578Smuller 		return(-1);
89157193Smuller 	case ISREG:
89257193Smuller 	case ISBLK:
89357193Smuller 	case ISCHR:
89457193Smuller 	default:
89557578Smuller 		if (sksz <= 0)
89657578Smuller 			break;
89757578Smuller 
89857193Smuller 		/*
89957193Smuller 		 * For things other than files, backwards movement has a very
90057193Smuller 		 * high probability of failure as we really do not know the
90157193Smuller 		 * true attributes of the device we are talking to (the device
90257193Smuller 		 * may not even have the ability to lseek() in any direction).
90357578Smuller 		 * First we figure out where we are in the archive.
90457193Smuller 		 */
90557578Smuller 		if ((cpos = lseek(arfd, (off_t)0L, SEEK_CUR)) < 0) {
90657578Smuller 			syswarn(1, errno,
90757578Smuller 			   "Unable to obtain current archive byte offset");
90857578Smuller 			lstrval = -1;
90957578Smuller 			return(-1);
91057578Smuller 		}
91157193Smuller 
91257193Smuller 		/*
91357193Smuller 		 * we may try to go backwards past the start when the archive
91457193Smuller 		 * is only a single record. If this hapens and we are on a
91557193Smuller 		 * multi volume archive, we need to go to the end of the
91657193Smuller 		 * previous volume and continue our movement backwards from
91757578Smuller 		 * there.
91857193Smuller 		 */
91957193Smuller 		if ((cpos -= sksz) < (off_t)0L) {
92057193Smuller 			if (arvol > 1) {
92157578Smuller 				/*
92257578Smuller 				 * this should never happen
92357578Smuller 				 */
92457578Smuller 				warn(1,"Reverse position on previous volume.");
92557193Smuller 				lstrval = -1;
92657193Smuller 				return(-1);
92757193Smuller 			}
92857193Smuller 			cpos = (off_t)0L;
92957193Smuller 		}
93057578Smuller 		if (lseek(arfd, cpos, SEEK_SET) < 0) {
93157578Smuller 			syswarn(1, errno, "Unable to seek archive backwards");
93257578Smuller 			lstrval = -1;
93357578Smuller 			return(-1);
93457578Smuller 		}
93557578Smuller 		break;
93657193Smuller 	case ISTAPE:
93757193Smuller 		/*
93857193Smuller 	 	 * Calculate and move the proper number of PHYSICAL tape
93957578Smuller 		 * blocks. If the sksz is not an even multiple of the physical
94057193Smuller 		 * tape size, we cannot do the move (this should never happen).
94157193Smuller 		 * (We also cannot handler trailers spread over two vols).
94257578Smuller 		 * get_phys() also makes sure we are in front of the filemark.
94357193Smuller 	 	 */
94457794Smuller 		if ((phyblk = get_phys()) <= 0) {
94557578Smuller 			lstrval = -1;
94657578Smuller 			return(-1);
94757193Smuller 		}
94857193Smuller 
94957578Smuller 		/*
95057578Smuller 		 * make sure future tape reads only go by physical tape block
95157578Smuller 		 * size (set rdblksz to the real size).
95257578Smuller 		 */
95357578Smuller 		rdblksz = phyblk;
95457578Smuller 
95557578Smuller 		/*
95657578Smuller 		 * if no movement is required, just return (we must be after
95757578Smuller 		 * get_phys() so the physical blocksize is properly set)
95857578Smuller 		 */
95957578Smuller 		if (sksz <= 0)
96057578Smuller 			break;
96157578Smuller 
96257578Smuller 		/*
96357578Smuller 		 * ok we have to move. Make sure the tape drive can do it.
96457578Smuller 		 */
96557193Smuller 		if (sksz % phyblk) {
96657578Smuller 			warn(1,
96757578Smuller 			    "Tape drive unable to backspace requested amount");
96857193Smuller 			lstrval = -1;
96957193Smuller 			return(-1);
97057193Smuller 		}
97157193Smuller 
97257578Smuller 		/*
97357578Smuller 		 * move backwards the requested number of bytes
97457578Smuller 		 */
97557193Smuller 		mb.mt_op = MTBSR;
97657193Smuller 		mb.mt_count = sksz/phyblk;
97757578Smuller 		if (ioctl(arfd, MTIOCTOP, &mb) < 0) {
97857578Smuller 			syswarn(1,errno, "Unable to backspace tape %d blocks.",
97957578Smuller 			    mb.mt_count);
98057578Smuller 			lstrval = -1;
98157578Smuller 			return(-1);
98257578Smuller 		}
98357578Smuller 		break;
98457193Smuller 	}
98557578Smuller 	lstrval = 1;
98657578Smuller 	return(0);
98757193Smuller }
98857193Smuller 
98957193Smuller /*
99057193Smuller  * get_phys()
99157578Smuller  *	Determine the physical block size on a tape drive. We need the physical
99257578Smuller  *	block size so we know how many bytes we skip over when we move with
99357578Smuller  *	mtio commands. We also make sure we are BEFORE THE TAPE FILEMARK when
99457578Smuller  *	return.
99557578Smuller  *	This is one really SLOW routine...
99657193Smuller  * Return:
99757794Smuller  *	physical block size if ok (ok > 0), -1 otherwise
99857193Smuller  */
99957193Smuller 
100057193Smuller #if __STDC__
100157193Smuller static int
get_phys(void)100257193Smuller get_phys(void)
100357193Smuller #else
100457193Smuller static int
100557193Smuller get_phys()
100657193Smuller #endif
100757193Smuller {
100857578Smuller 	register int padsz = 0;
100957535Smuller 	register int res;
101057794Smuller 	register int phyblk;
101157535Smuller 	struct mtop mb;
101257578Smuller 	char scbuf[MAXBLK];
101357193Smuller 
101457193Smuller 	/*
101557578Smuller 	 * move to the file mark, and then back up one record and read it.
101657578Smuller 	 * this should tell us the physical record size the tape is using.
101757578Smuller 	 */
101857578Smuller 	if (lstrval == 1) {
101957578Smuller 		/*
102057578Smuller 		 * we know we are at file mark when we get back a 0 from
102157578Smuller 		 * read()
102257578Smuller 		 */
102357578Smuller 		while ((res = read(arfd, scbuf, sizeof(scbuf))) > 0)
102457578Smuller 			padsz += res;
102557578Smuller 		if (res < 0) {
102657578Smuller 			syswarn(1, errno, "Unable to locate tape filemark.");
102757578Smuller 			return(-1);
102857578Smuller 		}
102957578Smuller 	}
103057193Smuller 
103157578Smuller 	/*
103257578Smuller 	 * move backwards over the file mark so we are at the end of the
103357578Smuller 	 * last record.
103457578Smuller 	 */
103557578Smuller 	mb.mt_op = MTBSF;
103657193Smuller 	mb.mt_count = 1;
103757578Smuller 	if (ioctl(arfd, MTIOCTOP, &mb) < 0) {
103857578Smuller 		syswarn(1, errno, "Unable to backspace over tape filemark.");
103957193Smuller 		return(-1);
104057535Smuller 	}
104157193Smuller 
104257193Smuller 	/*
104357578Smuller 	 * move backwards so we are in front of the last record and read it to
104457578Smuller 	 * get physical tape blocksize.
104557193Smuller 	 */
104657578Smuller 	mb.mt_op = MTBSR;
104757578Smuller 	mb.mt_count = 1;
104857578Smuller 	if (ioctl(arfd, MTIOCTOP, &mb) < 0) {
104957578Smuller 		syswarn(1, errno, "Unable to backspace over last tape block.");
105057193Smuller 		return(-1);
105157578Smuller 	}
105257578Smuller 	if ((phyblk = read(arfd, scbuf, sizeof(scbuf))) <= 0) {
105357578Smuller 		syswarn(1, errno, "Cannot determine archive tape blocksize.");
105457578Smuller 		return(-1);
105557578Smuller 	}
105657535Smuller 
105757535Smuller 	/*
105857578Smuller 	 * read foward to the file mark, then back up in front of the filemark
105957578Smuller 	 * (this is a bit paranoid, but should be safe to do).
106057535Smuller 	 */
106157578Smuller 	while ((res = read(arfd, scbuf, sizeof(scbuf))) > 0)
106257578Smuller 		;
106357578Smuller 	if (res < 0) {
106457578Smuller 		syswarn(1, errno, "Unable to locate tape filemark.");
106557535Smuller 		return(-1);
106657578Smuller 	}
106757578Smuller 	mb.mt_op = MTBSF;
106857578Smuller 	mb.mt_count = 1;
106957578Smuller 	if (ioctl(arfd, MTIOCTOP, &mb) < 0) {
107057578Smuller 		syswarn(1, errno, "Unable to backspace over tape filemark.");
107157578Smuller 		return(-1);
107257578Smuller 	}
107357535Smuller 
107457535Smuller 	/*
107557578Smuller 	 * set lstrval so we know that the filemark has not been seen
107657535Smuller 	 */
107757578Smuller 	lstrval = 1;
107857578Smuller 
107957578Smuller 	/*
108057578Smuller 	 * return if there was no padding
108157578Smuller 	 */
108257578Smuller 	if (padsz == 0)
108357794Smuller 		return(phyblk);
108457535Smuller 
108557535Smuller 	/*
108657578Smuller 	 * make sure we can move backwards over the padding. (this should
108757578Smuller 	 * never fail).
108857535Smuller 	 */
108957578Smuller 	if (padsz % phyblk) {
109057578Smuller 		warn(1, "Tape drive unable to backspace requested amount");
109157535Smuller 		return(-1);
109257578Smuller 	}
109357535Smuller 
109457535Smuller 	/*
109557578Smuller 	 * move backwards over the padding so the head is where it was when
109657578Smuller 	 * we were first called (if required).
109757535Smuller 	 */
109857578Smuller 	mb.mt_op = MTBSR;
109957578Smuller 	mb.mt_count = padsz/phyblk;
110057578Smuller 	if (ioctl(arfd, MTIOCTOP, &mb) < 0) {
110157578Smuller 		syswarn(1,errno,"Unable to backspace tape over %d pad blocks",
110257578Smuller 		    mb.mt_count);
110357535Smuller 		return(-1);
110457578Smuller 	}
110557794Smuller 	return(phyblk);
110657193Smuller }
110757193Smuller 
110857193Smuller /*
110957193Smuller  * ar_next()
111057535Smuller  *	prompts the user for the next volume in this archive. For some devices
111157535Smuller  *	we may allow the media to be changed. Otherwise a new archive is
111257535Smuller  *	prompted for. By pax spec, if there is no controlling tty or an eof is
111357535Smuller  *	read on tty input, we must quit pax.
111457193Smuller  * Return:
111557193Smuller  *	0 when ready to continue, -1 when all done
111657193Smuller  */
111757193Smuller 
111857193Smuller #if __STDC__
111957193Smuller int
ar_next(void)112057193Smuller ar_next(void)
112157193Smuller #else
112257193Smuller int
112357193Smuller ar_next()
112457193Smuller #endif
112557193Smuller {
112657193Smuller 	char buf[PAXPATHLEN+2];
112757193Smuller 	static int freeit = 0;
112857193Smuller 	sigset_t o_mask;
112957193Smuller 
113057193Smuller 	/*
113157535Smuller 	 * WE MUST CLOSE THE DEVICE. A lot of devices must see last close, (so
113257193Smuller 	 * things like writing EOF etc will be done) (Watch out ar_close() can
113357535Smuller 	 * also be called via a signal handler, so we must prevent a race.
113457193Smuller 	 */
113557193Smuller 	if (sigprocmask(SIG_BLOCK, &s_mask, &o_mask) < 0)
113657535Smuller 		syswarn(0, errno, "Unable to set signal mask");
113757193Smuller 	ar_close();
113857193Smuller 	if (sigprocmask(SIG_SETMASK, &o_mask, (sigset_t *)NULL) < 0)
113957535Smuller 		syswarn(0, errno, "Unable to restore signal mask");
114057193Smuller 
114157578Smuller 	if (done || !wr_trail)
114257193Smuller 		return(-1);
114357193Smuller 
1144*66890Sbostic 	tty_prnt("\nATTENTION! %s archive volume change required.\n", argv0);
114557193Smuller 
114657193Smuller 	/*
114757193Smuller 	 * if i/o is on stdin or stdout, we cannot reopen it (we do not know
114857535Smuller 	 * the name), the user will be forced to type it in.
114957193Smuller 	 */
115057193Smuller 	if (strcmp(arcname, STDO) && strcmp(arcname, STDN) && (artyp != ISREG)
115157193Smuller 	    && (artyp != ISPIPE)) {
115257193Smuller 		if (artyp == ISTAPE) {
115357193Smuller 			tty_prnt("%s ready for archive tape volume: %d\n",
115457193Smuller 				arcname, arvol);
115557193Smuller 			tty_prnt("Load the NEXT TAPE on the tape drive");
115657193Smuller 		} else {
115757193Smuller 			tty_prnt("%s ready for archive volume: %d\n",
115857193Smuller 				arcname, arvol);
115957193Smuller 			tty_prnt("Load the NEXT STORAGE MEDIA (if required)");
116057193Smuller 		}
116157193Smuller 
116257193Smuller 		if ((act == ARCHIVE) || (act == APPND))
116357193Smuller 			tty_prnt(" and make sure it is WRITE ENABLED.\n");
116457193Smuller 		else
116557193Smuller 			tty_prnt("\n");
116657193Smuller 
116757193Smuller 		for(;;) {
1168*66890Sbostic 			tty_prnt("Type \"y\" to continue, \".\" to quit %s,",
1169*66890Sbostic 				argv0);
117057193Smuller 			tty_prnt(" or \"s\" to switch to new device.\nIf you");
117157193Smuller 			tty_prnt(" cannot change storage media, type \"s\"\n");
117257193Smuller 			tty_prnt("Is the device ready and online? > ");
117357193Smuller 
117457193Smuller 			if ((tty_read(buf,sizeof(buf))<0) || !strcmp(buf,".")){
117557193Smuller 				done = 1;
117657193Smuller 				lstrval = -1;
1177*66890Sbostic 				tty_prnt("Quitting %s!\n", argv0);
117857193Smuller 				vfpart = 0;
117957193Smuller 				return(-1);
118057193Smuller 			}
118157193Smuller 
118257193Smuller 			if ((buf[0] == '\0') || (buf[1] != '\0')) {
118357193Smuller 				tty_prnt("%s unknown command, try again\n",buf);
118457193Smuller 				continue;
118557193Smuller 			}
118657193Smuller 
118757193Smuller 			switch (buf[0]) {
118857193Smuller 			case 'y':
118957193Smuller 			case 'Y':
119057193Smuller 				/*
119157193Smuller 				 * we are to continue with the same device
119257193Smuller 				 */
119357193Smuller 				if (ar_open(arcname) >= 0)
119457193Smuller 					return(0);
119557193Smuller 				tty_prnt("Cannot re-open %s, try again\n",
119657193Smuller 					arcname);
119757193Smuller 				continue;
119857193Smuller 			case 's':
119957193Smuller 			case 'S':
120057193Smuller 				/*
120157193Smuller 				 * user wants to open a different device
120257193Smuller 				 */
120357193Smuller 				tty_prnt("Switching to a different archive\n");
120457193Smuller 				break;
120557193Smuller 			default:
120657193Smuller 				tty_prnt("%s unknown command, try again\n",buf);
120757193Smuller 				continue;
120857193Smuller 			}
120957193Smuller 			break;
121057193Smuller 		}
121157193Smuller 	} else
121257193Smuller 		tty_prnt("Ready for archive volume: %d\n", arvol);
121357193Smuller 
121457193Smuller 	/*
121557193Smuller 	 * have to go to a different archive
121657193Smuller 	 */
121757193Smuller 	for (;;) {
1218*66890Sbostic 		tty_prnt("Input archive name or \".\" to quit %s.\n", argv0);
121957193Smuller 		tty_prnt("Archive name > ");
122057193Smuller 
122157193Smuller 		if ((tty_read(buf, sizeof(buf)) < 0) || !strcmp(buf, ".")) {
122257193Smuller 			done = 1;
122357193Smuller 			lstrval = -1;
1224*66890Sbostic 			tty_prnt("Quitting %s!\n", argv0);
122557193Smuller 			vfpart = 0;
122657193Smuller 			return(-1);
122757193Smuller 		}
122857193Smuller 		if (buf[0] == '\0') {
122957193Smuller 			tty_prnt("Empty file name, try again\n");
123057193Smuller 			continue;
123157193Smuller 		}
123257193Smuller                 if (!strcmp(buf, "..")) {
123357193Smuller                         tty_prnt("Illegal file name: .. try again\n");
123457193Smuller                         continue;
123557193Smuller                 }
123657193Smuller 		if (strlen(buf) > PAXPATHLEN) {
123757193Smuller 			tty_prnt("File name too long, try again\n");
123857193Smuller 			continue;
123957193Smuller 		}
124057193Smuller 
124157193Smuller 		/*
124257193Smuller 		 * try to open new archive
124357193Smuller 		 */
124457193Smuller 		if (ar_open(buf) >= 0) {
124557193Smuller 			if (freeit) {
124657193Smuller 				(void)free(arcname);
124757193Smuller 				freeit = 0;
124857193Smuller 			}
124957193Smuller 			if ((arcname = strdup(buf)) == NULL) {
125057193Smuller 				done = 1;
125157193Smuller 				lstrval = -1;
125257535Smuller 				warn(0, "Cannot save archive name.");
125357193Smuller 				return(-1);
125457193Smuller 			}
125557193Smuller 			freeit = 1;
125657193Smuller 			break;
125757193Smuller 		}
125857193Smuller 		tty_prnt("Cannot open %s, try again\n", buf);
125957193Smuller 		continue;
126057193Smuller 	}
126157193Smuller 	return(0);
126257193Smuller }
1263