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