[hackers] [sbase][PATCH] Add -O flag to tar

From: <th.ought_AT_slmail.me>
Date: Wed, 31 Mar 2021 04:01:44 -0000

From: th.ought <th.ought_AT_slmail.me>

---
 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