Home | History | Annotate | Line # | Download | only in pax
ar_io.c revision 1.13.4.1
      1  1.13.4.1  wrstuden /*	$NetBSD: ar_io.c,v 1.13.4.1 1999/12/27 18:27:07 wrstuden Exp $	*/
      2       1.4       cgd 
      3       1.1       jtc /*-
      4       1.1       jtc  * Copyright (c) 1992 Keith Muller.
      5       1.1       jtc  * Copyright (c) 1992, 1993
      6       1.1       jtc  *	The Regents of the University of California.  All rights reserved.
      7       1.1       jtc  *
      8       1.1       jtc  * This code is derived from software contributed to Berkeley by
      9       1.1       jtc  * Keith Muller of the University of California, San Diego.
     10       1.1       jtc  *
     11       1.1       jtc  * Redistribution and use in source and binary forms, with or without
     12       1.1       jtc  * modification, are permitted provided that the following conditions
     13       1.1       jtc  * are met:
     14       1.1       jtc  * 1. Redistributions of source code must retain the above copyright
     15       1.1       jtc  *    notice, this list of conditions and the following disclaimer.
     16       1.1       jtc  * 2. Redistributions in binary form must reproduce the above copyright
     17       1.1       jtc  *    notice, this list of conditions and the following disclaimer in the
     18       1.1       jtc  *    documentation and/or other materials provided with the distribution.
     19       1.1       jtc  * 3. All advertising materials mentioning features or use of this software
     20       1.1       jtc  *    must display the following acknowledgement:
     21       1.1       jtc  *	This product includes software developed by the University of
     22       1.1       jtc  *	California, Berkeley and its contributors.
     23       1.1       jtc  * 4. Neither the name of the University nor the names of its contributors
     24       1.1       jtc  *    may be used to endorse or promote products derived from this software
     25       1.1       jtc  *    without specific prior written permission.
     26       1.1       jtc  *
     27       1.1       jtc  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     28       1.1       jtc  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     29       1.1       jtc  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     30       1.1       jtc  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     31       1.1       jtc  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     32       1.1       jtc  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     33       1.1       jtc  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     34       1.1       jtc  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     35       1.1       jtc  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     36       1.1       jtc  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     37       1.1       jtc  * SUCH DAMAGE.
     38       1.1       jtc  */
     39       1.1       jtc 
     40       1.7  christos #include <sys/cdefs.h>
     41       1.1       jtc #ifndef lint
     42       1.4       cgd #if 0
     43       1.4       cgd static char sccsid[] = "@(#)ar_io.c	8.2 (Berkeley) 4/18/94";
     44       1.4       cgd #else
     45  1.13.4.1  wrstuden __RCSID("$NetBSD: ar_io.c,v 1.13.4.1 1999/12/27 18:27:07 wrstuden Exp $");
     46       1.4       cgd #endif
     47       1.1       jtc #endif /* not lint */
     48       1.1       jtc 
     49       1.1       jtc #include <sys/types.h>
     50       1.1       jtc #include <sys/time.h>
     51       1.1       jtc #include <sys/stat.h>
     52       1.1       jtc #include <sys/ioctl.h>
     53       1.1       jtc #include <sys/mtio.h>
     54       1.1       jtc #include <sys/param.h>
     55       1.1       jtc #include <signal.h>
     56       1.1       jtc #include <string.h>
     57       1.1       jtc #include <fcntl.h>
     58       1.1       jtc #include <unistd.h>
     59       1.1       jtc #include <stdio.h>
     60       1.1       jtc #include <ctype.h>
     61       1.1       jtc #include <errno.h>
     62       1.1       jtc #include <stdlib.h>
     63       1.7  christos #include <err.h>
     64       1.1       jtc #include "pax.h"
     65       1.1       jtc #include "extern.h"
     66       1.1       jtc 
     67       1.1       jtc /*
     68       1.1       jtc  * Routines which deal directly with the archive I/O device/file.
     69       1.1       jtc  */
     70       1.1       jtc 
     71       1.1       jtc #define DMOD		0666		/* default mode of created archives */
     72       1.1       jtc #define EXT_MODE	O_RDONLY	/* open mode for list/extract */
     73       1.1       jtc #define AR_MODE		(O_WRONLY | O_CREAT | O_TRUNC)	/* mode for archive */
     74       1.1       jtc #define APP_MODE	O_RDWR		/* mode for append */
     75       1.1       jtc #define STDO		"<STDOUT>"	/* psuedo name for stdout */
     76       1.1       jtc #define STDN		"<STDIN>"	/* psuedo name for stdin */
     77       1.1       jtc static int arfd = -1;			/* archive file descriptor */
     78       1.1       jtc static int artyp = ISREG;		/* archive type: file/FIFO/tape */
     79       1.1       jtc static int arvol = 1;			/* archive volume number */
     80       1.1       jtc static int lstrval = -1;		/* return value from last i/o */
     81       1.1       jtc static int io_ok;			/* i/o worked on volume after resync */
     82       1.1       jtc static int did_io;			/* did i/o ever occur on volume? */
     83       1.1       jtc static int done;			/* set via tty termination */
     84       1.1       jtc static struct stat arsb;		/* stat of archive device at open */
     85       1.1       jtc static int invld_rec;			/* tape has out of spec record size */
     86       1.1       jtc static int wr_trail = 1;		/* trailer was rewritten in append */
     87       1.1       jtc static int can_unlnk = 0;		/* do we unlink null archives?  */
     88       1.9   mycroft const char *arcname;                  	/* printable name of archive */
     89       1.9   mycroft const char *gzip_program;		/* name of gzip program */
     90      1.13  christos time_t starttime;			/* time the run started */
     91  1.13.4.1  wrstuden int minusCfd = -1;			/* active -C directory */
     92  1.13.4.1  wrstuden int curdirfd = -1;			/* original current directory */
     93       1.1       jtc 
     94       1.1       jtc static int get_phys __P((void));
     95       1.1       jtc extern sigset_t s_mask;
     96       1.5       mrg static void ar_start_gzip __P((int));
     97      1.13  christos static const char *timefmt __P((char *, size_t, off_t, time_t));
     98      1.13  christos static const char *sizefmt __P((char *, size_t, off_t));
     99       1.1       jtc 
    100       1.1       jtc /*
    101       1.1       jtc  * ar_open()
    102       1.1       jtc  *	Opens the next archive volume. Determines the type of the device and
    103       1.1       jtc  *	sets up block sizes as required by the archive device and the format.
    104       1.1       jtc  *	Note: we may be called with name == NULL on the first open only.
    105       1.1       jtc  * Return:
    106       1.1       jtc  *	-1 on failure, 0 otherwise
    107       1.1       jtc  */
    108       1.1       jtc 
    109       1.1       jtc #if __STDC__
    110       1.1       jtc int
    111       1.9   mycroft ar_open(const char *name)
    112       1.1       jtc #else
    113       1.1       jtc int
    114       1.1       jtc ar_open(name)
    115       1.9   mycroft 	const char *name;
    116       1.1       jtc #endif
    117       1.1       jtc {
    118       1.1       jtc         struct mtget mb;
    119       1.8       mrg 
    120       1.8       mrg 	/*
    121       1.8       mrg 	 * change back to the current directory (for now).
    122       1.8       mrg 	 */
    123       1.8       mrg 	if (curdirfd != -1)
    124       1.8       mrg 		fchdir(curdirfd);
    125       1.1       jtc 
    126       1.1       jtc 	if (arfd != -1)
    127       1.1       jtc 		(void)close(arfd);
    128       1.1       jtc 	arfd = -1;
    129       1.1       jtc 	can_unlnk = did_io = io_ok = invld_rec = 0;
    130       1.1       jtc 	artyp = ISREG;
    131       1.1       jtc 	flcnt = 0;
    132       1.1       jtc 
    133       1.1       jtc 	/*
    134       1.1       jtc 	 * open based on overall operation mode
    135       1.1       jtc 	 */
    136       1.1       jtc 	switch (act) {
    137       1.1       jtc 	case LIST:
    138       1.1       jtc 	case EXTRACT:
    139       1.1       jtc 		if (name == NULL) {
    140       1.1       jtc 			arfd = STDIN_FILENO;
    141       1.1       jtc 			arcname = STDN;
    142       1.1       jtc 		} else if ((arfd = open(name, EXT_MODE, DMOD)) < 0)
    143       1.1       jtc 			syswarn(0, errno, "Failed open to read on %s", name);
    144       1.5       mrg 		if (zflag)
    145       1.5       mrg 			ar_start_gzip(arfd);
    146       1.1       jtc 		break;
    147       1.1       jtc 	case ARCHIVE:
    148       1.1       jtc 		if (name == NULL) {
    149       1.1       jtc 			arfd = STDOUT_FILENO;
    150       1.1       jtc 			arcname = STDO;
    151       1.1       jtc 		} else if ((arfd = open(name, AR_MODE, DMOD)) < 0)
    152       1.1       jtc 			syswarn(0, errno, "Failed open to write on %s", name);
    153       1.1       jtc 		else
    154       1.1       jtc 			can_unlnk = 1;
    155       1.5       mrg 		if (zflag)
    156       1.5       mrg 			ar_start_gzip(arfd);
    157       1.1       jtc 		break;
    158       1.1       jtc 	case APPND:
    159       1.5       mrg 		if (zflag)
    160       1.5       mrg 			err(1, "can not gzip while appending");
    161       1.1       jtc 		if (name == NULL) {
    162       1.1       jtc 			arfd = STDOUT_FILENO;
    163       1.1       jtc 			arcname = STDO;
    164       1.1       jtc 		} else if ((arfd = open(name, APP_MODE, DMOD)) < 0)
    165       1.1       jtc 			syswarn(0, errno, "Failed open to read/write on %s",
    166       1.1       jtc 				name);
    167       1.1       jtc 		break;
    168       1.1       jtc 	case COPY:
    169       1.1       jtc 		/*
    170       1.1       jtc 		 * arfd not used in COPY mode
    171       1.1       jtc 		 */
    172       1.1       jtc 		arcname = "<NONE>";
    173       1.1       jtc 		lstrval = 1;
    174       1.1       jtc 		return(0);
    175       1.1       jtc 	}
    176       1.1       jtc 	if (arfd < 0)
    177       1.1       jtc 		return(-1);
    178       1.1       jtc 
    179       1.1       jtc 	/*
    180       1.1       jtc 	 * set up is based on device type
    181       1.1       jtc 	 */
    182       1.1       jtc 	if (fstat(arfd, &arsb) < 0) {
    183       1.1       jtc 		syswarn(0, errno, "Failed stat on %s", arcname);
    184       1.1       jtc 		(void)close(arfd);
    185       1.1       jtc 		arfd = -1;
    186       1.1       jtc 		can_unlnk = 0;
    187       1.1       jtc 		return(-1);
    188       1.1       jtc 	}
    189       1.1       jtc 	if (S_ISDIR(arsb.st_mode)) {
    190       1.7  christos 		tty_warn(0, "Cannot write an archive on top of a directory %s",
    191       1.1       jtc 		    arcname);
    192       1.1       jtc 		(void)close(arfd);
    193       1.1       jtc 		arfd = -1;
    194       1.1       jtc 		can_unlnk = 0;
    195       1.1       jtc 		return(-1);
    196       1.1       jtc 	}
    197       1.1       jtc 
    198       1.1       jtc 	if (S_ISCHR(arsb.st_mode))
    199       1.1       jtc 		artyp = ioctl(arfd, MTIOCGET, &mb) ? ISCHR : ISTAPE;
    200       1.1       jtc 	else if (S_ISBLK(arsb.st_mode))
    201       1.1       jtc 		artyp = ISBLK;
    202       1.1       jtc 	else if ((lseek(arfd, (off_t)0L, SEEK_CUR) == -1) && (errno == ESPIPE))
    203       1.1       jtc 		artyp = ISPIPE;
    204       1.1       jtc 	else
    205       1.1       jtc 		artyp = ISREG;
    206       1.1       jtc 
    207       1.1       jtc 	/*
    208       1.1       jtc 	 * make sure we beyond any doubt that we only can unlink regular files
    209       1.1       jtc 	 * we created
    210       1.1       jtc 	 */
    211       1.1       jtc 	if (artyp != ISREG)
    212       1.1       jtc 		can_unlnk = 0;
    213  1.13.4.1  wrstuden 
    214  1.13.4.1  wrstuden 	/*
    215  1.13.4.1  wrstuden 	 * change directory if necessary
    216  1.13.4.1  wrstuden 	 */
    217  1.13.4.1  wrstuden 	if (minusCfd != -1)
    218  1.13.4.1  wrstuden 		fchdir(minusCfd);
    219  1.13.4.1  wrstuden 
    220       1.1       jtc 	/*
    221       1.1       jtc 	 * if we are writing, we are done
    222       1.1       jtc 	 */
    223       1.1       jtc 	if (act == ARCHIVE) {
    224       1.1       jtc 		blksz = rdblksz = wrblksz;
    225       1.1       jtc 		lstrval = 1;
    226       1.1       jtc 		return(0);
    227       1.8       mrg 	}
    228       1.8       mrg 
    229       1.8       mrg 	/*
    230       1.1       jtc 	 * set default blksz on read. APPNDs writes rdblksz on the last volume
    231       1.1       jtc 	 * On all new archive volumes, we shift to wrblksz (if the user
    232       1.1       jtc 	 * specified one, otherwize we will continue to use rdblksz). We
    233       1.1       jtc 	 * must to set blocksize based on what kind of device the archive is
    234       1.1       jtc 	 * stored.
    235       1.1       jtc 	 */
    236       1.1       jtc 	switch(artyp) {
    237       1.1       jtc 	case ISTAPE:
    238       1.1       jtc 		/*
    239       1.1       jtc 		 * Tape drives come in at least two flavors. Those that support
    240       1.1       jtc 		 * variable sized records and those that have fixed sized
    241       1.1       jtc 		 * records. They must be treated differently. For tape drives
    242       1.1       jtc 		 * that support variable sized records, we must make large
    243       1.1       jtc 		 * reads to make sure we get the entire record, otherwise we
    244       1.1       jtc 		 * will just get the first part of the record (up to size we
    245       1.1       jtc 		 * asked). Tapes with fixed sized records may or may not return
    246       1.1       jtc 		 * multiple records in a single read. We really do not care
    247       1.1       jtc 		 * what the physical record size is UNLESS we are going to
    248       1.1       jtc 		 * append. (We will need the physical block size to rewrite
    249       1.1       jtc 		 * the trailer). Only when we are appending do we go to the
    250       1.1       jtc 		 * effort to figure out the true PHYSICAL record size.
    251       1.1       jtc 		 */
    252       1.1       jtc 		blksz = rdblksz = MAXBLK;
    253       1.1       jtc 		break;
    254       1.1       jtc 	case ISPIPE:
    255       1.1       jtc 	case ISBLK:
    256       1.1       jtc 	case ISCHR:
    257       1.1       jtc 		/*
    258       1.1       jtc 		 * Blocksize is not a major issue with these devices (but must
    259       1.1       jtc 		 * be kept a multiple of 512). If the user specified a write
    260       1.1       jtc 		 * block size, we use that to read. Under append, we must
    261       1.1       jtc 		 * always keep blksz == rdblksz. Otherwise we go ahead and use
    262       1.1       jtc 		 * the device optimal blocksize as (and if) returned by stat
    263       1.1       jtc 		 * and if it is within pax specs.
    264       1.1       jtc 		 */
    265       1.1       jtc 		if ((act == APPND) && wrblksz) {
    266       1.1       jtc 			blksz = rdblksz = wrblksz;
    267       1.1       jtc 			break;
    268       1.1       jtc 		}
    269       1.1       jtc 
    270       1.1       jtc 		if ((arsb.st_blksize > 0) && (arsb.st_blksize < MAXBLK) &&
    271       1.1       jtc 		    ((arsb.st_blksize % BLKMULT) == 0))
    272       1.1       jtc 			rdblksz = arsb.st_blksize;
    273       1.1       jtc 		else
    274       1.1       jtc 			rdblksz = DEVBLK;
    275       1.1       jtc 		/*
    276       1.1       jtc 		 * For performance go for large reads when we can without harm
    277       1.1       jtc 		 */
    278       1.1       jtc 		if ((act == APPND) || (artyp == ISCHR))
    279       1.1       jtc 			blksz = rdblksz;
    280       1.1       jtc 		else
    281       1.1       jtc 			blksz = MAXBLK;
    282       1.1       jtc 		break;
    283       1.1       jtc 	case ISREG:
    284       1.1       jtc 		/*
    285       1.1       jtc 		 * if the user specified wrblksz works, use it. Under appends
    286       1.1       jtc 		 * we must always keep blksz == rdblksz
    287       1.1       jtc 		 */
    288       1.1       jtc 		if ((act == APPND) && wrblksz && ((arsb.st_size%wrblksz)==0)){
    289       1.1       jtc 			blksz = rdblksz = wrblksz;
    290       1.1       jtc 			break;
    291       1.1       jtc 		}
    292       1.1       jtc 		/*
    293       1.1       jtc 		 * See if we can find the blocking factor from the file size
    294       1.1       jtc 		 */
    295       1.1       jtc 		for (rdblksz = MAXBLK; rdblksz > 0; rdblksz -= BLKMULT)
    296       1.1       jtc 			if ((arsb.st_size % rdblksz) == 0)
    297       1.1       jtc 				break;
    298       1.1       jtc 		/*
    299       1.1       jtc 		 * When we cannont find a match, we may have a flawed archive.
    300       1.1       jtc 		 */
    301       1.1       jtc 		if (rdblksz <= 0)
    302       1.1       jtc 			rdblksz = FILEBLK;
    303       1.1       jtc 		/*
    304       1.1       jtc 		 * for performance go for large reads when we can
    305       1.1       jtc 		 */
    306       1.1       jtc 		if (act == APPND)
    307       1.1       jtc 			blksz = rdblksz;
    308       1.1       jtc 		else
    309       1.1       jtc 			blksz = MAXBLK;
    310       1.1       jtc 		break;
    311       1.1       jtc 	default:
    312       1.1       jtc 		/*
    313       1.1       jtc 		 * should never happen, worse case, slow...
    314       1.1       jtc 		 */
    315       1.1       jtc 		blksz = rdblksz = BLKMULT;
    316       1.1       jtc 		break;
    317       1.1       jtc 	}
    318       1.1       jtc 	lstrval = 1;
    319       1.1       jtc 	return(0);
    320       1.1       jtc }
    321       1.1       jtc 
    322       1.1       jtc /*
    323       1.1       jtc  * ar_close()
    324       1.1       jtc  *	closes archive device, increments volume number, and prints i/o summary
    325       1.1       jtc  */
    326       1.1       jtc #if __STDC__
    327       1.1       jtc void
    328       1.1       jtc ar_close(void)
    329       1.1       jtc #else
    330       1.1       jtc void
    331       1.1       jtc ar_close()
    332       1.1       jtc #endif
    333       1.1       jtc {
    334       1.1       jtc 	FILE *outf;
    335       1.1       jtc 
    336       1.1       jtc 	if (arfd < 0) {
    337       1.1       jtc 		did_io = io_ok = flcnt = 0;
    338       1.1       jtc 		return;
    339       1.1       jtc 	}
    340       1.1       jtc 
    341       1.1       jtc 	if (act == LIST)
    342       1.1       jtc 		outf = stdout;
    343       1.1       jtc 	else
    344       1.1       jtc 		outf = stderr;
    345       1.1       jtc 
    346       1.1       jtc 	/*
    347       1.1       jtc 	 * Close archive file. This may take a LONG while on tapes (we may be
    348       1.1       jtc 	 * forced to wait for the rewind to complete) so tell the user what is
    349       1.1       jtc 	 * going on (this avoids the user hitting control-c thinking pax is
    350       1.1       jtc 	 * broken).
    351       1.1       jtc 	 */
    352       1.1       jtc 	if (vflag && (artyp == ISTAPE)) {
    353       1.1       jtc 		if (vfpart)
    354       1.1       jtc 			(void)putc('\n', outf);
    355       1.1       jtc 		(void)fprintf(outf,
    356       1.1       jtc 			"%s: Waiting for tape drive close to complete...",
    357       1.1       jtc 			argv0);
    358       1.1       jtc 		(void)fflush(outf);
    359       1.1       jtc 	}
    360       1.1       jtc 
    361       1.1       jtc 	/*
    362       1.1       jtc 	 * if nothing was written to the archive (and we created it), we remove
    363       1.1       jtc 	 * it
    364       1.1       jtc 	 */
    365       1.1       jtc 	if (can_unlnk && (fstat(arfd, &arsb) == 0) && (S_ISREG(arsb.st_mode)) &&
    366       1.1       jtc 	    (arsb.st_size == 0)) {
    367       1.1       jtc 		(void)unlink(arcname);
    368       1.1       jtc 		can_unlnk = 0;
    369       1.1       jtc 	}
    370       1.1       jtc 
    371       1.1       jtc 	(void)close(arfd);
    372       1.1       jtc 
    373       1.1       jtc 	if (vflag && (artyp == ISTAPE)) {
    374       1.1       jtc 		(void)fputs("done.\n", outf);
    375       1.1       jtc 		vfpart = 0;
    376       1.1       jtc 		(void)fflush(outf);
    377       1.1       jtc 	}
    378       1.1       jtc 	arfd = -1;
    379       1.1       jtc 
    380       1.1       jtc 	if (!io_ok && !did_io) {
    381       1.1       jtc 		flcnt = 0;
    382       1.1       jtc 		return;
    383       1.1       jtc 	}
    384       1.1       jtc 	did_io = io_ok = 0;
    385       1.1       jtc 
    386       1.1       jtc 	/*
    387       1.1       jtc 	 * The volume number is only increased when the last device has data
    388       1.1       jtc 	 * and we have already determined the archive format.
    389       1.1       jtc 	 */
    390       1.1       jtc 	if (frmt != NULL)
    391       1.1       jtc 		++arvol;
    392       1.1       jtc 
    393       1.1       jtc 	if (!vflag) {
    394       1.1       jtc 		flcnt = 0;
    395       1.1       jtc 		return;
    396       1.1       jtc 	}
    397       1.1       jtc 
    398       1.1       jtc 	/*
    399       1.1       jtc 	 * Print out a summary of I/O for this archive volume.
    400       1.1       jtc 	 */
    401       1.1       jtc 	if (vfpart) {
    402       1.1       jtc 		(void)putc('\n', outf);
    403       1.1       jtc 		vfpart = 0;
    404       1.1       jtc 	}
    405       1.1       jtc 
    406      1.13  christos 	ar_summary(0);
    407       1.1       jtc 
    408       1.1       jtc 	(void)fflush(outf);
    409       1.1       jtc 	flcnt = 0;
    410       1.1       jtc }
    411       1.1       jtc 
    412       1.1       jtc /*
    413       1.1       jtc  * ar_drain()
    414       1.1       jtc  *	drain any archive format independent padding from an archive read
    415       1.1       jtc  *	from a socket or a pipe. This is to prevent the process on the
    416       1.1       jtc  *	other side of the pipe from getting a SIGPIPE (pax will stop
    417       1.1       jtc  *	reading an archive once a format dependent trailer is detected).
    418       1.1       jtc  */
    419       1.1       jtc #if __STDC__
    420       1.1       jtc void
    421       1.1       jtc ar_drain(void)
    422       1.1       jtc #else
    423       1.1       jtc void
    424       1.1       jtc ar_drain()
    425       1.1       jtc #endif
    426       1.1       jtc {
    427       1.6       tls 	int res;
    428       1.1       jtc 	char drbuf[MAXBLK];
    429       1.1       jtc 
    430       1.1       jtc 	/*
    431       1.1       jtc 	 * we only drain from a pipe/socket. Other devices can be closed
    432       1.1       jtc 	 * without reading up to end of file. We sure hope that pipe is closed
    433       1.1       jtc 	 * on the other side so we will get an EOF.
    434       1.1       jtc 	 */
    435       1.1       jtc 	if ((artyp != ISPIPE) || (lstrval <= 0))
    436       1.1       jtc 		return;
    437       1.1       jtc 
    438       1.1       jtc 	/*
    439       1.1       jtc 	 * keep reading until pipe is drained
    440       1.1       jtc 	 */
    441       1.1       jtc 	while ((res = read(arfd, drbuf, sizeof(drbuf))) > 0)
    442       1.1       jtc 		;
    443       1.1       jtc 	lstrval = res;
    444       1.1       jtc }
    445       1.1       jtc 
    446       1.1       jtc /*
    447       1.1       jtc  * ar_set_wr()
    448       1.1       jtc  *	Set up device right before switching from read to write in an append.
    449       1.1       jtc  *	device dependent code (if required) to do this should be added here.
    450       1.1       jtc  *	For all archive devices we are already positioned at the place we want
    451       1.1       jtc  *	to start writing when this routine is called.
    452       1.1       jtc  * Return:
    453       1.1       jtc  *	0 if all ready to write, -1 otherwise
    454       1.1       jtc  */
    455       1.1       jtc 
    456       1.1       jtc #if __STDC__
    457       1.1       jtc int
    458       1.1       jtc ar_set_wr(void)
    459       1.1       jtc #else
    460       1.1       jtc int
    461       1.1       jtc ar_set_wr()
    462       1.1       jtc #endif
    463       1.1       jtc {
    464       1.1       jtc 	off_t cpos;
    465       1.1       jtc 
    466       1.1       jtc 	/*
    467       1.1       jtc 	 * we must make sure the trailer is rewritten on append, ar_next()
    468       1.1       jtc 	 * will stop us if the archive containing the trailer was not written
    469       1.1       jtc 	 */
    470       1.1       jtc 	wr_trail = 0;
    471       1.1       jtc 
    472       1.1       jtc 	/*
    473       1.1       jtc 	 * Add any device dependent code as required here
    474       1.1       jtc 	 */
    475       1.1       jtc 	if (artyp != ISREG)
    476       1.1       jtc 		return(0);
    477       1.1       jtc 	/*
    478       1.1       jtc 	 * Ok we have an archive in a regular file. If we were rewriting a
    479       1.1       jtc 	 * file, we must get rid of all the stuff after the current offset
    480       1.1       jtc 	 * (it was not written by pax).
    481       1.1       jtc 	 */
    482       1.1       jtc 	if (((cpos = lseek(arfd, (off_t)0L, SEEK_CUR)) < 0) ||
    483       1.1       jtc 	    (ftruncate(arfd, cpos) < 0)) {
    484       1.1       jtc 		syswarn(1, errno, "Unable to truncate archive file");
    485       1.1       jtc 		return(-1);
    486       1.1       jtc 	}
    487       1.1       jtc 	return(0);
    488       1.1       jtc }
    489       1.1       jtc 
    490       1.1       jtc /*
    491       1.1       jtc  * ar_app_ok()
    492       1.1       jtc  *	check if the last volume in the archive allows appends. We cannot check
    493       1.1       jtc  *	this until we are ready to write since there is no spec that says all
    494       1.1       jtc  *	volumes in a single archive have to be of the same type...
    495       1.1       jtc  * Return:
    496       1.1       jtc  *	0 if we can append, -1 otherwise.
    497       1.1       jtc  */
    498       1.1       jtc 
    499       1.1       jtc #if __STDC__
    500       1.1       jtc int
    501       1.1       jtc ar_app_ok(void)
    502       1.1       jtc #else
    503       1.1       jtc int
    504       1.1       jtc ar_app_ok()
    505       1.1       jtc #endif
    506       1.1       jtc {
    507       1.1       jtc 	if (artyp == ISPIPE) {
    508       1.7  christos 		tty_warn(1,
    509       1.7  christos 		    "Cannot append to an archive obtained from a pipe.");
    510       1.1       jtc 		return(-1);
    511       1.1       jtc 	}
    512       1.1       jtc 
    513       1.1       jtc 	if (!invld_rec)
    514       1.1       jtc 		return(0);
    515       1.7  christos 	tty_warn(1,
    516       1.7  christos 	    "Cannot append, device record size %d does not support %s spec",
    517       1.7  christos 	    rdblksz, argv0);
    518       1.1       jtc 	return(-1);
    519       1.1       jtc }
    520       1.1       jtc 
    521       1.1       jtc /*
    522       1.1       jtc  * ar_read()
    523       1.1       jtc  *	read up to a specified number of bytes from the archive into the
    524       1.1       jtc  *	supplied buffer. When dealing with tapes we may not always be able to
    525       1.1       jtc  *	read what we want.
    526       1.1       jtc  * Return:
    527       1.1       jtc  *	Number of bytes in buffer. 0 for end of file, -1 for a read error.
    528       1.1       jtc  */
    529       1.1       jtc 
    530       1.1       jtc #if __STDC__
    531       1.1       jtc int
    532       1.6       tls ar_read(char *buf, int cnt)
    533       1.1       jtc #else
    534       1.1       jtc int
    535       1.1       jtc ar_read(buf, cnt)
    536       1.6       tls 	char *buf;
    537       1.6       tls 	int cnt;
    538       1.1       jtc #endif
    539       1.1       jtc {
    540       1.6       tls 	int res = 0;
    541       1.1       jtc 
    542       1.1       jtc 	/*
    543       1.1       jtc 	 * if last i/o was in error, no more reads until reset or new volume
    544       1.1       jtc 	 */
    545       1.1       jtc 	if (lstrval <= 0)
    546       1.1       jtc 		return(lstrval);
    547       1.1       jtc 
    548       1.1       jtc 	/*
    549       1.1       jtc 	 * how we read must be based on device type
    550       1.1       jtc 	 */
    551       1.1       jtc 	switch (artyp) {
    552       1.1       jtc 	case ISTAPE:
    553       1.1       jtc 		if ((res = read(arfd, buf, cnt)) > 0) {
    554       1.1       jtc 			/*
    555       1.1       jtc 			 * CAUTION: tape systems may not always return the same
    556       1.1       jtc 			 * sized records so we leave blksz == MAXBLK. The
    557       1.1       jtc 			 * physical record size that a tape drive supports is
    558       1.1       jtc 			 * very hard to determine in a uniform and portable
    559       1.1       jtc 			 * manner.
    560       1.1       jtc 			 */
    561       1.1       jtc 			io_ok = 1;
    562       1.1       jtc 			if (res != rdblksz) {
    563       1.1       jtc 				/*
    564       1.1       jtc 				 * Record size changed. If this is happens on
    565       1.1       jtc 				 * any record after the first, we probably have
    566       1.1       jtc 				 * a tape drive which has a fixed record size
    567       1.1       jtc 				 * we are getting multiple records in a single
    568       1.1       jtc 				 * read). Watch out for record blocking that
    569       1.1       jtc 				 * violates pax spec (must be a multiple of
    570       1.1       jtc 				 * BLKMULT).
    571       1.1       jtc 				 */
    572       1.1       jtc 				rdblksz = res;
    573       1.1       jtc 				if (rdblksz % BLKMULT)
    574       1.1       jtc 					invld_rec = 1;
    575       1.1       jtc 			}
    576       1.1       jtc 			return(res);
    577       1.1       jtc 		}
    578       1.1       jtc 		break;
    579       1.1       jtc 	case ISREG:
    580       1.1       jtc 	case ISBLK:
    581       1.1       jtc 	case ISCHR:
    582       1.1       jtc 	case ISPIPE:
    583       1.1       jtc 	default:
    584       1.1       jtc 		/*
    585       1.1       jtc 		 * Files are so easy to deal with. These other things cannot
    586       1.1       jtc 		 * be trusted at all. So when we are dealing with character
    587       1.1       jtc 		 * devices and pipes we just take what they have ready for us
    588       1.1       jtc 		 * and return. Trying to do anything else with them runs the
    589       1.1       jtc 		 * risk of failure.
    590       1.1       jtc 		 */
    591       1.1       jtc 		if ((res = read(arfd, buf, cnt)) > 0) {
    592       1.1       jtc 			io_ok = 1;
    593       1.1       jtc 			return(res);
    594       1.1       jtc 		}
    595       1.1       jtc 		break;
    596       1.1       jtc 	}
    597       1.1       jtc 
    598       1.1       jtc 	/*
    599       1.1       jtc 	 * We are in trouble at this point, something is broken...
    600       1.1       jtc 	 */
    601       1.1       jtc 	lstrval = res;
    602       1.1       jtc 	if (res < 0)
    603       1.1       jtc 		syswarn(1, errno, "Failed read on archive volume %d", arvol);
    604      1.10        tv 	else if (!is_oldgnutar)
    605       1.7  christos 		tty_warn(0, "End of archive volume %d reached", arvol);
    606       1.1       jtc 	return(res);
    607       1.1       jtc }
    608       1.1       jtc 
    609       1.1       jtc /*
    610       1.1       jtc  * ar_write()
    611       1.1       jtc  *	Write a specified number of bytes in supplied buffer to the archive
    612       1.1       jtc  *	device so it appears as a single "block". Deals with errors and tries
    613       1.1       jtc  *	to recover when faced with short writes.
    614       1.1       jtc  * Return:
    615       1.1       jtc  *	Number of bytes written. 0 indicates end of volume reached and with no
    616       1.1       jtc  *	flaws (as best that can be detected). A -1 indicates an unrecoverable
    617       1.1       jtc  *	error in the archive occured.
    618       1.1       jtc  */
    619       1.1       jtc 
    620       1.1       jtc #if __STDC__
    621       1.1       jtc int
    622       1.6       tls ar_write(char *buf, int bsz)
    623       1.1       jtc #else
    624       1.1       jtc int
    625       1.1       jtc ar_write(buf, bsz)
    626       1.6       tls 	char *buf;
    627       1.6       tls 	int bsz;
    628       1.1       jtc #endif
    629       1.1       jtc {
    630       1.6       tls 	int res;
    631       1.1       jtc 	off_t cpos;
    632       1.1       jtc 
    633       1.1       jtc 	/*
    634       1.1       jtc 	 * do not allow pax to create a "bad" archive. Once a write fails on
    635       1.1       jtc 	 * an archive volume prevent further writes to it.
    636       1.1       jtc 	 */
    637       1.1       jtc 	if (lstrval <= 0)
    638       1.1       jtc 		return(lstrval);
    639       1.1       jtc 
    640       1.1       jtc 	if ((res = write(arfd, buf, bsz)) == bsz) {
    641       1.1       jtc 		wr_trail = 1;
    642       1.1       jtc 		io_ok = 1;
    643       1.1       jtc 		return(bsz);
    644       1.1       jtc 	}
    645       1.1       jtc 	/*
    646       1.1       jtc 	 * write broke, see what we can do with it. We try to send any partial
    647       1.1       jtc 	 * writes that may violate pax spec to the next archive volume.
    648       1.1       jtc 	 */
    649       1.1       jtc 	if (res < 0)
    650       1.1       jtc 		lstrval = res;
    651       1.1       jtc 	else
    652       1.1       jtc 		lstrval = 0;
    653       1.1       jtc 
    654       1.1       jtc 	switch (artyp) {
    655       1.1       jtc 	case ISREG:
    656       1.1       jtc 		if ((res > 0) && (res % BLKMULT)) {
    657       1.1       jtc 			/*
    658       1.1       jtc 		 	 * try to fix up partial writes which are not BLKMULT
    659       1.1       jtc 			 * in size by forcing the runt record to next archive
    660       1.1       jtc 			 * volume
    661       1.1       jtc 		 	 */
    662       1.1       jtc 			if ((cpos = lseek(arfd, (off_t)0L, SEEK_CUR)) < 0)
    663       1.1       jtc 				break;
    664       1.1       jtc 			cpos -= (off_t)res;
    665       1.1       jtc 			if (ftruncate(arfd, cpos) < 0)
    666       1.1       jtc 				break;
    667       1.1       jtc 			res = lstrval = 0;
    668       1.1       jtc 			break;
    669       1.1       jtc 		}
    670       1.1       jtc 		if (res >= 0)
    671       1.1       jtc 			break;
    672       1.1       jtc 		/*
    673       1.1       jtc 		 * if file is out of space, handle it like a return of 0
    674       1.1       jtc 		 */
    675       1.1       jtc 		if ((errno == ENOSPC) || (errno == EFBIG) || (errno == EDQUOT))
    676       1.1       jtc 			res = lstrval = 0;
    677       1.1       jtc 		break;
    678       1.1       jtc 	case ISTAPE:
    679       1.1       jtc 	case ISCHR:
    680       1.1       jtc 	case ISBLK:
    681       1.1       jtc 		if (res >= 0)
    682       1.1       jtc 			break;
    683       1.1       jtc 		if (errno == EACCES) {
    684       1.7  christos 			tty_warn(0,
    685       1.7  christos 			    "Write failed, archive is write protected.");
    686       1.1       jtc 			res = lstrval = 0;
    687       1.1       jtc 			return(0);
    688       1.1       jtc 		}
    689       1.1       jtc 		/*
    690       1.1       jtc 		 * see if we reached the end of media, if so force a change to
    691       1.1       jtc 		 * the next volume
    692       1.1       jtc 		 */
    693       1.1       jtc 		if ((errno == ENOSPC) || (errno == EIO) || (errno == ENXIO))
    694       1.1       jtc 			res = lstrval = 0;
    695       1.1       jtc 		break;
    696       1.1       jtc 	case ISPIPE:
    697       1.1       jtc 	default:
    698       1.1       jtc 		/*
    699       1.1       jtc 		 * we cannot fix errors to these devices
    700       1.1       jtc 		 */
    701       1.1       jtc 		break;
    702       1.1       jtc 	}
    703       1.1       jtc 
    704       1.1       jtc 	/*
    705       1.1       jtc 	 * Better tell the user the bad news...
    706       1.1       jtc 	 * if this is a block aligned archive format, we may have a bad archive
    707       1.1       jtc 	 * if the format wants the header to start at a BLKMULT boundry. While
    708       1.1       jtc 	 * we can deal with the mis-aligned data, it violates spec and other
    709       1.1       jtc 	 * archive readers will likely fail. if the format is not block
    710       1.1       jtc 	 * aligned, the user may be lucky (and the archive is ok).
    711       1.1       jtc 	 */
    712       1.1       jtc 	if (res >= 0) {
    713       1.1       jtc 		if (res > 0)
    714       1.1       jtc 			wr_trail = 1;
    715       1.1       jtc 		io_ok = 1;
    716       1.1       jtc 	}
    717       1.1       jtc 
    718       1.1       jtc 	/*
    719       1.1       jtc 	 * If we were trying to rewrite the trailer and it didn't work, we
    720       1.1       jtc 	 * must quit right away.
    721       1.1       jtc 	 */
    722       1.1       jtc 	if (!wr_trail && (res <= 0)) {
    723       1.7  christos 		tty_warn(1,
    724       1.7  christos 		    "Unable to append, trailer re-write failed. Quitting.");
    725       1.1       jtc 		return(res);
    726       1.1       jtc 	}
    727       1.1       jtc 
    728       1.1       jtc 	if (res == 0)
    729       1.7  christos 		tty_warn(0, "End of archive volume %d reached", arvol);
    730       1.1       jtc 	else if (res < 0)
    731       1.1       jtc 		syswarn(1, errno, "Failed write to archive volume: %d", arvol);
    732       1.1       jtc 	else if (!frmt->blkalgn || ((res % frmt->blkalgn) == 0))
    733       1.7  christos 		tty_warn(0,
    734       1.7  christos 		    "WARNING: partial archive write. Archive MAY BE FLAWED");
    735       1.1       jtc 	else
    736       1.7  christos 		tty_warn(1,"WARNING: partial archive write. Archive IS FLAWED");
    737       1.1       jtc 	return(res);
    738       1.1       jtc }
    739       1.1       jtc 
    740       1.1       jtc /*
    741       1.1       jtc  * ar_rdsync()
    742       1.1       jtc  *	Try to move past a bad spot on a flawed archive as needed to continue
    743       1.1       jtc  *	I/O. Clears error flags to allow I/O to continue.
    744       1.1       jtc  * Return:
    745       1.1       jtc  *	0 when ok to try i/o again, -1 otherwise.
    746       1.1       jtc  */
    747       1.1       jtc 
    748       1.1       jtc #if __STDC__
    749       1.1       jtc int
    750       1.1       jtc ar_rdsync(void)
    751       1.1       jtc #else
    752       1.1       jtc int
    753       1.1       jtc ar_rdsync()
    754       1.1       jtc #endif
    755       1.1       jtc {
    756       1.1       jtc 	long fsbz;
    757       1.1       jtc 	off_t cpos;
    758       1.1       jtc 	off_t mpos;
    759       1.1       jtc         struct mtop mb;
    760       1.1       jtc 
    761       1.1       jtc 	/*
    762       1.1       jtc 	 * Fail resync attempts at user request (done) or this is going to be
    763       1.1       jtc 	 * an update/append to a existing archive. if last i/o hit media end,
    764       1.1       jtc 	 * we need to go to the next volume not try a resync
    765       1.1       jtc 	 */
    766       1.1       jtc 	if ((done > 0) || (lstrval == 0))
    767       1.1       jtc 		return(-1);
    768       1.1       jtc 
    769       1.1       jtc 	if ((act == APPND) || (act == ARCHIVE)) {
    770       1.7  christos 		tty_warn(1, "Cannot allow updates to an archive with flaws.");
    771       1.1       jtc 		return(-1);
    772       1.1       jtc 	}
    773       1.1       jtc 	if (io_ok)
    774       1.1       jtc 		did_io = 1;
    775       1.1       jtc 
    776       1.1       jtc 	switch(artyp) {
    777       1.1       jtc 	case ISTAPE:
    778       1.1       jtc 		/*
    779       1.1       jtc 		 * if the last i/o was a successful data transfer, we assume
    780       1.1       jtc 		 * the fault is just a bad record on the tape that we are now
    781       1.1       jtc 		 * past. If we did not get any data since the last resync try
    782       1.1       jtc 		 * to move the tape foward one PHYSICAL record past any
    783       1.1       jtc 		 * damaged tape section. Some tape drives are stubborn and need
    784       1.1       jtc 		 * to be pushed.
    785       1.1       jtc 		 */
    786       1.1       jtc 		if (io_ok) {
    787       1.1       jtc 			io_ok = 0;
    788       1.1       jtc 			lstrval = 1;
    789       1.1       jtc 			break;
    790       1.1       jtc 		}
    791       1.1       jtc 		mb.mt_op = MTFSR;
    792       1.1       jtc 		mb.mt_count = 1;
    793       1.1       jtc 		if (ioctl(arfd, MTIOCTOP, &mb) < 0)
    794       1.1       jtc 			break;
    795       1.1       jtc 		lstrval = 1;
    796       1.1       jtc 		break;
    797       1.1       jtc 	case ISREG:
    798       1.1       jtc 	case ISCHR:
    799       1.1       jtc 	case ISBLK:
    800       1.1       jtc 		/*
    801       1.1       jtc 		 * try to step over the bad part of the device.
    802       1.1       jtc 		 */
    803       1.1       jtc 		io_ok = 0;
    804       1.1       jtc 		if (((fsbz = arsb.st_blksize) <= 0) || (artyp != ISREG))
    805       1.1       jtc 			fsbz = BLKMULT;
    806       1.1       jtc 		if ((cpos = lseek(arfd, (off_t)0L, SEEK_CUR)) < 0)
    807       1.1       jtc 			break;
    808       1.1       jtc 		mpos = fsbz - (cpos % (off_t)fsbz);
    809       1.1       jtc 		if (lseek(arfd, mpos, SEEK_CUR) < 0)
    810       1.1       jtc 			break;
    811       1.1       jtc 		lstrval = 1;
    812       1.1       jtc 		break;
    813       1.1       jtc 	case ISPIPE:
    814       1.1       jtc 	default:
    815       1.1       jtc 		/*
    816       1.1       jtc 		 * cannot recover on these archive device types
    817       1.1       jtc 		 */
    818       1.1       jtc 		io_ok = 0;
    819       1.1       jtc 		break;
    820       1.1       jtc 	}
    821       1.1       jtc 	if (lstrval <= 0) {
    822       1.7  christos 		tty_warn(1, "Unable to recover from an archive read failure.");
    823       1.1       jtc 		return(-1);
    824       1.1       jtc 	}
    825       1.7  christos 	tty_warn(0, "Attempting to recover from an archive read failure.");
    826       1.1       jtc 	return(0);
    827       1.1       jtc }
    828       1.1       jtc 
    829       1.1       jtc /*
    830       1.1       jtc  * ar_fow()
    831       1.1       jtc  *	Move the I/O position within the archive foward the specified number of
    832       1.1       jtc  *	bytes as supported by the device. If we cannot move the requested
    833       1.1       jtc  *	number of bytes, return the actual number of bytes moved in skipped.
    834       1.1       jtc  * Return:
    835       1.1       jtc  *	0 if moved the requested distance, -1 on complete failure, 1 on
    836       1.1       jtc  *	partial move (the amount moved is in skipped)
    837       1.1       jtc  */
    838       1.1       jtc 
    839       1.1       jtc #if __STDC__
    840       1.1       jtc int
    841       1.1       jtc ar_fow(off_t sksz, off_t *skipped)
    842       1.1       jtc #else
    843       1.1       jtc int
    844       1.1       jtc ar_fow(sksz, skipped)
    845       1.1       jtc 	off_t sksz;
    846       1.1       jtc 	off_t *skipped;
    847       1.1       jtc #endif
    848       1.1       jtc {
    849       1.1       jtc 	off_t cpos;
    850       1.1       jtc 	off_t mpos;
    851       1.1       jtc 
    852       1.1       jtc 	*skipped = 0;
    853       1.1       jtc 	if (sksz <= 0)
    854       1.1       jtc 		return(0);
    855       1.1       jtc 
    856       1.1       jtc 	/*
    857       1.1       jtc 	 * we cannot move foward at EOF or error
    858       1.1       jtc 	 */
    859       1.1       jtc 	if (lstrval <= 0)
    860       1.1       jtc 		return(lstrval);
    861       1.1       jtc 
    862       1.1       jtc 	/*
    863       1.1       jtc 	 * Safer to read forward on devices where it is hard to find the end of
    864       1.1       jtc 	 * the media without reading to it. With tapes we cannot be sure of the
    865       1.1       jtc 	 * number of physical blocks to skip (we do not know physical block
    866       1.1       jtc 	 * size at this point), so we must only read foward on tapes!
    867       1.1       jtc 	 */
    868       1.1       jtc 	if (artyp != ISREG)
    869       1.1       jtc 		return(0);
    870       1.1       jtc 
    871       1.1       jtc 	/*
    872       1.1       jtc 	 * figure out where we are in the archive
    873       1.1       jtc 	 */
    874       1.1       jtc 	if ((cpos = lseek(arfd, (off_t)0L, SEEK_CUR)) >= 0) {
    875       1.1       jtc 		/*
    876       1.1       jtc 	 	 * we can be asked to move farther than there are bytes in this
    877       1.1       jtc 		 * volume, if so, just go to file end and let normal buf_fill()
    878       1.1       jtc 		 * deal with the end of file (it will go to next volume by
    879       1.1       jtc 		 * itself)
    880       1.1       jtc 	 	 */
    881       1.1       jtc 		if ((mpos = cpos + sksz) > arsb.st_size) {
    882       1.1       jtc 			*skipped = arsb.st_size - cpos;
    883       1.1       jtc 			mpos = arsb.st_size;
    884       1.1       jtc 		} else
    885       1.1       jtc 			*skipped = sksz;
    886       1.1       jtc 		if (lseek(arfd, mpos, SEEK_SET) >= 0)
    887       1.1       jtc 			return(0);
    888       1.1       jtc 	}
    889       1.1       jtc 	syswarn(1, errno, "Foward positioning operation on archive failed");
    890       1.1       jtc 	lstrval = -1;
    891       1.1       jtc 	return(-1);
    892       1.1       jtc }
    893       1.1       jtc 
    894       1.1       jtc /*
    895       1.1       jtc  * ar_rev()
    896       1.1       jtc  *	move the i/o position within the archive backwards the specified byte
    897       1.1       jtc  *	count as supported by the device. With tapes drives we RESET rdblksz to
    898       1.1       jtc  *	the PHYSICAL blocksize.
    899       1.1       jtc  *	NOTE: We should only be called to move backwards so we can rewrite the
    900       1.1       jtc  *	last records (the trailer) of an archive (APPEND).
    901       1.1       jtc  * Return:
    902       1.1       jtc  *	0 if moved the requested distance, -1 on complete failure
    903       1.1       jtc  */
    904       1.1       jtc 
    905       1.1       jtc #if __STDC__
    906       1.1       jtc int
    907       1.1       jtc ar_rev(off_t sksz)
    908       1.1       jtc #else
    909       1.1       jtc int
    910       1.1       jtc ar_rev(sksz)
    911       1.1       jtc 	off_t sksz;
    912       1.1       jtc #endif
    913       1.1       jtc {
    914       1.1       jtc 	off_t cpos;
    915       1.1       jtc         struct mtop mb;
    916       1.6       tls 	int phyblk;
    917       1.1       jtc 
    918       1.1       jtc 	/*
    919       1.1       jtc 	 * make sure we do not have try to reverse on a flawed archive
    920       1.1       jtc 	 */
    921       1.1       jtc 	if (lstrval < 0)
    922       1.1       jtc 		return(lstrval);
    923       1.1       jtc 
    924       1.1       jtc 	switch(artyp) {
    925       1.1       jtc 	case ISPIPE:
    926       1.1       jtc 		if (sksz <= 0)
    927       1.1       jtc 			break;
    928       1.1       jtc 		/*
    929       1.1       jtc 		 * cannot go backwards on these critters
    930       1.1       jtc 		 */
    931       1.7  christos 		tty_warn(1, "Reverse positioning on pipes is not supported.");
    932       1.1       jtc 		lstrval = -1;
    933       1.1       jtc 		return(-1);
    934       1.1       jtc 	case ISREG:
    935       1.1       jtc 	case ISBLK:
    936       1.1       jtc 	case ISCHR:
    937       1.1       jtc 	default:
    938       1.1       jtc 		if (sksz <= 0)
    939       1.1       jtc 			break;
    940       1.1       jtc 
    941       1.1       jtc 		/*
    942       1.1       jtc 		 * For things other than files, backwards movement has a very
    943       1.1       jtc 		 * high probability of failure as we really do not know the
    944       1.1       jtc 		 * true attributes of the device we are talking to (the device
    945       1.1       jtc 		 * may not even have the ability to lseek() in any direction).
    946       1.1       jtc 		 * First we figure out where we are in the archive.
    947       1.1       jtc 		 */
    948       1.1       jtc 		if ((cpos = lseek(arfd, (off_t)0L, SEEK_CUR)) < 0) {
    949       1.1       jtc 			syswarn(1, errno,
    950       1.1       jtc 			   "Unable to obtain current archive byte offset");
    951       1.1       jtc 			lstrval = -1;
    952       1.1       jtc 			return(-1);
    953       1.1       jtc 		}
    954       1.1       jtc 
    955       1.1       jtc 		/*
    956       1.1       jtc 		 * we may try to go backwards past the start when the archive
    957       1.1       jtc 		 * is only a single record. If this hapens and we are on a
    958       1.1       jtc 		 * multi volume archive, we need to go to the end of the
    959       1.1       jtc 		 * previous volume and continue our movement backwards from
    960       1.1       jtc 		 * there.
    961       1.1       jtc 		 */
    962       1.1       jtc 		if ((cpos -= sksz) < (off_t)0L) {
    963       1.1       jtc 			if (arvol > 1) {
    964       1.1       jtc 				/*
    965       1.1       jtc 				 * this should never happen
    966       1.1       jtc 				 */
    967       1.7  christos 				tty_warn(1,
    968       1.7  christos 				    "Reverse position on previous volume.");
    969       1.1       jtc 				lstrval = -1;
    970       1.1       jtc 				return(-1);
    971       1.1       jtc 			}
    972       1.1       jtc 			cpos = (off_t)0L;
    973       1.1       jtc 		}
    974       1.1       jtc 		if (lseek(arfd, cpos, SEEK_SET) < 0) {
    975       1.1       jtc 			syswarn(1, errno, "Unable to seek archive backwards");
    976       1.1       jtc 			lstrval = -1;
    977       1.1       jtc 			return(-1);
    978       1.1       jtc 		}
    979       1.1       jtc 		break;
    980       1.1       jtc 	case ISTAPE:
    981       1.1       jtc 		/*
    982       1.1       jtc 	 	 * Calculate and move the proper number of PHYSICAL tape
    983       1.1       jtc 		 * blocks. If the sksz is not an even multiple of the physical
    984       1.1       jtc 		 * tape size, we cannot do the move (this should never happen).
    985       1.1       jtc 		 * (We also cannot handler trailers spread over two vols).
    986       1.1       jtc 		 * get_phys() also makes sure we are in front of the filemark.
    987       1.1       jtc 	 	 */
    988       1.1       jtc 		if ((phyblk = get_phys()) <= 0) {
    989       1.1       jtc 			lstrval = -1;
    990       1.1       jtc 			return(-1);
    991       1.1       jtc 		}
    992       1.1       jtc 
    993       1.1       jtc 		/*
    994       1.1       jtc 		 * make sure future tape reads only go by physical tape block
    995       1.1       jtc 		 * size (set rdblksz to the real size).
    996       1.1       jtc 		 */
    997       1.1       jtc 		rdblksz = phyblk;
    998       1.1       jtc 
    999       1.1       jtc 		/*
   1000       1.1       jtc 		 * if no movement is required, just return (we must be after
   1001       1.1       jtc 		 * get_phys() so the physical blocksize is properly set)
   1002       1.1       jtc 		 */
   1003       1.1       jtc 		if (sksz <= 0)
   1004       1.1       jtc 			break;
   1005       1.1       jtc 
   1006       1.1       jtc 		/*
   1007       1.1       jtc 		 * ok we have to move. Make sure the tape drive can do it.
   1008       1.1       jtc 		 */
   1009       1.1       jtc 		if (sksz % phyblk) {
   1010       1.7  christos 			tty_warn(1,
   1011       1.1       jtc 			    "Tape drive unable to backspace requested amount");
   1012       1.1       jtc 			lstrval = -1;
   1013       1.1       jtc 			return(-1);
   1014       1.1       jtc 		}
   1015       1.1       jtc 
   1016       1.1       jtc 		/*
   1017       1.1       jtc 		 * move backwards the requested number of bytes
   1018       1.1       jtc 		 */
   1019       1.1       jtc 		mb.mt_op = MTBSR;
   1020       1.1       jtc 		mb.mt_count = sksz/phyblk;
   1021       1.1       jtc 		if (ioctl(arfd, MTIOCTOP, &mb) < 0) {
   1022      1.11  christos 			syswarn(1,errno, "Unable to backspace tape %ld blocks.",
   1023      1.11  christos 			    (long) mb.mt_count);
   1024       1.1       jtc 			lstrval = -1;
   1025       1.1       jtc 			return(-1);
   1026       1.1       jtc 		}
   1027       1.1       jtc 		break;
   1028       1.1       jtc 	}
   1029       1.1       jtc 	lstrval = 1;
   1030       1.1       jtc 	return(0);
   1031       1.1       jtc }
   1032       1.1       jtc 
   1033       1.1       jtc /*
   1034       1.1       jtc  * get_phys()
   1035       1.1       jtc  *	Determine the physical block size on a tape drive. We need the physical
   1036       1.1       jtc  *	block size so we know how many bytes we skip over when we move with
   1037       1.1       jtc  *	mtio commands. We also make sure we are BEFORE THE TAPE FILEMARK when
   1038       1.1       jtc  *	return.
   1039       1.1       jtc  *	This is one really SLOW routine...
   1040       1.1       jtc  * Return:
   1041       1.1       jtc  *	physical block size if ok (ok > 0), -1 otherwise
   1042       1.1       jtc  */
   1043       1.1       jtc 
   1044       1.1       jtc #if __STDC__
   1045       1.1       jtc static int
   1046       1.1       jtc get_phys(void)
   1047       1.1       jtc #else
   1048       1.1       jtc static int
   1049       1.1       jtc get_phys()
   1050       1.1       jtc #endif
   1051       1.1       jtc {
   1052       1.6       tls 	int padsz = 0;
   1053       1.6       tls 	int res;
   1054       1.6       tls 	int phyblk;
   1055       1.1       jtc 	struct mtop mb;
   1056       1.1       jtc 	char scbuf[MAXBLK];
   1057       1.1       jtc 
   1058       1.1       jtc 	/*
   1059       1.1       jtc 	 * move to the file mark, and then back up one record and read it.
   1060       1.1       jtc 	 * this should tell us the physical record size the tape is using.
   1061       1.1       jtc 	 */
   1062       1.1       jtc 	if (lstrval == 1) {
   1063       1.1       jtc 		/*
   1064       1.1       jtc 		 * we know we are at file mark when we get back a 0 from
   1065       1.1       jtc 		 * read()
   1066       1.1       jtc 		 */
   1067       1.1       jtc 		while ((res = read(arfd, scbuf, sizeof(scbuf))) > 0)
   1068       1.1       jtc 			padsz += res;
   1069       1.1       jtc 		if (res < 0) {
   1070       1.1       jtc 			syswarn(1, errno, "Unable to locate tape filemark.");
   1071       1.1       jtc 			return(-1);
   1072       1.1       jtc 		}
   1073       1.1       jtc 	}
   1074       1.1       jtc 
   1075       1.1       jtc 	/*
   1076       1.1       jtc 	 * move backwards over the file mark so we are at the end of the
   1077       1.1       jtc 	 * last record.
   1078       1.1       jtc 	 */
   1079       1.1       jtc 	mb.mt_op = MTBSF;
   1080       1.1       jtc 	mb.mt_count = 1;
   1081       1.1       jtc 	if (ioctl(arfd, MTIOCTOP, &mb) < 0) {
   1082       1.1       jtc 		syswarn(1, errno, "Unable to backspace over tape filemark.");
   1083       1.1       jtc 		return(-1);
   1084       1.1       jtc 	}
   1085       1.1       jtc 
   1086       1.1       jtc 	/*
   1087       1.1       jtc 	 * move backwards so we are in front of the last record and read it to
   1088       1.1       jtc 	 * get physical tape blocksize.
   1089       1.1       jtc 	 */
   1090       1.1       jtc 	mb.mt_op = MTBSR;
   1091       1.1       jtc 	mb.mt_count = 1;
   1092       1.1       jtc 	if (ioctl(arfd, MTIOCTOP, &mb) < 0) {
   1093       1.1       jtc 		syswarn(1, errno, "Unable to backspace over last tape block.");
   1094       1.1       jtc 		return(-1);
   1095       1.1       jtc 	}
   1096       1.1       jtc 	if ((phyblk = read(arfd, scbuf, sizeof(scbuf))) <= 0) {
   1097       1.1       jtc 		syswarn(1, errno, "Cannot determine archive tape blocksize.");
   1098       1.1       jtc 		return(-1);
   1099       1.1       jtc 	}
   1100       1.1       jtc 
   1101       1.1       jtc 	/*
   1102       1.1       jtc 	 * read foward to the file mark, then back up in front of the filemark
   1103       1.1       jtc 	 * (this is a bit paranoid, but should be safe to do).
   1104       1.1       jtc 	 */
   1105       1.1       jtc 	while ((res = read(arfd, scbuf, sizeof(scbuf))) > 0)
   1106       1.1       jtc 		;
   1107       1.1       jtc 	if (res < 0) {
   1108       1.1       jtc 		syswarn(1, errno, "Unable to locate tape filemark.");
   1109       1.1       jtc 		return(-1);
   1110       1.1       jtc 	}
   1111       1.1       jtc 	mb.mt_op = MTBSF;
   1112       1.1       jtc 	mb.mt_count = 1;
   1113       1.1       jtc 	if (ioctl(arfd, MTIOCTOP, &mb) < 0) {
   1114       1.1       jtc 		syswarn(1, errno, "Unable to backspace over tape filemark.");
   1115       1.1       jtc 		return(-1);
   1116       1.1       jtc 	}
   1117       1.1       jtc 
   1118       1.1       jtc 	/*
   1119       1.1       jtc 	 * set lstrval so we know that the filemark has not been seen
   1120       1.1       jtc 	 */
   1121       1.1       jtc 	lstrval = 1;
   1122       1.1       jtc 
   1123       1.1       jtc 	/*
   1124       1.1       jtc 	 * return if there was no padding
   1125       1.1       jtc 	 */
   1126       1.1       jtc 	if (padsz == 0)
   1127       1.1       jtc 		return(phyblk);
   1128       1.1       jtc 
   1129       1.1       jtc 	/*
   1130       1.1       jtc 	 * make sure we can move backwards over the padding. (this should
   1131       1.1       jtc 	 * never fail).
   1132       1.1       jtc 	 */
   1133       1.1       jtc 	if (padsz % phyblk) {
   1134       1.7  christos 		tty_warn(1, "Tape drive unable to backspace requested amount");
   1135       1.1       jtc 		return(-1);
   1136       1.1       jtc 	}
   1137       1.1       jtc 
   1138       1.1       jtc 	/*
   1139       1.1       jtc 	 * move backwards over the padding so the head is where it was when
   1140       1.1       jtc 	 * we were first called (if required).
   1141       1.1       jtc 	 */
   1142       1.1       jtc 	mb.mt_op = MTBSR;
   1143       1.1       jtc 	mb.mt_count = padsz/phyblk;
   1144       1.1       jtc 	if (ioctl(arfd, MTIOCTOP, &mb) < 0) {
   1145      1.11  christos 		syswarn(1,errno,"Unable to backspace tape over %ld pad blocks",
   1146      1.11  christos 		    (long)mb.mt_count);
   1147       1.1       jtc 		return(-1);
   1148       1.1       jtc 	}
   1149       1.1       jtc 	return(phyblk);
   1150       1.1       jtc }
   1151       1.1       jtc 
   1152       1.1       jtc /*
   1153       1.1       jtc  * ar_next()
   1154       1.1       jtc  *	prompts the user for the next volume in this archive. For some devices
   1155       1.1       jtc  *	we may allow the media to be changed. Otherwise a new archive is
   1156       1.1       jtc  *	prompted for. By pax spec, if there is no controlling tty or an eof is
   1157       1.1       jtc  *	read on tty input, we must quit pax.
   1158       1.1       jtc  * Return:
   1159       1.1       jtc  *	0 when ready to continue, -1 when all done
   1160       1.1       jtc  */
   1161       1.1       jtc 
   1162       1.1       jtc #if __STDC__
   1163       1.1       jtc int
   1164       1.1       jtc ar_next(void)
   1165       1.1       jtc #else
   1166       1.1       jtc int
   1167       1.1       jtc ar_next()
   1168       1.1       jtc #endif
   1169       1.1       jtc {
   1170       1.1       jtc 	char buf[PAXPATHLEN+2];
   1171       1.1       jtc 	static int freeit = 0;
   1172       1.1       jtc 	sigset_t o_mask;
   1173       1.1       jtc 
   1174       1.1       jtc 	/*
   1175       1.1       jtc 	 * WE MUST CLOSE THE DEVICE. A lot of devices must see last close, (so
   1176       1.1       jtc 	 * things like writing EOF etc will be done) (Watch out ar_close() can
   1177       1.1       jtc 	 * also be called via a signal handler, so we must prevent a race.
   1178       1.1       jtc 	 */
   1179       1.1       jtc 	if (sigprocmask(SIG_BLOCK, &s_mask, &o_mask) < 0)
   1180       1.1       jtc 		syswarn(0, errno, "Unable to set signal mask");
   1181       1.1       jtc 	ar_close();
   1182       1.1       jtc 	if (sigprocmask(SIG_SETMASK, &o_mask, (sigset_t *)NULL) < 0)
   1183       1.1       jtc 		syswarn(0, errno, "Unable to restore signal mask");
   1184       1.1       jtc 
   1185      1.10        tv 	if (done || !wr_trail || is_oldgnutar)
   1186       1.1       jtc 		return(-1);
   1187       1.1       jtc 
   1188       1.1       jtc 	tty_prnt("\nATTENTION! %s archive volume change required.\n", argv0);
   1189       1.1       jtc 
   1190       1.1       jtc 	/*
   1191       1.1       jtc 	 * if i/o is on stdin or stdout, we cannot reopen it (we do not know
   1192       1.1       jtc 	 * the name), the user will be forced to type it in.
   1193       1.1       jtc 	 */
   1194       1.1       jtc 	if (strcmp(arcname, STDO) && strcmp(arcname, STDN) && (artyp != ISREG)
   1195       1.1       jtc 	    && (artyp != ISPIPE)) {
   1196       1.1       jtc 		if (artyp == ISTAPE) {
   1197       1.1       jtc 			tty_prnt("%s ready for archive tape volume: %d\n",
   1198       1.1       jtc 				arcname, arvol);
   1199       1.1       jtc 			tty_prnt("Load the NEXT TAPE on the tape drive");
   1200       1.1       jtc 		} else {
   1201       1.1       jtc 			tty_prnt("%s ready for archive volume: %d\n",
   1202       1.1       jtc 				arcname, arvol);
   1203       1.1       jtc 			tty_prnt("Load the NEXT STORAGE MEDIA (if required)");
   1204       1.1       jtc 		}
   1205       1.1       jtc 
   1206       1.1       jtc 		if ((act == ARCHIVE) || (act == APPND))
   1207       1.1       jtc 			tty_prnt(" and make sure it is WRITE ENABLED.\n");
   1208       1.1       jtc 		else
   1209       1.1       jtc 			tty_prnt("\n");
   1210       1.1       jtc 
   1211       1.1       jtc 		for(;;) {
   1212       1.1       jtc 			tty_prnt("Type \"y\" to continue, \".\" to quit %s,",
   1213       1.1       jtc 				argv0);
   1214       1.1       jtc 			tty_prnt(" or \"s\" to switch to new device.\nIf you");
   1215       1.1       jtc 			tty_prnt(" cannot change storage media, type \"s\"\n");
   1216       1.1       jtc 			tty_prnt("Is the device ready and online? > ");
   1217       1.1       jtc 
   1218       1.1       jtc 			if ((tty_read(buf,sizeof(buf))<0) || !strcmp(buf,".")){
   1219       1.1       jtc 				done = 1;
   1220       1.1       jtc 				lstrval = -1;
   1221       1.1       jtc 				tty_prnt("Quitting %s!\n", argv0);
   1222       1.1       jtc 				vfpart = 0;
   1223       1.1       jtc 				return(-1);
   1224       1.1       jtc 			}
   1225       1.1       jtc 
   1226       1.1       jtc 			if ((buf[0] == '\0') || (buf[1] != '\0')) {
   1227       1.1       jtc 				tty_prnt("%s unknown command, try again\n",buf);
   1228       1.1       jtc 				continue;
   1229       1.1       jtc 			}
   1230       1.1       jtc 
   1231       1.1       jtc 			switch (buf[0]) {
   1232       1.1       jtc 			case 'y':
   1233       1.1       jtc 			case 'Y':
   1234       1.1       jtc 				/*
   1235       1.1       jtc 				 * we are to continue with the same device
   1236       1.1       jtc 				 */
   1237       1.1       jtc 				if (ar_open(arcname) >= 0)
   1238       1.1       jtc 					return(0);
   1239       1.1       jtc 				tty_prnt("Cannot re-open %s, try again\n",
   1240       1.1       jtc 					arcname);
   1241       1.1       jtc 				continue;
   1242       1.1       jtc 			case 's':
   1243       1.1       jtc 			case 'S':
   1244       1.1       jtc 				/*
   1245       1.1       jtc 				 * user wants to open a different device
   1246       1.1       jtc 				 */
   1247       1.1       jtc 				tty_prnt("Switching to a different archive\n");
   1248       1.1       jtc 				break;
   1249       1.1       jtc 			default:
   1250       1.1       jtc 				tty_prnt("%s unknown command, try again\n",buf);
   1251       1.1       jtc 				continue;
   1252       1.1       jtc 			}
   1253       1.1       jtc 			break;
   1254       1.1       jtc 		}
   1255       1.1       jtc 	} else
   1256       1.1       jtc 		tty_prnt("Ready for archive volume: %d\n", arvol);
   1257       1.1       jtc 
   1258       1.1       jtc 	/*
   1259       1.1       jtc 	 * have to go to a different archive
   1260       1.1       jtc 	 */
   1261       1.1       jtc 	for (;;) {
   1262       1.1       jtc 		tty_prnt("Input archive name or \".\" to quit %s.\n", argv0);
   1263       1.1       jtc 		tty_prnt("Archive name > ");
   1264       1.1       jtc 
   1265       1.1       jtc 		if ((tty_read(buf, sizeof(buf)) < 0) || !strcmp(buf, ".")) {
   1266       1.1       jtc 			done = 1;
   1267       1.1       jtc 			lstrval = -1;
   1268       1.1       jtc 			tty_prnt("Quitting %s!\n", argv0);
   1269       1.1       jtc 			vfpart = 0;
   1270       1.1       jtc 			return(-1);
   1271       1.1       jtc 		}
   1272       1.1       jtc 		if (buf[0] == '\0') {
   1273       1.1       jtc 			tty_prnt("Empty file name, try again\n");
   1274       1.1       jtc 			continue;
   1275       1.1       jtc 		}
   1276       1.1       jtc                 if (!strcmp(buf, "..")) {
   1277       1.1       jtc                         tty_prnt("Illegal file name: .. try again\n");
   1278       1.1       jtc                         continue;
   1279       1.1       jtc                 }
   1280       1.1       jtc 		if (strlen(buf) > PAXPATHLEN) {
   1281       1.1       jtc 			tty_prnt("File name too long, try again\n");
   1282       1.1       jtc 			continue;
   1283       1.1       jtc 		}
   1284       1.1       jtc 
   1285       1.1       jtc 		/*
   1286       1.1       jtc 		 * try to open new archive
   1287       1.1       jtc 		 */
   1288       1.1       jtc 		if (ar_open(buf) >= 0) {
   1289       1.1       jtc 			if (freeit) {
   1290       1.9   mycroft 				(void)free((char *)arcname);
   1291       1.1       jtc 				freeit = 0;
   1292       1.1       jtc 			}
   1293       1.1       jtc 			if ((arcname = strdup(buf)) == NULL) {
   1294       1.1       jtc 				done = 1;
   1295       1.1       jtc 				lstrval = -1;
   1296       1.7  christos 				tty_warn(0, "Cannot save archive name.");
   1297       1.1       jtc 				return(-1);
   1298       1.1       jtc 			}
   1299       1.1       jtc 			freeit = 1;
   1300       1.1       jtc 			break;
   1301       1.1       jtc 		}
   1302       1.1       jtc 		tty_prnt("Cannot open %s, try again\n", buf);
   1303       1.1       jtc 		continue;
   1304       1.1       jtc 	}
   1305       1.1       jtc 	return(0);
   1306       1.5       mrg }
   1307       1.5       mrg 
   1308       1.5       mrg /*
   1309       1.5       mrg  * ar_start_gzip()
   1310       1.5       mrg  * starts the gzip compression/decompression process as a child, using magic
   1311       1.5       mrg  * to keep the fd the same in the calling function (parent).
   1312       1.5       mrg  */
   1313       1.5       mrg void
   1314       1.5       mrg #ifdef __STDC__
   1315       1.5       mrg ar_start_gzip(int fd)
   1316       1.5       mrg #else
   1317       1.5       mrg ar_start_gzip(fd)
   1318       1.5       mrg 	int fd;
   1319       1.5       mrg #endif
   1320       1.5       mrg {
   1321       1.5       mrg 	pid_t pid;
   1322       1.5       mrg 	int fds[2];
   1323       1.5       mrg 	char *gzip_flags;
   1324       1.5       mrg 
   1325       1.5       mrg 	if (pipe(fds) < 0)
   1326       1.5       mrg 		err(1, "could not pipe");
   1327       1.5       mrg 	pid = fork();
   1328       1.5       mrg 	if (pid < 0)
   1329       1.5       mrg 		err(1, "could not fork");
   1330       1.5       mrg 
   1331       1.5       mrg 	/* parent */
   1332       1.5       mrg 	if (pid) {
   1333       1.5       mrg 		switch (act) {
   1334       1.5       mrg 		case ARCHIVE:
   1335       1.5       mrg 			dup2(fds[1], fd);
   1336       1.5       mrg 			break;
   1337       1.5       mrg 		case LIST:
   1338       1.5       mrg 		case EXTRACT:
   1339       1.5       mrg 			dup2(fds[0], fd);
   1340       1.5       mrg 			break;
   1341       1.5       mrg 		default:
   1342       1.5       mrg 			errx(1, "ar_start_gzip:  impossible");
   1343       1.5       mrg 		}
   1344       1.5       mrg 		close(fds[0]);
   1345       1.5       mrg 		close(fds[1]);
   1346       1.5       mrg 	} else {
   1347       1.5       mrg 		switch (act) {
   1348       1.5       mrg 		case ARCHIVE:
   1349       1.5       mrg 			dup2(fds[0], STDIN_FILENO);
   1350       1.5       mrg 			dup2(fd, STDOUT_FILENO);
   1351       1.5       mrg 			gzip_flags = "-c";
   1352       1.5       mrg 			break;
   1353       1.5       mrg 		case LIST:
   1354       1.5       mrg 		case EXTRACT:
   1355       1.5       mrg 			dup2(fds[1], STDOUT_FILENO);
   1356       1.5       mrg 			dup2(fd, STDIN_FILENO);
   1357       1.5       mrg 			gzip_flags = "-dc";
   1358       1.5       mrg 			break;
   1359       1.5       mrg 		default:
   1360       1.5       mrg 			errx(1, "ar_start_gzip:  impossible");
   1361       1.5       mrg 		}
   1362       1.5       mrg 		close(fds[0]);
   1363       1.5       mrg 		close(fds[1]);
   1364       1.5       mrg 		if (execlp(gzip_program, gzip_program, gzip_flags, NULL) < 0)
   1365       1.5       mrg 			err(1, "could not exec");
   1366       1.5       mrg 		/* NOTREACHED */
   1367       1.5       mrg 	}
   1368      1.13  christos }
   1369      1.13  christos 
   1370      1.13  christos static const char *
   1371      1.13  christos timefmt(buf, size, sz, tm)
   1372      1.13  christos 	char *buf;
   1373      1.13  christos 	size_t size;
   1374      1.13  christos 	off_t sz;
   1375      1.13  christos 	time_t tm;
   1376      1.13  christos {
   1377      1.13  christos #ifdef NET2_STAT
   1378      1.13  christos 	(void)snprintf(buf, size, "%lu secs (%lu bytes/sec)",
   1379      1.13  christos 	    (unsigned long)tm, (unsigned long)(sz / tm));
   1380      1.13  christos #else
   1381      1.13  christos 	(void)snprintf(buf, size, "%lu secs (%llu bytes/sec)",
   1382      1.13  christos 	    (unsigned long)tm, (unsigned long long)(sz / tm));
   1383      1.13  christos #endif
   1384      1.13  christos 	return buf;
   1385      1.13  christos }
   1386      1.13  christos 
   1387      1.13  christos static const char *
   1388      1.13  christos sizefmt(buf, size, sz)
   1389      1.13  christos 	char *buf;
   1390      1.13  christos 	size_t size;
   1391      1.13  christos 	off_t sz;
   1392      1.13  christos {
   1393      1.13  christos #ifdef NET2_STAT
   1394      1.13  christos 	(void)snprintf(buf, size, "%lu bytes", (unsigned long)sz);
   1395      1.13  christos #else
   1396      1.13  christos 	(void)snprintf(buf, size, "%llu bytes", (unsigned long long)sz);
   1397      1.13  christos #endif
   1398      1.13  christos 	return buf;
   1399      1.13  christos }
   1400      1.13  christos 
   1401      1.13  christos #if __STDC__
   1402      1.13  christos void
   1403      1.13  christos ar_summary(int n)
   1404      1.13  christos #else
   1405      1.13  christos void
   1406      1.13  christos ar_summary(n)
   1407      1.13  christos 	int n;
   1408      1.13  christos #endif
   1409      1.13  christos {
   1410      1.13  christos 	time_t secs;
   1411      1.13  christos 	int len;
   1412      1.13  christos 	char buf[MAXPATHLEN];
   1413      1.13  christos 	char tbuf[MAXPATHLEN/4];
   1414      1.13  christos 	char s1buf[MAXPATHLEN/8];
   1415      1.13  christos 	char s2buf[MAXPATHLEN/8];
   1416      1.13  christos 	FILE *outf;
   1417      1.13  christos 
   1418      1.13  christos 	if (act == LIST)
   1419      1.13  christos 		outf = stdout;
   1420      1.13  christos 	else
   1421      1.13  christos 		outf = stderr;
   1422      1.13  christos 
   1423      1.13  christos 	/*
   1424      1.13  christos 	 * If we are called from a signal (n != 0), use snprintf(3) so that we
   1425      1.13  christos 	 * don't reenter stdio(3).
   1426      1.13  christos 	 */
   1427      1.13  christos 	(void)time(&secs);
   1428      1.13  christos 	if ((secs -= starttime) == 0)
   1429      1.13  christos 		secs = 1;
   1430      1.13  christos 
   1431      1.13  christos 	/*
   1432      1.13  christos 	 * If we have not determined the format yet, we just say how many bytes
   1433      1.13  christos 	 * we have skipped over looking for a header to id. there is no way we
   1434      1.13  christos 	 * could have written anything yet.
   1435      1.13  christos 	 */
   1436      1.13  christos 	if (frmt == NULL) {
   1437      1.13  christos 		len = snprintf(buf, sizeof(buf),
   1438      1.13  christos 		    "unknown format, %s skipped in %s\n",
   1439      1.13  christos 		    sizefmt(s1buf, sizeof(s1buf), rdcnt),
   1440      1.13  christos 		    timefmt(tbuf, sizeof(tbuf), rdcnt, secs));
   1441      1.13  christos 		if (n == 0)
   1442      1.13  christos 			(void)fprintf(outf, "%s: %s", argv0, buf);
   1443      1.13  christos 		else
   1444      1.13  christos 			(void)write(STDERR_FILENO, buf, len);
   1445      1.13  christos 		return;
   1446      1.13  christos 	}
   1447      1.13  christos 
   1448      1.13  christos 
   1449      1.13  christos 	if (n != 0) {
   1450      1.13  christos 		len = snprintf(buf, sizeof(buf), "Working on `%s' (%s)\n",
   1451      1.13  christos 		    archd.name, sizefmt(s1buf, sizeof(s1buf), archd.sb.st_size));
   1452      1.13  christos 		(void)write(STDERR_FILENO, buf, len);
   1453      1.13  christos 	}
   1454      1.13  christos 
   1455      1.13  christos 
   1456      1.13  christos 	len = snprintf(buf, sizeof(buf),
   1457      1.13  christos 	    "%s vol %d, %lu files, %s read, %s written in %s\n",
   1458      1.13  christos 	    frmt->name, arvol-1, (unsigned long)flcnt,
   1459      1.13  christos 	    sizefmt(s1buf, sizeof(s1buf), rdcnt),
   1460      1.13  christos 	    sizefmt(s2buf, sizeof(s2buf), wrcnt),
   1461      1.13  christos 	    timefmt(tbuf, sizeof(tbuf), rdcnt + wrcnt, secs));
   1462      1.13  christos 	if (n == 0)
   1463      1.13  christos 		(void)fprintf(outf, "%s: %s", argv0, buf);
   1464      1.13  christos 	else
   1465      1.13  christos 		(void)write(STDERR_FILENO, buf, strlen(buf));
   1466  1.13.4.1  wrstuden }
   1467  1.13.4.1  wrstuden 
   1468  1.13.4.1  wrstuden /*
   1469  1.13.4.1  wrstuden  * ar_dochdir(name)
   1470  1.13.4.1  wrstuden  *	change directory to name, and remember where we came from and
   1471  1.13.4.1  wrstuden  *	where we change to (for ar_open).
   1472  1.13.4.1  wrstuden  *
   1473  1.13.4.1  wrstuden  *	Maybe we could try to be smart and only do the actual chdir
   1474  1.13.4.1  wrstuden  *	when necessary to write a file read from the archive, but this
   1475  1.13.4.1  wrstuden  *	is not easy to get right given the pax code structure.
   1476  1.13.4.1  wrstuden  *
   1477  1.13.4.1  wrstuden  *	Be sure to not leak descriptors!
   1478  1.13.4.1  wrstuden  *
   1479  1.13.4.1  wrstuden  *	We are called N * M times when extracting, and N times when
   1480  1.13.4.1  wrstuden  *	writing archives, where
   1481  1.13.4.1  wrstuden  *	N:	number of -C options
   1482  1.13.4.1  wrstuden  *	M:	number of files in archive
   1483  1.13.4.1  wrstuden  *
   1484  1.13.4.1  wrstuden  * Returns 0 if all went well, else -1.
   1485  1.13.4.1  wrstuden  */
   1486  1.13.4.1  wrstuden 
   1487  1.13.4.1  wrstuden #ifdef __STDC__
   1488  1.13.4.1  wrstuden int
   1489  1.13.4.1  wrstuden ar_dochdir(char *name)
   1490  1.13.4.1  wrstuden #else
   1491  1.13.4.1  wrstuden int
   1492  1.13.4.1  wrstuden ar_dochdir(name)
   1493  1.13.4.1  wrstuden 	char *name;
   1494  1.13.4.1  wrstuden #endif
   1495  1.13.4.1  wrstuden {
   1496  1.13.4.1  wrstuden 	if (curdirfd == -1) {
   1497  1.13.4.1  wrstuden 		/* first time. remember where we came from */
   1498  1.13.4.1  wrstuden 		curdirfd = open(".", O_RDONLY);
   1499  1.13.4.1  wrstuden 		if (curdirfd < 0) {
   1500  1.13.4.1  wrstuden 			syswarn(0, errno, "failed to open directory .");
   1501  1.13.4.1  wrstuden 			return (-1);
   1502  1.13.4.1  wrstuden 		}
   1503  1.13.4.1  wrstuden 	} else /* XXX if (*name != '/') XXX */ {
   1504  1.13.4.1  wrstuden 		/*
   1505  1.13.4.1  wrstuden 		 * relative chdir. Make sure to get the same directory
   1506  1.13.4.1  wrstuden 		 * each time by fchdir-ing back first.
   1507  1.13.4.1  wrstuden 		 */
   1508  1.13.4.1  wrstuden 		fchdir(curdirfd);
   1509  1.13.4.1  wrstuden 	}
   1510  1.13.4.1  wrstuden 
   1511  1.13.4.1  wrstuden 	if (minusCfd != -1) {
   1512  1.13.4.1  wrstuden 		/* don't leak descriptors */
   1513  1.13.4.1  wrstuden 		close(minusCfd);
   1514  1.13.4.1  wrstuden 		minusCfd = -1;
   1515  1.13.4.1  wrstuden 	}
   1516  1.13.4.1  wrstuden 
   1517  1.13.4.1  wrstuden 	minusCfd = open(name, O_RDONLY);
   1518  1.13.4.1  wrstuden 	if (minusCfd < 0) {
   1519  1.13.4.1  wrstuden 		syswarn(0, errno, "failed to open directory %s", name);
   1520  1.13.4.1  wrstuden 		return (-1);
   1521  1.13.4.1  wrstuden 	}
   1522  1.13.4.1  wrstuden 
   1523  1.13.4.1  wrstuden 	fchdir(minusCfd);
   1524  1.13.4.1  wrstuden 	return (0);
   1525       1.1       jtc }
   1526