merge_file);
return NULL;
}
+ fn_len = strlen(fn);
} else {
strlcpy(fn, merge_file, len_ptr ? *len_ptr + 1 : MAXPATHLEN);
- clean_fname(fn, 1);
+ fn_len = clean_fname(fn, 1);
}
- fn_len = strlen(fn);
- if (fn == buf)
- goto done;
-
- if (dirbuf_len + fn_len >= MAXPATHLEN) {
- rprintf(FERROR, "merge-file name overflows: %s\n", fn);
- return NULL;
+ /* If the name isn't in buf yet, it's wasn't absolute. */
+ if (fn != buf) {
+ if (dirbuf_len + fn_len >= MAXPATHLEN) {
+ rprintf(FERROR, "merge-file name overflows: %s\n", fn);
+ return NULL;
+ }
+ memcpy(buf, dirbuf + prefix_skip, dirbuf_len - prefix_skip);
+ memcpy(buf + dirbuf_len - prefix_skip, fn, fn_len + 1);
+ fn_len = clean_fname(buf, 1);
}
- memcpy(buf, dirbuf + prefix_skip, dirbuf_len - prefix_skip);
- memcpy(buf + dirbuf_len - prefix_skip, fn, fn_len + 1);
- fn_len = clean_fname(buf, 1);
- done:
if (len_ptr)
*len_ptr = fn_len;
return buf;
if (litmatch_array(pattern, strings, slash_handling))
return ret_match;
} else if (anchored_match) {
- if (strcmp(strings[0], pattern) == 0)
+ if (strcmp(name, pattern) == 0)
return ret_match;
} else {
int l1 = strlen(name);
}
/* --delete-excluded turns an un-modified include/exclude into a
- * sender-side rule. We also affect a per-dir .cvsignore file so
- * that we are compatible with older protocol versions. */
+ * sender-side rule. We also affect per-dir merge files that take
+ * no prefixes as a simple optimization. */
if (delete_excluded
&& !(new_mflags & (MATCHFLG_RECEIVER_SIDE|MATCHFLG_SENDER_SIDE))
- && (!(new_mflags & MATCHFLG_PERDIR_MERGE) || new_mflags & MATCHFLG_CVS_IGNORE))
+ && (!(new_mflags & MATCHFLG_PERDIR_MERGE)
+ || new_mflags & MATCHFLG_NO_PREFIXES))
new_mflags |= MATCHFLG_SENDER_SIDE;
*len_ptr = len;
&pat_len, &new_mflags);
if (!cp)
break;
+
+ pattern = cp + pat_len;
+
if (pat_len >= MAXPATHLEN) {
- rprintf(FERROR, "discarding over-long filter: %s\n",
- cp);
+ rprintf(FERROR, "discarding over-long filter: %.*s\n",
+ (int)pat_len, cp);
continue;
}
- pattern = cp + pat_len;
if (new_mflags & MATCHFLG_CLEAR_LIST) {
if (verbose > 2) {
}
len = pat_len;
if (new_mflags & MATCHFLG_EXCLUDE_SELF) {
- const char *name = strrchr(cp, '/');
- if (name)
- len -= ++name - cp;
- else
- name = cp;
+ const char *name = cp + len;
+ while (name > cp && name[-1] != '/') name--;
+ len -= name - cp;
add_rule(listp, name, len, 0, 0);
new_mflags &= ~MATCHFLG_EXCLUDE_SELF;
len = pat_len;
/* Note we need to check delete_excluded here in addition to
* the code in parse_rule_tok() because some rules may have
- * been added before we found the --delete-excluded option. */
+ * been added before we found the --delete-excluded option.
+ * We must also elide any CVS merge-file rules to avoid a
+ * backward compatibility problem, and we elide any no-prefix
+ * merge files as an optimization (since they can only have
+ * include/exclude rules). */
if (ent->match_flags & MATCHFLG_SENDER_SIDE)
elide = am_sender ? 1 : -1;
if (ent->match_flags & MATCHFLG_RECEIVER_SIDE)
elide = elide ? 0 : am_sender ? -1 : 1;
else if (delete_excluded && !elide
- && (!(ent->match_flags & MATCHFLG_PERDIR_MERGE) || ent->match_flags & MATCHFLG_CVS_IGNORE))
+ && (!(ent->match_flags & MATCHFLG_PERDIR_MERGE)
+ || ent->match_flags & MATCHFLG_NO_PREFIXES))
elide = am_sender ? 1 : -1;
if (elide < 0) {
if (prev)