Fixed the --compare-dest docs.
[rsync/rsync.git] / generator.c
index 6966ec1..34cc99d 100644 (file)
@@ -149,7 +149,7 @@ static int delete_item(char *fname, int mode, int flags)
                        full_fname(fname));
                return -1;
        }
-       flags |= DEL_FORCE_RECURSE;
+       flags |= DEL_FORCE_RECURSE; /* mark subdir dels as not "in the way" */
 
        dlen = strlcpy(buf, fname, MAXPATHLEN);
        save_filters = push_local_filters(buf, dlen);
@@ -812,54 +812,58 @@ static void recv_generator(char *fname, struct file_list *flist,
        fnamecmp_type = FNAMECMP_FNAME;
 
        if (statret != 0 && basis_dir[0] != NULL) {
-               int fallback_match = -1;
+               int best_match = -1;
                int match_level = 0;
                int i = 0;
                do {
                        pathjoin(fnamecmpbuf, sizeof fnamecmpbuf,
                                 basis_dir[i], fname);
-                       if (link_stat(fnamecmpbuf, &st, 0) == 0
-                           && S_ISREG(st.st_mode)) {
-                               statret = 0;
-                               if (link_dest) {
-                                       if (!match_level) {
-                                               fallback_match = i;
-                                               match_level = 1;
-                                       } else if (match_level == 2
-                                           && !unchanged_attrs(file, &st))
-                                               continue;
-                                       if (!unchanged_file(fnamecmpbuf, file, &st))
-                                               continue;
-                                       fallback_match = i;
-                                       match_level = 2;
-                                       if (!unchanged_attrs(file, &st))
-                                               continue;
-                               }
+                       if (link_stat(fnamecmpbuf, &st, 0) < 0
+                           || !S_ISREG(st.st_mode))
+                               continue;
+                       switch (match_level) {
+                       case 0:
+                               best_match = i;
+                               match_level = 1;
+                               /* FALL THROUGH */
+                       case 1:
+                               if (!unchanged_file(fnamecmpbuf, file, &st))
+                                       continue;
+                               best_match = i;
+                               match_level = 2;
+                               /* FALL THROUGH */
+                       case 2:
+                               if (!unchanged_attrs(file, &st))
+                                       continue;
+                               best_match = i;
                                match_level = 3;
                                break;
                        }
+                       break;
                } while (basis_dir[++i] != NULL);
-               if (statret == 0) {
-                       if (match_level < 3) {
-                               i = fallback_match;
+               if (match_level) {
+                       statret = 0;
+                       if (i != best_match) {
+                               i = best_match;
                                pathjoin(fnamecmpbuf, sizeof fnamecmpbuf,
                                         basis_dir[i], fname);
+                               if (link_stat(fnamecmpbuf, &st, 0) < 0) {
+                                       match_level = 0;
+                                       statret = -1;
+                               }
                        }
 #ifdef HAVE_LINK
-                       if (link_dest && match_level == 3 && !dry_run) {
-                               if (do_link(fnamecmpbuf, fname) < 0) {
-                                       if (verbose) {
-                                               rsyserr(FINFO, errno,
-                                                       "link %s => %s",
-                                                       full_fname(fnamecmpbuf),
-                                                       safe_fname(fname));
-                                       }
-                                       fnamecmp = fnamecmpbuf;
-                                       fnamecmp_type = i;
+                       if (link_dest && match_level == 3
+                           && do_link(fnamecmpbuf, fname) < 0) {
+                               if (verbose) {
+                                       rsyserr(FINFO, errno, "link %s => %s",
+                                               full_fname(fnamecmpbuf),
+                                               safe_fname(fname));
                                }
-                       } else
+                               match_level = 2;
+                       }
 #endif
-                       {
+                       if (compare_dest || (match_level && match_level < 3)) {
                                fnamecmp = fnamecmpbuf;
                                fnamecmp_type = i;
                        }
@@ -1075,7 +1079,8 @@ void generate_files(int f_out, struct file_list *flist, char *local_name,
        int need_retouch_dir_perms = 0;
        int save_only_existing = only_existing;
        int save_opt_ignore_existing = opt_ignore_existing;
-       int allowed_lull = read_batch ? 0 : io_timeout / 2;
+       int allowed_lull = read_batch ? 0 : (io_timeout + 1) / 2;
+       int lull_mod = allowed_lull * 5;
 
        if (protocol_version >= 29) {
                itemizing = 1;
@@ -1134,7 +1139,7 @@ void generate_files(int f_out, struct file_list *flist, char *local_name,
                               flist, file, i, itemizing, maybe_PERMS_REPORT,
                               code, allowed_lull, f_out, f_out_name);
 
-               if (allowed_lull && !(i % 100))
+               if (allowed_lull && !(i % lull_mod))
                        maybe_send_keepalive(allowed_lull, flist->count);
        }
        recv_generator(NULL, NULL, NULL, 0, 0, 0, code, 0, -1, -1);
@@ -1146,6 +1151,7 @@ void generate_files(int f_out, struct file_list *flist, char *local_name,
        only_existing = max_size = opt_ignore_existing = 0;
        update_only = always_checksum = size_only = 0;
        ignore_times = 1;
+       make_backups = 0; /* avoid a duplicate backup for inplace processing */
 
        /* We expect to just sit around now, so don't exit on a timeout.
         * If we really get a timeout then the other process should exit. */
@@ -1163,8 +1169,6 @@ void generate_files(int f_out, struct file_list *flist, char *local_name,
                recv_generator(local_name ? local_name : f_name_to(file, fbuf),
                               flist, file, i, itemizing, maybe_PERMS_REPORT,
                               code, allowed_lull, f_out, f_out_name);
-               if (allowed_lull)
-                       maybe_send_keepalive(allowed_lull, flist->count);
        }
 
        phase++;
@@ -1180,13 +1184,14 @@ void generate_files(int f_out, struct file_list *flist, char *local_name,
        get_redo_num();
 
        if (preserve_hard_links)
-               do_hard_links();
+               do_hard_links(allowed_lull, flist->count);
 
        if (delete_after && !local_name && flist->count > 0)
                do_delete_pass(flist, allowed_lull);
 
        if ((need_retouch_dir_perms || need_retouch_dir_times)
            && !list_only && !local_name && !dry_run) {
+               int j = 0;
                /* Now we need to fix any directory permissions that were
                 * modified during the transfer and/or re-set any tweaked
                 * modified-time values. */
@@ -1200,7 +1205,7 @@ void generate_files(int f_out, struct file_list *flist, char *local_name,
                                       flist, file, i, itemizing,
                                       maybe_PERMS_REPORT, code, allowed_lull,
                                       -1, -1);
-                       if (allowed_lull && !(i % 500))
+                       if (allowed_lull && !(j++ % lull_mod))
                                maybe_send_keepalive(allowed_lull, flist->count);
                }
        }