archival: add option -k "keep" to gzip/bzip2/lzop, add -U "nokeep" to lzop
authorDenys Vlasenko <vda.linux@googlemail.com>
Thu, 15 Jun 2017 16:07:04 +0000 (18:07 +0200)
committerDenys Vlasenko <vda.linux@googlemail.com>
Thu, 15 Jun 2017 16:07:04 +0000 (18:07 +0200)
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>
archival/bbunzip.c
archival/bzip2.c
archival/gzip.c
archival/lzop.c

index 0e2a261f00164323bc0c4069a11f8b1b5c6e485c..c60f6e6df66738371a4ea1ed5b9d7401064da7f3 100644 (file)
@@ -21,10 +21,11 @@ enum {
        OPT_STDOUT     = 1 << 0,
        OPT_FORCE      = 1 << 1,
        /* only some decompressors: */
-       OPT_VERBOSE    = 1 << 2,
-       OPT_QUIET      = 1 << 3,
-       OPT_DECOMPRESS = 1 << 4,
-       OPT_TEST       = 1 << 5,
+       OPT_KEEP       = 1 << 2,
+       OPT_VERBOSE    = 1 << 3,
+       OPT_QUIET      = 1 << 4,
+       OPT_DECOMPRESS = 1 << 5,
+       OPT_TEST       = 1 << 6,
        SEAMLESS_MAGIC = (1 << 31) * ENABLE_ZCAT * SEAMLESS_COMPRESSION,
 };
 
@@ -182,8 +183,11 @@ int FAST_FUNC bbunpack(char **argv,
                                }
                                /* Delete _source_ file */
                                del = filename;
+                               if (option_mask32 & OPT_KEEP) /* ... unless -k */
+                                       del = NULL;
                        }
-                       xunlink(del);
+                       if (del)
+                               xunlink(del);
  free_name:
                        if (new_name != filename)
                                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 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");
+
        argv += optind;
 
        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.
  */
 //usage:#define gunzip_trivial_usage
-//usage:       "[-cft] [FILE]..."
+//usage:       "[-cfkt] [FILE]..."
 //usage:#define gunzip_full_usage "\n\n"
 //usage:       "Decompress FILEs (or stdin)\n"
 //usage:     "\n       -c      Write to stdout"
 //usage:     "\n       -f      Force"
+//usage:     "\n       -k      Keep input files"
 //usage:     "\n       -t      Test file integrity"
 //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
        applet_long_options = gunzip_longopts;
 #endif
-       getopt32(argv, "cfvqdtn");
+       getopt32(argv, "cfkvqdtn");
        argv += optind;
 
        /* 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.
  */
 //usage:#define bunzip2_trivial_usage
-//usage:       "[-cf] [FILE]..."
+//usage:       "[-cfk] [FILE]..."
 //usage:#define bunzip2_full_usage "\n\n"
 //usage:       "Decompress FILEs (or stdin)\n"
 //usage:     "\n       -c      Write to stdout"
 //usage:     "\n       -f      Force"
