---
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.2
Received 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