Changed human_num() to big_num() with an extra arg so that it can
[rsync/rsync.git] / hlink.c
diff --git a/hlink.c b/hlink.c
index 536b571..d6d0ecf 100644 (file)
--- a/hlink.c
+++ b/hlink.c
@@ -22,7 +22,6 @@
 
 #include "rsync.h"
 
-extern int verbose;
 extern int dry_run;
 extern int list_only;
 extern int am_sender;
@@ -37,7 +36,7 @@ extern int stdout_format_has_i;
 extern int maybe_ATTRS_REPORT;
 extern int unsort_ndx;
 extern char *basis_dir[];
-extern struct file_list *cur_flist;
+extern struct file_list *cur_flist, *first_flist;
 
 #ifdef SUPPORT_HARD_LINKS
 
@@ -215,7 +214,7 @@ static int maybe_hard_link(struct file_struct *file, int ndx,
                                        ITEM_LOCAL_CHANGE | ITEM_XNAME_FOLLOWS,
                                        0, "");
                        }
-                       if (verbose > 1 && maybe_ATTRS_REPORT)
+                       if (INFO_GTE(NAME, 2) && maybe_ATTRS_REPORT)
                                rprintf(FCLIENT, "%s is uptodate\n", fname);
                        file->flags |= FLAG_HLINK_DONE;
                        return 0;
@@ -236,7 +235,7 @@ static int maybe_hard_link(struct file_struct *file, int ndx,
                                ITEM_LOCAL_CHANGE | ITEM_XNAME_FOLLOWS, 0,
                                realname);
                }
-               if (code != FNONE && verbose)
+               if (code != FNONE && INFO_GTE(NAME, 1))
                        rprintf(code, "%s => %s\n", fname, realname);
                return 0;
        }
@@ -249,17 +248,13 @@ static char *check_prior(struct file_struct *file, int gnum,
                         int *prev_ndx_p, struct file_list **flist_p)
 {
        struct file_struct *fp;
-       struct file_list *flist;
        struct ht_int32_node *node;
        int prev_ndx = F_HL_PREV(file);
 
        while (1) {
-               if (prev_ndx < 0) {
-                       *prev_ndx_p = prev_ndx;
-                       *flist_p = NULL;
-                       return NULL;
-               }
-               if ((flist = flist_for_ndx(prev_ndx)) == NULL)
+               struct file_list *flist;
+               if (prev_ndx < 0
+                || (flist = flist_for_ndx(prev_ndx)) == NULL)
                        break;
                fp = flist->files[prev_ndx - flist->ndx_start];
                if (!(fp->flags & FLAG_SKIP_HLINK)) {
@@ -270,20 +265,21 @@ static char *check_prior(struct file_struct *file, int gnum,
                F_HL_PREV(file) = prev_ndx = F_HL_PREV(fp);
        }
 
-       node = hashtable_find(prior_hlinks, gnum, 0);
-       assert(node != NULL && node->data);
-
-       if (CVAL(node->data, 0) == 0) {
+       if (inc_recurse
+        && (node = hashtable_find(prior_hlinks, gnum, 0)) != NULL) {
+               assert(node->data != NULL);
+               if (CVAL(node->data, 0) != 0) {
+                       *prev_ndx_p = -1;
+                       *flist_p = NULL;
+                       return node->data;
+               }
                /* The prior file must have been skipped. */
-               F_HL_PREV(file) = prev_ndx = -1;
-               *prev_ndx_p = prev_ndx;
-               *flist_p = NULL;
-               return NULL;
+               F_HL_PREV(file) = -1;
        }
 
-       *prev_ndx_p = prev_ndx;
-       *flist_p = flist;
-       return node->data;
+       *prev_ndx_p = -1;
+       *flist_p = NULL;
+       return NULL;
 }
 
 /* Only called if FLAG_HLINKED is set and FLAG_HLINK_FIRST is not.  Returns:
@@ -380,10 +376,10 @@ int hard_link_check(struct file_struct *file, int ndx, const char *fname,
                                        continue;
                                statret = 1;
                                if (stdout_format_has_i == 0
-                                || (verbose < 2 && stdout_format_has_i < 2)) {
+                                || (!INFO_GTE(NAME, 2) && stdout_format_has_i < 2)) {
                                        itemizing = 0;
                                        code = FNONE;
-                                       if (verbose > 1 && maybe_ATTRS_REPORT)
+                                       if (INFO_GTE(NAME, 2) && maybe_ATTRS_REPORT)
                                                rprintf(FCLIENT, "%s is uptodate\n", fname);
                                }
                                break;
@@ -429,7 +425,7 @@ int hard_link_one(struct file_struct *file, const char *fname,
        if (do_link(oldname, fname) < 0) {
                enum logcode code;
                if (terse) {
-                       if (!verbose)
+                       if (!INFO_GTE(NAME, 1))
                                return 0;
                        code = FINFO;
                } else
@@ -450,7 +446,7 @@ void finish_hard_link(struct file_struct *file, const char *fname, int fin_ndx,
 {
        stat_x prev_sx;
        STRUCT_STAT st;
-       char alt_name[MAXPATHLEN], *prev_name;
+       char prev_name[MAXPATHLEN], alt_name[MAXPATHLEN];
        const char *our_name;
        struct file_list *flist;
        int prev_statret, ndx, prev_ndx = F_HL_PREV(file);
@@ -481,13 +477,20 @@ void finish_hard_link(struct file_struct *file, const char *fname, int fin_ndx,
        while ((ndx = prev_ndx) >= 0) {
                int val;
                flist = flist_for_ndx(ndx);
-               assert(flist != NULL);
+               if (flist == NULL) {
+                       int start1 = first_flist ? first_flist->ndx_start : 0;
+                       int start2 = first_flist ? first_flist->prev->ndx_start : 0;
+                       int used = first_flist ? first_flist->prev->used : 0;
+                       rprintf(FERROR,
+                               "File index not found: %d (%d - %d)\n",
+                               ndx, start1 - 1, start2 + used - 1);
+                       exit_cleanup(RERR_PROTOCOL);
+               }
                file = flist->files[ndx - flist->ndx_start];
                file->flags = (file->flags & ~FLAG_HLINK_FIRST) | FLAG_HLINK_DONE;
                prev_ndx = F_HL_PREV(file);
                F_HL_PREV(file) = fin_ndx;
-               prev_name = f_name(file, NULL);
-               prev_statret = link_stat(prev_name, &prev_sx.st, 0);
+               prev_statret = link_stat(f_name(file, prev_name), &prev_sx.st, 0);
                val = maybe_hard_link(file, ndx, prev_name, prev_statret, &prev_sx,
                                      our_name, stp, fname, itemizing, code);
                flist->in_progress--;