|
|
@@ -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);
|