X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/5e972dcf34df59af1ba5ffd91b6ca278de22b847..e7bf7c01613fbd726720cb676bc47a743da06f2f:/exclude.c diff --git a/exclude.c b/exclude.c index 78d9c8ce..225c0e21 100644 --- a/exclude.c +++ b/exclude.c @@ -84,14 +84,14 @@ static void make_exclude(struct exclude_list_struct *listp, const char *pat, for (cp = ret->pattern; (cp = strchr(cp, '/')) != NULL; cp++) ret->slash_cnt++; + ret->match_flags = mflags; + if (!listp->tail) listp->head = listp->tail = ret; else { listp->tail->next = ret; listp->tail = ret; } - - ret->match_flags = mflags; } static void free_exclude(struct exclude_struct *ex) @@ -100,7 +100,7 @@ static void free_exclude(struct exclude_struct *ex) free(ex); } -void free_exclude_list(struct exclude_list_struct *listp) +void clear_exclude_list(struct exclude_list_struct *listp) { struct exclude_struct *ent, *next; @@ -115,10 +115,13 @@ void free_exclude_list(struct exclude_list_struct *listp) static int check_one_exclude(char *name, struct exclude_struct *ex, int name_is_dir) { - char *p; + char *p, full_name[MAXPATHLEN]; int match_start = 0; char *pattern = ex->pattern; + if (!*name) + return 0; + /* If the pattern does not have any slashes AND it does not have * a "**" (which could match a slash), then we just match the * name portion of the path. */ @@ -126,15 +129,12 @@ static int check_one_exclude(char *name, struct exclude_struct *ex, if ((p = strrchr(name,'/')) != NULL) name = p+1; } - else if (ex->match_flags & MATCHFLG_ABS_PATH && *name != '/') { - static char full_name[MAXPATHLEN]; - int plus = curr_dir[1] == '\0'? 1 : 0; - pathjoin(full_name, sizeof full_name, curr_dir+plus, name); + else if (ex->match_flags & MATCHFLG_ABS_PATH && *name != '/' + && curr_dir[1]) { + pathjoin(full_name, sizeof full_name, curr_dir + 1, name); name = full_name; } - if (!name[0]) return 0; - if (ex->match_flags & MATCHFLG_DIRECTORY && !name_is_dir) return 0; @@ -235,10 +235,10 @@ int check_exclude(struct exclude_list_struct *listp, char *name, int name_is_dir /* 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. * Also, be sure to add this length to the returned pointer before passing - * it back to ask for the next token. This routine will not parse the +/- - * prefixes or the "!" token when xflags contains XFLG_WORDS_ONLY. The - * *incl_ptr value will be 1 for an include, 0 for an exclude, and -1 for - * the list-clearing "!" token. + * it back to ask for the next token. This routine parses the "!" (list- + * clearing) token and (if xflags does NOT contain XFLG_WORDS_ONLY) the + * +/- prefixes for overriding the include/exclude mode. The *flag_ptr + * value will also be set to the MATCHFLG_* bits for the current token. */ static const char *get_exclude_tok(const char *p, unsigned int *len_ptr, unsigned int *flag_ptr, int xflags) @@ -262,6 +262,8 @@ static const char *get_exclude_tok(const char *p, unsigned int *len_ptr, s += 2; } else if (xflags & XFLG_DEF_INCLUDE) mflags |= MATCHFLG_INCLUDE; + if (xflags & XFLG_DIRECTORY) + mflags |= MATCHFLG_DIRECTORY; if (xflags & XFLG_WORD_SPLIT) { const unsigned char *cp = s; @@ -272,7 +274,7 @@ static const char *get_exclude_tok(const char *p, unsigned int *len_ptr, } else len = strlen(s); - if (*p == '!' && len == 1 && !(xflags & XFLG_WORDS_ONLY)) + if (*p == '!' && len == 1) mflags |= MATCHFLG_CLEAR_LIST; *len_ptr = len; @@ -303,7 +305,7 @@ void add_exclude(struct exclude_list_struct *listp, const char *pattern, "[%s] clearing %sexclude list\n", who_am_i(), listp->debug_type); } - free_exclude_list(listp); + clear_exclude_list(listp); continue; } @@ -311,7 +313,7 @@ void add_exclude(struct exclude_list_struct *listp, const char *pattern, if (verbose > 2) { rprintf(FINFO, "[%s] add_exclude(%.*s, %s%sclude)\n", - who_am_i(), pat_len, cp, listp->debug_type, + who_am_i(), (int)pat_len, cp, listp->debug_type, mflags & MATCHFLG_INCLUDE ? "in" : "ex"); } } @@ -323,7 +325,7 @@ void add_exclude_file(struct exclude_list_struct *listp, const char *fname, { FILE *fp; char line[MAXPATHLEN+3]; /* Room for "x " prefix and trailing slash. */ - char *eob = line + MAXPATHLEN - 1; + char *eob = line + sizeof line - 1; int word_split = xflags & XFLG_WORD_SPLIT; if (!fname || !*fname) @@ -381,11 +383,9 @@ void send_exclude_list(int f) { struct exclude_struct *ent; - /* This is a complete hack - blame Rusty. - * - * FIXME: This pattern shows up in the output of - * report_exclude_result(), which is not ideal. */ - if (list_only && !recurse) + /* This is a complete hack - blame Rusty. FIXME! + * Remove this hack when older rsyncs (below 2.6.4) are gone. */ + if (list_only == 1 && !recurse) add_exclude(&exclude_list, "/*/*", 0); for (ent = exclude_list.head; ent; ent = ent->next) { @@ -403,7 +403,7 @@ void send_exclude_list(int f) if (ent->match_flags & MATCHFLG_INCLUDE) { write_int(f, l + 2); write_buf(f, "+ ", 2); - } else if ((*p == '-' || *p == '+') && p[1] == ' ') { + } else if (*p == '-' || *p == '+') { write_int(f, l + 2); write_buf(f, "- ", 2); } else