X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/448797a1e6b0abb1867faec4cf83c021c34b8bda..64b761c19a17fa009344ee593c555d6bc69c164c:/exclude.c diff --git a/exclude.c b/exclude.c index d25b1b15..a7bd9cae 100644 --- a/exclude.c +++ b/exclude.c @@ -278,7 +278,7 @@ static char *parse_merge_name(const char *merge_file, unsigned int *len_ptr, } if (!sanitize_path(fn, merge_file, r, dirbuf_depth)) { rprintf(FERROR, "merge-file name overflows: %s\n", - merge_file); + safe_fname(merge_file)); return NULL; } } else { @@ -291,7 +291,8 @@ static char *parse_merge_name(const char *merge_file, unsigned int *len_ptr, goto done; if (dirbuf_len + fn_len >= MAXPATHLEN) { - rprintf(FERROR, "merge-file name overflows: %s\n", fn); + rprintf(FERROR, "merge-file name overflows: %s\n", + safe_fname(fn)); return NULL; } memcpy(buf, dirbuf + prefix_skip, dirbuf_len - prefix_skip); @@ -604,6 +605,18 @@ int check_filter(struct filter_list_struct *listp, char *name, int name_is_dir) return 0; } +#define RULE_MATCH(s,r) rule_match((s), (r), sizeof (r) - 1) + +static const char *rule_match(const char *str, const char *rule, int rule_len) +{ + if (strncmp(str, rule, rule_len) != 0) + return NULL; + if (isspace(str[rule_len]) || str[rule_len] == '_' || !str[rule_len]) + return str + rule_len - 1; + if (str[rule_len] == ',') + return str + rule_len; + return NULL; +} /* Get the next include/exclude arg from the string. The token will not * be '\0' terminated, so use the returned length to limit the string. @@ -638,7 +651,7 @@ static const char *parse_rule_tok(const char *p, uint32 mflags, int xflags, * for old include/exclude patterns where just "+ " and "- " are * allowed as optional prefixes. */ if (mflags & MATCHFLG_NO_PREFIXES) { - if (*s == '!') + if (*s == '!' && mflags & MATCHFLG_CVS_IGNORE) new_mflags |= MATCHFLG_CLEAR_LIST; /* Tentative! */ } else if (xflags & XFLG_OLD_PREFIXES) { if (*s == '-' && s[1] == ' ') { @@ -651,8 +664,35 @@ static const char *parse_rule_tok(const char *p, uint32 mflags, int xflags, if (*s == '!') new_mflags |= MATCHFLG_CLEAR_LIST; /* Tentative! */ } else { - char *mods = ""; + char ch = 0, *mods = ""; switch (*s) { + case 'c': + if ((s = RULE_MATCH(s, "clear")) != NULL) + ch = '!'; + break; + case 'd': + if ((s = RULE_MATCH(s, "dir-merge")) != NULL) + ch = ':'; + break; + case 'e': + if ((s = RULE_MATCH(s, "exclude")) != NULL) + ch = '-'; + break; + case 'i': + if ((s = RULE_MATCH(s, "include")) != NULL) + ch = '+'; + break; + case 'm': + if ((s = RULE_MATCH(s, "merge")) != NULL) + ch = '.'; + break; + default: + ch = *s; + if (s[1] == ',') + s++; + break; + } + switch (ch) { case ':': new_mflags |= MATCHFLG_PERDIR_MERGE | MATCHFLG_FINISH_SETUP;