da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * CDDL HEADER START
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * The contents of this file are subject to the terms of the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Common Development and Distribution License (the "License").
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * You may not use this file except in compliance with the License.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * See the License for the specific language governing permissions
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * and limitations under the License.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * When distributing Covered Code, include this CDDL HEADER in each
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * If applicable, add the following below this CDDL HEADER, with the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * fields enclosed by brackets "[]" replaced with your own identifying
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * information: Portions Copyright [yyyy] [name of copyright owner]
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * CDDL HEADER END
148c5f43199ca0b43fc8e3b643aab11cd66ea327Alan Wright * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross * Copyright 2014 Nexenta Systems, Inc. All rights reserved.
3a6c5f83d4cb79e49561f3fad2b016450f0e6fecAlan Wright * Maximum recursion depth for the wildcard match functions.
3a6c5f83d4cb79e49561f3fad2b016450f0e6fecAlan Wright * These functions may recurse when processing a '*'.
c13be35a2c14be5433f5d23a6c4f84e66439b7b6Gordon Rossstatic int smb_match_private(const char *, const char *, struct match_priv *);
c13be35a2c14be5433f5d23a6c4f84e66439b7b6Gordon Ross * Return B_TRUE if pattern contains wildcards
c13be35a2c14be5433f5d23a6c4f84e66439b7b6Gordon Ross return (strpbrk(pattern, smb_wildcards) != NULL);
c13be35a2c14be5433f5d23a6c4f84e66439b7b6Gordon Ross * NT-compatible file name match function. [MS-FSA 3.1.4.4]
c13be35a2c14be5433f5d23a6c4f84e66439b7b6Gordon Ross * Returns TRUE if there is a match.
c13be35a2c14be5433f5d23a6c4f84e66439b7b6Gordon Rosssmb_match(const char *p, const char *s, boolean_t ci)
c13be35a2c14be5433f5d23a6c4f84e66439b7b6Gordon Ross * Optimize common patterns that match everything:
c13be35a2c14be5433f5d23a6c4f84e66439b7b6Gordon Ross * ("*", "<\"*") That second one is the converted
c13be35a2c14be5433f5d23a6c4f84e66439b7b6Gordon Ross * form of "*.*" after smb_convert_wildcards() does
c13be35a2c14be5433f5d23a6c4f84e66439b7b6Gordon Ross * its work on it for an old LM client. Note that a
c13be35a2c14be5433f5d23a6c4f84e66439b7b6Gordon Ross * plain "*.*" never gets this far.
c13be35a2c14be5433f5d23a6c4f84e66439b7b6Gordon Ross if (p[0] == '<' && p[1] == '\"' && p[2] == '*' && p[3] == '\0')
c13be35a2c14be5433f5d23a6c4f84e66439b7b6Gordon Ross * Match string ".." as if "." This is Windows behavior
c13be35a2c14be5433f5d23a6c4f84e66439b7b6Gordon Ross * (not mentioned in MS-FSA) that was determined using
c13be35a2c14be5433f5d23a6c4f84e66439b7b6Gordon Ross * the Samba masktest program.
c13be35a2c14be5433f5d23a6c4f84e66439b7b6Gordon Ross * Optimize simple patterns (no wildcards)
c13be35a2c14be5433f5d23a6c4f84e66439b7b6Gordon Ross return (rc == 0);
c13be35a2c14be5433f5d23a6c4f84e66439b7b6Gordon Ross * Do real wildcard match.
c13be35a2c14be5433f5d23a6c4f84e66439b7b6Gordon Ross * Internal file name match function. [MS-FSA 3.1.4.4]
c13be35a2c14be5433f5d23a6c4f84e66439b7b6Gordon Ross * This does the full expression evaluation.
c13be35a2c14be5433f5d23a6c4f84e66439b7b6Gordon Ross * '*' matches zero of more of any characters.
c13be35a2c14be5433f5d23a6c4f84e66439b7b6Gordon Ross * '?' matches exactly one of any character.
c13be35a2c14be5433f5d23a6c4f84e66439b7b6Gordon Ross * '<' matches any string up through the last dot or EOS.
c13be35a2c14be5433f5d23a6c4f84e66439b7b6Gordon Ross * '>' matches any one char not a dot, dot at EOS, or EOS.
c13be35a2c14be5433f5d23a6c4f84e66439b7b6Gordon Ross * '"' matches a dot, or EOS.
c13be35a2c14be5433f5d23a6c4f84e66439b7b6Gordon Ross * 0 no-match
c13be35a2c14be5433f5d23a6c4f84e66439b7b6Gordon Ross * -1 no-match, error (illseq, too many wildcards in pattern, ...)
c13be35a2c14be5433f5d23a6c4f84e66439b7b6Gordon Ross * Note that both the pattern and the string are in multi-byte form.
c13be35a2c14be5433f5d23a6c4f84e66439b7b6Gordon Ross * The implementation of this is quite tricky. First note that it
c13be35a2c14be5433f5d23a6c4f84e66439b7b6Gordon Ross * can call itself recursively, though it limits the recursion depth.
c13be35a2c14be5433f5d23a6c4f84e66439b7b6Gordon Ross * Each switch case in the while loop can basically do one of three
c13be35a2c14be5433f5d23a6c4f84e66439b7b6Gordon Ross * things: (a) return "Yes, match", (b) return "not a match", or
c13be35a2c14be5433f5d23a6c4f84e66439b7b6Gordon Ross * continue processing the match pattern. The cases for wildcards
c13be35a2c14be5433f5d23a6c4f84e66439b7b6Gordon Ross * that may match a variable number of characters ('*' and '<') do
c13be35a2c14be5433f5d23a6c4f84e66439b7b6Gordon Ross * recursive calls, looking for a match of the remaining pattern,
c13be35a2c14be5433f5d23a6c4f84e66439b7b6Gordon Ross * starting at the current and later positions in the string.
c13be35a2c14be5433f5d23a6c4f84e66439b7b6Gordon Rosssmb_match_private(const char *pat, const char *str, struct match_priv *priv)
c13be35a2c14be5433f5d23a6c4f84e66439b7b6Gordon Ross smb_wchar_t wcpat, wcstr; /* current wchar in pat, str */
c13be35a2c14be5433f5d23a6c4f84e66439b7b6Gordon Ross return (-1);
c13be35a2c14be5433f5d23a6c4f84e66439b7b6Gordon Ross * Advance over one multi-byte char, used in cases like
c13be35a2c14be5433f5d23a6c4f84e66439b7b6Gordon Ross * '?' or '>' where "match one character" needs to be
c13be35a2c14be5433f5d23a6c4f84e66439b7b6Gordon Ross * interpreted as "match one multi-byte sequence".
c13be35a2c14be5433f5d23a6c4f84e66439b7b6Gordon Ross * This macro needs to consume the semicolon following
c13be35a2c14be5433f5d23a6c4f84e66439b7b6Gordon Ross * each place it appears, so this is carefully written
c13be35a2c14be5433f5d23a6c4f84e66439b7b6Gordon Ross * as an if/else with a missing semicolon at the end.
c13be35a2c14be5433f5d23a6c4f84e66439b7b6Gordon Ross if ((nbstr = smb_mbtowc(NULL, str, MTS_MB_CHAR_MAX)) < 1) \
c13be35a2c14be5433f5d23a6c4f84e66439b7b6Gordon Ross return (-1); \
c13be35a2c14be5433f5d23a6c4f84e66439b7b6Gordon Ross * We move pat forward in each switch case so that the
c13be35a2c14be5433f5d23a6c4f84e66439b7b6Gordon Ross * default case can move it by a whole multi-byte seq.
c13be35a2c14be5433f5d23a6c4f84e66439b7b6Gordon Ross /* EOS: no-match */
c13be35a2c14be5433f5d23a6c4f84e66439b7b6Gordon Ross /* Optimize '*' at end of pattern. */
c13be35a2c14be5433f5d23a6c4f84e66439b7b6Gordon Ross case '<': /* any string up through the last dot or EOS */
c13be35a2c14be5433f5d23a6c4f84e66439b7b6Gordon Ross case '>': /* anything not a dot, dot at EOS, or EOS */
c13be35a2c14be5433f5d23a6c4f84e66439b7b6Gordon Ross /* dot at EOS */
c13be35a2c14be5433f5d23a6c4f84e66439b7b6Gordon Ross /* dot NOT at EOS: no-match */
c13be35a2c14be5433f5d23a6c4f84e66439b7b6Gordon Ross /* something not a dot */
c13be35a2c14be5433f5d23a6c4f84e66439b7b6Gordon Ross /* something else: no-match */
c13be35a2c14be5433f5d23a6c4f84e66439b7b6Gordon Ross default: /* not a wildcard */
c13be35a2c14be5433f5d23a6c4f84e66439b7b6Gordon Ross nbpat = smb_mbtowc(&wcpat, pat, MTS_MB_CHAR_MAX);
c13be35a2c14be5433f5d23a6c4f84e66439b7b6Gordon Ross nbstr = smb_mbtowc(&wcstr, str, MTS_MB_CHAR_MAX);
c13be35a2c14be5433f5d23a6c4f84e66439b7b6Gordon Ross /* make sure we advance */
c13be35a2c14be5433f5d23a6c4f84e66439b7b6Gordon Ross return (-1);
c13be35a2c14be5433f5d23a6c4f84e66439b7b6Gordon Ross return (0); /* no-match */