--- 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-30 16:35:08 +++ 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; @@ -1001,7 +1002,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) { @@ -1073,7 +1074,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-30 16:57:27 +++ main.c 2005-03-24 07:07:12 @@ -170,7 +170,7 @@ static void handle_stats(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); @@ -591,7 +591,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]); @@ -764,7 +764,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); @@ -802,7 +802,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) { @@ -1123,7 +1123,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); @@ -1142,6 +1142,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-31 00:24:21 +++ 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"); rprintf(F," --protocol=NUM force an older protocol version to be used\n"); #ifdef INET6 @@ -360,7 +362,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[] = { @@ -450,6 +453,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 }, @@ -791,6 +795,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; @@ -901,7 +910,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", @@ -1093,6 +1102,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-29 22:39:37 +++ 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; @@ -452,13 +453,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) { next_gen_i = get_next_gen_i(batch_gen_fd, next_gen_i, i); --- orig/rsync.yo 2005-03-30 16:57:29 +++ 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 --protocol=NUM force an older protocol version to be used --checksum-seed=NUM set block/file checksum seed (advanced) @@ -1271,6 +1272,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-28 20:56:55 +++ 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; @@ -208,6 +210,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) @@ -230,7 +233,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; @@ -266,10 +269,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; } @@ -321,9 +324,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", @@ -337,7 +340,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);