I have added regular expression support using a POSIX implementation. The patch (against 2.5.5) is attached. The implementation is simple and follows the same mechanism that is implemented for normal searches. I added these command line arguments: --rexclude=PATTERN exclude files matching regexp PATTERN --rexclude-from=FILE exclude regexp patterns listed in FILE --rinclude=PATTERN don?t exclude files matching regexp PATTERN --rinclude-from=FILE don?t exclude regexp patterns listed in FILE In order to follow the previous format, the following will also work: --include "+R PATTERN" --include "-R PATTERN" etc... I use this method to send the search patterns to a remote rsync server. So if the pattern is a regular expression, three bytes are prepended to the pattern (instead of two), a '+' or a '-', a capital 'R' and a space. A check is done against the remove server version number to check if it supports regular expressions. The regular expression PATTERN supports two formats, the first is plain and simple: .*\.txt$ The second format was to support some search options: /.*\.txt$/i This allows for case insensitive (//i) matching and extended (//e) matching. The implementation is optimized so that it does not compile the regular expression patterns more than once, for this reasons, a regex_t* pointer was added to exclude_struct. The man pages has been updated with the new format and a few examples. -- Paul N. Faure BEng 613.266.3286 Carleton University Systems Eng paul-at-faure-dot-ca Chief Technical Officer, CertainKey Inc. paul-at-certainkey-dot-com -------------- next part -------------- Only in rsync-2.5.5.mod/: Makefile Only in rsync-2.5.5.mod/: access.o Only in rsync-2.5.5.mod/: authenticate.o Only in rsync-2.5.5.mod/: backup.o Only in rsync-2.5.5.mod/: batch.o Only in rsync-2.5.5.mod/: checksum.o Only in rsync-2.5.5.mod/: cleanup.o Only in rsync-2.5.5.mod/: clientname.o Only in rsync-2.5.5.mod/: clientserver.o Only in rsync-2.5.5.mod/: compat.o Only in rsync-2.5.5.mod/: config.h Only in rsync-2.5.5.mod/: config.log Only in rsync-2.5.5.mod/: config.status Only in rsync-2.5.5.mod/: connection.o Common subdirectories: rsync-2.5.5/doc and rsync-2.5.5.mod/doc diff -u rsync-2.5.5/exclude.c rsync-2.5.5.mod/exclude.c --- rsync-2.5.5/exclude.c Mon Feb 18 14:10:28 2002 +++ rsync-2.5.5.mod/exclude.c Mon Nov 11 14:50:00 2002 @@ -31,7 +31,7 @@ static struct exclude_struct **exclude_list; /* build an exclude structure given a exclude pattern */ -static struct exclude_struct *make_exclude(const char *pattern, int include) +static struct exclude_struct *make_exclude(const char *pattern, int include, int regexp) { struct exclude_struct *ret; @@ -45,16 +45,25 @@ } else if (strncmp(pattern,"+ ",2) == 0) { ret->include = 1; pattern += 2; + } else if (strncmp(pattern,"-R ",3) == 0) { + pattern += 3; + ret->use_real_regexp = 1; + } else if (strncmp(pattern,"+R ",3) == 0) { + ret->include = 1; + ret->use_real_regexp = 1; + pattern += 3; } else { ret->include = include; + ret->use_real_regexp = regexp; } ret->pattern = strdup(pattern); if (!ret->pattern) out_of_memory("make_exclude"); + if (!ret->use_real_regexp) { if (strpbrk(pattern, "*[?")) { - ret->regular_exp = 1; + ret->fnmatch = 1; ret->fnmatch_flags = FNM_PATHNAME; if (strstr(pattern, "**")) { static int tested; @@ -76,6 +85,7 @@ if (!strchr(ret->pattern,'/')) { ret->local = 1; } + } return ret; } @@ -85,15 +95,86 @@ free(ex->pattern); memset(ex,0,sizeof(*ex)); free(ex); + if(ex->regexp){ + regfree(ex->regexp); + free(ex->regexp); + } } +#include <regex.h> static int check_one_exclude(char *name, struct exclude_struct *ex, STRUCT_STAT *st) { char *p; int match_start=0; char *pattern = ex->pattern; +// return 1; <-- MEANS EXCLUDE +printf("NAME=%s, %d %d\n", name, ex->use_real_regexp, S_ISDIR(st->st_mode)); + if (ex->use_real_regexp) { + #define reg_errbuf_size 256 + char errbuf[reg_errbuf_size]; + int status; + char *fullName=NULL; + if(!ex->regexp){ // Compile the regular expression only once, this speeds up performance considerably + int options = 0; + char *modifiedPattern=NULL, + *optionsString=NULL; + rprintf(FINFO, "Compiling regular expression '%s'\n", pattern); + ex->regexp=malloc(sizeof(regex_t)); + if(!ex->regexp) out_of_memory("check_one_exclude"); + memset(ex->regexp, 0, sizeof(regex_t)); + if(pattern[0]=='/'){ + modifiedPattern=strdup(&pattern[1]); + if(!modifiedPattern) out_of_memory("check_one_exclude"); + if((optionsString=strrchr(modifiedPattern, '/'))){ + optionsString[0]='\0'; + optionsString++; + if(strchr(optionsString,'e')) options += REG_EXTENDED; + if(strchr(optionsString,'i')) options += REG_ICASE; + if(strchr(optionsString,'m')) options += REG_NEWLINE; // This option is not usefull when matching strings without any newlines + if(strchr(optionsString,'s')) options += REG_NOSUB; // This option is not usefull when matching strings without any newlines + } + }else{ + modifiedPattern=strdup(pattern); + if(!modifiedPattern) out_of_memory("check_one_exclude"); + } + rprintf(FINFO, "Regular expression has following options:%s%s%s%s\n", + (options®_ICASE)?" REG_ICASE":"", + (options®_NEWLINE)?" REG_NEWLINE":"", + (options®_NOSUB)?" REG_NOSUB":"", + (options®_EXTENDED)?" REG_EXTENDED":"" + ); + + status=regcomp(ex->regexp, modifiedPattern, options); // POSIX regular expression compile + free(modifiedPattern); + if(status != 0){ + regerror(status, ex->regexp, errbuf, reg_errbuf_size); + rprintf(FERROR, "Regular expression compile error(pattern='%s'): %s\n", pattern, errbuf); + regfree(ex->regexp); + free(ex->regexp); + ex->regexp=NULL; + return 0; + } + } + + fullName=(char*)malloc(strlen(name) +2); // +1 for NULL at end, +1 for possible extra slash at end '/' + if(!fullName) out_of_memory("check_one_exclude"); + strcpy(fullName, name); + if(S_ISDIR(st->st_mode)){ + strcat(fullName, "/"); + } + + status=regexec(ex->regexp, fullName, (size_t) 0, NULL, 0); // POSIX regular expression execute + free(fullName); + if(status != 0){ + if(status == REG_NOMATCH) return 0; // No match found + regerror(status, ex->regexp, errbuf, reg_errbuf_size); + rprintf(FERROR, "Regular expression execute error(pattern='%s'): %s\n", pattern, errbuf); + return 0; + } + return 1; // If it got this far, the pattern matched the file + }else{ if (ex->local && (p=strrchr(name,'/'))) name = p+1; @@ -106,7 +187,7 @@ pattern++; } - if (ex->regular_exp) { + if (ex->fnmatch) { if (fnmatch(pattern, name, ex->fnmatch_flags) == 0) { return 1; } @@ -119,11 +200,11 @@ return 1; } } + } return 0; } - static void report_exclude_result(char const *name, struct exclude_struct const *ent, STRUCT_STAT const *st) @@ -179,7 +260,7 @@ } -void add_exclude_list(const char *pattern, struct exclude_struct ***list, int include) +void add_exclude_list(const char *pattern, struct exclude_struct ***list, int include, int regexp) { int len=0; if (list && *list) @@ -198,7 +279,7 @@ *list = (struct exclude_struct **)Realloc(*list,sizeof(struct exclude_struct *)*(len+2)); - if (!*list || !((*list)[len] = make_exclude(pattern, include))) + if (!*list || !((*list)[len] = make_exclude(pattern, include, regexp))) out_of_memory("add_exclude"); if (verbose > 2) { @@ -209,14 +290,14 @@ (*list)[len+1] = NULL; } -void add_exclude(const char *pattern, int include) +void add_exclude(const char *pattern, int include, int regexp) { - add_exclude_list(pattern,&exclude_list, include); + add_exclude_list(pattern,&exclude_list, include, regexp); } struct exclude_struct **make_exclude_list(const char *fname, struct exclude_struct **list1, - int fatal, int include) + int fatal, int include, int regexp) { struct exclude_struct **list=list1; FILE *f = fopen(fname,"r"); @@ -240,19 +321,18 @@ /* Skip lines starting with semicolon or pound. It probably wouldn't cause any harm to not skip them but there's no need to save them. */ - add_exclude_list(line,&list,include); + add_exclude_list(line,&list,include,regexp); } } fclose(f); return list; } - -void add_exclude_file(const char *fname, int fatal, int include) +void add_exclude_file(const char *fname, int fatal, int include, int regexp) { if (!fname || !*fname) return; - exclude_list = make_exclude_list(fname,exclude_list,fatal,include); + exclude_list = make_exclude_list(fname,exclude_list,fatal,include,regexp); } @@ -267,7 +347,7 @@ * FIXME: This pattern shows up in the output of * report_exclude_result(), which is not ideal. */ if (list_only && !recurse) { - add_exclude("/*/*", 0); + add_exclude("/*/*", 0, 0); } if (!exclude_list) { @@ -284,6 +364,20 @@ l = strlen(pattern); if (l == 0) continue; + + if (exclude_list[i]->use_real_regexp) { + if (remote_version < 25) { + rprintf(FERROR,"remote rsync does not support regular expressions syntax - aborting\n"); + exit_cleanup(RERR_UNSUPPORTED); + } + if (exclude_list[i]->include) { + write_int(f,l+3); + write_buf(f,"+R ",3); + }else{ + write_int(f,l+3); + write_buf(f,"-R ",3); + } + }else{ if (exclude_list[i]->include) { if (remote_version < 19) { rprintf(FERROR,"remote rsync does not support include syntax - aborting\n"); @@ -294,6 +388,7 @@ } else { write_int(f,l); } + } write_buf(f,pattern,l); } @@ -309,7 +404,7 @@ while ((l=read_int(f))) { if (l >= MAXPATHLEN) overflow("recv_exclude_list"); read_sbuf(f,line,l); - add_exclude(line,0); + add_exclude(line,0,0); } } @@ -362,25 +457,25 @@ } -void add_exclude_line(char *p) +void add_exclude_line(char *p, int regexp) { char *tok; if (!p || !*p) return; p = strdup(p); if (!p) out_of_memory("add_exclude_line"); for (tok=get_exclude_tok(p); tok; tok=get_exclude_tok(NULL)) - add_exclude(tok, 0); + add_exclude(tok, 0, regexp); free(p); } -void add_include_line(char *p) +void add_include_line(char *p, int regexp) { char *tok; if (!p || !*p) return; p = strdup(p); if (!p) out_of_memory("add_include_line"); for (tok=get_exclude_tok(p); tok; tok=get_exclude_tok(NULL)) - add_exclude(tok, 1); + add_exclude(tok, 1, regexp); free(p); } @@ -401,12 +496,12 @@ int i; for (i=0; cvs_ignore_list[i]; i++) - add_exclude(cvs_ignore_list[i], 0); + add_exclude(cvs_ignore_list[i], 0, 0); if ((p=getenv("HOME")) && strlen(p) < (MAXPATHLEN-12)) { snprintf(fname,sizeof(fname), "%s/.cvsignore",p); - add_exclude_file(fname,0,0); + add_exclude_file(fname,0,0,0); } - add_exclude_line(getenv("CVSIGNORE")); + add_exclude_line(getenv("CVSIGNORE"),0); } Only in rsync-2.5.5.mod/: exclude.o Only in rsync-2.5.5.mod/: fileio.o Only in rsync-2.5.5.mod/: flist.o Only in rsync-2.5.5.mod/: generator.o Only in rsync-2.5.5.mod/: hlink.o Only in rsync-2.5.5.mod/: io.o Common subdirectories: rsync-2.5.5/lib and rsync-2.5.5.mod/lib Only in rsync-2.5.5.mod/: loadparm.o Only in rsync-2.5.5.mod/: log.o Only in rsync-2.5.5.mod/: main.o Only in rsync-2.5.5.mod/: match.o diff -u rsync-2.5.5/options.c rsync-2.5.5.mod/options.c --- rsync-2.5.5/options.c Tue Mar 19 15:16:42 2002 +++ rsync-2.5.5.mod/options.c Mon Nov 11 01:27:50 2002 @@ -251,6 +251,10 @@ rprintf(F," --exclude-from=FILE exclude patterns listed in FILE\n"); rprintf(F," --include=PATTERN don't exclude files matching PATTERN\n"); rprintf(F," --include-from=FILE don't exclude patterns listed in FILE\n"); + rprintf(F," --rexclude=PATTERN exclude files matching regexp PATTERN\n"); + rprintf(F," --rexclude-from=FILE exclude regexp patterns listed in FILE\n"); + rprintf(F," --rinclude=PATTERN don't exclude files matching regexp PATTERN\n"); + rprintf(F," --rinclude-from=FILE don't exclude regexp patterns listed in FILE\n"); rprintf(F," --version print version number\n"); rprintf(F," --daemon run as a rsync daemon\n"); rprintf(F," --no-detach do not detach from the parent\n"); @@ -278,10 +282,10 @@ rprintf(F,"See http://rsync.samba.org/ for updates, bug reports, and answers\n"); } -enum {OPT_VERSION = 1000, OPT_SUFFIX, OPT_SENDER, OPT_SERVER, OPT_EXCLUDE, - OPT_EXCLUDE_FROM, OPT_DELETE, OPT_DELETE_EXCLUDED, OPT_NUMERIC_IDS, +enum {OPT_VERSION = 1000, OPT_SUFFIX, OPT_SENDER, OPT_SERVER, OPT_EXCLUDE, OPT_REXCLUDE, + OPT_EXCLUDE_FROM, OPT_REXCLUDE_FROM, OPT_DELETE, OPT_DELETE_EXCLUDED, OPT_NUMERIC_IDS, OPT_RSYNC_PATH, OPT_FORCE, OPT_TIMEOUT, OPT_DAEMON, OPT_CONFIG, OPT_PORT, - OPT_INCLUDE, OPT_INCLUDE_FROM, OPT_STATS, OPT_PARTIAL, OPT_PROGRESS, + OPT_INCLUDE, OPT_RINCLUDE, OPT_INCLUDE_FROM, OPT_RINCLUDE_FROM, OPT_STATS, OPT_PARTIAL, OPT_PROGRESS, OPT_COPY_UNSAFE_LINKS, OPT_SAFE_LINKS, OPT_COMPARE_DEST, OPT_LOG_FORMAT, OPT_PASSWORD_FILE, OPT_SIZE_ONLY, OPT_ADDRESS, OPT_DELETE_AFTER, OPT_EXISTING, OPT_MAX_DELETE, OPT_BACKUP_DIR, @@ -310,6 +314,10 @@ {"include", 0, POPT_ARG_STRING, 0, OPT_INCLUDE, 0, 0 }, {"exclude-from", 0, POPT_ARG_STRING, 0, OPT_EXCLUDE_FROM, 0, 0 }, {"include-from", 0, POPT_ARG_STRING, 0, OPT_INCLUDE_FROM, 0, 0 }, + {"rexclude", 0, POPT_ARG_STRING, 0, OPT_REXCLUDE, 0, 0 }, + {"rinclude", 0, POPT_ARG_STRING, 0, OPT_RINCLUDE, 0, 0 }, + {"rexclude-from", 0, POPT_ARG_STRING, 0, OPT_REXCLUDE_FROM, 0, 0 }, + {"rinclude-from", 0, POPT_ARG_STRING, 0, OPT_RINCLUDE_FROM, 0, 0 }, {"safe-links", 0, POPT_ARG_NONE, &safe_symlinks , 0, 0, 0 }, {"help", 'h', POPT_ARG_NONE, 0, 'h', 0, 0 }, {"backup", 'b', POPT_ARG_NONE, &make_backups , 0, 0, 0 }, @@ -469,19 +477,35 @@ break; case OPT_EXCLUDE: - add_exclude(poptGetOptArg(pc), 0); + add_exclude(poptGetOptArg(pc), 0, 0); break; case OPT_INCLUDE: - add_exclude(poptGetOptArg(pc), 1); + add_exclude(poptGetOptArg(pc), 1, 0); break; case OPT_EXCLUDE_FROM: - add_exclude_file(poptGetOptArg(pc), 1, 0); + add_exclude_file(poptGetOptArg(pc), 1, 0, 0); break; case OPT_INCLUDE_FROM: - add_exclude_file(poptGetOptArg(pc), 1, 1); + add_exclude_file(poptGetOptArg(pc), 1, 1, 0); + break; + + case OPT_REXCLUDE: + add_exclude(poptGetOptArg(pc), 0, 1); + break; + + case OPT_RINCLUDE: + add_exclude(poptGetOptArg(pc), 1, 1); + break; + + case OPT_REXCLUDE_FROM: + add_exclude_file(poptGetOptArg(pc), 1, 0, 1); + break; + + case OPT_RINCLUDE_FROM: + add_exclude_file(poptGetOptArg(pc), 1, 1, 1); break; case OPT_WHOLE_FILE: Only in rsync-2.5.5.mod/: options.o Common subdirectories: rsync-2.5.5/packaging and rsync-2.5.5.mod/packaging Only in rsync-2.5.5.mod/: params.o Common subdirectories: rsync-2.5.5/patches and rsync-2.5.5.mod/patches Common subdirectories: rsync-2.5.5/popt and rsync-2.5.5.mod/popt diff -u rsync-2.5.5/proto.h rsync-2.5.5.mod/proto.h --- rsync-2.5.5/proto.h Sun Mar 24 22:51:17 2002 +++ rsync-2.5.5.mod/proto.h Mon Nov 11 01:22:41 2002 @@ -57,17 +57,17 @@ int claim_connection(char *fname,int max_connections); int check_exclude(char *name, struct exclude_struct **local_exclude_list, STRUCT_STAT *st); -void add_exclude_list(const char *pattern, struct exclude_struct ***list, int include); -void add_exclude(const char *pattern, int include); +void add_exclude_list(const char *pattern, struct exclude_struct ***list, int include, int regexp); +void add_exclude(const char *pattern, int include, int regexp); struct exclude_struct **make_exclude_list(const char *fname, struct exclude_struct **list1, - int fatal, int include); -void add_exclude_file(const char *fname, int fatal, int include); + int fatal, int include, int regexp); +void add_exclude_file(const char *fname, int fatal, int include, int regexp); void send_exclude_list(int f); void recv_exclude_list(int f); char *get_exclude_tok(char *p); -void add_exclude_line(char *p); -void add_include_line(char *p); +void add_exclude_line(char *p, int regexp); +void add_include_line(char *p, int regexp); void add_cvs_excludes(void); int sparse_end(int f); int write_file(int f,char *buf,size_t len); Only in rsync-2.5.5.mod/: receiver.o Only in rsync-2.5.5.mod/: rsync diff -u rsync-2.5.5/rsync.1 rsync-2.5.5.mod/rsync.1 --- rsync-2.5.5/rsync.1 Wed Feb 6 16:21:19 2002 +++ rsync-2.5.5.mod/rsync.1 Mon Nov 11 15:17:20 2002 @@ -296,6 +296,10 @@ --exclude-from=FILE exclude patterns listed in FILE --include=PATTERN don\'t exclude files matching PATTERN --include-from=FILE don\'t exclude patterns listed in FILE + --rexclude=PATTERN exclude files matching regexp PATTERN + --rexclude-from=FILE exclude regexp patterns listed in FILE + --rinclude=PATTERN don\'t exclude files matching regexp PATTERN + --rinclude-from=FILE don\'t exclude regexp patterns listed in FILE --version print version number --daemon run as a rsync daemon --no-detach do not detach from the parent @@ -844,11 +848,12 @@ every path is visited from top down, so include/exclude patterns get applied recursively to each subcomponent\&. .PP -Note also that the --include and --exclude options take one pattern -each\&. To add multiple patterns use the --include-from and ---exclude-from options or multiple --include and --exclude options\&. +Note also that the --include, --exclude, --rinclude and --rexclude options +take one pattern each\&. To add multiple patterns use the --include-from, +--exclude-from, --rinclude-from and --rexclude-from options or multiple +--include, --exclude, --rinclude and --rexclude options\&. .PP -The patterns can take several forms\&. The rules are: +The --include and --exclude patterns can take several forms\&. The rules are: .PP .IP o if the pattern starts with a / then it is matched against the @@ -894,8 +899,47 @@ if the pattern is a single exclamation mark ! then the current include/exclude list is reset, removing all previously defined patterns\&. .PP -The +/- rules are most useful in exclude lists, allowing you to have a -single exclude list that contains both include and exclude options\&. +The --rinclude and --rexclude patterns can take several forms\&. The rules are: +.PP +.IP o +simple regular expression form, where the regular expression pattern is the +given string. eg. ".*\\.exe"\&. +.br +Notes: +.br +- When using regular expressions on the command line, care must be taken to +escape any special characters that are handled differently\&. For example, +"lib|bin" in bash must be written as "lib\\|bin"\&. +.br +- Perl style regular expressions are not supported, so the common \\w, \\s, \\d +will not work\&. +.br +- To use grouping (), you need to specify the extended format, ie. //e +.PP +.IP o +if the pattern starts with a '/' and ends with a '/' with some operators +(e or i) at the end, then the pattern is extracted from between the +slashes '/'\&. eg. "/.*\\.exe/i"\&. The operators are as follows: +.br +e <-- Extended regular expression +.br +i <-- Ingnore case +.IP +.IP o +if the pattern starts with "+R " (a plus followed by an 'R' followed by +a space) then it is always considered a regular expression include +pattern, even if specified as part of an include or exclude option\&. +The "+R " part is discarded before matching\&. +.IP +.IP o +if the pattern starts with "-R " (a minus followed by an 'R' followed by +a space) then it is always considered a regular expression exclude +pattern, even if specified as part of an include or exclude option\&. +The "-R " part is discarded before matching\&. +.PP +The +/- and +R/-R rules are most useful in exclude lists, allowing you +to have a single exclude list that contains both include and exclude +options\&. .PP If you end an exclude list with --exclude \'*\', note that since the algorithm is applied recursively that unless you explicitly include @@ -925,6 +969,25 @@ --include "foo/" --include "foo/bar\&.c" --exclude "*" would include only foo/bar\&.c (the foo/ directory must be explicitly included or it would be excluded by the "*") +.IP o +--rinclude "foo" would include any filename that has foo in its path. +ie. base/foo/bar.h +.IP o +--rinclude "/foo/i" would include any filename that has foo, FOO, Foo +etc. in its path. ie. base/FoO/bar.h +.IP o +--rinclude ".*/$" would include all directories +.IP o +--rexclude "/lib|bin|.*\.o$|.*\.so$/" would exclude all files that +have lib or bin in the path, or end in .o or .so +.IP o +--rinclude "/\\/(.*?) (.*?)$/e" would include all files that +have two words in them (eg 'base/dir/hello there') +.IP o +--rinclude "\\/backup[Jan|Mar|May|Jul|Sep|Nov]$" would include the backup +files for every other month +.IP o +--rinclude "\\/version[1-5]$" would include the first five version of a file .PP .SH "BATCH MODE" .PP diff -u rsync-2.5.5/rsync.h rsync-2.5.5.mod/rsync.h --- rsync-2.5.5/rsync.h Mon Mar 25 02:29:43 2002 +++ rsync-2.5.5.mod/rsync.h Mon Nov 11 12:09:35 2002 @@ -198,6 +198,9 @@ #include <syslog.h> #include <sys/file.h> +/* this is needed for regexp matching */ +#include <regex.h> + #if HAVE_DIRENT_H # include <dirent.h> #else @@ -392,11 +395,13 @@ struct exclude_struct { char *pattern; - int regular_exp; + int fnmatch; int fnmatch_flags; int include; int directory; int local; + int use_real_regexp; + regex_t *regexp; }; struct stats { Only in rsync-2.5.5.mod/: rsync.o diff -u rsync-2.5.5/rsyncd.conf.5 rsync-2.5.5.mod/rsyncd.conf.5 --- rsync-2.5.5/rsyncd.conf.5 Fri Aug 31 04:12:35 2001 +++ rsync-2.5.5.mod/rsyncd.conf.5 Mon Nov 11 15:38:03 2002 @@ -193,7 +193,7 @@ option except that the exclude list is not passed to the client and thus only apply on the server\&. Only one "exclude" option may be specified, but you can use "-" and "+" before patterns to specify -exclude/include\&. +exclude/include, and "R" to specify a regular expressions pattern\&. .IP Note that this option is not designed with strong security in mind, it is quite possible that a client may find a way to bypass this @@ -215,7 +215,8 @@ equivalent to the client specifying these patterns with the --include option\&. This is useful as it allows you to build up quite complex exclude/include rules\&. Only one "include" option may be specified, but you -can use "+" and "-" before patterns to switch include/exclude\&. +can use "+" and "-" before patterns to switch include/exclude, and "R" +to specify a regular expressions pattern\&. .IP See the section of exclude patterns in the rsync man page for information on the syntax of this option\&. Only in rsync-2.5.5.mod/: sender.o Only in rsync-2.5.5.mod/: shconfig Only in rsync-2.5.5.mod/: socket.o Only in rsync-2.5.5.mod/: syscall.o Common subdirectories: rsync-2.5.5/testhelp and rsync-2.5.5.mod/testhelp Common subdirectories: rsync-2.5.5/testsuite and rsync-2.5.5.mod/testsuite Only in rsync-2.5.5.mod/: token.o Only in rsync-2.5.5.mod/: uidlist.o Only in rsync-2.5.5.mod/: util.o Common subdirectories: rsync-2.5.5/zlib and rsync-2.5.5.mod/zlib