This patch sends the new fnamecmp_type value from the generator to the sender if --inplace was specified. This allows the sender to know when the transfer can fully utilize the basis file (i.e., when the basis file is not the destination file). --- orig/generator.c 2004-11-03 20:30:45 +++ generator.c 2004-11-03 20:37:57 @@ -563,6 +563,8 @@ prepare_to_open: notify_others: write_int(f_out, i); + if (protocol_version >= 29 && inplace && !read_batch) + write_byte(f_out, fnamecmp_type); if (f_out_name >= 0) write_byte(f_out_name, fnamecmp_type); --- orig/match.c 2004-09-07 21:45:30 +++ match.c 2004-11-03 20:38:34 @@ -24,7 +24,8 @@ extern int am_server; extern int do_progress; extern int checksum_seed; extern int inplace; -extern int make_backups; + +int alternate_basis; typedef unsigned short tag; @@ -205,7 +206,7 @@ static void hash_search(int f,struct sum /* inplace: ensure chunk's offset is either >= our * offset or that the data didn't move. */ - if (inplace && !make_backups && s->sums[i].offset < offset + if (inplace && !alternate_basis && s->sums[i].offset < offset && !(s->sums[i].flags & SUMFLG_SAME_OFFSET)) continue; @@ -227,7 +228,7 @@ static void hash_search(int f,struct sum /* If inplace is enabled, the best possible match is * one with an identical offset, so we prefer that over * the following want_i optimization. */ - if (inplace && !make_backups) { + if (inplace && !alternate_basis) { do { size_t i2 = targets[j].i; if (s->sums[i2].offset != offset) @@ -250,7 +251,7 @@ static void hash_search(int f,struct sum /* we've found a match, but now check to see * if want_i can hint at a better match. */ if (i != want_i && want_i < s->count - && (!inplace || make_backups || s->sums[want_i].offset >= offset + && (!inplace || alternate_basis || s->sums[want_i].offset >= offset || s->sums[want_i].flags & SUMFLG_SAME_OFFSET) && sum == s->sums[want_i].sum1 && memcmp(sum2, s->sums[want_i].sum2, s->s2length) == 0) { --- orig/options.c 2004-10-14 17:11:40 +++ options.c 2004-11-03 20:47:21 @@ -884,10 +884,9 @@ int parse_arguments(int *argc, const cha am_server ? "server" : "client"); return 0; #endif - if (compare_dest) { + if (link_dest) { snprintf(err_buf, sizeof err_buf, - "--inplace does not yet work with %s\n", - link_dest ? "--link-dest" : "--compare-dest"); + "--inplace does not yet work with --link-dest\n"); return 0; } } else { --- orig/rsync.h 2004-11-03 20:30:45 +++ rsync.h 2004-11-03 20:32:34 @@ -62,7 +62,7 @@ #define FLAG_MOUNT_POINT (1<<2) /* sender only */ /* update this if you make incompatible changes */ -#define PROTOCOL_VERSION 28 +#define PROTOCOL_VERSION 29 /* We refuse to interoperate with versions that are not in this range. * Note that we assume we'll work with later versions: the onus is on --- orig/sender.c 2004-09-20 05:10:48 +++ sender.c 2004-11-03 20:38:50 @@ -27,7 +27,9 @@ extern int dry_run; extern int am_server; extern int am_daemon; extern int protocol_version; +extern int alternate_basis; extern int make_backups; +extern int inplace; extern struct stats stats; @@ -117,6 +119,7 @@ void send_files(struct file_list *flist, struct map_struct *mbuf = NULL; STRUCT_STAT st; char *fname2, fname[MAXPATHLEN]; + uchar fnamecmp_type = FNAMECMP_FNAME; int i; struct file_struct *file; int phase = 0; @@ -166,6 +169,11 @@ void send_files(struct file_list *flist, } else offset = 0; fname2 = f_name_to(file, fname + offset); + if (protocol_version >= 29 && inplace) { + fnamecmp_type = read_byte(f_in); + alternate_basis = fnamecmp_type != FNAMECMP_FNAME; + } else + alternate_basis = make_backups; if (verbose > 2) rprintf(FINFO, "send_files(%d, %s)\n", i, fname);