From owner-freebsd-hackers Thu Apr 26 2:54:51 2001 Delivered-To: freebsd-hackers@freebsd.org Received: from obsecurity.dyndns.org (adsl-63-207-60-27.dsl.lsan03.pacbell.net [63.207.60.27]) by hub.freebsd.org (Postfix) with ESMTP id 9765337B424; Thu, 26 Apr 2001 02:54:26 -0700 (PDT) (envelope-from kris@obsecurity.org) Received: by obsecurity.dyndns.org (Postfix, from userid 1000) id EAFA166DF6; Thu, 26 Apr 2001 02:54:25 -0700 (PDT) Date: Thu, 26 Apr 2001 02:54:25 -0700 From: Kris Kennaway To: hackers@FreeBSD.org Cc: audit@FreeBSD.org Subject: pax(1) gzip functionality Message-ID: <20010426025425.A92262@xor.obsecurity.org> Mime-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-md5; protocol="application/pgp-signature"; boundary="PEIAKu/WMn1b1Hv9" Content-Disposition: inline User-Agent: Mutt/1.2.5i Sender: owner-freebsd-hackers@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG --PEIAKu/WMn1b1Hv9 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable Hi all, Please review the following code from OpenBSD; it adds -z and -Z options to pax(1) to gzip(1) the archives created. Kris Index: ar_io.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /home/ncvs/src/bin/pax/ar_io.c,v retrieving revision 1.14 diff -u -r1.14 ar_io.c --- ar_io.c 2001/04/26 09:22:27 1.14 +++ ar_io.c 2001/04/26 09:52:32 @@ -44,16 +44,18 @@ #endif /* not lint */ =20 #include -#include #include #include -#include -#include +#include +#include +#include +#include #include -#include +#include #include -#include +#include #include +#include #include "pax.h" #include "extern.h" =20 @@ -79,9 +81,12 @@ static int wr_trail =3D 1; /* trailer was rewritten in append */ static int can_unlnk =3D 0; /* do we unlink null archives? */ char *arcname; /* printable name of archive */ +const char *gzip_program; /* name of gzip program */ +static pid_t zpid =3D -1; /* pid of child process */ =20 static int get_phys __P((void)); extern sigset_t s_mask; +static void ar_start_gzip __P((int, const char *, int)); =20 /* * ar_open() @@ -121,6 +126,8 @@ arcname =3D STDN; } else if ((arfd =3D open(name, EXT_MODE, DMOD)) < 0) syswarn(0, errno, "Failed open to read on %s", name); + if (arfd !=3D -1 && gzip_program !=3D NULL) + ar_start_gzip(arfd, gzip_program, 0); break; case ARCHIVE: if (name =3D=3D NULL) { @@ -130,6 +137,8 @@ syswarn(0, errno, "Failed open to write on %s", name); else can_unlnk =3D 1; + if (arfd !=3D -1 && gzip_program !=3D NULL) + ar_start_gzip(arfd, gzip_program, 1); break; case APPND: if (name =3D=3D NULL) { @@ -335,6 +344,16 @@ can_unlnk =3D 0; } =20 + /* + * for a quick extract/list, pax frequently exits before the child + * process is done + */ + if ((act =3D=3D LIST || act =3D=3D EXTRACT) && nflag && zpid > 0) { + int status; + kill(zpid, SIGINT); + waitpid(zpid, &status, 0); + } + (void)close(arfd); =20 if (vflag && (artyp =3D=3D ISTAPE)) { @@ -1286,4 +1305,47 @@ continue; } return(0); +} + +/* + * ar_start_gzip() + * starts the gzip compression/decompression process as a child, using mag= ic + * 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 =3D 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 =3D "-c"; + } else { + dup2(fds[1], STDOUT_FILENO); + dup2(fd, STDIN_FILENO); + gzip_flags =3D "-dc"; + } + close(fds[0]); + close(fds[1]); + if (execlp(gzip_program, gzip_program, gzip_flags, NULL) < 0) + err(1, "could not exec"); + /* NOTREACHED */ + } } Index: extern.h =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /home/ncvs/src/bin/pax/extern.h,v retrieving revision 1.10 diff -u -r1.10 extern.h --- extern.h 2001/04/26 08:37:00 1.10 +++ extern.h 2001/04/26 09:52:32 @@ -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)); Index: options.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /home/ncvs/src/bin/pax/options.c,v retrieving revision 1.17 diff -u -r1.17 options.c --- options.c 2001/04/26 09:22:28 1.17 +++ options.c 2001/04/26 09:52:32 @@ -78,6 +78,9 @@ static void cpio_usage __P((void)); #endif =20 +#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 @@ /* * process option flags */ - while ((c=3Dgetopt(argc,argv,"ab:cdf:iklno:p:rs:tuvwx:B:DE:G:HLPT:U:XYZ")) + while ((c=3Dgetopt(argc,argv,"ab:cdf:iklno:p:rs:tuvwx:zB:DE:G:HLPT:U:XYZ"= )) !=3D -1) { switch (c) { case 'a': @@ -376,6 +379,12 @@ (void)fputs("\n\n", stderr); pax_usage(); break; + case 'z': + /* + * use gzip. Non standard option. + */ + gzip_program =3D GZIP_CMD; + break; case 'B': /* * non-standard option on number of bytes written on a @@ -694,6 +703,12 @@ */ act =3D EXTRACT; break; + case 'z': + /* + * use gzip. Non standard option. + */ + gzip_program =3D GZIP_CMD; + break; case 'B': /* * Nothing to do here, this is pax default @@ -723,6 +738,12 @@ */ Xflag =3D 1; break; + case 'Z': + /* + * use compress. + */ + gzip_program =3D COMPRESS_CMD; + break; case '0': arcname =3D DEV_0; break; @@ -1075,18 +1096,18 @@ 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 @@ 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); Index: pax.1 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /home/ncvs/src/bin/pax/pax.1,v retrieving revision 1.16 diff -u -r1.16 pax.1 --- pax.1 2001/02/13 09:50:27 1.16 +++ pax.1 2001/04/26 09:52:33 @@ -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 @@ 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 . Index: pax.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /home/ncvs/src/bin/pax/pax.c,v retrieving revision 1.17 diff -u -r1.17 pax.c --- pax.c 2001/04/26 09:22:28 1.17 +++ pax.c 2001/04/26 09:52:33 @@ -53,6 +53,7 @@ #include #include #include +#include #include #include #include @@ -272,6 +273,8 @@ archive(); break; case APPND: + if (gzip_program !=3D NULL) + err(1, "can not gzip while appending"); append(); break; case COPY: --PEIAKu/WMn1b1Hv9 Content-Type: application/pgp-signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.0.4 (FreeBSD) Comment: For info see http://www.gnupg.org iD8DBQE65/BRWry0BWjoQKURAnUYAJsGTDfFtQkbK0iWnjNZKh5Dkh9tDgCg0YfW wBpGzhlNrd6YPWTrApsQJWc= =ADf+ -----END PGP SIGNATURE----- --PEIAKu/WMn1b1Hv9-- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-hackers" in the body of the message