From dafb9211c77788d7ea124aca18205e924d1ac48a Mon Sep 17 00:00:00 2001 From: Rob Landley Date: Fri, 16 Apr 2021 01:39:08 -0500 Subject: cpio: continue past TRAILER!!! (like kernel does) but error on empty archive. --- tests/cpio.test | 3 +++ toys/posix/cpio.c | 20 +++++++++++--------- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/tests/cpio.test b/tests/cpio.test index 7e2955a1..3955800f 100755 --- a/tests/cpio.test +++ b/tests/cpio.test @@ -59,3 +59,6 @@ testing "-id keeps existing files" "echo new >a/b && cpio -id /dev/nul testing "-iu replaces existing files; no error" "echo new >a/b && cpio -iu a/b && cpio -idu /dev/null || echo err" "err\n" "" "" diff --git a/toys/posix/cpio.c b/toys/posix/cpio.c index b60e19b4..d90be7f3 100644 --- a/toys/posix/cpio.c +++ b/toys/posix/cpio.c @@ -72,7 +72,7 @@ static unsigned x8u(char *hex) // Because scanf gratuitously treats %*X differently than printf does. sprintf(pattern, "%%%dX%%n", inpos); sscanf(hex, pattern, &val, &outpos); - if (inpos != outpos) error_exit("bad header"); + if (inpos != outpos) error_exit("bad hex"); return val; } @@ -80,7 +80,7 @@ static unsigned x8u(char *hex) void cpio_main(void) { // Subtle bit: FLAG_o is 1 so we can just use it to select stdin/stdout. - int pipe, afd = FLAG(o); + int pipe, afd = FLAG(o), empty = 1; pid_t pid = 0; // In passthrough mode, parent stays in original dir and generates archive @@ -111,18 +111,21 @@ void cpio_main(void) // read cpio archive - if (FLAG(i) || FLAG(t)) for (;;) { + if (FLAG(i) || FLAG(t)) for (;; empty = 0) { char *name, *tofree, *data; unsigned size, mode, uid, gid, timestamp; int test = FLAG(t), err = 0; // Read header and name. - if (!(size =readall(afd, toybuf, 110))) break; + if (!(size = readall(afd, toybuf, 110))) { + if (empty) error_exit("empty archive"); + else break; + } if (size != 110 || memcmp(toybuf, "070701", 6)) error_exit("bad header"); tofree = name = strpad(afd, x8u(toybuf+94), 110); if (!strcmp("TRAILER!!!", name)) { - if (CFG_TOYBOX_FREE) free(tofree); - break; + free(tofree); + continue; } // If you want to extract absolute paths, "cd /" and run cpio. @@ -283,9 +286,8 @@ void cpio_main(void) } if (CFG_TOYBOX_FREE) free(name); - memset(toybuf, 0, sizeof(toybuf)); - xwrite(afd, toybuf, - sprintf(toybuf, "070701%040X%056X%08XTRAILER!!!", 1, 0x0b, 0)+4); + // nlink=1, namesize=11, with padding + dprintf(afd, "070701%040X%056X%08XTRAILER!!!%c%c%c%c", 1, 11, 0, 0, 0, 0,0); } if (TT.F) xclose(afd); -- cgit v1.2.3