Re: Autoconf, libpq and replacement function

Поиск
Список
Период
Сортировка
От Magnus Hagander
Тема Re: Autoconf, libpq and replacement function
Дата
Msg-id 4925B132.6000605@hagander.net
обсуждение исходный текст
Ответ на Re: Autoconf, libpq and replacement function  (Magnus Hagander <magnus@hagander.net>)
Список pgsql-hackers
Magnus Hagander wrote:
> Peter Eisentraut wrote:
>> Magnus Hagander wrote:
>>> How do I make this work with the autoconf magic? I see there is an
>>> AC_CHECK_FNMATCH and AC_REPLACE_FNMATCH and so, but I have a feeling I
>>> need to do something different since it's libpq?
>> AC_*_FNMATCH will figure out whether you need fnmatch(), so something
>> involving those is necessary.
>>
>> For libpq, check libpq's Makefile for, say, snprintf, to get an idea
>> about the "something different".
>>
>> Altogether, this might not be a trivial case.
>
> Hmm. If I did it the right way, it actually didn't seem too hard once I
> found a good example. Attached - does that seem reasonable?
>
> (will add msvc code as well)

That was easy. I also reversed the accidentally-reversed #ifdef in port.h.

//Mangus

*** a/configure
--- b/configure
***************
*** 16930,16936 **** LIBS=`echo "$LIBS" | sed -e 's/-ledit//g' -e 's/-lreadline//g'`



! for ac_func in crypt getopt getrusage inet_aton random rint srandom strdup strerror strlcat strlcpy strtol strtoul
unsetenv
  do
  as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
  { echo "$as_me:$LINENO: checking for $ac_func" >&5
--- 16930,16937 ----



!
! for ac_func in crypt fnmatch getopt getrusage inet_aton random rint srandom strdup strerror strlcat strlcpy strtol
strtoulunsetenv 
  do
  as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
  { echo "$as_me:$LINENO: checking for $ac_func" >&5
*** a/configure.in
--- b/configure.in
***************
*** 1235,1241 **** fi
  pgac_save_LIBS="$LIBS"
  LIBS=`echo "$LIBS" | sed -e 's/-ledit//g' -e 's/-lreadline//g'`

! AC_REPLACE_FUNCS([crypt getopt getrusage inet_aton random rint srandom strdup strerror strlcat strlcpy strtol strtoul
unsetenv])

  LIBS="$pgac_save_LIBS"

--- 1235,1241 ----
  pgac_save_LIBS="$LIBS"
  LIBS=`echo "$LIBS" | sed -e 's/-ledit//g' -e 's/-lreadline//g'`

! AC_REPLACE_FUNCS([crypt fnmatch getopt getrusage inet_aton random rint srandom strdup strerror strlcat strlcpy strtol
strtoulunsetenv]) 

  LIBS="$pgac_save_LIBS"

*** 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 you have the `fnmatch' function. */
+ #undef HAVE_FNMATCH
+
  /* Define to 1 if you have the `fpclass' function. */
  #undef HAVE_FPCLASS

*** a/src/include/port.h
--- b/src/include/port.h
***************
*** 393,398 **** extern void unsetenv(const char *name);
--- 393,409 ----
  extern void srandom(unsigned int seed);
  #endif

+ #ifndef HAVE_FNMATCH
+ 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
+
  /* thread.h */
  extern char *pqStrerror(int errnum, char *strerrbuf, size_t buflen);

*** 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.cpgsleep.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.cpgsleep.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.cstrlcpy.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.cstrerror.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,73 ----
  #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>
+ #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;
      }
  }

--- 466,485 ----
           * 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 (conklin@ngai.kaleida.com)
+      */
+     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

В списке pgsql-hackers по дате отправления:

Предыдущее
От: Magnus Hagander
Дата:
Сообщение: Re: Autoconf, libpq and replacement function
Следующее
От: Magnus Hagander
Дата:
Сообщение: Re: Re: [COMMITTERS] pgsql: Silence compiler warning about ignored return value.