データ構造 | |
struct | max_n |
関数 | |
static int | null_match (const smb_ucs2_t *p) |
static int | ms_fnmatch_core (const smb_ucs2_t *p, const smb_ucs2_t *n, struct max_n *max_n, const smb_ucs2_t *ldot, BOOL is_case_sensitive) |
int | ms_fnmatch (const char *pattern, const char *string, BOOL translate_pattern, BOOL is_case_sensitive) |
int | gen_fnmatch (const char *pattern, const char *string) |
static int null_match | ( | const smb_ucs2_t * | p | ) | [static] |
ms_fnmatch.c の 30 行で定義されています。
参照元 ms_fnmatch_core().
00031 { 00032 for (;*p;p++) { 00033 if (*p != UCS2_CHAR('*') && 00034 *p != UCS2_CHAR('<') && 00035 *p != UCS2_CHAR('"') && 00036 *p != UCS2_CHAR('>')) return -1; 00037 } 00038 return 0; 00039 }
static int ms_fnmatch_core | ( | const smb_ucs2_t * | p, | |
const smb_ucs2_t * | n, | |||
struct max_n * | max_n, | |||
const smb_ucs2_t * | ldot, | |||
BOOL | is_case_sensitive | |||
) | [static] |
ms_fnmatch.c の 57 行で定義されています。
参照先 c・null_match()・max_n::postdot・max_n::predot・toupper_w().
参照元 ms_fnmatch().
00060 { 00061 smb_ucs2_t c; 00062 int i; 00063 00064 while ((c = *p++)) { 00065 switch (c) { 00066 /* a '*' matches zero or more characters of any type */ 00067 case UCS2_CHAR('*'): 00068 if (max_n->predot && max_n->predot <= n) { 00069 return null_match(p); 00070 } 00071 for (i=0; n[i]; i++) { 00072 if (ms_fnmatch_core(p, n+i, max_n+1, ldot, is_case_sensitive) == 0) { 00073 return 0; 00074 } 00075 } 00076 if (!max_n->predot || max_n->predot > n) max_n->predot = n; 00077 return null_match(p); 00078 00079 /* a '<' matches zero or more characters of 00080 any type, but stops matching at the last 00081 '.' in the string. */ 00082 case UCS2_CHAR('<'): 00083 if (max_n->predot && max_n->predot <= n) { 00084 return null_match(p); 00085 } 00086 if (max_n->postdot && max_n->postdot <= n && n <= ldot) { 00087 return -1; 00088 } 00089 for (i=0; n[i]; i++) { 00090 if (ms_fnmatch_core(p, n+i, max_n+1, ldot, is_case_sensitive) == 0) return 0; 00091 if (n+i == ldot) { 00092 if (ms_fnmatch_core(p, n+i+1, max_n+1, ldot, is_case_sensitive) == 0) return 0; 00093 if (!max_n->postdot || max_n->postdot > n) max_n->postdot = n; 00094 return -1; 00095 } 00096 } 00097 if (!max_n->predot || max_n->predot > n) max_n->predot = n; 00098 return null_match(p); 00099 00100 /* a '?' matches any single character */ 00101 case UCS2_CHAR('?'): 00102 if (! *n) { 00103 return -1; 00104 } 00105 n++; 00106 break; 00107 00108 /* a '?' matches any single character */ 00109 case UCS2_CHAR('>'): 00110 if (n[0] == UCS2_CHAR('.')) { 00111 if (! n[1] && null_match(p) == 0) { 00112 return 0; 00113 } 00114 break; 00115 } 00116 if (! *n) return null_match(p); 00117 n++; 00118 break; 00119 00120 case UCS2_CHAR('"'): 00121 if (*n == 0 && null_match(p) == 0) { 00122 return 0; 00123 } 00124 if (*n != UCS2_CHAR('.')) return -1; 00125 n++; 00126 break; 00127 00128 default: 00129 if (c != *n) { 00130 if (is_case_sensitive) { 00131 return -1; 00132 } 00133 if (toupper_w(c) != toupper_w(*n)) { 00134 return -1; 00135 } 00136 } 00137 n++; 00138 break; 00139 } 00140 } 00141 00142 if (! *n) { 00143 return 0; 00144 } 00145 00146 return -1; 00147 }
int ms_fnmatch | ( | const char * | pattern, | |
const char * | string, | |||
BOOL | translate_pattern, | |||
BOOL | is_case_sensitive | |||
) |
ms_fnmatch.c の 149 行で定義されています。
参照先 ms_fnmatch_core()・push_ucs2()・StrCaseCmp()・strrchr_w().
参照元 gen_fnmatch()・mask_match()・mask_match_search()・reg_match_one().
00151 { 00152 wpstring p, s; 00153 int ret, count, i; 00154 struct max_n *max_n = NULL; 00155 00156 if (strcmp(string, "..") == 0) { 00157 string = "."; 00158 } 00159 00160 if (strpbrk(pattern, "<>*?\"") == NULL) { 00161 /* this is not just an optmisation - it is essential 00162 for LANMAN1 correctness */ 00163 if (is_case_sensitive) { 00164 return strcmp(pattern, string); 00165 } else { 00166 return StrCaseCmp(pattern, string); 00167 } 00168 } 00169 00170 if (push_ucs2(NULL, p, pattern, sizeof(p), STR_TERMINATE) == (size_t)-1) { 00171 /* Not quite the right answer, but finding the right one 00172 under this failure case is expensive, and it's pretty close */ 00173 return -1; 00174 } 00175 00176 if (push_ucs2(NULL, s, string, sizeof(s), STR_TERMINATE) == (size_t)-1) { 00177 /* Not quite the right answer, but finding the right one 00178 under this failure case is expensive, and it's pretty close */ 00179 return -1; 00180 } 00181 00182 if (translate_pattern) { 00183 /* 00184 for older negotiated protocols it is possible to 00185 translate the pattern to produce a "new style" 00186 pattern that exactly matches w2k behaviour 00187 */ 00188 for (i=0;p[i];i++) { 00189 if (p[i] == UCS2_CHAR('?')) { 00190 p[i] = UCS2_CHAR('>'); 00191 } else if (p[i] == UCS2_CHAR('.') && 00192 (p[i+1] == UCS2_CHAR('?') || 00193 p[i+1] == UCS2_CHAR('*') || 00194 p[i+1] == 0)) { 00195 p[i] = UCS2_CHAR('"'); 00196 } else if (p[i] == UCS2_CHAR('*') && p[i+1] == UCS2_CHAR('.')) { 00197 p[i] = UCS2_CHAR('<'); 00198 } 00199 } 00200 } 00201 00202 for (count=i=0;p[i];i++) { 00203 if (p[i] == UCS2_CHAR('*') || p[i] == UCS2_CHAR('<')) count++; 00204 } 00205 00206 if (count != 0) { 00207 max_n = SMB_CALLOC_ARRAY(struct max_n, count); 00208 if (!max_n) { 00209 return -1; 00210 } 00211 } 00212 00213 ret = ms_fnmatch_core(p, s, max_n, strrchr_w(s, UCS2_CHAR('.')), is_case_sensitive); 00214 00215 if (max_n) { 00216 free(max_n); 00217 } 00218 00219 return ret; 00220 }
int gen_fnmatch | ( | const char * | pattern, | |
const char * | string | |||
) |
ms_fnmatch.c の 224 行で定義されています。
参照先 ms_fnmatch()・PROTOCOL_NT1.
参照元 file_find()・interpret_interface().
00225 { 00226 return ms_fnmatch(pattern, string, PROTOCOL_NT1, False); 00227 }