Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 : Samba utility functions
4 : Copyright (C) Jeremy Allison 2001
5 :
6 : This program is free software; you can redistribute it and/or modify
7 : it under the terms of the GNU General Public License as published by
8 : the Free Software Foundation; either version 3 of the License, or
9 : (at your option) any later version.
10 :
11 : This program is distributed in the hope that it will be useful,
12 : but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 : GNU General Public License for more details.
15 :
16 : You should have received a copy of the GNU General Public License
17 : along with this program. If not, see <http://www.gnu.org/licenses/>.
18 : */
19 :
20 : #include "replace.h"
21 : #include <talloc.h>
22 : #include "lib/util/talloc_stack.h"
23 : #include "lib/util/charset/charset.h"
24 : #include "lib/util/unix_match.h"
25 :
26 : /*********************************************************
27 : Recursive routine that is called by unix_wild_match.
28 : *********************************************************/
29 :
30 0 : static bool unix_do_match(const char *regexp, const char *str)
31 : {
32 : const char *p;
33 :
34 0 : for( p = regexp; *p && *str; ) {
35 :
36 0 : switch(*p) {
37 0 : case '?':
38 0 : str++;
39 0 : p++;
40 0 : break;
41 :
42 0 : case '*':
43 :
44 : /*
45 : * Look for a character matching
46 : * the one after the '*'.
47 : */
48 0 : p++;
49 0 : if(!*p) {
50 0 : return true; /* Automatic match */
51 : }
52 0 : while(*str) {
53 :
54 0 : while(*str && (*p != *str)) {
55 0 : str++;
56 : }
57 :
58 : /*
59 : * Patch from weidel@multichart.de.
60 : * In the case of the regexp
61 : * '*XX*' we want to ensure there are
62 : * at least 2 'X' characters in the
63 : * string after the '*' for a match to
64 : * be made.
65 : */
66 :
67 0 : {
68 0 : int matchcount=0;
69 :
70 : /*
71 : * Eat all the characters that
72 : * match, but count how many
73 : * there were.
74 : */
75 :
76 0 : while(*str && (*p == *str)) {
77 0 : str++;
78 0 : matchcount++;
79 : }
80 :
81 : /*
82 : * Now check that if the regexp
83 : * had n identical characters
84 : * that matchcount had at least
85 : * that many matches.
86 : */
87 :
88 0 : while (*(p+1) && (*(p+1)==*p)) {
89 0 : p++;
90 0 : matchcount--;
91 : }
92 :
93 0 : if ( matchcount <= 0 ) {
94 0 : return false;
95 : }
96 : }
97 :
98 : /*
99 : * We've eaten the match char
100 : * after the '*'
101 : */
102 0 : str--;
103 :
104 0 : if(unix_do_match(p, str)) {
105 0 : return true;
106 : }
107 :
108 0 : if(!*str) {
109 0 : return false;
110 : } else {
111 0 : str++;
112 : }
113 : }
114 0 : return false;
115 :
116 0 : default:
117 0 : if(*str != *p) {
118 0 : return false;
119 : }
120 0 : str++;
121 0 : p++;
122 0 : break;
123 : }
124 : }
125 :
126 0 : if(!*p && !*str) {
127 0 : return true;
128 : }
129 :
130 0 : if (!*p && str[0] == '.' && str[1] == 0) {
131 0 : return true;
132 : }
133 :
134 0 : if (!*str && *p == '?') {
135 0 : while (*p == '?') {
136 0 : p++;
137 : }
138 0 : return(!*p);
139 : }
140 :
141 0 : if(!*str && (*p == '*' && p[1] == '\0')) {
142 0 : return true;
143 : }
144 :
145 0 : return false;
146 : }
147 :
148 : /*******************************************************************
149 : Simple case insensitive interface to a UNIX wildcard matcher.
150 : Returns True if match, False if not.
151 : *******************************************************************/
152 :
153 0 : bool unix_wild_match(const char *pattern, const char *string)
154 : {
155 0 : TALLOC_CTX *ctx = talloc_stackframe();
156 : char *p2;
157 : char *s2;
158 : char *p;
159 0 : bool ret = false;
160 :
161 0 : p2 = strlower_talloc(ctx, pattern);
162 0 : s2 = strlower_talloc(ctx, string);
163 0 : if (!p2 || !s2) {
164 0 : TALLOC_FREE(ctx);
165 0 : return false;
166 : }
167 :
168 : /* Remove any *? and ** from the pattern as they are meaningless */
169 0 : for(p = p2; *p; p++) {
170 0 : while( *p == '*' && (p[1] == '?' ||p[1] == '*')) {
171 0 : memmove(&p[1], &p[2], strlen(&p[2])+1);
172 : }
173 : }
174 :
175 0 : if (p2[0] == '*' && p2[1] == '\0') {
176 0 : TALLOC_FREE(ctx);
177 0 : return true;
178 : }
179 :
180 0 : ret = unix_do_match(p2, s2);
181 0 : TALLOC_FREE(ctx);
182 0 : return ret;
183 : }
|