Regular Expression support

Paul Faure paul at faure.ca
Mon Nov 11 20:58:00 EST 2002


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&REG_ICASE)?" REG_ICASE":"",
+                    (options&REG_NEWLINE)?" REG_NEWLINE":"",
+                    (options&REG_NOSUB)?" REG_NOSUB":"",
+                    (options&REG_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


More information about the rsync mailing list