1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 /* Copyright (c) 1988 AT&T */
28 /* All Rights Reserved */
29
30 #pragma ident "%Z%%M% %I% %E% SMI"
31
32 #ifdef illumos
33 #pragma weak gmatch = _gmatch
34
35 #include "gen_synonyms.h"
36 #endif
37 #include <sys/types.h>
38 #include <libgen.h>
39 #include <stdlib.h>
40 #include <limits.h>
41 #ifdef illumos
42 #include <widec.h>
43 #include "_range.h"
44 #else
45 #include <ctype.h>
46 /* DOODAD */ static int multibyte = 0;
47 #define WCHAR_CSMASK 0x30000000
48 #define valid_range(c1, c2) \
49 (((c1) & WCHAR_CSMASK) == ((c2) & WCHAR_CSMASK) && \
50 ((c1) > 0xff || !iscntrl((int)c1)) && ((c2) > 0xff || \
51 !iscntrl((int)c2)))
52 #endif
53
54 #define Popwchar(p, c) \
55 n = mbtowc(&cl, p, MB_LEN_MAX); \
56 c = cl; \
57 if (n <= 0) \
58 return (0); \
59 p += n
60
61 int
gmatch(const char * s,const char * p)62 gmatch(const char *s, const char *p)
63 {
64 const char *olds;
65 wchar_t scc, c;
66 int n;
67 wchar_t cl;
68
69 olds = s;
70 n = mbtowc(&cl, s, MB_LEN_MAX);
71 if (n <= 0) {
72 s++;
73 scc = n;
74 } else {
75 scc = cl;
76 s += n;
77 }
78 n = mbtowc(&cl, p, MB_LEN_MAX);
79 if (n < 0)
80 return (0);
81 if (n == 0)
82 return (scc == 0);
83 p += n;
84 c = cl;
85
86 switch (c) {
87 case '[':
88 if (scc <= 0)
89 return (0);
90 {
91 int ok;
92 wchar_t lc = 0;
93 int notflag = 0;
94
95 ok = 0;
96 if (*p == '!') {
97 notflag = 1;
98 p++;
99 }
100 Popwchar(p, c);
101 do
102 {
103 if (c == '-' && lc && *p != ']') {
104 Popwchar(p, c);
105 if (c == '\\') {
106 Popwchar(p, c);
107 }
108 if (notflag) {
109 if (!multibyte ||
110 valid_range(lc, c)) {
111 if (scc < lc || scc > c)
112 ok++;
113 else
114 return (0);
115 }
116 } else {
117 if (!multibyte ||
118 valid_range(lc, c))
119 if (lc <= scc &&
120 scc <= c)
121 ok++;
122 }
123 } else if (c == '\\') {
124 /* skip to quoted character */
125 Popwchar(p, c);
126 }
127 lc = c;
128 if (notflag) {
129 if (scc != lc)
130 ok++;
131 else
132 return (0);
133 }
134 else
135 {
136 if (scc == lc)
137 ok++;
138 }
139 Popwchar(p, c);
140 } while (c != ']');
141 return (ok ? gmatch(s, p) : 0);
142 }
143
144 case '\\':
145 /* skip to quoted character and see if it matches */
146 Popwchar(p, c);
147
148 default:
149 if (c != scc)
150 return (0);
151 /*FALLTHRU*/
152
153 case '?':
154 return (scc > 0 ? gmatch(s, p) : 0);
155
156 case '*':
157 while (*p == '*')
158 p++;
159
160 if (*p == 0)
161 return (1);
162 s = olds;
163 while (*s) {
164 if (gmatch(s, p))
165 return (1);
166 n = mbtowc(&cl, s, MB_LEN_MAX);
167 if (n < 0)
168 /* skip past illegal byte sequence */
169 s++;
170 else
171 s += n;
172 }
173 return (0);
174 }
175 }
176