Tom Lane wrote:
> Magnus Hagander <[EMAIL PROTECTED]> writes:
>> AFAICS, we're not doing this for any other functions though - or am I
>> too tired and just looking in the wrong place? Or is that because
>> they're just function definitions and not #defines?
>> (I want to be sure to stick whatever new file there is in the same place..)
> 
> src/include/rusagestub.h is doing things more or less this way.
> 
> Also, right now we have got
> 
> src/include/getaddrinfo.h
> src/include/getopt_long.h
> 
> which really make me itch now that I am contemplating the possibility
> that we try to use libc-supplied code for these functions along with
> our own header definitions.
> 
> I think the reason we've avoided putting such stuff into include/port/
> is that right now that directory consists exclusively of OS-specific
> files.  Maybe we need another include subdirectory?

Or in the same directly, called something else. Like fnmatchstub.h. See
attached, seems reasonable?

//Magnus

*** a/configure
--- b/configure
***************
*** 24821,24826 **** esac
--- 24821,24910 ----
  
  
  
+ # Check for fnmatch()
+ { echo "$as_me:$LINENO: checking for working POSIX fnmatch" >&5
+ echo $ECHO_N "checking for working POSIX fnmatch... $ECHO_C" >&6; }
+ if test "${ac_cv_func_fnmatch_works+set}" = set; then
+   echo $ECHO_N "(cached) $ECHO_C" >&6
+ else
+   # Some versions of Solaris, SCO, and the GNU C Library
+    # have a broken or incompatible fnmatch.
+    # So we run a test program.  If we are cross-compiling, take no chance.
+    # Thanks to John Oleynick, Franc,ois Pinard, and Paul Eggert for this test.
+    if test "$cross_compiling" = yes; then
+   ac_cv_func_fnmatch_works=cross
+ else
+   cat >conftest.$ac_ext <<_ACEOF
+ /* confdefs.h.  */
+ _ACEOF
+ cat confdefs.h >>conftest.$ac_ext
+ cat >>conftest.$ac_ext <<_ACEOF
+ /* end confdefs.h.  */
+ #include <fnmatch.h>
+ #	   define y(a, b, c) (fnmatch (a, b, c) == 0)
+ #	   define n(a, b, c) (fnmatch (a, b, c) == FNM_NOMATCH)
+ 
+ int
+ main ()
+ {
+ return
+ 	   (!(y ("a*", "abc", 0)
+ 	      && n ("d*/*1", "d/s/1", FNM_PATHNAME)
+ 	      && y ("a\\\\bc", "abc", 0)
+ 	      && n ("a\\\\bc", "abc", FNM_NOESCAPE)
+ 	      && y ("*x", ".x", 0)
+ 	      && n ("*x", ".x", FNM_PERIOD)
+ 	      && 1));
+   ;
+   return 0;
+ }
+ _ACEOF
+ rm -f conftest$ac_exeext
+ if { (ac_try="$ac_link"
+ case "(($ac_try" in
+   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+   *) ac_try_echo=$ac_try;;
+ esac
+ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+   (eval "$ac_link") 2>&5
+   ac_status=$?
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+   { (case "(($ac_try" in
+   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+   *) ac_try_echo=$ac_try;;
+ esac
+ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+   (eval "$ac_try") 2>&5
+   ac_status=$?
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); }; }; then
+   ac_cv_func_fnmatch_works=yes
+ else
+   echo "$as_me: program exited with status $ac_status" >&5
+ echo "$as_me: failed program was:" >&5
+ sed 's/^/| /' conftest.$ac_ext >&5
+ 
+ ( exit $ac_status )
+ ac_cv_func_fnmatch_works=no
+ fi
+ rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+ fi
+ 
+ 
+ fi
+ { echo "$as_me:$LINENO: result: $ac_cv_func_fnmatch_works" >&5
+ echo "${ECHO_T}$ac_cv_func_fnmatch_works" >&6; }
+ if test $ac_cv_func_fnmatch_works = yes; then
+ 
+ cat >>confdefs.h <<\_ACEOF
+ #define HAVE_FNMATCH 1
+ _ACEOF
+ 
+ fi
+ 
+ 
+ 
  
  # Select semaphore implementation type.
  if test "$PORTNAME" != "win32"; then
*** a/configure.in
--- b/configure.in
***************
*** 1625,1630 **** fi
--- 1625,1632 ----
  # SunOS doesn't handle negative byte comparisons properly with +/- return
  AC_FUNC_MEMCMP
  
+ # Check for fnmatch()
+ AC_FUNC_FNMATCH
  
  # Select semaphore implementation type.
  if test "$PORTNAME" != "win32"; then
