/* a lot of this stuff was originally derived from GNU tar, although
it has now changed so much that it is hard to tell :) */
+/* include/exclude cluestick added by Martin Pool <mbp@samba.org> */
+
#include "rsync.h"
extern int verbose;
if (strpbrk(pattern, "*[?")) {
ret->regular_exp = 1;
- ret->fnmatch_flags = strstr(pattern, "**") ? 0 : FNM_PATHNAME;
+ ret->fnmatch_flags = FNM_PATHNAME;
+ if (strstr(pattern, "**")) {
+ static int tested;
+ if (!tested) {
+ tested = 1;
+ if (fnmatch("a/b/*", "a/b/c/d", FNM_PATHNAME)==0) {
+ rprintf(FERROR,"WARNING: fnmatch FNM_PATHNAME is broken on your system\n");
+ }
+ }
+ ret->fnmatch_flags = 0;
+ }
}
if (strlen(pattern) > 1 && pattern[strlen(pattern)-1] == '/') {
free(ex);
}
-static int check_one_exclude(char *name,struct exclude_struct *ex,
- STRUCT_STAT *st)
+static int check_one_exclude(char *name, struct exclude_struct *ex,
+ STRUCT_STAT *st)
{
char *p;
int match_start=0;
}
-int check_exclude(char *name,struct exclude_struct **local_exclude_list,
+static void report_exclude_result(char const *name,
+ struct exclude_struct const *ent,
+ STRUCT_STAT const *st)
+{
+ /* If a trailing slash is present to match only directories,
+ * then it is stripped out by make_exclude. So as a special
+ * case we add it back in here. */
+
+ if (verbose >= 2)
+ rprintf(FINFO, "%s %s %s because of pattern %s%s\n",
+ ent->include ? "including" : "excluding",
+ S_ISDIR(st->st_mode) ? "directory" : "file",
+ name, ent->pattern,
+ ent->directory ? "/" : "");
+}
+
+
+/*
+ * Return true if file NAME is defined to be excluded by either
+ * LOCAL_EXCLUDE_LIST or the globals EXCLUDE_LIST.
+ */
+int check_exclude(char *name, struct exclude_struct **local_exclude_list,
STRUCT_STAT *st)
{
int n;
+ struct exclude_struct *ent;
if (name && (name[0] == '.') && !name[1])
/* never exclude '.', even if somebody does --exclude '*' */
return 0;
if (exclude_list) {
- for (n=0; exclude_list[n]; n++)
- if (check_one_exclude(name,exclude_list[n],st))
- return !exclude_list[n]->include;
+ for (n=0; exclude_list[n]; n++) {
+ ent = exclude_list[n];
+ if (check_one_exclude(name, ent, st)) {
+ report_exclude_result(name, ent, st);
+ return !ent->include;
+ }
+ }
}
if (local_exclude_list) {
- for (n=0; local_exclude_list[n]; n++)
- if (check_one_exclude(name,local_exclude_list[n],st))
- return !local_exclude_list[n]->include;
+ for (n=0; local_exclude_list[n]; n++) {
+ ent = exclude_list[n];
+ if (check_one_exclude(name, ent, st)) {
+ report_exclude_result(name, ent, st);
+ return !ent->include;
+ }
+ }
}
return 0;
char line[MAXPATHLEN];
if (!f) {
if (fatal) {
- rprintf(FERROR,"%s : %s\n",fname,strerror(errno));
+ rsyserr(FERROR, errno,
+ "failed to open %s file %s",
+ include ? "include" : "exclude",
+ fname);
exit_cleanup(RERR_FILEIO);
}
return list;
{
int i;
extern int remote_version;
+ extern int list_only, recurse;
+
+ /* this is a complete hack - blame Rusty */
+ if (list_only && !recurse) {
+ add_exclude("/*/*", 0);
+ }
if (!exclude_list) {
write_int(f,0);