#include "includes.h"
static int ms_fnmatch_lanman_core(const char *pattern, const char *string)
{
const char *p = pattern, *n = string;
char c;
if (strcmp(p,"?")==0 && strcmp(n,".")==0) goto match;
while ((c = *p++)) {
switch (c) {
case '.':
if (! *n) goto next;
if (*n != '.') goto nomatch;
n++;
break;
case '?':
if (! *n) goto next;
if ((*n == '.' && n[1] != '.') || ! *n) goto next;
n++;
break;
case '>':
if (! *n) goto next;
if (n[0] == '.') {
if (! n[1] && ms_fnmatch_lanman_core(p, n+1) == 0) goto match;
if (ms_fnmatch_lanman_core(p, n) == 0) goto match;
goto nomatch;
}
n++;
break;
case '*':
if (! *n) goto next;
if (! *p) goto match;
for (; *n; n++) {
if (ms_fnmatch_lanman_core(p, n) == 0) goto match;
}
break;
case '<':
for (; *n; n++) {
if (ms_fnmatch_lanman_core(p, n) == 0) goto match;
if (*n == '.' && !strchr(n+1,'.')) {
n++;
break;
}
}
break;
case '"':
if (*n == 0 && ms_fnmatch_lanman_core(p, n) == 0) goto match;
if (*n != '.') goto nomatch;
n++;
break;
default:
if (c != *n) goto nomatch;
n++;
}
}
if (! *n) goto match;
nomatch:
return -1;
next:
if (ms_fnmatch_lanman_core(p, n) == 0) goto match;
goto nomatch;
match:
return 0;
}
static int ms_fnmatch_lanman1(const char *pattern, const char *string)
{
if (!strpbrk(pattern, "?*<>\"")) {
if (strcmp(string,"..") == 0) string = ".";
return strcasecmp(pattern, string);
}
if (strcmp(string,"..") == 0 || strcmp(string,".") == 0) {
return ms_fnmatch_lanman_core(pattern, "..") &&
ms_fnmatch_lanman_core(pattern, ".");
}
return ms_fnmatch_lanman_core(pattern, string);
}
int ms_fnmatch(const char *pattern, const char *string)
{
const char *p = pattern, *n = string;
char c;
extern int Protocol;
if (Protocol <= PROTOCOL_LANMAN2) {
return ms_fnmatch_lanman1(pattern, string);
}
while ((c = *p++)) {
switch (c) {
case '?':
if (! *n) return -1;
n++;
break;
case '>':
if (n[0] == '.') {
if (! n[1] && ms_fnmatch(p, n+1) == 0) return 0;
if (ms_fnmatch(p, n) == 0) return 0;
return -1;
}
if (! *n) return ms_fnmatch(p, n);
n++;
break;
case '*':
for (; *n; n++) {
if (ms_fnmatch(p, n) == 0) return 0;
}
break;
case '<':
for (; *n; n++) {
if (ms_fnmatch(p, n) == 0) return 0;
if (*n == '.' && !strchr(n+1,'.')) {
n++;
break;
}
}
break;
case '"':
if (*n == 0 && ms_fnmatch(p, n) == 0) return 0;
if (*n != '.') return -1;
n++;
break;
default:
if (c != *n) return -1;
n++;
}
}
if (! *n) return 0;
return -1;
}