archival: add option -k "keep" to gzip/bzip2/lzop, add -U "nokeep" to lzop

function                                             old     new   delta
bbunpack                                             745     779     +34
lzop_main                                             93     121     +28
do_lzo_compress                                      320     328      +8
packed_usage                                       31685   31653     -32
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 3/1 up/down: 70/-32)             Total: 38 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
Denys Vlasenko 2017-06-15 18:07:04 +02:00
parent 5d72ae53c9
commit 1c013fae28
4 changed files with 81 additions and 43 deletions

View File

@ -21,10 +21,11 @@ enum {
OPT_STDOUT = 1 << 0, OPT_STDOUT = 1 << 0,
OPT_FORCE = 1 << 1, OPT_FORCE = 1 << 1,
/* only some decompressors: */ /* only some decompressors: */
OPT_VERBOSE = 1 << 2, OPT_KEEP = 1 << 2,
OPT_QUIET = 1 << 3, OPT_VERBOSE = 1 << 3,
OPT_DECOMPRESS = 1 << 4, OPT_QUIET = 1 << 4,
OPT_TEST = 1 << 5, OPT_DECOMPRESS = 1 << 5,
OPT_TEST = 1 << 6,
SEAMLESS_MAGIC = (1 << 31) * ENABLE_ZCAT * SEAMLESS_COMPRESSION, SEAMLESS_MAGIC = (1 << 31) * ENABLE_ZCAT * SEAMLESS_COMPRESSION,
}; };
@ -182,8 +183,11 @@ int FAST_FUNC bbunpack(char **argv,
} }
/* Delete _source_ file */ /* Delete _source_ file */
del = filename; del = filename;
if (option_mask32 & OPT_KEEP) /* ... unless -k */
del = NULL;
} }
xunlink(del); if (del)
xunlink(del);
free_name: free_name:
if (new_name != filename) if (new_name != filename)
free(new_name); free(new_name);
@ -240,7 +244,16 @@ char* FAST_FUNC make_new_name_generic(char *filename, const char *expected_ext)
int uncompress_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int uncompress_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
int uncompress_main(int argc UNUSED_PARAM, char **argv) int uncompress_main(int argc UNUSED_PARAM, char **argv)
{ {
// (N)compress 4.2.4.4:
// -d If given, decompression is done instead
// -c Write output on stdout, don't remove original
// -b Parameter limits the max number of bits/code
// -f Forces output file to be generated
// -v Write compression statistics
// -V Output vesion and compile options
// -r Recursive. If a filename is a directory, descend into it and compress everything
getopt32(argv, "cf"); getopt32(argv, "cf");
argv += optind; argv += optind;
return bbunpack(argv, unpack_Z_stream, make_new_name_generic, "Z"); return bbunpack(argv, unpack_Z_stream, make_new_name_generic, "Z");
@ -273,11 +286,12 @@ int uncompress_main(int argc UNUSED_PARAM, char **argv)
* Ken Turkowski, Dave Mack and Peter Jannesen. * Ken Turkowski, Dave Mack and Peter Jannesen.
*/ */
//usage:#define gunzip_trivial_usage //usage:#define gunzip_trivial_usage
//usage: "[-cft] [FILE]..." //usage: "[-cfkt] [FILE]..."
//usage:#define gunzip_full_usage "\n\n" //usage:#define gunzip_full_usage "\n\n"
//usage: "Decompress FILEs (or stdin)\n" //usage: "Decompress FILEs (or stdin)\n"
//usage: "\n -c Write to stdout" //usage: "\n -c Write to stdout"
//usage: "\n -f Force" //usage: "\n -f Force"
//usage: "\n -k Keep input files"
//usage: "\n -t Test file integrity" //usage: "\n -t Test file integrity"
//usage: //usage:
//usage:#define gunzip_example_usage //usage:#define gunzip_example_usage
@ -372,7 +386,7 @@ int gunzip_main(int argc UNUSED_PARAM, char **argv)
#if ENABLE_FEATURE_GUNZIP_LONG_OPTIONS #if ENABLE_FEATURE_GUNZIP_LONG_OPTIONS
applet_long_options = gunzip_longopts; applet_long_options = gunzip_longopts;
#endif #endif
getopt32(argv, "cfvqdtn"); getopt32(argv, "cfkvqdtn");
argv += optind; argv += optind;
/* If called as zcat... /* If called as zcat...
@ -394,11 +408,12 @@ int gunzip_main(int argc UNUSED_PARAM, char **argv)
* Licensed under GPLv2 or later, see file LICENSE in this source tree. * Licensed under GPLv2 or later, see file LICENSE in this source tree.
*/ */
//usage:#define bunzip2_trivial_usage //usage:#define bunzip2_trivial_usage
//usage: "[-cf] [FILE]..." //usage: "[-cfk] [FILE]..."
//usage:#define bunzip2_full_usage "\n\n" //usage:#define bunzip2_full_usage "\n\n"
//usage: "Decompress FILEs (or stdin)\n" //usage: "Decompress FILEs (or stdin)\n"
//usage: "\n -c Write to stdout" //usage: "\n -c Write to stdout"
//usage: "\n -f Force" //usage: "\n -f Force"
//usage: "\n -k Keep input files"
//usage:#define bzcat_trivial_usage //usage:#define bzcat_trivial_usage
//usage: "[FILE]..." //usage: "[FILE]..."
//usage:#define bzcat_full_usage "\n\n" //usage:#define bzcat_full_usage "\n\n"
@ -432,7 +447,7 @@ int gunzip_main(int argc UNUSED_PARAM, char **argv)
int bunzip2_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int bunzip2_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
int bunzip2_main(int argc UNUSED_PARAM, char **argv) int bunzip2_main(int argc UNUSED_PARAM, char **argv)
{ {
getopt32(argv, "cfvqdt"); getopt32(argv, "cfkvqdt");
argv += optind; argv += optind;
if (ENABLE_BZCAT && applet_name[2] == 'c') /* bzcat */ if (ENABLE_BZCAT && applet_name[2] == 'c') /* bzcat */
option_mask32 |= OPT_STDOUT; option_mask32 |= OPT_STDOUT;
@ -451,19 +466,21 @@ int bunzip2_main(int argc UNUSED_PARAM, char **argv)
* Licensed under GPLv2, see file LICENSE in this source tree. * Licensed under GPLv2, see file LICENSE in this source tree.
*/ */
//usage:#define unlzma_trivial_usage //usage:#define unlzma_trivial_usage
//usage: "[-cf] [FILE]..." //usage: "[-cfk] [FILE]..."
//usage:#define unlzma_full_usage "\n\n" //usage:#define unlzma_full_usage "\n\n"
//usage: "Decompress FILE (or stdin)\n" //usage: "Decompress FILE (or stdin)\n"
//usage: "\n -c Write to stdout" //usage: "\n -c Write to stdout"
//usage: "\n -f Force" //usage: "\n -f Force"
//usage: "\n -k Keep input files"
//usage: //usage:
//usage:#define lzma_trivial_usage //usage:#define lzma_trivial_usage
//usage: "-d [-cf] [FILE]..." //usage: "-d [-cfk] [FILE]..."
//usage:#define lzma_full_usage "\n\n" //usage:#define lzma_full_usage "\n\n"
//usage: "Decompress FILE (or stdin)\n" //usage: "Decompress FILE (or stdin)\n"
//usage: "\n -d Decompress" //usage: "\n -d Decompress"
//usage: "\n -c Write to stdout" //usage: "\n -c Write to stdout"
//usage: "\n -f Force" //usage: "\n -f Force"
//usage: "\n -k Keep input files"
//usage: //usage:
//usage:#define lzcat_trivial_usage //usage:#define lzcat_trivial_usage
//usage: "[FILE]..." //usage: "[FILE]..."
@ -520,7 +537,7 @@ int bunzip2_main(int argc UNUSED_PARAM, char **argv)
int unlzma_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int unlzma_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
int unlzma_main(int argc UNUSED_PARAM, char **argv) int unlzma_main(int argc UNUSED_PARAM, char **argv)
{ {
IF_LZMA(int opts =) getopt32(argv, "cfvqdt"); IF_LZMA(int opts =) getopt32(argv, "cfkvqdt");
# if ENABLE_LZMA # if ENABLE_LZMA
/* lzma without -d or -t? */ /* lzma without -d or -t? */
if (applet_name[2] == 'm' && !(opts & (OPT_DECOMPRESS|OPT_TEST))) if (applet_name[2] == 'm' && !(opts & (OPT_DECOMPRESS|OPT_TEST)))
@ -537,19 +554,21 @@ int unlzma_main(int argc UNUSED_PARAM, char **argv)
//usage:#define unxz_trivial_usage //usage:#define unxz_trivial_usage
//usage: "[-cf] [FILE]..." //usage: "[-cfk] [FILE]..."
//usage:#define unxz_full_usage "\n\n" //usage:#define unxz_full_usage "\n\n"
//usage: "Decompress FILE (or stdin)\n" //usage: "Decompress FILE (or stdin)\n"
//usage: "\n -c Write to stdout" //usage: "\n -c Write to stdout"
//usage: "\n -f Force" //usage: "\n -f Force"
//usage: "\n -k Keep input files"
//usage: //usage:
//usage:#define xz_trivial_usage //usage:#define xz_trivial_usage
//usage: "-d [-cf] [FILE]..." //usage: "-d [-cfk] [FILE]..."
//usage:#define xz_full_usage "\n\n" //usage:#define xz_full_usage "\n\n"
//usage: "Decompress FILE (or stdin)\n" //usage: "Decompress FILE (or stdin)\n"
//usage: "\n -d Decompress" //usage: "\n -d Decompress"
//usage: "\n -c Write to stdout" //usage: "\n -c Write to stdout"
//usage: "\n -f Force" //usage: "\n -f Force"
//usage: "\n -k Keep input files"
//usage: //usage:
//usage:#define xzcat_trivial_usage //usage:#define xzcat_trivial_usage
//usage: "[FILE]..." //usage: "[FILE]..."
@ -586,7 +605,7 @@ int unlzma_main(int argc UNUSED_PARAM, char **argv)
int unxz_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int unxz_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
int unxz_main(int argc UNUSED_PARAM, char **argv) int unxz_main(int argc UNUSED_PARAM, char **argv)
{ {
IF_XZ(int opts =) getopt32(argv, "cfvqdt"); IF_XZ(int opts =) getopt32(argv, "cfkvqdt");
# if ENABLE_XZ # if ENABLE_XZ
/* xz without -d or -t? */ /* xz without -d or -t? */
if (applet_name[2] == '\0' && !(opts & (OPT_DECOMPRESS|OPT_TEST))) if (applet_name[2] == '\0' && !(opts & (OPT_DECOMPRESS|OPT_TEST)))

View File

@ -43,6 +43,7 @@
//usage: ) //usage: )
//usage: "\n -c Write to stdout" //usage: "\n -c Write to stdout"
//usage: "\n -f Force" //usage: "\n -f Force"
//usage: "\n -k Keep input files"
#include "libbb.h" #include "libbb.h"
#include "bb_archive.h" #include "bb_archive.h"
@ -196,13 +197,13 @@ int bzip2_main(int argc UNUSED_PARAM, char **argv)
opt_complementary = "s2"; /* -s means -2 (compatibility) */ opt_complementary = "s2"; /* -s means -2 (compatibility) */
/* Must match bbunzip's constants OPT_STDOUT, OPT_FORCE! */ /* Must match bbunzip's constants OPT_STDOUT, OPT_FORCE! */
opt = getopt32(argv, "cfv" IF_FEATURE_BZIP2_DECOMPRESS("dt") "123456789qzs"); opt = getopt32(argv, "cfkv" IF_FEATURE_BZIP2_DECOMPRESS("dt") "123456789qzs");
#if ENABLE_FEATURE_BZIP2_DECOMPRESS /* bunzip2_main may not be visible... */ #if ENABLE_FEATURE_BZIP2_DECOMPRESS /* bunzip2_main may not be visible... */
if (opt & 0x18) // -d and/or -t if (opt & 0x30) // -d and/or -t
return bunzip2_main(argc, argv); return bunzip2_main(argc, argv);
opt >>= 5; opt >>= 6;
#else #else
opt >>= 3; opt >>= 4;
#endif #endif
opt = (uint8_t)opt; /* isolate bits for -1..-8 */ opt = (uint8_t)opt; /* isolate bits for -1..-8 */
opt |= 0x100; /* if nothing else, assume -9 */ opt |= 0x100; /* if nothing else, assume -9 */
@ -213,6 +214,6 @@ int bzip2_main(int argc UNUSED_PARAM, char **argv)
} }
argv += optind; argv += optind;
option_mask32 &= 0x7; /* ignore all except -cfv */ option_mask32 &= 0xf; /* ignore all except -cfkv */
return bbunpack(argv, compressStream, append_ext, "bz2"); return bbunpack(argv, compressStream, append_ext, "bz2");
} }

View File

@ -84,7 +84,7 @@ aa: 85.1% -- replaced with aa.gz
//kbuild:lib-$(CONFIG_GZIP) += gzip.o //kbuild:lib-$(CONFIG_GZIP) += gzip.o
//usage:#define gzip_trivial_usage //usage:#define gzip_trivial_usage
//usage: "[-cf" IF_FEATURE_GZIP_DECOMPRESS("dt") IF_FEATURE_GZIP_LEVELS("123456789") "] [FILE]..." //usage: "[-cfk" IF_FEATURE_GZIP_DECOMPRESS("dt") IF_FEATURE_GZIP_LEVELS("123456789") "] [FILE]..."
//usage:#define gzip_full_usage "\n\n" //usage:#define gzip_full_usage "\n\n"
//usage: "Compress FILEs (or stdin)\n" //usage: "Compress FILEs (or stdin)\n"
//usage: IF_FEATURE_GZIP_LEVELS( //usage: IF_FEATURE_GZIP_LEVELS(
@ -96,6 +96,7 @@ aa: 85.1% -- replaced with aa.gz
//usage: ) //usage: )
//usage: "\n -c Write to stdout" //usage: "\n -c Write to stdout"
//usage: "\n -f Force" //usage: "\n -f Force"
//usage: "\n -k Keep input files"
//usage: //usage:
//usage:#define gzip_example_usage //usage:#define gzip_example_usage
//usage: "$ ls -la /tmp/busybox*\n" //usage: "$ ls -la /tmp/busybox*\n"
@ -2219,13 +2220,13 @@ int gzip_main(int argc UNUSED_PARAM, char **argv)
applet_long_options = gzip_longopts; applet_long_options = gzip_longopts;
#endif #endif
/* Must match bbunzip's constants OPT_STDOUT, OPT_FORCE! */ /* Must match bbunzip's constants OPT_STDOUT, OPT_FORCE! */
opt = getopt32(argv, "cfv" IF_FEATURE_GZIP_DECOMPRESS("dt") "qn123456789"); opt = getopt32(argv, "cfkv" IF_FEATURE_GZIP_DECOMPRESS("dt") "qn123456789");
#if ENABLE_FEATURE_GZIP_DECOMPRESS /* gunzip_main may not be visible... */ #if ENABLE_FEATURE_GZIP_DECOMPRESS /* gunzip_main may not be visible... */
if (opt & 0x18) // -d and/or -t if (opt & 0x30) // -d and/or -t
return gunzip_main(argc, argv); return gunzip_main(argc, argv);
#endif #endif
#if ENABLE_FEATURE_GZIP_LEVELS #if ENABLE_FEATURE_GZIP_LEVELS
opt >>= ENABLE_FEATURE_GZIP_DECOMPRESS ? 7 : 5; /* drop cfv[dt]qn bits */ opt >>= ENABLE_FEATURE_GZIP_DECOMPRESS ? 8 : 6; /* drop cfkv[dt]qn bits */
if (opt == 0) if (opt == 0)
opt = 1 << 6; /* default: 6 */ opt = 1 << 6; /* default: 6 */
opt = ffs(opt >> 4); /* Maps -1..-4 to [0], -5 to [1] ... -9 to [5] */ opt = ffs(opt >> 4); /* Maps -1..-4 to [0], -5 to [1] ... -9 to [5] */
@ -2234,7 +2235,7 @@ int gzip_main(int argc UNUSED_PARAM, char **argv)
max_lazy_match = gzip_level_config[opt].lazy2 * 2; max_lazy_match = gzip_level_config[opt].lazy2 * 2;
nice_match = gzip_level_config[opt].nice2 * 2; nice_match = gzip_level_config[opt].nice2 * 2;
#endif #endif
option_mask32 &= 0x7; /* retain only -cfv */ option_mask32 &= 0xf; /* retain only -cfkv */
/* Allocate all global buffers (for DYN_ALLOC option) */ /* Allocate all global buffers (for DYN_ALLOC option) */
ALLOC(uch, G1.l_buf, INBUFSIZ); ALLOC(uch, G1.l_buf, INBUFSIZ);

View File

@ -33,13 +33,13 @@
//config: //config:
//config:config UNLZOP //config:config UNLZOP
//config: bool "unlzop" //config: bool "unlzop"
//config: default y //config: default n # INCOMPAT: upstream lzop does not provide such tool
//config: help //config: help
//config: Lzop decompresion. //config: Lzop decompresion.
//config: //config:
//config:config LZOPCAT //config:config LZOPCAT
//config: bool "lzopcat" //config: bool "lzopcat"
//config: default y //config: default n # INCOMPAT: upstream lzop does not provide such tool
//config: help //config: help
//config: Alias to "unlzop -c". //config: Alias to "unlzop -c".
//config: //config:
@ -61,12 +61,14 @@
//kbuild:lib-$(CONFIG_LZOPCAT) += lzop.o //kbuild:lib-$(CONFIG_LZOPCAT) += lzop.o
//usage:#define lzop_trivial_usage //usage:#define lzop_trivial_usage
//usage: "[-cfvd123456789CF] [FILE]..." //usage: "[-cfUvd123456789CF] [FILE]..."
//usage:#define lzop_full_usage "\n\n" //usage:#define lzop_full_usage "\n\n"
//usage: " -1..9 Compression level" //usage: " -1..9 Compression level"
//usage: "\n -d Decompress" //usage: "\n -d Decompress"
//usage: "\n -c Write to stdout" //usage: "\n -c Write to stdout"
//usage: "\n -f Force" //usage: "\n -f Force"
//usage: "\n -U Delete input files"
///////: "\n -k Keep input files" (default, so why bother documenting?)
//usage: "\n -v Verbose" //usage: "\n -v Verbose"
//usage: "\n -F Don't store or verify checksum" //usage: "\n -F Don't store or verify checksum"
//usage: "\n -C Also write checksum of compressed block" //usage: "\n -C Also write checksum of compressed block"
@ -78,10 +80,12 @@
//usage: "\n -F Don't verify checksum" //usage: "\n -F Don't verify checksum"
//usage: //usage:
//usage:#define unlzop_trivial_usage //usage:#define unlzop_trivial_usage
//usage: "[-cfvF] [FILE]..." //usage: "[-cfkvF] [FILE]..."
//usage:#define unlzop_full_usage "\n\n" //usage:#define unlzop_full_usage "\n\n"
//usage: " -c Write to stdout" //usage: " -c Write to stdout"
//usage: "\n -f Force" //usage: "\n -f Force"
//usage: "\n -U Delete input files"
///////: "\n -k Keep input files" (default, so why bother documenting?)
//usage: "\n -v Verbose" //usage: "\n -v Verbose"
//usage: "\n -F Don't verify checksum" //usage: "\n -F Don't verify checksum"
@ -472,27 +476,33 @@ struct globals {
//#define LZOP_VERSION_STRING "1.01" //#define LZOP_VERSION_STRING "1.01"
//#define LZOP_VERSION_DATE "Apr 27th 2003" //#define LZOP_VERSION_DATE "Apr 27th 2003"
#define OPTION_STRING "cfvqdt123456789CF" // lzop wants to be weird:
// unlike all other compressosrs, its -k "keep" option is the default,
// and -U is used to delete the source. We will invert the bit after getopt().
#define OPTION_STRING "cfUvqdt123456789CFk"
/* Note: must be kept in sync with archival/bbunzip.c */ /* Note: must be kept in sync with archival/bbunzip.c */
enum { enum {
OPT_STDOUT = (1 << 0), OPT_STDOUT = (1 << 0),
OPT_FORCE = (1 << 1), OPT_FORCE = (1 << 1),
OPT_VERBOSE = (1 << 2), OPT_KEEP = (1 << 2),
OPT_QUIET = (1 << 3), OPT_VERBOSE = (1 << 3),
OPT_DECOMPRESS = (1 << 4), OPT_QUIET = (1 << 4),
OPT_TEST = (1 << 5), OPT_DECOMPRESS = (1 << 5),
OPT_1 = (1 << 6), OPT_TEST = (1 << 6),
OPT_2 = (1 << 7), OPT_1 = (1 << 7),
OPT_3 = (1 << 8), OPT_2 = (1 << 8),
OPT_4 = (1 << 9), OPT_3 = (1 << 9),
OPT_5 = (1 << 10), OPT_4 = (1 << 10),
OPT_6 = (1 << 11), OPT_5 = (1 << 11),
OPT_789 = (7 << 12), OPT_6 = (1 << 12),
OPT_7 = (1 << 13), OPT_7 = (1 << 13),
OPT_8 = (1 << 14), OPT_8 = (1 << 14),
OPT_C = (1 << 15), OPT_9 = (1 << 15),
OPT_F = (1 << 16), OPT_C = (1 << 16),
OPT_F = (1 << 17),
OPT_k = (1 << 18),
OPT_789 = OPT_7 | OPT_8 | OPT_9
}; };
/**********************************************************************/ /**********************************************************************/
@ -1125,6 +1135,13 @@ int lzop_main(int argc UNUSED_PARAM, char **argv)
{ {
getopt32(argv, OPTION_STRING); getopt32(argv, OPTION_STRING);
argv += optind; argv += optind;
/* -U is "anti -k", invert bit for bbunpack(): */
option_mask32 ^= OPT_KEEP;
/* -k disables -U (if any): */
/* opt_complementary = "k-U"; - nope, only handles -Uk, not -kU */
if (option_mask32 & OPT_k)
option_mask32 |= OPT_KEEP;
/* lzopcat? */ /* lzopcat? */
if (ENABLE_LZOPCAT && applet_name[4] == 'c') if (ENABLE_LZOPCAT && applet_name[4] == 'c')
option_mask32 |= (OPT_STDOUT | OPT_DECOMPRESS); option_mask32 |= (OPT_STDOUT | OPT_DECOMPRESS);