*** /dev/null
--- b/src/include/fnmatchstub.h
***************
*** 0 ****
--- 1,27 ----
+ /*-------------------------------------------------------------------------
+  *
+  * fnmatchstub.h
+  *	  Stubs for fnmatch() in port/fnmatch.c
+  *
+  *
+  * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
+  * Portions Copyright (c) 1994, Regents of the University of California
+  *
+  * $PostgreSQL$
+  *
+  *-------------------------------------------------------------------------
+  */
+ #ifndef FNMATCHSTUB_H
+ #define FNMATCHSTUB_H
+ 
+ extern int fnmatch(const char *, const char *, int);
+ #define FNM_NOMATCH		1		/* Match failed. */
+ #define FNM_NOSYS		2		/* Function not implemented. */
+ #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_CASEFOLD	0x08	/* Pattern is matched case-insensitive */
+ #define FNM_LEADING_DIR	0x10	/* Ignore /<tail> after Imatch. */
+ 
+ 
+ #endif
*** a/src/include/pg_config.h.in
--- b/src/include/pg_config.h.in
***************
*** 143,148 ****
--- 143,151 ----
  /* Define to 1 if you have the `fdatasync' function. */
  #undef HAVE_FDATASYNC
  
+ /* Define to 1 if your system has a working POSIX `fnmatch' function. */
+ #undef HAVE_FNMATCH
+ 
  /* Define to 1 if you have the `fpclass' function. */
  #undef HAVE_FPCLASS
  
*** a/src/interfaces/libpq/Makefile
--- b/src/interfaces/libpq/Makefile
***************
*** 34,40 **** OBJS=	fe-auth.o fe-connect.o fe-exec.o fe-misc.o fe-print.o fe-lobj.o \
  	fe-protocol2.o fe-protocol3.o pqexpbuffer.o pqsignal.o fe-secure.o \
  	libpq-events.o \
  	md5.o ip.o wchar.o encnames.o noblock.o pgstrcasecmp.o thread.o \
! 	$(filter crypt.o getaddrinfo.o inet_aton.o open.o snprintf.o strerror.o strlcpy.o win32error.o, $(LIBOBJS))
  
  ifeq ($(PORTNAME), cygwin)
  override shlib = cyg$(NAME)$(DLSUFFIX)
--- 34,40 ----
  	fe-protocol2.o fe-protocol3.o pqexpbuffer.o pqsignal.o fe-secure.o \
  	libpq-events.o \
  	md5.o ip.o wchar.o encnames.o noblock.o pgstrcasecmp.o thread.o \
! 	$(filter crypt.o fnmatch.o getaddrinfo.o inet_aton.o open.o snprintf.o strerror.o strlcpy.o win32error.o, $(LIBOBJS))
  
  ifeq ($(PORTNAME), cygwin)
  override shlib = cyg$(NAME)$(DLSUFFIX)
***************
*** 80,86 **** backend_src = $(top_srcdir)/src/backend
  # For port modules, this only happens if configure decides the module
  # is needed (see filter hack in OBJS, above).
  
! crypt.c getaddrinfo.c inet_aton.c noblock.c open.c pgstrcasecmp.c snprintf.c strerror.c strlcpy.c thread.c win32error.c pgsleep.c: % : $(top_srcdir)/src/port/%
  	rm -f $@ && $(LN_S) $< .
  
  md5.c ip.c: % : $(backend_src)/libpq/%
--- 80,86 ----
  # For port modules, this only happens if configure decides the module
  # is needed (see filter hack in OBJS, above).
  
! crypt.c fnmatch.c getaddrinfo.c inet_aton.c noblock.c open.c pgstrcasecmp.c snprintf.c strerror.c strlcpy.c thread.c win32error.c pgsleep.c: % : $(top_srcdir)/src/port/%
  	rm -f $@ && $(LN_S) $< .
  
  md5.c ip.c: % : $(backend_src)/libpq/%
***************
*** 123,129 **** uninstall: uninstall-lib
  	rm -f '$(DESTDIR)$(datadir)/pg_service.conf.sample'
  
  clean distclean: clean-lib
! 	rm -f $(OBJS) pg_config_paths.h crypt.c getaddrinfo.c inet_aton.c noblock.c open.c pgstrcasecmp.c snprintf.c strerror.c strlcpy.c thread.c md5.c ip.c encnames.c wchar.c win32error.c pgsleep.c pthread.h libpq.rc
  # Might be left over from a Win32 client-only build
  	rm -f pg_config_paths.h
  
--- 123,129 ----
  	rm -f '$(DESTDIR)$(datadir)/pg_service.conf.sample'
  
  clean distclean: clean-lib
! 	rm -f $(OBJS) pg_config_paths.h crypt.c fnmatch.c getaddrinfo.c inet_aton.c noblock.c open.c pgstrcasecmp.c snprintf.c strerror.c strlcpy.c thread.c md5.c ip.c encnames.c wchar.c win32error.c pgsleep.c pthread.h libpq.rc
  # Might be left over from a Win32 client-only build
  	rm -f pg_config_paths.h
  
