diff options
author | kris <kris@FreeBSD.org> | 2001-05-05 01:10:13 +0000 |
---|---|---|
committer | kris <kris@FreeBSD.org> | 2001-05-05 01:10:13 +0000 |
commit | b48e2b1dc26b8ed5eefa8412ae1efc92d53c6247 (patch) | |
tree | 863108cbe97f2ce506e4671f0a90e21db4946c19 /bin | |
parent | 4ac9ed2901e82789c73fcf17f3c486b55fbef8c2 (diff) | |
download | FreeBSD-src-b48e2b1dc26b8ed5eefa8412ae1efc92d53c6247.zip FreeBSD-src-b48e2b1dc26b8ed5eefa8412ae1efc92d53c6247.tar.gz |
Add -z flag to pax to allow gzipping of archive output. Add -z and -Z (gzip
and compress) to pax when used in tar mode (invoked as 'tar') for
compatibility with GNU tar.
bzip2 functionality for further GNU tar compatibility will be added at a
later date.
Note in the manpage that -z is non-standard.
Obtained from: OpenBSD
Reviewed by: -hackers
MFC after: 2 weeks
Diffstat (limited to 'bin')
-rw-r--r-- | bin/pax/ar_io.c | 72 | ||||
-rw-r--r-- | bin/pax/extern.h | 1 | ||||
-rw-r--r-- | bin/pax/options.c | 31 | ||||
-rw-r--r-- | bin/pax/pax.1 | 13 | ||||
-rw-r--r-- | bin/pax/pax.c | 3 |
5 files changed, 107 insertions, 13 deletions
diff --git a/bin/pax/ar_io.c b/bin/pax/ar_io.c index 0d02f20..ee4681b 100644 --- a/bin/pax/ar_io.c +++ b/bin/pax/ar_io.c @@ -44,16 +44,18 @@ static const char rcsid[] = #endif /* not lint */ #include <sys/types.h> -#include <sys/stat.h> #include <sys/ioctl.h> #include <sys/mtio.h> -#include <signal.h> -#include <string.h> +#include <sys/stat.h> +#include <sys/wait.h> +#include <err.h> +#include <errno.h> #include <fcntl.h> -#include <unistd.h> +#include <signal.h> #include <stdio.h> -#include <errno.h> +#include <string.h> #include <stdlib.h> +#include <unistd.h> #include "pax.h" #include "extern.h" @@ -79,9 +81,12 @@ 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? */ char *arcname; /* printable name of archive */ +const char *gzip_program; /* name of gzip program */ +static pid_t zpid = -1; /* pid of child process */ static int get_phys __P((void)); extern sigset_t s_mask; +static void ar_start_gzip __P((int, const char *, int)); /* * ar_open() @@ -121,6 +126,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 (arfd != -1 && gzip_program != NULL) + ar_start_gzip(arfd, gzip_program, 0); break; case ARCHIVE: if (name == NULL) { @@ -130,6 +137,8 @@ ar_open(name) syswarn(0, errno, "Failed open to write on %s", name); else can_unlnk = 1; + if (arfd != -1 && gzip_program != NULL) + ar_start_gzip(arfd, gzip_program, 1); break; case APPND: if (name == NULL) { @@ -335,6 +344,16 @@ ar_close() can_unlnk = 0; } + /* + * for a quick extract/list, pax frequently exits before the child + * process is done + */ + if ((act == LIST || act == EXTRACT) && nflag && zpid > 0) { + int status; + kill(zpid, SIGINT); + waitpid(zpid, &status, 0); + } + (void)close(arfd); if (vflag && (artyp == ISTAPE)) { @@ -1287,3 +1306,46 @@ 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 +ar_start_gzip(int fd, const char *gzip_program, int wr) +{ + int fds[2]; + char *gzip_flags; + + if (pipe(fds) < 0) + err(1, "could not pipe"); + zpid = fork(); + if (zpid < 0) + err(1, "could not fork"); + + /* parent */ + if (zpid) { + if (wr) + dup2(fds[1], fd); + else + dup2(fds[0], fd); + close(fds[0]); + close(fds[1]); + } else { + if (wr) { + dup2(fds[0], STDIN_FILENO); + dup2(fd, STDOUT_FILENO); + gzip_flags = "-c"; + } else { + dup2(fds[1], STDOUT_FILENO); + dup2(fd, STDIN_FILENO); + gzip_flags = "-dc"; + } + 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 528ce6c..9f4097c 100644 --- a/bin/pax/extern.h +++ b/bin/pax/extern.h @@ -48,6 +48,7 @@ * ar_io.c */ extern char *arcname; +extern const 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 5b253f9..cbdcb11 100644 --- a/bin/pax/options.c +++ b/bin/pax/options.c @@ -78,6 +78,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) @@ -192,7 +195,7 @@ pax_options(argc, argv) /* * process option flags */ - while ((c=getopt(argc,argv,"ab:cdf:iklno:p:rs:tuvwx:B:DE:G:HLPT:U:XYZ")) + while ((c=getopt(argc,argv,"ab:cdf:iklno:p:rs:tuvwx:zB:DE:G:HLPT:U:XYZ")) != -1) { switch (c) { case 'a': @@ -376,6 +379,12 @@ pax_options(argc, argv) (void)fputs("\n\n", stderr); pax_usage(); break; + case 'z': + /* + * use gzip. Non standard option. + */ + gzip_program = GZIP_CMD; + break; case 'B': /* * non-standard option on number of bytes written on a @@ -694,6 +703,12 @@ tar_options(argc, argv) */ act = EXTRACT; break; + case 'z': + /* + * use gzip. Non standard option. + */ + gzip_program = GZIP_CMD; + break; case 'B': /* * Nothing to do here, this is pax default @@ -723,6 +738,12 @@ tar_options(argc, argv) */ Xflag = 1; break; + case 'Z': + /* + * use compress. + */ + gzip_program = COMPRESS_CMD; + break; case '0': arcname = DEV_0; break; @@ -1075,18 +1096,18 @@ void pax_usage() #endif { - (void)fputs("usage: pax [-cdnv] [-E limit] [-f archive] ", stderr); + (void)fputs("usage: pax [-cdnvz] [-E limit] [-f archive] ", stderr); (void)fputs("[-s replstr] ... [-U user] ...", stderr); (void)fputs("\n [-G group] ... ", stderr); (void)fputs("[-T [from_date][,to_date]] ... ", stderr); (void)fputs("[pattern ...]\n", stderr); - (void)fputs(" pax -r [-cdiknuvDYZ] [-E limit] ", stderr); + (void)fputs(" pax -r [-cdiknuvzDYZ] [-E limit] ", stderr); (void)fputs("[-f archive] [-o options] ... \n", stderr); (void)fputs(" [-p string] ... [-s replstr] ... ", stderr); (void)fputs("[-U user] ... [-G group] ...\n ", stderr); (void)fputs("[-T [from_date][,to_date]] ... ", stderr); (void)fputs(" [pattern ...]\n", stderr); - (void)fputs(" pax -w [-dituvHLPX] [-b blocksize] ", stderr); + (void)fputs(" pax -w [-dituvzHLPX] [-b blocksize] ", stderr); (void)fputs("[ [-a] [-f archive] ] [-x format] \n", stderr); (void)fputs(" [-B bytes] [-s replstr] ... ", stderr); (void)fputs("[-o options] ... [-U user] ...", stderr); @@ -1114,7 +1135,7 @@ void tar_usage() #endif { - (void)fputs("usage: tar -{txru}[cevfbmopwBHLPX014578] [tapefile] ", + (void)fputs("usage: tar -{txru}[cevfbmopwzBHLPXZ014578] [tapefile] ", stderr); (void)fputs("[blocksize] file1 file2...\n", stderr); exit(1); diff --git a/bin/pax/pax.1 b/bin/pax/pax.1 index 052d57b..88a11eb 100644 --- a/bin/pax/pax.1 +++ b/bin/pax/pax.1 @@ -44,7 +44,7 @@ .Nd read and write file archives and copy directory hierarchies .Sh SYNOPSIS .Nm -.Op Fl cdnv +.Op Fl cdnvz .Bk -words .Op Fl f Ar archive .Ek @@ -71,7 +71,7 @@ .Op Ar pattern ...\& .Nm .Fl r -.Op Fl cdiknuvDYZ +.Op Fl cdiknuvzDYZ .Bk -words .Op Fl f Ar archive .Ek @@ -107,7 +107,7 @@ .Op Ar pattern ...\& .Nm .Fl w -.Op Fl dituvHLPX +.Op Fl dituvzHLPX .Bk -words .Op Fl b Ar blocksize .Ek @@ -756,6 +756,12 @@ as the result of any specific archive format restrictions. The individual archive formats may impose additional restrictions on use. Typical archive format restrictions include (but are not limited to): file pathname length, file size, link pathname length and the type of the file. +.It Fl z +Use +.Xr gzip 1 +to compress (decompress) the archive while writing (reading). +Incompatible with +.Fl a . .It Fl B Ar bytes Limit the number of bytes written to a single archive volume to .Ar bytes . @@ -1100,6 +1106,7 @@ utility is a superset of the .St -p1003.2 standard. The options +.Fl z , .Fl B , .Fl D , .Fl E , diff --git a/bin/pax/pax.c b/bin/pax/pax.c index 91719ae..a53ba80 100644 --- a/bin/pax/pax.c +++ b/bin/pax/pax.c @@ -53,6 +53,7 @@ static const char rcsid[] = #include <sys/stat.h> #include <sys/time.h> #include <sys/resource.h> +#include <err.h> #include <errno.h> #include <locale.h> #include <paths.h> @@ -272,6 +273,8 @@ main(argc, argv) archive(); break; case APPND: + if (gzip_program != NULL) + err(1, "can not gzip while appending"); append(); break; case COPY: |