xref: /csrg-svn/bin/pax/ar_io.c (revision 57535)
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*57535Smuller static char sccsid[] = "@(#)ar_io.c	1.2 (Berkeley) 01/14/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 /*
34*57535Smuller  * 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 */
4457193Smuller static int artyp;			/* 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 */
48*57535Smuller 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 */
5257193Smuller static int phyblk; 			/* size of physical block on TAPE */
5357193Smuller char *arcname;                  	/* printable name of archive */
5457193Smuller 
5557193Smuller static int get_phys __P((void));
5657193Smuller extern sigset_t s_mask;
5757193Smuller 
5857193Smuller /*
5957193Smuller  * ar_open()
6057193Smuller  *	Opens the next archive volume. Determines the type of the device and
6157193Smuller  *	sets up block sizes as required by the archive device and the format.
6257193Smuller  *	Note: we may be called with name == NULL on the first open only.
6357193Smuller  * Return:
6457193Smuller  *	-1 on failure, 0 otherwise
6557193Smuller  */
6657193Smuller 
6757193Smuller #if __STDC__
6857193Smuller int
6957193Smuller ar_open(char *name)
7057193Smuller #else
7157193Smuller int
7257193Smuller ar_open(name)
7357193Smuller 	char *name;
7457193Smuller #endif
7557193Smuller {
7657193Smuller         struct mtget mb;
7757193Smuller 
7857193Smuller 	if (arfd != -1)
7957193Smuller 		(void)close(arfd);
8057193Smuller 	arfd = -1;
8157193Smuller 	phyblk = did_io = io_ok = invld_rec = 0;
8257193Smuller 	flcnt = 0;
8357193Smuller 
8457193Smuller 	/*
8557193Smuller 	 * open based on overall operation mode
8657193Smuller 	 */
8757193Smuller 	switch (act) {
8857193Smuller 	case LIST:
8957193Smuller 	case EXTRACT:
9057193Smuller 		if (name == NULL) {
9157193Smuller 			arfd = STDIN_FILENO;
9257193Smuller 			arcname = STDN;
9357193Smuller 		} else if ((arfd = open(name, EXT_MODE, DMOD)) < 0)
94*57535Smuller 			syswarn(0, errno, "Failed open to read on %s", name);
9557193Smuller 		break;
9657193Smuller 	case ARCHIVE:
9757193Smuller 		if (name == NULL) {
9857193Smuller 			arfd = STDOUT_FILENO;
9957193Smuller 			arcname = STDO;
10057193Smuller 		} else if ((arfd = open(name, AR_MODE, DMOD)) < 0)
101*57535Smuller 			syswarn(0, errno, "Failed open to write on %s", name);
10257193Smuller 		break;
10357193Smuller 	case APPND:
10457193Smuller 		if (name == NULL) {
10557193Smuller 			arfd = STDOUT_FILENO;
10657193Smuller 			arcname = STDO;
10757193Smuller 		} else if ((arfd = open(name, APP_MODE, DMOD)) < 0)
108*57535Smuller 			syswarn(0, errno, "Failed open to read/write on %s",
10957193Smuller 				name);
11057193Smuller 		break;
11157193Smuller 	case COPY:
11257193Smuller 		/*
11357193Smuller 		 * arfd not used in COPY mode
11457193Smuller 		 */
11557193Smuller 		arcname = "<NONE>";
11657193Smuller 		lstrval = 1;
11757193Smuller 		return(0);
11857193Smuller 	}
11957193Smuller 	if (arfd < 0)
12057193Smuller 		return(-1);
12157193Smuller 
12257193Smuller 	/*
12357193Smuller 	 * set up is based on device type
12457193Smuller 	 */
12557193Smuller 	if (fstat(arfd, &arsb) < 0) {
126*57535Smuller 		syswarn(0, errno, "Failed stat on %s", arcname);
12757193Smuller 		return(-1);
12857193Smuller 	}
12957193Smuller 	if (S_ISDIR(arsb.st_mode)) {
130*57535Smuller 		warn(0, "Cannot write an archive on top of a directory %s",
13157193Smuller 		    arcname);
13257193Smuller 		return(-1);
13357193Smuller 	}
13457193Smuller 	if (S_ISCHR(arsb.st_mode))
13557193Smuller 		artyp = ioctl(arfd, MTIOCGET, &mb) ? ISCHR : ISTAPE;
13657193Smuller 	else if (S_ISBLK(arsb.st_mode))
13757193Smuller 		artyp = ISBLK;
13857193Smuller 	else if ((lseek(arfd, (off_t)0L, SEEK_CUR) == -1) && (errno == ESPIPE))
13957193Smuller 		artyp = ISPIPE;
14057193Smuller 	else
14157193Smuller 		artyp = ISREG;
14257193Smuller 
14357193Smuller 	/*
144*57535Smuller 	 * if we are writing, we are done
14557193Smuller 	 */
14657193Smuller 	if (act == ARCHIVE) {
14757193Smuller 		blksz = rdblksz = wrblksz;
14857193Smuller 		lstrval = 1;
14957193Smuller 		return(0);
15057193Smuller 	}
15157193Smuller 
15257193Smuller 	/*
15357193Smuller 	 * set default blksz on read. APPNDs writes rdblksz on the last volume
15457193Smuller 	 * On all new archive volumes, we shift to wrblksz (if the user
15557193Smuller 	 * specified one, otherwize we will continue to use rdblksz). We
15657193Smuller 	 * must to set blocksize based on what kind of device the archive is
15757193Smuller 	 * stored.
15857193Smuller 	 */
15957193Smuller 	switch(artyp) {
16057193Smuller 	case ISTAPE:
16157193Smuller 		/*
16257193Smuller 		 * Tape drives come in at least two flavors. Those that support
16357193Smuller 		 * variable sized records and those that have fixed sized
16457193Smuller 		 * records. They must be treated differently. For tape drives
16557193Smuller 		 * that support variable sized records, we must make large
16657193Smuller 		 * reads to make sure we get the entire record, otherwise we
16757193Smuller 		 * will just get the first part of the record (up to size we
16857193Smuller 		 * asked). Tapes with fixed sized records may or may not return
16957193Smuller 		 * multiple records in a single read. We really do not care
17057193Smuller 		 * what the physical record size is UNLESS we are going to
17157193Smuller 		 * append. (We will need the physical block size to rewrite
17257193Smuller 		 * the trailer). Only when we are appending do we go to the
173*57535Smuller 		 * effort to figure out the true PHYSICAL record size.
17457193Smuller 		 */
17557193Smuller 		blksz = rdblksz = MAXBLK;
17657193Smuller 		break;
17757193Smuller 	case ISPIPE:
17857193Smuller 	case ISBLK:
17957193Smuller 	case ISCHR:
18057193Smuller 		/*
18157193Smuller 		 * Blocksize is not a major issue with these devices (but must
18257193Smuller 		 * be kept a multiple of 512). If the user specified a write
18357193Smuller 		 * block size, we use that to read. Under append, we must
18457193Smuller 		 * always keep blksz == rdblksz. Otherwise we go ahead and use
18557193Smuller 		 * the device optimal blocksize as (and if) returned by stat
18657193Smuller 		 * and if it is within pax specs.
18757193Smuller 		 */
18857193Smuller 		if ((act == APPND) && wrblksz) {
18957193Smuller 			blksz = rdblksz = wrblksz;
19057193Smuller 			break;
19157193Smuller 		}
19257193Smuller 
19357193Smuller 		if ((arsb.st_blksize > 0) && (arsb.st_blksize < MAXBLK) &&
19457193Smuller 		    ((arsb.st_blksize % BLKMULT) == 0))
19557193Smuller 			rdblksz = arsb.st_blksize;
19657193Smuller 		else
19757193Smuller 			rdblksz = DEVBLK;
19857193Smuller 		/*
19957193Smuller 		 * For performance go for large reads when we can without harm
20057193Smuller 		 */
20157193Smuller 		if ((act == APPND) || (artyp == ISCHR))
20257193Smuller 			blksz = rdblksz;
20357193Smuller 		else
20457193Smuller 			blksz = MAXBLK;
20557193Smuller 		break;
20657193Smuller 	case ISREG:
20757193Smuller 		/*
20857193Smuller 		 * if the user specified wrblksz works, use it. Under appends
20957193Smuller 		 * we must always keep blksz == rdblksz
21057193Smuller 		 */
21157193Smuller 		if ((act == APPND) && wrblksz && ((arsb.st_size%wrblksz)==0)){
21257193Smuller 			blksz = rdblksz = wrblksz;
21357193Smuller 			break;
21457193Smuller 		}
21557193Smuller 		/*
21657193Smuller 		 * See if we can find the blocking factor from the file size
21757193Smuller 		 */
21857193Smuller 		for (rdblksz = MAXBLK; rdblksz > 0; rdblksz -= BLKMULT)
21957193Smuller 			if ((arsb.st_size % rdblksz) == 0)
22057193Smuller 				break;
22157193Smuller 		/*
22257193Smuller 		 * When we cannont find a match, we may have a flawed archive.
22357193Smuller 		 */
22457193Smuller 		if (rdblksz <= 0)
22557193Smuller 			rdblksz = FILEBLK;
22657193Smuller 		/*
22757193Smuller 		 * for performance go for large reads when we can
22857193Smuller 		 */
22957193Smuller 		if (act == APPND)
23057193Smuller 			blksz = rdblksz;
23157193Smuller 		else
23257193Smuller 			blksz = MAXBLK;
23357193Smuller 		break;
23457193Smuller 	default:
23557193Smuller 		/*
23657193Smuller 		 * should never happen, worse case, slow...
23757193Smuller 		 */
23857193Smuller 		blksz = rdblksz = BLKMULT;
23957193Smuller 		break;
24057193Smuller 	}
24157193Smuller 	lstrval = 1;
24257193Smuller 	return(0);
24357193Smuller }
24457193Smuller 
24557193Smuller /*
24657193Smuller  * ar_close()
24757193Smuller  *	closes archive device, increments volume number, and prints i/o summary
24857193Smuller  */
24957193Smuller #if __STDC__
25057193Smuller void
25157193Smuller ar_close(void)
25257193Smuller #else
25357193Smuller void
25457193Smuller ar_close()
25557193Smuller #endif
25657193Smuller {
25757193Smuller 	FILE *outf;
25857193Smuller 
259*57535Smuller 	if (act == LIST)
260*57535Smuller 		outf = stdout;
261*57535Smuller 	else
262*57535Smuller 		outf = stderr;
263*57535Smuller 
264*57535Smuller 	/*
265*57535Smuller 	 * Close archive file. This may take a LONG while on tapes (we may be
266*57535Smuller 	 * forced to wait for the rewind to complete) so tell the user what is
267*57535Smuller 	 * going on (this avoids the user hitting control-c thinking pax is
268*57535Smuller 	 * broken).
269*57535Smuller 	 */
270*57535Smuller 	if (vflag && (arfd >= 0) && (artyp == ISTAPE)) {
271*57535Smuller 		if (vfpart) {
272*57535Smuller 			(void)putc('\n', outf);
273*57535Smuller 			vfpart = 0;
274*57535Smuller 		}
275*57535Smuller 		(void)fputs("pax: Waiting for tape drive close to complete...",
276*57535Smuller 		    outf);
277*57535Smuller 		(void)fflush(outf);
278*57535Smuller 	}
279*57535Smuller 
28057193Smuller 	(void)close(arfd);
281*57535Smuller 
282*57535Smuller 	if (vflag && (arfd >= 0) && (artyp == ISTAPE)) {
283*57535Smuller 		(void)fputs("done.\n", outf);
284*57535Smuller 		(void)fflush(outf);
285*57535Smuller 	}
28657193Smuller 	arfd = -1;
287*57535Smuller 
28857193Smuller 	if (!io_ok && !did_io) {
28957193Smuller 		flcnt = 0;
29057193Smuller 		return;
29157193Smuller 	}
29257193Smuller 	did_io = io_ok = 0;
29357193Smuller 
29457193Smuller 	/*
29557193Smuller 	 * The volume number is only increased when the last device has data
296*57535Smuller 	 * and we have already determined the archive format.
29757193Smuller 	 */
298*57535Smuller 	if (frmt != NULL)
299*57535Smuller 		++arvol;
300*57535Smuller 
30157193Smuller 	if (!vflag) {
30257193Smuller 		flcnt = 0;
30357193Smuller 		return;
30457193Smuller 	}
30557193Smuller 
30657193Smuller 	/*
30757193Smuller 	 * Print out a summary of I/O for this archive volume.
30857193Smuller 	 */
30957193Smuller 	if (vfpart) {
31057193Smuller 		(void)putc('\n', outf);
31157193Smuller 		vfpart = 0;
31257193Smuller 	}
31357193Smuller 
314*57535Smuller 	/*
315*57535Smuller 	 * If we have not determined the format yet, we just say how many bytes
316*57535Smuller 	 * we have skipped over looking for a header to id. there is no way we
317*57535Smuller 	 * could have written anything yet.
318*57535Smuller 	 */
319*57535Smuller 	if (frmt == NULL) {
320*57535Smuller #	ifdef NET2_STAT
321*57535Smuller 		(void)fprintf(outf, "pax: unknown format, %lu bytes skipped.\n",
322*57535Smuller #	else
323*57535Smuller 		(void)fprintf(outf, "pax: unknown format, %qu bytes skipped.\n",
324*57535Smuller #	endif
325*57535Smuller 		    rdcnt);
326*57535Smuller 		(void)fflush(outf);
327*57535Smuller 		flcnt = 0;
328*57535Smuller 		return;
329*57535Smuller 	}
330*57535Smuller 
33157193Smuller 	(void)fprintf(outf,
33257193Smuller #	ifdef NET2_STAT
333*57535Smuller 	    "pax: %s vol %d, %lu files, %lu bytes read, %lu bytes written.\n",
33457193Smuller #	else
335*57535Smuller 	    "pax: %s vol %d, %lu files, %qu bytes read, %qu bytes written.\n",
33657193Smuller #	endif
33757193Smuller 	    frmt->name, arvol-1, flcnt, rdcnt, wrcnt);
33857193Smuller 	(void)fflush(outf);
33957193Smuller 	flcnt = 0;
34057193Smuller }
34157193Smuller 
34257193Smuller /*
34357193Smuller  * ar_set_wr()
34457193Smuller  *	special device dependent handling to switch from archive read to
34557193Smuller  *	archive write on a single volume (an append). VERY device dependent.
34657193Smuller  *	Note: for tapes, head is already positioned at the place we want to
34757193Smuller  *	start writing.
34857193Smuller  * Return:
34957193Smuller  *	0 if all ready to write, -1 otherwise
35057193Smuller  */
35157193Smuller 
35257193Smuller #if __STDC__
35357193Smuller int
35457193Smuller ar_set_wr(void)
35557193Smuller #else
35657193Smuller int
35757193Smuller ar_set_wr()
35857193Smuller #endif
35957193Smuller {
36057193Smuller 	off_t cpos;
36157193Smuller 
36257193Smuller 	/*
36357193Smuller 	 * Add any device dependent code as required here
36457193Smuller 	 */
36557193Smuller 	if (artyp != ISREG)
36657193Smuller 		return(0);
36757193Smuller 	/*
368*57535Smuller 	 * Ok we have an archive in a regular file. If we were rewriting a
369*57535Smuller 	 * file, we must get rid of all the stuff after the current offset
370*57535Smuller 	 * (it was not written by pax).
37157193Smuller 	 */
37257193Smuller 	if (((cpos = lseek(arfd, (off_t)0L, SEEK_CUR)) < 0) ||
37357193Smuller 	    (ftruncate(arfd, cpos) < 0))
37457193Smuller 		return(-1);
37557193Smuller 	return(0);
37657193Smuller }
37757193Smuller 
37857193Smuller /*
37957193Smuller  * ar_app_ok()
38057193Smuller  *	check if the last volume in the archive allows appends. We cannot check
38157193Smuller  *	this until we are ready to write since there is no spec that says all
38257193Smuller  *	volumes in a single archive have to be of the same type...
38357193Smuller  * Return:
38457193Smuller  *	0 if we can append, -1 otherwise.
38557193Smuller  */
38657193Smuller 
38757193Smuller #if __STDC__
38857193Smuller int
38957193Smuller ar_app_ok(void)
39057193Smuller #else
39157193Smuller int
39257193Smuller ar_app_ok()
39357193Smuller #endif
39457193Smuller {
39557193Smuller 	if (artyp == ISPIPE) {
39657193Smuller 		warn(1, "Cannot append to an archive obtained from a pipe.");
39757193Smuller 		return(-1);
39857193Smuller 	}
39957193Smuller 
40057193Smuller 	if (!invld_rec)
40157193Smuller 		return(0);
40257193Smuller 	warn(1,"Cannot append, device record size %d does not support pax spec",
40357193Smuller 		rdblksz);
40457193Smuller 	return(-1);
40557193Smuller }
40657193Smuller 
40757193Smuller /*
40857193Smuller  * ar_read()
40957193Smuller  *	read up to a specified number of bytes from the archive into the
41057193Smuller  *	supplied buffer. When dealing with tapes we may not always be able to
41157193Smuller  *	read what we want.
41257193Smuller  * Return:
41357193Smuller  *	Number of bytes in buffer. 0 for end of file, -1 for a read error.
41457193Smuller  */
41557193Smuller 
41657193Smuller #if __STDC__
41757193Smuller int
41857193Smuller ar_read(register char *buf, register int cnt)
41957193Smuller #else
42057193Smuller int
42157193Smuller ar_read(buf, cnt)
42257193Smuller 	register char *buf;
42357193Smuller 	register int cnt;
42457193Smuller #endif
42557193Smuller {
42657193Smuller 	register int res = 0;
42757193Smuller 
42857193Smuller 	/*
42957193Smuller 	 * if last i/o was in error, no more reads until reset or new volume
43057193Smuller 	 */
43157193Smuller 	if (lstrval <= 0)
43257193Smuller 		return(lstrval);
43357193Smuller 
43457193Smuller 	/*
43557193Smuller 	 * how we read must be based on device type
43657193Smuller 	 */
43757193Smuller 	switch (artyp) {
43857193Smuller 	case ISTAPE:
43957193Smuller 		if ((res = read(arfd, buf, cnt)) > 0) {
44057193Smuller 			/*
44157193Smuller 			 * CAUTION: tape systems may not always return the same
44257193Smuller 			 * sized records so we leave blksz == MAXBLK. The
44357193Smuller 			 * physical record size that a tape drive supports is
44457193Smuller 			 * very hard to determine in a uniform and portable
44557193Smuller 			 * manner.
44657193Smuller 			 */
44757193Smuller 			io_ok = 1;
44857193Smuller 			if (res != rdblksz) {
44957193Smuller 				/*
45057193Smuller 				 * Record size changed. If this is happens on
451*57535Smuller 				 * any record after the first, we probably have
452*57535Smuller 				 * a tape drive which has a fixed record size
453*57535Smuller 				 * we are getting multiple records in a single
454*57535Smuller 				 * read). Watch out for record blocking that
455*57535Smuller 				 * violates pax spec (must be a multiple of
456*57535Smuller 				 * BLKMULT).
45757193Smuller 				 */
45857193Smuller 				rdblksz = res;
45957193Smuller 				if (rdblksz % BLKMULT)
46057193Smuller 					invld_rec = 1;
46157193Smuller 			}
46257193Smuller 			return(res);
46357193Smuller 		}
46457193Smuller 		break;
46557193Smuller 	case ISREG:
46657193Smuller 	case ISBLK:
46757193Smuller 	case ISCHR:
46857193Smuller 	case ISPIPE:
46957193Smuller 	default:
47057193Smuller 		/*
47157193Smuller 		 * Files are so easy to deal with. These other things cannot
47257193Smuller 		 * be trusted at all. So when we are dealing with character
47357193Smuller 		 * devices and pipes we just take what they have ready for us
47457193Smuller 		 * and return. Trying to do anything else with them runs the
47557193Smuller 		 * risk of failure.
47657193Smuller 		 */
47757193Smuller 		if ((res = read(arfd, buf, cnt)) > 0) {
47857193Smuller 			io_ok = 1;
47957193Smuller 			return(res);
48057193Smuller 		}
48157193Smuller 		break;
48257193Smuller 	}
48357193Smuller 
48457193Smuller 	/*
48557193Smuller 	 * We are in trouble at this point, something is broken...
48657193Smuller 	 */
48757193Smuller 	lstrval = res;
48857193Smuller 	if (res < 0)
48957193Smuller 		syswarn(1, errno, "Failed read on archive volume %d", arvol);
49057193Smuller 	else
49157193Smuller 		warn(0, "End of archive volume %d reached", arvol);
49257193Smuller 	return(res);
49357193Smuller }
49457193Smuller 
49557193Smuller /*
49657193Smuller  * ar_write()
49757193Smuller  *	Write a specified number of bytes in supplied buffer to the archive
49857193Smuller  *	device so it appears as a single "block". Deals with errors and tries
49957193Smuller  *	to recover when faced with short writes.
50057193Smuller  * Return:
50157193Smuller  *	Number of bytes written. 0 indicates end of volume reached and with no
50257193Smuller  *	flaws (as best that can be detected). A -1 indicates an unrecoverable
50357193Smuller  *	error in the archive occured.
50457193Smuller  */
50557193Smuller 
50657193Smuller #if __STDC__
50757193Smuller int
50857193Smuller ar_write(register char *buf, register int bsz)
50957193Smuller #else
51057193Smuller int
51157193Smuller ar_write(buf, bsz)
51257193Smuller 	register char *buf;
51357193Smuller 	register int bsz;
51457193Smuller #endif
51557193Smuller {
51657193Smuller 	register int res;
51757193Smuller 	off_t cpos;
51857193Smuller 
51957193Smuller 	/*
52057193Smuller 	 * do not allow pax to create a "bad" archive. Once a write fails on
52157193Smuller 	 * an archive volume prevent further writes to it.
52257193Smuller 	 */
52357193Smuller 	if (lstrval <= 0)
52457193Smuller 		return(lstrval);
52557193Smuller 
52657193Smuller 	if ((res = write(arfd, buf, bsz)) == bsz) {
52757193Smuller 		io_ok = 1;
52857193Smuller 		return(bsz);
52957193Smuller 	}
53057193Smuller 
53157193Smuller 	/*
53257193Smuller 	 * write broke, see what we can do with it. We try to send any partial
533*57535Smuller 	 * writes that may violate pax spec to the next archive volume.
53457193Smuller 	 */
53557193Smuller 	if (res < 0)
53657193Smuller 		lstrval = res;
53757193Smuller 	else
53857193Smuller 		lstrval = 0;
53957193Smuller 
54057193Smuller 	switch (artyp) {
54157193Smuller 	case ISREG:
54257193Smuller 		if ((res > 0) && (res % BLKMULT)) {
54357193Smuller 			/*
54457193Smuller 		 	 * try to fix up partial writes which are not BLKMULT
54557193Smuller 			 * in size by forcing the runt record to next archive
54657193Smuller 			 * volume
54757193Smuller 		 	 */
54857193Smuller 			if ((cpos = lseek(arfd, (off_t)0L, SEEK_CUR)) < 0)
54957193Smuller 				break;
55057193Smuller 			cpos -= (off_t)res;
55157193Smuller 			if (ftruncate(arfd, cpos) < 0)
55257193Smuller 				break;
55357193Smuller 			res = lstrval = 0;
55457193Smuller 			break;
55557193Smuller 		}
55657193Smuller 		if (res >= 0)
55757193Smuller 			break;
55857193Smuller 		/*
55957193Smuller 		 * if file is out of space, handle it like a return of 0
56057193Smuller 		 */
56157193Smuller 		if ((errno == ENOSPC) || (errno == EFBIG) || (errno == EDQUOT))
56257193Smuller 			res = lstrval = 0;
56357193Smuller 		break;
56457193Smuller 	case ISTAPE:
56557193Smuller 	case ISCHR:
56657193Smuller 	case ISBLK:
56757193Smuller 		if (res >= 0)
56857193Smuller 			break;
56957193Smuller 		if (errno == EACCES) {
57057193Smuller 			warn(0, "Write failed, archive is write protected.");
57157193Smuller 			res = lstrval = 0;
57257193Smuller 			return(0);
57357193Smuller 		}
57457193Smuller 		/*
57557193Smuller 		 * see if we reached the end of media, if so force a change to
57657193Smuller 		 * the next volume
57757193Smuller 		 */
57857193Smuller 		if ((errno == ENOSPC) || (errno == EIO) || (errno == ENXIO))
57957193Smuller 			res = lstrval = 0;
58057193Smuller 		break;
58157193Smuller 	case ISPIPE:
58257193Smuller 	default:
58357193Smuller 		/*
58457193Smuller 		 * we cannot fix errors to these devices
58557193Smuller 		 */
58657193Smuller 		break;
58757193Smuller 	}
58857193Smuller 
58957193Smuller 	/*
59057193Smuller 	 * Better tell the user the bad news...
591*57535Smuller 	 * if this is a block aligned archive format, we may have a bad archive
592*57535Smuller 	 * if the format wants the header to start at a BLKMULT boundry. While
59357193Smuller 	 * we can deal with the mis-aligned data, it violates spec and other
59457193Smuller 	 * archive readers will likely fail. if the format is not block
595*57535Smuller 	 * aligned, the user may be lucky (and the archive is ok).
59657193Smuller 	 */
59757193Smuller 	if (res >= 0)
59857193Smuller 		io_ok = 1;
59957193Smuller 	if (res == 0)
60057193Smuller 		warn(0, "End of archive volume %d reached", arvol);
60157193Smuller 	else if (res < 0)
60257193Smuller 		syswarn(1, errno, "Failed write to archive volume: %d", arvol);
60357193Smuller 	else if (!frmt->blkalgn || ((res % frmt->blkalgn) == 0))
60457193Smuller 		warn(0,"WARNING: partial archive write. Archive MAY BE FLAWED");
60557193Smuller 	else
60657193Smuller 		warn(1,"WARNING: partial archive write. Archive IS FLAWED");
60757193Smuller 	return(res);
60857193Smuller }
60957193Smuller 
61057193Smuller /*
61157193Smuller  * ar_rdsync()
61257193Smuller  *	Try to move past a bad spot on a flawed archive as needed to continue
61357193Smuller  *	I/O. Clears error flags to allow I/O to continue.
61457193Smuller  * Return:
61557193Smuller  *	0 when ok to try i/o again, -1 otherwise.
61657193Smuller  */
61757193Smuller 
61857193Smuller #if __STDC__
61957193Smuller int
62057193Smuller ar_rdsync(void)
62157193Smuller #else
62257193Smuller int
62357193Smuller ar_rdsync()
62457193Smuller #endif
62557193Smuller {
62657193Smuller 	long fsbz;
62757193Smuller 	off_t cpos;
62857193Smuller 	off_t mpos;
62957193Smuller         struct mtop mb;
63057193Smuller 
63157193Smuller 	/*
63257193Smuller 	 * Fail resync attempts at user request (done) or this is going to be
63357193Smuller 	 * an update/append to a existing archive. if last i/o hit media end,
63457193Smuller 	 * we need to go to the next volume not try a resync
63557193Smuller 	 */
63657193Smuller 	if ((done > 0) || (lstrval == 0))
63757193Smuller 		return(-1);
63857193Smuller 
63957193Smuller 	if ((act == APPND) || (act == ARCHIVE)) {
64057193Smuller 		warn(1, "Cannot allow updates to an archive with flaws.");
64157193Smuller 		return(-1);
64257193Smuller 	}
64357193Smuller 	if (io_ok)
64457193Smuller 		did_io = 1;
64557193Smuller 
64657193Smuller 	switch(artyp) {
64757193Smuller 	case ISTAPE:
64857193Smuller 		/*
64957193Smuller 		 * if the last i/o was a successful data transfer, we assume
65057193Smuller 		 * the fault is just a bad record on the tape that we are now
65157193Smuller 		 * past. If we did not get any data since the last resync try
65257193Smuller 		 * to move the tape foward one PHYSICAL record past any
65357193Smuller 		 * damaged tape section. Some tape drives are stubborn and need
65457193Smuller 		 * to be pushed.
65557193Smuller 		 */
65657193Smuller 		if (io_ok) {
65757193Smuller 			io_ok = 0;
65857193Smuller 			lstrval = 1;
65957193Smuller 			break;
66057193Smuller 		}
66157193Smuller 		mb.mt_op = MTFSR;
66257193Smuller 		mb.mt_count = 1;
66357193Smuller 		if (ioctl(arfd, MTIOCTOP, &mb) < 0)
66457193Smuller 			break;
66557193Smuller 		lstrval = 1;
66657193Smuller 		break;
66757193Smuller 	case ISREG:
66857193Smuller 	case ISCHR:
66957193Smuller 	case ISBLK:
67057193Smuller 		/*
67157193Smuller 		 * try to step over the bad part of the device.
67257193Smuller 		 */
67357193Smuller 		io_ok = 0;
67457193Smuller 		if (((fsbz = arsb.st_blksize) <= 0) || (artyp != ISREG))
67557193Smuller 			fsbz = BLKMULT;
67657193Smuller 		if ((cpos = lseek(arfd, (off_t)0L, SEEK_CUR)) < 0)
67757193Smuller 			break;
67857193Smuller 		mpos = fsbz - (cpos % (off_t)fsbz);
67957193Smuller 		if (lseek(arfd, mpos, SEEK_CUR) < 0)
68057193Smuller 			break;
68157193Smuller 		lstrval = 1;
68257193Smuller 		break;
68357193Smuller 	case ISPIPE:
68457193Smuller 	default:
68557193Smuller 		/*
68657193Smuller 		 * cannot recover on these archive device types
68757193Smuller 		 */
68857193Smuller 		io_ok = 0;
68957193Smuller 		break;
69057193Smuller 	}
69157193Smuller 	if (lstrval <= 0) {
692*57535Smuller 		warn(1, "Unable to recover from an archive read failure.");
69357193Smuller 		return(-1);
69457193Smuller 	}
69557193Smuller 	warn(0, "Attempting to recover from an archive read failure.");
69657193Smuller 	return(0);
69757193Smuller }
69857193Smuller 
69957193Smuller /*
70057193Smuller  * ar_fow()
70157193Smuller  *	Move the I/O position within the archive foward the specified number of
70257193Smuller  *	bytes as supported by the device. If we cannot move the requested
70357193Smuller  *	number of bytes, return the actual number of bytes moved in skipped.
70457193Smuller  * Return:
70557193Smuller  *	0 if moved the requested distance, -1 on complete failure, 1 on
70657193Smuller  *	partial move (the amount moved is in skipped)
70757193Smuller  */
70857193Smuller 
70957193Smuller #if __STDC__
71057193Smuller int
71157193Smuller ar_fow(off_t sksz, off_t *skipped)
71257193Smuller #else
71357193Smuller int
71457193Smuller ar_fow(sksz, skipped)
71557193Smuller 	off_t sksz;
71657193Smuller 	off_t *skipped;
71757193Smuller #endif
71857193Smuller {
71957193Smuller 	off_t cpos;
72057193Smuller 	off_t mpos;
72157193Smuller 
72257193Smuller 	*skipped = 0;
72357193Smuller 	if (sksz <= 0)
72457193Smuller 		return(0);
72557193Smuller 
72657193Smuller 	/*
72757193Smuller 	 * we cannot move foward at EOF or error
72857193Smuller 	 */
72957193Smuller 	if (lstrval <= 0)
73057193Smuller 		return(lstrval);
73157193Smuller 
73257193Smuller 	/*
73357193Smuller 	 * Safer to read forward on devices where it is hard to find the end of
73457193Smuller 	 * the media without reading to it. With tapes we cannot be sure of the
73557193Smuller 	 * number of physical blocks to skip (we do not know physical block
73657193Smuller 	 * size at this point), so we must only read foward on tapes!
73757193Smuller 	 */
73857193Smuller 	if (artyp != ISREG)
73957193Smuller 		return(0);
74057193Smuller 
74157193Smuller 	/*
74257193Smuller 	 * figure out where we are in the archive
74357193Smuller 	 */
74457193Smuller 	if ((cpos = lseek(arfd, (off_t)0L, SEEK_CUR)) >= 0) {
74557193Smuller 		/*
74657193Smuller 	 	 * we can be asked to move farther than there are bytes in this
74757193Smuller 		 * volume, if so, just go to file end and let normal buf_fill()
74857193Smuller 		 * deal with the end of file (it will go to next volume by
74957193Smuller 		 * itself)
75057193Smuller 	 	 */
75157193Smuller 		if ((mpos = cpos + sksz) > arsb.st_size) {
75257193Smuller 			*skipped = arsb.st_size - cpos;
75357193Smuller 			mpos = arsb.st_size;
75457193Smuller 		} else
75557193Smuller 			*skipped = sksz;
75657193Smuller 		if (lseek(arfd, mpos, SEEK_SET) >= 0)
75757193Smuller 			return(0);
75857193Smuller 	}
75957193Smuller 	syswarn(1, errno, "Foward positioning operation on archive failed");
76057193Smuller 	lstrval = -1;
76157193Smuller 	return(-1);
76257193Smuller }
76357193Smuller 
76457193Smuller /*
76557193Smuller  * ar_rev()
76657193Smuller  *	move the i/o position within the archive backwards the specified byte
76757193Smuller  *	count as supported by the device. With tapes drives we RESET rdblksz to
76857193Smuller  *	the PHYSICAL blocksize.
76957193Smuller  *	NOTE: We should only be called to move backwards so we can rewrite the
77057193Smuller  *	last records (the trailer) of an archive (APPEND).
77157193Smuller  * Return:
77257193Smuller  *	0 if moved the requested distance, -1 on complete failure
77357193Smuller  */
77457193Smuller 
77557193Smuller #if __STDC__
77657193Smuller int
77757193Smuller ar_rev(off_t sksz)
77857193Smuller #else
77957193Smuller int
78057193Smuller ar_rev(sksz)
78157193Smuller 	off_t sksz;
78257193Smuller #endif
78357193Smuller {
78457193Smuller 	off_t cpos;
78557193Smuller         struct mtop mb;
78657193Smuller 
78757193Smuller 	if (sksz <= 0)
78857193Smuller 		return(0);
78957193Smuller 
79057193Smuller 	/*
79157193Smuller 	 * make sure we do not have a flawed archive
79257193Smuller 	 */
79357193Smuller 	if (lstrval < 0)
79457193Smuller 		return(lstrval);
79557193Smuller 
79657193Smuller 	switch(artyp) {
79757193Smuller 	case ISPIPE:
79857193Smuller 		/*
79957193Smuller 		 * cannot go backwards on these critters
80057193Smuller 		 */
80157193Smuller 		break;
80257193Smuller 	case ISREG:
80357193Smuller 	case ISBLK:
80457193Smuller 	case ISCHR:
80557193Smuller 	default:
80657193Smuller 		/*
80757193Smuller 		 * For things other than files, backwards movement has a very
80857193Smuller 		 * high probability of failure as we really do not know the
80957193Smuller 		 * true attributes of the device we are talking to (the device
81057193Smuller 		 * may not even have the ability to lseek() in any direction).
81157193Smuller 		 * first we figure out where we are in the archive
81257193Smuller 		 */
81357193Smuller 		if ((cpos = lseek(arfd, (off_t)0L, SEEK_CUR)) < 0)
81457193Smuller 			break;
81557193Smuller 
81657193Smuller 		/*
81757193Smuller 		 * we may try to go backwards past the start when the archive
81857193Smuller 		 * is only a single record. If this hapens and we are on a
81957193Smuller 		 * multi volume archive, we need to go to the end of the
82057193Smuller 		 * previous volume and continue our movement backwards from
82157193Smuller 		 * there. (This is really hard to do and is NOT IMPLEMENTED)
82257193Smuller 		 */
82357193Smuller 		if ((cpos -= sksz) < (off_t)0L) {
82457193Smuller 			if (arvol > 1) {
82557193Smuller 				warn(1,"End of archive is on previous volume.");
82657193Smuller 				lstrval = -1;
82757193Smuller 				return(-1);
82857193Smuller 			}
82957193Smuller 			cpos = (off_t)0L;
83057193Smuller 		}
83157193Smuller 		if (lseek(arfd, cpos, SEEK_SET) < 0)
83257193Smuller 			break;
83357193Smuller 		lstrval = 1;
83457193Smuller 		return(0);
83557193Smuller 	case ISTAPE:
83657193Smuller 		/*
83757193Smuller 	 	 * Calculate and move the proper number of PHYSICAL tape
83857193Smuller 		 * records. If the sksz is not an even multiple of the physical
83957193Smuller 		 * tape size, we cannot do the move (this should never happen).
84057193Smuller 		 * (We also cannot handler trailers spread over two vols).
84157193Smuller 	 	 */
84257193Smuller 		if (get_phys() < 0) {
84357193Smuller 			warn(1, "Cannot determine archive tape blocksize.");
84457193Smuller 			break;
84557193Smuller 		}
84657193Smuller 
84757193Smuller 		if (sksz % phyblk) {
84857193Smuller 			warn(1,"Tape drive cannot backspace %d bytes (%d phys)",
84957193Smuller 			    sksz, phyblk);
85057193Smuller 			lstrval = -1;
85157193Smuller 			return(-1);
85257193Smuller 		}
85357193Smuller 
85457193Smuller 		mb.mt_op = MTBSR;
85557193Smuller 		mb.mt_count = sksz/phyblk;
85657193Smuller 		if (ioctl(arfd, MTIOCTOP, &mb) < 0)
85757193Smuller 			break;
85857193Smuller 
85957193Smuller 		/*
86057193Smuller 		 * reset rdblksz to be the device physical blocksize.
86157193Smuller 		 */
86257193Smuller 		rdblksz = phyblk;
86357193Smuller 		lstrval = 1;
86457193Smuller 		return(0);
86557193Smuller 	}
86657193Smuller 	syswarn(1, errno, "Reverse positioning operation on archive failed");
86757193Smuller 	lstrval = -1;
86857193Smuller 	return(-1);
86957193Smuller }
87057193Smuller 
87157193Smuller /*
87257193Smuller  * get_phys()
87357193Smuller  *	Determine the physical block size on a tape drive. Should only be
874*57535Smuller  *	when at EOF. Tape drives are so inconsistant, while finding true record
875*57535Smuller  *	size should be a trival thing to figure out, it really is difficult and
876*57535Smuller  *	very likely to fail.
87757193Smuller  * Return:
87857193Smuller  *	0 if ok, -1 otherwise
87957193Smuller  */
88057193Smuller 
88157193Smuller #if __STDC__
88257193Smuller static int
88357193Smuller get_phys(void)
88457193Smuller #else
88557193Smuller static int
88657193Smuller get_phys()
88757193Smuller #endif
88857193Smuller {
889*57535Smuller 	register int res;
890*57535Smuller 	struct mtop mb;
89157193Smuller 	char scbuf1[MAXBLK];
89257193Smuller 	char scbuf2[MAXBLK];
89357193Smuller 
89457193Smuller 	/*
895*57535Smuller 	 * We backspace one record and read foward. The read should tell us the
896*57535Smuller 	 * true physical size.  We can only use this technique when we are at
897*57535Smuller 	 * tape EOF (so the MTBSR will leave just a SINGLE PHYSICAL record
898*57535Smuller 	 * between the head and the end of the tape file; the max we can then
899*57535Smuller 	 * read should be just ONE physical record). Since we may be called
900*57535Smuller 	 * more than once, only the first phyblk detection will be used.
901*57535Smuller  	 */
90257193Smuller 	if (phyblk > 0)
90357193Smuller 		return(0);
90457193Smuller 
90557193Smuller 	mb.mt_op = MTBSR;
90657193Smuller 	mb.mt_count = 1;
90757193Smuller 	if ((ioctl(arfd, MTIOCTOP, &mb) < 0) ||
908*57535Smuller 	    ((phyblk = read(arfd, scbuf1, sizeof(scbuf1))) <= 0)) {
90957193Smuller 		return(-1);
910*57535Smuller 	}
91157193Smuller 
91257193Smuller 	/*
913*57535Smuller 	 * We must be careful, we may not have been called with the tape head
914*57535Smuller 	 * at the end of the tape.  We expect if we read again we will get the
915*57535Smuller 	 * true blocksize. (We expect the true size on the second read because
916*57535Smuller 	 * by pax spec the trailer is always in the last record, and we are
917*57535Smuller 	 * only called after the trailer was seen. If this is not true, the
918*57535Smuller 	 * archive is flawed and we will return a failure indication). After
919*57535Smuller 	 * the second read we must adjust the head position so it is at the
920*57535Smuller 	 * same place it was when we are called. We also check for consistancy,
921*57535Smuller 	 * if we cannot repeat we return a failure.
92257193Smuller 	 */
92357193Smuller 	if ((ioctl(arfd, MTIOCTOP, &mb) < 0) ||
924*57535Smuller 	    ((res = read(arfd, scbuf2, sizeof(scbuf2))) <= 0))
92557193Smuller 		return(-1);
926*57535Smuller 
927*57535Smuller 	/*
928*57535Smuller 	 * If we get a bigger size on the second read or the first read is not
929*57535Smuller 	 * a multiple of the second read, we better not chance an append.
930*57535Smuller 	 */
931*57535Smuller 	if ((res > phyblk) || (phyblk % res))
932*57535Smuller 		return(-1);
933*57535Smuller 
934*57535Smuller 	/*
935*57535Smuller 	 * if both reads are the same size and the data is consistant we can
936*57535Smuller 	 * go on with the append
937*57535Smuller 	 */
938*57535Smuller 	if (res == phyblk) {
939*57535Smuller 		if (bcmp(scbuf1, scbuf2, phyblk) != 0)
940*57535Smuller 			return(-1);
941*57535Smuller 		return(0);
942*57535Smuller 	}
943*57535Smuller 
944*57535Smuller 	/*
945*57535Smuller 	 * We got two different block sizes. We were not at the tape EOF.
946*57535Smuller 	 * So we try one more time, if the result is not consistant we abort.
947*57535Smuller 	 */
948*57535Smuller 	if ((ioctl(arfd, MTIOCTOP, &mb) < 0) ||
949*57535Smuller 	    (read(arfd, scbuf1, sizeof(scbuf1)) != res) ||
950*57535Smuller 	    (bcmp(scbuf1, scbuf2, res) != 0))
951*57535Smuller 		return(-1);
952*57535Smuller 
953*57535Smuller 	/*
954*57535Smuller 	 * Ok, we assume the physical block size is in res. We need to adjust
955*57535Smuller 	 * head position backwards based on the what we got on the first read.
956*57535Smuller 	 * (must leave the head at the same place it was when we were called).
957*57535Smuller 	 */
958*57535Smuller 	mb.mt_count = (phyblk - res)/res;
959*57535Smuller 	phyblk = res;
960*57535Smuller 	if ((mb.mt_count == 0) || (ioctl(arfd, MTIOCTOP, &mb) < 0))
961*57535Smuller 		return(-1);
96257193Smuller 	return(0);
96357193Smuller }
96457193Smuller 
96557193Smuller /*
96657193Smuller  * ar_next()
967*57535Smuller  *	prompts the user for the next volume in this archive. For some devices
968*57535Smuller  *	we may allow the media to be changed. Otherwise a new archive is
969*57535Smuller  *	prompted for. By pax spec, if there is no controlling tty or an eof is
970*57535Smuller  *	read on tty input, we must quit pax.
97157193Smuller  * Return:
97257193Smuller  *	0 when ready to continue, -1 when all done
97357193Smuller  */
97457193Smuller 
97557193Smuller #if __STDC__
97657193Smuller int
97757193Smuller ar_next(void)
97857193Smuller #else
97957193Smuller int
98057193Smuller ar_next()
98157193Smuller #endif
98257193Smuller {
98357193Smuller 	char buf[PAXPATHLEN+2];
98457193Smuller 	static int freeit = 0;
98557193Smuller 	sigset_t o_mask;
98657193Smuller 
98757193Smuller 	/*
988*57535Smuller 	 * WE MUST CLOSE THE DEVICE. A lot of devices must see last close, (so
98957193Smuller 	 * things like writing EOF etc will be done) (Watch out ar_close() can
990*57535Smuller 	 * also be called via a signal handler, so we must prevent a race.
99157193Smuller 	 */
99257193Smuller 	if (sigprocmask(SIG_BLOCK, &s_mask, &o_mask) < 0)
993*57535Smuller 		syswarn(0, errno, "Unable to set signal mask");
99457193Smuller 	ar_close();
99557193Smuller 	if (sigprocmask(SIG_SETMASK, &o_mask, (sigset_t *)NULL) < 0)
996*57535Smuller 		syswarn(0, errno, "Unable to restore signal mask");
99757193Smuller 
99857193Smuller 	if (done)
99957193Smuller 		return(-1);
100057193Smuller 
100157193Smuller 	tty_prnt("\nATTENTION! Pax archive volume change required.\n");
100257193Smuller 
100357193Smuller 	/*
100457193Smuller 	 * if i/o is on stdin or stdout, we cannot reopen it (we do not know
1005*57535Smuller 	 * the name), the user will be forced to type it in.
100657193Smuller 	 */
100757193Smuller 	if (strcmp(arcname, STDO) && strcmp(arcname, STDN) && (artyp != ISREG)
100857193Smuller 	    && (artyp != ISPIPE)) {
100957193Smuller 		if (artyp == ISTAPE) {
101057193Smuller 			tty_prnt("%s ready for archive tape volume: %d\n",
101157193Smuller 				arcname, arvol);
101257193Smuller 			tty_prnt("Load the NEXT TAPE on the tape drive");
101357193Smuller 		} else {
101457193Smuller 			tty_prnt("%s ready for archive volume: %d\n",
101557193Smuller 				arcname, arvol);
101657193Smuller 			tty_prnt("Load the NEXT STORAGE MEDIA (if required)");
101757193Smuller 		}
101857193Smuller 
101957193Smuller 		if ((act == ARCHIVE) || (act == APPND))
102057193Smuller 			tty_prnt(" and make sure it is WRITE ENABLED.\n");
102157193Smuller 		else
102257193Smuller 			tty_prnt("\n");
102357193Smuller 
102457193Smuller 		for(;;) {
102557193Smuller 			tty_prnt("Type \"y\" to continue, \".\" to quit pax,");
102657193Smuller 			tty_prnt(" or \"s\" to switch to new device.\nIf you");
102757193Smuller 			tty_prnt(" cannot change storage media, type \"s\"\n");
102857193Smuller 			tty_prnt("Is the device ready and online? > ");
102957193Smuller 
103057193Smuller 			if ((tty_read(buf,sizeof(buf))<0) || !strcmp(buf,".")){
103157193Smuller 				done = 1;
103257193Smuller 				lstrval = -1;
103357193Smuller 				tty_prnt("Quitting pax!\n");
103457193Smuller 				vfpart = 0;
103557193Smuller 				return(-1);
103657193Smuller 			}
103757193Smuller 
103857193Smuller 			if ((buf[0] == '\0') || (buf[1] != '\0')) {
103957193Smuller 				tty_prnt("%s unknown command, try again\n",buf);
104057193Smuller 				continue;
104157193Smuller 			}
104257193Smuller 
104357193Smuller 			switch (buf[0]) {
104457193Smuller 			case 'y':
104557193Smuller 			case 'Y':
104657193Smuller 				/*
104757193Smuller 				 * we are to continue with the same device
104857193Smuller 				 */
104957193Smuller 				if (ar_open(arcname) >= 0)
105057193Smuller 					return(0);
105157193Smuller 				tty_prnt("Cannot re-open %s, try again\n",
105257193Smuller 					arcname);
105357193Smuller 				continue;
105457193Smuller 			case 's':
105557193Smuller 			case 'S':
105657193Smuller 				/*
105757193Smuller 				 * user wants to open a different device
105857193Smuller 				 */
105957193Smuller 				tty_prnt("Switching to a different archive\n");
106057193Smuller 				break;
106157193Smuller 			default:
106257193Smuller 				tty_prnt("%s unknown command, try again\n",buf);
106357193Smuller 				continue;
106457193Smuller 			}
106557193Smuller 			break;
106657193Smuller 		}
106757193Smuller 	} else
106857193Smuller 		tty_prnt("Ready for archive volume: %d\n", arvol);
106957193Smuller 
107057193Smuller 	/*
107157193Smuller 	 * have to go to a different archive
107257193Smuller 	 */
107357193Smuller 	for (;;) {
107457193Smuller 		tty_prnt("Input archive name or \".\" to quit pax.\n");
107557193Smuller 		tty_prnt("Archive name > ");
107657193Smuller 
107757193Smuller 		if ((tty_read(buf, sizeof(buf)) < 0) || !strcmp(buf, ".")) {
107857193Smuller 			done = 1;
107957193Smuller 			lstrval = -1;
108057193Smuller 			tty_prnt("Quitting pax!\n");
108157193Smuller 			vfpart = 0;
108257193Smuller 			return(-1);
108357193Smuller 		}
108457193Smuller 		if (buf[0] == '\0') {
108557193Smuller 			tty_prnt("Empty file name, try again\n");
108657193Smuller 			continue;
108757193Smuller 		}
108857193Smuller                 if (!strcmp(buf, "..")) {
108957193Smuller                         tty_prnt("Illegal file name: .. try again\n");
109057193Smuller                         continue;
109157193Smuller                 }
109257193Smuller 		if (strlen(buf) > PAXPATHLEN) {
109357193Smuller 			tty_prnt("File name too long, try again\n");
109457193Smuller 			continue;
109557193Smuller 		}
109657193Smuller 
109757193Smuller 		/*
109857193Smuller 		 * try to open new archive
109957193Smuller 		 */
110057193Smuller 		if (ar_open(buf) >= 0) {
110157193Smuller 			if (freeit) {
110257193Smuller 				(void)free(arcname);
110357193Smuller 				freeit = 0;
110457193Smuller 			}
110557193Smuller 			if ((arcname = strdup(buf)) == NULL) {
110657193Smuller 				done = 1;
110757193Smuller 				lstrval = -1;
1108*57535Smuller 				warn(0, "Cannot save archive name.");
110957193Smuller 				return(-1);
111057193Smuller 			}
111157193Smuller 			freeit = 1;
111257193Smuller 			break;
111357193Smuller 		}
111457193Smuller 		tty_prnt("Cannot open %s, try again\n", buf);
111557193Smuller 		continue;
111657193Smuller 	}
111757193Smuller 	return(0);
111857193Smuller }
1119