1303 files changed, 32187 insertions, 57138 deletions
diff --git a/archival/cpio.c b/archival/cpio.c index 5fb5327..be98b42 100644 --- a/archival/cpio.c +++ b/archival/cpio.c @@ -11,6 +11,7 @@ * Only supports new ASCII and CRC formats */ #include "libbb.h" +#include "common_bufsiz.h" #include "bb_archive.h" //config:config CPIO @@ -22,7 +23,7 @@ //config: cpio has 110 bytes of overheads for every stored file. //config: //config: This implementation of cpio can extract cpio archives created in the -//config: "newc" or "crc" format, it cannot create or modify them. +//config: "newc" or "crc" format. //config: //config: Unless you have a specific application which requires cpio, you //config: should probably say N here. @@ -46,14 +47,14 @@ //kbuild:lib-$(CONFIG_CPIO) += cpio.o //usage:#define cpio_trivial_usage -//usage: "[-dmvu] [-F FILE]" IF_FEATURE_CPIO_O(" [-H newc]") +//usage: "[-dmvu] [-F FILE] [-R USER[:GRP]]" IF_FEATURE_CPIO_O(" [-H newc]") //usage: " [-ti"IF_FEATURE_CPIO_O("o")"]" IF_FEATURE_CPIO_P(" [-p DIR]") //usage: " [EXTR_FILE]..." //usage:#define cpio_full_usage "\n\n" -//usage: "Extract or list files from a cpio archive" +//usage: "Extract (-i) or list (-t) files from a cpio archive" //usage: IF_FEATURE_CPIO_O(", or" -//usage: "\ncreate an archive" IF_FEATURE_CPIO_P(" (-o) or copy files (-p)") -//usage: " using file list on stdin" +//usage: "\ntake file list from stdin and create an archive (-o)" +//usage: IF_FEATURE_CPIO_P(" or copy files (-p)") //usage: ) //usage: "\n" //usage: "\nMain operation mode:" @@ -65,11 +66,13 @@ //usage: IF_FEATURE_CPIO_P( //usage: "\n -p DIR Copy files to DIR" //usage: ) +//usage: "\nOptions:" //usage: "\n -d Make leading directories" //usage: "\n -m Preserve mtime" //usage: "\n -v Verbose" //usage: "\n -u Overwrite" //usage: "\n -F FILE Input (-t,-i,-p) or output (-o) file" +//usage: "\n -R USER[:GRP] Set owner of created files" //usage: IF_FEATURE_CPIO_O( //usage: "\n -H newc Archive format" //usage: ) @@ -129,7 +132,7 @@ -I FILE File to use instead of standard input -L, --dereference Dereference symbolic links (copy the files that they point to instead of copying the links) - -R, --owner=[USER][:.][GROUP] Set owner of created files + -R, --owner=[USER][:.][GRP] Set owner of created files Options valid in --extract and --pass-through modes: -d, --make-directories Create leading directories where needed @@ -149,7 +152,8 @@ enum { OPT_PRESERVE_MTIME = (1 << 6), OPT_DEREF = (1 << 7), OPT_FILE = (1 << 8), - OPTBIT_FILE = 8, + OPT_OWNER = (1 << 9), + OPTBIT_OWNER = 9, IF_FEATURE_CPIO_O(OPTBIT_CREATE ,) IF_FEATURE_CPIO_O(OPTBIT_FORMAT ,) IF_FEATURE_CPIO_P(OPTBIT_PASSTHROUGH,) @@ -162,7 +166,18 @@ enum { OPT_2STDOUT = IF_LONG_OPTS( (1 << OPTBIT_2STDOUT )) + 0, }; -#define OPTION_STR "it0uvdmLF:" +#define OPTION_STR "it0uvdmLF:R:" + +struct globals { + struct bb_uidgid_t owner_ugid; +} FIX_ALIASING; +#define G (*(struct globals*)bb_common_bufsiz1) +void BUG_cpio_globals_too_big(void); +#define INIT_G() do { \ + setup_common_bufsiz(); \ + G.owner_ugid.uid = -1L; \ + G.owner_ugid.gid = -1L; \ +} while (0) #if ENABLE_FEATURE_CPIO_O static off_t cpio_pad4(off_t size) @@ -180,7 +195,6 @@ static off_t cpio_pad4(off_t size) * It's ok to exit instead of return. */ static NOINLINE int cpio_o(void) { - static const char trailer[] ALIGN1 = "TRAILER!!!"; struct name_s { struct name_s *next; char name[1]; @@ -222,6 +236,11 @@ static NOINLINE int cpio_o(void) bb_simple_perror_msg_and_die(name); } + if (G.owner_ugid.uid != (uid_t)-1L) + st.st_uid = G.owner_ugid.uid; + if (G.owner_ugid.gid != (gid_t)-1L) + st.st_gid = G.owner_ugid.gid; + if (!(S_ISLNK(st.st_mode) || S_ISREG(st.st_mode))) st.st_size = 0; /* paranoia */ @@ -256,7 +275,6 @@ static NOINLINE int cpio_o(void) free(line); continue; } - } else { /* line == NULL: EOF */ next_link: if (links) { @@ -275,7 +293,7 @@ static NOINLINE int cpio_o(void) } else { /* If no (more) hardlinks to output, * output "trailer" entry */ - name = trailer; + name = cpio_TRAILER; /* st.st_size == 0 is a must, but for uniformity * in the output, we zero out everything */ memset(&st, 0, sizeof(st)); @@ -323,7 +341,7 @@ static NOINLINE int cpio_o(void) } if (!line) { - if (name != trailer) + if (name != cpio_TRAILER) goto next_link; /* TODO: GNU cpio pads trailer to 512 bytes, do we want that? */ return EXIT_SUCCESS; @@ -339,6 +357,7 @@ int cpio_main(int argc UNUSED_PARAM, char **argv) { archive_handle_t *archive_handle; char *cpio_filename; + char *cpio_owner; IF_FEATURE_CPIO_O(const char *cpio_fmt = "";) unsigned opt; @@ -353,12 +372,14 @@ int cpio_main(int argc UNUSED_PARAM, char **argv) "pass-through\0" No_argument "p" #endif #endif + "owner\0" Required_argument "R" "verbose\0" No_argument "v" "quiet\0" No_argument "\xff" "to-stdout\0" No_argument "\xfe" ; #endif + INIT_G(); archive_handle = init_handle(); /* archive_handle->src_fd = STDIN_FILENO; - done by init_handle */ archive_handle->ah_flags = ARCHIVE_EXTRACT_NEWER; @@ -369,14 +390,21 @@ int cpio_main(int argc UNUSED_PARAM, char **argv) /* -L makes sense only with -o or -p */ #if !ENABLE_FEATURE_CPIO_O - opt = getopt32(argv, OPTION_STR, &cpio_filename); + opt = getopt32(argv, OPTION_STR, &cpio_filename, &cpio_owner); +#else + opt = getopt32(argv, OPTION_STR "oH:" IF_FEATURE_CPIO_P("p"), + &cpio_filename, &cpio_owner, &cpio_fmt); +#endif argv += optind; + if (opt & OPT_OWNER) { /* -R */ + parse_chown_usergroup_or_die(&G.owner_ugid, cpio_owner); + archive_handle->cpio__owner = G.owner_ugid; + } +#if !ENABLE_FEATURE_CPIO_O if (opt & OPT_FILE) { /* -F */ xmove_fd(xopen(cpio_filename, O_RDONLY), STDIN_FILENO); } #else - opt = getopt32(argv, OPTION_STR "oH:" IF_FEATURE_CPIO_P("p"), &cpio_filename, &cpio_fmt); - argv += optind; if ((opt & (OPT_FILE|OPT_CREATE)) == OPT_FILE) { /* -F without -o */ xmove_fd(xopen(cpio_filename, O_RDONLY), STDIN_FILENO); } |