X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/4adbb5f24683417a90a1cc00be54e58d2f7a901a..9aacb4df0e29b11e298d7353467d821e4a17cc12:/exclude.c diff --git a/exclude.c b/exclude.c index fa11e449..32fac195 100644 --- a/exclude.c +++ b/exclude.c @@ -133,9 +133,9 @@ static void add_rule(struct filter_list_struct *listp, const char *pat, listp->debug_type); } - /* This flag also indicates that we're reading a list that + /* These flags also indicate that we're reading a list that * needs to be filtered now, not post-filtered later. */ - if (xflags & XFLG_ANCHORED2ABS) { + if (xflags & (XFLG_ANCHORED2ABS|XFLG_ABS_IF_SLASH)) { uint32 mf = mflags & (MATCHFLG_RECEIVER_SIDE|MATCHFLG_SENDER_SIDE); if (am_sender) { if (mf == MATCHFLG_RECEIVER_SIDE) @@ -150,10 +150,14 @@ static void add_rule(struct filter_list_struct *listp, const char *pat, out_of_memory("add_rule"); memset(ret, 0, sizeof ret[0]); - if (xflags & XFLG_ANCHORED2ABS && *pat == '/' - && !(mflags & (MATCHFLG_ABS_PATH | MATCHFLG_MERGE_FILE))) { + if (!(mflags & (MATCHFLG_ABS_PATH | MATCHFLG_MERGE_FILE)) + && ((xflags & (XFLG_ANCHORED2ABS|XFLG_ABS_IF_SLASH) && *pat == '/') + || (xflags & XFLG_ABS_IF_SLASH && strchr(pat, '/') != NULL))) { mflags |= MATCHFLG_ABS_PATH; - ex_len = dirbuf_len - module_dirlen - 1; + if (*pat == '/') + ex_len = dirbuf_len - module_dirlen - 1; + else + ex_len = 0; } else ex_len = 0; if (!(ret->pattern = new_array(char, ex_len + pat_len + 1))) @@ -674,8 +678,7 @@ static const char *parse_rule_tok(const char *p, uint32 mflags, int xflags, } else if (*s == '+' && s[1] == ' ') { new_mflags |= MATCHFLG_INCLUDE; s += 2; - } - if (*s == '!') + } else if (*s == '!') new_mflags |= MATCHFLG_CLEAR_LIST; /* Tentative! */ } else { char ch = 0, *mods = ""; @@ -716,7 +719,6 @@ static const char *parse_rule_tok(const char *p, uint32 mflags, int xflags, if ((s = RULE_STRCMP(s, "show")) != NULL) ch = 'S'; break; - default: ch = *s; if (s[1] == ',') @@ -757,7 +759,7 @@ static const char *parse_rule_tok(const char *p, uint32 mflags, int xflags, mods = NULL; break; default: - rprintf(FERROR, "Unknown filter rule: %s\n", p); + rprintf(FERROR, "Unknown filter rule: `%s'\n", p); exit_cleanup(RERR_SYNTAX); } while (mods && *++s && *s != ' ' && *s != '_') { @@ -829,7 +831,8 @@ static const char *parse_rule_tok(const char *p, uint32 mflags, int xflags, len = strlen((char*)s); if (new_mflags & MATCHFLG_CLEAR_LIST) { - if (!(xflags & XFLG_OLD_PREFIXES) && len) { + if (!(mflags & MATCHFLG_NO_PREFIXES) + && !(xflags & XFLG_OLD_PREFIXES) && len) { rprintf(FERROR, "'!' rule has trailing characters: %s\n", p); exit_cleanup(RERR_SYNTAX); @@ -956,7 +959,7 @@ void parse_filter_file(struct filter_list_struct *listp, const char *fname, uint32 mflags, int xflags) { FILE *fp; - char line[MAXPATHLEN+MAX_RULE_PREFIX+1]; /* +1 for trailing slash. */ + char line[BIGPATHBUFLEN]; char *eob = line + sizeof line - 1; int word_split = mflags & MATCHFLG_WORD_SPLIT; @@ -1034,7 +1037,7 @@ char *get_rule_prefix(int match_flags, const char *pat, int for_xfer, { static char buf[MAX_RULE_PREFIX+1]; char *op = buf; - int legal_len = for_xfer && protocol_version < 29 ? 1 : MAX_RULE_PREFIX; + int legal_len = for_xfer && protocol_version < 29 ? 1 : MAX_RULE_PREFIX-1; if (match_flags & MATCHFLG_PERDIR_MERGE) { if (legal_len == 1) @@ -1071,10 +1074,10 @@ char *get_rule_prefix(int match_flags, const char *pat, int for_xfer, && (!for_xfer || protocol_version >= 29 || (delete_excluded && am_sender))) *op++ = 'r'; - if (legal_len) - *op++ = ' '; if (op - buf > legal_len) return NULL; + if (legal_len) + *op++ = ' '; *op = '\0'; if (plen_ptr) *plen_ptr = op - buf; @@ -1107,9 +1110,9 @@ static void send_rules(int f_out, struct filter_list_struct *flp) continue; if (ent->match_flags & MATCHFLG_CVS_IGNORE && !(ent->match_flags & MATCHFLG_MERGE_FILE)) { - int f = am_sender || protocol_version < 29 ? f_out : -1; + int f = am_sender || protocol_version < 29 ? f_out : -2; send_rules(f, &cvs_filter_list); - if (f >= 0) + if (f == f_out) continue; } p = get_rule_prefix(ent->match_flags, ent->pattern, 1, &plen); @@ -1169,7 +1172,7 @@ void send_filter_list(int f_out) /* This is only called by the server. */ void recv_filter_list(int f_in) { - char line[MAXPATHLEN+MAX_RULE_PREFIX+1]; /* +1 for trailing slash. */ + char line[BIGPATHBUFLEN]; int xflags = protocol_version >= 29 ? 0 : XFLG_OLD_PREFIXES; int receiver_wants_list = delete_mode && (!delete_excluded || protocol_version >= 29); @@ -1178,7 +1181,7 @@ void recv_filter_list(int f_in) if (!local_server && (am_sender || receiver_wants_list)) { while ((len = read_int(f_in)) != 0) { if (len >= sizeof line) - overflow("recv_rules"); + overflow_exit("recv_rules"); read_sbuf(f_in, line, len); parse_rule(&filter_list, line, 0, xflags); }