From d94bda4baba49a88baa25b202ce5ae61c26acd1a Mon Sep 17 00:00:00 2001 From: Rob Landley Date: Thu, 12 Jan 2023 20:16:58 -0600 Subject: [PATCH] Add cpio -R, tweak help text. --- toys/posix/cpio.c | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/toys/posix/cpio.c b/toys/posix/cpio.c index 8faf899b..282a39b1 100644 --- a/toys/posix/cpio.c +++ b/toys/posix/cpio.c @@ -16,33 +16,33 @@ * * todo: export/import linux file list text format ala gen_initramfs_list.sh -USE_CPIO(NEWTOY(cpio, "(ignore-devno)(renumber-inodes)(quiet)(no-preserve-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)uH:p|i|t|F:v(verbose)o|[!pio][!pot][!pF]", TOYFLAG_BIN)) config CPIO bool "cpio" default y help - usage: cpio -{o|t|i|p DEST} [-v] [--verbose] [-F FILE] [--no-preserve-owner] - [ignored: -m -H newc] + usage: cpio -{o|t|i|p DEST} [-v] [--verbose] [-F FILE] [-R [USER][:GROUP] [--no-preserve-owner] Copy files into and out of a "newc" format cpio archive. + -d Create directories if needed -F FILE Use archive FILE instead of stdin/stdout - -p DEST Copy-pass mode, copy stdin file list to directory DEST -i Extract from archive into file system (stdin=archive) -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] -t Test files (list only, stdin=archive, stdout=list of files) - -d Create directories if needed - -u unlink existing files when extracting + -u Unlink existing files when extracting -v Verbose - --no-preserve-owner (don't set ownership during extract) + --no-preserve-owner Don't set ownership during extract */ #define FOR_cpio #include "toys.h" GLOBALS( - char *F, *H; + char *F, *H, *R; ) // Read strings, tail padded to 4 byte alignment. Argument "align" is amount @@ -83,6 +83,17 @@ 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), empty = 1; pid_t pid = 0; + long Ruid = -1, Rgid = -1; + + if (TT.R) { + char *group = TT.R+strcspn(TT.R, ":."); + + if (*group) { + Rgid = xgetgid(group+1); + *group = 0; + } + if (group != TT.R) Ruid = xgetuid(TT.R); + } // In passthrough mode, parent stays in original dir and generates archive // to pipe, child does chdir to new dir and reads archive from stdin (pipe). @@ -145,8 +156,8 @@ void cpio_main(void) size = x8u(toybuf+54); mode = x8u(toybuf+14); - uid = x8u(toybuf+22); - gid = x8u(toybuf+30); + uid = (Ruid>=0) ? Ruid : x8u(toybuf+22); + gid = (Rgid>=0) ? Rgid : x8u(toybuf+30); timestamp = x8u(toybuf+46); // unsigned 32 bit, so year 2100 problem // (This output is unaffected by --quiet.) @@ -266,6 +277,8 @@ void cpio_main(void) // encrypted filesystems can stat the wrong link size if (link) st.st_size = strlen(link); + if (Ruid>=0) st.st_uid = Ruid; + if (Rgid>=0) st.st_gid = Rgid; if (FLAG(no_preserve_owner)) st.st_uid = st.st_gid = 0; if (!S_ISREG(st.st_mode) && !S_ISLNK(st.st_mode)) st.st_size = 0; if (st.st_size >> 32) perror_msg("skipping >2G file '%s'", name); -- 2.39.2