+
+ if (hard_link_one(file, fname, oldname, 0)) {
+ if (itemizing) {
+ itemize(fname, file, ndx, statret, sxp,
+ ITEM_LOCAL_CHANGE | ITEM_XNAME_FOLLOWS, 0,
+ realname);
+ }
+ if (code != FNONE && verbose)
+ rprintf(code, "%s => %s\n", fname, realname);
+ return 0;
+ }
+ return -1;
+}
+
+/* Figure out if a prior entry is still there or if we just have a
+ * cached name for it. */
+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)
+ break;
+ fp = flist->files[prev_ndx - flist->ndx_start];
+ if (!(fp->flags & FLAG_SKIP_HLINK)) {
+ *prev_ndx_p = prev_ndx;
+ *flist_p = flist;
+ return NULL;
+ }
+ 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) {
+ /* The prior file must have been skipped. */
+ F_HL_PREV(file) = prev_ndx = -1;
+ *prev_ndx_p = prev_ndx;
+ *flist_p = NULL;
+ return NULL;
+ }
+
+ *prev_ndx_p = prev_ndx;
+ *flist_p = flist;
+ return node->data;