Replace UCB fnmatch.c with a non-recursive version written by

William A. Rowe Jr.
This commit is contained in:
Todd C. Miller
2011-11-29 14:57:08 -05:00
parent dd2fcf16d6
commit e9e4a84528
3 changed files with 495 additions and 256 deletions

View File

@@ -1,39 +1,72 @@
/*
* Copyright (c) 2008, 2010 Todd C. Miller <Todd.Miller@courtesan.com>
* Copyright (c) 1989, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Guido van Rossum.
*
/* $OpenBSD: fnmatch.c,v 1.15 2011/02/10 21:31:59 stsp Exp $ */
/* Copyright (c) 2011, VMware, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the VMware, Inc. nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ARE DISCLAIMED. IN NO EVENT SHALL VMWARE, INC. OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Function fnmatch() as specified in POSIX 1003.2-1992, section B.6.
* Compares a filename or pathname to a pattern.
/* Authored by William A. Rowe Jr. <wrowe; apache.org, vmware.com>, April 2011
*
* Derived from The Open Group Base Specifications Issue 7, IEEE Std 1003.1-2008
* as described in;
* http://pubs.opengroup.org/onlinepubs/9699919799/functions/fnmatch.html
*
* Filename pattern matches defined in section 2.13, "Pattern Matching Notation"
* from chapter 2. "Shell Command Language"
* http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_13
* where; 1. A bracket expression starting with an unquoted <circumflex> '^'
* character CONTINUES to specify a non-matching list; 2. an explicit <period> '.'
* in a bracket expression matching list, e.g. "[.abc]" does NOT match a leading
* <period> in a filename; 3. a <left-square-bracket> '[' which does not introduce
* a valid bracket expression is treated as an ordinary character; 4. a differing
* number of consecutive slashes within pattern and string will NOT match;
* 5. a trailing '\' in FNM_ESCAPE mode is treated as an ordinary '\' character.
*
* Bracket expansion defined in section 9.3.5, "RE Bracket Expression",
* from chapter 9, "Regular Expressions"
* http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap09.html#tag_09_03_05
* with no support for collating symbols, equivalence class expressions or
* character class expressions. A partial range expression with a leading
* hyphen following a valid range expression will match only the ordinary
* <hyphen> and the ending character (e.g. "[a-m-z]" will match characters
* 'a' through 'm', a <hyphen> '-', or a 'z').
*
* Supports BSD extensions FNM_LEADING_DIR to match pattern to the end of one
* path segment of string, and FNM_CASEFOLD to ignore alpha case.
*
* NOTE: Only POSIX/C single byte locales are correctly supported at this time.
* Notably, non-POSIX locales with FNM_CASEFOLD produce undefined results,
* particularly in ranges of mixed case (e.g. "[A-z]") or spanning alpha and
* nonalpha characters within a range.
*
* XXX comments below indicate porting required for multi-byte character sets
* and non-POSIX locale collation orders; requires mbr* APIs to track shift
* state of pattern and string (rewinding pattern and string repeatedly).
*
* Certain parts of the code assume 0x00-0x3F are unique with any MBCS (e.g.
* UTF-8, SHIFT-JIS, etc). Any implementation allowing '\' as an alternate
* path delimiter must be aware that 0x5C is NOT unique within SHIFT-JIS.
*/
#include <config.h>
@@ -48,200 +81,33 @@
#ifdef HAVE_STRINGS_H
# include <strings.h>
#endif /* HAVE_STRINGS_H */
#include <limits.h>
#include "missing.h"
#include "compat/charclass.h"
#include "compat/fnmatch.h"
#undef EOS
#define EOS '\0'
#define RANGE_MATCH 1
#define RANGE_NOMATCH 0
#define RANGE_ERROR (-1)
#if defined(LIBC_SCCS) && !defined(lint)
__unused static const char rcsid[] = "$OpenBSD: fnmatch.c,v 1.6 1998/03/19 00:29:59 millert Exp $";
#endif /* LIBC_SCCS and not lint */
static int rangematch(const char *, int, int, char **);
static int classmatch(const char *, int, int, const char **);
int
rpl_fnmatch(const char *pattern, const char *string, int flags)
{
const char *stringstart;
char *newp;
char c, test;
for (stringstart = string;;)
switch (c = *pattern++) {
case EOS:
if (ISSET(flags, FNM_LEADING_DIR) && *string == '/')
return 0;
return *string == EOS ? 0 : FNM_NOMATCH;
case '?':
if (*string == EOS)
return FNM_NOMATCH;
if (*string == '/' && ISSET(flags, FNM_PATHNAME))
return FNM_NOMATCH;
if (*string == '.' && ISSET(flags, FNM_PERIOD) &&
(string == stringstart ||
(ISSET(flags, FNM_PATHNAME) && *(string - 1) == '/')))
return FNM_NOMATCH;
++string;
break;
case '*':
c = *pattern;
/* Collapse multiple stars. */
while (c == '*')
c = *++pattern;
if (*string == '.' && ISSET(flags, FNM_PERIOD) &&
(string == stringstart ||
(ISSET(flags, FNM_PATHNAME) && *(string - 1) == '/')))
return FNM_NOMATCH;
/* Optimize for pattern with * at end or before /. */
if (c == EOS) {
if (ISSET(flags, FNM_PATHNAME))
return (ISSET(flags, FNM_LEADING_DIR) ||
strchr(string, '/') == NULL ?
0 : FNM_NOMATCH);
else
return 0;
} else if (c == '/' && ISSET(flags, FNM_PATHNAME)) {
if ((string = strchr(string, '/')) == NULL)
return FNM_NOMATCH;
break;
}
/* General case, use recursion. */
while ((test = *string) != EOS) {
if (!fnmatch(pattern, string, flags & ~FNM_PERIOD))
return 0;
if (test == '/' && ISSET(flags, FNM_PATHNAME))
break;
++string;
}
return FNM_NOMATCH;
case '[':
if (*string == EOS)
return FNM_NOMATCH;
if (*string == '/' && ISSET(flags, FNM_PATHNAME))
return FNM_NOMATCH;
if (*string == '.' && ISSET(flags, FNM_PERIOD) &&
(string == stringstart ||
(ISSET(flags, FNM_PATHNAME) && *(string - 1) == '/')))
return FNM_NOMATCH;
switch (rangematch(pattern, *string, flags, &newp)) {
case RANGE_ERROR:
/* not a good range, treat as normal text */
goto normal;
case RANGE_MATCH:
pattern = newp;
break;
case RANGE_NOMATCH:
return FNM_NOMATCH;
}
++string;
break;
case '\\':
if (!ISSET(flags, FNM_NOESCAPE)) {
if ((c = *pattern++) == EOS) {
c = '\\';
--pattern;
}
}
/* FALLTHROUGH */
default:
normal:
if (c != *string && !(ISSET(flags, FNM_CASEFOLD) &&
(tolower((unsigned char)c) ==
tolower((unsigned char)*string))))
return FNM_NOMATCH;
++string;
break;
}
/* NOTREACHED */
}
static int
rangematch(const char *pattern, int test, int flags, char **newp)
classmatch(const char *pattern, char test, int foldcase, const char **ep)
{
int negate, ok, rv;
char c, c2;
/*
* A bracket expression starting with an unquoted circumflex
* character produces unspecified results (IEEE 1003.2-1992,
* 3.13.2). This implementation treats it like '!', for
* consistency with the regular expression syntax.
* J.T. Conklin (conklin@ngai.kaleida.com)
*/
if ((negate = (*pattern == '!' || *pattern == '^')))
++pattern;
if (ISSET(flags, FNM_CASEFOLD))
test = tolower(test);
/*
* A right bracket shall lose its special meaning and represent
* itself in a bracket expression if it occurs first in the list.
* -- POSIX.2 2.8.3.2
*/
ok = 0;
c = *pattern++;
do {
if (c == '[' && *pattern == ':') {
do {
rv = classmatch(pattern + 1, test,
(flags & FNM_CASEFOLD), &pattern);
if (rv == RANGE_MATCH)
ok = 1;
c = *pattern++;
} while (rv != RANGE_ERROR && c == '[' && *pattern == ':');
if (c == ']')
break;
}
if (c == '\\' && !ISSET(flags, FNM_NOESCAPE))
c = *pattern++;
if (c == EOS)
return RANGE_ERROR;
if (c == '/' && ISSET(flags, FNM_PATHNAME))
return RANGE_NOMATCH;
if (ISSET(flags, FNM_CASEFOLD))
c = tolower((unsigned char)c);
if (*pattern == '-'
&& (c2 = *(pattern+1)) != EOS && c2 != ']') {
pattern += 2;
if (c2 == '\\' && !ISSET(flags, FNM_NOESCAPE))
c2 = *pattern++;
if (c2 == EOS)
return RANGE_ERROR;
if (ISSET(flags, FNM_CASEFOLD))
c2 = tolower((unsigned char)c2);
if (c <= test && test <= c2)
ok = 1;
} else if (c == test)
ok = 1;
} while ((c = *pattern++) != ']');
*newp = (char *)pattern;
return ok == negate ? RANGE_NOMATCH : RANGE_MATCH;
}
static int
classmatch(const char *pattern, int test, int foldcase, const char **ep)
{
struct cclass *cc;
const char * const mismatch = pattern;
const char *colon;
size_t len;
struct cclass *cc;
int rval = RANGE_NOMATCH;
size_t len;
if (pattern[0] != '[' || pattern[1] != ':') {
*ep = mismatch;
return RANGE_ERROR;
}
pattern += 2;
if ((colon = strchr(pattern, ':')) == NULL || colon[1] != ']') {
*ep = pattern - 2;
*ep = mismatch;
return RANGE_ERROR;
}
*ep = colon + 2;
@@ -251,15 +117,356 @@ classmatch(const char *pattern, int test, int foldcase, const char **ep)
pattern = "lower:]";
for (cc = cclasses; cc->name != NULL; cc++) {
if (!strncmp(pattern, cc->name, len) && cc->name[len] == '\0') {
if (cc->isctype(test))
if (cc->isctype((unsigned char)test))
rval = RANGE_MATCH;
break;
}
}
if (cc->name == NULL) {
/* invalid character class, return EOS */
*ep = colon + strlen(colon);
/* invalid character class, treat as normal text */
*ep = mismatch;
rval = RANGE_ERROR;
}
return rval;
}
/* Most MBCS/collation/case issues handled here. Wildcard '*' is not handled.
* EOS '\0' and the FNM_PATHNAME '/' delimiters are not advanced over,
* however the "\/" sequence is advanced to '/'.
*
* Both pattern and string are **char to support pointer increment of arbitrary
* multibyte characters for the given locale, in a later iteration of this code
*/
static int fnmatch_ch(const char **pattern, const char **string, int flags)
{
const char * const mismatch = *pattern;
const int nocase = !!(flags & FNM_CASEFOLD);
const int escape = !(flags & FNM_NOESCAPE);
const int slash = !!(flags & FNM_PATHNAME);
int result = FNM_NOMATCH;
const char *startch;
int negate;
if (**pattern == '[')
{
++*pattern;
/* Handle negation, either leading ! or ^ operators (never both) */
negate = ((**pattern == '!') || (**pattern == '^'));
if (negate)
++*pattern;
/* ']' is an ordinary character at the start of the range pattern */
if (**pattern == ']')
goto leadingclosebrace;
while (**pattern)
{
if (**pattern == ']') {
++*pattern;
/* XXX: Fix for MBCS character width */
++*string;
return (result ^ negate);
}
if (escape && (**pattern == '\\')) {
++*pattern;
/* Patterns must be terminated with ']', not EOS */
if (!**pattern)
break;
}
/* Patterns must be terminated with ']' not '/' */
if (slash && (**pattern == '/'))
break;
/* Match character classes. */
if (classmatch(*pattern, **string, nocase, pattern)
== RANGE_MATCH) {
result = 0;
continue;
}
leadingclosebrace:
/* Look at only well-formed range patterns;
* "x-]" is not allowed unless escaped ("x-\]")
* XXX: Fix for locale/MBCS character width
*/
if (((*pattern)[1] == '-') && ((*pattern)[2] != ']'))
{
startch = *pattern;
*pattern += (escape && ((*pattern)[2] == '\\')) ? 3 : 2;
/* NOT a properly balanced [expr] pattern, EOS terminated
* or ranges containing a slash in FNM_PATHNAME mode pattern
* fall out to to the rewind and test '[' literal code path
*/
if (!**pattern || (slash && (**pattern == '/')))
break;
/* XXX: handle locale/MBCS comparison, advance by MBCS char width */
if ((**string >= *startch) && (**string <= **pattern))
result = 0;
else if (nocase && (isupper(**string) || isupper(*startch)
|| isupper(**pattern))
&& (tolower(**string) >= tolower(*startch))
&& (tolower(**string) <= tolower(**pattern)))
result = 0;
++*pattern;
continue;
}
/* XXX: handle locale/MBCS comparison, advance by MBCS char width */
if ((**string == **pattern))
result = 0;
else if (nocase && (isupper(**string) || isupper(**pattern))
&& (tolower(**string) == tolower(**pattern)))
result = 0;
++*pattern;
}
/* NOT a properly balanced [expr] pattern; Rewind
* and reset result to test '[' literal
*/
*pattern = mismatch;
result = FNM_NOMATCH;
}
else if (**pattern == '?') {
/* Optimize '?' match before unescaping **pattern */
if (!**string || (slash && (**string == '/')))
return FNM_NOMATCH;
result = 0;
goto fnmatch_ch_success;
}
else if (escape && (**pattern == '\\') && (*pattern)[1]) {
++*pattern;
}
/* XXX: handle locale/MBCS comparison, advance by the MBCS char width */
if (**string == **pattern)
result = 0;
else if (nocase && (isupper(**string) || isupper(**pattern))
&& (tolower(**string) == tolower(**pattern)))
result = 0;
/* Refuse to advance over trailing slash or nulls
*/
if (!**string || !**pattern || (slash && ((**string == '/') || (**pattern == '/'))))
return result;
fnmatch_ch_success:
++*pattern;
++*string;
return result;
}
int rpl_fnmatch(const char *pattern, const char *string, int flags)
{
static const char dummystring[2] = {' ', 0};
const int escape = !(flags & FNM_NOESCAPE);
const int slash = !!(flags & FNM_PATHNAME);
const int leading_dir = !!(flags & FNM_LEADING_DIR);
const char *strendseg;
const char *dummyptr;
const char *matchptr;
int wild;
/* For '*' wild processing only; surpress 'used before initialization'
* warnings with dummy initialization values;
*/
const char *strstartseg = NULL;
const char *mismatch = NULL;
int matchlen = 0;
if (strlen(pattern) > PATH_MAX || strlen(string) > PATH_MAX)
return FNM_NOMATCH;
if (*pattern == '*')
goto firstsegment;
while (*pattern && *string)
{
/* Pre-decode "\/" which has no special significance, and
* match balanced slashes, starting a new segment pattern
*/
if (slash && escape && (*pattern == '\\') && (pattern[1] == '/'))
++pattern;
if (slash && (*pattern == '/') && (*string == '/')) {
++pattern;
++string;
}
firstsegment:
/* At the beginning of each segment, validate leading period behavior.
*/
if ((flags & FNM_PERIOD) && (*string == '.'))
{
if (*pattern == '.')
++pattern;
else if (escape && (*pattern == '\\') && (pattern[1] == '.'))
pattern += 2;
else
return FNM_NOMATCH;
++string;
}
/* Determine the end of string segment
*
* Presumes '/' character is unique, not composite in any MBCS encoding
*/
if (slash) {
strendseg = strchr(string, '/');
if (!strendseg)
strendseg = strchr(string, '\0');
}
else {
strendseg = strchr(string, '\0');
}
/* Allow pattern '*' to be consumed even with no remaining string to match
*/
while (*pattern)
{
if ((string > strendseg)
|| ((string == strendseg) && (*pattern != '*')))
break;
if (slash && ((*pattern == '/')
|| (escape && (*pattern == '\\')
&& (pattern[1] == '/'))))
break;
/* Reduce groups of '*' and '?' to n '?' matches
* followed by one '*' test for simplicity
*/
for (wild = 0; ((*pattern == '*') || (*pattern == '?')); ++pattern)
{
if (*pattern == '*') {
wild = 1;
}
else if (string < strendseg) { /* && (*pattern == '?') */
/* XXX: Advance 1 char for MBCS locale */
++string;
}
else { /* (string >= strendseg) && (*pattern == '?') */
return FNM_NOMATCH;
}
}
if (wild)
{
strstartseg = string;
mismatch = pattern;
/* Count fixed (non '*') char matches remaining in pattern
* excluding '/' (or "\/") and '*'
*/
for (matchptr = pattern, matchlen = 0; 1; ++matchlen)
{
if ((*matchptr == '\0')
|| (slash && ((*matchptr == '/')
|| (escape && (*matchptr == '\\')
&& (matchptr[1] == '/')))))
{
/* Compare precisely this many trailing string chars,
* the resulting match needs no wildcard loop
*/
/* XXX: Adjust for MBCS */
if (string + matchlen > strendseg)
return FNM_NOMATCH;
string = strendseg - matchlen;
wild = 0;
break;
}
if (*matchptr == '*')
{
/* Ensure at least this many trailing string chars remain
* for the first comparison
*/
/* XXX: Adjust for MBCS */
if (string + matchlen > strendseg)
return FNM_NOMATCH;
/* Begin first wild comparison at the current position */
break;
}
/* Skip forward in pattern by a single character match
* Use a dummy fnmatch_ch() test to count one "[range]" escape
*/
/* XXX: Adjust for MBCS */
if (escape && (*matchptr == '\\') && matchptr[1]) {
matchptr += 2;
}
else if (*matchptr == '[') {
dummyptr = dummystring;
fnmatch_ch(&matchptr, &dummyptr, flags);
}
else {
++matchptr;
}
}
}
/* Incrementally match string against the pattern
*/
while (*pattern && (string < strendseg))
{
/* Success; begin a new wild pattern search
*/
if (*pattern == '*')
break;
if (slash && ((*string == '/')
|| (*pattern == '/')
|| (escape && (*pattern == '\\')
&& (pattern[1] == '/'))))
break;
/* Compare ch's (the pattern is advanced over "\/" to the '/',
* but slashes will mismatch, and are not consumed)
*/
if (!fnmatch_ch(&pattern, &string, flags))
continue;
/* Failed to match, loop against next char offset of string segment
* until not enough string chars remain to match the fixed pattern
*/
if (wild) {
/* XXX: Advance 1 char for MBCS locale */
string = ++strstartseg;
if (string + matchlen > strendseg)
return FNM_NOMATCH;
pattern = mismatch;
continue;
}
else
return FNM_NOMATCH;
}
}
if (*string && !((slash || leading_dir) && (*string == '/')))
return FNM_NOMATCH;
if (*pattern && !(slash && ((*pattern == '/')
|| (escape && (*pattern == '\\')
&& (pattern[1] == '/')))))
return FNM_NOMATCH;
if (leading_dir && !*pattern && *string == '/')
return 0;
}
/* Where both pattern and string are at EOS, declare success
*/
if (!*string && !*pattern)
return 0;
/* pattern didn't match to the end of string */
return FNM_NOMATCH;
}

