X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/c9b62cf375f393de076d0fc7a3c2748d581c54a2..97dde6b6200aa0a3333e4f821e24dd5f0f91ec75:/hlink.c diff --git a/hlink.c b/hlink.c index 536b571f..d6d0ecfc 100644 --- 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--;