summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bin/pax/Makefile8
-rw-r--r--bin/pax/ar_io.c419
-rw-r--r--bin/pax/extern.h3
-rw-r--r--bin/pax/options.c16
-rw-r--r--bin/pax/pax.h8
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