*** a/src/interfaces/libpq/fe-secure.c
--- b/src/interfaces/libpq/fe-secure.c
***************
*** 63,68 ****
--- 63,75 ----
  #if (SSLEAY_VERSION_NUMBER >= 0x00907000L) && !defined(OPENSSL_NO_ENGINE)
  #include <openssl/engine.h>
  #endif
+ 
+ /* fnmatch() needed for client certificate mapping */
+ #ifdef HAVE_FNMATCH
+ #include <fnmatch.h>
+ #else
+ #include "fnmatchstub.h"
+ #endif
  #endif   /* USE_SSL */
  
  
***************
*** 461,477 **** verify_peer_name_matches_certificate(PGconn *conn)
  		 * Connect by hostname.
  		 *
  		 * XXX: Should support alternate names here
- 		 * XXX: Should support wildcard certificates here
  		 */
! 		if (pg_strcasecmp(conn->peer_cn, conn->pghost) != 0)
  		{
  			printfPQExpBuffer(&conn->errorMessage,
  							  libpq_gettext("server common name '%s' does not match hostname '%s'"),
  							  conn->peer_cn, conn->pghost);
  			return false;
  		}
- 		else
- 			return true;
  	}
  }
  
--- 468,487 ----
  		 * Connect by hostname.
  		 *
  		 * XXX: Should support alternate names here
  		 */
! 		if (pg_strcasecmp(conn->peer_cn, conn->pghost) == 0)
! 			/* Exact name match */
! 			return true;
! 		else if (fnmatch(conn->peer_cn, conn->pghost, FNM_NOESCAPE | FNM_CASEFOLD) == 0)
! 			/* Matched wildcard certificate */
! 			return true;
! 		else
  		{
  			printfPQExpBuffer(&conn->errorMessage,
  							  libpq_gettext("server common name '%s' does not match hostname '%s'"),
  							  conn->peer_cn, conn->pghost);
  			return false;
  		}
  	}
  }
  
