diff --git a/archival/unzip.c b/archival/unzip.c index b27dd2187..691a2d81b 100644 --- a/archival/unzip.c +++ b/archival/unzip.c @@ -56,7 +56,7 @@ //kbuild:lib-$(CONFIG_UNZIP) += unzip.o //usage:#define unzip_trivial_usage -//usage: "[-lnojpq] FILE[.zip] [FILE]... [-x FILE]... [-d DIR]" +//usage: "[-lnojpqK] FILE[.zip] [FILE]... [-x FILE]... [-d DIR]" //usage:#define unzip_full_usage "\n\n" //usage: "Extract FILEs from ZIP archive\n" //usage: "\n -l List contents (with -q for short form)" @@ -66,6 +66,7 @@ //usage: "\n -p Write to stdout" //usage: "\n -t Test" //usage: "\n -q Quiet" +//usage: "\n -K Do not clear SUID bit" //usage: "\n -x FILE Exclude FILEs" //usage: "\n -d DIR Extract into DIR" @@ -494,6 +495,7 @@ int unzip_main(int argc, char **argv) OPT_l = (1 << 0), OPT_x = (1 << 1), OPT_j = (1 << 2), + OPT_K = (1 << 3), }; unsigned opts; smallint quiet = 0; @@ -559,7 +561,7 @@ int unzip_main(int argc, char **argv) opts = 0; /* '-' makes getopt return 1 for non-options */ - while ((i = getopt(argc, argv, "-d:lnotpqxjv")) != -1) { + while ((i = getopt(argc, argv, "-d:lnotpqxjvK")) != -1) { switch (i) { case 'd': /* Extract to base directory */ base_dir = optarg; @@ -602,6 +604,10 @@ int unzip_main(int argc, char **argv) opts |= OPT_j; break; + case 'K': + opts |= OPT_K; + break; + case 1: if (!src_fn) { /* The zip file */ @@ -819,7 +825,10 @@ int unzip_main(int argc, char **argv) # endif if ((cdf.fmt.version_made_by >> 8) == 3) { /* This archive is created on Unix */ - dir_mode = file_mode = (cdf.fmt.external_attributes >> 16); + file_mode = (cdf.fmt.external_attributes >> 16); + if (!(opts & OPT_K)) + file_mode &= ~(mode_t)(S_ISUID | S_ISGID); + dir_mode = file_mode; } } #endif