unzip: implement -j, closes 9126
function old new delta unzip_main 2642 2703 +61 packed_usage 31747 31770 +23 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 2/0 up/down: 84/0) Total: 84 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
@ -62,6 +62,7 @@
|
|||||||
//usage: "\n -l List contents (with -q for short form)"
|
//usage: "\n -l List contents (with -q for short form)"
|
||||||
//usage: "\n -n Never overwrite files (default: ask)"
|
//usage: "\n -n Never overwrite files (default: ask)"
|
||||||
//usage: "\n -o Overwrite"
|
//usage: "\n -o Overwrite"
|
||||||
|
//usage: "\n -j Do not restore paths"
|
||||||
//usage: "\n -p Print to stdout"
|
//usage: "\n -p Print to stdout"
|
||||||
//usage: "\n -q Quiet"
|
//usage: "\n -q Quiet"
|
||||||
//usage: "\n -x FILE Exclude FILEs"
|
//usage: "\n -x FILE Exclude FILEs"
|
||||||
@ -455,13 +456,16 @@ static int get_lstat_mode(const char *dst_fn)
|
|||||||
int unzip_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
|
int unzip_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
|
||||||
int unzip_main(int argc, char **argv)
|
int unzip_main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
enum { O_PROMPT, O_NEVER, O_ALWAYS };
|
enum {
|
||||||
|
OPT_l = (1 << 0),
|
||||||
|
OPT_x = (1 << 1),
|
||||||
|
OPT_j = (1 << 2),
|
||||||
|
};
|
||||||
|
unsigned opts;
|
||||||
smallint quiet = 0;
|
smallint quiet = 0;
|
||||||
IF_NOT_FEATURE_UNZIP_CDF(const) smallint verbose = 0;
|
IF_NOT_FEATURE_UNZIP_CDF(const) smallint verbose = 0;
|
||||||
smallint listing = 0;
|
enum { O_PROMPT, O_NEVER, O_ALWAYS };
|
||||||
smallint overwrite = O_PROMPT;
|
smallint overwrite = O_PROMPT;
|
||||||
smallint x_opt_seen;
|
|
||||||
uint32_t cdf_offset;
|
uint32_t cdf_offset;
|
||||||
unsigned long total_usize;
|
unsigned long total_usize;
|
||||||
unsigned long total_size;
|
unsigned long total_size;
|
||||||
@ -472,7 +476,7 @@ int unzip_main(int argc, char **argv)
|
|||||||
llist_t *zaccept = NULL;
|
llist_t *zaccept = NULL;
|
||||||
llist_t *zreject = NULL;
|
llist_t *zreject = NULL;
|
||||||
char *base_dir = NULL;
|
char *base_dir = NULL;
|
||||||
int i, opt;
|
int i;
|
||||||
char key_buf[80]; /* must match size used by my_fgets80 */
|
char key_buf[80]; /* must match size used by my_fgets80 */
|
||||||
|
|
||||||
/* -q, -l and -v: UnZip 5.52 of 28 February 2005, by Info-ZIP:
|
/* -q, -l and -v: UnZip 5.52 of 28 February 2005, by Info-ZIP:
|
||||||
@ -516,16 +520,16 @@ int unzip_main(int argc, char **argv)
|
|||||||
* 204372 1 file
|
* 204372 1 file
|
||||||
*/
|
*/
|
||||||
|
|
||||||
x_opt_seen = 0;
|
opts = 0;
|
||||||
/* '-' makes getopt return 1 for non-options */
|
/* '-' makes getopt return 1 for non-options */
|
||||||
while ((opt = getopt(argc, argv, "-d:lnopqxv")) != -1) {
|
while ((i = getopt(argc, argv, "-d:lnopqxjv")) != -1) {
|
||||||
switch (opt) {
|
switch (i) {
|
||||||
case 'd': /* Extract to base directory */
|
case 'd': /* Extract to base directory */
|
||||||
base_dir = optarg;
|
base_dir = optarg;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'l': /* List */
|
case 'l': /* List */
|
||||||
listing = 1;
|
opts |= OPT_l;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'n': /* Never overwrite existing files */
|
case 'n': /* Never overwrite existing files */
|
||||||
@ -545,11 +549,15 @@ int unzip_main(int argc, char **argv)
|
|||||||
|
|
||||||
case 'v': /* Verbose list */
|
case 'v': /* Verbose list */
|
||||||
IF_FEATURE_UNZIP_CDF(verbose++;)
|
IF_FEATURE_UNZIP_CDF(verbose++;)
|
||||||
listing = 1;
|
opts |= OPT_l;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'x':
|
case 'x':
|
||||||
x_opt_seen = 1;
|
opts |= OPT_x;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'j':
|
||||||
|
opts |= OPT_j;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
@ -558,7 +566,7 @@ int unzip_main(int argc, char **argv)
|
|||||||
/* +5: space for ".zip" and NUL */
|
/* +5: space for ".zip" and NUL */
|
||||||
src_fn = xmalloc(strlen(optarg) + 5);
|
src_fn = xmalloc(strlen(optarg) + 5);
|
||||||
strcpy(src_fn, optarg);
|
strcpy(src_fn, optarg);
|
||||||
} else if (!x_opt_seen) {
|
} else if (!(opts & OPT_x)) {
|
||||||
/* Include files */
|
/* Include files */
|
||||||
llist_add_to(&zaccept, optarg);
|
llist_add_to(&zaccept, optarg);
|
||||||
} else {
|
} else {
|
||||||
@ -626,7 +634,7 @@ int unzip_main(int argc, char **argv)
|
|||||||
if (quiet <= 1) { /* not -qq */
|
if (quiet <= 1) { /* not -qq */
|
||||||
if (quiet == 0)
|
if (quiet == 0)
|
||||||
printf("Archive: %s\n", src_fn);
|
printf("Archive: %s\n", src_fn);
|
||||||
if (listing) {
|
if (opts & OPT_l) {
|
||||||
puts(verbose ?
|
puts(verbose ?
|
||||||
" Length Method Size Cmpr Date Time CRC-32 Name\n"
|
" Length Method Size Cmpr Date Time CRC-32 Name\n"
|
||||||
"-------- ------ ------- ---- ---------- ----- -------- ----"
|
"-------- ------ ------- ---- ---------- ----- -------- ----"
|
||||||
@ -778,13 +786,19 @@ int unzip_main(int argc, char **argv)
|
|||||||
free(dst_fn);
|
free(dst_fn);
|
||||||
dst_fn = xzalloc(zip.fmt.filename_len + 1);
|
dst_fn = xzalloc(zip.fmt.filename_len + 1);
|
||||||
xread(zip_fd, dst_fn, zip.fmt.filename_len);
|
xread(zip_fd, dst_fn, zip.fmt.filename_len);
|
||||||
|
|
||||||
/* Skip extra header bytes */
|
/* Skip extra header bytes */
|
||||||
unzip_skip(zip.fmt.extra_len);
|
unzip_skip(zip.fmt.extra_len);
|
||||||
|
|
||||||
/* Guard against "/abspath", "/../" and similar attacks */
|
/* Guard against "/abspath", "/../" and similar attacks */
|
||||||
overlapping_strcpy(dst_fn, strip_unsafe_prefix(dst_fn));
|
overlapping_strcpy(dst_fn, strip_unsafe_prefix(dst_fn));
|
||||||
|
|
||||||
|
if (opts & OPT_j) /* Strip paths? */
|
||||||
|
overlapping_strcpy(dst_fn, bb_basename(dst_fn));
|
||||||
|
|
||||||
|
/* Did this strip everything ("DIR/" case)? Then skip */
|
||||||
|
if (!dst_fn[0])
|
||||||
|
goto skip_cmpsize;
|
||||||
|
|
||||||
/* Filter zip entries */
|
/* Filter zip entries */
|
||||||
if (find_list_entry(zreject, dst_fn)
|
if (find_list_entry(zreject, dst_fn)
|
||||||
|| (zaccept && !find_list_entry(zaccept, dst_fn))
|
|| (zaccept && !find_list_entry(zaccept, dst_fn))
|
||||||
@ -792,7 +806,7 @@ int unzip_main(int argc, char **argv)
|
|||||||
goto skip_cmpsize;
|
goto skip_cmpsize;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (listing) {
|
if (opts & OPT_l) {
|
||||||
/* List entry */
|
/* List entry */
|
||||||
char dtbuf[sizeof("mm-dd-yyyy hh:mm")];
|
char dtbuf[sizeof("mm-dd-yyyy hh:mm")];
|
||||||
sprintf(dtbuf, "%02u-%02u-%04u %02u:%02u",
|
sprintf(dtbuf, "%02u-%02u-%04u %02u:%02u",
|
||||||
@ -960,7 +974,7 @@ int unzip_main(int argc, char **argv)
|
|||||||
total_entries++;
|
total_entries++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (listing && quiet <= 1) {
|
if ((opts & OPT_l) && quiet <= 1) {
|
||||||
if (!verbose) {
|
if (!verbose) {
|
||||||
// " Length Date Time Name\n"
|
// " Length Date Time Name\n"
|
||||||
// "--------- ---------- ----- ----"
|
// "--------- ---------- ----- ----"
|
||||||
|
Reference in New Issue
Block a user