Superseded by the better solution in merge-exclude-file.diff.
authorWayne Davison <wayned@samba.org>
Sat, 24 Apr 2004 20:13:07 +0000 (20:13 +0000)
committerWayne Davison <wayned@samba.org>
Sat, 24 Apr 2004 20:13:07 +0000 (20:13 +0000)
perdir-exclude-from.diff [deleted file]

diff --git a/perdir-exclude-from.diff b/perdir-exclude-from.diff
deleted file mode 100644 (file)
index 0598361..0000000
+++ /dev/null
@@ -1,337 +0,0 @@
-This patch was prompted by a patch called "--rsync-exclude" that John
-Bowman sent to the rsync mailing list.  It was improved and the option
-was renamed by Wayne Davison.
-
-Note that "merge-exclude-file.diff" solves this same problem in a better
-way, so this patch will be gone soon.
-
-..wayne..
-
---- exclude.c  24 Apr 2004 08:00:39 -0000      1.73
-+++ exclude.c  24 Apr 2004 08:09:39 -0000
-@@ -27,15 +27,17 @@
- #include "rsync.h"
- extern int verbose;
-+extern int protocol_version;
- extern int eol_nulls;
- extern int list_only;
- extern int recurse;
- extern char curr_dir[];
--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 " };
-+struct exclude_list_struct exclude_list = { 0, 0, 0, "" };
-+struct exclude_list_struct perdir_exclude_list = { 0, 0, 0, "per-dir custom " };
-+struct exclude_list_struct local_exclude_list = { 0, 0, 0, "per-dir .cvsignore " };
-+struct exclude_list_struct server_exclude_list = { 0, 0, 0, "server " };
- char *exclude_path_prefix = NULL;
- /** Build an exclude structure given a exclude pattern */
-@@ -85,6 +87,8 @@ static void make_exclude(struct exclude_
-       for (cp = ret->pattern; (cp = strchr(cp, '/')) != NULL; cp++)
-               ret->slash_cnt++;
-+      ret->next = listp->extra;
-+
-       if (!listp->tail)
-               listp->head = listp->tail = ret;
-       else {
-@@ -108,12 +112,26 @@ void free_exclude_list(struct exclude_li
-                       who_am_i(), listp->debug_type);
-       }
-+      if (listp->extra) {
-+              if (listp->tail)
-+                      listp->tail->next = NULL;
-+              else
-+                      listp->head = NULL;
-+      }
-+
-       for (ent = listp->head; ent; ent = next) {
-               next = ent->next;
-               free_exclude(ent);
-       }
--      listp->head = listp->tail = NULL;
-+      clear_exclude_list(listp, NULL);
-+}
-+
-+void clear_exclude_list(struct exclude_list_struct *listp,
-+                      struct exclude_struct *extra)
-+{
-+      listp->head = listp->extra = extra;
-+      listp->tail = NULL;
- }
- static int check_one_exclude(char *name, struct exclude_struct *ex,
-@@ -215,21 +233,24 @@ static void report_exclude_result(char c
- /*
-  * 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.
-+ * exclude list, 0 for a normal include, or 1 for a super include.
-  */
--int check_exclude(struct exclude_list_struct *listp, char *name, int name_is_dir)
-+int check_exclude(struct exclude_list_struct *listp, char *name, int name_is_dir,
-+                int current_exclusion)
- {
-       struct exclude_struct *ent;
-       for (ent = listp->head; ent; ent = ent->next) {
-+              if (current_exclusion < 0 && ent->include < 2)
-+                      continue;
-               if (check_one_exclude(name, ent, name_is_dir)) {
-                       report_exclude_result(name, ent, name_is_dir,
-                                             listp->debug_type);
--                      return ent->include ? 1 : -1;
-+                      return ent->include - 1;
-               }
-       }
--      return 0;
-+      return current_exclusion;
- }
-@@ -255,10 +276,10 @@ static const char *get_exclude_tok(const
-               p = (const char *)s;
-       }
--      /* Is this a '+' or '-' followed by a space (not whitespace)? */
-+      /* Is this a +/-/& followed by a space (not whitespace)? */
-       if (!(xflags & XFLG_NO_PREFIXES)
--          && (*s == '-' || *s == '+') && s[1] == ' ') {
--              *incl_ptr = *s == '+';
-+          && (*s == '-' || *s == '+' || *s == '&') && s[1] == ' ') {
-+              *incl_ptr = *s == '+' ? 1 : *s == '&' ? 2 : 0;
-               s += 2;
-       } else
-               *incl_ptr = xflags & XFLG_DEF_INCLUDE;
-@@ -390,8 +411,12 @@ void send_exclude_list(int f)
-               if (ent->include) {
-                       write_int(f, l + 2);
--                      write_buf(f, "+ ", 2);
--              } else if ((*p == '-' || *p == '+') && p[1] == ' ') {
-+                      if (ent->include > 1 && protocol_version >= 28)
-+                              write_buf(f, "& ", 2);
-+                      else
-+                              write_buf(f, "+ ", 2);
-+              } else if ((*p == '-' || *p == '+' || *p == '&')
-+                  && p[1] == ' ') {
-                       write_int(f, l + 2);
-                       write_buf(f, "- ", 2);
-               } else
---- flist.c    22 Apr 2004 22:17:15 -0000      1.216
-+++ flist.c    24 Apr 2004 08:09:39 -0000
-@@ -40,6 +40,7 @@ extern int ignore_errors;
- extern int numeric_ids;
- extern int cvs_exclude;
-+extern const char *perdir_exclude_from;
- extern int recurse;
- extern char curr_dir[MAXPATHLEN];
-@@ -66,6 +67,7 @@ extern int write_batch;
- extern struct exclude_list_struct exclude_list;
- extern struct exclude_list_struct server_exclude_list;
-+extern struct exclude_list_struct perdir_exclude_list;
- extern struct exclude_list_struct local_exclude_list;
- int io_error;
-@@ -211,7 +213,9 @@ int link_stat(const char *path, STRUCT_S
-  */
- static int check_exclude_file(char *fname, int is_dir, int exclude_level)
- {
--      int rc;
-+      static struct exclude_list_struct *elist[] = {
-+          &exclude_list, &perdir_exclude_list, &local_exclude_list, NULL };
-+      int i, rc;
- #if 0 /* This currently never happens, so avoid a useless compare. */
-       if (exclude_level == NO_EXCLUDES)
-@@ -229,17 +233,18 @@ static int check_exclude_file(char *fnam
-               }
-       }
-       if (server_exclude_list.head
--          && check_exclude(&server_exclude_list, fname, is_dir) < 0)
-+          && check_exclude(&server_exclude_list, fname, is_dir, 0) < 0)
-               return 1;
-       if (exclude_level != ALL_EXCLUDES)
-               return 0;
--      if (exclude_list.head
--          && (rc = check_exclude(&exclude_list, fname, is_dir)) != 0)
--              return rc < 0;
--      if (local_exclude_list.head
--          && check_exclude(&local_exclude_list, fname, is_dir) < 0)
--              return 1;
--      return 0;
-+      for (i = 0, rc = 0; elist[i]; i++) {
-+              if (!elist[i]->head)
-+                      continue;
-+              rc = check_exclude(elist[i], fname, is_dir, rc);
-+              if (rc > 0)
-+                      return 0;
-+      }
-+      return rc < 0;
- }
- /* used by the one_file_system code */
-@@ -947,8 +952,12 @@ void send_file_name(int f, struct file_l
-       if (recursive && S_ISDIR(file->mode)
-           && !(file->flags & FLAG_MOUNT_POINT)) {
-               struct exclude_list_struct last_list = local_exclude_list;
--              local_exclude_list.head = local_exclude_list.tail = NULL;
-+              struct exclude_list_struct sub_list = perdir_exclude_list;
-+              clear_exclude_list(&local_exclude_list, NULL);
-+              clear_exclude_list(&perdir_exclude_list, sub_list.head);
-               send_directory(f, flist, f_name_to(file, fbuf));
-+              free_exclude_list(&perdir_exclude_list);
-+              perdir_exclude_list = sub_list;
-               free_exclude_list(&local_exclude_list);
-               local_exclude_list = last_list;
-       }
-@@ -994,6 +1003,18 @@ static void send_directory(int f, struct
-                       io_error |= IOERR_GENERAL;
-                       rprintf(FINFO,
-                               "cannot cvs-exclude in long-named directory %s\n",
-+                              full_fname(fname));
-+              }
-+      }
-+
-+      if (perdir_exclude_from) {
-+              if (strlcpy(p, perdir_exclude_from, MAXPATHLEN - offset)
-+                  < MAXPATHLEN - offset)
-+                      add_exclude_file(&perdir_exclude_list, fname, 0);
-+              else {
-+                      io_error |= IOERR_GENERAL;
-+                      rprintf(FINFO,
-+                              "cannot perdir-exclude in long-named directory %s\n",
-                               full_fname(fname));
-               }
-       }
---- options.c  17 Apr 2004 17:07:23 -0000      1.147
-+++ options.c  24 Apr 2004 08:09:40 -0000
-@@ -70,6 +70,7 @@ int am_server = 0;
- int am_sender = 0;
- int am_generator = 0;
- char *files_from = NULL;
-+char *perdir_exclude_from = NULL;
- int filesfrom_fd = -1;
- char *remote_filesfrom_file = NULL;
- int eol_nulls = 0;
-@@ -273,6 +274,7 @@ void usage(enum logcode F)
-   rprintf(F,"     --exclude-from=FILE     exclude patterns listed in FILE\n");
-   rprintf(F,"     --include=PATTERN       don't exclude files matching PATTERN\n");
-   rprintf(F,"     --include-from=FILE     don't exclude patterns listed in FILE\n");
-+  rprintf(F,"     --perdir-exclude-from=F look in each dir for exclude-file F\n");
-   rprintf(F,"     --files-from=FILE       read FILE for list of source-file names\n");
-   rprintf(F," -0  --from0                 all *-from file lists are delimited by nulls\n");
-   rprintf(F,"     --version               print version number\n");
-@@ -335,6 +337,7 @@ static struct poptOption long_options[] 
-   {"dry-run",         'n', POPT_ARG_NONE,   &dry_run, 0, 0, 0 },
-   {"sparse",          'S', POPT_ARG_NONE,   &sparse_files, 0, 0, 0 },
-   {"cvs-exclude",     'C', POPT_ARG_NONE,   &cvs_exclude, 0, 0, 0 },
-+  {"perdir-exclude-from",0,POPT_ARG_STRING, &perdir_exclude_from, 0, 0, 0 },
-   {"update",          'u', POPT_ARG_NONE,   &update_only, 0, 0, 0 },
-   {"links",           'l', POPT_ARG_NONE,   &preserve_links, 0, 0, 0 },
-   {"copy-links",      'L', POPT_ARG_NONE,   &copy_links, 0, 0, 0 },
---- proto.h    22 Apr 2004 09:58:09 -0000      1.189
-+++ proto.h    24 Apr 2004 08:09:40 -0000
-@@ -52,7 +52,10 @@ int daemon_main(void);
- void setup_protocol(int f_out,int f_in);
- int claim_connection(char *fname,int max_connections);
- void free_exclude_list(struct exclude_list_struct *listp);
--int check_exclude(struct exclude_list_struct *listp, char *name, int name_is_dir);
-+void clear_exclude_list(struct exclude_list_struct *listp,
-+                      struct exclude_struct *extra);
-+int check_exclude(struct exclude_list_struct *listp, char *name, int name_is_dir,
-+                int current_exclusion);
- void add_exclude(struct exclude_list_struct *listp, const char *pattern,
-                int xflags);
- void add_exclude_file(struct exclude_list_struct *listp, const char *fname,
---- rsync.h    22 Apr 2004 09:58:24 -0000      1.198
-+++ rsync.h    24 Apr 2004 08:09:40 -0000
-@@ -502,6 +502,7 @@ struct exclude_struct {
- struct exclude_list_struct {
-       struct exclude_struct *head;
-       struct exclude_struct *tail;
-+      struct exclude_struct *extra;
-       char *debug_type;
- };
---- rsync.yo   24 Apr 2004 06:16:04 -0000      1.164
-+++ rsync.yo   24 Apr 2004 08:09:41 -0000
-@@ -331,6 +331,7 @@ verb(
-      --exclude-from=FILE     exclude patterns listed in FILE
-      --include=PATTERN       don't exclude files matching PATTERN
-      --include-from=FILE     don't exclude patterns listed in FILE
-+     --perdir-exclude-from=F look in each dir for exclude file F
-      --files-from=FILE       read FILE for list of source-file names
-  -0  --from0                 all file lists are delimited by nulls
-      --version               print version number
-@@ -680,6 +681,15 @@ dit(bf(--include-from=FILE)) This specif
- from a file.
- If em(FILE) is bf(-) the list will be read from standard input.
-+dit(bf(--perdir-exclude-from=FILE)) In any given directory, patterns
-+listed in FILE (one per line) are excluded from the file lists
-+associated with that directory and all of its subdirectories. Rules
-+specified in a subdir take precedence over rules evaluated in a parent
-+dir (think of each file's rules being prefixed to the prior rules).  If
-+you don't want to inherit the parent-dir rules, start the FILE with a
-+single exclamation mark ! to clear them out. You may prefix names with
-+an explicit exclude, include, or super-include prefix (see below).
-+
- dit(bf(--files-from=FILE)) Using this option allows you to specify the
- exact list of files to transfer (as read from the specified FILE or "-"
- for stdin).  It also tweaks the default behavior of rsync to make
-@@ -719,7 +729,8 @@ was located on the remote "src" host.
- dit(bf(-0, --from0)) This tells rsync that the filenames it reads from a
- file are terminated by a null ('\0') character, not a NL, CR, or CR+LF.
--This affects --exclude-from, --include-from, and --files-from.
-+This affects --exclude-from, --include-from, --perdir-exclude-from,
-+and --files-from.
- It does not affect --cvs-exclude (since all names read from a .cvsignore
- file are split on whitespace).
-@@ -1011,6 +1022,12 @@ itemize(
-   it() if the pattern starts with "- " (a minus followed by a space)
-   then it is always considered an exclude pattern, even if specified as
-   part of an include option. The prefix is discarded before matching.
-+
-+  it() if the pattern starts with "& " (an ampersand followed by a space)
-+  then it is considered a super-include pattern.  A super-include will
-+  override an exclude from another exclude list (a normal include only
-+  overrides an exclusion from further down in the same list).  The
-+  prefix is discarded before matching.
-   it() if the pattern is a single exclamation mark ! then the current
-   include/exclude list is reset, removing all previously defined patterns.
---- t_stub.c   22 Apr 2004 09:58:11 -0000      1.7
-+++ t_stub.c   24 Apr 2004 08:09:41 -0000
-@@ -46,7 +46,7 @@ struct exclude_list_struct server_exclud
- }
-  int check_exclude(UNUSED(struct exclude_list_struct *listp), UNUSED(char *name),
--                 UNUSED(int name_is_dir))
-+                 UNUSED(int name_is_dir), UNUSED(int current_exclusion))
- {
-       /* This function doesn't really get called in this test context, so
-        * just return 0. */
---- util.c     22 Apr 2004 22:17:15 -0000      1.138
-+++ util.c     24 Apr 2004 08:09:41 -0000
-@@ -476,7 +476,7 @@ static int exclude_server_path(char *arg
-       if (server_exclude_list.head) {
-               for (s = arg; (s = strchr(s, '/')) != NULL; ) {
-                       *s = '\0';
--                      if (check_exclude(&server_exclude_list, arg, 1) < 0) {
-+                      if (check_exclude(&server_exclude_list, arg, 1, 0) < 0) {
-                               /* We must leave arg truncated! */
-                               return 1;
-                       }