Index: batch.c =================================================================== RCS file: /cvsroot/rsync/batch.c,v retrieving revision 1.53 diff -u -d -b -w -r1.53 batch.c --- batch.c 9 Apr 2005 18:59:44 -0000 1.53 +++ batch.c 17 Oct 2005 10:48:19 -0000 @@ -18,7 +18,7 @@ extern int preserve_uid; extern int preserve_gid; extern int always_checksum; -extern int do_compression; +extern int opt_compression_level; extern int protocol_version; extern char *batch_name; @@ -33,7 +33,7 @@ &preserve_hard_links, /* 5 */ &always_checksum, /* 6 */ &xfer_dirs, /* 7 (protocol 29) */ - &do_compression, /* 8 (protocol 29) */ + &opt_compression_level, /* 8 (protocol 29) */ NULL }; Index: options.c =================================================================== RCS file: /cvsroot/rsync/options.c,v retrieving revision 1.265 diff -u -d -b -w -r1.265 options.c --- options.c 19 May 2005 08:52:17 -0000 1.265 +++ options.c 17 Oct 2005 10:48:20 -0000 @@ -20,6 +20,7 @@ #include "rsync.h" #include "popt.h" +#include "zlib/zlib.h" extern int module_id; extern int sanitize_paths; @@ -63,7 +64,7 @@ int one_file_system = 0; int protocol_version = PROTOCOL_VERSION; int sparse_files = 0; -int do_compression = 0; +extern int opt_compression_level; int am_root = 0; int am_server = 0; int am_sender = 0; @@ -321,7 +322,8 @@ rprintf(F," --compare-dest=DIR also compare destination files relative to DIR\n"); rprintf(F," --copy-dest=DIR ... and include copies of unchanged files\n"); rprintf(F," --link-dest=DIR hardlink to files in DIR when unchanged\n"); - rprintf(F," -z, --compress compress file data during the transfer\n"); + rprintf(F," -z compress file data during the transfer\n"); + rprintf(F," --compress[=NUM] compress file data using optional compression level\n"); rprintf(F," -C, --cvs-exclude auto-ignore files the same way CVS does\n"); rprintf(F," -f, --filter=RULE add a file-filtering RULE\n"); rprintf(F," -F same as --filter='dir-merge /.rsync-filter'\n"); @@ -363,7 +365,7 @@ enum {OPT_VERSION = 1000, OPT_DAEMON, OPT_SENDER, OPT_EXCLUDE, OPT_EXCLUDE_FROM, OPT_FILTER, OPT_COMPARE_DEST, OPT_COPY_DEST, OPT_LINK_DEST, OPT_INCLUDE, OPT_INCLUDE_FROM, OPT_MODIFY_WINDOW, - OPT_READ_BATCH, OPT_WRITE_BATCH, OPT_ONLY_WRITE_BATCH, OPT_MAX_SIZE, + OPT_READ_BATCH, OPT_WRITE_BATCH, OPT_ONLY_WRITE_BATCH, OPT_MAX_SIZE, OPT_COMPRESS, OPT_REFUSED_BASE = 9000}; static struct poptOption long_options[] = { @@ -433,8 +435,8 @@ {"copy-dest", 0, POPT_ARG_STRING, 0, OPT_COPY_DEST, 0, 0 }, {"link-dest", 0, POPT_ARG_STRING, 0, OPT_LINK_DEST, 0, 0 }, {"fuzzy", 'y', POPT_ARG_NONE, &fuzzy_basis, 0, 0, 0 }, - /* TODO: Should this take an optional int giving the compression level? */ - {"compress", 'z', POPT_ARG_NONE, &do_compression, 0, 0, 0 }, + {"compress", 0, POPT_ARG_INT|POPT_ARGFLAG_OPTIONAL, 0, OPT_COMPRESS, 0, 0 }, + {0, 'z', POPT_ARG_NONE, 0, OPT_COMPRESS, 0, 0 }, {"stats", 0, POPT_ARG_NONE, &do_stats, 0, 0, 0 }, {"progress", 0, POPT_ARG_NONE, &do_progress, 0, 0, 0 }, {"partial", 0, POPT_ARG_NONE, &keep_partial, 0, 0, 0 }, @@ -876,6 +878,23 @@ basis_dir[basis_dir_cnt++] = (char *)arg; break; + case 'z': + case OPT_COMPRESS: + arg = poptGetOptArg(pc); + if (arg == NULL) + opt_compression_level = Z_DEFAULT_COMPRESSION; + else { + opt_compression_level = atoi(arg); + if (opt_compression_level < Z_NO_COMPRESSION || + opt_compression_level > Z_BEST_COMPRESSION) { + snprintf(err_buf, sizeof err_buf, + "ERROR: invalid compression level %d\n", + opt_compression_level); + return 0; + } + } + break; + default: /* A large opt value means that set_refuse_options() * turned this option off. */ @@ -1308,8 +1327,15 @@ argstr[x++] = 'x'; if (sparse_files) argstr[x++] = 'S'; - if (do_compression) + if (opt_compression_level != Z_NO_COMPRESSION) { + if (opt_compression_level == Z_DEFAULT_COMPRESSION) { argstr[x++] = 'z'; + } else { + if (asprintf(&arg, "--compress=%d", opt_compression_level) < 0) + goto oom; + args[ac++] = arg; + } + } /* This is a complete hack - blame Rusty. FIXME! * This hack is only needed for older rsync versions that Index: token.c =================================================================== RCS file: /cvsroot/rsync/token.c,v retrieving revision 1.37 diff -u -d -b -w -r1.37 token.c --- token.c 14 Feb 2005 08:28:00 -0000 1.37 +++ token.c 17 Oct 2005 10:48:20 -0000 @@ -20,9 +20,10 @@ #include "rsync.h" #include "zlib/zlib.h" -extern int do_compression; extern int module_id; +int opt_compression_level = Z_NO_COMPRESSION; + static int compression_level = Z_DEFAULT_COMPRESSION; /* determine the compression level based on a wildcard filename list */ @@ -31,10 +32,10 @@ char *dont; char *tok; - if (!do_compression) + if (compression_level == Z_NO_COMPRESSION) return; - compression_level = Z_DEFAULT_COMPRESSION; + compression_level = opt_compression_level; dont = lp_dont_compress(module_id); if (!dont || !*dont) @@ -474,7 +475,7 @@ void send_token(int f, int32 token, struct map_struct *buf, OFF_T offset, int32 n, int32 toklen) { - if (!do_compression) + if (compression_level == Z_NO_COMPRESSION) simple_send_token(f, token, buf, offset, n); else send_deflated_token(f, token, buf, offset, n, toklen); @@ -491,7 +492,7 @@ { int tok; - if (!do_compression) { + if (compression_level == Z_NO_COMPRESSION) { tok = simple_recv_token(f,data); } else { tok = recv_deflated_token(f, data); @@ -504,6 +505,6 @@ */ void see_token(char *data, int32 toklen) { - if (do_compression) + if (compression_level != Z_NO_COMPRESSION) see_deflate_token(data, toklen); } Index: popt/popt.c =================================================================== RCS file: /cvsroot/rsync/popt/popt.c,v retrieving revision 1.10 diff -u -d -b -w -r1.10 popt.c --- popt/popt.c 20 Feb 2005 17:21:13 -0000 1.10 +++ popt/popt.c 17 Oct 2005 10:48:21 -0000 @@ -842,6 +842,10 @@ } if (con->os->argv != NULL) { /* XXX can't happen */ + if (opt->argInfo & POPT_ARGFLAG_OPTIONAL && + con->os->argv[con->os->next][0] == '-') { + con->os->nextArg = NULL; + } else { /* XXX watchout: subtle side-effects live here. */ longArg = con->os->argv[con->os->next++]; longArg = expandNextArg(con, longArg); @@ -849,6 +853,7 @@ } } } + } longArg = NULL; if (opt->arg) {