--- /dev/null
+--- orig/batch.c 2005-03-27 05:13:14
++++ batch.c 2005-03-27 05:14:42
+@@ -139,7 +139,7 @@ static void write_filter_rules(int fd)
+ * (hopefully) work. */
+ void write_batch_shell_file(int argc, char *argv[], int file_arg_cnt)
+ {
+- int fd, i;
++ int fd, i, len;
+ char *p, filename[MAXPATHLEN];
+
+ stringjoin(filename, sizeof filename,
+@@ -175,11 +175,12 @@ void write_batch_shell_file(int argc, ch
+ continue;
+ }
+ write(fd, " ", 1);
+- if (strncmp(p, "--write-batch", 13) == 0) {
++ if (strncmp(p, "--write-batch", len = 13) == 0
++ || strncmp(p, "--only-write-batch", len = 18) == 0) {
+ write(fd, "--read-batch", 12);
+- if (p[13] == '=') {
++ if (p[len] == '=') {
+ write(fd, "=", 1);
+- write_arg(fd, p + 14);
++ write_arg(fd, p + len + 1);
+ }
+ } else
+ write_arg(fd, p);
+--- orig/generator.c 2005-03-17 09:05:21
++++ generator.c 2005-03-24 07:07:12
+@@ -25,6 +25,7 @@
+
+ extern int verbose;
+ extern int dry_run;
++extern int do_xfers;
+ extern int log_format_has_i;
+ extern int log_format_has_o_or_i;
+ extern int daemon_log_format_has_i;
+@@ -1002,7 +1003,7 @@ prepare_to_open:
+ statret = 0;
+ }
+
+- if (dry_run || read_batch || whole_file)
++ if (!do_xfers || read_batch || whole_file)
+ goto notify_others;
+
+ if (fuzzy_basis) {
+@@ -1074,7 +1075,7 @@ notify_others:
+ fuzzy_file ? fuzzy_file->basename : NULL);
+ }
+
+- if (dry_run) {
++ if (!do_xfers) {
+ if (preserve_hard_links && file->link_u.links)
+ hard_link_cluster(file, ndx, itemizing, code);
+ return;
+@@ -1122,9 +1123,9 @@ void generate_files(int f_out, struct fi
+ maybe_PERMS_REPORT = log_format_has_i ? 0 : PERMS_REPORT;
+ code = daemon_log_format_has_i ? 0 : FLOG;
+ } else if (am_daemon) {
+- itemizing = daemon_log_format_has_i && !dry_run;
++ itemizing = daemon_log_format_has_i && do_xfers;
+ maybe_PERMS_REPORT = PERMS_REPORT;
+- code = itemizing || dry_run ? FCLIENT : FINFO;
++ code = itemizing || !do_xfers ? FCLIENT : FINFO;
+ } else if (!am_server) {
+ itemizing = log_format_has_i;
+ maybe_PERMS_REPORT = log_format_has_i ? 0 : PERMS_REPORT;
+--- orig/main.c 2005-03-16 02:19:30
++++ main.c 2005-03-24 07:07:12
+@@ -168,7 +168,7 @@ static void report(int f)
+ stats.flist_buildtime = read_longint(f);
+ stats.flist_xfertime = read_longint(f);
+ }
+- } else if (write_batch) {
++ } else if (write_batch && !am_server) {
+ /* The --read-batch process is going to be a client
+ * receiver, so we need to give it the stats. */
+ write_longint(batch_fd, total_read);
+@@ -583,7 +583,7 @@ static int do_recv(int f_in,int f_out,st
+
+ am_generator = 1;
+ close_multiplexing_in();
+- if (write_batch)
++ if (write_batch && !am_server)
+ stop_write_batch();
+
+ close(error_pipe[1]);
+@@ -756,7 +756,7 @@ int client_run(int f_in, int f_out, pid_
+ if (filesfrom_host)
+ filesfrom_fd = f_in;
+
+- if (write_batch)
++ if (write_batch && !am_server)
+ start_write_batch(f_out);
+ flist = send_file_list(f_out, argc, argv);
+ set_msg_fd_in(-1);
+@@ -793,7 +793,7 @@ int client_run(int f_in, int f_out, pid_
+ filesfrom_fd = -1;
+ }
+
+- if (write_batch)
++ if (write_batch && !am_server)
+ start_write_batch(f_in);
+ flist = recv_file_list(f_in);
+ if (!flist || flist->count == 0) {
+@@ -1111,7 +1111,7 @@ int main(int argc,char *argv[])
+
+ init_flist();
+
+- if (write_batch || read_batch) {
++ if ((write_batch || read_batch) && !am_server) {
+ if (write_batch)
+ write_batch_shell_file(orig_argc, orig_argv, argc);
+
+@@ -1130,6 +1130,8 @@ int main(int argc,char *argv[])
+ if (read_batch)
+ read_stream_flags(batch_fd);
+ }
++ if (write_batch < 0)
++ dry_run = 1;
+
+ if (am_daemon && !am_server)
+ return daemon_main();
+--- orig/options.c 2005-03-24 16:41:46
++++ options.c 2005-03-24 07:07:13
+@@ -53,6 +53,7 @@ int omit_dir_times = 0;
+ int update_only = 0;
+ int cvs_exclude = 0;
+ int dry_run = 0;
++int do_xfers = 1;
+ int ignore_times = 0;
+ int delete_mode = 0;
+ int delete_during = 0;
+@@ -344,6 +345,7 @@ void usage(enum logcode F)
+ rprintf(F," --list-only list the files instead of copying them\n");
+ rprintf(F," --bwlimit=KBPS limit I/O bandwidth; KBytes per second\n");
+ rprintf(F," --write-batch=FILE write a batched update to FILE\n");
++ rprintf(F," --only-write-batch=FILE like --write-batch but w/o updating destination\n");
+ rprintf(F," --read-batch=FILE read a batched update from FILE\n");
+ #ifdef INET6
+ rprintf(F," -4, --ipv4 prefer IPv4\n");
+@@ -359,7 +361,8 @@ void usage(enum logcode F)
+ 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_TIMEOUT, OPT_MAX_SIZE,
++ OPT_READ_BATCH, OPT_WRITE_BATCH, OPT_ONLY_WRITE_BATCH,
++ OPT_TIMEOUT, OPT_MAX_SIZE,
+ OPT_REFUSED_BASE = 9000};
+
+ static struct poptOption long_options[] = {
+@@ -449,6 +452,7 @@ static struct poptOption long_options[]
+ {"hard-links", 'H', POPT_ARG_NONE, &preserve_hard_links, 0, 0, 0 },
+ {"read-batch", 0, POPT_ARG_STRING, &batch_name, OPT_READ_BATCH, 0, 0 },
+ {"write-batch", 0, POPT_ARG_STRING, &batch_name, OPT_WRITE_BATCH, 0, 0 },
++ {"only-write-batch", 0, POPT_ARG_STRING, &batch_name, OPT_ONLY_WRITE_BATCH, 0, 0 },
+ {"files-from", 0, POPT_ARG_STRING, &files_from, 0, 0, 0 },
+ {"from0", '0', POPT_ARG_NONE, &eol_nulls, 0, 0, 0},
+ {"no-implied-dirs", 0, POPT_ARG_VAL, &implied_dirs, 0, 0, 0 },
+@@ -790,6 +794,11 @@ int parse_arguments(int *argc, const cha
+ write_batch = 1;
+ break;
+
++ case OPT_ONLY_WRITE_BATCH:
++ /* batch_name is already set */
++ write_batch = -1;
++ break;
++
+ case OPT_READ_BATCH:
+ /* batch_name is already set */
+ read_batch = 1;
+@@ -900,7 +909,7 @@ int parse_arguments(int *argc, const cha
+ "--write-batch and --read-batch can not be used together\n");
+ return 0;
+ }
+- if (write_batch || read_batch) {
++ if (write_batch > 0 || read_batch) {
+ if (am_server) {
+ rprintf(FINFO,
+ "ignoring --%s-batch option sent to server\n",
+@@ -1092,6 +1101,9 @@ int parse_arguments(int *argc, const cha
+ && !am_server)
+ verbose = 1;
+
++ if (dry_run)
++ do_xfers = 0;
++
+ if (verbose && !log_format) {
+ log_format = "%n%L";
+ log_before_transfer = !am_server;
+@@ -1245,7 +1257,7 @@ void server_options(char **args,int *arg
+ argstr[x++] = 'b';
+ if (update_only)
+ argstr[x++] = 'u';
+- if (dry_run)
++ if (!do_xfers)
+ argstr[x++] = 'n';
+ if (preserve_links)
+ argstr[x++] = 'l';
+@@ -1373,6 +1385,8 @@ void server_options(char **args,int *arg
+ args[ac++] = "--delete-after";
+ if (force_delete)
+ args[ac++] = "--force";
++ if (write_batch < 0)
++ args[ac++] = "--only-write-batch=X";
+ }
+
+ if (size_only)
+--- orig/pipe.c 2005-02-07 20:36:43
++++ pipe.c 2005-03-24 07:07:13
+@@ -25,7 +25,6 @@ extern int am_sender;
+ extern int am_server;
+ extern int blocking_io;
+ extern int orig_umask;
+-extern int write_batch;
+ extern int filesfrom_fd;
+
+ /**
+@@ -128,10 +127,6 @@ pid_t local_child(int argc, char **argv,
+ am_sender = !am_sender;
+ am_server = 1;
+
+- /* The server side never writes the batch, even if it
+- * is local (it makes the logic easier elsewhere). */
+- write_batch = 0;
+-
+ if (!am_sender)
+ filesfrom_fd = -1;
+
+--- orig/receiver.c 2005-03-24 16:41:46
++++ receiver.c 2005-03-24 07:07:13
+@@ -21,7 +21,7 @@
+ #include "rsync.h"
+
+ extern int verbose;
+-extern int dry_run;
++extern int do_xfers;
+ extern int am_daemon;
+ extern int am_server;
+ extern int do_progress;
+@@ -30,6 +30,7 @@ extern int log_format_has_i;
+ extern int daemon_log_format_has_i;
+ extern int csum_length;
+ extern int read_batch;
++extern int write_batch;
+ extern int batch_gen_fd;
+ extern int protocol_version;
+ extern int relative_paths;
+@@ -435,13 +436,18 @@ int recv_files(int f_in, struct file_lis
+ exit_cleanup(RERR_PROTOCOL);
+ }
+
+- if (dry_run) { /* log the transfer */
++ if (!do_xfers) { /* log the transfer */
+ if (!am_server && log_format)
+ log_item(file, &stats, iflags, NULL);
+ if (read_batch)
+ discard_receive_data(f_in, file->length);
+ continue;
+ }
++ if (write_batch < 0) {
++ log_item(file, &stats, iflags, NULL);
++ discard_receive_data(f_in, file->length);
++ continue;
++ }
+
+ if (read_batch) {
+ while (i > next_gen_i) {
+--- orig/rsync.yo 2005-03-16 02:19:30
++++ rsync.yo 2005-03-27 05:13:01
+@@ -379,6 +379,7 @@ to the detailed description below for a
+ --list-only list the files instead of copying them
+ --bwlimit=KBPS limit I/O bandwidth; KBytes per second
+ --write-batch=FILE write a batched update to FILE
++ --only-write-batch=FILE like --write-batch but w/o updating dest
+ --read-batch=FILE read a batched update from FILE
+ --checksum-seed=NUM set block/file checksum seed (advanced)
+ -4, --ipv4 prefer IPv4
+@@ -1270,6 +1271,16 @@ dit(bf(--write-batch=FILE)) Record a fil
+ another identical destination with bf(--read-batch). See the "BATCH MODE"
+ section for details.
+
++dit(bf(--only-write-batch=FILE)) Works like bf(--write-batch), except that
++no updates are made on the destination system when creating the batch.
++This lets you transport the changes to the destination system via some
++other means and then apply the changes via bf(--read-batch). Note that
++you can feel free to write the batch directly to some portable media: if
++this media fills to capacity before the end of the transfer, you can just
++apply that partial transfer to the destination and repeat the whole process
++to get the rest of the changes (as long as you don't mind a partially
++updated destination system while the multi-update cycle is happening).
++
+ dit(bf(--read-batch=FILE)) Apply all of the changes stored in FILE, a
+ file previously generated by bf(--write-batch).
+ If em(FILE) is "-" the batch data will be read from standard input.
+--- orig/sender.c 2005-03-16 02:19:30
++++ sender.c 2005-03-24 07:07:13
+@@ -20,7 +20,7 @@
+ #include "rsync.h"
+
+ extern int verbose;
+-extern int dry_run;
++extern int do_xfers;
+ extern int am_server;
+ extern int am_daemon;
+ extern int log_before_transfer;
+@@ -34,6 +34,8 @@ extern int updating_basis_file;
+ extern int make_backups;
+ extern int do_progress;
+ extern int inplace;
++extern int batch_fd;
++extern int write_batch;
+ extern struct stats stats;
+ extern struct file_list *the_file_list;
+ extern char *log_format;
+@@ -216,6 +218,7 @@ void send_files(struct file_list *flist,
+ int save_make_backups = make_backups;
+ int itemizing = am_daemon ? daemon_log_format_has_i
+ : !am_server && log_format_has_i;
++ int f_xfer = write_batch < 0 ? batch_fd : f_out;
+ int i, j;
+
+ if (verbose > 2)
+@@ -238,7 +241,7 @@ void send_files(struct file_list *flist,
+ continue;
+ }
+
+- iflags = read_item_attrs(f_in, f_out, i, &fnamecmp_type,
++ iflags = read_item_attrs(f_in, f_xfer, i, &fnamecmp_type,
+ xname, &xlen);
+ if (iflags == ITEM_IS_NEW) /* no-op packet */
+ continue;
+@@ -274,10 +277,10 @@ void send_files(struct file_list *flist,
+ stats.num_transferred_files++;
+ stats.total_transferred_size += file->length;
+
+- if (dry_run) { /* log the transfer */
++ if (!do_xfers) { /* log the transfer */
+ if (!am_server && log_format)
+ log_item(file, &stats, iflags, NULL);
+- write_ndx_and_attrs(f_out, i, iflags, fnamecmp_type,
++ write_ndx_and_attrs(f_xfer, i, iflags, fnamecmp_type,
+ xname, xlen);
+ continue;
+ }
+@@ -329,9 +332,9 @@ void send_files(struct file_list *flist,
+ safe_fname(fname), (double)st.st_size);
+ }
+
+- write_ndx_and_attrs(f_out, i, iflags, fnamecmp_type,
++ write_ndx_and_attrs(f_xfer, i, iflags, fnamecmp_type,
+ xname, xlen);
+- write_sum_head(f_out, s);
++ write_sum_head(f_xfer, s);
+
+ if (verbose > 2) {
+ rprintf(FINFO, "calling match_sums %s\n",
+@@ -345,7 +348,7 @@ void send_files(struct file_list *flist,
+
+ set_compression(fname);
+
+- match_sums(f_out, s, mbuf, st.st_size);
++ match_sums(f_xfer, s, mbuf, st.st_size);
+ if (do_progress)
+ end_progress(st.st_size);
+