Some demon_log_* variables changed into logfile_* variables that are
[rsync/rsync.git] / exclude.c
index 35a64b9..0da15b2 100644 (file)
--- a/exclude.c
+++ b/exclude.c
@@ -1,8 +1,10 @@
-/* -*- c-file-style: "linux" -*-
+/*
+ * The filter include/exclude routines.
  *
- * Copyright (C) 1996-2001 by Andrew Tridgell <tridge@samba.org>
- * Copyright (C) 1996 by Paul Mackerras
- * Copyright (C) 2002 by Martin Pool
+ * Copyright (C) 1996-2001 Andrew Tridgell <tridge@samba.org>
+ * Copyright (C) 1996 Paul Mackerras
+ * Copyright (C) 2002 Martin Pool
+ * Copyright (C) 2003, 2004, 2005, 2006 Wayne Davison
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
  */
 
-/* a lot of this stuff was originally derived from GNU tar, although
-   it has now changed so much that it is hard to tell :) */
-
-/* include/exclude cluestick added by Martin Pool <mbp@samba.org> */
-
 #include "rsync.h"
 
 extern int verbose;
@@ -34,6 +31,7 @@ extern int list_only;
 extern int recurse;
 extern int io_error;
 extern int local_server;
+extern int prune_empty_dirs;
 extern int delete_mode;
 extern int delete_excluded;
 extern int cvs_exclude;
@@ -300,23 +298,22 @@ static char *parse_merge_name(const char *merge_file, unsigned int *len_ptr,
                        strlcpy(to, merge_file, *len_ptr + 1);
                        merge_file = to;
                }
-               if (!sanitize_path(fn, merge_file, r, dirbuf_depth)) {
+               if (!sanitize_path(fn, merge_file, r, dirbuf_depth, NULL)) {
                        rprintf(FERROR, "merge-file name overflows: %s\n",
-                               safe_fname(merge_file));
+                               merge_file);
                        return NULL;
                }
        } else {
                strlcpy(fn, merge_file, len_ptr ? *len_ptr + 1 : MAXPATHLEN);
                clean_fname(fn, 1);
        }
-       
+
        fn_len = strlen(fn);
        if (fn == buf)
                goto done;
 
        if (dirbuf_len + fn_len >= MAXPATHLEN) {
-               rprintf(FERROR, "merge-file name overflows: %s\n",
-                       safe_fname(fn));
+               rprintf(FERROR, "merge-file name overflows: %s\n", fn);
                return NULL;
        }
        memcpy(buf, dirbuf + prefix_skip, dirbuf_len - prefix_skip);
@@ -560,7 +557,7 @@ static int rule_matches(char *name, struct filter_struct *ex, int name_is_dir)
                if (litmatch_array(pattern, strings, slash_handling))
                        return ret_match;
        } else if (anchored_match) {
-               if (strcmp(name,pattern) == 0)
+               if (strcmp(strings[0], pattern) == 0)
                        return ret_match;
        } else {
                int l1 = strlen(name);
@@ -585,11 +582,13 @@ static void report_filter_result(char const *name,
         * case we add it back in here. */
 
        if (verbose >= 2) {
-               rprintf(FINFO, "[%s] %scluding %s %s because of pattern %s%s%s\n",
-                       who_am_i(),
-                       ent->match_flags & MATCHFLG_INCLUDE ? "in" : "ex",
-                       name_is_dir ? "directory" : "file", name, ent->pattern,
-                       ent->match_flags & MATCHFLG_DIRECTORY ? "/" : "", type);
+               static char *actions[2][2]
+                   = { {"show", "hid"}, {"risk", "protect"} };
+               const char *w = who_am_i();
+               rprintf(FINFO, "[%s] %sing %s %s because of pattern %s%s%s\n",
+                   w, actions[*w!='s'][!(ent->match_flags&MATCHFLG_INCLUDE)],
+                   name_is_dir ? "directory" : "file", name, ent->pattern,
+                   ent->match_flags & MATCHFLG_DIRECTORY ? "/" : "", type);
        }
 }
 
@@ -854,7 +853,7 @@ static const char *parse_rule_tok(const char *p, uint32 mflags, int xflags,
 }
 
 
-static char default_cvsignore[] = 
+static char default_cvsignore[] =
        /* These default ignored items come from the CVS manual. */
        "RCS SCCS CVS CVS.adm RCSLOG cvslog.* tags TAGS"
        " .make.state .nse_depinfo *~ #* .#* ,* _$* *$"
@@ -985,7 +984,7 @@ void parse_filter_file(struct filter_list_struct *listp, const char *fname,
 
        if (verbose > 2) {
                rprintf(FINFO, "[%s] parse_filter_file(%s,%x,%x)%s\n",
-                       who_am_i(), safe_fname(fname), mflags, xflags,
+                       who_am_i(), fname, mflags, xflags,
                        fp ? "" : " [not found]");
        }
 
@@ -994,7 +993,7 @@ void parse_filter_file(struct filter_list_struct *listp, const char *fname,
                        rsyserr(FERROR, errno,
                                "failed to open %sclude file %s",
                                mflags & MATCHFLG_INCLUDE ? "in" : "ex",
-                               safe_fname(fname));
+                               fname);
                        exit_cleanup(RERR_FILEIO);
                }
                return;
@@ -1006,8 +1005,10 @@ void parse_filter_file(struct filter_list_struct *listp, const char *fname,
                int ch, overflow = 0;
                while (1) {
                        if ((ch = getc(fp)) == EOF) {
-                               if (ferror(fp) && errno == EINTR)
+                               if (ferror(fp) && errno == EINTR) {
+                                       clearerr(fp);
                                        continue;
+                               }
                                break;
                        }
                        if (word_split && isspace(ch))
@@ -1144,8 +1145,8 @@ static void send_rules(int f_out, struct filter_list_struct *flp)
 /* This is only called by the client. */
 void send_filter_list(int f_out)
 {
-       int receiver_wants_list = delete_mode
-               && (!delete_excluded || protocol_version >= 29);
+       int receiver_wants_list = prune_empty_dirs
+           || (delete_mode && (!delete_excluded || protocol_version >= 29));
 
        if (local_server || (am_sender && !receiver_wants_list))
                f_out = -1;
@@ -1178,8 +1179,9 @@ void recv_filter_list(int f_in)
 {
        char line[BIGPATHBUFLEN];
        int xflags = protocol_version >= 29 ? 0 : XFLG_OLD_PREFIXES;
-       int receiver_wants_list = delete_mode
-               && (!delete_excluded || protocol_version >= 29);
+       int receiver_wants_list = prune_empty_dirs
+           || (delete_mode
+            && (!delete_excluded || protocol_version >= 29));
        unsigned int len;
 
        if (!local_server && (am_sender || receiver_wants_list)) {