*** /dev/null
--- b/src/port/fnmatch.c
***************
*** 0 ****
--- 1,197 ----
+ /*-------------------------------------------------------------------------
+  *
+  * fnmatch.c
+  *        fnmatch() - wildcard matching function
+  *
+  * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
+  *
+  *
+  * IDENTIFICATION
+  *        $PostgreSQL$
+  *
+  * This file was taken from NetBSD and is used on platforms that don't
+  * provide fnmatch(). The NetBSD copyright terms follow.
+  *-------------------------------------------------------------------------
+  */
+ 
+ /*	$NetBSD: fnmatch.c,v 1.21 2005/12/24 21:11:16 perry Exp $	*/
+ 
+ /*
+  * 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.
+  *
+  * 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
+  * 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.
+  */
+ 
+ /*
+  * Function fnmatch() as specified in POSIX 1003.2-1992, section B.6.
+  * Compares a filename or pathname to a pattern.
+  */
+ 
+ #include "c.h"
+ 
+ #define	EOS	'\0'
+ 
+ static const char *rangematch (const char *, int, int);
+ 
+ static inline int
+ foldcase(int ch, int flags)
+ {
+ 
+ 	if ((flags & FNM_CASEFOLD) != 0 && isupper(ch))
+ 		return (tolower(ch));
+ 	return (ch);
+ }
+ 
+ #define	FOLDCASE(ch, flags)	foldcase((unsigned char)(ch), (flags))
+ 
+ int
+ fnmatch(pattern, string, flags)
+ 	const char *pattern, *string;
+ 	int flags;
+ {
+ 	const char *stringstart;
+ 	char c, test;
+ 
+ 	for (stringstart = string;;)
+ 		switch (c = FOLDCASE(*pattern++, flags)) {
+ 		case EOS:
+ 			if ((flags & FNM_LEADING_DIR) && *string == '/')
+ 				return (0);
+ 			return (*string == EOS ? 0 : FNM_NOMATCH);
+ 		case '?':
+ 			if (*string == EOS)
+ 				return (FNM_NOMATCH);
+ 			if (*string == '/' && (flags & FNM_PATHNAME))
+ 				return (FNM_NOMATCH);
+ 			if (*string == '.' && (flags & FNM_PERIOD) &&
+ 			    (string == stringstart ||
+ 			    ((flags & FNM_PATHNAME) && *(string - 1) == '/')))
+ 				return (FNM_NOMATCH);
+ 			++string;
+ 			break;
+ 		case '*':
+ 			c = FOLDCASE(*pattern, flags);
+ 			/* Collapse multiple stars. */
+ 			while (c == '*')
+ 				c = FOLDCASE(*++pattern, flags);
+ 
+ 			if (*string == '.' && (flags & FNM_PERIOD) &&
+ 			    (string == stringstart ||
+ 			    ((flags & FNM_PATHNAME) && *(string - 1) == '/')))
+ 				return (FNM_NOMATCH);
+ 
+ 			/* Optimize for pattern with * at end or before /. */
+ 			if (c == EOS) {
+ 				if (flags & FNM_PATHNAME)
+ 					return ((flags & FNM_LEADING_DIR) ||
+ 					    strchr(string, '/') == NULL ?
+ 					    0 : FNM_NOMATCH);
+ 				else
+ 					return (0);
+ 			} else if (c == '/' && flags & FNM_PATHNAME) {
+ 				if ((string = strchr(string, '/')) == NULL)
+ 					return (FNM_NOMATCH);
+ 				break;
+ 			}
+ 
+ 			/* General case, use recursion. */
+ 			while ((test = FOLDCASE(*string, flags)) != EOS) {
+ 				if (!fnmatch(pattern, string,
+ 					     flags & ~FNM_PERIOD))
+ 					return (0);
+ 				if (test == '/' && flags & FNM_PATHNAME)
+ 					break;
+ 				++string;
+ 			}
+ 			return (FNM_NOMATCH);
+ 		case '[':
+ 			if (*string == EOS)
+ 				return (FNM_NOMATCH);
+ 			if (*string == '/' && flags & FNM_PATHNAME)
+ 				return (FNM_NOMATCH);
+ 			if ((pattern =
+ 			    rangematch(pattern, FOLDCASE(*string, flags),
+ 				       flags)) == NULL)
+ 				return (FNM_NOMATCH);
+ 			++string;
+ 			break;
+ 		case '\\':
+ 			if (!(flags & FNM_NOESCAPE)) {
+ 				if ((c = FOLDCASE(*pattern++, flags)) == EOS) {
+ 					c = '\\';
+ 					--pattern;
+ 				}
+ 			}
+ 			/* FALLTHROUGH */
+ 		default:
+ 			if (c != FOLDCASE(*string++, flags))
+ 				return (FNM_NOMATCH);
+ 			break;
+ 		}
+ 	/* NOTREACHED */
+ }
+ 
+ static const char *
+ rangematch(pattern, test, flags)
+ 	const char *pattern;
+ 	int test, flags;
+ {
+ 	int negate, ok;
+ 	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 ([EMAIL PROTECTED])
+ 	 */
+ 	if ((negate = (*pattern == '!' || *pattern == '^')) != 0)
+ 		++pattern;
+ 	
+ 	for (ok = 0; (c = FOLDCASE(*pattern++, flags)) != ']';) {
+ 		if (c == '\\' && !(flags & FNM_NOESCAPE))
+ 			c = FOLDCASE(*pattern++, flags);
+ 		if (c == EOS)
+ 			return (NULL);
+ 		if (*pattern == '-' 
+ 		    && (c2 = FOLDCASE(*(pattern+1), flags)) != EOS &&
+ 		        c2 != ']') {
+ 			pattern += 2;
+ 			if (c2 == '\\' && !(flags & FNM_NOESCAPE))
+ 				c2 = FOLDCASE(*pattern++, flags);
+ 			if (c2 == EOS)
+ 				return (NULL);
+ 			if (c <= test && test <= c2)
+ 				ok = 1;
+ 		} else if (c == test)
+ 			ok = 1;
+ 	}
+ 	return (ok == negate ? NULL : pattern);
+ }
*** a/src/tools/msvc/Mkvcbuild.pm
--- b/src/tools/msvc/Mkvcbuild.pm
***************
*** 43,49 **** sub mkvcbuild
      $solution = new Solution($config);
  
      our @pgportfiles = qw(
!       chklocale.c crypt.c fseeko.c getrusage.c inet_aton.c random.c srandom.c
        unsetenv.c getaddrinfo.c gettimeofday.c kill.c open.c rand.c
        snprintf.c strlcat.c strlcpy.c copydir.c dirmod.c exec.c noblock.c path.c pipe.c
        pgsleep.c pgstrcasecmp.c qsort.c qsort_arg.c sprompt.c thread.c
--- 43,49 ----
      $solution = new Solution($config);
  
      our @pgportfiles = qw(
!       chklocale.c crypt.c fseeko.c fnmatch.c getrusage.c inet_aton.c random.c srandom.c
        unsetenv.c getaddrinfo.c gettimeofday.c kill.c open.c rand.c
        snprintf.c strlcat.c strlcpy.c copydir.c dirmod.c exec.c noblock.c path.c pipe.c
        pgsleep.c pgstrcasecmp.c qsort.c qsort_arg.c sprompt.c thread.c
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to