Changed PERMS_SKIP_TIME to PERMS_SKIP_MTIME.
[rsync/rsync.git] / exclude.c
index d0653be..07d24a1 100644 (file)
--- a/exclude.c
+++ b/exclude.c
@@ -33,9 +33,9 @@ extern int recurse;
 
 extern char curr_dir[];
 
-struct exclude_list_struct exclude_list;
-struct exclude_list_struct local_exclude_list;
-struct exclude_list_struct server_exclude_list;
+struct exclude_list_struct exclude_list = { 0, 0, "" };
+struct exclude_list_struct local_exclude_list = { 0, 0, "per-dir .cvsignore " };
+struct exclude_list_struct server_exclude_list = { 0, 0, "server " };
 char *exclude_path_prefix = NULL;
 
 /** Build an exclude structure given a exclude pattern */
@@ -103,15 +103,17 @@ void free_exclude_list(struct exclude_list_struct *listp)
 {
        struct exclude_struct *ent, *next;
 
-       if (verbose > 2)
-               rprintf(FINFO, "[%s] clearing exclude list\n", who_am_i());
+       if (verbose > 2) {
+               rprintf(FINFO, "[%s] clearing %sexclude list\n",
+                       who_am_i(), listp->debug_type);
+       }
 
        for (ent = listp->head; ent; ent = next) {
                next = ent->next;
                free_exclude(ent);
        }
 
-       memset(listp, 0, sizeof listp[0]);
+       listp->head = listp->tail = NULL;
 }
 
 static int check_one_exclude(char *name, struct exclude_struct *ex,
@@ -203,7 +205,7 @@ static void report_exclude_result(char const *name,
         * case we add it back in here. */
 
        if (verbose >= 2) {
-               rprintf(FINFO, "[%s] %scluding %s %s because of %s %s%s\n",
+               rprintf(FINFO, "[%s] %scluding %s %s because of %spattern %s%s\n",
                        who_am_i(), ent->include ? "in" : "ex",
                        name_is_dir ? "directory" : "file", name, type,
                        ent->pattern, ent->directory ? "/" : "");
@@ -212,18 +214,18 @@ static void report_exclude_result(char const *name,
 
 
 /*
- * Return true if file NAME is defined to be excluded by the specified
- * exclude list.
+ * Return -1 if file "name" is defined to be excluded by the specified
+ * exclude list, 1 if it is included, and 0 if it was not matched.
  */
-int check_exclude(struct exclude_list_struct *listp, char *name, int name_is_dir,
-                 const char *type)
+int check_exclude(struct exclude_list_struct *listp, char *name, int name_is_dir)
 {
        struct exclude_struct *ent;
 
        for (ent = listp->head; ent; ent = ent->next) {
                if (check_one_exclude(name, ent, name_is_dir)) {
-                       report_exclude_result(name, ent, name_is_dir, type);
-                       return !ent->include;
+                       report_exclude_result(name, ent, name_is_dir,
+                                             listp->debug_type);
+                       return ent->include ? 1 : -1;
                }
        }
 
@@ -234,8 +236,8 @@ 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 split off a
- * prefix of "+ " or "- " unless xflags contains XFLG_NO_PREFIXES.  The
+ * 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.
  */
@@ -254,7 +256,7 @@ static const char *get_exclude_tok(const char *p, int *len_ptr, int *incl_ptr,
        }
 
        /* Is this a '+' or '-' followed by a space (not whitespace)? */
-       if (!(xflags & XFLG_NO_PREFIXES)
+       if (!(xflags & XFLG_WORDS_ONLY)
            && (*s == '-' || *s == '+') && s[1] == ' ') {
                *incl_ptr = *s == '+';
                s += 2;
@@ -270,7 +272,7 @@ static const char *get_exclude_tok(const char *p, int *len_ptr, int *incl_ptr,
        } else
                len = strlen(s);
 
-       if (*p == '!' && len == 1 && !(xflags & XFLG_NO_PREFIXES))
+       if (*p == '!' && len == 1 && !(xflags & XFLG_WORDS_ONLY))
                *incl_ptr = -1;
 
        *len_ptr = len;
@@ -300,8 +302,9 @@ void add_exclude(struct exclude_list_struct *listp, const char *pattern,
                        make_exclude(listp, cp, pat_len, incl);
 
                        if (verbose > 2) {
-                               rprintf(FINFO, "[%s] add_exclude(%s,%s)\n",
-                                       who_am_i(), cp,
+                               rprintf(FINFO, "[%s] add_exclude(%.*s, %s%s)\n",
+                                       who_am_i(), pat_len, cp,
+                                       listp->debug_type,
                                        incl ? "include" : "exclude");
                        }
                }
@@ -352,8 +355,8 @@ void add_exclude_file(struct exclude_list_struct *listp, const char *fname,
                                *s++ = ch;
                }
                *s = '\0';
-               /* Skip lines starting with semicolon or pound. */
-               if (*line && *line != ';' && *line != '#')
+               /* Skip an empty token and (when line parsing) comments. */
+               if (*line && (word_split || (*line != ';' && *line != '#')))
                        add_exclude(listp, line, xflags);
                if (ch == EOF)
                        break;
@@ -430,14 +433,14 @@ void add_cvs_excludes(void)
        char *p;
 
        add_exclude(&exclude_list, default_cvsignore,
-                   XFLG_WORD_SPLIT | XFLG_NO_PREFIXES);
+                   XFLG_WORD_SPLIT | XFLG_WORDS_ONLY);
 
        if ((p = getenv("HOME"))
            && pathjoin(fname, sizeof fname, p, ".cvsignore") < sizeof fname) {
                add_exclude_file(&exclude_list, fname,
-                                XFLG_WORD_SPLIT | XFLG_NO_PREFIXES);
+                                XFLG_WORD_SPLIT | XFLG_WORDS_ONLY);
        }
 
        add_exclude(&exclude_list, getenv("CVSIGNORE"),
-                   XFLG_WORD_SPLIT | XFLG_NO_PREFIXES);
+                   XFLG_WORD_SPLIT | XFLG_WORDS_ONLY);
 }