[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