--- flist.c 16 Sep 2005 05:52:54 -0000 1.303 +++ flist.c 16 Sep 2005 16:41:25 -0000 @@ -36,6 +36,7 @@ extern int am_daemon; extern int am_sender; extern int do_progress; extern int always_checksum; +extern int pre_checksum; extern int module_id; extern int ignore_errors; extern int numeric_ids; @@ -716,6 +717,16 @@ static struct file_struct *receive_file_ sum = empty_sum; } read_buf(f, sum, slen); + if (pre_checksum) { + char sum2[MD4_SUM_LENGTH]; + STRUCT_STAT st; + char *fname = f_name(file); + if (stat(fname, &st) == 0 && st.st_size == file_length) { + file_checksum(fname, sum2, st.st_size); + if (memcmp(sum, sum2, slen) != 0) + file->flags |= FLAG_SUM_DIFFERS; + } + } } if (!preserve_perms) { --- generator.c 6 Sep 2005 18:12:38 -0000 1.222 +++ generator.c 16 Sep 2005 16:41:25 -0000 @@ -67,6 +67,7 @@ extern int ignore_timeout; extern int protocol_version; extern int fuzzy_basis; extern int always_checksum; +extern int pre_checksum; extern char *partial_dir; extern char *basis_dir[]; extern int compare_dest; @@ -358,7 +359,8 @@ void itemize(struct file_struct *file, i /* Perform our quick-check heuristic for determining if a file is unchanged. */ -static int unchanged_file(char *fn, struct file_struct *file, STRUCT_STAT *st) +static int unchanged_file(char *fn, int fnamecmp_type, struct file_struct *file, + STRUCT_STAT *st) { if (st->st_size != file->length) return 0; @@ -367,6 +369,8 @@ static int unchanged_file(char *fn, stru of the file time to determine whether to sync */ if (always_checksum && S_ISREG(st->st_mode)) { char sum[MD4_SUM_LENGTH]; + if (pre_checksum && fnamecmp_type == FNAMECMP_FNAME) + return !(file->flags & FLAG_SUM_DIFFERS); file_checksum(fn, sum, st->st_size); return memcmp(sum, file->u.sum, protocol_version < 21 ? 2 : MD4_SUM_LENGTH) == 0; @@ -913,7 +917,7 @@ static void recv_generator(char *fname, match_level = 1; /* FALL THROUGH */ case 1: - if (!unchanged_file(fnamecmpbuf, file, &st)) + if (!unchanged_file(fnamecmpbuf, 0, file, &st)) continue; best_match = i; match_level = 2; @@ -1044,7 +1048,7 @@ static void recv_generator(char *fname, ; else if (fnamecmp_type == FNAMECMP_FUZZY) ; - else if (unchanged_file(fnamecmp, file, &st)) { + else if (unchanged_file(fnamecmp, fnamecmp_type, file, &st)) { if (fnamecmp_type == FNAMECMP_FNAME) { if (itemizing) { itemize(file, ndx, real_ret, &real_st, --- main.c 16 Sep 2005 16:40:30 -0000 1.277 +++ main.c 16 Sep 2005 16:41:25 -0000 @@ -45,6 +45,7 @@ extern int copy_links; extern int keep_dirlinks; extern int preserve_hard_links; extern int protocol_version; +extern int always_checksum; extern int recurse; extern int relative_paths; extern int rsync_port; @@ -60,8 +61,10 @@ extern char *filesfrom_host; extern char *rsync_path; extern char *shell_cmd; extern char *batch_name; +extern char curr_dir[MAXPATHLEN]; int local_server = 0; +int pre_checksum = 0; struct file_list *the_file_list; /* There's probably never more than at most 2 outstanding child processes, @@ -613,6 +616,7 @@ static void do_server_recv(int f_in, int struct file_list *flist; char *local_name = NULL; char *dir = NULL; + char olddir[sizeof curr_dir]; int save_verbose = verbose; if (filesfrom_fd >= 0) { @@ -657,6 +661,10 @@ static void do_server_recv(int f_in, int filesfrom_fd = -1; } + strlcpy(olddir, curr_dir, sizeof olddir); + if (always_checksum && argc > 0) + pre_checksum = push_dir(argv[0]); + flist = recv_file_list(f_in); verbose = save_verbose; if (!flist) { @@ -665,6 +673,9 @@ static void do_server_recv(int f_in, int } the_file_list = flist; + if (pre_checksum) + pop_dir(olddir); + if (argc > 0) local_name = get_local_name(flist,argv[0]); @@ -713,6 +724,7 @@ int client_run(int f_in, int f_out, pid_ { struct file_list *flist = NULL; int status = 0, status2 = 0; + char olddir[sizeof curr_dir]; char *local_name = NULL; cleanup_child_pid = pid; @@ -784,11 +796,18 @@ int client_run(int f_in, int f_out, pid_ filesfrom_fd = -1; } + strlcpy(olddir, curr_dir, sizeof olddir); + if (always_checksum) + pre_checksum = push_dir(argv[0]); + if (write_batch && !am_server) start_write_batch(f_in); flist = recv_file_list(f_in); the_file_list = flist; + if (pre_checksum) + pop_dir(olddir); + if (flist && flist->count > 0) { local_name = get_local_name(flist, argv[0]); --- rsync.h 29 Jul 2005 18:31:03 -0000 1.265 +++ rsync.h 16 Sep 2005 16:41:26 -0000 @@ -64,6 +64,7 @@ #define FLAG_DEL_HERE (1<<3) /* receiver/generator */ #define FLAG_SENT (1<<3) /* sender */ #define FLAG_HLINK_TOL (1<<4) /* receiver/generator */ +#define FLAG_SUM_DIFFERS (1<<5) /* receiver/generator */ /* update this if you make incompatible changes */ #define PROTOCOL_VERSION 29