diff options
-rw-r--r-- | bin/pax/Makefile | 8 | ||||
-rw-r--r-- | bin/pax/ar_io.c | 419 | ||||
-rw-r--r-- | bin/pax/extern.h | 3 | ||||
-rw-r--r-- | bin/pax/options.c | 16 | ||||
-rw-r--r-- | bin/pax/pax.h | 8 |
5 files changed, 205 insertions, 249 deletions
diff --git a/bin/pax/Makefile b/bin/pax/Makefile index 0a8a8ed091d..ebaa9f8d900 100644 --- a/bin/pax/Makefile +++ b/bin/pax/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.4 1996/09/22 20:09:52 tholo Exp $ +# $OpenBSD: Makefile,v 1.5 1996/12/09 12:00:13 deraadt Exp $ # $NetBSD: Makefile,v 1.4 1995/03/21 09:07:02 cgd Exp $ # To install on versions prior to BSD 4.4 the following may have to be @@ -28,12 +28,8 @@ PROG= pax SRCS= ar_io.c ar_subs.c buf_subs.c cache.c cpio.c file_subs.c ftree.c\ gen_subs.c getoldopt.c options.c pat_rep.c pax.c sel_subs.c tables.c\ - tar.c tty_subs.c zopen.c -LDADD+= -lz -DPADD+= ${LIBZ} + tar.c tty_subs.c MAN= pax.1 tar.1 LINKS= ${BINDIR}/pax ${BINDIR}/tar -.PATH: ${.CURDIR}/../../usr.bin/compress - .include <bsd.prog.mk> diff --git a/bin/pax/ar_io.c b/bin/pax/ar_io.c index 3573f7c021b..aff14dcfe10 100644 --- a/bin/pax/ar_io.c +++ b/bin/pax/ar_io.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ar_io.c,v 1.7 1996/11/24 18:15:59 millert Exp $ */ +/* $OpenBSD: ar_io.c,v 1.8 1996/12/09 12:00:13 deraadt Exp $ */ /* $NetBSD: ar_io.c,v 1.5 1996/03/26 23:54:13 mrg Exp $ */ /*- @@ -42,7 +42,7 @@ #if 0 static char sccsid[] = "@(#)ar_io.c 8.2 (Berkeley) 4/18/94"; #else -static char rcsid[] = "$OpenBSD: ar_io.c,v 1.7 1996/11/24 18:15:59 millert Exp $"; +static char rcsid[] = "$OpenBSD: ar_io.c,v 1.8 1996/12/09 12:00:13 deraadt Exp $"; #endif #endif /* not lint */ @@ -60,7 +60,6 @@ static char rcsid[] = "$OpenBSD: ar_io.c,v 1.7 1996/11/24 18:15:59 millert Exp $ #include <errno.h> #include <stdlib.h> #include <err.h> -#include <zlib.h> #include "pax.h" #include "extern.h" @@ -85,13 +84,12 @@ static struct stat arsb; /* stat of archive device at open */ static int invld_rec; /* tape has out of spec record size */ static int wr_trail = 1; /* trailer was rewritten in append */ static int can_unlnk = 0; /* do we unlink null archives? */ -static gzFile gzf; /* file pointer for gzip archives */ -static FILE *cfp; /* file pointer for compress archives */ char *arcname; /* printable name of archive */ +char *gzip_program; /* name of gzip program */ -FILE *zdopen __P((int, const char *)); static int get_phys __P((void)); extern sigset_t s_mask; +static void ar_start_gzip __P((int)); /* * ar_open() @@ -113,14 +111,8 @@ ar_open(name) { struct mtget mb; - if (arfd != -1) { - if (zflag == GZIP_CMP) - (void)gzclose(gzf); - else if (zflag == COMPRESS_CMP) - (void)fclose(cfp); - else - (void)close(arfd); - } + if (arfd != -1) + (void)close(arfd); arfd = -1; can_unlnk = did_io = io_ok = invld_rec = 0; artyp = ISREG; @@ -137,15 +129,8 @@ ar_open(name) arcname = STDN; } else if ((arfd = open(name, EXT_MODE, DMOD)) < 0) syswarn(0, errno, "Failed open to read on %s", name); - if (zflag == GZIP_CMP) { - gzf = gzdopen(arfd, "r"); - if (gzf && !gz_iszipped(gzf)) { - (void)lseek(arfd, 0, SEEK_SET); - zflag = COMPRESS_CMP; - } - } - if (zflag == COMPRESS_CMP) - cfp = zdopen(arfd, "r"); + if (zflag) + ar_start_gzip(arfd); break; case ARCHIVE: if (name == NULL) { @@ -155,14 +140,12 @@ ar_open(name) syswarn(0, errno, "Failed open to write on %s", name); else can_unlnk = 1; - if (zflag == GZIP_CMP) - gzf = gzdopen(arfd, "w"); - else if (zflag == COMPRESS_CMP) - cfp = zdopen(arfd, "w"); + if (zflag) + ar_start_gzip(arfd); break; case APPND: if (zflag) - err(1, "can not compress while appending"); + err(1, "can not gzip while appending"); if (name == NULL) { arfd = STDOUT_FILENO; arcname = STDO; @@ -186,12 +169,7 @@ ar_open(name) */ if (fstat(arfd, &arsb) < 0) { syswarn(0, errno, "Failed stat on %s", arcname); - if (zflag == GZIP_CMP) - (void)gzclose(gzf); - else if (zflag == COMPRESS_CMP) - (void)fclose(cfp); - else - (void)close(arfd); + (void)close(arfd); arfd = -1; can_unlnk = 0; return(-1); @@ -199,12 +177,7 @@ ar_open(name) if (S_ISDIR(arsb.st_mode)) { paxwarn(0, "Cannot write an archive on top of a directory %s", arcname); - if (zflag == GZIP_CMP) - (void)gzclose(gzf); - else if (zflag == COMPRESS_CMP) - (void)fclose(cfp); - else - (void)close(arfd); + (void)close(arfd); arfd = -1; can_unlnk = 0; return(-1); @@ -376,12 +349,7 @@ ar_close() can_unlnk = 0; } - if (zflag == GZIP_CMP) - (void)gzclose(gzf); - else if (zflag == COMPRESS_CMP) - (void)fclose(cfp); - else - (void)close(arfd); + (void)close(arfd); if (vflag && (artyp == ISTAPE)) { (void)fputs("done.\n", outf); @@ -473,18 +441,8 @@ ar_drain() /* * keep reading until pipe is drained */ - if (zflag == GZIP_CMP) { - while ((res = gzread(gzf, drbuf, sizeof(drbuf))) > 0) - ; - } - else if (zflag == COMPRESS_CMP) { - while ((res = fread(drbuf, 1, sizeof(drbuf), cfp)) > 0) - ; - } - else { - while ((res = read(arfd, drbuf, sizeof(drbuf))) > 0) - ; - } + while ((res = read(arfd, drbuf, sizeof(drbuf))) > 0) + ; lstrval = res; } @@ -554,11 +512,6 @@ ar_app_ok() return(-1); } - if (zflag) { - paxwarn(1, "Cannot append to a compressed archive."); - return(-1); - } - if (!invld_rec) return(0); paxwarn(1,"Cannot append, device record size %d does not support %s spec", @@ -598,34 +551,32 @@ ar_read(buf, cnt) */ switch (artyp) { case ISTAPE: - if (!zflag) { - if ((res = read(arfd, buf, cnt)) > 0) { + if ((res = read(arfd, buf, cnt)) > 0) { + /* + * CAUTION: tape systems may not always return the same + * sized records so we leave blksz == MAXBLK. The + * physical record size that a tape drive supports is + * very hard to determine in a uniform and portable + * manner. + */ + io_ok = 1; + if (res != rdblksz) { /* - * CAUTION: tape systems may not always return the same - * sized records so we leave blksz == MAXBLK. The - * physical record size that a tape drive supports is - * very hard to determine in a uniform and portable - * manner. + * Record size changed. If this is happens on + * any record after the first, we probably have + * a tape drive which has a fixed record size + * we are getting multiple records in a single + * read). Watch out for record blocking that + * violates pax spec (must be a multiple of + * BLKMULT). */ - io_ok = 1; - if (res != rdblksz) { - /* - * Record size changed. If this is happens on - * any record after the first, we probably have - * a tape drive which has a fixed record size - * we are getting multiple records in a single - * read). Watch out for record blocking that - * violates pax spec (must be a multiple of - * BLKMULT). - */ - rdblksz = res; - if (rdblksz % BLKMULT) - invld_rec = 1; - } - return(res); + rdblksz = res; + if (rdblksz % BLKMULT) + invld_rec = 1; } - break; + return(res); } + break; case ISREG: case ISBLK: case ISCHR: @@ -638,23 +589,9 @@ ar_read(buf, cnt) * and return. Trying to do anything else with them runs the * risk of failure. */ - if (zflag == GZIP_CMP) { - if ((res = gzread(gzf, buf, cnt)) > 0) { - io_ok = 1; - return(res); - } - } - else if (zflag == COMPRESS_CMP) { - if ((res = fread(buf, 1, cnt, cfp)) > 0) { - io_ok = 1; - return(res); - } - } - else { - if ((res = read(arfd, buf, cnt)) > 0) { - io_ok = 1; - return(res); - } + if ((res = read(arfd, buf, cnt)) > 0) { + io_ok = 1; + return(res); } break; } @@ -701,26 +638,10 @@ ar_write(buf, bsz) if (lstrval <= 0) return(lstrval); - if (zflag == GZIP_CMP) { - if ((res = gzwrite(gzf, buf, bsz)) == bsz) { - wr_trail = 1; - io_ok = 1; - return(bsz); - } - } - else if (zflag == COMPRESS_CMP) { - if ((res = fwrite(buf, 1, bsz, cfp)) == bsz) { - wr_trail = 1; - io_ok = 1; - return(bsz); - } - } - else { - if ((res = write(arfd, buf, bsz)) == bsz) { - wr_trail = 1; - io_ok = 1; - return(bsz); - } + if ((res = write(arfd, buf, bsz)) == bsz) { + wr_trail = 1; + io_ok = 1; + return(bsz); } /* * write broke, see what we can do with it. We try to send any partial @@ -731,55 +652,53 @@ ar_write(buf, bsz) else lstrval = 0; - if (!zflag) { - switch (artyp) { - case ISREG: - if ((res > 0) && (res % BLKMULT)) { - /* - * try to fix up partial writes which are not BLKMULT - * in size by forcing the runt record to next archive - * volume - */ - if ((cpos = lseek(arfd, (off_t)0L, SEEK_CUR)) < 0) - break; - cpos -= (off_t)res; - if (ftruncate(arfd, cpos) < 0) - break; - res = lstrval = 0; + switch (artyp) { + case ISREG: + if ((res > 0) && (res % BLKMULT)) { + /* + * try to fix up partial writes which are not BLKMULT + * in size by forcing the runt record to next archive + * volume + */ + if ((cpos = lseek(arfd, (off_t)0L, SEEK_CUR)) < 0) break; - } - if (res >= 0) + cpos -= (off_t)res; + if (ftruncate(arfd, cpos) < 0) break; - /* - * if file is out of space, handle it like a return of 0 - */ - if ((errno == ENOSPC) || (errno == EFBIG) || (errno == EDQUOT)) - res = lstrval = 0; + res = lstrval = 0; break; - case ISTAPE: - case ISCHR: - case ISBLK: - if (res >= 0) - break; - if (errno == EACCES) { - paxwarn(0, "Write failed, archive is write protected."); - res = lstrval = 0; - return(0); - } - /* - * see if we reached the end of media, if so force a change to - * the next volume - */ - if ((errno == ENOSPC) || (errno == EIO) || (errno == ENXIO)) - res = lstrval = 0; + } + if (res >= 0) break; - case ISPIPE: - default: - /* - * we cannot fix errors to these devices - */ + /* + * if file is out of space, handle it like a return of 0 + */ + if ((errno == ENOSPC) || (errno == EFBIG) || (errno == EDQUOT)) + res = lstrval = 0; + break; + case ISTAPE: + case ISCHR: + case ISBLK: + if (res >= 0) break; + if (errno == EACCES) { + paxwarn(0, "Write failed, archive is write protected."); + res = lstrval = 0; + return(0); } + /* + * see if we reached the end of media, if so force a change to + * the next volume + */ + if ((errno == ENOSPC) || (errno == EIO) || (errno == ENXIO)) + res = lstrval = 0; + break; + case ISPIPE: + default: + /* + * we cannot fix errors to these devices + */ + break; } /* @@ -852,54 +771,50 @@ ar_rdsync() if (io_ok) did_io = 1; - if (zflag) - io_ok = 0; - else { - switch(artyp) { - case ISTAPE: - /* - * if the last i/o was a successful data transfer, we assume - * the fault is just a bad record on the tape that we are now - * past. If we did not get any data since the last resync try - * to move the tape foward one PHYSICAL record past any - * damaged tape section. Some tape drives are stubborn and need - * to be pushed. - */ - if (io_ok) { - io_ok = 0; - lstrval = 1; - break; - } - mb.mt_op = MTFSR; - mb.mt_count = 1; - if (ioctl(arfd, MTIOCTOP, &mb) < 0) - break; - lstrval = 1; - break; - case ISREG: - case ISCHR: - case ISBLK: - /* - * try to step over the bad part of the device. - */ + switch(artyp) { + case ISTAPE: + /* + * if the last i/o was a successful data transfer, we assume + * the fault is just a bad record on the tape that we are now + * past. If we did not get any data since the last resync try + * to move the tape foward one PHYSICAL record past any + * damaged tape section. Some tape drives are stubborn and need + * to be pushed. + */ + if (io_ok) { io_ok = 0; - if (((fsbz = arsb.st_blksize) <= 0) || (artyp != ISREG)) - fsbz = BLKMULT; - if ((cpos = lseek(arfd, (off_t)0L, SEEK_CUR)) < 0) - break; - mpos = fsbz - (cpos % (off_t)fsbz); - if (lseek(arfd, mpos, SEEK_CUR) < 0) - break; lstrval = 1; break; - case ISPIPE: - default: - /* - * cannot recover on these archive device types - */ - io_ok = 0; - break; } + mb.mt_op = MTFSR; + mb.mt_count = 1; + if (ioctl(arfd, MTIOCTOP, &mb) < 0) + break; + lstrval = 1; + break; + case ISREG: + case ISCHR: + case ISBLK: + /* + * try to step over the bad part of the device. + */ + io_ok = 0; + if (((fsbz = arsb.st_blksize) <= 0) || (artyp != ISREG)) + fsbz = BLKMULT; + if ((cpos = lseek(arfd, (off_t)0L, SEEK_CUR)) < 0) + break; + mpos = fsbz - (cpos % (off_t)fsbz); + if (lseek(arfd, mpos, SEEK_CUR) < 0) + break; + lstrval = 1; + break; + case ISPIPE: + default: + /* + * cannot recover on these archive device types + */ + io_ok = 0; + break; } if (lstrval <= 0) { paxwarn(1, "Unable to recover from an archive read failure."); @@ -933,7 +848,7 @@ ar_fow(sksz, skipped) off_t mpos; *skipped = 0; - if (zflag || sksz <= 0) + if (sksz <= 0) return(0); /* @@ -1004,19 +919,6 @@ ar_rev(sksz) if (lstrval < 0) return(lstrval); - if (zflag) { - if (sksz <= 0) { - lstrval = 1; - return 0; - } - /* - * cannot go backwards on these critters - */ - paxwarn(1, "Reverse positioning on pipes is not supported."); - lstrval = -1; - return(-1); - } - switch(artyp) { case ISPIPE: if (sksz <= 0) @@ -1150,11 +1052,6 @@ get_phys() struct mtop mb; char scbuf[MAXBLK]; - if (zflag) { - syswarn(1, errno, "Cannot determine archive tape blocksize."); - return(-1); - } - /* * move to the file mark, and then back up one record and read it. * this should tell us the physical record size the tape is using. @@ -1404,3 +1301,65 @@ ar_next() } return(0); } + +/* + * ar_start_gzip() + * starts the gzip compression/decompression process as a child, using magic + * to keep the fd the same in the calling function (parent). + */ +void +#ifdef __STDC__ +ar_start_gzip(int fd) +#else +ar_start_gzip(fd) + int fd; +#endif +{ + pid_t pid; + int fds[2]; + char *gzip_flags; + + if (pipe(fds) < 0) + err(1, "could not pipe"); + pid = fork(); + if (pid < 0) + err(1, "could not fork"); + + /* parent */ + if (pid) { + switch (act) { + case ARCHIVE: + dup2(fds[1], fd); + break; + case LIST: + case EXTRACT: + dup2(fds[0], fd); + break; + default: + errx(1, "ar_start_gzip: impossible"); + } + close(fds[0]); + close(fds[1]); + } else { + switch (act) { + case ARCHIVE: + dup2(fds[0], STDIN_FILENO); + dup2(fd, STDOUT_FILENO); + gzip_flags = "-c"; + break; + case LIST: + case EXTRACT: + dup2(fds[1], STDOUT_FILENO); + dup2(fd, STDIN_FILENO); + gzip_flags = "-dc"; + break; + default: + errx(1, "ar_start_gzip: impossible"); + } + close(fds[0]); + close(fds[1]); + if (execlp(gzip_program, gzip_program, gzip_flags, NULL) < 0) + err(1, "could not exec"); + /* NOTREACHED */ + } +} diff --git a/bin/pax/extern.h b/bin/pax/extern.h index b6f42b67eb2..908c5626ba1 100644 --- a/bin/pax/extern.h +++ b/bin/pax/extern.h @@ -1,4 +1,4 @@ -/* $OpenBSD: extern.h,v 1.6 1996/10/27 06:45:10 downsj Exp $ */ +/* $OpenBSD: extern.h,v 1.7 1996/12/09 12:00:14 deraadt Exp $ */ /* $NetBSD: extern.h,v 1.5 1996/03/26 23:54:16 mrg Exp $ */ /*- @@ -50,6 +50,7 @@ * ar_io.c */ extern char *arcname; +extern char *gzip_program; int ar_open __P((char *)); void ar_close __P((void)); void ar_drain __P((void)); diff --git a/bin/pax/options.c b/bin/pax/options.c index f23419b3bae..4bdffe20d88 100644 --- a/bin/pax/options.c +++ b/bin/pax/options.c @@ -1,4 +1,4 @@ -/* $OpenBSD: options.c,v 1.10 1996/10/27 06:45:12 downsj Exp $ */ +/* $OpenBSD: options.c,v 1.11 1996/12/09 12:00:15 deraadt Exp $ */ /* $NetBSD: options.c,v 1.6 1996/03/26 23:54:18 mrg Exp $ */ /*- @@ -42,7 +42,7 @@ #if 0 static char sccsid[] = "@(#)options.c 8.2 (Berkeley) 4/18/94"; #else -static char rcsid[] = "$OpenBSD: options.c,v 1.10 1996/10/27 06:45:12 downsj Exp $"; +static char rcsid[] = "$OpenBSD: options.c,v 1.11 1996/12/09 12:00:15 deraadt Exp $"; #endif #endif /* not lint */ @@ -84,6 +84,9 @@ static void cpio_options __P((register int, register char **)); static void cpio_usage __P((void)); #endif +#define GZIP_CMD "gzip" /* command to run as gzip */ +#define COMPRESS_CMD "compress" /* command to run as compress */ + /* * Format specific routine table - MUST BE IN SORTED ORDER BY NAME * (see pax.h for description of each function) @@ -388,7 +391,8 @@ pax_options(argc, argv) /* * use gzip. Non standard option. */ - zflag = GZIP_CMP; + zflag = 1; + gzip_program = GZIP_CMD; break; case 'B': /* @@ -701,7 +705,8 @@ tar_options(argc, argv) /* * use gzip. Non standard option. */ - zflag = GZIP_CMP; + zflag = 1; + gzip_program = GZIP_CMD; break; case 'B': /* @@ -739,7 +744,8 @@ tar_options(argc, argv) /* * use compress. */ - zflag = COMPRESS_CMP; + zflag = 1; + gzip_program = COMPRESS_CMD; break; case '0': arcname = DEV_0; diff --git a/bin/pax/pax.h b/bin/pax/pax.h index 7e0993d3e69..50a2aac10e4 100644 --- a/bin/pax/pax.h +++ b/bin/pax/pax.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pax.h,v 1.5 1996/10/27 06:45:14 downsj Exp $ */ +/* $OpenBSD: pax.h,v 1.6 1996/12/09 12:00:16 deraadt Exp $ */ /* $NetBSD: pax.h,v 1.3 1995/03/21 09:07:41 cgd Exp $ */ /*- @@ -74,12 +74,6 @@ #define ISPIPE 4 /* pipe/socket */ /* - * Compression types - */ -#define GZIP_CMP 1 /* gzip format */ -#define COMPRESS_CMP 2 /* compress format */ - -/* * Format Specific Routine Table * * The format specific routine table allows new archive formats to be quickly |