Subject: Re: pax-as-tar extract to stdout patch
To: Simon Burge <simonb@wasabisystems.com>
From: James Chacon <jmc@netbsd.org>
List: tech-userlevel
Date: 06/16/2003 00:04:32
Please commit this. (It makes things like the distrib/cdrom Makefile a lot
simpler to deal with for instance as it extracts one-off files from the
tarballs for some cd images).
James
>Hi folks,
>
>The following patch adds support for pax-as-tar to extract files to
>stdout (the -O option from GNU tar). Anyone see any problems with
>this patch?
>
>Simon.
>--
>Simon Burge <simonb@wasabisystems.com>
>NetBSD Development, Support and Service: http://www.wasabisystems.com/
>
>Index: ar_subs.c
>===================================================================
>RCS file: /cvsroot/src/bin/pax/ar_subs.c,v
>retrieving revision 1.24
>diff -d -p -u -r1.24 ar_subs.c
>--- ar_subs.c 2003/03/31 20:06:33 1.24
>+++ ar_subs.c 2003/06/15 08:37:30
>@@ -308,7 +308,8 @@ extract(void)
> /*
> * if required, chdir around.
> */
>- if ((arcn->pat != NULL) && (arcn->pat->chdname != NULL))
>+ if ((arcn->pat != NULL) && (arcn->pat->chdname != NULL) &&
>+ !to_stdout)
> if (chdir(arcn->pat->chdname) != 0)
> syswarn(1, errno, "Cannot chdir to %s",
> arcn->pat->chdname);
>@@ -336,22 +337,28 @@ extract(void)
> }
> continue;
> }
>- /*
>- * we have a file with data here. If we can not create it, skip
>- * over the data and purge the name from hard link table
>- */
>- if ((fd = file_creat(arcn)) < 0) {
>- (void)fflush(listf);
>- (void)rd_skip(arcn->skip + arcn->pad);
>- purg_lnk(arcn);
>- continue;
>+ if (to_stdout)
>+ fd = STDOUT_FILENO;
>+ else {
>+ /*
>+ * we have a file with data here. If we can not create
>+ * it, skip over the data and purge the name from hard
>+ * link table
>+ */
>+ if ((fd = file_creat(arcn)) < 0) {
>+ (void)fflush(listf);
>+ (void)rd_skip(arcn->skip + arcn->pad);
>+ purg_lnk(arcn);
>+ continue;
>+ }
> }
> /*
> * extract the file from the archive and skip over padding and
> * any unprocessed data
> */
> res = (*frmt->rd_data)(arcn, fd, &cnt);
>- file_close(arcn, fd);
>+ if (!to_stdout)
>+ file_close(arcn, fd);
> if (vflag && vfpart) {
> (void)putc('\n', listf);
> vfpart = 0;
>Index: extern.h
>===================================================================
>RCS file: /cvsroot/src/bin/pax/extern.h,v
>retrieving revision 1.37
>diff -d -p -u -r1.37 extern.h
>--- extern.h 2003/02/25 13:36:59 1.37
>+++ extern.h 2003/06/15 08:37:31
>@@ -251,6 +251,7 @@ extern int pids;
> extern int rmleadslash;
> extern int exit_val;
> extern int docrc;
>+extern int to_stdout;
> extern char *dirptr;
> extern char *ltmfrmt;
> extern char *argv0;
>Index: options.c
>===================================================================
>RCS file: /cvsroot/src/bin/pax/options.c,v
>retrieving revision 1.64
>diff -d -p -u -r1.64 options.c
>--- options.c 2003/04/08 15:13:10 1.64
>+++ options.c 2003/06/15 08:37:32
>@@ -709,6 +709,7 @@ struct option tar_longopts[] = {
> { "gunzip", no_argument, 0, 'z' },
> { "read-full-blocks", no_argument, 0, 'B' },
> { "directory", required_argument, 0, 'C' },
>+ { "to-stdout", no_argument, 0, 'O' },
> { "absolute-paths", no_argument, 0, 'P' },
> { "files-from", required_argument, 0, 'T' },
> { "exclude-from", required_argument, 0, 'X' },
>@@ -749,7 +750,6 @@ struct option tar_longopts[] = {
> { "multi-volume", no_argument, 0, 'M' },
> { "after-date", required_argument, 0, 'N' },
> { "newer", required_argument, 0, 'N' },
>- { "to-stdout", no_argument, 0, 'O' },
> { "record-number", no_argument, 0, 'R' },
> { "remove-files", no_argument, 0,
> OPT_REMOVE_FILES },
>@@ -1076,9 +1076,17 @@ tar_options(int argc, char **argv)
> if (act == ARCHIVE || act == APPND)
> frmt = &(fsub[Oflag ? F_TAR : F_USTAR]);
> else if (Oflag) {
>- tty_warn(1, "The -O/-o options are only valid when writing an archive");
>- tar_usage(); /* only valid when writing */
>+ if (act == EXTRACT)
>+ to_stdout = 1;
>+ else {
>+ tty_warn(1, "The -O/-o options are only valid when "
>+ "writing or extracting an archive");
>+ tar_usage();
>+ }
> }
>+
>+ if (act == EXTRACT && Oflag)
>+ to_stdout = 1;
>
> /*
> * process the args as they are interpreted by the operation mode
>Index: pax.c
>===================================================================
>RCS file: /cvsroot/src/bin/pax/pax.c,v
>retrieving revision 1.26
>diff -d -p -u -r1.26 pax.c
>--- pax.c 2003/03/03 11:42:36 1.26
>+++ pax.c 2003/06/15 08:37:32
>@@ -107,6 +107,7 @@ int pids; /* preserve file uid/gid */
> int rmleadslash = 0; /* remove leading '/' from pathnames */
> int exit_val; /* exit value */
> int docrc; /* check/create file crc */
>+int to_stdout; /* extract to stdout */
> char *dirptr; /* destination dir in a copy */
> char *ltmfrmt; /* -v locale time format (if any) */
> char *argv0; /* root of argv[0] */
>Index: tar.1
>===================================================================
>RCS file: /cvsroot/src/bin/pax/tar.1,v
>retrieving revision 1.11
>diff -d -p -u -r1.11 tar.1
>--- tar.1 2003/04/10 06:07:40 1.11
>+++ tar.1 2003/06/15 08:37:33
>@@ -124,7 +124,8 @@ Do not cross filesystems.
> .It Fl m , -modification-time
> Do not preserve modification time.
> .It Fl O
>-Write old-style (non-POSIX) archives.
>+When creating and appending to an archive, write old-style (non-POSIX) archives.
>+When extracting from an archive, extract to standard output.
> .It Fl o , -portability , -old-archive
> Don't write directory information that the older (V7) style
> .Nm
>
>
>