From a8b9d4edec745757d34a10be0f6956c0609c2284 Mon Sep 17 00:00:00 2001 From: David Dykstra Date: Thu, 18 Feb 1999 16:27:36 +0000 Subject: [PATCH] Changed exclude/include matching so that normally wildcards will stop at slashes. The old behavior of crossing slashes can be achieved by using a double-asterisk ('**') anywhere in a pattern. Note that this can change some existing exclude patterns in a subtle way. Also note that if the remote side is an older release the processing on the two sides might not be exactly the same when there's no double-asterisk, which can affect which files are excluded from deletion, but they're close enough that people will probably not notice. I considered changing the protocol version and checking the remote_version number to ensure the same processing on both sides, but the exclude patterns are pre-processed before the remote version number is known and it's just not worth going through extraordinary efforts. Suggested by Cameron Simpson --- README | 1 + configure.in | 2 +- exclude.c | 3 ++- rsync.h | 1 + rsync.yo | 15 ++++++++++----- 5 files changed, 15 insertions(+), 7 deletions(-) diff --git a/README b/README index 4c5de888..7e6c181e 100644 --- a/README +++ b/README @@ -66,6 +66,7 @@ Options --numeric-ids don't map uid/gid values by user/group name --timeout=TIME set IO timeout in seconds -I, --ignore-times don't exclude files that match length and time + --size-only only use file size when determining if a file should be transferred -T --temp-dir=DIR create temporary files in directory DIR --compare-dest=DIR also compare destination files relative to DIR -z, --compress compress file data diff --git a/configure.in b/configure.in index 25bf768c..11d6faec 100644 --- a/configure.in +++ b/configure.in @@ -56,7 +56,7 @@ AC_CHECK_FUNCS(strlcat strlcpy) echo $ac_n "checking for working fnmatch... $ac_c" AC_TRY_RUN([#include -main() { exit(fnmatch("*.o", "x.o", 0) == 0? 0: 1); }], +main() { exit(fnmatch("*.o", "x.o", FNM_PATHNAME) == 0? 0: 1); }], echo yes;AC_DEFINE(HAVE_FNMATCH), echo no) diff --git a/exclude.c b/exclude.c index 15fa4f60..66aeb671 100644 --- a/exclude.c +++ b/exclude.c @@ -100,6 +100,7 @@ static struct exclude_struct *make_exclude(char *pattern, int include) only_included_files = 0; } ret->regular_exp = 1; + ret->fnmatch_flags = strstr(pattern, "**") ? 0 : FNM_PATHNAME; } else if (!ret->include) { only_included_files = 0; } @@ -143,7 +144,7 @@ static int check_one_exclude(char *name,struct exclude_struct *ex, } if (ex->regular_exp) { - if (fnmatch(pattern, name, 0) == 0) + if (fnmatch(pattern, name, ex->fnmatch_flags) == 0) return 1; } else { int l1 = strlen(name); diff --git a/rsync.h b/rsync.h index 258695f8..92ba2561 100644 --- a/rsync.h +++ b/rsync.h @@ -339,6 +339,7 @@ struct exclude_struct { char *orig; char *pattern; int regular_exp; + int fnmatch_flags; int include; int directory; int local; diff --git a/rsync.yo b/rsync.yo index 5bcbc311..28097494 100644 --- a/rsync.yo +++ b/rsync.yo @@ -1,5 +1,5 @@ mailto(rsync-bugs@samba.org) -manpage(rsync)(1)(17 Feb 1999)()() +manpage(rsync)(1)(18 Feb 1999)()() manpagename(rsync)(faster, flexible replacement for rcp) manpagesynopsis() @@ -641,14 +641,15 @@ itemize( directory, not a file, link or device. it() if the pattern contains a wildcard character from the set - *?[ then regular expression matching is applied using the - normal shell filename matching rules. Otherwise a simple string - match is used. + *?[ then expression matching is applied using the shell filename + matching rules. Otherwise a simple string match is used. it() if the pattern contains a / (not counting a trailing /) then it is matched against the full filename, including any leading directory. If the pattern doesn't contain a / then it is matched - only against the final component of the filename. + only against the final component of the filename. Furthermore, if + the pattern includes a double asterisk "**" then all wildcards in + the pattern will match slashes, otherwise they will stop at slashes. it() if the pattern starts with "+ " (a plus followed by a space) then it is always considered an include pattern, even if specified as @@ -671,6 +672,10 @@ itemize( it() --exclude "*.o" would exclude all filenames matching *.o it() --exclude "/foo" would exclude a file in the base directory called foo it() --exclude "foo/" would exclude any directory called foo + it() --exclude "/foo/*/bar" would exclude any file called bar two + levels below a base directory called foo + it() --exclude "/foo/**/bar" would exclude any file called bar two + or more levels below a base directory called foo it() --include "*/" --include "*.c" --exclude "*" would include all directories and C source files it() --include "foo/" --include "foo/bar.c" --exclude "*" would include -- 2.34.1