View File

@@ -1,48 +1,32 @@
/*-
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
/*
* Copyright (c) 2011 Todd C. Miller <Todd.Miller@courtesan.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)fnmatch.h 8.1 (Berkeley) 6/2/93
* $OpenBSD: fnmatch.h,v 1.4 1997/09/22 05:25:32 millert Exp $
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef _FNMATCH_H_
#define _FNMATCH_H_
#ifndef _FNMATCH_H
#define _FNMATCH_H
#define FNM_NOMATCH 1 /* Match failed. */
#define FNM_NOMATCH 1 /* String does not match pattern */
#define FNM_NOESCAPE 0x01 /* Disable backslash escaping. */
#define FNM_PATHNAME 0x02 /* Slash must be matched by slash. */
#define FNM_PERIOD 0x04 /* Period must be matched by period. */
#define FNM_LEADING_DIR 0x08 /* Ignore /<tail> after Imatch. */
#define FNM_CASEFOLD 0x10 /* Case insensitive search. */
#define FNM_PATHNAME (1 << 0) /* Globbing chars don't match '/' */
#define FNM_PERIOD (1 << 1) /* Leading '.' in string must exactly */
#define FNM_NOESCAPE (1 << 2) /* Backslash treated as ordinary char */
#define FNM_LEADING_DIR (1 << 3) /* Only match the leading directory */
#define FNM_CASEFOLD (1 << 4) /* Case insensitive matching */
int rpl_fnmatch(const char *, const char *, int);
int rpl_fnmatch(const char *pattern, const char *string, int flags);
#define fnmatch(_a, _b, _c) rpl_fnmatch((_a), (_b), (_c))
#endif /* !_FNMATCH_H_ */
#endif /* _FNMATCH_H */

