diff options
author | Rob Landley <rob@landley.net> | 2021-04-17 05:54:36 -0500 |
---|---|---|
committer | Rob Landley <rob@landley.net> | 2021-04-17 05:54:36 -0500 |
commit | 95a15d238120167959bd7aee3e71ac5be3a72804 (patch) | |
tree | cbf37c21f822542971b1c916e1f36be25a1a3116 /toys | |
parent | dafb9211c77788d7ea124aca18205e924d1ac48a (diff) | |
download | toybox-95a15d238120167959bd7aee3e71ac5be3a72804.tar.gz |
Teach cpio to skip runs of NUL bytes between records.
Diffstat (limited to 'toys')
-rw-r--r-- | toys/posix/cpio.c | 23 |
1 files changed, 17 insertions, 6 deletions
diff --git a/toys/posix/cpio.c b/toys/posix/cpio.c index d90be7f3..07c294f0 100644 --- a/toys/posix/cpio.c +++ b/toys/posix/cpio.c @@ -3,7 +3,8 @@ * Copyright 2013 Isaac Dunham <ibid.ag@gmail.com> * Copyright 2015 Frontier Silicon Ltd. * - * see http://refspecs.linuxfoundation.org/LSB_4.1.0/LSB-Core-generic/LSB-Core-generic/cpio.html + * see https://www.kernel.org/doc/Documentation/early-userspace/buffer-format.txt + * and http://refspecs.linuxfoundation.org/LSB_4.1.0/LSB-Core-generic/LSB-Core-generic/cpio.html * and http://pubs.opengroup.org/onlinepubs/7908799/xcu/cpio.html * * Yes, that's SUSv2, newer versions removed it, but RPM and initramfs use @@ -11,7 +12,7 @@ * expanded headers to 110 bytes (first field 6 bytes, rest are 8). * In order: magic ino mode uid gid nlink mtime filesize devmajor devminor * rdevmajor rdevminor namesize check - * This is the equiavlent of mode -H newc when using GNU CPIO. + * This is the equivalent of mode -H newc in other implementations. * * todo: export/import linux file list text format ala gen_initramfs_list.sh @@ -113,11 +114,21 @@ void cpio_main(void) if (FLAG(i) || FLAG(t)) for (;; empty = 0) { char *name, *tofree, *data; - unsigned size, mode, uid, gid, timestamp; - int test = FLAG(t), err = 0; + unsigned mode, uid, gid, timestamp; + int test = FLAG(t), err = 0, size = 0, len; - // Read header and name. - if (!(size = readall(afd, toybuf, 110))) { + // read header, skipping arbitrary leading NUL bytes (concatenated archives) + for (;;) { + if (1>(len = readall(afd, toybuf+size, 110-size))) break; + if (size || *toybuf) { + size += len; + break; + } + for (size = 0; size<len; size++) if (toybuf[size]) break; + memmove(toybuf, toybuf+size, len-size); + size = len-size; + } + if (!size) { if (empty) error_exit("empty archive"); else break; } |