diff options
author | Thorsten Lockert <tholo@cvs.openbsd.org> | 1996-09-22 20:09:55 +0000 |
---|---|---|
committer | Thorsten Lockert <tholo@cvs.openbsd.org> | 1996-09-22 20:09:55 +0000 |
commit | cd06b07ab1df0cca27399fcbe997d5a0a05d2a4e (patch) | |
tree | b3911cc6842a28b055edd1648e432eefc941d5ef /bin/pax/ar_io.c | |
parent | b94f37f55f7022871e1921d7578e3a9b689a522a (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.c | 414 |
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 */ - } -} |