View File

@@ -1,4 +1,4 @@
Sudo is distributed under the following ISC-style license:
Sudo is distributed under the following license:
Copyright (c) 1994-1996, 1998-2011
Todd C. Miller <Todd.Miller@courtesan.com>
@@ -19,10 +19,31 @@ Sudo is distributed under the following ISC-style license:
Agency (DARPA) and Air Force Research Laboratory, Air Force
Materiel Command, USAF, under agreement number F39502-99-1-0512.
The files fnmatch.c, fnmatch.h, getcwd.c, glob.c, glob.h and snprintf.c
bear the following UCB license:
The file redblack.c bears the following license:
Copyright (c) 1987, 1989, 1990, 1991, 1992, 1993, 1994
Copyright (c) 2001 Emin Martinian
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that neither the name of Emin
Martinian nor the names of any contributors are be used to endorse or
promote products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
The files getcwd.c, glob.c, glob.h and snprintf.c bear the following license:
Copyright (c) 1989, 1990, 1991, 1993
The Regents of the University of California. All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -49,6 +70,33 @@ bear the following UCB license:
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
The file fnmatch.c bears the following license:
Copyright (c) 2011, VMware, Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the VMware, Inc. nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL VMWARE, INC. OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
The embedded copy of zlib bears the following license:
Copyright (C) 1995-2010 Jean-loup Gailly and Mark Adler