--- tar.1 | 3 +++ tar.c | 35 ++++++++++++++++++++++++++--------- 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/tar.1 b/tar.1 index be2ebea..67242dd 100644 --- a/tar.1 +++ b/tar.1 _AT_@ -9,6 +9,7 @@ .Op Fl C Ar dir .Op Fl J | Fl Z | Fl a | Fl j | Fl z .Fl x Op Fl m | Fl t +.Op Fl O .Op Fl f Ar file .Op Ar file ... .Nm _AT_@ -40,6 +41,8 @@ Do not preserve modification time. List all files in the archive. .It Fl x Extract archive. +.It Fl O +Extract files to standard output. .It Fl h Always dereference symbolic links while recursively traversing directories. .It Fl J | Fl Z | Fl a | Fl j | Fl z diff --git a/tar.c b/tar.c index b74c134..1c25ae5 100644 --- a/tar.c +++ b/tar.c _AT_@ -63,7 +63,7 @@ static int tarfd; static ino_t tarinode; static dev_t tardev; -static int mflag, vflag; +static int mflag, vflag, Oflag; static int filtermode; static const char *filtertool; _AT_@ -251,6 +251,21 @@ archive(const char *path) return 0; } +static int +writefile(int fd, ssize_t l, char b[BLKSIZ]) +{ + for (; l > 0; l -= BLKSIZ) + if (eread(tarfd, b, BLKSIZ) > 0) + ewrite(fd, b, MIN(l, BLKSIZ)); + return 0; +} + +static int +printfile(char *fname, ssize_t l, char b[BLKSIZ]) +{ + return writefile(STDOUT_FILENO, l, b); +} + static int unarchive(char *fname, ssize_t l, char b[BLKSIZ]) { _AT_@ -323,9 +338,7 @@ unarchive(char *fname, ssize_t l, char b[BLKSIZ]) eprintf("strtol %s: invalid number\n", h->gid); if (fd != -1) { - for (; l > 0; l -= BLKSIZ) - if (eread(tarfd, b, BLKSIZ) > 0) - ewrite(fd, b, MIN(l, BLKSIZ)); + writefile(fd, l, b); close(fd); } _AT_@ -360,7 +373,7 @@ skipblk(ssize_t l) } static int -print(char *fname, ssize_t l, char b[BLKSIZ]) +printfname(char *fname, ssize_t l, char b[BLKSIZ]) { puts(fname); skipblk(l); _AT_@ -451,7 +464,8 @@ xt(int argc, char *argv[], int mode) struct dirtime *dirtime; long size; int i, n; - int (*fn)(char *, ssize_t, char[BLKSIZ]) = (mode == 'x') ? unarchive : print; + int (*fn)(char *, ssize_t, char[BLKSIZ]) = (mode == 'x') ? + (Oflag ? printfile : unarchive) : printfname; while (eread(tarfd, b, BLKSIZ) > 0 && h->name[0]) { chktar(h); _AT_@ -486,7 +500,7 @@ xt(int argc, char *argv[], int mode) fn(fname, size, b); if (vflag && mode != 't') - puts(fname); + fprintf(Oflag ? stderr : stdout, "%s\n", fname); } if (mode == 'x' && !mflag) { _AT_@ -505,7 +519,7 @@ xt(int argc, char *argv[], int mode) static void usage(void) { - eprintf("usage: %s [-C dir] [-J | -Z | -a | -j | -z] -x [-m | -t] " + eprintf("usage: %s [-C dir] [-J | -Z | -a | -j | -z] -x [-m | -t] [-O] " "[-f file] [file ...]\n" " %s [-C dir] [-J | -Z | -a | -j | -z] [-h] -c path ... " "[-f file]\n", argv0, argv0); _AT_@ -534,6 +548,9 @@ main(int argc, char *argv[]) case 'm': mflag = 1; break; + case 'O': + Oflag = 1; + break; case 'J': case 'Z': case 'a': _AT_@ -555,7 +572,7 @@ main(int argc, char *argv[]) if (!mode) usage(); if (mode == 'c') - if (!argc) + if (!argc || Oflag) usage(); switch (mode) { -- 2.30.2Received on Wed Mar 31 2021 - 06:01:44 CEST
This archive was generated by hypermail 2.3.0 : Wed Mar 31 2021 - 06:12:33 CEST