1 /* Copyright (C) 1991,1992,1993,1996,1997,1998,1999,2000,2001,2002,2003,2007
2 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, write to the Free
17 Software Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA
18 02110-1335, USA. */
19
20 /* This file comes from the GNU C Library and has been modified for use in
21 * ProFTPD.
22 *
23 * Changes are released under the GNU Public License, version 2.
24 * Copyright (C) 2000 MacGyver aka Habeeb J. Dihu <macgyver@tos.net>
25 * Copyright (C) 2010-2012 The ProFTPD Project
26 */
27
28 /* AIX requires this to be the first thing in the file. */
29 #if defined _AIX && !defined __GNUC__
30 #pragma alloca
31 #endif
32
33 #include <config.h>
34
35 /* Make alloca work the best possible way. */
36 #ifdef __GNUC__
37 #define alloca __builtin_alloca
38 #else /* not __GNUC__ */
39 #if HAVE_ALLOCA_H
40 #include <alloca.h>
41 #else /* not __GNUC__ or HAVE_ALLOCA_H */
42 #ifndef _AIX /* Already did AIX, up at the top. */
43 char *alloca ();
44 #endif /* not _AIX */
45 #endif /* not HAVE_ALLOCA_H */
46 #endif /* not __GNUC__ */
47
48 /* Necessary for platforms which don't use __alloca. */
49 #define __alloca alloca
50
51 /* Required to tell conf.h not to include the standard ProFTPD
52 * header files
53 */
54
55 #define __PROFTPD_SUPPORT_LIBRARY
56
57 #include <conf.h>
58 #include <libsupp.h>
59
60 #if 0 /* Not used in ProFTPD */
61 /* Enable GNU extensions in fnmatch.h. */
62 #ifndef _GNU_SOURCE
63 # define _GNU_SOURCE 1
64 #endif
65
66 #include <assert.h>
67 #include <errno.h>
68 #include <fnmatch.h>
69 #include <ctype.h>
70
71 #if HAVE_STRING_H || defined _LIBC
72 # include <string.h>
73 #else
74 # include <strings.h>
75 #endif
76
77 #if defined STDC_HEADERS || defined _LIBC
78 # include <stdlib.h>
79 #endif
80
81 /* For platform which support the ISO C amendement 1 functionality we
82 support user defined character classes. */
83 #if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
84 /* Solaris 2.5 has a bug: <wchar.h> must be included before <wctype.h>. */
85 # include <wchar.h>
86 # include <wctype.h>
87 #endif
88
89 /* We need some of the locale data (the collation sequence information)
90 but there is no interface to get this information in general. Therefore
91 we support a correct implementation only in glibc. */
92 #ifdef _LIBC
93 # include "../locale/localeinfo.h"
94 # include "../locale/elem-hash.h"
95 # include "../locale/coll-lookup.h"
96 # include <shlib-compat.h>
97
98 # define CONCAT(a,b) __CONCAT(a,b)
99 # define mbsrtowcs __mbsrtowcs
100 # define fnmatch __fnmatch
101 extern int fnmatch (const char *pattern, const char *string, int flags);
102 #endif
103 #endif /* Not used in ProFTPD */
104
105 /* We often have to test for FNM_FILE_NAME and FNM_PERIOD being both set. */
106 #define NO_LEADING_PERIOD(flags) \
107 ((flags & (PR_FNM_FILE_NAME | PR_FNM_PERIOD)) == (PR_FNM_FILE_NAME | PR_FNM_PERIOD))
108
109 /* Comment out all this code if we are using the GNU C Library, and are not
110 actually compiling the library itself. This code is part of the GNU C
111 Library, but also included in many other GNU distributions. Compiling
112 and linking in this code is a waste when using the GNU C library
113 (especially if it is a shared library). Rather than having every GNU
114 program understand `configure --with-gnu-libc' and omit the object files,
115 it is simpler to just do this in the source for each such file. */
116
117 /* The comment above notwithstanding, we do want to use our own version to
118 * ensure cross-platform compatibility...among other things.
119 */
120 #undef _LIBC
121 #undef __GNU_LIBRARY__
122
123 /* Provide an implementation of the gcc-specific __builtin_expect macro,
124 * for the non-gcc compilers out there.
125 */
126 #ifndef __builtin_expect
127 # define __builtin_expect(e, n) (e)
128 #endif /* __builtin_expect */
129
130 #if defined _LIBC || !defined __GNU_LIBRARY__
131
132
133 # if defined STDC_HEADERS || !defined isascii
134 # define ISASCII(c) 1
135 # else
136 # define ISASCII(c) isascii(c)
137 # endif
138
139 # ifdef isblank
140 # define ISBLANK(c) (ISASCII (c) && isblank (c))
141 # else
142 # define ISBLANK(c) ((c) == ' ' || (c) == '\t')
143 # endif
144 # ifdef isgraph
145 # define ISGRAPH(c) (ISASCII (c) && isgraph (c))
146 # else
147 # define ISGRAPH(c) (ISASCII (c) && isprint (c) && !isspace (c))
148 # endif
149
150 # define ISPRINT(c) (ISASCII (c) && isprint (c))
151 # define ISDIGIT(c) (ISASCII (c) && isdigit (c))
152 # define ISALNUM(c) (ISASCII (c) && isalnum (c))
153 # define ISALPHA(c) (ISASCII (c) && isalpha (c))
154 # define ISCNTRL(c) (ISASCII (c) && iscntrl (c))
155 # define ISLOWER(c) (ISASCII (c) && islower (c))
156 # define ISPUNCT(c) (ISASCII (c) && ispunct (c))
157 # define ISSPACE(c) (ISASCII (c) && isspace (c))
158 # define ISUPPER(c) (ISASCII (c) && isupper (c))
159 # define ISXDIGIT(c) (ISASCII (c) && isxdigit (c))
160
161 # define STREQ(s1, s2) ((strcmp (s1, s2) == 0))
162
163 # define HANDLE_MULTIBYTE 0
164
165 # if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
166 /* The GNU C library provides support for user-defined character classes
167 and the functions from ISO C amendement 1. */
168 # ifdef CHARCLASS_NAME_MAX
169 # define CHAR_CLASS_MAX_LENGTH CHARCLASS_NAME_MAX
170 # else
171 /* This shouldn't happen but some implementation might still have this
172 problem. Use a reasonable default value. */
173 # define CHAR_CLASS_MAX_LENGTH 256
174 # endif
175
176 # ifdef _LIBC
177 # define IS_CHAR_CLASS(string) __wctype (string)
178 # else
179 # define IS_CHAR_CLASS(string) wctype (string)
180 # endif
181
182 # ifdef _LIBC
183 # define ISWCTYPE(WC, WT) __iswctype (WC, WT)
184 # else
185 # define ISWCTYPE(WC, WT) iswctype (WC, WT)
186 # endif
187
188 # if (HAVE_MBSTATE_T && HAVE_MBSRTOWCS) || _LIBC
189 /* In this case we are implementing the multibyte character handling. */
190 # define HANDLE_MULTIBYTE 1
191 # endif
192
193 # else
194 # define CHAR_CLASS_MAX_LENGTH 6 /* Namely, `xdigit'. */
195
196 # define IS_CHAR_CLASS(string) \
197 (STREQ (string, "alpha") || STREQ (string, "upper") \
198 || STREQ (string, "lower") || STREQ (string, "digit") \
199 || STREQ (string, "alnum") || STREQ (string, "xdigit") \
200 || STREQ (string, "space") || STREQ (string, "print") \
201 || STREQ (string, "punct") || STREQ (string, "graph") \
202 || STREQ (string, "cntrl") || STREQ (string, "blank"))
203 # endif
204
205 /* Avoid depending on library functions or files
206 whose names are inconsistent. */
207
208 # ifndef errno
209 extern int errno;
210 # endif
211
212 /* Global variable. */
213 static int posixly_correct;
214
215 # if HANDLE_MULTIBYTE && !defined HAVE___STRCHRNUL && !defined _LIBC
216 static wchar_t *
__wcschrnul(const wchar_t * s,wint_t c)217 __wcschrnul (const wchar_t *s, wint_t c)
218 {
219 wchar_t *result = wcschr (s, c);
220 if (result == NULL)
221 result = wcschr (s, '\0');
222 return result;
223 }
224 # endif
225
226 # ifndef internal_function
227 /* Inside GNU libc we mark some function in a special way. In other
228 environments simply ignore the marking. */
229 # define internal_function
230 # endif
231
232 /* Note that this evaluates C many times. */
233 # ifdef _LIBC
234 # define FOLD(c) ((flags & PR_FNM_CASEFOLD) ? tolower (c) : (c))
235 # else
236 # define FOLD(c) ((flags & PR_FNM_CASEFOLD) && ISUPPER (c) ? tolower (c) : (c))
237 # endif
238 # define CHAR char
239 # define UCHAR unsigned char
240 # define INT int
241 # define FCT internal_fnmatch
242 # define EXT ext_match
243 # define END end_pattern
244 # define STRUCT fnmatch_struct
245 # define L(CS) CS
246 # ifdef _LIBC
247 # define BTOWC(C) __btowc (C)
248 # else
249 # define BTOWC(C) btowc (C)
250 # endif
251 # define STRLEN(S) strlen (S)
252 # define STRCAT(D, S) strcat (D, S)
253 # ifdef HAVE_MEMPCPY
254 # define MEMPCPY(D, S, N) mempcpy (D, S, N)
255 # else
256 # define MEMPCPY(D, S, N) __mempcpy (D, S, N)
257 # endif
258 # define MEMCHR(S, C, N) memchr (S, C, N)
259 # define STRCOLL(S1, S2) strcoll (S1, S2)
260 # include "pr_fnmatch_loop.c"
261
262
263 # if HANDLE_MULTIBYTE
264 /* Note that this evaluates C many times. */
265 # ifdef _LIBC
266 # define FOLD(c) ((flags & PR_FNM_CASEFOLD) ? towlower (c) : (c))
267 # else
268 # define FOLD(c) ((flags & PR_FNM_CASEFOLD) && ISUPPER (c) ? towlower (c) : (c))
269 # endif
270 # define CHAR wchar_t
271 # define UCHAR wint_t
272 # define INT wint_t
273 # define FCT internal_fnwmatch
274 # define EXT ext_wmatch
275 # define END end_wpattern
276 # define STRUCT fnwmatch_struct
277 # define L(CS) L##CS
278 # define BTOWC(C) (C)
279 # define STRLEN(S) __wcslen (S)
280 # define STRCAT(D, S) __wcscat (D, S)
281 # define MEMPCPY(D, S, N) wmempcpy (D, S, N)
282 # define MEMCHR(S, C, N) wmemchr (S, C, N)
283 # define STRCOLL(S1, S2) wcscoll (S1, S2)
284 # define WIDE_CHAR_VERSION 1
285
286 # undef IS_CHAR_CLASS
287 /* We have to convert the wide character string in a multibyte string. But
288 we know that the character class names consist of alphanumeric characters
289 from the portable character set, and since the wide character encoding
290 for a member of the portable character set is the same code point as
291 its single-byte encoding, we can use a simplified method to convert the
292 string to a multibyte character string. */
293 static wctype_t
is_char_class(const wchar_t * wcs)294 is_char_class (const wchar_t *wcs)
295 {
296 char s[CHAR_CLASS_MAX_LENGTH + 1];
297 char *cp = s;
298
299 do
300 {
301 /* Test for a printable character from the portable character set. */
302 # ifdef _LIBC
303 if (*wcs < 0x20 || *wcs > 0x7e
304 || *wcs == 0x24 || *wcs == 0x40 || *wcs == 0x60)
305 return (wctype_t) 0;
306 # else
307 switch (*wcs)
308 {
309 case L' ': case L'!': case L'"': case L'#': case L'%':
310 case L'&': case L'\'': case L'(': case L')': case L'*':
311 case L'+': case L',': case L'-': case L'.': case L'/':
312 case L'0': case L'1': case L'2': case L'3': case L'4':
313 case L'5': case L'6': case L'7': case L'8': case L'9':
314 case L':': case L';': case L'<': case L'=': case L'>':
315 case L'?':
316 case L'A': case L'B': case L'C': case L'D': case L'E':
317 case L'F': case L'G': case L'H': case L'I': case L'J':
318 case L'K': case L'L': case L'M': case L'N': case L'O':
319 case L'P': case L'Q': case L'R': case L'S': case L'T':
320 case L'U': case L'V': case L'W': case L'X': case L'Y':
321 case L'Z':
322 case L'[': case L'\\': case L']': case L'^': case L'_':
323 case L'a': case L'b': case L'c': case L'd': case L'e':
324 case L'f': case L'g': case L'h': case L'i': case L'j':
325 case L'k': case L'l': case L'm': case L'n': case L'o':
326 case L'p': case L'q': case L'r': case L's': case L't':
327 case L'u': case L'v': case L'w': case L'x': case L'y':
328 case L'z': case L'{': case L'|': case L'}': case L'~':
329 break;
330 default:
331 return (wctype_t) 0;
332 }
333 # endif
334
335 /* Avoid overrunning the buffer. */
336 if (cp == s + CHAR_CLASS_MAX_LENGTH)
337 return (wctype_t) 0;
338
339 *cp++ = (char) *wcs++;
340 }
341 while (*wcs != L'\0');
342
343 *cp = '\0';
344
345 # ifdef _LIBC
346 return __wctype (s);
347 # else
348 return wctype (s);
349 # endif
350 }
351 # define IS_CHAR_CLASS(string) is_char_class (string)
352
353 # include "pr_fnmatch_loop.c"
354 # endif
355
356
357 int
pr_fnmatch(pattern,string,flags)358 pr_fnmatch (pattern, string, flags)
359 const char *pattern;
360 const char *string;
361 int flags;
362 {
363 # if HANDLE_MULTIBYTE
364 if (__builtin_expect (MB_CUR_MAX, 1) != 1)
365 {
366 mbstate_t ps;
367 size_t n;
368 const char *p;
369 wchar_t *wpattern;
370 wchar_t *wstring;
371
372 /* Convert the strings into wide characters. */
373 memset (&ps, '\0', sizeof (ps));
374 p = pattern;
375 #ifdef _LIBC
376 n = strnlen (pattern, 1024);
377 #else
378 n = strlen (pattern);
379 #endif
380 if (__builtin_expect (n < 1024, 1))
381 {
382 wpattern = (wchar_t *) __alloca ((n + 1) * sizeof (wchar_t));
383 n = mbsrtowcs (wpattern, &p, n + 1, &ps);
384 if (__builtin_expect (n == (size_t) -1, 0))
385 /* Something wrong.
386 XXX Do we have to set `errno' to something which mbsrtows hasn't
387 already done? */
388 return -1;
389 if (p)
390 {
391 memset (&ps, '\0', sizeof (ps));
392 goto prepare_wpattern;
393 }
394 }
395 else
396 {
397 prepare_wpattern:
398 n = mbsrtowcs (NULL, &pattern, 0, &ps);
399 if (__builtin_expect (n == (size_t) -1, 0))
400 /* Something wrong.
401 XXX Do we have to set `errno' to something which mbsrtows hasn't
402 already done? */
403 return -1;
404 wpattern = (wchar_t *) __alloca ((n + 1) * sizeof (wchar_t));
405 assert (mbsinit (&ps));
406 (void) mbsrtowcs (wpattern, &pattern, n + 1, &ps);
407 }
408
409 assert (mbsinit (&ps));
410 #ifdef _LIBC
411 n = strnlen (string, 1024);
412 #else
413 n = strlen (string);
414 #endif
415 p = string;
416 if (__builtin_expect (n < 1024, 1))
417 {
418 wstring = (wchar_t *) __alloca ((n + 1) * sizeof (wchar_t));
419 n = mbsrtowcs (wstring, &p, n + 1, &ps);
420 if (__builtin_expect (n == (size_t) -1, 0))
421 /* Something wrong.
422 XXX Do we have to set `errno' to something which mbsrtows hasn't
423 already done? */
424 return -1;
425 if (p)
426 {
427 memset (&ps, '\0', sizeof (ps));
428 goto prepare_wstring;
429 }
430 }
431 else
432 {
433 prepare_wstring:
434 n = mbsrtowcs (NULL, &string, 0, &ps);
435 if (__builtin_expect (n == (size_t) -1, 0))
436 /* Something wrong.
437 XXX Do we have to set `errno' to something which mbsrtows hasn't
438 already done? */
439 return -1;
440 wstring = (wchar_t *) __alloca ((n + 1) * sizeof (wchar_t));
441 assert (mbsinit (&ps));
442 (void) mbsrtowcs (wstring, &string, n + 1, &ps);
443 }
444
445 return internal_fnwmatch (wpattern, wstring, wstring + n,
446 flags & PR_FNM_PERIOD, flags, NULL);
447 }
448 # endif /* mbstate_t and mbsrtowcs or _LIBC. */
449
450 return internal_fnmatch (pattern, string, string + strlen (string),
451 flags & PR_FNM_PERIOD, flags, NULL);
452 }
453
454 #endif /* _LIBC or not __GNU_LIBRARY__. */
455