Home | History | Annotate | Download | only in smbsrv
      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  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
     23  * Use is subject to license terms.
     24  */
     25 
     26 #pragma ident	"%Z%%M%	%I%	%E% SMI"
     27 
     28 #ifndef _KERNEL
     29 #include <stdlib.h>
     30 #include <string.h>
     31 #else
     32 #include <sys/types.h>
     33 #include <sys/sunddi.h>
     34 #endif
     35 #include <smbsrv/ctype.h>
     36 
     37 
     38 /*
     39  *	c	Any non-special character matches itslef
     40  *	?	Match any character
     41  *	ab	character 'a' followed by character 'b'
     42  *	S	Any string of non-special characters
     43  *	AB	String 'A' followed by string 'B'
     44  *	*	Any String, including the empty string
     45  */
     46 int
     47 smb_match(char *patn, char *str)
     48 {
     49 	for (;;) {
     50 		switch (*patn) {
     51 		case 0:
     52 			return (*str == 0);
     53 
     54 		case '?':
     55 			if (*str != 0) {
     56 				str++;
     57 				patn++;
     58 				continue;
     59 			} else {
     60 				return (0);
     61 			}
     62 			/*NOTREACHED*/
     63 
     64 #if 0
     65 		case '[':
     66 			int	invert = 0, clower, cupper;
     67 
     68 			patn++;
     69 			if (*patn == '!') {
     70 				invert = 1;
     71 				patn++;
     72 			}
     73 			for (;;) {
     74 				clower = *patn;
     75 				if (clower == 0)
     76 					break;
     77 				if (clower == ']') {
     78 					patn++;
     79 					break;
     80 				}
     81 				patn++;
     82 				if (*patn == '-') {
     83 					/* range */
     84 					patn++;
     85 					cupper = *patn;
     86 					if (cupper == 0)
     87 						break;
     88 					patn++;
     89 				} else {
     90 					cupper = clower;
     91 				}
     92 				if (*str < clower || cupper < *str)
     93 					continue;
     94 
     95 				/* match */
     96 				if (invert)
     97 					return (0);
     98 
     99 				while (*patn && *patn++ != ']')
    100 					;
    101 				str++;
    102 				continue; /* THIS WON`T WORK */
    103 			}
    104 			if (invert) {
    105 				str++;
    106 				continue;
    107 			}
    108 			return (0);
    109 
    110 #endif
    111 
    112 		case '*':
    113 			patn++;
    114 			if (*patn == 0)
    115 				return (1);
    116 
    117 #if 0
    118 			if (*patn != '?' && *patn != '*' && *patn != '[') {
    119 				/* accelerate */
    120 				while (*str) {
    121 					if (*str == *patn &&
    122 					    match(patn+1, str+1))
    123 						return (1);
    124 					str++;
    125 				}
    126 				return (0);
    127 			}
    128 #endif
    129 
    130 			while (*str) {
    131 				if (smb_match(patn, str))
    132 					return (1);
    133 				str++;
    134 			}
    135 			return (0);
    136 
    137 		default:
    138 			if (*str != *patn)
    139 				return (0);
    140 			str++;
    141 			patn++;
    142 			continue;
    143 		}
    144 	}
    145 }
    146 
    147 int
    148 smb_match83(char *patn, char *str83)
    149 {
    150 	int	avail;
    151 	char	*ptr;
    152 	char	name83[14];
    153 
    154 	ptr = name83;
    155 	for (avail = 8; (avail > 0) && (*patn != '.') && (*patn != 0);
    156 	    avail--) {
    157 		*(ptr++) = *(patn++);
    158 	}
    159 	while (avail--)
    160 		*(ptr++) = ' ';
    161 	*(ptr++) = '.';
    162 
    163 	if (*patn == '.')
    164 		patn++;
    165 	else if (*patn != 0)
    166 		return (0);
    167 
    168 	for (avail = 3; (avail > 0) && (*patn != 0); avail--) {
    169 		*(ptr++) = *(patn++);
    170 	}
    171 	if (*patn != 0)
    172 		return (0);
    173 
    174 	while (avail--)
    175 		*(ptr++) = ' ';
    176 	*ptr = 0;
    177 
    178 	return (smb_match_ci(name83, str83));
    179 }
    180 
    181 
    182 
    183 int
    184 smb_match_ci(char *patn, char *str)
    185 {
    186 	/*
    187 	 * "<" is a special pattern that matches only those names that do
    188 	 * NOT have an extension. "." and ".." are ok.
    189 	 */
    190 	if (strcmp(patn, "<") == 0) {
    191 		if ((strcmp(str, ".") == 0) || (strcmp(str, "..") == 0))
    192 			return (1);
    193 		if (strchr(str, '.') == 0)
    194 			return (1);
    195 		return (0);
    196 	}
    197 	for (;;) {
    198 		switch (*patn) {
    199 		case 0:
    200 			return (*str == 0);
    201 
    202 		case '?':
    203 			if (*str != 0) {
    204 				str++;
    205 				patn++;
    206 				continue;
    207 			} else {
    208 				return (0);
    209 			}
    210 			/*NOTREACHED*/
    211 
    212 
    213 		case '*':
    214 			patn++;
    215 			if (*patn == 0)
    216 				return (1);
    217 
    218 			while (*str) {
    219 				if (smb_match_ci(patn, str))
    220 					return (1);
    221 				str++;
    222 			}
    223 			return (0);
    224 
    225 		default:
    226 			if (*str != *patn) {
    227 				int	c1 = *str;
    228 				int	c2 = *patn;
    229 
    230 				c1 = mts_tolower(c1);
    231 				c2 = mts_tolower(c2);
    232 				if (c1 != c2)
    233 					return (0);
    234 			}
    235 			str++;
    236 			patn++;
    237 			continue;
    238 		}
    239 	}
    240 	/* NOT REACHED */
    241 }
    242