From d999efe6e56bda37f8b7109fd0a146c1a4c290be Mon Sep 17 00:00:00 2001 From: Wayne Davison Date: Mon, 25 May 2020 10:47:57 -0700 Subject: [PATCH] Make compression-level handling generic. --- checksum.c | 2 +- compat.c | 17 ++++++++++++----- options.c | 26 +++++++------------------- rsync.h | 5 +++++ token.c | 36 ++++++++++++++++++++++++++++++++++-- 5 files changed, 59 insertions(+), 27 deletions(-) diff --git a/checksum.c b/checksum.c index bde7c35f..cd84bdb7 100644 --- a/checksum.c +++ b/checksum.c @@ -123,7 +123,7 @@ void parse_checksum_choice(int final_call) if (xfersum_type == CSUM_NONE) whole_file = 1; - if (final_call && DEBUG_GTE(NSTR, am_server ? 2 : 1)) { + if (final_call && DEBUG_GTE(NSTR, am_server ? 3 : 1)) { const char *c_s = am_server ? "Server" : "Client"; if (valid_checksums.negotiated_name) rprintf(FINFO, "%s negotiated checksum: %s\n", c_s, valid_checksums.negotiated_name); diff --git a/compat.c b/compat.c index 4e2fd4b8..d35a3f98 100644 --- a/compat.c +++ b/compat.c @@ -48,6 +48,7 @@ extern int xfer_flags_as_varint; extern int need_messages_from_generator; extern int delete_mode, delete_before, delete_during, delete_after; extern int do_compression; +extern int do_compression_level; extern char *shell_cmd; extern char *partial_dir; extern char *dest_option; @@ -172,16 +173,22 @@ void parse_compress_choice(int final_call) else do_compression = CPRES_NONE; + if (do_compression != CPRES_NONE && final_call) + init_compression_level(); /* There's a chance this might turn compression off! */ + if (do_compression == CPRES_NONE) compress_choice = NULL; - if (final_call && DEBUG_GTE(NSTR, am_server ? 2 : 1)) { + if (final_call && DEBUG_GTE(NSTR, am_server ? 3 : 1) + && (do_compression != CPRES_NONE || do_compression_level != CLVL_NOT_SPECIFIED)) { const char *c_s = am_server ? "Server" : "Client"; - if (valid_compressions.negotiated_name) - rprintf(FINFO, "%s negotiated compress: %s\n", c_s, valid_compressions.negotiated_name); - else { + if (do_compression != CPRES_NONE && valid_compressions.negotiated_name) { + rprintf(FINFO, "%s negotiated compress: %s (level %d)\n", + c_s, valid_compressions.negotiated_name, do_compression_level); + } else { struct name_num_item *nni = get_nni_by_num(&valid_compressions, do_compression); - rprintf(FINFO, "%s compress: %s\n", c_s, nni ? nni->name : "UNKNOWN"); + rprintf(FINFO, "%s compress: %s (level %d)\n", + c_s, nni ? nni->name : "UNKNOWN", do_compression_level); } } } diff --git a/options.c b/options.c index 1a0d2c22..5f3b8d92 100644 --- a/options.c +++ b/options.c @@ -23,7 +23,6 @@ #include "itypes.h" #include "latest-year.h" #include -#include extern int module_id; extern int local_server; @@ -33,8 +32,6 @@ extern unsigned int module_dirlen; extern filter_rule_list filter_list; extern filter_rule_list daemon_filter_list; -#define NOT_SPECIFIED (-42) - int make_backups = 0; /** @@ -81,7 +78,7 @@ int protocol_version = PROTOCOL_VERSION; int sparse_files = 0; int preallocate_files = 0; int do_compression = 0; -int def_compress_level = NOT_SPECIFIED; +int do_compression_level = CLVL_NOT_SPECIFIED; int am_root = 0; /* 0 = normal, 1 = root, 2 = --super, -1 = --fake-super */ int am_server = 0; int am_sender = 0; @@ -1003,7 +1000,7 @@ static struct poptOption long_options[] = { {"compress-choice", 0, POPT_ARG_STRING, &compress_choice, 0, 0, 0 }, {"zz", 0, POPT_ARG_STRING, &compress_choice, 0, 0, 0 }, {"skip-compress", 0, POPT_ARG_STRING, &skip_compress, 0, 0, 0 }, - {"compress-level", 0, POPT_ARG_INT, &def_compress_level, 0, 0, 0 }, + {"compress-level", 0, POPT_ARG_INT, &do_compression_level, 0, 0, 0 }, {0, 'P', POPT_ARG_NONE, 0, 'P', 0, 0 }, {"progress", 0, POPT_ARG_VAL, &do_progress, 1, 0, 0 }, {"no-progress", 0, POPT_ARG_VAL, &do_progress, 0, 0, 0 }, @@ -1972,18 +1969,9 @@ int parse_arguments(int *argc_p, const char ***argv_p) else compress_choice = NULL; - if (do_compression || def_compress_level != NOT_SPECIFIED) { - if (def_compress_level == NOT_SPECIFIED) - def_compress_level = Z_DEFAULT_COMPRESSION; - else if (def_compress_level < Z_DEFAULT_COMPRESSION || def_compress_level > Z_BEST_COMPRESSION) { - snprintf(err_buf, sizeof err_buf, "--compress-level value is invalid: %d\n", - def_compress_level); - return 0; - } else if (def_compress_level == Z_NO_COMPRESSION) { - do_compression = 0; - compress_choice = NULL; - } else if (!do_compression) - do_compression = CPRES_ZLIB; + if (do_compression || do_compression_level != CLVL_NOT_SPECIFIED) { + if (!do_compression) + do_compression = CPRES_AUTO; if (do_compression && refused_compress) { create_refuse_error(refused_compress); return 0; @@ -2701,8 +2689,8 @@ void server_options(char **args, int *argc_p) if (xfer_dirs && !recurse && delete_mode && am_sender) args[ac++] = "--no-r"; - if (do_compression && def_compress_level != Z_DEFAULT_COMPRESSION) { - if (asprintf(&arg, "--compress-level=%d", def_compress_level) < 0) + if (do_compression && do_compression_level != CLVL_NOT_SPECIFIED) { + if (asprintf(&arg, "--compress-level=%d", do_compression_level) < 0) goto oom; args[ac++] = arg; } diff --git a/rsync.h b/rsync.h index cffd0d8e..210cef40 100644 --- a/rsync.h +++ b/rsync.h @@ -1061,9 +1061,14 @@ typedef struct { #define ACL_READY(sx) ((sx).acc_acl != NULL) #define XATTR_READY(sx) ((sx).xattr != NULL) +#define CLVL_NOT_SPECIFIED INT_MIN + +#define CPRES_AUTO (-1) #define CPRES_NONE 0 #define CPRES_ZLIB 1 #define CPRES_ZLIBX 2 +#define CPRES_LZ4 3 +#define CPRES_ZSTD 4 struct name_num_item { int num; diff --git a/token.c b/token.c index c1de27f0..ca95e014 100644 --- a/token.c +++ b/token.c @@ -26,7 +26,7 @@ extern int do_compression; extern int protocol_version; extern int module_id; -extern int def_compress_level; +extern int do_compression_level; extern char *skip_compress; #ifndef Z_INSERT_ONLY @@ -44,6 +44,38 @@ struct suffix_tree { static char *match_list; static struct suffix_tree *suftree; +void init_compression_level(void) +{ + int min_level, max_level, def_level, off_level; + + switch (do_compression) { + case CPRES_ZLIB: + case CPRES_ZLIBX: + min_level = 1; + max_level = Z_BEST_COMPRESSION; + def_level = 6; /* Z_DEFAULT_COMPRESSION is -1, so set it to the real default */ + off_level = Z_NO_COMPRESSION; + if (do_compression_level == Z_DEFAULT_COMPRESSION) + do_compression_level = def_level; + break; + default: /* paranoia to prevent missing case values */ + exit_cleanup(RERR_UNSUPPORTED); + } + + if (do_compression_level == off_level) { + do_compression = CPRES_NONE; + return; + } + + /* We don't bother with any errors or warnings -- just make sure that the values are valid. */ + if (do_compression_level == CLVL_NOT_SPECIFIED) + do_compression_level = def_level; + else if (do_compression_level < min_level) + do_compression_level = min_level; + else if (do_compression_level > max_level) + do_compression_level = max_level; +} + static void add_suffix(struct suffix_tree **prior, char ltr, const char *str) { struct suffix_tree *node, *newnode; @@ -129,7 +161,7 @@ static void init_set_compression(void) if (!(match_list = t = new_array(char, strlen(f) + 2))) out_of_memory("set_compression"); - per_file_default_level = def_compress_level; + per_file_default_level = do_compression_level; while (*f) { if (*f == ' ') { -- 2.34.1