summaryrefslogtreecommitdiff
path: root/bin/pax/ar_io.c
diff options
context:
space:
mode:
authorThorsten Lockert <tholo@cvs.openbsd.org>1996-09-22 20:09:55 +0000
committerThorsten Lockert <tholo@cvs.openbsd.org>1996-09-22 20:09:55 +0000
commitcd06b07ab1df0cca27399fcbe997d5a0a05d2a4e (patch)
treeb3911cc6842a28b055edd1648e432eefc941d5ef /bin/pax/ar_io.c
parentb94f37f55f7022871e1921d7578e3a9b689a522a (diff)
Use zopen for compress-style compressed archives
Use libz for gzip-style compressed archives
Diffstat (limited to 'bin/pax/ar_io.c')
-rw-r--r--bin/pax/ar_io.c414
1 files changed, 225 insertions, 189 deletions
diff --git a/bin/pax/ar_io.c b/bin/pax/ar_io.c
index 35d1adbdfab..2bc617ab3c7 100644
--- a/bin/pax/ar_io.c
+++ b/bin/pax/ar_io.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ar_io.c,v 1.4 1996/06/23 14:20:28 deraadt Exp $ */
+/* $OpenBSD: ar_io.c,v 1.5 1996/09/22 20:09:53 tholo 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.4 1996/06/23 14:20:28 deraadt Exp $";
+static char rcsid[] = "$OpenBSD: ar_io.c,v 1.5 1996/09/22 20:09:53 tholo Exp $";
#endif
#endif /* not lint */
@@ -60,6 +60,7 @@ static char rcsid[] = "$OpenBSD: ar_io.c,v 1.4 1996/06/23 14:20:28 deraadt Exp $
#include <errno.h>
#include <stdlib.h>
#include <err.h>
+#include <zlib.h>
#include "pax.h"
#include "extern.h"
@@ -84,12 +85,13 @@ 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()
@@ -111,8 +113,14 @@ ar_open(name)
{
struct mtget mb;
- if (arfd != -1)
- (void)close(arfd);
+ if (arfd != -1) {
+ if (zflag == GZIP_CMP)
+ (void)gzclose(gzf);
+ else if (zflag == COMPRESS_CMP)
+ (void)fclose(cfp);
+ else
+ (void)close(arfd);
+ }
arfd = -1;
can_unlnk = did_io = io_ok = invld_rec = 0;
artyp = ISREG;
@@ -129,8 +137,10 @@ 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)
- ar_start_gzip(arfd);
+ if (zflag == GZIP_CMP)
+ gzf = gzdopen(arfd, "r");
+ else if (zflag == COMPRESS_CMP)
+ cfp = zdopen(arfd, "r");
break;
case ARCHIVE:
if (name == NULL) {
@@ -140,12 +150,14 @@ ar_open(name)
syswarn(0, errno, "Failed open to write on %s", name);
else
can_unlnk = 1;
- if (zflag)
- ar_start_gzip(arfd);
+ if (zflag == GZIP_CMP)
+ gzf = gzdopen(arfd, "w");
+ else if (zflag == COMPRESS_CMP)
+ cfp = zdopen(arfd, "w");
break;
case APPND:
if (zflag)
- err(1, "can not gzip while appending");
+ err(1, "can not compress while appending");
if (name == NULL) {
arfd = STDOUT_FILENO;
arcname = STDO;
@@ -169,7 +181,12 @@ ar_open(name)
*/
if (fstat(arfd, &arsb) < 0) {
syswarn(0, errno, "Failed stat on %s", arcname);
- (void)close(arfd);
+ if (zflag == GZIP_CMP)
+ (void)gzclose(gzf);
+ else if (zflag == COMPRESS_CMP)
+ (void)fclose(cfp);
+ else
+ (void)close(arfd);
arfd = -1;
can_unlnk = 0;
return(-1);
@@ -177,7 +194,12 @@ ar_open(name)
if (S_ISDIR(arsb.st_mode)) {
paxwarn(0, "Cannot write an archive on top of a directory %s",
arcname);
- (void)close(arfd);
+ if (zflag == GZIP_CMP)
+ (void)gzclose(gzf);
+ else if (zflag == COMPRESS_CMP)
+ (void)fclose(cfp);
+ else
+ (void)close(arfd);
arfd = -1;
can_unlnk = 0;
return(-1);
@@ -349,7 +371,12 @@ ar_close()
can_unlnk = 0;
}
- (void)close(arfd);
+ if (zflag == GZIP_CMP)
+ (void)gzclose(gzf);
+ else if (zflag == COMPRESS_CMP)
+ (void)fclose(cfp);
+ else
+ (void)close(arfd);
if (vflag && (artyp == ISTAPE)) {
(void)fputs("done.\n", outf);
@@ -441,8 +468,18 @@ ar_drain()
/*
* keep reading until pipe is drained
*/
- while ((res = read(arfd, drbuf, sizeof(drbuf))) > 0)
- ;
+ 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)
+ ;
+ }
lstrval = res;
}
@@ -512,6 +549,11 @@ 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",
@@ -551,32 +593,34 @@ ar_read(buf, cnt)
*/
switch (artyp) {
case ISTAPE:
- 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) {
+ if (!zflag) {
+ if ((res = read(arfd, buf, cnt)) > 0) {
/*
- * 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).
+ * 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.
*/
- rdblksz = res;
- if (rdblksz % BLKMULT)
- invld_rec = 1;
+ 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);
}
- return(res);
+ break;
}
- break;
case ISREG:
case ISBLK:
case ISCHR:
@@ -589,9 +633,23 @@ ar_read(buf, cnt)
* and return. Trying to do anything else with them runs the
* risk of failure.
*/
- if ((res = read(arfd, buf, cnt)) > 0) {
- io_ok = 1;
- return(res);
+ 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);
+ }
}
break;
}
@@ -638,10 +696,26 @@ ar_write(buf, bsz)
if (lstrval <= 0)
return(lstrval);
- if ((res = write(arfd, buf, bsz)) == bsz) {
- wr_trail = 1;
- io_ok = 1;
- return(bsz);
+ 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);
+ }
}
/*
* write broke, see what we can do with it. We try to send any partial
@@ -652,53 +726,55 @@ ar_write(buf, bsz)
else
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)
+ 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;
break;
- cpos -= (off_t)res;
- if (ftruncate(arfd, cpos) < 0)
+ }
+ if (res >= 0)
break;
- res = lstrval = 0;
+ /*
+ * if file is out of space, handle it like a return of 0
+ */
+ if ((errno == ENOSPC) || (errno == EFBIG) || (errno == EDQUOT))
+ res = lstrval = 0;
break;
- }
- if (res >= 0)
+ 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;
- /*
- * 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)
+ case ISPIPE:
+ default:
+ /*
+ * we cannot fix errors to these devices
+ */
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;
}
/*
@@ -771,50 +847,54 @@ ar_rdsync()
if (io_ok)
did_io = 1;
- 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 (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;
- }
- 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)
+ 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;
- mpos = fsbz - (cpos % (off_t)fsbz);
- if (lseek(arfd, mpos, SEEK_CUR) < 0)
+ case ISPIPE:
+ default:
+ /*
+ * cannot recover on these archive device types
+ */
+ io_ok = 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.");
@@ -848,7 +928,7 @@ ar_fow(sksz, skipped)
off_t mpos;
*skipped = 0;
- if (sksz <= 0)
+ if (zflag || sksz <= 0)
return(0);
/*
@@ -919,6 +999,19 @@ 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)
@@ -1052,6 +1145,11 @@ 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.
@@ -1301,65 +1399,3 @@ 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 */
- }
-}