- int j;
- const char *p;
-
- for (p=opts; *p; p++) {
- switch (*p) {
- case 'a': /* alway replace */
- case '0': /* no option */
- break;
- case 'e':
- ff->flags |= FO_EXCLUDE;
- break;
- case 'f':
- ff->flags |= FO_MULTIFS;
- break;
- case 'h': /* no recursion */
- ff->flags |= FO_NO_RECURSION;
- break;
- case 'M': /* MD5 */
- ff->flags |= FO_MD5;
- break;
- case 'n':
- ff->flags |= FO_NOREPLACE;
- break;
- case 'p': /* use portable data format */
- ff->flags |= FO_PORTABLE;
- break;
- case 'r': /* read fifo */
- ff->flags |= FO_READFIFO;
- break;
- case 'S':
- ff->flags |= FO_SHA1;
- break;
- case 's':
- ff->flags |= FO_SPARSE;
- break;
- case 'm':
- ff->flags |= FO_MTIMEONLY;
- break;
- case 'k':
- ff->flags |= FO_KEEPATIME;
- break;
- case 'V': /* verify options */
- /* Copy Verify Options */
- for (j=0; *p && *p != ':'; p++) {
- ff->VerifyOpts[j] = *p;
- if (j < (int)sizeof(ff->VerifyOpts) - 1) {
- j++;
- }
- }
- ff->VerifyOpts[j] = 0;
- break;
- case 'w':
- ff->flags |= FO_IF_NEWER;
- break;
- case 'Z': /* gzip compression */
- ff->flags |= FO_GZIP;
- ff->GZIP_level = *++p - '0';
- Dmsg1(200, "Compression level=%d\n", ff->GZIP_level);
- break;
- default:
- Emsg1(M_ERROR, 0, "Unknown include/exclude option: %c\n", *p);
- break;
+ dlistString *node;
+ char *fname;
+ int i;
+ findINCEXE *incexe;
+ findFILESET *fileset = ff->fileset;
+ if (fileset) {
+ for (i=0; i<fileset->include_list.size(); i++) {
+ incexe = (findINCEXE *)fileset->include_list.get(i);
+ foreach_dlist(node, &incexe->name_list) {
+ fname = node->c_str();
+ Dmsg2(100, "Inc fname=%s ff->fname=%s\n", fname, ff->fname);
+ if (strcmp(fname, ff->fname) == 0) {
+ return true;
+ }
+ }
+ }
+ for (i=0; i<fileset->exclude_list.size(); i++) {
+ incexe = (findINCEXE *)fileset->exclude_list.get(i);
+ foreach_dlist(node, &incexe->name_list) {
+ fname = node->c_str();
+ Dmsg2(100, "Exc fname=%s ff->fname=%s\n", fname, ff->fname);
+ if (strcmp(fname, ff->fname) == 0) {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+}
+
+
+static bool accept_file(FF_PKT *ff)
+{
+ int i, j, k;
+ int fnm_flags;
+ findFILESET *fileset = ff->fileset;
+ findINCEXE *incexe = fileset->incexe;
+ const char *basename;
+ int (*match_func)(const char *pattern, const char *string, int flags);
+
+ if (ff->flags & FO_ENHANCEDWILD) {
+// match_func = enh_fnmatch;
+ match_func = fnmatch;
+ if ((basename = last_path_separator(ff->fname)) != NULL)
+ basename++;
+ else
+ basename = ff->fname;
+ } else {
+ match_func = fnmatch;
+ basename = ff->fname;
+ }
+
+ ff->ignoredir = incexe->ignoredir;
+
+ for (j = 0; j < incexe->opts_list.size(); j++) {
+ findFOPTS *fo = (findFOPTS *)incexe->opts_list.get(j);
+ ff->flags = fo->flags;
+ ff->GZIP_level = fo->GZIP_level;
+ ff->fstypes = fo->fstype;
+ ff->drivetypes = fo->drivetype;
+
+ fnm_flags = (ff->flags & FO_IGNORECASE) ? FNM_CASEFOLD : 0;
+ fnm_flags |= (ff->flags & FO_ENHANCEDWILD) ? FNM_PATHNAME : 0;
+
+ if (S_ISDIR(ff->statp.st_mode)) {
+ for (k=0; k<fo->wilddir.size(); k++) {
+ if (match_func((char *)fo->wilddir.get(k), ff->fname, fnmode|fnm_flags) == 0) {
+ if (ff->flags & FO_EXCLUDE) {
+ Dmsg2(100, "Exclude wilddir: %s file=%s\n", (char *)fo->wilddir.get(k),
+ ff->fname);
+ return false; /* reject dir */
+ }
+ return true; /* accept dir */
+ }
+ }
+ } else {
+ for (k=0; k<fo->wildfile.size(); k++) {
+ if (match_func((char *)fo->wildfile.get(k), ff->fname, fnmode|fnm_flags) == 0) {
+ if (ff->flags & FO_EXCLUDE) {
+ Dmsg2(100, "Exclude wildfile: %s file=%s\n", (char *)fo->wildfile.get(k),
+ ff->fname);
+ return false; /* reject file */
+ }
+ return true; /* accept file */
+ }
+ }
+
+ for (k=0; k<fo->wildbase.size(); k++) {
+ if (match_func((char *)fo->wildbase.get(k), basename, fnmode|fnm_flags) == 0) {
+ if (ff->flags & FO_EXCLUDE) {
+ Dmsg2(100, "Exclude wildbase: %s file=%s\n", (char *)fo->wildbase.get(k),
+ basename);
+ return false; /* reject file */
+ }
+ return true; /* accept file */
+ }
+ }
+ }
+ for (k=0; k<fo->wild.size(); k++) {
+ if (match_func((char *)fo->wild.get(k), ff->fname, fnmode|fnm_flags) == 0) {
+ if (ff->flags & FO_EXCLUDE) {
+ Dmsg2(100, "Exclude wild: %s file=%s\n", (char *)fo->wild.get(k),
+ ff->fname);
+ return false; /* reject file */
+ }
+ return true; /* accept file */
+ }
+ }
+ if (S_ISDIR(ff->statp.st_mode)) {
+ for (k=0; k<fo->regexdir.size(); k++) {
+ const int nmatch = 30;
+ regmatch_t pmatch[nmatch];
+ if (regexec((regex_t *)fo->regexdir.get(k), ff->fname, nmatch, pmatch, 0) == 0) {
+ if (ff->flags & FO_EXCLUDE) {
+ return false; /* reject file */
+ }
+ return true; /* accept file */
+ }
+ }
+ } else {
+ for (k=0; k<fo->regexfile.size(); k++) {
+ const int nmatch = 30;
+ regmatch_t pmatch[nmatch];
+ if (regexec((regex_t *)fo->regexfile.get(k), ff->fname, nmatch, pmatch, 0) == 0) {
+ if (ff->flags & FO_EXCLUDE) {
+ return false; /* reject file */
+ }
+ return true; /* accept file */
+ }
+ }
+ }
+ for (k=0; k<fo->regex.size(); k++) {
+ const int nmatch = 30;
+ regmatch_t pmatch[nmatch];
+ if (regexec((regex_t *)fo->regex.get(k), ff->fname, nmatch, pmatch, 0) == 0) {
+ if (ff->flags & FO_EXCLUDE) {
+ return false; /* reject file */
+ }
+ return true; /* accept file */
+ }
+ }
+ /*
+ * If we have an empty Options clause with exclude, then
+ * exclude the file
+ */
+ if (ff->flags & FO_EXCLUDE &&
+ fo->regex.size() == 0 && fo->wild.size() == 0 &&
+ fo->regexdir.size() == 0 && fo->wilddir.size() == 0 &&
+ fo->regexfile.size() == 0 && fo->wildfile.size() == 0 &&
+ fo->wildbase.size() == 0) {
+ return false; /* reject file */
+ }
+ }
+
+ /* Now apply the Exclude { } directive */
+ for (i=0; i<fileset->exclude_list.size(); i++) {
+ findINCEXE *incexe = (findINCEXE *)fileset->exclude_list.get(i);
+ for (j=0; j<incexe->opts_list.size(); j++) {
+ findFOPTS *fo = (findFOPTS *)incexe->opts_list.get(j);
+ fnm_flags = (fo->flags & FO_IGNORECASE) ? FNM_CASEFOLD : 0;
+ for (k=0; k<fo->wild.size(); k++) {
+ if (fnmatch((char *)fo->wild.get(k), ff->fname, fnmode|fnm_flags) == 0) {
+ Dmsg1(100, "Reject wild1: %s\n", ff->fname);
+ return false; /* reject file */
+ }
+ }
+ }
+ fnm_flags = (incexe->current_opts != NULL && incexe->current_opts->flags & FO_IGNORECASE)
+ ? FNM_CASEFOLD : 0;
+ dlistString *node;
+ foreach_dlist(node, &incexe->name_list) {
+ char *fname = node->c_str();
+ if (fnmatch(fname, ff->fname, fnmode|fnm_flags) == 0) {
+ Dmsg1(100, "Reject wild2: %s\n", ff->fname);
+ return false; /* reject file */
+ }