From c7117be0a4945596f2792530bf222ea149af69d8 Mon Sep 17 00:00:00 2001 From: deraadt Date: Mon, 9 Dec 1996 12:00:13 +0000 Subject: [PATCH] revert to spawning compress-ing program. normally we want extracts using 'z' to also work on .Z files, but libz does not deal with compressed data. Hacking the code to deal well with pipes has proven very hard. --- bin/pax/Makefile | 8 +- bin/pax/ar_io.c | 419 +++++++++++++++++++++------------------------- bin/pax/extern.h | 3 +- bin/pax/options.c | 16 +- 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 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 #include #include -#include #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 $ */ /*- @@ -73,12 +73,6 @@ #define ISTAPE 3 /* tape drive */ #define ISPIPE 4 /* pipe/socket */ -/* - * Compression types - */ -#define GZIP_CMP 1 /* gzip format */ -#define COMPRESS_CMP 2 /* compress format */ - /* * Format Specific Routine Table * -- 2.20.1