1*6236dae4SAndroid Build Coastguard Worker /***************************************************************************
2*6236dae4SAndroid Build Coastguard Worker * _ _ ____ _
3*6236dae4SAndroid Build Coastguard Worker * Project ___| | | | _ \| |
4*6236dae4SAndroid Build Coastguard Worker * / __| | | | |_) | |
5*6236dae4SAndroid Build Coastguard Worker * | (__| |_| | _ <| |___
6*6236dae4SAndroid Build Coastguard Worker * \___|\___/|_| \_\_____|
7*6236dae4SAndroid Build Coastguard Worker *
8*6236dae4SAndroid Build Coastguard Worker * Copyright (C) Daniel Stenberg, <[email protected]>, et al.
9*6236dae4SAndroid Build Coastguard Worker *
10*6236dae4SAndroid Build Coastguard Worker * This software is licensed as described in the file COPYING, which
11*6236dae4SAndroid Build Coastguard Worker * you should have received as part of this distribution. The terms
12*6236dae4SAndroid Build Coastguard Worker * are also available at https://curl.se/docs/copyright.html.
13*6236dae4SAndroid Build Coastguard Worker *
14*6236dae4SAndroid Build Coastguard Worker * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15*6236dae4SAndroid Build Coastguard Worker * copies of the Software, and permit persons to whom the Software is
16*6236dae4SAndroid Build Coastguard Worker * furnished to do so, under the terms of the COPYING file.
17*6236dae4SAndroid Build Coastguard Worker *
18*6236dae4SAndroid Build Coastguard Worker * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19*6236dae4SAndroid Build Coastguard Worker * KIND, either express or implied.
20*6236dae4SAndroid Build Coastguard Worker *
21*6236dae4SAndroid Build Coastguard Worker * SPDX-License-Identifier: curl
22*6236dae4SAndroid Build Coastguard Worker *
23*6236dae4SAndroid Build Coastguard Worker ***************************************************************************/
24*6236dae4SAndroid Build Coastguard Worker
25*6236dae4SAndroid Build Coastguard Worker #include "curl_setup.h"
26*6236dae4SAndroid Build Coastguard Worker #ifndef CURL_DISABLE_FTP
27*6236dae4SAndroid Build Coastguard Worker #include <curl/curl.h>
28*6236dae4SAndroid Build Coastguard Worker
29*6236dae4SAndroid Build Coastguard Worker #include "curl_fnmatch.h"
30*6236dae4SAndroid Build Coastguard Worker #include "curl_memory.h"
31*6236dae4SAndroid Build Coastguard Worker
32*6236dae4SAndroid Build Coastguard Worker /* The last #include file should be: */
33*6236dae4SAndroid Build Coastguard Worker #include "memdebug.h"
34*6236dae4SAndroid Build Coastguard Worker
35*6236dae4SAndroid Build Coastguard Worker #ifndef HAVE_FNMATCH
36*6236dae4SAndroid Build Coastguard Worker
37*6236dae4SAndroid Build Coastguard Worker #define CURLFNM_CHARSET_LEN (sizeof(char) * 256)
38*6236dae4SAndroid Build Coastguard Worker #define CURLFNM_CHSET_SIZE (CURLFNM_CHARSET_LEN + 15)
39*6236dae4SAndroid Build Coastguard Worker
40*6236dae4SAndroid Build Coastguard Worker #define CURLFNM_NEGATE CURLFNM_CHARSET_LEN
41*6236dae4SAndroid Build Coastguard Worker
42*6236dae4SAndroid Build Coastguard Worker #define CURLFNM_ALNUM (CURLFNM_CHARSET_LEN + 1)
43*6236dae4SAndroid Build Coastguard Worker #define CURLFNM_DIGIT (CURLFNM_CHARSET_LEN + 2)
44*6236dae4SAndroid Build Coastguard Worker #define CURLFNM_XDIGIT (CURLFNM_CHARSET_LEN + 3)
45*6236dae4SAndroid Build Coastguard Worker #define CURLFNM_ALPHA (CURLFNM_CHARSET_LEN + 4)
46*6236dae4SAndroid Build Coastguard Worker #define CURLFNM_PRINT (CURLFNM_CHARSET_LEN + 5)
47*6236dae4SAndroid Build Coastguard Worker #define CURLFNM_BLANK (CURLFNM_CHARSET_LEN + 6)
48*6236dae4SAndroid Build Coastguard Worker #define CURLFNM_LOWER (CURLFNM_CHARSET_LEN + 7)
49*6236dae4SAndroid Build Coastguard Worker #define CURLFNM_GRAPH (CURLFNM_CHARSET_LEN + 8)
50*6236dae4SAndroid Build Coastguard Worker #define CURLFNM_SPACE (CURLFNM_CHARSET_LEN + 9)
51*6236dae4SAndroid Build Coastguard Worker #define CURLFNM_UPPER (CURLFNM_CHARSET_LEN + 10)
52*6236dae4SAndroid Build Coastguard Worker
53*6236dae4SAndroid Build Coastguard Worker typedef enum {
54*6236dae4SAndroid Build Coastguard Worker CURLFNM_SCHS_DEFAULT = 0,
55*6236dae4SAndroid Build Coastguard Worker CURLFNM_SCHS_RIGHTBR,
56*6236dae4SAndroid Build Coastguard Worker CURLFNM_SCHS_RIGHTBRLEFTBR
57*6236dae4SAndroid Build Coastguard Worker } setcharset_state;
58*6236dae4SAndroid Build Coastguard Worker
59*6236dae4SAndroid Build Coastguard Worker typedef enum {
60*6236dae4SAndroid Build Coastguard Worker CURLFNM_PKW_INIT = 0,
61*6236dae4SAndroid Build Coastguard Worker CURLFNM_PKW_DDOT
62*6236dae4SAndroid Build Coastguard Worker } parsekey_state;
63*6236dae4SAndroid Build Coastguard Worker
64*6236dae4SAndroid Build Coastguard Worker typedef enum {
65*6236dae4SAndroid Build Coastguard Worker CCLASS_OTHER = 0,
66*6236dae4SAndroid Build Coastguard Worker CCLASS_DIGIT,
67*6236dae4SAndroid Build Coastguard Worker CCLASS_UPPER,
68*6236dae4SAndroid Build Coastguard Worker CCLASS_LOWER
69*6236dae4SAndroid Build Coastguard Worker } char_class;
70*6236dae4SAndroid Build Coastguard Worker
71*6236dae4SAndroid Build Coastguard Worker #define SETCHARSET_OK 1
72*6236dae4SAndroid Build Coastguard Worker #define SETCHARSET_FAIL 0
73*6236dae4SAndroid Build Coastguard Worker
parsekeyword(unsigned char ** pattern,unsigned char * charset)74*6236dae4SAndroid Build Coastguard Worker static int parsekeyword(unsigned char **pattern, unsigned char *charset)
75*6236dae4SAndroid Build Coastguard Worker {
76*6236dae4SAndroid Build Coastguard Worker parsekey_state state = CURLFNM_PKW_INIT;
77*6236dae4SAndroid Build Coastguard Worker #define KEYLEN 10
78*6236dae4SAndroid Build Coastguard Worker char keyword[KEYLEN] = { 0 };
79*6236dae4SAndroid Build Coastguard Worker int i;
80*6236dae4SAndroid Build Coastguard Worker unsigned char *p = *pattern;
81*6236dae4SAndroid Build Coastguard Worker bool found = FALSE;
82*6236dae4SAndroid Build Coastguard Worker for(i = 0; !found; i++) {
83*6236dae4SAndroid Build Coastguard Worker char c = (char)*p++;
84*6236dae4SAndroid Build Coastguard Worker if(i >= KEYLEN)
85*6236dae4SAndroid Build Coastguard Worker return SETCHARSET_FAIL;
86*6236dae4SAndroid Build Coastguard Worker switch(state) {
87*6236dae4SAndroid Build Coastguard Worker case CURLFNM_PKW_INIT:
88*6236dae4SAndroid Build Coastguard Worker if(ISLOWER(c))
89*6236dae4SAndroid Build Coastguard Worker keyword[i] = c;
90*6236dae4SAndroid Build Coastguard Worker else if(c == ':')
91*6236dae4SAndroid Build Coastguard Worker state = CURLFNM_PKW_DDOT;
92*6236dae4SAndroid Build Coastguard Worker else
93*6236dae4SAndroid Build Coastguard Worker return SETCHARSET_FAIL;
94*6236dae4SAndroid Build Coastguard Worker break;
95*6236dae4SAndroid Build Coastguard Worker case CURLFNM_PKW_DDOT:
96*6236dae4SAndroid Build Coastguard Worker if(c == ']')
97*6236dae4SAndroid Build Coastguard Worker found = TRUE;
98*6236dae4SAndroid Build Coastguard Worker else
99*6236dae4SAndroid Build Coastguard Worker return SETCHARSET_FAIL;
100*6236dae4SAndroid Build Coastguard Worker }
101*6236dae4SAndroid Build Coastguard Worker }
102*6236dae4SAndroid Build Coastguard Worker #undef KEYLEN
103*6236dae4SAndroid Build Coastguard Worker
104*6236dae4SAndroid Build Coastguard Worker *pattern = p; /* move caller's pattern pointer */
105*6236dae4SAndroid Build Coastguard Worker if(strcmp(keyword, "digit") == 0)
106*6236dae4SAndroid Build Coastguard Worker charset[CURLFNM_DIGIT] = 1;
107*6236dae4SAndroid Build Coastguard Worker else if(strcmp(keyword, "alnum") == 0)
108*6236dae4SAndroid Build Coastguard Worker charset[CURLFNM_ALNUM] = 1;
109*6236dae4SAndroid Build Coastguard Worker else if(strcmp(keyword, "alpha") == 0)
110*6236dae4SAndroid Build Coastguard Worker charset[CURLFNM_ALPHA] = 1;
111*6236dae4SAndroid Build Coastguard Worker else if(strcmp(keyword, "xdigit") == 0)
112*6236dae4SAndroid Build Coastguard Worker charset[CURLFNM_XDIGIT] = 1;
113*6236dae4SAndroid Build Coastguard Worker else if(strcmp(keyword, "print") == 0)
114*6236dae4SAndroid Build Coastguard Worker charset[CURLFNM_PRINT] = 1;
115*6236dae4SAndroid Build Coastguard Worker else if(strcmp(keyword, "graph") == 0)
116*6236dae4SAndroid Build Coastguard Worker charset[CURLFNM_GRAPH] = 1;
117*6236dae4SAndroid Build Coastguard Worker else if(strcmp(keyword, "space") == 0)
118*6236dae4SAndroid Build Coastguard Worker charset[CURLFNM_SPACE] = 1;
119*6236dae4SAndroid Build Coastguard Worker else if(strcmp(keyword, "blank") == 0)
120*6236dae4SAndroid Build Coastguard Worker charset[CURLFNM_BLANK] = 1;
121*6236dae4SAndroid Build Coastguard Worker else if(strcmp(keyword, "upper") == 0)
122*6236dae4SAndroid Build Coastguard Worker charset[CURLFNM_UPPER] = 1;
123*6236dae4SAndroid Build Coastguard Worker else if(strcmp(keyword, "lower") == 0)
124*6236dae4SAndroid Build Coastguard Worker charset[CURLFNM_LOWER] = 1;
125*6236dae4SAndroid Build Coastguard Worker else
126*6236dae4SAndroid Build Coastguard Worker return SETCHARSET_FAIL;
127*6236dae4SAndroid Build Coastguard Worker return SETCHARSET_OK;
128*6236dae4SAndroid Build Coastguard Worker }
129*6236dae4SAndroid Build Coastguard Worker
130*6236dae4SAndroid Build Coastguard Worker /* Return the character class. */
charclass(unsigned char c)131*6236dae4SAndroid Build Coastguard Worker static char_class charclass(unsigned char c)
132*6236dae4SAndroid Build Coastguard Worker {
133*6236dae4SAndroid Build Coastguard Worker if(ISUPPER(c))
134*6236dae4SAndroid Build Coastguard Worker return CCLASS_UPPER;
135*6236dae4SAndroid Build Coastguard Worker if(ISLOWER(c))
136*6236dae4SAndroid Build Coastguard Worker return CCLASS_LOWER;
137*6236dae4SAndroid Build Coastguard Worker if(ISDIGIT(c))
138*6236dae4SAndroid Build Coastguard Worker return CCLASS_DIGIT;
139*6236dae4SAndroid Build Coastguard Worker return CCLASS_OTHER;
140*6236dae4SAndroid Build Coastguard Worker }
141*6236dae4SAndroid Build Coastguard Worker
142*6236dae4SAndroid Build Coastguard Worker /* Include a character or a range in set. */
setcharorrange(unsigned char ** pp,unsigned char * charset)143*6236dae4SAndroid Build Coastguard Worker static void setcharorrange(unsigned char **pp, unsigned char *charset)
144*6236dae4SAndroid Build Coastguard Worker {
145*6236dae4SAndroid Build Coastguard Worker unsigned char *p = (*pp)++;
146*6236dae4SAndroid Build Coastguard Worker unsigned char c = *p++;
147*6236dae4SAndroid Build Coastguard Worker
148*6236dae4SAndroid Build Coastguard Worker charset[c] = 1;
149*6236dae4SAndroid Build Coastguard Worker if(ISALNUM(c) && *p++ == '-') {
150*6236dae4SAndroid Build Coastguard Worker char_class cc = charclass(c);
151*6236dae4SAndroid Build Coastguard Worker unsigned char endrange = *p++;
152*6236dae4SAndroid Build Coastguard Worker
153*6236dae4SAndroid Build Coastguard Worker if(endrange == '\\')
154*6236dae4SAndroid Build Coastguard Worker endrange = *p++;
155*6236dae4SAndroid Build Coastguard Worker if(endrange >= c && charclass(endrange) == cc) {
156*6236dae4SAndroid Build Coastguard Worker while(c++ != endrange)
157*6236dae4SAndroid Build Coastguard Worker if(charclass(c) == cc) /* Chars in class may be not consecutive. */
158*6236dae4SAndroid Build Coastguard Worker charset[c] = 1;
159*6236dae4SAndroid Build Coastguard Worker *pp = p;
160*6236dae4SAndroid Build Coastguard Worker }
161*6236dae4SAndroid Build Coastguard Worker }
162*6236dae4SAndroid Build Coastguard Worker }
163*6236dae4SAndroid Build Coastguard Worker
164*6236dae4SAndroid Build Coastguard Worker /* returns 1 (TRUE) if pattern is OK, 0 if is bad ("p" is pattern pointer) */
setcharset(unsigned char ** p,unsigned char * charset)165*6236dae4SAndroid Build Coastguard Worker static int setcharset(unsigned char **p, unsigned char *charset)
166*6236dae4SAndroid Build Coastguard Worker {
167*6236dae4SAndroid Build Coastguard Worker setcharset_state state = CURLFNM_SCHS_DEFAULT;
168*6236dae4SAndroid Build Coastguard Worker bool something_found = FALSE;
169*6236dae4SAndroid Build Coastguard Worker unsigned char c;
170*6236dae4SAndroid Build Coastguard Worker
171*6236dae4SAndroid Build Coastguard Worker memset(charset, 0, CURLFNM_CHSET_SIZE);
172*6236dae4SAndroid Build Coastguard Worker for(;;) {
173*6236dae4SAndroid Build Coastguard Worker c = **p;
174*6236dae4SAndroid Build Coastguard Worker if(!c)
175*6236dae4SAndroid Build Coastguard Worker return SETCHARSET_FAIL;
176*6236dae4SAndroid Build Coastguard Worker
177*6236dae4SAndroid Build Coastguard Worker switch(state) {
178*6236dae4SAndroid Build Coastguard Worker case CURLFNM_SCHS_DEFAULT:
179*6236dae4SAndroid Build Coastguard Worker if(c == ']') {
180*6236dae4SAndroid Build Coastguard Worker if(something_found)
181*6236dae4SAndroid Build Coastguard Worker return SETCHARSET_OK;
182*6236dae4SAndroid Build Coastguard Worker something_found = TRUE;
183*6236dae4SAndroid Build Coastguard Worker state = CURLFNM_SCHS_RIGHTBR;
184*6236dae4SAndroid Build Coastguard Worker charset[c] = 1;
185*6236dae4SAndroid Build Coastguard Worker (*p)++;
186*6236dae4SAndroid Build Coastguard Worker }
187*6236dae4SAndroid Build Coastguard Worker else if(c == '[') {
188*6236dae4SAndroid Build Coastguard Worker unsigned char *pp = *p + 1;
189*6236dae4SAndroid Build Coastguard Worker
190*6236dae4SAndroid Build Coastguard Worker if(*pp++ == ':' && parsekeyword(&pp, charset))
191*6236dae4SAndroid Build Coastguard Worker *p = pp;
192*6236dae4SAndroid Build Coastguard Worker else {
193*6236dae4SAndroid Build Coastguard Worker charset[c] = 1;
194*6236dae4SAndroid Build Coastguard Worker (*p)++;
195*6236dae4SAndroid Build Coastguard Worker }
196*6236dae4SAndroid Build Coastguard Worker something_found = TRUE;
197*6236dae4SAndroid Build Coastguard Worker }
198*6236dae4SAndroid Build Coastguard Worker else if(c == '^' || c == '!') {
199*6236dae4SAndroid Build Coastguard Worker if(!something_found) {
200*6236dae4SAndroid Build Coastguard Worker if(charset[CURLFNM_NEGATE]) {
201*6236dae4SAndroid Build Coastguard Worker charset[c] = 1;
202*6236dae4SAndroid Build Coastguard Worker something_found = TRUE;
203*6236dae4SAndroid Build Coastguard Worker }
204*6236dae4SAndroid Build Coastguard Worker else
205*6236dae4SAndroid Build Coastguard Worker charset[CURLFNM_NEGATE] = 1; /* negate charset */
206*6236dae4SAndroid Build Coastguard Worker }
207*6236dae4SAndroid Build Coastguard Worker else
208*6236dae4SAndroid Build Coastguard Worker charset[c] = 1;
209*6236dae4SAndroid Build Coastguard Worker (*p)++;
210*6236dae4SAndroid Build Coastguard Worker }
211*6236dae4SAndroid Build Coastguard Worker else if(c == '\\') {
212*6236dae4SAndroid Build Coastguard Worker c = *(++(*p));
213*6236dae4SAndroid Build Coastguard Worker if(c)
214*6236dae4SAndroid Build Coastguard Worker setcharorrange(p, charset);
215*6236dae4SAndroid Build Coastguard Worker else
216*6236dae4SAndroid Build Coastguard Worker charset['\\'] = 1;
217*6236dae4SAndroid Build Coastguard Worker something_found = TRUE;
218*6236dae4SAndroid Build Coastguard Worker }
219*6236dae4SAndroid Build Coastguard Worker else {
220*6236dae4SAndroid Build Coastguard Worker setcharorrange(p, charset);
221*6236dae4SAndroid Build Coastguard Worker something_found = TRUE;
222*6236dae4SAndroid Build Coastguard Worker }
223*6236dae4SAndroid Build Coastguard Worker break;
224*6236dae4SAndroid Build Coastguard Worker case CURLFNM_SCHS_RIGHTBR:
225*6236dae4SAndroid Build Coastguard Worker if(c == '[') {
226*6236dae4SAndroid Build Coastguard Worker state = CURLFNM_SCHS_RIGHTBRLEFTBR;
227*6236dae4SAndroid Build Coastguard Worker charset[c] = 1;
228*6236dae4SAndroid Build Coastguard Worker (*p)++;
229*6236dae4SAndroid Build Coastguard Worker }
230*6236dae4SAndroid Build Coastguard Worker else if(c == ']') {
231*6236dae4SAndroid Build Coastguard Worker return SETCHARSET_OK;
232*6236dae4SAndroid Build Coastguard Worker }
233*6236dae4SAndroid Build Coastguard Worker else if(ISPRINT(c)) {
234*6236dae4SAndroid Build Coastguard Worker charset[c] = 1;
235*6236dae4SAndroid Build Coastguard Worker (*p)++;
236*6236dae4SAndroid Build Coastguard Worker state = CURLFNM_SCHS_DEFAULT;
237*6236dae4SAndroid Build Coastguard Worker }
238*6236dae4SAndroid Build Coastguard Worker else
239*6236dae4SAndroid Build Coastguard Worker /* used 'goto fail' instead of 'return SETCHARSET_FAIL' to avoid a
240*6236dae4SAndroid Build Coastguard Worker * nonsense warning 'statement not reached' at end of the fnc when
241*6236dae4SAndroid Build Coastguard Worker * compiling on Solaris */
242*6236dae4SAndroid Build Coastguard Worker goto fail;
243*6236dae4SAndroid Build Coastguard Worker break;
244*6236dae4SAndroid Build Coastguard Worker case CURLFNM_SCHS_RIGHTBRLEFTBR:
245*6236dae4SAndroid Build Coastguard Worker if(c == ']')
246*6236dae4SAndroid Build Coastguard Worker return SETCHARSET_OK;
247*6236dae4SAndroid Build Coastguard Worker state = CURLFNM_SCHS_DEFAULT;
248*6236dae4SAndroid Build Coastguard Worker charset[c] = 1;
249*6236dae4SAndroid Build Coastguard Worker (*p)++;
250*6236dae4SAndroid Build Coastguard Worker break;
251*6236dae4SAndroid Build Coastguard Worker }
252*6236dae4SAndroid Build Coastguard Worker }
253*6236dae4SAndroid Build Coastguard Worker fail:
254*6236dae4SAndroid Build Coastguard Worker return SETCHARSET_FAIL;
255*6236dae4SAndroid Build Coastguard Worker }
256*6236dae4SAndroid Build Coastguard Worker
loop(const unsigned char * pattern,const unsigned char * string,int maxstars)257*6236dae4SAndroid Build Coastguard Worker static int loop(const unsigned char *pattern, const unsigned char *string,
258*6236dae4SAndroid Build Coastguard Worker int maxstars)
259*6236dae4SAndroid Build Coastguard Worker {
260*6236dae4SAndroid Build Coastguard Worker unsigned char *p = (unsigned char *)pattern;
261*6236dae4SAndroid Build Coastguard Worker unsigned char *s = (unsigned char *)string;
262*6236dae4SAndroid Build Coastguard Worker unsigned char charset[CURLFNM_CHSET_SIZE] = { 0 };
263*6236dae4SAndroid Build Coastguard Worker
264*6236dae4SAndroid Build Coastguard Worker for(;;) {
265*6236dae4SAndroid Build Coastguard Worker unsigned char *pp;
266*6236dae4SAndroid Build Coastguard Worker
267*6236dae4SAndroid Build Coastguard Worker switch(*p) {
268*6236dae4SAndroid Build Coastguard Worker case '*':
269*6236dae4SAndroid Build Coastguard Worker if(!maxstars)
270*6236dae4SAndroid Build Coastguard Worker return CURL_FNMATCH_NOMATCH;
271*6236dae4SAndroid Build Coastguard Worker /* Regroup consecutive stars and question marks. This can be done because
272*6236dae4SAndroid Build Coastguard Worker '*?*?*' can be expressed as '??*'. */
273*6236dae4SAndroid Build Coastguard Worker for(;;) {
274*6236dae4SAndroid Build Coastguard Worker if(*++p == '\0')
275*6236dae4SAndroid Build Coastguard Worker return CURL_FNMATCH_MATCH;
276*6236dae4SAndroid Build Coastguard Worker if(*p == '?') {
277*6236dae4SAndroid Build Coastguard Worker if(!*s++)
278*6236dae4SAndroid Build Coastguard Worker return CURL_FNMATCH_NOMATCH;
279*6236dae4SAndroid Build Coastguard Worker }
280*6236dae4SAndroid Build Coastguard Worker else if(*p != '*')
281*6236dae4SAndroid Build Coastguard Worker break;
282*6236dae4SAndroid Build Coastguard Worker }
283*6236dae4SAndroid Build Coastguard Worker /* Skip string characters until we find a match with pattern suffix. */
284*6236dae4SAndroid Build Coastguard Worker for(maxstars--; *s; s++) {
285*6236dae4SAndroid Build Coastguard Worker if(loop(p, s, maxstars) == CURL_FNMATCH_MATCH)
286*6236dae4SAndroid Build Coastguard Worker return CURL_FNMATCH_MATCH;
287*6236dae4SAndroid Build Coastguard Worker }
288*6236dae4SAndroid Build Coastguard Worker return CURL_FNMATCH_NOMATCH;
289*6236dae4SAndroid Build Coastguard Worker case '?':
290*6236dae4SAndroid Build Coastguard Worker if(!*s)
291*6236dae4SAndroid Build Coastguard Worker return CURL_FNMATCH_NOMATCH;
292*6236dae4SAndroid Build Coastguard Worker s++;
293*6236dae4SAndroid Build Coastguard Worker p++;
294*6236dae4SAndroid Build Coastguard Worker break;
295*6236dae4SAndroid Build Coastguard Worker case '\0':
296*6236dae4SAndroid Build Coastguard Worker return *s ? CURL_FNMATCH_NOMATCH : CURL_FNMATCH_MATCH;
297*6236dae4SAndroid Build Coastguard Worker case '\\':
298*6236dae4SAndroid Build Coastguard Worker if(p[1])
299*6236dae4SAndroid Build Coastguard Worker p++;
300*6236dae4SAndroid Build Coastguard Worker if(*s++ != *p++)
301*6236dae4SAndroid Build Coastguard Worker return CURL_FNMATCH_NOMATCH;
302*6236dae4SAndroid Build Coastguard Worker break;
303*6236dae4SAndroid Build Coastguard Worker case '[':
304*6236dae4SAndroid Build Coastguard Worker pp = p + 1; /* Copy in case of syntax error in set. */
305*6236dae4SAndroid Build Coastguard Worker if(setcharset(&pp, charset)) {
306*6236dae4SAndroid Build Coastguard Worker bool found = FALSE;
307*6236dae4SAndroid Build Coastguard Worker if(!*s)
308*6236dae4SAndroid Build Coastguard Worker return CURL_FNMATCH_NOMATCH;
309*6236dae4SAndroid Build Coastguard Worker if(charset[(unsigned int)*s])
310*6236dae4SAndroid Build Coastguard Worker found = TRUE;
311*6236dae4SAndroid Build Coastguard Worker else if(charset[CURLFNM_ALNUM])
312*6236dae4SAndroid Build Coastguard Worker found = ISALNUM(*s);
313*6236dae4SAndroid Build Coastguard Worker else if(charset[CURLFNM_ALPHA])
314*6236dae4SAndroid Build Coastguard Worker found = ISALPHA(*s);
315*6236dae4SAndroid Build Coastguard Worker else if(charset[CURLFNM_DIGIT])
316*6236dae4SAndroid Build Coastguard Worker found = ISDIGIT(*s);
317*6236dae4SAndroid Build Coastguard Worker else if(charset[CURLFNM_XDIGIT])
318*6236dae4SAndroid Build Coastguard Worker found = ISXDIGIT(*s);
319*6236dae4SAndroid Build Coastguard Worker else if(charset[CURLFNM_PRINT])
320*6236dae4SAndroid Build Coastguard Worker found = ISPRINT(*s);
321*6236dae4SAndroid Build Coastguard Worker else if(charset[CURLFNM_SPACE])
322*6236dae4SAndroid Build Coastguard Worker found = ISSPACE(*s);
323*6236dae4SAndroid Build Coastguard Worker else if(charset[CURLFNM_UPPER])
324*6236dae4SAndroid Build Coastguard Worker found = ISUPPER(*s);
325*6236dae4SAndroid Build Coastguard Worker else if(charset[CURLFNM_LOWER])
326*6236dae4SAndroid Build Coastguard Worker found = ISLOWER(*s);
327*6236dae4SAndroid Build Coastguard Worker else if(charset[CURLFNM_BLANK])
328*6236dae4SAndroid Build Coastguard Worker found = ISBLANK(*s);
329*6236dae4SAndroid Build Coastguard Worker else if(charset[CURLFNM_GRAPH])
330*6236dae4SAndroid Build Coastguard Worker found = ISGRAPH(*s);
331*6236dae4SAndroid Build Coastguard Worker
332*6236dae4SAndroid Build Coastguard Worker if(charset[CURLFNM_NEGATE])
333*6236dae4SAndroid Build Coastguard Worker found = !found;
334*6236dae4SAndroid Build Coastguard Worker
335*6236dae4SAndroid Build Coastguard Worker if(!found)
336*6236dae4SAndroid Build Coastguard Worker return CURL_FNMATCH_NOMATCH;
337*6236dae4SAndroid Build Coastguard Worker p = pp + 1;
338*6236dae4SAndroid Build Coastguard Worker s++;
339*6236dae4SAndroid Build Coastguard Worker break;
340*6236dae4SAndroid Build Coastguard Worker }
341*6236dae4SAndroid Build Coastguard Worker /* Syntax error in set; mismatch! */
342*6236dae4SAndroid Build Coastguard Worker return CURL_FNMATCH_NOMATCH;
343*6236dae4SAndroid Build Coastguard Worker
344*6236dae4SAndroid Build Coastguard Worker default:
345*6236dae4SAndroid Build Coastguard Worker if(*p++ != *s++)
346*6236dae4SAndroid Build Coastguard Worker return CURL_FNMATCH_NOMATCH;
347*6236dae4SAndroid Build Coastguard Worker break;
348*6236dae4SAndroid Build Coastguard Worker }
349*6236dae4SAndroid Build Coastguard Worker }
350*6236dae4SAndroid Build Coastguard Worker }
351*6236dae4SAndroid Build Coastguard Worker
352*6236dae4SAndroid Build Coastguard Worker /*
353*6236dae4SAndroid Build Coastguard Worker * @unittest: 1307
354*6236dae4SAndroid Build Coastguard Worker */
Curl_fnmatch(void * ptr,const char * pattern,const char * string)355*6236dae4SAndroid Build Coastguard Worker int Curl_fnmatch(void *ptr, const char *pattern, const char *string)
356*6236dae4SAndroid Build Coastguard Worker {
357*6236dae4SAndroid Build Coastguard Worker (void)ptr; /* the argument is specified by the curl_fnmatch_callback
358*6236dae4SAndroid Build Coastguard Worker prototype, but not used by Curl_fnmatch() */
359*6236dae4SAndroid Build Coastguard Worker if(!pattern || !string) {
360*6236dae4SAndroid Build Coastguard Worker return CURL_FNMATCH_FAIL;
361*6236dae4SAndroid Build Coastguard Worker }
362*6236dae4SAndroid Build Coastguard Worker return loop((unsigned char *)pattern, (unsigned char *)string, 2);
363*6236dae4SAndroid Build Coastguard Worker }
364*6236dae4SAndroid Build Coastguard Worker #else
365*6236dae4SAndroid Build Coastguard Worker #include <fnmatch.h>
366*6236dae4SAndroid Build Coastguard Worker /*
367*6236dae4SAndroid Build Coastguard Worker * @unittest: 1307
368*6236dae4SAndroid Build Coastguard Worker */
Curl_fnmatch(void * ptr,const char * pattern,const char * string)369*6236dae4SAndroid Build Coastguard Worker int Curl_fnmatch(void *ptr, const char *pattern, const char *string)
370*6236dae4SAndroid Build Coastguard Worker {
371*6236dae4SAndroid Build Coastguard Worker (void)ptr; /* the argument is specified by the curl_fnmatch_callback
372*6236dae4SAndroid Build Coastguard Worker prototype, but not used by Curl_fnmatch() */
373*6236dae4SAndroid Build Coastguard Worker if(!pattern || !string) {
374*6236dae4SAndroid Build Coastguard Worker return CURL_FNMATCH_FAIL;
375*6236dae4SAndroid Build Coastguard Worker }
376*6236dae4SAndroid Build Coastguard Worker
377*6236dae4SAndroid Build Coastguard Worker switch(fnmatch(pattern, string, 0)) {
378*6236dae4SAndroid Build Coastguard Worker case 0:
379*6236dae4SAndroid Build Coastguard Worker return CURL_FNMATCH_MATCH;
380*6236dae4SAndroid Build Coastguard Worker case FNM_NOMATCH:
381*6236dae4SAndroid Build Coastguard Worker return CURL_FNMATCH_NOMATCH;
382*6236dae4SAndroid Build Coastguard Worker default:
383*6236dae4SAndroid Build Coastguard Worker return CURL_FNMATCH_FAIL;
384*6236dae4SAndroid Build Coastguard Worker }
385*6236dae4SAndroid Build Coastguard Worker /* not reached */
386*6236dae4SAndroid Build Coastguard Worker }
387*6236dae4SAndroid Build Coastguard Worker
388*6236dae4SAndroid Build Coastguard Worker #endif
389*6236dae4SAndroid Build Coastguard Worker
390*6236dae4SAndroid Build Coastguard Worker #endif /* if FTP is disabled */
391