aboutsummaryrefslogtreecommitdiff
path: root/toys/posix/tar.c
diff options
context:
space:
mode:
authorRob Landley <rob@landley.net>2022-09-28 01:27:26 -0500
committerRob Landley <rob@landley.net>2022-09-28 01:27:26 -0500
commit5262c5387426f645d9df9f0398ea77965d437112 (patch)
tree98c604c0b5200448f45c7ab40a3051bcd3b31518 /toys/posix/tar.c
parent331ecc9ae78726433afe941ee24fc1befb15b6ae (diff)
downloadtoybox-5262c5387426f645d9df9f0398ea77965d437112.tar.gz
Add sed --tarxform mode to wrap a simple protocol around transforms,
and have tar --xform use it.
Diffstat (limited to 'toys/posix/tar.c')
-rw-r--r--toys/posix/tar.c45
1 files changed, 31 insertions, 14 deletions
diff --git a/toys/posix/tar.c b/toys/posix/tar.c
index 7893b259..34182387 100644
--- a/toys/posix/tar.c
+++ b/toys/posix/tar.c
@@ -61,7 +61,7 @@ GLOBALS(
struct double_list *incl, *excl, *seen;
struct string_list *dirs;
char *cwd, **xfsed;
- int fd, ouid, ggid, hlc, warn, sparselen, pid;
+ int fd, ouid, ggid, hlc, warn, sparselen, pid, xfpipe[2];
struct dev_ino archive_di;
long long *sparse;
time_t mtt;
@@ -192,6 +192,23 @@ static void alloread(void *buf, int len)
(*b)[len] = 0;
}
+static char *xform(char **name)
+{
+ char buf[9], *end;
+ off_t len;
+
+ if (!TT.xform) return 0;
+
+ buf[8] = 0;
+ if (dprintf(TT.xfpipe[0], "%s%c", *name, 0) != strlen(*name)+1
+ || readall(TT.xfpipe[1], buf, 8) != 8
+ || !(len = estrtol(buf, &end, 16)) || errno ||*end) error_exit("bad xform");
+ xreadall(TT.xfpipe[1], *name = xmalloc(len+1), len);
+ (*name)[len] = 0;
+
+ return *name;
+}
+
// callback from dirtree to create archive
static int add_to_tar(struct dirtree *node)
{
@@ -242,10 +259,7 @@ static int add_to_tar(struct dirtree *node)
TT.warn = 0;
}
- // Note: linux sed doesn't add newline, so no need to remove it or use -z.
- if (TT.xfsed)
- if (!(hname = xfname = xrunread(TT.xfsed, hname))) error_exit("bad xform");
-
+ xfname = xform(&hname);
if (TT.owner) st->st_uid = TT.ouid;
if (TT.group) st->st_gid = TT.ggid;
if (TT.mode) st->st_mode = string_to_mode(TT.mode, st->st_mode);
@@ -781,8 +795,7 @@ static void unpack_tar(char *first)
// We accept --show-transformed but always do, so it's a NOP.
name = TT.hdr.name;
- if (TT.xfsed) {
- if (!(name = xrunread(TT.xfsed, name))) error_exit("bad xform");
+ if (xform(&name)) {
free(TT.hdr.name);
TT.hdr.name = name;
}
@@ -885,7 +898,7 @@ static char *get_archiver()
void tar_main(void)
{
- char *s, **args = toys.optargs;
+ char *s, **xfsed, **args = toys.optargs;
int len = 0, ii;
// Needed when extracting to command
@@ -927,13 +940,17 @@ void tar_main(void)
struct arg_list *al;
for (ii = 0, al = TT.xform; al; al = al->next) ii++;
- TT.xfsed = xmalloc((ii+1)*2*sizeof(char *));
- TT.xfsed[0] = "sed";
- for (ii = 1, al = TT.xform; al; al = al->next) {
- TT.xfsed[ii++] = "-e";
- TT.xfsed[ii++] = al->arg;
+ xfsed = xmalloc((ii+2)*2*sizeof(char *));
+ xfsed[0] = "sed";
+ xfsed[1] = "--tarxform";
+ for (ii = 2, al = TT.xform; al; al = al->next) {
+ xfsed[ii++] = "-e";
+ xfsed[ii++] = al->arg;
}
- TT.xfsed[ii] = 0;
+ xfsed[ii] = 0;
+ TT.xfpipe[0] = TT.xfpipe[1] = -1;
+ xpopen_both(xfsed, TT.xfpipe);
+ free(xfsed);
}
// nommu reentry for nonseekable input skips this, parent did it for us