[PATCH] cpio: implement -R/--owner
Aaro Koskinen
aaro.koskinen at iki.fi
Thu Oct 15 19:43:35 UTC 2015
Implement -R/--owner to force ownership of files.
function old new delta
cpio_main 501 556 +55
usage_messages 40468 40504 +36
get_header_cpio 910 943 +33
cpio_o 814 844 +30
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 4/0 up/down: 154/0) Total: 154 bytes
Signed-off-by: Aaro Koskinen <aaro.koskinen at iki.fi>
---
archival/cpio.c | 40 ++++++++++++++++++++++++++++++-----
archival/libarchive/get_header_cpio.c | 6 ++++++
include/bb_archive.h | 1 +
3 files changed, 42 insertions(+), 5 deletions(-)
diff --git a/archival/cpio.c b/archival/cpio.c
index cdc16c1..05a20c7 100644
--- a/archival/cpio.c
+++ b/archival/cpio.c
@@ -71,6 +71,7 @@
//usage: "\n -v Verbose"
//usage: "\n -u Overwrite"
//usage: "\n -F FILE Input (-t,-i,-p) or output (-o) file"
+//usage: "\n -R UGID Set owner of created files"
//usage: IF_FEATURE_CPIO_O(
//usage: "\n -H newc Archive format"
//usage: )
@@ -150,7 +151,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,)
@@ -163,7 +165,20 @@ 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)
+#define owner_ugid (G.owner_ugid)
+void BUG_cpio_globals_too_big(void);
+#define INIT_G() do { \
+ if (sizeof(G) > COMMON_BUFSIZE) \
+ BUG_cpio_globals_too_big(); \
+ owner_ugid.uid = -1L; \
+ owner_ugid.gid = -1L; \
+} while (0)
#if ENABLE_FEATURE_CPIO_O
static off_t cpio_pad4(off_t size)
@@ -223,6 +238,11 @@ static NOINLINE int cpio_o(void)
bb_simple_perror_msg_and_die(name);
}
+ if (owner_ugid.uid != (uid_t)-1L)
+ st.st_uid = owner_ugid.uid;
+ if (owner_ugid.gid != (gid_t)-1L)
+ st.st_gid = owner_ugid.gid;
+
if (!(S_ISLNK(st.st_mode) || S_ISREG(st.st_mode)))
st.st_size = 0; /* paranoia */
@@ -339,6 +359,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 +374,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 +392,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) {
+ parse_chown_usergroup_or_die(&owner_ugid, cpio_owner);
+ archive_handle->cpio__owner = &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);
}
diff --git a/archival/libarchive/get_header_cpio.c b/archival/libarchive/get_header_cpio.c
index 7861d1f..1cfcf56 100644
--- a/archival/libarchive/get_header_cpio.c
+++ b/archival/libarchive/get_header_cpio.c
@@ -52,6 +52,12 @@ char FAST_FUNC get_header_cpio(archive_handle_t *archive_handle)
&major, &minor, &namesize) != 10)
bb_error_msg_and_die("damaged cpio file");
file_header->mode = mode;
+ if (archive_handle->cpio__owner) {
+ if (archive_handle->cpio__owner->uid != (uid_t)-1L)
+ uid = archive_handle->cpio__owner->uid;
+ if (archive_handle->cpio__owner->gid != (gid_t)-1L)
+ gid = archive_handle->cpio__owner->gid;
+ }
file_header->uid = uid;
file_header->gid = gid;
file_header->mtime = mtime;
diff --git a/include/bb_archive.h b/include/bb_archive.h
index 5d9e24c..84164e4 100644
--- a/include/bb_archive.h
+++ b/include/bb_archive.h
@@ -97,6 +97,7 @@ typedef struct archive_handle_t {
uoff_t cpio__blocks;
struct hardlinks_t *cpio__hardlinks_to_create;
struct hardlinks_t *cpio__created_hardlinks;
+ struct bb_uidgid_t *cpio__owner;
#endif
#if ENABLE_DPKG || ENABLE_DPKG_DEB
/* Temporary storage */
--
2.4.0
More information about the busybox
mailing list