/* Scan the list and let the last match determine the fate. * Return 1 for exclude, 0 for include and -1 for undecided. */ int excluded_from_list(const char *pathname, int pathlen, const char *basename, int *dtype, struct exclude_list *el) { int i; if (el->nr) { for (i = el->nr - 1; 0 <= i; i--) { struct exclude *x = el->excludes[i]; const char *exclude = x->pattern; int to_exclude = x->to_exclude; if (x->flags & EXC_FLAG_MUSTBEDIR) { if (*dtype == DT_UNKNOWN) *dtype = get_dtype(NULL, pathname, pathlen); if (*dtype != DT_DIR) continue; } if (x->flags & EXC_FLAG_NODIR) { /* match basename */ if (x->flags & EXC_FLAG_NOWILDCARD) { if (!strcmp_icase(exclude, basename)) return to_exclude; } else if (x->flags & EXC_FLAG_ENDSWITH) { if (x->patternlen - 1 <= pathlen && !strcmp_icase(exclude + 1, pathname + pathlen - x->patternlen + 1)) return to_exclude; } else { if (fnmatch_icase(exclude, basename, 0) == 0) return to_exclude; } } else { /* match with FNM_PATHNAME: * exclude has base (baselen long) implicitly * in front of it. */ int baselen = x->baselen; if (*exclude == '/') exclude++; if (pathlen < baselen || (baselen && pathname[baselen-1] != '/') || strncmp_icase(pathname, x->base, baselen)) continue; if (x->flags & EXC_FLAG_NOWILDCARD) { if (!strcmp_icase(exclude, pathname + baselen)) return to_exclude; } else { if (fnmatch_icase(exclude, pathname+baselen, FNM_PATHNAME) == 0) return to_exclude; } } } } return -1; /* undecided */ }
int match_basename(const char *basename, int basenamelen, const char *pattern, int prefix, int patternlen, int flags) { if (prefix == patternlen) { if (!strcmp_icase(pattern, basename)) return 1; } else if (flags & EXC_FLAG_ENDSWITH) { if (patternlen - 1 <= basenamelen && !strcmp_icase(pattern + 1, basename + basenamelen - patternlen + 1)) return 1; } else { if (fnmatch_icase(pattern, basename, 0) == 0) return 1; } return 0; }