xref: /illumos-gate/usr/src/common/smbsrv/smb_match.c (revision da6c28aa)
1*da6c28aaSamw /*
2*da6c28aaSamw  * CDDL HEADER START
3*da6c28aaSamw  *
4*da6c28aaSamw  * The contents of this file are subject to the terms of the
5*da6c28aaSamw  * Common Development and Distribution License (the "License").
6*da6c28aaSamw  * You may not use this file except in compliance with the License.
7*da6c28aaSamw  *
8*da6c28aaSamw  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*da6c28aaSamw  * or http://www.opensolaris.org/os/licensing.
10*da6c28aaSamw  * See the License for the specific language governing permissions
11*da6c28aaSamw  * and limitations under the License.
12*da6c28aaSamw  *
13*da6c28aaSamw  * When distributing Covered Code, include this CDDL HEADER in each
14*da6c28aaSamw  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*da6c28aaSamw  * If applicable, add the following below this CDDL HEADER, with the
16*da6c28aaSamw  * fields enclosed by brackets "[]" replaced with your own identifying
17*da6c28aaSamw  * information: Portions Copyright [yyyy] [name of copyright owner]
18*da6c28aaSamw  *
19*da6c28aaSamw  * CDDL HEADER END
20*da6c28aaSamw  */
21*da6c28aaSamw /*
22*da6c28aaSamw  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
23*da6c28aaSamw  * Use is subject to license terms.
24*da6c28aaSamw  */
25*da6c28aaSamw 
26*da6c28aaSamw #pragma ident	"%Z%%M%	%I%	%E% SMI"
27*da6c28aaSamw 
28*da6c28aaSamw #ifndef _KERNEL
29*da6c28aaSamw #include <stdlib.h>
30*da6c28aaSamw #include <string.h>
31*da6c28aaSamw #else
32*da6c28aaSamw #include <sys/types.h>
33*da6c28aaSamw #include <sys/sunddi.h>
34*da6c28aaSamw #endif
35*da6c28aaSamw #include <smbsrv/ctype.h>
36*da6c28aaSamw 
37*da6c28aaSamw 
38*da6c28aaSamw /*
39*da6c28aaSamw  *	c	Any non-special character matches itslef
40*da6c28aaSamw  *	?	Match any character
41*da6c28aaSamw  *	ab	character 'a' followed by character 'b'
42*da6c28aaSamw  *	S	Any string of non-special characters
43*da6c28aaSamw  *	AB	String 'A' followed by string 'B'
44*da6c28aaSamw  *	*	Any String, including the empty string
45*da6c28aaSamw  */
46*da6c28aaSamw int
47*da6c28aaSamw smb_match(char *patn, char *str)
48*da6c28aaSamw {
49*da6c28aaSamw 	for (;;) {
50*da6c28aaSamw 		switch (*patn) {
51*da6c28aaSamw 		case 0:
52*da6c28aaSamw 			return (*str == 0);
53*da6c28aaSamw 
54*da6c28aaSamw 		case '?':
55*da6c28aaSamw 			if (*str != 0) {
56*da6c28aaSamw 				str++;
57*da6c28aaSamw 				patn++;
58*da6c28aaSamw 				continue;
59*da6c28aaSamw 			} else {
60*da6c28aaSamw 				return (0);
61*da6c28aaSamw 			}
62*da6c28aaSamw 			/*NOTREACHED*/
63*da6c28aaSamw 
64*da6c28aaSamw #if 0
65*da6c28aaSamw 		case '[':
66*da6c28aaSamw 			int	invert = 0, clower, cupper;
67*da6c28aaSamw 
68*da6c28aaSamw 			patn++;
69*da6c28aaSamw 			if (*patn == '!') {
70*da6c28aaSamw 				invert = 1;
71*da6c28aaSamw 				patn++;
72*da6c28aaSamw 			}
73*da6c28aaSamw 			for (;;) {
74*da6c28aaSamw 				clower = *patn;
75*da6c28aaSamw 				if (clower == 0)
76*da6c28aaSamw 					break;
77*da6c28aaSamw 				if (clower == ']') {
78*da6c28aaSamw 					patn++;
79*da6c28aaSamw 					break;
80*da6c28aaSamw 				}
81*da6c28aaSamw 				patn++;
82*da6c28aaSamw 				if (*patn == '-') {
83*da6c28aaSamw 					/* range */
84*da6c28aaSamw 					patn++;
85*da6c28aaSamw 					cupper = *patn;
86*da6c28aaSamw 					if (cupper == 0)
87*da6c28aaSamw 						break;
88*da6c28aaSamw 					patn++;
89*da6c28aaSamw 				} else {
90*da6c28aaSamw 					cupper = clower;
91*da6c28aaSamw 				}
92*da6c28aaSamw 				if (*str < clower || cupper < *str)
93*da6c28aaSamw 					continue;
94*da6c28aaSamw 
95*da6c28aaSamw 				/* match */
96*da6c28aaSamw 				if (invert)
97*da6c28aaSamw 					return (0);
98*da6c28aaSamw 
99*da6c28aaSamw 				while (*patn && *patn++ != ']')
100*da6c28aaSamw 					;
101*da6c28aaSamw 				str++;
102*da6c28aaSamw 				continue; /* THIS WON`T WORK */
103*da6c28aaSamw 			}
104*da6c28aaSamw 			if (invert) {
105*da6c28aaSamw 				str++;
106*da6c28aaSamw 				continue;
107*da6c28aaSamw 			}
108*da6c28aaSamw 			return (0);
109*da6c28aaSamw 
110*da6c28aaSamw #endif
111*da6c28aaSamw 
112*da6c28aaSamw 		case '*':
113*da6c28aaSamw 			patn++;
114*da6c28aaSamw 			if (*patn == 0)
115*da6c28aaSamw 				return (1);
116*da6c28aaSamw 
117*da6c28aaSamw #if 0
118*da6c28aaSamw 			if (*patn != '?' && *patn != '*' && *patn != '[') {
119*da6c28aaSamw 				/* accelerate */
120*da6c28aaSamw 				while (*str) {
121*da6c28aaSamw 					if (*str == *patn &&
122*da6c28aaSamw 					    match(patn+1, str+1))
123*da6c28aaSamw 						return (1);
124*da6c28aaSamw 					str++;
125*da6c28aaSamw 				}
126*da6c28aaSamw 				return (0);
127*da6c28aaSamw 			}
128*da6c28aaSamw #endif
129*da6c28aaSamw 
130*da6c28aaSamw 			while (*str) {
131*da6c28aaSamw 				if (smb_match(patn, str))
132*da6c28aaSamw 					return (1);
133*da6c28aaSamw 				str++;
134*da6c28aaSamw 			}
135*da6c28aaSamw 			return (0);
136*da6c28aaSamw 
137*da6c28aaSamw 		default:
138*da6c28aaSamw 			if (*str != *patn)
139*da6c28aaSamw 				return (0);
140*da6c28aaSamw 			str++;
141*da6c28aaSamw 			patn++;
142*da6c28aaSamw 			continue;
143*da6c28aaSamw 		}
144*da6c28aaSamw 	}
145*da6c28aaSamw }
146*da6c28aaSamw 
147*da6c28aaSamw int
148*da6c28aaSamw smb_match83(char *patn, char *str83)
149*da6c28aaSamw {
150*da6c28aaSamw 	int	avail;
151*da6c28aaSamw 	char	*ptr;
152*da6c28aaSamw 	char	name83[14];
153*da6c28aaSamw 
154*da6c28aaSamw 	ptr = name83;
155*da6c28aaSamw 	for (avail = 8; (avail > 0) && (*patn != '.') && (*patn != 0);
156*da6c28aaSamw 	    avail--) {
157*da6c28aaSamw 		*(ptr++) = *(patn++);
158*da6c28aaSamw 	}
159*da6c28aaSamw 	while (avail--)
160*da6c28aaSamw 		*(ptr++) = ' ';
161*da6c28aaSamw 	*(ptr++) = '.';
162*da6c28aaSamw 
163*da6c28aaSamw 	if (*patn == '.')
164*da6c28aaSamw 		patn++;
165*da6c28aaSamw 	else if (*patn != 0)
166*da6c28aaSamw 		return (0);
167*da6c28aaSamw 
168*da6c28aaSamw 	for (avail = 3; (avail > 0) && (*patn != 0); avail--) {
169*da6c28aaSamw 		*(ptr++) = *(patn++);
170*da6c28aaSamw 	}
171*da6c28aaSamw 	if (*patn != 0)
172*da6c28aaSamw 		return (0);
173*da6c28aaSamw 
174*da6c28aaSamw 	while (avail--)
175*da6c28aaSamw 		*(ptr++) = ' ';
176*da6c28aaSamw 	*ptr = 0;
177*da6c28aaSamw 
178*da6c28aaSamw 	return (smb_match_ci(name83, str83));
179*da6c28aaSamw }
180*da6c28aaSamw 
181*da6c28aaSamw 
182*da6c28aaSamw 
183*da6c28aaSamw int
184*da6c28aaSamw smb_match_ci(char *patn, char *str)
185*da6c28aaSamw {
186*da6c28aaSamw 	/*
187*da6c28aaSamw 	 * "<" is a special pattern that matches only those names that do
188*da6c28aaSamw 	 * NOT have an extension. "." and ".." are ok.
189*da6c28aaSamw 	 */
190*da6c28aaSamw 	if (strcmp(patn, "<") == 0) {
191*da6c28aaSamw 		if ((strcmp(str, ".") == 0) || (strcmp(str, "..") == 0))
192*da6c28aaSamw 			return (1);
193*da6c28aaSamw 		if (strchr(str, '.') == 0)
194*da6c28aaSamw 			return (1);
195*da6c28aaSamw 		return (0);
196*da6c28aaSamw 	}
197*da6c28aaSamw 	for (;;) {
198*da6c28aaSamw 		switch (*patn) {
199*da6c28aaSamw 		case 0:
200*da6c28aaSamw 			return (*str == 0);
201*da6c28aaSamw 
202*da6c28aaSamw 		case '?':
203*da6c28aaSamw 			if (*str != 0) {
204*da6c28aaSamw 				str++;
205*da6c28aaSamw 				patn++;
206*da6c28aaSamw 				continue;
207*da6c28aaSamw 			} else {
208*da6c28aaSamw 				return (0);
209*da6c28aaSamw 			}
210*da6c28aaSamw 			/*NOTREACHED*/
211*da6c28aaSamw 
212*da6c28aaSamw 
213*da6c28aaSamw 		case '*':
214*da6c28aaSamw 			patn++;
215*da6c28aaSamw 			if (*patn == 0)
216*da6c28aaSamw 				return (1);
217*da6c28aaSamw 
218*da6c28aaSamw 			while (*str) {
219*da6c28aaSamw 				if (smb_match_ci(patn, str))
220*da6c28aaSamw 					return (1);
221*da6c28aaSamw 				str++;
222*da6c28aaSamw 			}
223*da6c28aaSamw 			return (0);
224*da6c28aaSamw 
225*da6c28aaSamw 		default:
226*da6c28aaSamw 			if (*str != *patn) {
227*da6c28aaSamw 				int	c1 = *str;
228*da6c28aaSamw 				int	c2 = *patn;
229*da6c28aaSamw 
230*da6c28aaSamw 				c1 = mts_tolower(c1);
231*da6c28aaSamw 				c2 = mts_tolower(c2);
232*da6c28aaSamw 				if (c1 != c2)
233*da6c28aaSamw 					return (0);
234*da6c28aaSamw 			}
235*da6c28aaSamw 			str++;
236*da6c28aaSamw 			patn++;
237*da6c28aaSamw 			continue;
238*da6c28aaSamw 		}
239*da6c28aaSamw 	}
240*da6c28aaSamw 	/* NOT REACHED */
241*da6c28aaSamw }
242