From 57f85a153ebb9c741c91fc7447877164a32c8efd Mon Sep 17 00:00:00 2001 From: Rob Landley Date: Thu, 15 Jun 2023 21:56:27 -0500 Subject: [PATCH] Add cpio -L --- tests/cpio.test | 7 ++++++- toys/posix/cpio.c | 5 +++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/tests/cpio.test b/tests/cpio.test index 6f5eddef..45d528d8 100755 --- a/tests/cpio.test +++ b/tests/cpio.test @@ -68,7 +68,8 @@ testing "-i keeps existing files" "echo new >a/b && $CPIO -i /dev/null testing "-id keeps existing files" "echo new >a/b && $CPIO -id /dev/null; cat a/b" "new\n" "" "" testing "-iu replaces existing files; no error" "echo new >a/b && $CPIO -iu a/b && $CPIO -idu /dev/null; cat a.cpio; done | $CPIO -t -H newc" \ +# The kernel's initramfs extractor does this +toyonly testing "skip NUL" "for i in a b; do dd if=/dev/zero bs=512 count=1 2>/dev/null; cat a.cpio; done | $CPIO -t -H newc" \ "a\na/b\na\na/b\n" "" "" rm -rf a a.cpio @@ -92,3 +93,7 @@ fi skipnot [ $(id -u) -eq 0 ] testing "-t preserve ownership" "$CPIO -t /dev/null && stat -c '%U:%G' a/file a/symlink a/dir" "${USR}:${GRP}\n${USR}:${GRP}\n${USR}:${GRP}\n" "" "" rm -rf a a.cpio + +echo payload > one +ln -s one two +testing '-L' "$CPI_O -L | grep -ao payload" 'payload\n' '' 'two\n' diff --git a/toys/posix/cpio.c b/toys/posix/cpio.c index bbcde4b5..48b9b889 100644 --- a/toys/posix/cpio.c +++ b/toys/posix/cpio.c @@ -19,7 +19,7 @@ * TODO: hardlink support, -A, -0, -a, -L, --sparse * TODO: --renumber-archives (probably always?) --ignore-devno --reproducible -USE_CPIO(NEWTOY(cpio, "(ignore-devno)(renumber-inodes)(quiet)(no-preserve-owner)R(owner):md(make-directories)uH:p|i|t|F:v(verbose)o|[!pio][!pot][!pF]", TOYFLAG_BIN)) +USE_CPIO(NEWTOY(cpio, "(ignore-devno)(renumber-inodes)(quiet)(no-preserve-owner)R(owner):md(make-directories)uLH:p|i|t|F:v(verbose)o|[!pio][!pot][!pF]", TOYFLAG_BIN)) config CPIO bool "cpio" @@ -32,6 +32,7 @@ config CPIO -d Create directories if needed -F FILE Use archive FILE instead of stdin/stdout -i Extract from archive into file system (stdin=archive) + -L Follow symlinks -o Create archive (stdin=list of files, stdout=archive) -p DEST Copy-pass mode, copy stdin file list to directory DEST -R USER Replace owner with USER[:GROUP] @@ -265,7 +266,7 @@ void cpio_main(void) if (len<1) break; if (name[len-1] == '\n') name[--len] = 0; nlen = len+1; - if (lstat(name, &st) || (S_ISREG(st.st_mode) + if ((FLAG(L)?stat:lstat)(name, &st) || (S_ISREG(st.st_mode) && st.st_size && (fd = open(name, O_RDONLY))<0) || (S_ISLNK(st.st_mode) && !(link = xreadlink(name)))) { -- 2.39.2