xref: /csrg-svn/bin/pax/ar_io.c (revision 58651)
157193Smuller /*-
257193Smuller  * Copyright (c) 1992 Keith Muller.
357193Smuller  * Copyright (c) 1992 The Regents of the University of California.
457193Smuller  * 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*58651Smuller static char sccsid[] = "@(#)ar_io.c	1.6 (Berkeley) 03/12/93";
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
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
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);
29557535Smuller 		(void)fputs("pax: Waiting for tape drive close to complete...",
29657535Smuller 		    outf);
29757535Smuller 		(void)fflush(outf);
29857535Smuller 	}
29957535Smuller 
30057584Smuller 	/*
30157584Smuller 	 * if nothing was written to the archive (and we created it), we remove
30257584Smuller 	 * it
30357584Smuller 	 */
30457584Smuller 	if (can_unlnk && (fstat(arfd, &arsb) == 0) && (S_ISREG(arsb.st_mode)) &&
30557584Smuller 	    (arsb.st_size == 0)) {
30657584Smuller 		(void)unlink(arcname);
30757584Smuller 		can_unlnk = 0;
30857584Smuller 	}
30957584Smuller 
31057193Smuller 	(void)close(arfd);
31157535Smuller 
31257578Smuller 	if (vflag && (artyp == ISTAPE)) {
31357535Smuller 		(void)fputs("done.\n", outf);
31457578Smuller 		vfpart = 0;
31557535Smuller 		(void)fflush(outf);
31657535Smuller 	}
31757193Smuller 	arfd = -1;
31857535Smuller 
31957193Smuller 	if (!io_ok && !did_io) {
32057193Smuller 		flcnt = 0;
32157193Smuller 		return;
32257193Smuller 	}
32357193Smuller 	did_io = io_ok = 0;
32457193Smuller 
32557193Smuller 	/*
32657193Smuller 	 * The volume number is only increased when the last device has data
32757535Smuller 	 * and we have already determined the archive format.
32857193Smuller 	 */
32957535Smuller 	if (frmt != NULL)
33057535Smuller 		++arvol;
33157535Smuller 
33257193Smuller 	if (!vflag) {
33357193Smuller 		flcnt = 0;
33457193Smuller 		return;
33557193Smuller 	}
33657193Smuller 
33757193Smuller 	/*
33857193Smuller 	 * Print out a summary of I/O for this archive volume.
33957193Smuller 	 */
34057193Smuller 	if (vfpart) {
34157193Smuller 		(void)putc('\n', outf);
34257193Smuller 		vfpart = 0;
34357193Smuller 	}
34457193Smuller 
34557535Smuller 	/*
34657535Smuller 	 * If we have not determined the format yet, we just say how many bytes
34757535Smuller 	 * we have skipped over looking for a header to id. there is no way we
34857535Smuller 	 * could have written anything yet.
34957535Smuller 	 */
35057535Smuller 	if (frmt == NULL) {
35157535Smuller #	ifdef NET2_STAT
35257535Smuller 		(void)fprintf(outf, "pax: unknown format, %lu bytes skipped.\n",
35357535Smuller #	else
35457535Smuller 		(void)fprintf(outf, "pax: unknown format, %qu bytes skipped.\n",
35557535Smuller #	endif
35657535Smuller 		    rdcnt);
35757535Smuller 		(void)fflush(outf);
35857535Smuller 		flcnt = 0;
35957535Smuller 		return;
36057535Smuller 	}
36157535Smuller 
36257193Smuller 	(void)fprintf(outf,
36357193Smuller #	ifdef NET2_STAT
36457535Smuller 	    "pax: %s vol %d, %lu files, %lu bytes read, %lu bytes written.\n",
36557193Smuller #	else
36657535Smuller 	    "pax: %s vol %d, %lu files, %qu bytes read, %qu bytes written.\n",
36757193Smuller #	endif
36857193Smuller 	    frmt->name, arvol-1, flcnt, rdcnt, wrcnt);
36957193Smuller 	(void)fflush(outf);
37057193Smuller 	flcnt = 0;
37157193Smuller }
37257193Smuller 
37357193Smuller /*
374*58651Smuller  * ar_drain()
375*58651Smuller  *	drain any archive format independent padding from an archive read
376*58651Smuller  *	from a socket or a pipe. This is to prevent the process on the
377*58651Smuller  *	other side of the pipe from getting a SIGPIPE (pax will stop
378*58651Smuller  *	reading an archive once a format dependent trailer is detected).
379*58651Smuller  */
380*58651Smuller #if __STDC__
381*58651Smuller void
382*58651Smuller ar_drain(void)
383*58651Smuller #else
384*58651Smuller void
385*58651Smuller ar_drain()
386*58651Smuller #endif
387*58651Smuller {
388*58651Smuller 	register int res;
389*58651Smuller 	char drbuf[MAXBLK];
390*58651Smuller 
391*58651Smuller 	/*
392*58651Smuller 	 * we only drain from a pipe/socket. Other devices can be closed
393*58651Smuller 	 * without reading up to end of file. We sure hope that pipe is closed
394*58651Smuller 	 * on the other side so we will get an EOF.
395*58651Smuller 	 */
396*58651Smuller 	if ((artyp != ISPIPE) || (lstrval <= 0))
397*58651Smuller 		return;
398*58651Smuller 
399*58651Smuller 	/*
400*58651Smuller 	 * keep reading until pipe is drained
401*58651Smuller 	 */
402*58651Smuller 	while ((res = read(arfd, drbuf, sizeof(drbuf))) > 0)
403*58651Smuller 		;
404*58651Smuller 	lstrval = res;
405*58651Smuller }
406*58651Smuller 
407*58651Smuller /*
40857193Smuller  * ar_set_wr()
40957578Smuller  *	Set up device right before switching from read to write in an append.
41057578Smuller  *	device dependent code (if required) to do this should be added here.
41157578Smuller  *	For all archive devices we are already positioned at the place we want
41257578Smuller  *	to start writing when this routine is called.
41357193Smuller  * Return:
41457193Smuller  *	0 if all ready to write, -1 otherwise
41557193Smuller  */
41657193Smuller 
41757193Smuller #if __STDC__
41857193Smuller int
41957193Smuller ar_set_wr(void)
42057193Smuller #else
42157193Smuller int
42257193Smuller ar_set_wr()
42357193Smuller #endif
42457193Smuller {
42557193Smuller 	off_t cpos;
42657193Smuller 
42757578Smuller 	/*
42857578Smuller 	 * we must make sure the trailer is rewritten on append, ar_next()
42957578Smuller 	 * will stop us if the archive containing the trailer was not written
43057578Smuller 	 */
43157578Smuller 	wr_trail = 0;
43257578Smuller 
43357193Smuller 	/*
43457193Smuller 	 * Add any device dependent code as required here
43557193Smuller 	 */
43657193Smuller 	if (artyp != ISREG)
43757193Smuller 		return(0);
43857193Smuller 	/*
43957535Smuller 	 * Ok we have an archive in a regular file. If we were rewriting a
44057535Smuller 	 * file, we must get rid of all the stuff after the current offset
44157535Smuller 	 * (it was not written by pax).
44257193Smuller 	 */
44357193Smuller 	if (((cpos = lseek(arfd, (off_t)0L, SEEK_CUR)) < 0) ||
44457578Smuller 	    (ftruncate(arfd, cpos) < 0)) {
44557578Smuller 		syswarn(1, errno, "Unable to truncate archive file");
44657193Smuller 		return(-1);
44757578Smuller 	}
44857193Smuller 	return(0);
44957193Smuller }
45057193Smuller 
45157193Smuller /*
45257193Smuller  * ar_app_ok()
45357193Smuller  *	check if the last volume in the archive allows appends. We cannot check
45457193Smuller  *	this until we are ready to write since there is no spec that says all
45557193Smuller  *	volumes in a single archive have to be of the same type...
45657193Smuller  * Return:
45757193Smuller  *	0 if we can append, -1 otherwise.
45857193Smuller  */
45957193Smuller 
46057193Smuller #if __STDC__
46157193Smuller int
46257193Smuller ar_app_ok(void)
46357193Smuller #else
46457193Smuller int
46557193Smuller ar_app_ok()
46657193Smuller #endif
46757193Smuller {
46857193Smuller 	if (artyp == ISPIPE) {
46957193Smuller 		warn(1, "Cannot append to an archive obtained from a pipe.");
47057193Smuller 		return(-1);
47157193Smuller 	}
47257193Smuller 
47357193Smuller 	if (!invld_rec)
47457193Smuller 		return(0);
47557193Smuller 	warn(1,"Cannot append, device record size %d does not support pax spec",
47657193Smuller 		rdblksz);
47757193Smuller 	return(-1);
47857193Smuller }
47957193Smuller 
48057193Smuller /*
48157193Smuller  * ar_read()
48257193Smuller  *	read up to a specified number of bytes from the archive into the
48357193Smuller  *	supplied buffer. When dealing with tapes we may not always be able to
48457193Smuller  *	read what we want.
48557193Smuller  * Return:
48657193Smuller  *	Number of bytes in buffer. 0 for end of file, -1 for a read error.
48757193Smuller  */
48857193Smuller 
48957193Smuller #if __STDC__
49057193Smuller int
49157193Smuller ar_read(register char *buf, register int cnt)
49257193Smuller #else
49357193Smuller int
49457193Smuller ar_read(buf, cnt)
49557193Smuller 	register char *buf;
49657193Smuller 	register int cnt;
49757193Smuller #endif
49857193Smuller {
49957193Smuller 	register int res = 0;
50057193Smuller 
50157193Smuller 	/*
50257193Smuller 	 * if last i/o was in error, no more reads until reset or new volume
50357193Smuller 	 */
50457193Smuller 	if (lstrval <= 0)
50557193Smuller 		return(lstrval);
50657193Smuller 
50757193Smuller 	/*
50857193Smuller 	 * how we read must be based on device type
50957193Smuller 	 */
51057193Smuller 	switch (artyp) {
51157193Smuller 	case ISTAPE:
51257193Smuller 		if ((res = read(arfd, buf, cnt)) > 0) {
51357193Smuller 			/*
51457193Smuller 			 * CAUTION: tape systems may not always return the same
51557193Smuller 			 * sized records so we leave blksz == MAXBLK. The
51657193Smuller 			 * physical record size that a tape drive supports is
51757193Smuller 			 * very hard to determine in a uniform and portable
51857193Smuller 			 * manner.
51957193Smuller 			 */
52057193Smuller 			io_ok = 1;
52157193Smuller 			if (res != rdblksz) {
52257193Smuller 				/*
52357193Smuller 				 * Record size changed. If this is happens on
52457535Smuller 				 * any record after the first, we probably have
52557535Smuller 				 * a tape drive which has a fixed record size
52657535Smuller 				 * we are getting multiple records in a single
52757535Smuller 				 * read). Watch out for record blocking that
52857535Smuller 				 * violates pax spec (must be a multiple of
52957535Smuller 				 * BLKMULT).
53057193Smuller 				 */
53157193Smuller 				rdblksz = res;
53257193Smuller 				if (rdblksz % BLKMULT)
53357193Smuller 					invld_rec = 1;
53457193Smuller 			}
53557193Smuller 			return(res);
53657193Smuller 		}
53757193Smuller 		break;
53857193Smuller 	case ISREG:
53957193Smuller 	case ISBLK:
54057193Smuller 	case ISCHR:
54157193Smuller 	case ISPIPE:
54257193Smuller 	default:
54357193Smuller 		/*
54457193Smuller 		 * Files are so easy to deal with. These other things cannot
54557193Smuller 		 * be trusted at all. So when we are dealing with character
54657193Smuller 		 * devices and pipes we just take what they have ready for us
54757193Smuller 		 * and return. Trying to do anything else with them runs the
54857193Smuller 		 * risk of failure.
54957193Smuller 		 */
55057193Smuller 		if ((res = read(arfd, buf, cnt)) > 0) {
55157193Smuller 			io_ok = 1;
55257193Smuller 			return(res);
55357193Smuller 		}
55457193Smuller 		break;
55557193Smuller 	}
55657193Smuller 
55757193Smuller 	/*
55857193Smuller 	 * We are in trouble at this point, something is broken...
55957193Smuller 	 */
56057193Smuller 	lstrval = res;
56157193Smuller 	if (res < 0)
56257193Smuller 		syswarn(1, errno, "Failed read on archive volume %d", arvol);
56357193Smuller 	else
56457193Smuller 		warn(0, "End of archive volume %d reached", arvol);
56557193Smuller 	return(res);
56657193Smuller }
56757193Smuller 
56857193Smuller /*
56957193Smuller  * ar_write()
57057193Smuller  *	Write a specified number of bytes in supplied buffer to the archive
57157193Smuller  *	device so it appears as a single "block". Deals with errors and tries
57257193Smuller  *	to recover when faced with short writes.
57357193Smuller  * Return:
57457193Smuller  *	Number of bytes written. 0 indicates end of volume reached and with no
57557193Smuller  *	flaws (as best that can be detected). A -1 indicates an unrecoverable
57657193Smuller  *	error in the archive occured.
57757193Smuller  */
57857193Smuller 
57957193Smuller #if __STDC__
58057193Smuller int
58157193Smuller ar_write(register char *buf, register int bsz)
58257193Smuller #else
58357193Smuller int
58457193Smuller ar_write(buf, bsz)
58557193Smuller 	register char *buf;
58657193Smuller 	register int bsz;
58757193Smuller #endif
58857193Smuller {
58957193Smuller 	register int res;
59057193Smuller 	off_t cpos;
59157193Smuller 
59257193Smuller 	/*
59357193Smuller 	 * do not allow pax to create a "bad" archive. Once a write fails on
59457193Smuller 	 * an archive volume prevent further writes to it.
59557193Smuller 	 */
59657193Smuller 	if (lstrval <= 0)
59757193Smuller 		return(lstrval);
59857193Smuller 
59957193Smuller 	if ((res = write(arfd, buf, bsz)) == bsz) {
60057578Smuller 		wr_trail = 1;
60157193Smuller 		io_ok = 1;
60257193Smuller 		return(bsz);
60357193Smuller 	}
60457193Smuller 	/*
60557193Smuller 	 * write broke, see what we can do with it. We try to send any partial
60657535Smuller 	 * writes that may violate pax spec to the next archive volume.
60757193Smuller 	 */
60857193Smuller 	if (res < 0)
60957193Smuller 		lstrval = res;
61057193Smuller 	else
61157193Smuller 		lstrval = 0;
61257193Smuller 
61357193Smuller 	switch (artyp) {
61457193Smuller 	case ISREG:
61557193Smuller 		if ((res > 0) && (res % BLKMULT)) {
61657193Smuller 			/*
61757193Smuller 		 	 * try to fix up partial writes which are not BLKMULT
61857193Smuller 			 * in size by forcing the runt record to next archive
61957193Smuller 			 * volume
62057193Smuller 		 	 */
62157193Smuller 			if ((cpos = lseek(arfd, (off_t)0L, SEEK_CUR)) < 0)
62257193Smuller 				break;
62357193Smuller 			cpos -= (off_t)res;
62457193Smuller 			if (ftruncate(arfd, cpos) < 0)
62557193Smuller 				break;
62657193Smuller 			res = lstrval = 0;
62757193Smuller 			break;
62857193Smuller 		}
62957193Smuller 		if (res >= 0)
63057193Smuller 			break;
63157193Smuller 		/*
63257193Smuller 		 * if file is out of space, handle it like a return of 0
63357193Smuller 		 */
63457193Smuller 		if ((errno == ENOSPC) || (errno == EFBIG) || (errno == EDQUOT))
63557193Smuller 			res = lstrval = 0;
63657193Smuller 		break;
63757193Smuller 	case ISTAPE:
63857193Smuller 	case ISCHR:
63957193Smuller 	case ISBLK:
64057193Smuller 		if (res >= 0)
64157193Smuller 			break;
64257193Smuller 		if (errno == EACCES) {
64357193Smuller 			warn(0, "Write failed, archive is write protected.");
64457193Smuller 			res = lstrval = 0;
64557193Smuller 			return(0);
64657193Smuller 		}
64757193Smuller 		/*
64857193Smuller 		 * see if we reached the end of media, if so force a change to
64957193Smuller 		 * the next volume
65057193Smuller 		 */
65157193Smuller 		if ((errno == ENOSPC) || (errno == EIO) || (errno == ENXIO))
65257193Smuller 			res = lstrval = 0;
65357193Smuller 		break;
65457193Smuller 	case ISPIPE:
65557193Smuller 	default:
65657193Smuller 		/*
65757193Smuller 		 * we cannot fix errors to these devices
65857193Smuller 		 */
65957193Smuller 		break;
66057193Smuller 	}
66157193Smuller 
66257193Smuller 	/*
66357193Smuller 	 * Better tell the user the bad news...
66457535Smuller 	 * if this is a block aligned archive format, we may have a bad archive
66557535Smuller 	 * if the format wants the header to start at a BLKMULT boundry. While
66657193Smuller 	 * we can deal with the mis-aligned data, it violates spec and other
66757193Smuller 	 * archive readers will likely fail. if the format is not block
66857535Smuller 	 * aligned, the user may be lucky (and the archive is ok).
66957193Smuller 	 */
67057578Smuller 	if (res >= 0) {
67157578Smuller 		if (res > 0)
67257578Smuller 			wr_trail = 1;
67357193Smuller 		io_ok = 1;
67457578Smuller 	}
67557578Smuller 
67657578Smuller 	/*
67757578Smuller 	 * If we were trying to rewrite the trailer and it didn't work, we
67857578Smuller 	 * must quit right away.
67957578Smuller 	 */
68057578Smuller 	if (!wr_trail && (res <= 0)) {
68157578Smuller 		warn(1,"Unable to append, trailer re-write failed. Quitting.");
68257578Smuller 		return(res);
68357578Smuller 	}
68457578Smuller 
68557578Smuller 	if (res == 0)
68657193Smuller 		warn(0, "End of archive volume %d reached", arvol);
68757193Smuller 	else if (res < 0)
68857193Smuller 		syswarn(1, errno, "Failed write to archive volume: %d", arvol);
68957193Smuller 	else if (!frmt->blkalgn || ((res % frmt->blkalgn) == 0))
69057193Smuller 		warn(0,"WARNING: partial archive write. Archive MAY BE FLAWED");
69157193Smuller 	else
69257193Smuller 		warn(1,"WARNING: partial archive write. Archive IS FLAWED");
69357193Smuller 	return(res);
69457193Smuller }
69557193Smuller 
69657193Smuller /*
69757193Smuller  * ar_rdsync()
69857193Smuller  *	Try to move past a bad spot on a flawed archive as needed to continue
69957193Smuller  *	I/O. Clears error flags to allow I/O to continue.
70057193Smuller  * Return:
70157193Smuller  *	0 when ok to try i/o again, -1 otherwise.
70257193Smuller  */
70357193Smuller 
70457193Smuller #if __STDC__
70557193Smuller int
70657193Smuller ar_rdsync(void)
70757193Smuller #else
70857193Smuller int
70957193Smuller ar_rdsync()
71057193Smuller #endif
71157193Smuller {
71257193Smuller 	long fsbz;
71357193Smuller 	off_t cpos;
71457193Smuller 	off_t mpos;
71557193Smuller         struct mtop mb;
71657193Smuller 
71757193Smuller 	/*
71857193Smuller 	 * Fail resync attempts at user request (done) or this is going to be
71957193Smuller 	 * an update/append to a existing archive. if last i/o hit media end,
72057193Smuller 	 * we need to go to the next volume not try a resync
72157193Smuller 	 */
72257193Smuller 	if ((done > 0) || (lstrval == 0))
72357193Smuller 		return(-1);
72457193Smuller 
72557193Smuller 	if ((act == APPND) || (act == ARCHIVE)) {
72657193Smuller 		warn(1, "Cannot allow updates to an archive with flaws.");
72757193Smuller 		return(-1);
72857193Smuller 	}
72957193Smuller 	if (io_ok)
73057193Smuller 		did_io = 1;
73157193Smuller 
73257193Smuller 	switch(artyp) {
73357193Smuller 	case ISTAPE:
73457193Smuller 		/*
73557193Smuller 		 * if the last i/o was a successful data transfer, we assume
73657193Smuller 		 * the fault is just a bad record on the tape that we are now
73757193Smuller 		 * past. If we did not get any data since the last resync try
73857193Smuller 		 * to move the tape foward one PHYSICAL record past any
73957193Smuller 		 * damaged tape section. Some tape drives are stubborn and need
74057193Smuller 		 * to be pushed.
74157193Smuller 		 */
74257193Smuller 		if (io_ok) {
74357193Smuller 			io_ok = 0;
74457193Smuller 			lstrval = 1;
74557193Smuller 			break;
74657193Smuller 		}
74757193Smuller 		mb.mt_op = MTFSR;
74857193Smuller 		mb.mt_count = 1;
74957193Smuller 		if (ioctl(arfd, MTIOCTOP, &mb) < 0)
75057193Smuller 			break;
75157193Smuller 		lstrval = 1;
75257193Smuller 		break;
75357193Smuller 	case ISREG:
75457193Smuller 	case ISCHR:
75557193Smuller 	case ISBLK:
75657193Smuller 		/*
75757193Smuller 		 * try to step over the bad part of the device.
75857193Smuller 		 */
75957193Smuller 		io_ok = 0;
76057193Smuller 		if (((fsbz = arsb.st_blksize) <= 0) || (artyp != ISREG))
76157193Smuller 			fsbz = BLKMULT;
76257193Smuller 		if ((cpos = lseek(arfd, (off_t)0L, SEEK_CUR)) < 0)
76357193Smuller 			break;
76457193Smuller 		mpos = fsbz - (cpos % (off_t)fsbz);
76557193Smuller 		if (lseek(arfd, mpos, SEEK_CUR) < 0)
76657193Smuller 			break;
76757193Smuller 		lstrval = 1;
76857193Smuller 		break;
76957193Smuller 	case ISPIPE:
77057193Smuller 	default:
77157193Smuller 		/*
77257193Smuller 		 * cannot recover on these archive device types
77357193Smuller 		 */
77457193Smuller 		io_ok = 0;
77557193Smuller 		break;
77657193Smuller 	}
77757193Smuller 	if (lstrval <= 0) {
77857535Smuller 		warn(1, "Unable to recover from an archive read failure.");
77957193Smuller 		return(-1);
78057193Smuller 	}
78157193Smuller 	warn(0, "Attempting to recover from an archive read failure.");
78257193Smuller 	return(0);
78357193Smuller }
78457193Smuller 
78557193Smuller /*
78657193Smuller  * ar_fow()
78757193Smuller  *	Move the I/O position within the archive foward the specified number of
78857193Smuller  *	bytes as supported by the device. If we cannot move the requested
78957193Smuller  *	number of bytes, return the actual number of bytes moved in skipped.
79057193Smuller  * Return:
79157193Smuller  *	0 if moved the requested distance, -1 on complete failure, 1 on
79257193Smuller  *	partial move (the amount moved is in skipped)
79357193Smuller  */
79457193Smuller 
79557193Smuller #if __STDC__
79657193Smuller int
79757193Smuller ar_fow(off_t sksz, off_t *skipped)
79857193Smuller #else
79957193Smuller int
80057193Smuller ar_fow(sksz, skipped)
80157193Smuller 	off_t sksz;
80257193Smuller 	off_t *skipped;
80357193Smuller #endif
80457193Smuller {
80557193Smuller 	off_t cpos;
80657193Smuller 	off_t mpos;
80757193Smuller 
80857193Smuller 	*skipped = 0;
80957193Smuller 	if (sksz <= 0)
81057193Smuller 		return(0);
81157193Smuller 
81257193Smuller 	/*
81357193Smuller 	 * we cannot move foward at EOF or error
81457193Smuller 	 */
81557193Smuller 	if (lstrval <= 0)
81657193Smuller 		return(lstrval);
81757193Smuller 
81857193Smuller 	/*
81957193Smuller 	 * Safer to read forward on devices where it is hard to find the end of
82057193Smuller 	 * the media without reading to it. With tapes we cannot be sure of the
82157193Smuller 	 * number of physical blocks to skip (we do not know physical block
82257193Smuller 	 * size at this point), so we must only read foward on tapes!
82357193Smuller 	 */
82457193Smuller 	if (artyp != ISREG)
82557193Smuller 		return(0);
82657193Smuller 
82757193Smuller 	/*
82857193Smuller 	 * figure out where we are in the archive
82957193Smuller 	 */
83057193Smuller 	if ((cpos = lseek(arfd, (off_t)0L, SEEK_CUR)) >= 0) {
83157193Smuller 		/*
83257193Smuller 	 	 * we can be asked to move farther than there are bytes in this
83357193Smuller 		 * volume, if so, just go to file end and let normal buf_fill()
83457193Smuller 		 * deal with the end of file (it will go to next volume by
83557193Smuller 		 * itself)
83657193Smuller 	 	 */
83757193Smuller 		if ((mpos = cpos + sksz) > arsb.st_size) {
83857193Smuller 			*skipped = arsb.st_size - cpos;
83957193Smuller 			mpos = arsb.st_size;
84057193Smuller 		} else
84157193Smuller 			*skipped = sksz;
84257193Smuller 		if (lseek(arfd, mpos, SEEK_SET) >= 0)
84357193Smuller 			return(0);
84457193Smuller 	}
84557193Smuller 	syswarn(1, errno, "Foward positioning operation on archive failed");
84657193Smuller 	lstrval = -1;
84757193Smuller 	return(-1);
84857193Smuller }
84957193Smuller 
85057193Smuller /*
85157193Smuller  * ar_rev()
85257193Smuller  *	move the i/o position within the archive backwards the specified byte
85357193Smuller  *	count as supported by the device. With tapes drives we RESET rdblksz to
85457193Smuller  *	the PHYSICAL blocksize.
85557193Smuller  *	NOTE: We should only be called to move backwards so we can rewrite the
85657193Smuller  *	last records (the trailer) of an archive (APPEND).
85757193Smuller  * Return:
85857193Smuller  *	0 if moved the requested distance, -1 on complete failure
85957193Smuller  */
86057193Smuller 
86157193Smuller #if __STDC__
86257193Smuller int
86357193Smuller ar_rev(off_t sksz)
86457193Smuller #else
86557193Smuller int
86657193Smuller ar_rev(sksz)
86757193Smuller 	off_t sksz;
86857193Smuller #endif
86957193Smuller {
87057193Smuller 	off_t cpos;
87157193Smuller         struct mtop mb;
87257794Smuller 	register int phyblk;
87357193Smuller 
87457193Smuller 	/*
87557578Smuller 	 * make sure we do not have try to reverse on a flawed archive
87657193Smuller 	 */
87757193Smuller 	if (lstrval < 0)
87857193Smuller 		return(lstrval);
87957193Smuller 
88057193Smuller 	switch(artyp) {
88157193Smuller 	case ISPIPE:
88257578Smuller 		if (sksz <= 0)
88357578Smuller 			break;
88457193Smuller 		/*
88557193Smuller 		 * cannot go backwards on these critters
88657193Smuller 		 */
88757578Smuller 		warn(1, "Reverse positioning on pipes is not supported.");
88857578Smuller 		lstrval = -1;
88957578Smuller 		return(-1);
89057193Smuller 	case ISREG:
89157193Smuller 	case ISBLK:
89257193Smuller 	case ISCHR:
89357193Smuller 	default:
89457578Smuller 		if (sksz <= 0)
89557578Smuller 			break;
89657578Smuller 
89757193Smuller 		/*
89857193Smuller 		 * For things other than files, backwards movement has a very
89957193Smuller 		 * high probability of failure as we really do not know the
90057193Smuller 		 * true attributes of the device we are talking to (the device
90157193Smuller 		 * may not even have the ability to lseek() in any direction).
90257578Smuller 		 * First we figure out where we are in the archive.
90357193Smuller 		 */
90457578Smuller 		if ((cpos = lseek(arfd, (off_t)0L, SEEK_CUR)) < 0) {
90557578Smuller 			syswarn(1, errno,
90657578Smuller 			   "Unable to obtain current archive byte offset");
90757578Smuller 			lstrval = -1;
90857578Smuller 			return(-1);
90957578Smuller 		}
91057193Smuller 
91157193Smuller 		/*
91257193Smuller 		 * we may try to go backwards past the start when the archive
91357193Smuller 		 * is only a single record. If this hapens and we are on a
91457193Smuller 		 * multi volume archive, we need to go to the end of the
91557193Smuller 		 * previous volume and continue our movement backwards from
91657578Smuller 		 * there.
91757193Smuller 		 */
91857193Smuller 		if ((cpos -= sksz) < (off_t)0L) {
91957193Smuller 			if (arvol > 1) {
92057578Smuller 				/*
92157578Smuller 				 * this should never happen
92257578Smuller 				 */
92357578Smuller 				warn(1,"Reverse position on previous volume.");
92457193Smuller 				lstrval = -1;
92557193Smuller 				return(-1);
92657193Smuller 			}
92757193Smuller 			cpos = (off_t)0L;
92857193Smuller 		}
92957578Smuller 		if (lseek(arfd, cpos, SEEK_SET) < 0) {
93057578Smuller 			syswarn(1, errno, "Unable to seek archive backwards");
93157578Smuller 			lstrval = -1;
93257578Smuller 			return(-1);
93357578Smuller 		}
93457578Smuller 		break;
93557193Smuller 	case ISTAPE:
93657193Smuller 		/*
93757193Smuller 	 	 * Calculate and move the proper number of PHYSICAL tape
93857578Smuller 		 * blocks. If the sksz is not an even multiple of the physical
93957193Smuller 		 * tape size, we cannot do the move (this should never happen).
94057193Smuller 		 * (We also cannot handler trailers spread over two vols).
94157578Smuller 		 * get_phys() also makes sure we are in front of the filemark.
94257193Smuller 	 	 */
94357794Smuller 		if ((phyblk = get_phys()) <= 0) {
94457578Smuller 			lstrval = -1;
94557578Smuller 			return(-1);
94657193Smuller 		}
94757193Smuller 
94857578Smuller 		/*
94957578Smuller 		 * make sure future tape reads only go by physical tape block
95057578Smuller 		 * size (set rdblksz to the real size).
95157578Smuller 		 */
95257578Smuller 		rdblksz = phyblk;
95357578Smuller 
95457578Smuller 		/*
95557578Smuller 		 * if no movement is required, just return (we must be after
95657578Smuller 		 * get_phys() so the physical blocksize is properly set)
95757578Smuller 		 */
95857578Smuller 		if (sksz <= 0)
95957578Smuller 			break;
96057578Smuller 
96157578Smuller 		/*
96257578Smuller 		 * ok we have to move. Make sure the tape drive can do it.
96357578Smuller 		 */
96457193Smuller 		if (sksz % phyblk) {
96557578Smuller 			warn(1,
96657578Smuller 			    "Tape drive unable to backspace requested amount");
96757193Smuller 			lstrval = -1;
96857193Smuller 			return(-1);
96957193Smuller 		}
97057193Smuller 
97157578Smuller 		/*
97257578Smuller 		 * move backwards the requested number of bytes
97357578Smuller 		 */
97457193Smuller 		mb.mt_op = MTBSR;
97557193Smuller 		mb.mt_count = sksz/phyblk;
97657578Smuller 		if (ioctl(arfd, MTIOCTOP, &mb) < 0) {
97757578Smuller 			syswarn(1,errno, "Unable to backspace tape %d blocks.",
97857578Smuller 			    mb.mt_count);
97957578Smuller 			lstrval = -1;
98057578Smuller 			return(-1);
98157578Smuller 		}
98257578Smuller 		break;
98357193Smuller 	}
98457578Smuller 	lstrval = 1;
98557578Smuller 	return(0);
98657193Smuller }
98757193Smuller 
98857193Smuller /*
98957193Smuller  * get_phys()
99057578Smuller  *	Determine the physical block size on a tape drive. We need the physical
99157578Smuller  *	block size so we know how many bytes we skip over when we move with
99257578Smuller  *	mtio commands. We also make sure we are BEFORE THE TAPE FILEMARK when
99357578Smuller  *	return.
99457578Smuller  *	This is one really SLOW routine...
99557193Smuller  * Return:
99657794Smuller  *	physical block size if ok (ok > 0), -1 otherwise
99757193Smuller  */
99857193Smuller 
99957193Smuller #if __STDC__
100057193Smuller static int
100157193Smuller get_phys(void)
100257193Smuller #else
100357193Smuller static int
100457193Smuller get_phys()
100557193Smuller #endif
100657193Smuller {
100757578Smuller 	register int padsz = 0;
100857535Smuller 	register int res;
100957794Smuller 	register int phyblk;
101057535Smuller 	struct mtop mb;
101157578Smuller 	char scbuf[MAXBLK];
101257193Smuller 
101357193Smuller 	/*
101457578Smuller 	 * move to the file mark, and then back up one record and read it.
101557578Smuller 	 * this should tell us the physical record size the tape is using.
101657578Smuller 	 */
101757578Smuller 	if (lstrval == 1) {
101857578Smuller 		/*
101957578Smuller 		 * we know we are at file mark when we get back a 0 from
102057578Smuller 		 * read()
102157578Smuller 		 */
102257578Smuller 		while ((res = read(arfd, scbuf, sizeof(scbuf))) > 0)
102357578Smuller 			padsz += res;
102457578Smuller 		if (res < 0) {
102557578Smuller 			syswarn(1, errno, "Unable to locate tape filemark.");
102657578Smuller 			return(-1);
102757578Smuller 		}
102857578Smuller 	}
102957193Smuller 
103057578Smuller 	/*
103157578Smuller 	 * move backwards over the file mark so we are at the end of the
103257578Smuller 	 * last record.
103357578Smuller 	 */
103457578Smuller 	mb.mt_op = MTBSF;
103557193Smuller 	mb.mt_count = 1;
103657578Smuller 	if (ioctl(arfd, MTIOCTOP, &mb) < 0) {
103757578Smuller 		syswarn(1, errno, "Unable to backspace over tape filemark.");
103857193Smuller 		return(-1);
103957535Smuller 	}
104057193Smuller 
104157193Smuller 	/*
104257578Smuller 	 * move backwards so we are in front of the last record and read it to
104357578Smuller 	 * get physical tape blocksize.
104457193Smuller 	 */
104557578Smuller 	mb.mt_op = MTBSR;
104657578Smuller 	mb.mt_count = 1;
104757578Smuller 	if (ioctl(arfd, MTIOCTOP, &mb) < 0) {
104857578Smuller 		syswarn(1, errno, "Unable to backspace over last tape block.");
104957193Smuller 		return(-1);
105057578Smuller 	}
105157578Smuller 	if ((phyblk = read(arfd, scbuf, sizeof(scbuf))) <= 0) {
105257578Smuller 		syswarn(1, errno, "Cannot determine archive tape blocksize.");
105357578Smuller 		return(-1);
105457578Smuller 	}
105557535Smuller 
105657535Smuller 	/*
105757578Smuller 	 * read foward to the file mark, then back up in front of the filemark
105857578Smuller 	 * (this is a bit paranoid, but should be safe to do).
105957535Smuller 	 */
106057578Smuller 	while ((res = read(arfd, scbuf, sizeof(scbuf))) > 0)
106157578Smuller 		;
106257578Smuller 	if (res < 0) {
106357578Smuller 		syswarn(1, errno, "Unable to locate tape filemark.");
106457535Smuller 		return(-1);
106557578Smuller 	}
106657578Smuller 	mb.mt_op = MTBSF;
106757578Smuller 	mb.mt_count = 1;
106857578Smuller 	if (ioctl(arfd, MTIOCTOP, &mb) < 0) {
106957578Smuller 		syswarn(1, errno, "Unable to backspace over tape filemark.");
107057578Smuller 		return(-1);
107157578Smuller 	}
107257535Smuller 
107357535Smuller 	/*
107457578Smuller 	 * set lstrval so we know that the filemark has not been seen
107557535Smuller 	 */
107657578Smuller 	lstrval = 1;
107757578Smuller 
107857578Smuller 	/*
107957578Smuller 	 * return if there was no padding
108057578Smuller 	 */
108157578Smuller 	if (padsz == 0)
108257794Smuller 		return(phyblk);
108357535Smuller 
108457535Smuller 	/*
108557578Smuller 	 * make sure we can move backwards over the padding. (this should
108657578Smuller 	 * never fail).
108757535Smuller 	 */
108857578Smuller 	if (padsz % phyblk) {
108957578Smuller 		warn(1, "Tape drive unable to backspace requested amount");
109057535Smuller 		return(-1);
109157578Smuller 	}
109257535Smuller 
109357535Smuller 	/*
109457578Smuller 	 * move backwards over the padding so the head is where it was when
109557578Smuller 	 * we were first called (if required).
109657535Smuller 	 */
109757578Smuller 	mb.mt_op = MTBSR;
109857578Smuller 	mb.mt_count = padsz/phyblk;
109957578Smuller 	if (ioctl(arfd, MTIOCTOP, &mb) < 0) {
110057578Smuller 		syswarn(1,errno,"Unable to backspace tape over %d pad blocks",
110157578Smuller 		    mb.mt_count);
110257535Smuller 		return(-1);
110357578Smuller 	}
110457794Smuller 	return(phyblk);
110557193Smuller }
110657193Smuller 
110757193Smuller /*
110857193Smuller  * ar_next()
110957535Smuller  *	prompts the user for the next volume in this archive. For some devices
111057535Smuller  *	we may allow the media to be changed. Otherwise a new archive is
111157535Smuller  *	prompted for. By pax spec, if there is no controlling tty or an eof is
111257535Smuller  *	read on tty input, we must quit pax.
111357193Smuller  * Return:
111457193Smuller  *	0 when ready to continue, -1 when all done
111557193Smuller  */
111657193Smuller 
111757193Smuller #if __STDC__
111857193Smuller int
111957193Smuller ar_next(void)
112057193Smuller #else
112157193Smuller int
112257193Smuller ar_next()
112357193Smuller #endif
112457193Smuller {
112557193Smuller 	char buf[PAXPATHLEN+2];
112657193Smuller 	static int freeit = 0;
112757193Smuller 	sigset_t o_mask;
112857193Smuller 
112957193Smuller 	/*
113057535Smuller 	 * WE MUST CLOSE THE DEVICE. A lot of devices must see last close, (so
113157193Smuller 	 * things like writing EOF etc will be done) (Watch out ar_close() can
113257535Smuller 	 * also be called via a signal handler, so we must prevent a race.
113357193Smuller 	 */
113457193Smuller 	if (sigprocmask(SIG_BLOCK, &s_mask, &o_mask) < 0)
113557535Smuller 		syswarn(0, errno, "Unable to set signal mask");
113657193Smuller 	ar_close();
113757193Smuller 	if (sigprocmask(SIG_SETMASK, &o_mask, (sigset_t *)NULL) < 0)
113857535Smuller 		syswarn(0, errno, "Unable to restore signal mask");
113957193Smuller 
114057578Smuller 	if (done || !wr_trail)
114157193Smuller 		return(-1);
114257193Smuller 
114357193Smuller 	tty_prnt("\nATTENTION! Pax archive volume change required.\n");
114457193Smuller 
114557193Smuller 	/*
114657193Smuller 	 * if i/o is on stdin or stdout, we cannot reopen it (we do not know
114757535Smuller 	 * the name), the user will be forced to type it in.
114857193Smuller 	 */
114957193Smuller 	if (strcmp(arcname, STDO) && strcmp(arcname, STDN) && (artyp != ISREG)
115057193Smuller 	    && (artyp != ISPIPE)) {
115157193Smuller 		if (artyp == ISTAPE) {
115257193Smuller 			tty_prnt("%s ready for archive tape volume: %d\n",
115357193Smuller 				arcname, arvol);
115457193Smuller 			tty_prnt("Load the NEXT TAPE on the tape drive");
115557193Smuller 		} else {
115657193Smuller 			tty_prnt("%s ready for archive volume: %d\n",
115757193Smuller 				arcname, arvol);
115857193Smuller 			tty_prnt("Load the NEXT STORAGE MEDIA (if required)");
115957193Smuller 		}
116057193Smuller 
116157193Smuller 		if ((act == ARCHIVE) || (act == APPND))
116257193Smuller 			tty_prnt(" and make sure it is WRITE ENABLED.\n");
116357193Smuller 		else
116457193Smuller 			tty_prnt("\n");
116557193Smuller 
116657193Smuller 		for(;;) {
116757193Smuller 			tty_prnt("Type \"y\" to continue, \".\" to quit pax,");
116857193Smuller 			tty_prnt(" or \"s\" to switch to new device.\nIf you");
116957193Smuller 			tty_prnt(" cannot change storage media, type \"s\"\n");
117057193Smuller 			tty_prnt("Is the device ready and online? > ");
117157193Smuller 
117257193Smuller 			if ((tty_read(buf,sizeof(buf))<0) || !strcmp(buf,".")){
117357193Smuller 				done = 1;
117457193Smuller 				lstrval = -1;
117557193Smuller 				tty_prnt("Quitting pax!\n");
117657193Smuller 				vfpart = 0;
117757193Smuller 				return(-1);
117857193Smuller 			}
117957193Smuller 
118057193Smuller 			if ((buf[0] == '\0') || (buf[1] != '\0')) {
118157193Smuller 				tty_prnt("%s unknown command, try again\n",buf);
118257193Smuller 				continue;
118357193Smuller 			}
118457193Smuller 
118557193Smuller 			switch (buf[0]) {
118657193Smuller 			case 'y':
118757193Smuller 			case 'Y':
118857193Smuller 				/*
118957193Smuller 				 * we are to continue with the same device
119057193Smuller 				 */
119157193Smuller 				if (ar_open(arcname) >= 0)
119257193Smuller 					return(0);
119357193Smuller 				tty_prnt("Cannot re-open %s, try again\n",
119457193Smuller 					arcname);
119557193Smuller 				continue;
119657193Smuller 			case 's':
119757193Smuller 			case 'S':
119857193Smuller 				/*
119957193Smuller 				 * user wants to open a different device
120057193Smuller 				 */
120157193Smuller 				tty_prnt("Switching to a different archive\n");
120257193Smuller 				break;
120357193Smuller 			default:
120457193Smuller 				tty_prnt("%s unknown command, try again\n",buf);
120557193Smuller 				continue;
120657193Smuller 			}
120757193Smuller 			break;
120857193Smuller 		}
120957193Smuller 	} else
121057193Smuller 		tty_prnt("Ready for archive volume: %d\n", arvol);
121157193Smuller 
121257193Smuller 	/*
121357193Smuller 	 * have to go to a different archive
121457193Smuller 	 */
121557193Smuller 	for (;;) {
121657193Smuller 		tty_prnt("Input archive name or \".\" to quit pax.\n");
121757193Smuller 		tty_prnt("Archive name > ");
121857193Smuller 
121957193Smuller 		if ((tty_read(buf, sizeof(buf)) < 0) || !strcmp(buf, ".")) {
122057193Smuller 			done = 1;
122157193Smuller 			lstrval = -1;
122257193Smuller 			tty_prnt("Quitting pax!\n");
122357193Smuller 			vfpart = 0;
122457193Smuller 			return(-1);
122557193Smuller 		}
122657193Smuller 		if (buf[0] == '\0') {
122757193Smuller 			tty_prnt("Empty file name, try again\n");
122857193Smuller 			continue;
122957193Smuller 		}
123057193Smuller                 if (!strcmp(buf, "..")) {
123157193Smuller                         tty_prnt("Illegal file name: .. try again\n");
123257193Smuller                         continue;
123357193Smuller                 }
123457193Smuller 		if (strlen(buf) > PAXPATHLEN) {
123557193Smuller 			tty_prnt("File name too long, try again\n");
123657193Smuller 			continue;
123757193Smuller 		}
123857193Smuller 
123957193Smuller 		/*
124057193Smuller 		 * try to open new archive
124157193Smuller 		 */
124257193Smuller 		if (ar_open(buf) >= 0) {
124357193Smuller 			if (freeit) {
124457193Smuller 				(void)free(arcname);
124557193Smuller 				freeit = 0;
124657193Smuller 			}
124757193Smuller 			if ((arcname = strdup(buf)) == NULL) {
124857193Smuller 				done = 1;
124957193Smuller 				lstrval = -1;
125057535Smuller 				warn(0, "Cannot save archive name.");
125157193Smuller 				return(-1);
125257193Smuller 			}
125357193Smuller 			freeit = 1;
125457193Smuller 			break;
125557193Smuller 		}
125657193Smuller 		tty_prnt("Cannot open %s, try again\n", buf);
125757193Smuller 		continue;
125857193Smuller 	}
125957193Smuller 	return(0);
126057193Smuller }
1261