[Csync2] Partial path excludes?
Lars Ellenberg
lars.ellenberg at linbit.com
Thu May 5 21:41:10 CEST 2011
On Thu, May 05, 2011 at 11:59:58AM -0400, Tony Muka wrote:
> Sorry to drag up this old message, but I didn't see much documentation
> on this issue, and wanted to share my findings in trying to exclude
> .svn folders with csync2.
>
> After trying many failing variations of
>
> exclude .svn
> exclude .snv*
> exclude .svn/*
> exclude ".svn/*"
> exclude *svn*
>
> the only thing that worked was
>
> exclude /var/www/*/htdocs/.svn/*;
> exclude /var/www/*/htdocs/*/.svn/*;
> exclude /var/www/*/htdocs/*/*/.svn/*;
> exclude /var/www/*/htdocs/*/*/*/.svn/*;
> exclude /var/www/*/htdocs/*/*/*/*/.svn/*;
> exclude /var/www/*/htdocs/*/*/*/*/*/.svn/*;
> exclude /var/www/*/htdocs/*/*/*/*/*/*/.svn/*;
> exclude /var/www/*/htdocs/*/*/*/*/*/*/*/.svn/*;
> exclude /var/www/*/htdocs/*/*/*/*/*/*/*/*/.svn/*;
> exclude /var/www/*/htdocs/*/*/*/*/*/*/*/*/*/.svn/*;
>
> It would really be nice if there was a way to use one simple rule to
> exclude the descendants of any .svn folder, but for now, this works.
>
> I probably don't have a good enough reason to exclude the .svn paths
> to use this case as a justification for the feature, etc... Excluding
> the .svn folders does cut my disk usage by 50% on the slave nodes.*
I think that I made a feature request to have that fixed in the 2.0 code
base, with 2 "**" matching slashes as well.
I'm currently not sure if that has been done,
/me checks ...
Hm. Has not been done :(
Ok, so please do
git clone git://git.linbit.com/csync2.git
apply the quick'n'dirty only compile tested patch below,
and try
exclude /var/www/*/htdocs**/.svn;
Note that the "**" is only the trigger, the matching function used is
still fnmatch, so once the trigger is present, _any_ star in that
pattern will match slashes (see man fnmatch(3)).
Doing it "right" could be to steal the rsync pattern matching functions,
and/or to use regexes/pcre, with new keywords exclude-pcre/include-pcre.
Cheers,
Lars
diff --git a/action.c b/action.c
index 0328040..9ac8126 100644
--- a/action.c
+++ b/action.c
@@ -44,10 +44,12 @@ void csync_schedule_commands(const char *filename, int islocal)
continue;
if (!a->pattern)
goto found_matching_pattern;
- for (p=a->pattern; p; p=p->next)
+ for (p=a->pattern; p; p=p->next) {
+ int fnm_pathname = p->star_matches_slashes ? 0 : FNM_PATHNAME;
if ( !fnmatch(p->pattern, filename,
- FNM_LEADING_DIR|FNM_PATHNAME) )
+ FNM_LEADING_DIR|fnm_pathname) )
goto found_matching_pattern;
+ }
continue;
found_matching_pattern:
for (c=a->command; c; c=c->next)
diff --git a/cfgfile_parser.y b/cfgfile_parser.y
index 3aadb3e..7f493ab 100644
--- a/cfgfile_parser.y
+++ b/cfgfile_parser.y
@@ -109,12 +109,17 @@ static void add_patt(int patterntype, char *pattern)
}
#endif
+ /* strip trailing slashes from pattern */
for (i=strlen(pattern)-1; i>0; i--)
if (pattern[i] == '/')
pattern[i] = 0;
else
break;
+ /* if you use ** at least once anywhere in the pattern,
+ * _all_ stars in the pattern, even single ones,
+ * will match slashes. */
+ t->star_matches_slashes = !!strstr(pattern, "**");
t->isinclude = patterntype >= 1;
t->iscompare = patterntype >= 2;
t->pattern = pattern;
@@ -283,6 +288,7 @@ static void add_action_pattern(const char *pattern)
{
struct csync_group_action_pattern *t =
calloc(sizeof(struct csync_group_action_pattern), 1);
+ t->star_matches_slashes = !!strstr(pattern, "**");
t->pattern = pattern;
t->next = csync_group->action->pattern;
csync_group->action->pattern = t;
diff --git a/csync2.h b/csync2.h
index 5240d15..d76f880 100644
--- a/csync2.h
+++ b/csync2.h
@@ -287,12 +287,13 @@ struct csync_group_host {
struct csync_group_pattern {
struct csync_group_pattern *next;
- int isinclude, iscompare;
+ int isinclude, iscompare, star_matches_slashes;
const char *pattern;
};
struct csync_group_action_pattern {
struct csync_group_action_pattern *next;
+ int star_matches_slashes;
const char *pattern;
};
diff --git a/groups.c b/groups.c
index 1ff9a1a..511586e 100644
--- a/groups.c
+++ b/groups.c
@@ -41,8 +41,9 @@ int match_pattern_list(
matched = 1;
}
} else {
+ int fnm_pathname = p->star_matches_slashes ? 0 : FNM_PATHNAME;
if ( !fnmatch(p->pattern, filename,
- FNM_LEADING_DIR|FNM_PATHNAME) ) {
+ FNM_LEADING_DIR|fnm_pathname) ) {
match_path = p->isinclude;
matched = 1;
}
@@ -91,10 +92,11 @@ int csync_step_into(const char *file)
continue;
if ( (p->pattern[0] == '/' || p->pattern[0] == '%') && p->isinclude ) {
char t[strlen(p->pattern)+1], *l;
+ int fnm_pathname = p->star_matches_slashes ? 0 : FNM_PATHNAME;
strcpy(t, p->pattern);
while ( (l=strrchr(t, '/')) != 0 ) {
*l = 0;
- if ( !fnmatch(t, file, FNM_PATHNAME) )
+ if ( !fnmatch(t, file, fnm_pathname) )
return 1;
}
}
--
: Lars Ellenberg
: LINBIT | Your Way to High Availability
: DRBD/HA support and consulting http://www.linbit.com
More information about the Csync2
mailing list