+//usage:     "\n       -k      Keep input files"
 //usage:#define bzcat_trivial_usage
 //usage:       "[FILE]..."
 //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 UNUSED_PARAM, char **argv)
 {
-       getopt32(argv, "cfvqdt");
+       getopt32(argv, "cfkvqdt");
        argv += optind;
        if (ENABLE_BZCAT && applet_name[2] == 'c') /* bzcat */
                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.
  */
 //usage:#define unlzma_trivial_usage
-//usage:       "[-cf] [FILE]..."
+//usage:       "[-cfk] [FILE]..."
 //usage:#define unlzma_full_usage "\n\n"
 //usage:       "Decompress FILE (or stdin)\n"
 //usage:     "\n       -c      Write to stdout"
 //usage:     "\n       -f      Force"
+//usage:     "\n       -k      Keep input files"
 //usage:
 //usage:#define lzma_trivial_usage
-//usage:       "-d [-cf] [FILE]..."
+//usage:       "-d [-cfk] [FILE]..."
 //usage:#define lzma_full_usage "\n\n"
 //usage:       "Decompress FILE (or stdin)\n"
 //usage:     "\n       -d      Decompress"
 //usage:     "\n       -c      Write to stdout"
 //usage:     "\n       -f      Force"
+//usage:     "\n       -k      Keep input files"
 //usage:
 //usage:#define lzcat_trivial_usage
 //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 UNUSED_PARAM, char **argv)
 {
-       IF_LZMA(int opts =) getopt32(argv, "cfvqdt");
+       IF_LZMA(int opts =) getopt32(argv, "cfkvqdt");
 # if ENABLE_LZMA
        /* lzma without -d or -t? */
        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:       "[-cf] [FILE]..."
+//usage:       "[-cfk] [FILE]..."
 //usage:#define unxz_full_usage "\n\n"
 //usage:       "Decompress FILE (or stdin)\n"
 //usage:     "\n       -c      Write to stdout"
 //usage:     "\n       -f      Force"
+//usage:     "\n       -k      Keep input files"
 //usage:
 //usage:#define xz_trivial_usage
-//usage:       "-d [-cf] [FILE]..."
+//usage:       "-d [-cfk] [FILE]..."
 //usage:#define xz_full_usage "\n\n"
 //usage:       "Decompress FILE (or stdin)\n"
 //usage:     "\n       -d      Decompress"
 //usage:     "\n       -c      Write to stdout"
 //usage:     "\n       -f      Force"
+//usage:     "\n       -k      Keep input files"
 //usage:
 //usage:#define xzcat_trivial_usage
 //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 UNUSED_PARAM, char **argv)
 {
-       IF_XZ(int opts =) getopt32(argv, "cfvqdt");
+       IF_XZ(int opts =) getopt32(argv, "cfkvqdt");
 # if ENABLE_XZ
        /* xz without -d or -t? */
        if (applet_name[2] == '\0' && !(opts & (OPT_DECOMPRESS|OPT_TEST)))
index 7e38e78b3471b8953b949c3c8c5be48926a43de5..8afa438022dfb877595f47f067b3bc8e0c100e24 100644 (file)
@@ -43,6 +43,7 @@
 //usage:       )
 //usage:     "\n       -c      Write to stdout"
 //usage:     "\n       -f      Force"
+//usage:     "\n       -k      Keep input files"
 
 #include "libbb.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) */
        /* 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 (opt & 0x18) // -d and/or -t
+       if (opt & 0x30) // -d and/or -t
                return bunzip2_main(argc, argv);
-       opt >>= 5;
+       opt >>= 6;
 #else
-       opt >>= 3;
+       opt >>= 4;
 #endif
        opt = (uint8_t)opt; /* isolate bits for -1..-8 */
        opt |= 0x100; /* if nothing else, assume -9 */
@@ -213,6 +214,6 @@ int bzip2_main(int argc UNUSED_PARAM, char **argv)
        }
 
        argv += optind;
-       option_mask32 &= 0x7; /* ignore all except -cfv */
+       option_mask32 &= 0xf; /* ignore all except -cfkv */
        return bbunpack(argv, compressStream, append_ext, "bz2");
 }
index 7c6dee1d7533429a89cbe9926d909a49d0a48c87..c895de4268a86509798b2984f651c450f9aca1bb 100644 (file)
@@ -84,7 +84,7 @@ aa:      85.1% -- replaced with aa.gz
 //kbuild:lib-$(CONFIG_GZIP) += gzip.o
 
 //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:       "Compress FILEs (or stdin)\n"
 //usage:       IF_FEATURE_GZIP_LEVELS(
@@ -96,6 +96,7 @@ aa:      85.1% -- replaced with aa.gz
 //usage:       )
 //usage:     "\n       -c      Write to stdout"
 //usage:     "\n       -f      Force"
+//usage:     "\n       -k      Keep input files"
 //usage:
 //usage:#define gzip_example_usage
 //usage:       "$ ls -la /tmp/busybox*\n"
@@ -2219,13 +2220,13 @@ int gzip_main(int argc UNUSED_PARAM, char **argv)
        applet_long_options = gzip_longopts;
 #endif
        /* 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 (opt & 0x18) // -d and/or -t
+       if (opt & 0x30) // -d and/or -t
                return gunzip_main(argc, argv);
 #endif
 #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)
                opt = 1 << 6; /* default: 6 */
        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;
        nice_match       = gzip_level_config[opt].nice2 * 2;
 #endif
-       option_mask32 &= 0x7; /* retain only -cfv */
+       option_mask32 &= 0xf; /* retain only -cfkv */
 
        /* Allocate all global buffers (for DYN_ALLOC option) */
        ALLOC(uch, G1.l_buf, INBUFSIZ);
index ca61add3c688e18a9972b22f947ad8588c44c65f..6ef82b749164cbc7cbc871006dacadb7ee6f71bc 100644 (file)
 //config:
 //config:config UNLZOP
 //config:      bool "unlzop"
-//config:      default y
+//config:      default n  # INCOMPAT: upstream lzop does not provide such tool
 //config:      help
 //config:        Lzop decompresion.
 //config:
 //config:config LZOPCAT
 //config:      bool "lzopcat"
-//config:      default y
+//config:      default n  # INCOMPAT: upstream lzop does not provide such tool
 //config:      help
 //config:        Alias to "unlzop -c".
 //config:
 //kbuild:lib-$(CONFIG_LZOPCAT) += lzop.o
 
 //usage:#define lzop_trivial_usage
-//usage:       "[-cfvd123456789CF] [FILE]..."
+//usage:       "[-cfUvd123456789CF] [FILE]..."
 //usage:#define lzop_full_usage "\n\n"
 //usage:       "       -1..9   Compression level"
 //usage:     "\n       -d      Decompress"
 //usage:     "\n       -c      Write to stdout"
 //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       -F      Don't store or verify checksum"
 //usage:     "\n       -C      Also write checksum of compressed block"
 //usage:     "\n       -F      Don't verify checksum"
 //usage:
 //usage:#define unlzop_trivial_usage
-//usage:       "[-cfvF] [FILE]..."
+//usage:       "[-cfkvF] [FILE]..."
 //usage:#define unlzop_full_usage "\n\n"
 //usage:       "       -c      Write to stdout"
 //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       -F      Don't verify checksum"
 
@@ -472,27 +476,33 @@ struct globals {
 //#define LZOP_VERSION_STRING     "1.01"
 //#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 */
 enum {
        OPT_STDOUT      = (1 << 0),
        OPT_FORCE       = (1 << 1),
-       OPT_VERBOSE     = (1 << 2),
-       OPT_QUIET       = (1 << 3),
-       OPT_DECOMPRESS  = (1 << 4),
-       OPT_TEST        = (1 << 5),
-       OPT_1           = (1 << 6),
-       OPT_2           = (1 << 7),
-       OPT_3           = (1 << 8),
-       OPT_4           = (1 << 9),
-       OPT_5           = (1 << 10),
-       OPT_6           = (1 << 11),
-       OPT_789         = (7 << 12),
+       OPT_KEEP        = (1 << 2),
+       OPT_VERBOSE     = (1 << 3),
+       OPT_QUIET       = (1 << 4),
+       OPT_DECOMPRESS  = (1 << 5),
+       OPT_TEST        = (1 << 6),
+       OPT_1           = (1 << 7),
+       OPT_2           = (1 << 8),
+       OPT_3           = (1 << 9),
+       OPT_4           = (1 << 10),
+       OPT_5           = (1 << 11),
+       OPT_6           = (1 << 12),
        OPT_7           = (1 << 13),
        OPT_8           = (1 << 14),
-       OPT_C           = (1 << 15),
-       OPT_F           = (1 << 16),
+       OPT_9           = (1 << 15),
+       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);
        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? */
        if (ENABLE_LZOPCAT && applet_name[4] == 'c')
                option_mask32 |= (OPT_STDOUT | OPT_DECOMPRESS);