- char *p;
-
- if (!strchr(pattern,'/') && (p=strrchr(name,'/')))
- name = p+1;
-
- if (!name[0]) return 0;
-
- if (is_regex(pattern)) {
- if (fnmatch(pattern, name, 0) == 0)
- return 1;
- } else {
- int l1 = strlen(name);
- int l2 = strlen(pattern);
- if (l2 <= l1 &&
- strcmp(name+(l1-l2),pattern) == 0 &&
- (l1==l2 || name[l1-(l2+1)] == '/'))
- return 1;
- }
-
- return 0;
+ char *p;
+ int match_start = 0;
+ char *pattern = ex->pattern;
+
+ /* If the pattern does not have any slashes AND it does not have
+ * a "**" (which could match a slash), then we just match the
+ * name portion of the path. */
+ if (!ex->slash_cnt && !(ex->match_flags & MATCHFLG_WILD2) &&
+ (p = strrchr(name,'/')) != NULL)
+ name = p+1;
+
+ if (!name[0]) return 0;
+
+ if (ex->directory && !S_ISDIR(st->st_mode)) return 0;
+
+ if (*pattern == '/') {
+ match_start = 1;
+ pattern++;
+ if (*name == '/')
+ name++;
+ }
+
+ if (ex->match_flags & MATCHFLG_WILD) {
+ int fnmatch_flags = (ex->match_flags & MATCHFLG_WILD2)?
+ 0 : FNM_PATHNAME;
+ /* A non-anchored match with an infix slash and no "**"
+ * needs to match the last slash_cnt+1 name elements. */
+ if (!match_start && ex->slash_cnt &&
+ !(ex->match_flags & MATCHFLG_WILD2)) {
+ int cnt = ex->slash_cnt + 1;
+ for (p = name + strlen(name) - 1; p >= name; p--) {
+ if (*p == '/' && !--cnt)
+ break;
+ }
+ name = p+1;
+ }
+ if (fnmatch(pattern, name, fnmatch_flags) == 0)
+ return 1;
+ if (ex->match_flags & MATCHFLG_WILD2_PREFIX) {
+ /* If the **-prefixed pattern has a '/' as the next
+ * character, then try to match the rest of the
+ * pattern at the root. */
+ if (pattern[2] == '/' &&
+ fnmatch(pattern+3, name, fnmatch_flags) == 0)
+ return 1;
+ }
+ else if (!match_start && ex->match_flags & MATCHFLG_WILD2) {
+ /* A non-anchored match with an infix or trailing "**"
+ * (but not a prefixed "**") needs to try matching
+ * after every slash. */
+ while ((name = strchr(name, '/')) != NULL) {
+ name++;
+ if (fnmatch(pattern, name, fnmatch_flags) == 0)
+ return 1;
+ }
+ }
+ } else if (match_start) {
+ if (strcmp(name,pattern) == 0)
+ return 1;
+ } else {
+ int l1 = strlen(name);
+ int l2 = strlen(pattern);
+ if (l2 <= l1 &&
+ strcmp(name+(l1-l2),pattern) == 0 &&
+ (l1==l2 || name[l1-(l2+1)] == '/')) {
+ return 1;
+ }
+ }
+
+ return 0;