Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 26 Apr 2001 02:54:25 -0700
From:      Kris Kennaway <kris@obsecurity.org>
To:        hackers@FreeBSD.org
Cc:        audit@FreeBSD.org
Subject:   pax(1) gzip functionality
Message-ID:  <20010426025425.A92262@xor.obsecurity.org>

next in thread | raw e-mail | index | archive | help

--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 <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"
=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 <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 @@
 		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




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20010426025425.A92262>