#include "rsync.h"
-extern int verbose;
extern int am_server;
extern int am_sender;
extern int eol_nulls;
#define MODIFIERS_INCL_EXCL "/!Crsp"
#define MODIFIERS_HIDE_PROTECT "/!p"
+#define SLASH_WILD3_SUFFIX "/***"
+
/* The dirbuf is set by push_local_filters() to the current subdirectory
* relative to curr_dir that is being processed. The path always has a
* trailing slash appended, and the variable dirbuf_len contains the length
{
struct filter_struct *ret;
const char *cp;
- unsigned int pre_len, slash_cnt = 0;
+ unsigned int pre_len, suf_len, slash_cnt = 0;
- if (verbose > 2) {
+ if (DEBUG_GTE(FILTER, 2)) {
rprintf(FINFO, "[%s] add_rule(%s%.*s%s)%s\n",
who_am_i(), get_rule_prefix(mflags, pat, 0, NULL),
(int)pat_len, pat,
} else
pre_len = 0;
- if (!(ret->pattern = new_array(char, pre_len + pat_len + 1)))
+ /* The daemon wants dir-exclude rules to get an appended "/" + "***". */
+ if (xflags & XFLG_DIR2WILD3
+ && BITS_SETnUNSET(mflags, MATCHFLG_DIRECTORY, MATCHFLG_INCLUDE)) {
+ mflags &= ~MATCHFLG_DIRECTORY;
+ suf_len = sizeof SLASH_WILD3_SUFFIX - 1;
+ } else
+ suf_len = 0;
+
+ if (!(ret->pattern = new_array(char, pre_len + pat_len + suf_len + 1)))
out_of_memory("add_rule");
if (pre_len) {
memcpy(ret->pattern, dirbuf + module_dirlen, pre_len);
}
strlcpy(ret->pattern + pre_len, pat, pat_len + 1);
pat_len += pre_len;
+ if (suf_len) {
+ memcpy(ret->pattern + pat_len, SLASH_WILD3_SUFFIX, suf_len+1);
+ pat_len += suf_len;
+ slash_cnt++;
+ }
if (strpbrk(ret->pattern, "*[?")) {
mflags |= MATCHFLG_WILD;
/* If the name isn't in buf yet, it's wasn't absolute. */
if (fn != buf) {
- if (dirbuf_len + fn_len >= MAXPATHLEN) {
+ int d_len = dirbuf_len - prefix_skip;
+ if (d_len + fn_len >= MAXPATHLEN) {
rprintf(FERROR, "merge-file name overflows: %s\n", fn);
return NULL;
}
- memcpy(buf, dirbuf + prefix_skip, dirbuf_len - prefix_skip);
- memcpy(buf + dirbuf_len - prefix_skip, fn, fn_len + 1);
+ memcpy(buf, dirbuf + prefix_skip, d_len);
+ memcpy(buf + d_len, fn, fn_len + 1);
fn_len = clean_fname(buf, CFN_COLLAPSE_DOT_DOT_DIRS);
}
struct filter_struct *ex = mergelist_parents[i];
struct filter_list_struct *lp = ex->u.mergelist;
- if (verbose > 2) {
+ if (DEBUG_GTE(FILTER, 2)) {
rprintf(FINFO, "[%s] pushing filter list%s\n",
who_am_i(), lp->debug_type);
}
struct filter_struct *ex = mergelist_parents[i];
struct filter_list_struct *lp = ex->u.mergelist;
- if (verbose > 2) {
+ if (DEBUG_GTE(FILTER, 2)) {
rprintf(FINFO, "[%s] popping filter list%s\n",
who_am_i(), lp->debug_type);
}
}
-static void report_filter_result(char const *name,
+static void report_filter_result(enum logcode code, char const *name,
struct filter_struct const *ent,
int name_is_dir, const char *type)
{
* then it is stripped out by add_rule(). So as a special
* case we add it back in here. */
- if (verbose >= 2) {
+ if (DEBUG_GTE(FILTER, 1)) {
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",
+ rprintf(code, "[%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);
* 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_filter(struct filter_list_struct *listp, const char *name, int name_is_dir)
+int check_filter(struct filter_list_struct *listp, enum logcode code,
+ const char *name, int name_is_dir)
{
struct filter_struct *ent;
if (ignore_perishable && ent->match_flags & MATCHFLG_PERISHABLE)
continue;
if (ent->match_flags & MATCHFLG_PERDIR_MERGE) {
- int rc = check_filter(ent->u.mergelist, name,
+ int rc = check_filter(ent->u.mergelist, code, name,
name_is_dir);
if (rc)
return rc;
continue;
}
if (ent->match_flags & MATCHFLG_CVS_IGNORE) {
- int rc = check_filter(&cvs_filter_list, name,
+ int rc = check_filter(&cvs_filter_list, code, name,
name_is_dir);
if (rc)
return rc;
continue;
}
if (rule_matches(name, ent, name_is_dir)) {
- report_filter_result(name, ent, name_is_dir,
- listp->debug_type);
+ report_filter_result(code, name, ent, name_is_dir,
+ listp->debug_type);
return ent->match_flags & MATCHFLG_INCLUDE ? 1 : -1;
}
}
}
if (new_mflags & MATCHFLG_CLEAR_LIST) {
- if (verbose > 2) {
+ if (DEBUG_GTE(FILTER, 2)) {
rprintf(FINFO,
"[%s] clearing filter list%s\n",
who_am_i(), listp->debug_type);
if (daemon_filter_list.head) {
strlcpy(line, fname, sizeof line);
clean_fname(line, CFN_COLLAPSE_DOT_DOT_DIRS);
- if (check_filter(&daemon_filter_list, line, 0) < 0)
+ if (check_filter(&daemon_filter_list, FLOG, line, 0) < 0)
fp = NULL;
else
fp = fopen(line, "rb");
} else
fp = stdin;
- if (verbose > 2) {
+ if (DEBUG_GTE(FILTER, 2)) {
rprintf(FINFO, "[%s] parse_filter_file(%s,%x,%x)%s\n",
who_am_i(), fname, mflags, xflags,
fp ? "" : " [not found]");