Subject: pax-as-tar extract to stdout patch
To: None <tech-userlevel@netbsd.org>
From: Simon Burge <simonb@wasabisystems.com>
List: tech-userlevel
Date: 06/15/2003 18:39:50
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