aboutsummaryrefslogtreecommitdiff
path: root/toys/posix/cpio.c
diff options
context:
space:
mode:
Diffstat (limited to 'toys/posix/cpio.c')
-rw-r--r--toys/posix/cpio.c20
1 files changed, 11 insertions, 9 deletions
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);