RPM Package Manager, CVS Repository
  http://rpm5.org/cvs/
  ____________________________________________________________________________

  Server: rpm5.org                         Name:   Jeff Johnson
  Root:   /v/rpm/cvs                       Email:  j...@rpm5.org
  Module: rpm                              Date:   19-Jun-2016 08:48:47
  Branch: rpm-5_4                          Handle: 20080925193928243947359

  Added files:              (Branch: rpm-5_4)
    rpm/misc                fnmatch.c fnmatch.h fnmatch_loop.c glob.c glob.h
  Modified files:           (Branch: rpm-5_4)
    rpm                     CHANGES system.h
    rpm/m4                  .cvsignore
    rpm/misc                Makefile.am librpmmisc.c
    rpm/rpmio               Makefile.am
  Removed files:            (Branch: rpm-5_4)
    rpm/rpmio               fnmatch.c fnmatch.h fnmatch_loop.c glob.c glob.h

  Log:
    - cygwin: fix: move glob/fnmatch from rpmio->misc to remove linkage
    loops.

  Summary:
    Revision    Changes     Path
    1.3501.2.493+1  -0      rpm/CHANGES
    1.1.8.3     +83 -145    rpm/m4/.cvsignore
    1.56.2.15   +5  -2      rpm/misc/Makefile.am
    1.12.2.2    +390 -0     rpm/misc/fnmatch.c
    1.8.2.2     +75 -0      rpm/misc/fnmatch.h
    1.1.2.1     +1244 -0    rpm/misc/fnmatch_loop.c
    1.22.2.2    +1268 -0    rpm/misc/glob.c
    1.16.2.2    +224 -0     rpm/misc/glob.h
    1.5.4.1     +4  -0      rpm/misc/librpmmisc.c
    1.293.2.71  +2  -4      rpm/rpmio/Makefile.am
    2.4         +0  -390    rpm/rpmio/fnmatch.c
    2.2         +0  -75     rpm/rpmio/fnmatch.h
    2.2         +0  -1244   rpm/rpmio/fnmatch_loop.c
    2.6         +0  -1272   rpm/rpmio/glob.c
    2.2         +0  -224    rpm/rpmio/glob.h
    2.129.2.20  +4  -2      rpm/system.h
  ____________________________________________________________________________

  patch -p0 <<'@@ .'
  Index: rpm/CHANGES
  ============================================================================
  $ cvs diff -u -r1.3501.2.492 -r1.3501.2.493 CHANGES
  --- rpm/CHANGES       19 Jun 2016 06:02:37 -0000      1.3501.2.492
  +++ rpm/CHANGES       19 Jun 2016 06:48:46 -0000      1.3501.2.493
  @@ -1,4 +1,5 @@
   5.4.17 -> 5.4.18:
  +    - jbj: cygwin: fix: move glob/fnmatch from rpmio->misc to remove linkage 
loops.
       - jbj: msvc: use gnulib msvc_* module stubs.
       - jbj: vs: stub in dll *.def generation.
       - jbj: cygwin: add portability fixes.
  @@ .
  patch -p0 <<'@@ .'
  Index: rpm/m4/.cvsignore
  ============================================================================
  $ cvs diff -u -r1.1.8.2 -r1.1.8.3 .cvsignore
  --- rpm/m4/.cvsignore 17 Jun 2016 08:07:27 -0000      1.1.8.2
  +++ rpm/m4/.cvsignore 19 Jun 2016 06:48:46 -0000      1.1.8.3
  @@ -1,185 +1,123 @@
   00gnulib.m4
   absolute-header.m4
  -alloca.m4
  -argz.m4
  -base32.m4
  -base64.m4
  -btowc.m4
  -codeset.m4
   configmake.m4
  -ctype.m4
  -eealloc.m4
  -environ.m4
  -errno_h.m4
  -exponentd.m4
   extensions.m4
   extern-inline.m4
  -fcntl_h.m4
  -fcntl-o.m4
  -fdopen.m4
  -ffs.m4
  -float_h.m4
  -fnmatch.m4
  -fpieee.m4
  -fseek.m4
  -fseeko.m4
  -fstat.m4
  -getcwd.m4
  -getdelim.m4
  -getline.m4
  -getpagesize.m4
  -getpass.m4
  -gettimeofday.m4
  -glibc21.m4
   gnulib-cache.m4
   gnulib-common.m4
   gnulib-comp.m4
   gnulib-tool.m4
  -hard-locale.m4
   include_next.m4
  -intlmacosx.m4
  -intmax_t.m4
  -inttostr.m4
  -inttypes_h.m4
   inttypes.m4
   inttypes-pri.m4
  -langinfo_h.m4
  -largefile.m4
  -lcmessage.m4
  -lib-ld.m4
  -lib-link.m4
  -lib-prefix.m4
  -localcharset.m4
  -localeconv.m4
  -locale-fr.m4
  -locale_h.m4
  -locale-ja.m4
  -localename.m4
  -locale-tr.m4
  -locale-zh.m4
  -lock.m4
   longlong.m4
  -lseek.m4
  -lstat.m4
  -malloca.m4
  -malloc.m4
  -math_h.m4
  -mbrtowc.m4
  -mbsinit.m4
  -mbsrtowcs.m4
  -mbstate_t.m4
  -mbtowc.m4
  -memchr.m4
  -mempcpy.m4
  -mkdtemp.m4
  -mkstemp.m4
  -mmap-anon.m4
   msvc-inval.m4
   msvc-nothrow.m4
   multiarch.m4
  -nl_langinfo.m4
   off_t.m4
  -pathmax.m4
  -printf.m4
  -putenv.m4
  -realloc.m4
  -regex.m4
  -secure_getenv.m4
  -setenv.m4
  -setlocale.m4
  -size_max.m4
  -snprintf.m4
   ssize_t.m4
  -stat.m4
   stdalign.m4
   stdbool.m4
   stddef_h.m4
  -stdint_h.m4
   stdint.m4
  -stdio_h.m4
   stdlib_h.m4
  -stpcpy.m4
  -stpncpy.m4
  -strdup.m4
  -strerror.m4
  -string_h.m4
  -strings_h.m4
  -strndup.m4
  -strnlen.m4
  -strstr.m4
  -symlink.m4
  -sys_socket_h.m4
  -sys_stat_h.m4
  -sys_time_h.m4
   sys_types_h.m4
  -sys_wait_h.m4
  -tempname.m4
  -threadlib.m4
  -thread.m4
  -time_h.m4
  -ungetc.m4
   unistd_h.m4
  -vasnprintf.m4
  -vasprintf.m4
   warn-on-use.m4
   wchar_h.m4
   wchar_t.m4
  -wcrtomb.m4
  -wctob.m4
  -wctomb.m4
  -wctype_h.m4
   wint_t.m4
  -xsize.m4
  -yield.m4
  -gettext.m4
  -glibc2.m4
  -iconv.m4
  -intdiv0.m4
  -intl.m4
  -intldir.m4
  -intmax.m4
   libtool.m4
   ltoptions.m4
   ltsugar.m4
   ltversion.m4
   lt~obsolete.m4
  -nls.m4
  -po.m4
  -printf-posix.m4
  -progtest.m4
  -uintmax_t.m4
  -visibility.m4
  -closedir.m4
  -d-type.m4
  -dirent_h.m4
  -dirfd.m4
  -getlogin_r.m4
  -glob.m4
  +relocatable-lib.m4
   ld-output-def.m4
  -opendir.m4
  -readdir.m4
  -chdir-long.m4
  +ld-version-script.m4
  +alloca.m4
  +arpa_inet_h.m4
  +assert_h.m4
   close.m4
  -cycle-check.m4
  -d-ino.m4
  -dirent-safer.m4
  -dirname.m4
  -double-slash-root.m4
  -dup.m4
  +ctype.m4
  +dirent_h.m4
   dup2.m4
  -error.m4
  -fchdir.m4
  -fcntl-safer.m4
  -fcntl.m4
  -fdopendir.m4
  -filenamecat.m4
  -flexmember.m4
  -fts.m4
  +eealloc.m4
  +environ.m4
  +errno_h.m4
  +fcntl_h.m4
  +fdopen.m4
  +fstat.m4
  +getcwd.m4
   getdtablesize.m4
  -i-ring.m4
  -memrchr.m4
  +getopt.m4
  +gettimeofday.m4
  +largefile.m4
  +locale_h.m4
  +lstat.m4
  +malloc.m4
  +malloca.m4
   mode_t.m4
  +netdb_h.m4
  +netinet_in_h.m4
  +nocrash.m4
   open.m4
  -openat.m4
  -save-cwd.m4
  -unistd-safer.m4
  +pathmax.m4
  +putenv.m4
  +realloc.m4
  +secure_getenv.m4
  +setenv.m4
  +signal_h.m4
  +socklen.m4
  +sockpfaf.m4
  +stat.m4
  +stdio_h.m4
  +stpcpy.m4
  +stpncpy.m4
  +string_h.m4
  +symlink.m4
  +sys_socket_h.m4
  +sys_stat_h.m4
  +sys_time_h.m4
  +sys_uio_h.m4
  +sys_utsname_h.m4
  +sys_wait_h.m4
  +time_h.m4
  +dup.m4
  +fclose.m4
  +fcntl.m4
  +fflush.m4
  +flock.m4
  +fpurge.m4
  +freading.m4
  +fseek.m4
  +fseeko.m4
  +fsync.m4
  +ftell.m4
  +ftello.m4
  +ftruncate.m4
  +gethostname.m4
  +inet_pton.m4
  +ioctl.m4
  +isatty.m4
  +lseek.m4
  +perror.m4
  +pipe.m4
  +poll.m4
  +poll_h.m4
  +raise.m4
  +read.m4
  +select.m4
  +signalblocking.m4
  +sleep.m4
  +socketlib.m4
  +sockets.m4
  +strerror.m4
  +strerror_r.m4
  +sys_file_h.m4
  +sys_ioctl_h.m4
  +sys_select_h.m4
  +thread.m4
  +ungetc.m4
  +write.m4
  +yield.m4
  @@ .
  patch -p0 <<'@@ .'
  Index: rpm/misc/Makefile.am
  ============================================================================
  $ cvs diff -u -r1.56.2.14 -r1.56.2.15 Makefile.am
  --- rpm/misc/Makefile.am      17 Jun 2016 08:07:27 -0000      1.56.2.14
  +++ rpm/misc/Makefile.am      19 Jun 2016 06:48:46 -0000      1.56.2.15
  @@ -19,10 +19,13 @@
        strftime.c      strcspn.c       strstr.c        strtol.c        \
        strtoul.c \
           tempname.h \
  -        mkdtemp.c 
  +        mkdtemp.c \
  +     fnmatch.c fnmatch_loop.c \
  +     glob.c
   
   noinst_HEADERS = \
  -     err.h           error.h tempname.h
  +     err.h           error.h tempname.h \
  +     fnmatch.h glob.h
   
   usrlibdir = $(libdir)
   usrlib_LTLIBRARIES = librpmmisc.la
  @@ .
  patch -p0 <<'@@ .'
  Index: rpm/misc/fnmatch.c
  ============================================================================
  $ cvs diff -u -r0 -r1.12.2.2 fnmatch.c
  --- /dev/null 2016-06-19 08:45:30.000000000 +0200
  +++ fnmatch.c 2016-06-19 08:48:47.304275608 +0200
  @@ -0,0 +1,390 @@
  +/*@-bounds@*/
  +/*@-retalias@*/
  +/*@-shiftimplementation@*/
  +/*@-temptrans@*/
  +/*@-unreachable@*/
  +/* Copyright (C) 1991,1992,1993,1996,1997,1998,1999,2000,2001,2002,2003,2007
  +     Free Software Foundation, Inc.
  +   This file is part of the GNU C Library.
  +
  +   The GNU C Library is free software; you can redistribute it and/or
  +   modify it under the terms of the GNU Lesser General Public
  +   License as published by the Free Software Foundation; either
  +   version 2.1 of the License, or (at your option) any later version.
  +
  +   The GNU C Library is distributed in the hope that it will be useful,
  +   but WITHOUT ANY WARRANTY; without even the implied warranty of
  +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  +   Lesser General Public License for more details.
  +
  +   You should have received a copy of the GNU Lesser General Public
  +   License along with the GNU C Library; if not, write to the Free
  +   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  +   02111-1307 USA.  */
  +
  +#include "system.h"
  +
  +#include <string.h>
  +
  +#include "debug.h"
  +
  +#if ! defined __builtin_expect && __GNUC__ < 3
  +# define __builtin_expect(expr, expected) (expr)
  +#elif ! defined __builtin_expect && defined(__SUNPRO_C)
  +# define __builtin_expect(expr, expected) (expr)
  +#endif
  +
  +/* XXX Don't bother with wide and multibyte characters ... */
  +#undef       HAVE_WCTYPE_H
  +#undef       HAVE_WCHAR_H
  +#undef       HAVE_MBSTATE_T
  +#undef       HAVE_MBSRTOWCS
  +
  +/* We often have to test for FNM_FILE_NAME and FNM_PERIOD being both set.  */
  +#define NO_LEADING_PERIOD(flags) \
  +  ((flags & (FNM_FILE_NAME | FNM_PERIOD)) == (FNM_FILE_NAME | FNM_PERIOD))
  +
  +/* Comment out all this code if we are using the GNU C Library, and are not
  +   actually compiling the library itself.  This code is part of the GNU C
  +   Library, but also included in many other GNU distributions.  Compiling
  +   and linking in this code is a waste when using the GNU C library
  +   (especially if it is a shared library).  Rather than having every GNU
  +   program understand `configure --with-gnu-libc' and omit the object files,
  +   it is simpler to just do this in the source for each such file.  */
  +
  +#if defined _LIBC || !defined __GNU_LIBRARY__
  +
  +
  +# if defined STDC_HEADERS || !defined isascii
  +#  define ISASCII(c) 1
  +# else
  +#  define ISASCII(c) isascii(c)
  +# endif
  +
  +# ifdef isblank
  +#  define ISBLANK(c) (ISASCII (c) && isblank (c))
  +# else
  +#  define ISBLANK(c) ((c) == ' ' || (c) == '\t')
  +# endif
  +# ifdef isgraph
  +#  define ISGRAPH(c) (ISASCII (c) && isgraph (c))
  +# else
  +#  define ISGRAPH(c) (ISASCII (c) && isprint (c) && !isspace (c))
  +# endif
  +
  +# define ISPRINT(c) (ISASCII (c) && isprint (c))
  +# define ISDIGIT(c) (ISASCII (c) && isdigit (c))
  +# define ISALNUM(c) (ISASCII (c) && isalnum (c))
  +# define ISALPHA(c) (ISASCII (c) && isalpha (c))
  +# define ISCNTRL(c) (ISASCII (c) && iscntrl (c))
  +# define ISLOWER(c) (ISASCII (c) && islower (c))
  +# define ISPUNCT(c) (ISASCII (c) && ispunct (c))
  +# define ISSPACE(c) (ISASCII (c) && isspace (c))
  +# define ISUPPER(c) (ISASCII (c) && isupper (c))
  +# define ISXDIGIT(c) (ISASCII (c) && isxdigit (c))
  +
  +# define STREQ(s1, s2) ((strcmp (s1, s2) == 0))
  +
  +# if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
  +/* The GNU C library provides support for user-defined character classes
  +   and the functions from ISO C amendement 1.  */
  +#  ifdef CHARCLASS_NAME_MAX
  +#   define CHAR_CLASS_MAX_LENGTH CHARCLASS_NAME_MAX
  +#  else
  +/* This shouldn't happen but some implementation might still have this
  +   problem.  Use a reasonable default value.  */
  +#   define CHAR_CLASS_MAX_LENGTH 256
  +#  endif
  +
  +#  ifdef _LIBC
  +#   define IS_CHAR_CLASS(string) __wctype (string)
  +#  else
  +#   define IS_CHAR_CLASS(string) wctype (string)
  +#  endif
  +
  +#  ifdef _LIBC
  +#   define ISWCTYPE(WC, WT)  __iswctype (WC, WT)
  +#  else
  +#   define ISWCTYPE(WC, WT)  iswctype (WC, WT)
  +#  endif
  +
  +#  if (HAVE_MBSTATE_T && HAVE_MBSRTOWCS) || _LIBC
  +/* In this case we are implementing the multibyte character handling.  */
  +#   define HANDLE_MULTIBYTE  1
  +#  endif
  +
  +# else
  +#  define CHAR_CLASS_MAX_LENGTH  6 /* Namely, `xdigit'.  */
  +
  +#  define IS_CHAR_CLASS(string)                                              
      \
  +   (STREQ (string, "alpha") || STREQ (string, "upper")                       
      \
  +    || STREQ (string, "lower") || STREQ (string, "digit")                  \
  +    || STREQ (string, "alnum") || STREQ (string, "xdigit")                 \
  +    || STREQ (string, "space") || STREQ (string, "print")                  \
  +    || STREQ (string, "punct") || STREQ (string, "graph")                  \
  +    || STREQ (string, "cntrl") || STREQ (string, "blank"))
  +# endif
  +
  +/* Avoid depending on library functions or files
  +   whose names are inconsistent.  */
  +
  +# if defined __linux__ && (!defined _LIBC && !defined getenv)
  +extern char *getenv ();
  +# endif
  +
  +# ifndef errno
  +extern int errno;
  +# endif
  +
  +/* Global variable.  */
  +static int posixly_correct;
  +
  +# ifndef internal_function
  +/* Inside GNU libc we mark some function in a special way.  In other
  +   environments simply ignore the marking.  */
  +#  define internal_function
  +# endif
  +
  +/* Note that this evaluates C many times.  */
  +# ifdef _LIBC
  +#  define FOLD(c) ((flags & FNM_CASEFOLD) ? tolower (c) : (c))
  +# else
  +#  define FOLD(c) ((flags & FNM_CASEFOLD) && ISUPPER (c) ? tolower (c) : (c))
  +# endif
  +# define CHAR        char
  +# define UCHAR       unsigned char
  +# define INT int
  +# define FCT internal_fnmatch
  +# define EXT ext_match
  +# define END end_pattern
  +# define STRUCT      fnmatch_struct
  +# define L(CS)       CS
  +# ifdef _LIBC
  +#  define BTOWC(C)   __btowc (C)
  +# else
  +#  define BTOWC(C)   btowc (C)
  +# endif
  +# define STRLEN(S) strlen (S)
  +# define STRCAT(D, S) strcat (D, S)
  +# if defined HAVE_MEMPCPY
  +# define MEMPCPY(D, S, N) mempcpy (D, S, N)
  +#else
  +# define MEMPCPY(D, S, N) __fnmatch_mempcpy (D, S, N)
  +static void *__fnmatch_mempcpy(void *, const void *, size_t);
  +static void *__fnmatch_mempcpy(void *dest, const void *src, size_t n)
  +{
  +    return (void *)((char *)memcpy(dest, src, n) + n);
  +}
  +#endif
  +# define MEMCHR(S, C, N) memchr (S, C, N)
  +# define STRCOLL(S1, S2) strcoll (S1, S2)
  +# include "fnmatch_loop.c"
  +
  +
  +# if HANDLE_MULTIBYTE
  +/* Note that this evaluates C many times.  */
  +#  ifdef _LIBC
  +#   define FOLD(c) ((flags & FNM_CASEFOLD) ? towlower (c) : (c))
  +#  else
  +#   define FOLD(c) ((flags & FNM_CASEFOLD) && ISUPPER (c) ? towlower (c) : 
(c))
  +#  endif
  +#  define CHAR       wchar_t
  +#  define UCHAR      wint_t
  +#  define INT        wint_t
  +#  define FCT        internal_fnwmatch
  +#  define EXT        ext_wmatch
  +#  define END        end_wpattern
  +#  define STRUCT fnwmatch_struct
  +#  define L(CS)      L##CS
  +#  define BTOWC(C)   (C)
  +#  define STRLEN(S) __wcslen (S)
  +#  define STRCAT(D, S) __wcscat (D, S)
  +#  define MEMPCPY(D, S, N) __wmempcpy (D, S, N)
  +#  define MEMCHR(S, C, N) wmemchr (S, C, N)
  +#  define STRCOLL(S1, S2) wcscoll (S1, S2)
  +#  define WIDE_CHAR_VERSION 1
  +
  +#  undef IS_CHAR_CLASS
  +/* We have to convert the wide character string in a multibyte string.  But
  +   we know that the character class names consist of alphanumeric characters
  +   from the portable character set, and since the wide character encoding
  +   for a member of the portable character set is the same code point as
  +   its single-byte encoding, we can use a simplified method to convert the
  +   string to a multibyte character string.  */
  +static wctype_t
  +is_char_class (const wchar_t *wcs)
  +{
  +  char s[CHAR_CLASS_MAX_LENGTH + 1];
  +  char *cp = s;
  +
  +  do
  +    {
  +      /* Test for a printable character from the portable character set.  */
  +#  ifdef _LIBC
  +      if (*wcs < 0x20 || *wcs > 0x7e
  +       || *wcs == 0x24 || *wcs == 0x40 || *wcs == 0x60)
  +     return (wctype_t) 0;
  +#  else
  +      switch (*wcs)
  +     {
  +     case L' ': case L'!': case L'"': case L'#': case L'%':
  +     case L'&': case L'\'': case L'(': case L')': case L'*':
  +     case L'+': case L',': case L'-': case L'.': case L'/':
  +     case L'0': case L'1': case L'2': case L'3': case L'4':
  +     case L'5': case L'6': case L'7': case L'8': case L'9':
  +     case L':': case L';': case L'<': case L'=': case L'>':
  +     case L'?':
  +     case L'A': case L'B': case L'C': case L'D': case L'E':
  +     case L'F': case L'G': case L'H': case L'I': case L'J':
  +     case L'K': case L'L': case L'M': case L'N': case L'O':
  +     case L'P': case L'Q': case L'R': case L'S': case L'T':
  +     case L'U': case L'V': case L'W': case L'X': case L'Y':
  +     case L'Z':
  +     case L'[': case L'\\': case L']': case L'^': case L'_':
  +     case L'a': case L'b': case L'c': case L'd': case L'e':
  +     case L'f': case L'g': case L'h': case L'i': case L'j':
  +     case L'k': case L'l': case L'm': case L'n': case L'o':
  +     case L'p': case L'q': case L'r': case L's': case L't':
  +     case L'u': case L'v': case L'w': case L'x': case L'y':
  +     case L'z': case L'{': case L'|': case L'}': case L'~':
  +       break;
  +     default:
  +       return (wctype_t) 0;
  +     }
  +#  endif
  +
  +      /* Avoid overrunning the buffer.  */
  +      if (cp == s + CHAR_CLASS_MAX_LENGTH)
  +     return (wctype_t) 0;
  +
  +      *cp++ = (char) *wcs++;
  +    }
  +  while (*wcs != L'\0');
  +
  +  *cp = '\0';
  +
  +#  ifdef _LIBC
  +  return __wctype (s);
  +#  else
  +  return wctype (s);
  +#  endif
  +}
  +#  define IS_CHAR_CLASS(string) is_char_class (string)
  +
  +#  include "fnmatch_loop.c"
  +# endif
  +
  +
  +int
  +fnmatch (pattern, string, flags)
  +     const char *pattern;
  +     const char *string;
  +     int flags;
  +{
  +# if HANDLE_MULTIBYTE
  +  if (__builtin_expect (MB_CUR_MAX, 1) != 1)
  +    {
  +      mbstate_t ps;
  +      size_t n;
  +      const char *p;
  +      wchar_t *wpattern;
  +      wchar_t *wstring;
  +
  +      /* Convert the strings into wide characters.  */
  +      memset (&ps, '\0', sizeof (ps));
  +      p = pattern;
  +#ifdef _LIBC
  +      n = strnlen (pattern, 1024);
  +#else
  +      n = strlen (pattern);
  +#endif
  +      if (__builtin_expect (n < 1024, 1))
  +     {
  +       wpattern = (wchar_t *) alloca ((n + 1) * sizeof (wchar_t));
  +       n = mbsrtowcs (wpattern, &p, n + 1, &ps);
  +       if (__builtin_expect (n == (size_t) -1, 0))
  +         /* Something wrong.
  +            XXX Do we have to set `errno' to something which mbsrtows hasn't
  +            already done?  */
  +         return -1;
  +       if (p)
  +         {
  +           memset (&ps, '\0', sizeof (ps));
  +           goto prepare_wpattern;
  +         }
  +     }
  +      else
  +     {
  +     prepare_wpattern:
  +       n = mbsrtowcs (NULL, &pattern, 0, &ps);
  +       if (__builtin_expect (n == (size_t) -1, 0))
  +         /* Something wrong.
  +            XXX Do we have to set `errno' to something which mbsrtows hasn't
  +            already done?  */
  +         return -1;
  +       wpattern = (wchar_t *) alloca ((n + 1) * sizeof (wchar_t));
  +       assert (mbsinit (&ps));
  +       (void) mbsrtowcs (wpattern, &pattern, n + 1, &ps);
  +     }
  +
  +      assert (mbsinit (&ps));
  +#ifdef _LIBC
  +      n = strnlen (string, 1024);
  +#else
  +      n = strlen (string);
  +#endif
  +      p = string;
  +      if (__builtin_expect (n < 1024, 1))
  +     {
  +       wstring = (wchar_t *) alloca ((n + 1) * sizeof (wchar_t));
  +       n = mbsrtowcs (wstring, &p, n + 1, &ps);
  +       if (__builtin_expect (n == (size_t) -1, 0))
  +         /* Something wrong.
  +            XXX Do we have to set `errno' to something which mbsrtows hasn't
  +            already done?  */
  +         return -1;
  +       if (p)
  +         {
  +           memset (&ps, '\0', sizeof (ps));
  +           goto prepare_wstring;
  +         }
  +     }
  +      else
  +     {
  +     prepare_wstring:
  +       n = mbsrtowcs (NULL, &string, 0, &ps);
  +       if (__builtin_expect (n == (size_t) -1, 0))
  +         /* Something wrong.
  +            XXX Do we have to set `errno' to something which mbsrtows hasn't
  +            already done?  */
  +         return -1;
  +       wstring = (wchar_t *) alloca ((n + 1) * sizeof (wchar_t));
  +       assert (mbsinit (&ps));
  +       (void) mbsrtowcs (wstring, &string, n + 1, &ps);
  +     }
  +
  +      return internal_fnwmatch (wpattern, wstring, wstring + n,
  +                             flags & FNM_PERIOD, flags, NULL);
  +    }
  +# endif  /* mbstate_t and mbsrtowcs or _LIBC.  */
  +
  +  return internal_fnmatch (pattern, string, string + strlen (string),
  +                        flags & FNM_PERIOD, flags, NULL);
  +}
  +
  +# ifdef _LIBC
  +#  undef fnmatch
  +versioned_symbol (libc, __fnmatch, fnmatch, GLIBC_2_2_3);
  +#  if SHLIB_COMPAT(libc, GLIBC_2_0, GLIBC_2_2_3)
  +strong_alias (__fnmatch, __fnmatch_old)
  +compat_symbol (libc, __fnmatch_old, fnmatch, GLIBC_2_0);
  +#  endif
  +libc_hidden_ver (__fnmatch, fnmatch)
  +# endif
  +
  +#endif       /* _LIBC or not __GNU_LIBRARY__.  */
  +/*@=unreachable@*/
  +/*@=temptrans@*/
  +/*@=shiftimplementation@*/
  +/*@=retalias@*/
  +/*@=bounds@*/
  @@ .
  patch -p0 <<'@@ .'
  Index: rpm/misc/fnmatch.h
  ============================================================================
  $ cvs diff -u -r0 -r1.8.2.2 fnmatch.h
  --- /dev/null 2016-06-19 08:45:30.000000000 +0200
  +++ fnmatch.h 2016-06-19 08:48:47.315275568 +0200
  @@ -0,0 +1,75 @@
  +/* Copyright (C) 1991-93,96,97,98,99,2001,2004 Free Software Foundation, Inc.
  +   This file is part of the GNU C Library.
  +
  +   The GNU C Library is free software; you can redistribute it and/or
  +   modify it under the terms of the GNU Lesser General Public
  +   License as published by the Free Software Foundation; either
  +   version 2.1 of the License, or (at your option) any later version.
  +
  +   The GNU C Library is distributed in the hope that it will be useful,
  +   but WITHOUT ANY WARRANTY; without even the implied warranty of
  +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  +   Lesser General Public License for more details.
  +
  +   You should have received a copy of the GNU Lesser General Public
  +   License along with the GNU C Library; if not, write to the Free
  +   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  +   02111-1307 USA.  */
  +
  +#ifndef      _FNMATCH_H
  +#define      _FNMATCH_H      1
  +
  +#ifdef       __cplusplus
  +extern "C" {
  +#endif
  +
  +#ifndef const
  +# if (defined __STDC__ && __STDC__) || defined __cplusplus
  +#  define __const    const
  +# else
  +#  define __const
  +# endif
  +#endif
  +
  +/* We #undef these before defining them because some losing systems
  +   (HP-UX A.08.07 for example) define these in <unistd.h>.  */
  +#undef       FNM_PATHNAME
  +#undef       FNM_NOESCAPE
  +#undef       FNM_PERIOD
  +
  +/* Bits set in the FLAGS argument to `fnmatch'.  */
  +#define      FNM_PATHNAME    (1 << 0) /* No wildcard can ever match `/'.  */
  +#define      FNM_NOESCAPE    (1 << 1) /* Backslashes don't quote special 
chars.  */
  +#define      FNM_PERIOD      (1 << 2) /* Leading `.' is matched only 
explicitly.  */
  +
  +#if !defined _POSIX_C_SOURCE || _POSIX_C_SOURCE < 2 || defined _GNU_SOURCE
  +# define FNM_FILE_NAME        FNM_PATHNAME   /* Preferred GNU name.  */
  +# define FNM_LEADING_DIR (1 << 3)    /* Ignore `/...' after a match.  */
  +# define FNM_CASEFOLD         (1 << 4)       /* Compare without regard to 
case.  */
  +# define FNM_EXTMATCH         (1 << 5)       /* Use ksh-like extended 
matching. */
  +#endif
  +
  +/* Value returned by `fnmatch' if STRING does not match PATTERN.  */
  +#define      FNM_NOMATCH     1
  +
  +/* This value is returned if the implementation does not support
  +   `fnmatch'.  Since this is not the case here it will never be
  +   returned but the conformance test suites still require the symbol
  +   to be defined.  */
  +#ifdef _XOPEN_SOURCE
  +# define FNM_NOSYS   (-1)
  +#endif
  +
  +/* Match NAME against the filename pattern PATTERN,
  +   returning zero if it matches, FNM_NOMATCH if not.  */
  +/*@-redecl@*/
  +extern int fnmatch (__const char *__pattern, __const char *__name,
  +                 int __flags)
  +     /*@*/;
  +/*@=redecl@*/
  +
  +#ifdef       __cplusplus
  +}
  +#endif
  +
  +#endif /* fnmatch.h */
  @@ .
  patch -p0 <<'@@ .'
  Index: rpm/misc/fnmatch_loop.c
  ============================================================================
  $ cvs diff -u -r0 -r1.1.2.1 fnmatch_loop.c
  --- /dev/null 2016-06-19 08:45:30.000000000 +0200
  +++ fnmatch_loop.c    2016-06-19 08:48:47.330275466 +0200
  @@ -0,0 +1,1244 @@
  +/* Copyright (C) 1991-1993,1996-2001,2003-2005,2007
  +   Free Software Foundation, Inc.
  +   This file is part of the GNU C Library.
  +
  +   The GNU C Library is free software; you can redistribute it and/or
  +   modify it under the terms of the GNU Lesser General Public
  +   License as published by the Free Software Foundation; either
  +   version 2.1 of the License, or (at your option) any later version.
  +
  +   The GNU C Library is distributed in the hope that it will be useful,
  +   but WITHOUT ANY WARRANTY; without even the implied warranty of
  +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  +   Lesser General Public License for more details.
  +
  +   You should have received a copy of the GNU Lesser General Public
  +   License along with the GNU C Library; if not, write to the Free
  +   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  +   02111-1307 USA.  */
  +
  +struct STRUCT
  +{
  +  const CHAR *pattern;
  +  const CHAR *string;
  +  int no_leading_period;
  +};
  +
  +/* Match STRING against the filename pattern PATTERN, returning zero if
  +   it matches, nonzero if not.  */
  +static int FCT (const CHAR *pattern, const CHAR *string,
  +             const CHAR *string_end, int no_leading_period, int flags,
  +             struct STRUCT *ends)
  +     internal_function;
  +static int EXT (INT opt, const CHAR *pattern, const CHAR *string,
  +             const CHAR *string_end, int no_leading_period, int flags)
  +     internal_function;
  +static const CHAR *END (const CHAR *patternp) internal_function;
  +
  +static int
  +internal_function
  +FCT (pattern, string, string_end, no_leading_period, flags, ends)
  +     const CHAR *pattern;
  +     const CHAR *string;
  +     const CHAR *string_end;
  +     int no_leading_period;
  +     int flags;
  +     struct STRUCT *ends;
  +{
  +  register const CHAR *p = pattern, *n = string;
  +  register UCHAR c;
  +#ifdef _LIBC
  +# if WIDE_CHAR_VERSION
  +  const char *collseq = (const char *)
  +    _NL_CURRENT(LC_COLLATE, _NL_COLLATE_COLLSEQWC);
  +# else
  +  const UCHAR *collseq = (const UCHAR *)
  +    _NL_CURRENT(LC_COLLATE, _NL_COLLATE_COLLSEQMB);
  +# endif
  +#endif
  +
  +  while ((c = *p++) != L('\0'))
  +    {
  +      int new_no_leading_period = 0;
  +      c = FOLD (c);
  +
  +      switch (c)
  +     {
  +     case L('?'):
  +       if (__builtin_expect (flags & FNM_EXTMATCH, 0) && *p == '(')
  +         {
  +           int res;
  +
  +           res = EXT (c, p, n, string_end, no_leading_period,
  +                      flags);
  +           if (res != -1)
  +             return res;
  +         }
  +
  +       if (n == string_end)
  +         return FNM_NOMATCH;
  +       else if (*n == L('/') && (flags & FNM_FILE_NAME))
  +         return FNM_NOMATCH;
  +       else if (*n == L('.') && no_leading_period)
  +         return FNM_NOMATCH;
  +       break;
  +
  +     case L('\\'):
  +       if (!(flags & FNM_NOESCAPE))
  +         {
  +           c = *p++;
  +           if (c == L('\0'))
  +             /* Trailing \ loses.  */
  +             return FNM_NOMATCH;
  +           c = FOLD (c);
  +         }
  +       if (n == string_end || FOLD ((UCHAR) *n) != c)
  +         return FNM_NOMATCH;
  +       break;
  +
  +     case L('*'):
  +       if (__builtin_expect (flags & FNM_EXTMATCH, 0) && *p == '(')
  +         {
  +           int res;
  +
  +           res = EXT (c, p, n, string_end, no_leading_period,
  +                      flags);
  +           if (res != -1)
  +             return res;
  +         }
  +       else if (ends != NULL)
  +         {
  +           ends->pattern = p - 1;
  +           ends->string = n;
  +           ends->no_leading_period = no_leading_period;
  +           return 0;
  +         }
  +
  +       if (n != string_end && *n == L('.') && no_leading_period)
  +         return FNM_NOMATCH;
  +
  +       for (c = *p++; c == L('?') || c == L('*'); c = *p++)
  +         {
  +           if (*p == L('(') && (flags & FNM_EXTMATCH) != 0)
  +             {
  +               const CHAR *endp = END (p);
  +               if (endp != p)
  +                 {
  +                   /* This is a pattern.  Skip over it.  */
  +                   p = endp;
  +                   continue;
  +                 }
  +             }
  +
  +           if (c == L('?'))
  +             {
  +               /* A ? needs to match one character.  */
  +               if (n == string_end)
  +                 /* There isn't another character; no match.  */
  +                 return FNM_NOMATCH;
  +               else if (*n == L('/')
  +                        && __builtin_expect (flags & FNM_FILE_NAME, 0))
  +                 /* A slash does not match a wildcard under
  +                    FNM_FILE_NAME.  */
  +                 return FNM_NOMATCH;
  +               else
  +                 /* One character of the string is consumed in matching
  +                    this ? wildcard, so *??? won't match if there are
  +                    less than three characters.  */
  +                 ++n;
  +             }
  +         }
  +
  +       if (c == L('\0'))
  +         /* The wildcard(s) is/are the last element of the pattern.
  +            If the name is a file name and contains another slash
  +            this means it cannot match, unless the FNM_LEADING_DIR
  +            flag is set.  */
  +         {
  +           int result = (flags & FNM_FILE_NAME) == 0 ? 0 : FNM_NOMATCH;
  +
  +           if (flags & FNM_FILE_NAME)
  +             {
  +               if (flags & FNM_LEADING_DIR)
  +                 result = 0;
  +               else
  +                 {
  +                   if (MEMCHR (n, L('/'), string_end - n) == NULL)
  +                     result = 0;
  +                 }
  +             }
  +
  +           return result;
  +         }
  +       else
  +         {
  +           const CHAR *endp;
  +           struct STRUCT end;
  +
  +           end.pattern = NULL;
  +           endp = MEMCHR (n, (flags & FNM_FILE_NAME) ? L('/') : L('\0'),
  +                          string_end - n);
  +           if (endp == NULL)
  +             endp = string_end;
  +
  +           if (c == L('[')
  +               || (__builtin_expect (flags & FNM_EXTMATCH, 0) != 0
  +                   && (c == L('@') || c == L('+') || c == L('!'))
  +                   && *p == L('(')))
  +             {
  +               int flags2 = ((flags & FNM_FILE_NAME)
  +                             ? flags : (flags & ~FNM_PERIOD));
  +
  +               for (--p; n < endp; ++n, no_leading_period = 0)
  +                 if (FCT (p, n, string_end, no_leading_period, flags2,
  +                          &end) == 0)
  +                   goto found;
  +             }
  +           else if (c == L('/') && (flags & FNM_FILE_NAME))
  +             {
  +               while (n < string_end && *n != L('/'))
  +                 ++n;
  +               if (n < string_end && *n == L('/')
  +                   && (FCT (p, n + 1, string_end, flags & FNM_PERIOD, flags,
  +                            NULL) == 0))
  +                 return 0;
  +             }
  +           else
  +             {
  +               int flags2 = ((flags & FNM_FILE_NAME)
  +                             ? flags : (flags & ~FNM_PERIOD));
  +
  +               if (c == L('\\') && !(flags & FNM_NOESCAPE))
  +                 c = *p;
  +               c = FOLD (c);
  +               for (--p; n < endp; ++n, no_leading_period = 0)
  +                 if (FOLD ((UCHAR) *n) == c
  +                     && (FCT (p, n, string_end, no_leading_period, flags2,
  +                              &end) == 0))
  +                   {
  +                   found:
  +                     if (end.pattern == NULL)
  +                       return 0;
  +                     break;
  +                   }
  +               if (end.pattern != NULL)
  +                 {
  +                   p = end.pattern;
  +                   n = end.string;
  +                   no_leading_period = end.no_leading_period;
  +                   continue;
  +                 }
  +             }
  +         }
  +
  +       /* If we come here no match is possible with the wildcard.  */
  +       return FNM_NOMATCH;
  +
  +     case L('['):
  +       {
  +         /* Nonzero if the sense of the character class is inverted.  */
  +         register int not;
  +         CHAR cold;
  +         UCHAR fn;
  +
  +         if (posixly_correct == 0)
  +           posixly_correct = getenv ("POSIXLY_CORRECT") != NULL ? 1 : -1;
  +
  +         if (n == string_end)
  +           return FNM_NOMATCH;
  +
  +         if (*n == L('.') && no_leading_period)
  +           return FNM_NOMATCH;
  +
  +         if (*n == L('/') && (flags & FNM_FILE_NAME))
  +           /* `/' cannot be matched.  */
  +           return FNM_NOMATCH;
  +
  +         not = (*p == L('!') || (posixly_correct < 0 && *p == L('^')));
  +         if (not)
  +           ++p;
  +
  +         fn = FOLD ((UCHAR) *n);
  +
  +         c = *p++;
  +         for (;;)
  +           {
  +             if (!(flags & FNM_NOESCAPE) && c == L('\\'))
  +               {
  +                 if (*p == L('\0'))
  +                   return FNM_NOMATCH;
  +                 c = FOLD ((UCHAR) *p);
  +                 ++p;
  +
  +                 goto normal_bracket;
  +               }
  +             else if (c == L('[') && *p == L(':'))
  +               {
  +                 /* Leave room for the null.  */
  +                 CHAR str[CHAR_CLASS_MAX_LENGTH + 1];
  +                 size_t c1 = 0;
  +#if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
  +                 wctype_t wt;
  +#endif
  +                 const CHAR *startp = p;
  +
  +                 for (;;)
  +                   {
  +                     if (c1 == CHAR_CLASS_MAX_LENGTH)
  +                       /* The name is too long and therefore the pattern
  +                          is ill-formed.  */
  +                       return FNM_NOMATCH;
  +
  +                     c = *++p;
  +                     if (c == L(':') && p[1] == L(']'))
  +                       {
  +                         p += 2;
  +                         break;
  +                       }
  +                     if (c < L('a') || c >= L('z'))
  +                       {
  +                         /* This cannot possibly be a character class name.
  +                            Match it as a normal range.  */
  +                         p = startp;
  +                         c = L('[');
  +                         goto normal_bracket;
  +                       }
  +                     str[c1++] = c;
  +                   }
  +                 str[c1] = L('\0');
  +
  +#if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
  +                 wt = IS_CHAR_CLASS (str);
  +                 if (wt == 0)
  +                   /* Invalid character class name.  */
  +                   return FNM_NOMATCH;
  +
  +# if defined _LIBC && ! WIDE_CHAR_VERSION
  +                 /* The following code is glibc specific but does
  +                    there a good job in speeding up the code since
  +                    we can avoid the btowc() call.  */
  +                 if (_ISCTYPE ((UCHAR) *n, wt))
  +                   goto matched;
  +# else
  +                 if (ISWCTYPE (BTOWC ((UCHAR) *n), wt))
  +                   goto matched;
  +# endif
  +#else
  +                 if ((STREQ (str, L("alnum")) && ISALNUM ((UCHAR) *n))
  +                     || (STREQ (str, L("alpha")) && ISALPHA ((UCHAR) *n))
  +                     || (STREQ (str, L("blank")) && ISBLANK ((UCHAR) *n))
  +                     || (STREQ (str, L("cntrl")) && ISCNTRL ((UCHAR) *n))
  +                     || (STREQ (str, L("digit")) && ISDIGIT ((UCHAR) *n))
  +                     || (STREQ (str, L("graph")) && ISGRAPH ((UCHAR) *n))
  +                     || (STREQ (str, L("lower")) && ISLOWER ((UCHAR) *n))
  +                     || (STREQ (str, L("print")) && ISPRINT ((UCHAR) *n))
  +                     || (STREQ (str, L("punct")) && ISPUNCT ((UCHAR) *n))
  +                     || (STREQ (str, L("space")) && ISSPACE ((UCHAR) *n))
  +                     || (STREQ (str, L("upper")) && ISUPPER ((UCHAR) *n))
  +                     || (STREQ (str, L("xdigit")) && ISXDIGIT ((UCHAR) *n)))
  +                   goto matched;
  +#endif
  +                 c = *p++;
  +               }
  +#ifdef _LIBC
  +             else if (c == L('[') && *p == L('='))
  +               {
  +                 UCHAR str[1];
  +                 uint32_t nrules =
  +                   _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
  +                 const CHAR *startp = p;
  +
  +                 c = *++p;
  +                 if (c == L('\0'))
  +                   {
  +                     p = startp;
  +                     c = L('[');
  +                     goto normal_bracket;
  +                   }
  +                 str[0] = c;
  +
  +                 c = *++p;
  +                 if (c != L('=') || p[1] != L(']'))
  +                   {
  +                     p = startp;
  +                     c = L('[');
  +                     goto normal_bracket;
  +                   }
  +                 p += 2;
  +
  +                 if (nrules == 0)
  +                   {
  +                     if ((UCHAR) *n == str[0])
  +                       goto matched;
  +                   }
  +                 else
  +                   {
  +                     const int32_t *table;
  +# if WIDE_CHAR_VERSION
  +                     const int32_t *weights;
  +                     const int32_t *extra;
  +# else
  +                     const unsigned char *weights;
  +                     const unsigned char *extra;
  +# endif
  +                     const int32_t *indirect;
  +                     int32_t idx;
  +                     const UCHAR *cp = (const UCHAR *) str;
  +
  +                     /* This #include defines a local function!  */
  +# if WIDE_CHAR_VERSION
  +#  include <locale/weightwc.h>
  +# else
  +#  include <locale/weight.h>
  +# endif
  +
  +# if WIDE_CHAR_VERSION
  +                     table = (const int32_t *)
  +                       _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEWC);
  +                     weights = (const int32_t *)
  +                       _NL_CURRENT (LC_COLLATE, _NL_COLLATE_WEIGHTWC);
  +                     extra = (const int32_t *)
  +                       _NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAWC);
  +                     indirect = (const int32_t *)
  +                       _NL_CURRENT (LC_COLLATE, _NL_COLLATE_INDIRECTWC);
  +# else
  +                     table = (const int32_t *)
  +                       _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB);
  +                     weights = (const unsigned char *)
  +                       _NL_CURRENT (LC_COLLATE, _NL_COLLATE_WEIGHTMB);
  +                     extra = (const unsigned char *)
  +                       _NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAMB);
  +                     indirect = (const int32_t *)
  +                       _NL_CURRENT (LC_COLLATE, _NL_COLLATE_INDIRECTMB);
  +# endif
  +
  +                     idx = findidx (&cp);
  +                     if (idx != 0)
  +                       {
  +                         /* We found a table entry.  Now see whether the
  +                            character we are currently at has the same
  +                            equivalance class value.  */
  +                         int len = weights[idx & 0xffffff];
  +                         int32_t idx2;
  +                         const UCHAR *np = (const UCHAR *) n;
  +
  +                         idx2 = findidx (&np);
  +                         if (idx2 != 0
  +                             && (idx >> 24) == (idx2 >> 24)
  +                             && len == weights[idx2 & 0xffffff])
  +                           {
  +                             int cnt = 0;
  +
  +                             idx &= 0xffffff;
  +                             idx2 &= 0xffffff;
  +
  +                             while (cnt < len
  +                                    && (weights[idx + 1 + cnt]
  +                                        == weights[idx2 + 1 + cnt]))
  +                               ++cnt;
  +
  +                             if (cnt == len)
  +                               goto matched;
  +                           }
  +                       }
  +                   }
  +
  +                 c = *p++;
  +               }
  +#endif
  +             else if (c == L('\0'))
  +               /* [ (unterminated) loses.  */
  +               return FNM_NOMATCH;
  +             else
  +               {
  +                 int is_range = 0;
  +                 int is_seqval = 0;
  +
  +#ifdef _LIBC
  +
  +                 if (c == L('[') && *p == L('.'))
  +                   {
  +                     uint32_t nrules =
  +                       _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
  +                     const CHAR *startp = p;
  +                     size_t c1 = 0;
  +
  +                     while (1)
  +                       {
  +                         c = *++p;
  +                         if (c == L('.') && p[1] == L(']'))
  +                           {
  +                             p += 2;
  +                             break;
  +                           }
  +                         if (c == '\0')
  +                           return FNM_NOMATCH;
  +                         ++c1;
  +                       }
  +
  +                     /* We have to handling the symbols differently in
  +                        ranges since then the collation sequence is
  +                        important.  */
  +                     is_range = *p == L('-') && p[1] != L('\0');
  +
  +                     if (nrules == 0)
  +                       {
  +                         /* There are no names defined in the collation
  +                            data.  Therefore we only accept the trivial
  +                            names consisting of the character itself.  */
  +                         if (c1 != 1)
  +                           return FNM_NOMATCH;
  +
  +                         if (!is_range && *n == startp[1])
  +                           goto matched;
  +
  +                         cold = startp[1];
  +                         c = *p++;
  +                       }
  +                     else
  +                       {
  +                         int32_t table_size;
  +                         const int32_t *symb_table;
  +# ifdef WIDE_CHAR_VERSION
  +                         char str[c1];
  +                         unsigned int strcnt;
  +# else
  +#  define str (startp + 1)
  +# endif
  +                         const unsigned char *extra;
  +                         int32_t idx;
  +                         int32_t elem;
  +                         int32_t second;
  +                         int32_t hash;
  +
  +# ifdef WIDE_CHAR_VERSION
  +                         /* We have to convert the name to a single-byte
  +                            string.  This is possible since the names
  +                            consist of ASCII characters and the internal
  +                            representation is UCS4.  */
  +                         for (strcnt = 0; strcnt < c1; ++strcnt)
  +                           str[strcnt] = startp[1 + strcnt];
  +#endif
  +
  +                         table_size =
  +                           _NL_CURRENT_WORD (LC_COLLATE,
  +                                             _NL_COLLATE_SYMB_HASH_SIZEMB);
  +                         symb_table = (const int32_t *)
  +                           _NL_CURRENT (LC_COLLATE,
  +                                        _NL_COLLATE_SYMB_TABLEMB);
  +                         extra = (const unsigned char *)
  +                           _NL_CURRENT (LC_COLLATE,
  +                                        _NL_COLLATE_SYMB_EXTRAMB);
  +
  +                         /* Locate the character in the hashing table.  */
  +                         hash = elem_hash (str, c1);
  +
  +                         idx = 0;
  +                         elem = hash % table_size;
  +                         if (symb_table[2 * elem] != 0)
  +                           {
  +                             second = hash % (table_size - 2) + 1;
  +
  +                             do
  +                               {
  +                                 /* First compare the hashing value.  */
  +                                 if (symb_table[2 * elem] == hash
  +                                     && (c1
  +                                         == extra[symb_table[2 * elem + 1]])
  +                                     && memcmp (str,
  +                                                &extra[symb_table[2 * elem
  +                                                                  + 1]
  +                                                       + 1], c1) == 0)
  +                                   {
  +                                     /* Yep, this is the entry.  */
  +                                     idx = symb_table[2 * elem + 1];
  +                                     idx += 1 + extra[idx];
  +                                     break;
  +                                   }
  +
  +                                 /* Next entry.  */
  +                                 elem += second;
  +                               }
  +                             while (symb_table[2 * elem] != 0);
  +                           }
  +
  +                         if (symb_table[2 * elem] != 0)
  +                           {
  +                             /* Compare the byte sequence but only if
  +                                this is not part of a range.  */
  +# ifdef WIDE_CHAR_VERSION
  +                             int32_t *wextra;
  +
  +                             idx += 1 + extra[idx];
  +                             /* Adjust for the alignment.  */
  +                             idx = (idx + 3) & ~3;
  +
  +                             wextra = (int32_t *) &extra[idx + 4];
  +# endif
  +
  +                             if (! is_range)
  +                               {
  +# ifdef WIDE_CHAR_VERSION
  +                                 for (c1 = 0;
  +                                      (int32_t) c1 < wextra[idx];
  +                                      ++c1)
  +                                   if (n[c1] != wextra[1 + c1])
  +                                     break;
  +
  +                                 if ((int32_t) c1 == wextra[idx])
  +                                   goto matched;
  +# else
  +                                 for (c1 = 0; c1 < extra[idx]; ++c1)
  +                                   if (n[c1] != extra[1 + c1])
  +                                     break;
  +
  +                                 if (c1 == extra[idx])
  +                                   goto matched;
  +# endif
  +                               }
  +
  +                             /* Get the collation sequence value.  */
  +                             is_seqval = 1;
  +# ifdef WIDE_CHAR_VERSION
  +                             cold = wextra[1 + wextra[idx]];
  +# else
  +                             /* Adjust for the alignment.  */
  +                             idx += 1 + extra[idx];
  +                             idx = (idx + 3) & ~4;
  +                             cold = *((int32_t *) &extra[idx]);
  +# endif
  +
  +                             c = *p++;
  +                           }
  +                         else if (c1 == 1)
  +                           {
  +                             /* No valid character.  Match it as a
  +                                single byte.  */
  +                             if (!is_range && *n == str[0])
  +                               goto matched;
  +
  +                             cold = str[0];
  +                             c = *p++;
  +                           }
  +                         else
  +                           return FNM_NOMATCH;
  +                       }
  +                   }
  +                 else
  +# undef str
  +#endif
  +                   {
  +                     c = FOLD (c);
  +                   normal_bracket:
  +
  +                     /* We have to handling the symbols differently in
  +                        ranges since then the collation sequence is
  +                        important.  */
  +                     is_range = (*p == L('-') && p[1] != L('\0')
  +                                 && p[1] != L(']'));
  +
  +                     if (!is_range && c == fn)
  +                       goto matched;
  +
  +                     /* This is needed if we goto normal_bracket; from
  +                        outside of is_seqval's scope.  */
  +                     is_seqval = 0;
  +                     cold = c;
  +                     c = *p++;
  +                   }
  +
  +                 if (c == L('-') && *p != L(']'))
  +                   {
  +#if _LIBC
  +                     /* We have to find the collation sequence
  +                        value for C.  Collation sequence is nothing
  +                        we can regularly access.  The sequence
  +                        value is defined by the order in which the
  +                        definitions of the collation values for the
  +                        various characters appear in the source
  +                        file.  A strange concept, nowhere
  +                        documented.  */
  +                     uint32_t fcollseq;
  +                     uint32_t lcollseq;
  +                     UCHAR cend = *p++;
  +
  +# ifdef WIDE_CHAR_VERSION
  +                     /* Search in the `names' array for the characters.  */
  +                     fcollseq = __collseq_table_lookup (collseq, fn);
  +                     if (fcollseq == ~((uint32_t) 0))
  +                       /* XXX We don't know anything about the character
  +                          we are supposed to match.  This means we are
  +                          failing.  */
  +                       goto range_not_matched;
  +
  +                     if (is_seqval)
  +                       lcollseq = cold;
  +                     else
  +                       lcollseq = __collseq_table_lookup (collseq, cold);
  +# else
  +                     fcollseq = collseq[fn];
  +                     lcollseq = is_seqval ? cold : collseq[(UCHAR) cold];
  +# endif
  +
  +                     is_seqval = 0;
  +                     if (cend == L('[') && *p == L('.'))
  +                       {
  +                         uint32_t nrules =
  +                           _NL_CURRENT_WORD (LC_COLLATE,
  +                                             _NL_COLLATE_NRULES);
  +                         const CHAR *startp = p;
  +                         size_t c1 = 0;
  +
  +                         while (1)
  +                           {
  +                             c = *++p;
  +                             if (c == L('.') && p[1] == L(']'))
  +                               {
  +                                 p += 2;
  +                                 break;
  +                               }
  +                             if (c == '\0')
  +                               return FNM_NOMATCH;
  +                             ++c1;
  +                           }
  +
  +                         if (nrules == 0)
  +                           {
  +                             /* There are no names defined in the
  +                                collation data.  Therefore we only
  +                                accept the trivial names consisting
  +                                of the character itself.  */
  +                             if (c1 != 1)
  +                               return FNM_NOMATCH;
  +
  +                             cend = startp[1];
  +                           }
  +                         else
  +                           {
  +                             int32_t table_size;
  +                             const int32_t *symb_table;
  +# ifdef WIDE_CHAR_VERSION
  +                             char str[c1];
  +                             unsigned int strcnt;
  +# else
  +#  define str (startp + 1)
  +# endif
  +                             const unsigned char *extra;
  +                             int32_t idx;
  +                             int32_t elem;
  +                             int32_t second;
  +                             int32_t hash;
  +
  +# ifdef WIDE_CHAR_VERSION
  +                             /* We have to convert the name to a single-byte
  +                                string.  This is possible since the names
  +                                consist of ASCII characters and the internal
  +                                representation is UCS4.  */
  +                             for (strcnt = 0; strcnt < c1; ++strcnt)
  +                               str[strcnt] = startp[1 + strcnt];
  +# endif
  +
  +                             table_size =
  +                               _NL_CURRENT_WORD (LC_COLLATE,
  +                                                 
_NL_COLLATE_SYMB_HASH_SIZEMB);
  +                             symb_table = (const int32_t *)
  +                               _NL_CURRENT (LC_COLLATE,
  +                                            _NL_COLLATE_SYMB_TABLEMB);
  +                             extra = (const unsigned char *)
  +                               _NL_CURRENT (LC_COLLATE,
  +                                            _NL_COLLATE_SYMB_EXTRAMB);
  +
  +                             /* Locate the character in the hashing
  +                                   table.  */
  +                             hash = elem_hash (str, c1);
  +
  +                             idx = 0;
  +                             elem = hash % table_size;
  +                             if (symb_table[2 * elem] != 0)
  +                               {
  +                                 second = hash % (table_size - 2) + 1;
  +
  +                                 do
  +                                   {
  +                                     /* First compare the hashing value.  */
  +                                     if (symb_table[2 * elem] == hash
  +                                         && (c1
  +                                             == extra[symb_table[2 * elem + 
1]])
  +                                         && memcmp (str,
  +                                                    &extra[symb_table[2 * 
elem + 1]
  +                                                           + 1], c1) == 0)
  +                                       {
  +                                         /* Yep, this is the entry.  */
  +                                         idx = symb_table[2 * elem + 1];
  +                                         idx += 1 + extra[idx];
  +                                         break;
  +                                       }
  +
  +                                     /* Next entry.  */
  +                                     elem += second;
  +                                   }
  +                                 while (symb_table[2 * elem] != 0);
  +                               }
  +
  +                             if (symb_table[2 * elem] != 0)
  +                               {
  +                                 /* Compare the byte sequence but only if
  +                                    this is not part of a range.  */
  +# ifdef WIDE_CHAR_VERSION
  +                                 int32_t *wextra;
  +
  +                                 idx += 1 + extra[idx];
  +                                 /* Adjust for the alignment.  */
  +                                 idx = (idx + 3) & ~4;
  +
  +                                 wextra = (int32_t *) &extra[idx + 4];
  +# endif
  +                                 /* Get the collation sequence value.  */
  +                                 is_seqval = 1;
  +# ifdef WIDE_CHAR_VERSION
  +                                 cend = wextra[1 + wextra[idx]];
  +# else
  +                                 /* Adjust for the alignment.  */
  +                                 idx += 1 + extra[idx];
  +                                 idx = (idx + 3) & ~4;
  +                                 cend = *((int32_t *) &extra[idx]);
  +# endif
  +                               }
  +                             else if (symb_table[2 * elem] != 0 && c1 == 1)
  +                               {
  +                                 cend = str[0];
  +                                 c = *p++;
  +                               }
  +                             else
  +                               return FNM_NOMATCH;
  +                           }
  +# undef str
  +                       }
  +                     else
  +                       {
  +                         if (!(flags & FNM_NOESCAPE) && cend == L('\\'))
  +                           cend = *p++;
  +                         if (cend == L('\0'))
  +                           return FNM_NOMATCH;
  +                         cend = FOLD (cend);
  +                       }
  +
  +                     /* XXX It is not entirely clear to me how to handle
  +                        characters which are not mentioned in the
  +                        collation specification.  */
  +                     if (
  +# ifdef WIDE_CHAR_VERSION
  +                         lcollseq == 0xffffffff ||
  +# endif
  +                         lcollseq <= fcollseq)
  +                       {
  +                         /* We have to look at the upper bound.  */
  +                         uint32_t hcollseq;
  +
  +                         if (is_seqval)
  +                           hcollseq = cend;
  +                         else
  +                           {
  +# ifdef WIDE_CHAR_VERSION
  +                             hcollseq =
  +                               __collseq_table_lookup (collseq, cend);
  +                             if (hcollseq == ~((uint32_t) 0))
  +                               {
  +                                 /* Hum, no information about the upper
  +                                    bound.  The matching succeeds if the
  +                                    lower bound is matched exactly.  */
  +                                 if (lcollseq != fcollseq)
  +                                   goto range_not_matched;
  +
  +                                 goto matched;
  +                               }
  +# else
  +                             hcollseq = collseq[cend];
  +# endif
  +                           }
  +
  +                         if (lcollseq <= hcollseq && fcollseq <= hcollseq)
  +                           goto matched;
  +                       }
  +# ifdef WIDE_CHAR_VERSION
  +                   range_not_matched:
  +# endif
  +#else
  +                     /* We use a boring value comparison of the character
  +                        values.  This is better than comparing using
  +                        `strcoll' since the latter would have surprising
  +                        and sometimes fatal consequences.  */
  +                     UCHAR cend = *p++;
  +
  +                     if (!(flags & FNM_NOESCAPE) && cend == L('\\'))
  +                       cend = *p++;
  +                     if (cend == L('\0'))
  +                       return FNM_NOMATCH;
  +
  +                     /* It is a range.  */
  +                     if (cold <= fn && fn <= cend)
  +                       goto matched;
  +#endif
  +
  +                     c = *p++;
  +                   }
  +               }
  +
  +             if (c == L(']'))
  +               break;
  +           }
  +
  +         if (!not)
  +           return FNM_NOMATCH;
  +         break;
  +
  +       matched:
  +         /* Skip the rest of the [...] that already matched.  */
  +         do
  +           {
  +           ignore_next:
  +             c = *p++;
  +
  +             if (c == L('\0'))
  +               /* [... (unterminated) loses.  */
  +               return FNM_NOMATCH;
  +
  +             if (!(flags & FNM_NOESCAPE) && c == L('\\'))
  +               {
  +                 if (*p == L('\0'))
  +                   return FNM_NOMATCH;
  +                 /* XXX 1003.2d11 is unclear if this is right.  */
  +                 ++p;
  +               }
  +             else if (c == L('[') && *p == L(':'))
  +               {
  +                 int c1 = 0;
  +                 const CHAR *startp = p;
  +
  +                 while (1)
  +                   {
  +                     c = *++p;
  +                     if (++c1 == CHAR_CLASS_MAX_LENGTH)
  +                       return FNM_NOMATCH;
  +
  +                     if (*p == L(':') && p[1] == L(']'))
  +                       break;
  +
  +                     if (c < L('a') || c >= L('z'))
  +                       {
  +                         p = startp;
  +                         goto ignore_next;
  +                       }
  +                   }
  +                 p += 2;
  +                 c = *p++;
  +               }
  +             else if (c == L('[') && *p == L('='))
  +               {
  +                 c = *++p;
  +                 if (c == L('\0'))
  +                   return FNM_NOMATCH;
  +                 c = *++p;
  +                 if (c != L('=') || p[1] != L(']'))
  +                   return FNM_NOMATCH;
  +                 p += 2;
  +                 c = *p++;
  +               }
  +             else if (c == L('[') && *p == L('.'))
  +               {
  +                 ++p;
  +                 while (1)
  +                   {
  +                     c = *++p;
  +                     if (c == '\0')
  +                       return FNM_NOMATCH;
  +
  +                     if (*p == L('.') && p[1] == L(']'))
  +                       break;
  +                   }
  +                 p += 2;
  +                 c = *p++;
  +               }
  +           }
  +         while (c != L(']'));
  +         if (not)
  +           return FNM_NOMATCH;
  +       }
  +       break;
  +
  +     case L('+'):
  +     case L('@'):
  +     case L('!'):
  +       if (__builtin_expect (flags & FNM_EXTMATCH, 0) && *p == '(')
  +         {
  +           int res;
  +
  +           res = EXT (c, p, n, string_end, no_leading_period, flags);
  +           if (res != -1)
  +             return res;
  +         }
  +       goto normal_match;
  +
  +     case L('/'):
  +       if (NO_LEADING_PERIOD (flags))
  +         {
  +           if (n == string_end || c != (UCHAR) *n)
  +             return FNM_NOMATCH;
  +
  +           new_no_leading_period = 1;
  +           break;
  +         }
  +       /* FALLTHROUGH */
  +     default:
  +     normal_match:
  +       if (n == string_end || c != FOLD ((UCHAR) *n))
  +         return FNM_NOMATCH;
  +     }
  +
  +      no_leading_period = new_no_leading_period;
  +      ++n;
  +    }
  +
  +  if (n == string_end)
  +    return 0;
  +
  +  if ((flags & FNM_LEADING_DIR) && n != string_end && *n == L('/'))
  +    /* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz".  
*/
  +    return 0;
  +
  +  return FNM_NOMATCH;
  +}
  +
  +
  +static const CHAR *
  +internal_function
  +END (const CHAR *pattern)
  +{
  +  const CHAR *p = pattern;
  +
  +  while (1)
  +    if (*++p == L('\0'))
  +      /* This is an invalid pattern.  */
  +      return pattern;
  +    else if (*p == L('['))
  +      {
  +     /* Handle brackets special.  */
  +     if (posixly_correct == 0)
  +       posixly_correct = getenv ("POSIXLY_CORRECT") != NULL ? 1 : -1;
  +
  +     /* Skip the not sign.  We have to recognize it because of a possibly
  +        following ']'.  */
  +     if (*++p == L('!') || (posixly_correct < 0 && *p == L('^')))
  +       ++p;
  +     /* A leading ']' is recognized as such.  */
  +     if (*p == L(']'))
  +       ++p;
  +     /* Skip over all characters of the list.  */
  +     while (*p != L(']'))
  +       if (*p++ == L('\0'))
  +         /* This is no valid pattern.  */
  +         return pattern;
  +      }
  +    else if ((*p == L('?') || *p == L('*') || *p == L('+') || *p == L('@')
  +           || *p == L('!')) && p[1] == L('('))
  +      p = END (p + 1);
  +    else if (*p == L(')'))
  +      break;
  +
  +  return p + 1;
  +}
  +
  +
  +static int
  +internal_function
  +EXT (INT opt, const CHAR *pattern, const CHAR *string, const CHAR 
*string_end,
  +     int no_leading_period, int flags)
  +{
  +  const CHAR *startp;
  +  int level;
  +  struct patternlist
  +  {
  +    struct patternlist *next;
  +    CHAR str[0];
  +  } *list = NULL;
  +  struct patternlist **lastp = &list;
  +  size_t pattern_len = STRLEN (pattern);
  +  const CHAR *p;
  +  const CHAR *rs;
  +
  +  /* Parse the pattern.  Store the individual parts in the list.  */
  +  level = 0;
  +  for (startp = p = pattern + 1; level >= 0; ++p)
  +    if (*p == L('\0'))
  +      /* This is an invalid pattern.  */
  +      return -1;
  +    else if (*p == L('['))
  +      {
  +     /* Handle brackets special.  */
  +     if (posixly_correct == 0)
  +       posixly_correct = getenv ("POSIXLY_CORRECT") != NULL ? 1 : -1;
  +
  +     /* Skip the not sign.  We have to recognize it because of a possibly
  +        following ']'.  */
  +     if (*++p == L('!') || (posixly_correct < 0 && *p == L('^')))
  +       ++p;
  +     /* A leading ']' is recognized as such.  */
  +     if (*p == L(']'))
  +       ++p;
  +     /* Skip over all characters of the list.  */
  +     while (*p != L(']'))
  +       if (*p++ == L('\0'))
  +         /* This is no valid pattern.  */
  +         return -1;
  +      }
  +    else if ((*p == L('?') || *p == L('*') || *p == L('+') || *p == L('@')
  +           || *p == L('!')) && p[1] == L('('))
  +      /* Remember the nesting level.  */
  +      ++level;
  +    else if (*p == L(')'))
  +      {
  +     if (level-- == 0)
  +       {
  +         /* This means we found the end of the pattern.  */
  +#define NEW_PATTERN \
  +         struct patternlist *newp;                                         \
  +                                                                           \
  +         if (opt == L('?') || opt == L('@'))                               \
  +           newp = alloca (sizeof (struct patternlist)                      \
  +                          + (pattern_len * sizeof (CHAR)));                \
  +         else                                                              \
  +           newp = alloca (sizeof (struct patternlist)                      \
  +                          + ((p - startp + 1) * sizeof (CHAR)));           \
  +         *((CHAR *) MEMPCPY (newp->str, startp, p - startp)) = L('\0');    \
  +         newp->next = NULL;                                                \
  +         *lastp = newp;                                                    \
  +         lastp = &newp->next
  +         NEW_PATTERN;
  +       }
  +      }
  +    else if (*p == L('|'))
  +      {
  +     if (level == 0)
  +       {
  +         NEW_PATTERN;
  +         startp = p + 1;
  +       }
  +      }
  +  assert (list != NULL);
  +  assert (p[-1] == L(')'));
  +#undef NEW_PATTERN
  +
  +  switch (opt)
  +    {
  +    case L('*'):
  +      if (FCT (p, string, string_end, no_leading_period, flags, NULL) == 0)
  +     return 0;
  +      /* FALLTHROUGH */
  +
  +    case L('+'):
  +      do
  +     {
  +       for (rs = string; rs <= string_end; ++rs)
  +         /* First match the prefix with the current pattern with the
  +            current pattern.  */
  +         if (FCT (list->str, string, rs, no_leading_period,
  +                  (flags & FNM_FILE_NAME) ? flags : (flags & ~FNM_PERIOD),
  +                  NULL) == 0
  +             /* This was successful.  Now match the rest with the rest
  +                of the pattern.  */
  +             && (FCT (p, rs, string_end,
  +                      rs == string
  +                      ? no_leading_period
  +                      : rs[-1] == '/' && NO_LEADING_PERIOD (flags) ? 1 : 0,
  +                      (flags & FNM_FILE_NAME)
  +                      ? flags : (flags & ~FNM_PERIOD), NULL) == 0
  +                 /* This didn't work.  Try the whole pattern.  */
  +                 || (rs != string
  +                     && FCT (pattern - 1, rs, string_end,
  +                             rs == string
  +                             ? no_leading_period
  +                             : (rs[-1] == '/' && NO_LEADING_PERIOD (flags)
  +                                ? 1 : 0),
  +                             (flags & FNM_FILE_NAME)
  +                             ? flags : (flags & ~FNM_PERIOD), NULL) == 0)))
  +           /* It worked.  Signal success.  */
  +           return 0;
  +     }
  +      while ((list = list->next) != NULL);
  +
  +      /* None of the patterns lead to a match.  */
  +      return FNM_NOMATCH;
  +
  +    case L('?'):
  +      if (FCT (p, string, string_end, no_leading_period, flags, NULL) == 0)
  +     return 0;
  +      /* FALLTHROUGH */
  +
  +    case L('@'):
  +      do
  +     /* I cannot believe it but `strcat' is actually acceptable
  +        here.  Match the entire string with the prefix from the
  +        pattern list and the rest of the pattern following the
  +        pattern list.  */
  +     if (FCT (STRCAT (list->str, p), string, string_end,
  +              no_leading_period,
  +              (flags & FNM_FILE_NAME) ? flags : (flags & ~FNM_PERIOD),
  +              NULL) == 0)
  +       /* It worked.  Signal success.  */
  +       return 0;
  +      while ((list = list->next) != NULL);
  +
  +      /* None of the patterns lead to a match.  */
  +      return FNM_NOMATCH;
  +
  +    case L('!'):
  +      for (rs = string; rs <= string_end; ++rs)
  +     {
  +       struct patternlist *runp;
  +
  +       for (runp = list; runp != NULL; runp = runp->next)
  +         if (FCT (runp->str, string, rs,  no_leading_period,
  +                  (flags & FNM_FILE_NAME) ? flags : (flags & ~FNM_PERIOD),
  +                  NULL) == 0)
  +           break;
  +
  +       /* If none of the patterns matched see whether the rest does.  */
  +       if (runp == NULL
  +           && (FCT (p, rs, string_end,
  +                    rs == string
  +                    ? no_leading_period
  +                    : rs[-1] == '/' && NO_LEADING_PERIOD (flags) ? 1 : 0,
  +                    (flags & FNM_FILE_NAME) ? flags : (flags & ~FNM_PERIOD),
  +                    NULL) == 0))
  +         /* This is successful.  */
  +         return 0;
  +     }
  +
  +      /* None of the patterns together with the rest of the pattern
  +      lead to a match.  */
  +      return FNM_NOMATCH;
  +
  +    default:
  +      assert (! "Invalid extended matching operator");
  +      break;
  +    }
  +
  +  return -1;
  +}
  +
  +
  +#undef FOLD
  +#undef CHAR
  +#undef UCHAR
  +#undef INT
  +#undef FCT
  +#undef EXT
  +#undef END
  +#undef STRUCT
  +#undef MEMPCPY
  +#undef MEMCHR
  +#undef STRCOLL
  +#undef STRLEN
  +#undef STRCAT
  +#undef L
  +#undef BTOWC
  @@ .
  patch -p0 <<'@@ .'
  Index: rpm/misc/glob.c
  ============================================================================
  $ cvs diff -u -r0 -r1.22.2.2 glob.c
  --- /dev/null 2016-06-19 08:45:30.000000000 +0200
  +++ glob.c    2016-06-19 08:48:47.349275632 +0200
  @@ -0,0 +1,1268 @@
  +/*@-bounds@*/
  +/*@-branchstate@*/
  +/*@-compdef@*/
  +/*@-immediatetrans@*/
  +/*@-internalglobs@*/
  +/*@-loopswitchbreak@*/
  +/*@-modnomods@*/
  +/*@-mods@*/
  +/*@-moduncon@*/
  +/*@-modunconnomods@*/
  +/*@-noeffectuncon@*/
  +/*@-nullpass@*/
  +/*@-onlytrans@*/
  +/*@-protoparammatch@*/
  +/*@-retalias@*/
  +/*@-retvalint@*/
  +/*@-shadow@*/
  +/*@-sizeoftype@*/
  +/*@-temptrans@*/
  +/*@-type@*/
  +/*@-unqualifiedtrans@*/
  +/*@-unrecog@*/
  +
  +/* Copyright (C) 1991,92,93,94,95,96,97,98,99 Free Software Foundation, Inc.
  +
  +   This library is free software; you can redistribute it and/or
  +   modify it under the terms of the GNU Library General Public License as
  +   published by the Free Software Foundation; either version 2 of the
  +   License, or (at your option) any later version.
  +
  +   This library is distributed in the hope that it will be useful,
  +   but WITHOUT ANY WARRANTY; without even the implied warranty of
  +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  +   Library General Public License for more details.
  +
  +   You should have received a copy of the GNU Library General Public
  +   License along with this library; see the file COPYING.LIB.  If not,
  +   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  +   Boston, MA 02111-1307, USA.  */
  +
  +/* AIX requires this to be the first thing in the file.  */
  +#if defined _AIX && !defined __GNUC__
  + #pragma alloca
  +#endif
  +
  +/*@access DIR@*/
  +
  +# include "system.h"
  +
  +/* Needed for offsetof() */
  +# include <stddef.h>
  +
  +# include <assert.h>
  +
  +#undef __alloca
  +#define      __alloca        alloca
  +#define      __stat          stat
  +#define      NAMLEN(_d)      NLENGTH(_d)
  +
  +/* If the system has the `struct dirent64' type we use it internally.  */
  +# if defined HAVE_DIRENT_H || defined __GNU_LIBRARY__
  +#  define CONVERT_D_NAMLEN(d64, d32)
  +# else
  +#  define CONVERT_D_NAMLEN(d64, d32) \
  +  (d64)->d_namlen = (d32)->d_namlen;
  +# endif
  +
  +# if (defined POSIX || defined WINDOWS32) && !defined __GNU_LIBRARY__
  +#  define CONVERT_D_INO(d64, d32)
  +# else
  +#  define CONVERT_D_INO(d64, d32) \
  +  (d64)->d_ino = (d32)->d_ino;
  +# endif
  +
  +# ifdef _DIRENT_HAVE_D_TYPE
  +#  define CONVERT_D_TYPE(d64, d32) \
  +  (d64)->d_type = (d32)->d_type;
  +# else
  +#  define CONVERT_D_TYPE(d64, d32)
  +# endif
  +
  +# define CONVERT_DIRENT_DIRENT64(d64, d32) \
  +  memcpy ((d64)->d_name, (d32)->d_name, NAMLEN (d32) + 1);                 \
  +  CONVERT_D_NAMLEN (d64, d32)                                                
      \
  +  CONVERT_D_INO (d64, d32)                                                 \
  +  CONVERT_D_TYPE (d64, d32)
  +
  +#if (defined POSIX || defined WINDOWS32) && !defined __GNU_LIBRARY__
  +/* Posix does not require that the d_ino field be present, and some
  +   systems do not provide it. */
  +# define REAL_DIR_ENTRY(dp) 1
  +#else
  +# define REAL_DIR_ENTRY(dp) (dp->d_ino != 0)
  +#endif /* POSIX */
  +
  +#include <errno.h>
  +#ifndef __set_errno
  +# define __set_errno(val) errno = (val)
  +#endif
  +
  +#if !defined(NAME_MAX)       /* XXX OpenIndiana needs this. */
  +#define      NAME_MAX        255
  +#endif
  +
  +/* Outcomment the following line for production quality code.  */
  +/* #define NDEBUG 1 */
  +
  +#define GLOB_INTERFACE_VERSION 1
  +
  +/*@null@*/
  +static inline const char *next_brace_sub __P ((const char *begin))
  +     /*@*/;
  +static int glob_in_dir __P ((const char *pattern, const char *directory,
  +                          int flags,
  +                          int (*errfunc) (const char *, int),
  +                          glob_t *pglob))
  +     /*@globals fileSystem @*/
  +     /*@modifies fileSystem @*/;
  +static int prefix_array __P ((const char *prefix, char **array, size_t n))
  +     /*@*/;
  +static int collated_compare __P ((const __ptr_t, const __ptr_t))
  +     /*@*/;
  +
  +
  +/* Find the end of the sub-pattern in a brace expression.  We define
  +   this as an inline function if the compiler permits.  */
  +static inline const char *
  +next_brace_sub (const char *begin)
  +{
  +  unsigned int depth = 0;
  +  const char *cp = begin;
  +
  +  while (1)
  +    {
  +      if (depth == 0)
  +     {
  +       if (*cp != ',' && *cp != '}' && *cp != '\0')
  +         {
  +           if (*cp == '{')
  +             ++depth;
  +           ++cp;
  +           continue;
  +         }
  +     }
  +      else
  +     {
  +       while (*cp != '\0' && (*cp != '}' || depth > 0))
  +         {
  +           if (*cp == '}')
  +             --depth;
  +           ++cp;
  +         }
  +       if (*cp == '\0')
  +         /* An incorrectly terminated brace expression.  */
  +         return NULL;
  +
  +       continue;
  +     }
  +      break;
  +    }
  +
  +  return cp;
  +}
  +
  +static int __glob_pattern_p (const char *pattern, int quote);
  +
  +/* Do glob searching for PATTERN, placing results in PGLOB.
  +   The bits defined above may be set in FLAGS.
  +   If a directory cannot be opened or read and ERRFUNC is not nil,
  +   it is called with the pathname that caused the error, and the
  +   `errno' value from the failing call; if it returns non-zero
  +   `glob' returns GLOB_ABORTED; if it returns zero, the error is ignored.
  +   If memory cannot be allocated for PGLOB, GLOB_NOSPACE is returned.
  +   Otherwise, `glob' returns zero.  */
  +int
  +glob (const char *pattern, int flags,
  +     int (*errfunc) __P ((const char *, int)), glob_t *pglob)
  +{
  +  const char *filename;
  +  const char *dirname;
  +  size_t dirlen;
  +  int status;
  +  int oldcount;
  +
  +  if (pattern == NULL || pglob == NULL || (flags & ~__GLOB_FLAGS) != 0)
  +    {
  +      __set_errno (EINVAL);
  +      return -1;
  +    }
  +
  +  if (flags & GLOB_BRACE)
  +    {
  +      const char *begin = strchr (pattern, '{');
  +      if (begin != NULL)
  +     {
  +       /* Allocate working buffer large enough for our work.  Note that
  +         we have at least an opening and closing brace.  */
  +       int firstc;
  +       char *alt_start;
  +       const char *p;
  +       const char *next;
  +       const char *rest;
  +       size_t rest_len;
  +#ifdef __GNUC__
  +       char onealt[strlen (pattern) - 1];
  +#else
  +       char *onealt = (char *) malloc (strlen (pattern) - 1);
  +       if (onealt == NULL)
  +         {
  +           if (!(flags & GLOB_APPEND))
  +             globfree (pglob);
  +           return GLOB_NOSPACE;
  +         }
  +#endif
  +
  +       /* We know the prefix for all sub-patterns.  */
  +#ifdef HAVE_MEMPCPY
  +       alt_start = (char *) mempcpy (onealt, pattern, begin - pattern);
  +#else
  +       memcpy (onealt, pattern, begin - pattern);
  +       alt_start = &onealt[begin - pattern];
  +#endif
  +
  +       /* Find the first sub-pattern and at the same time find the
  +          rest after the closing brace.  */
  +       next = next_brace_sub (begin + 1);
  +       if (next == NULL)
  +         {
  +           /* It is an illegal expression.  */
  +#ifndef __GNUC__
  +           free (onealt);
  +#endif
  +           return glob (pattern, flags & ~GLOB_BRACE, errfunc, pglob);
  +         }
  +
  +       /* Now find the end of the whole brace expression.  */
  +       rest = next;
  +       while (*rest != '}')
  +         {
  +           rest = next_brace_sub (rest + 1);
  +           if (rest == NULL)
  +             {
  +               /* It is an illegal expression.  */
  +#ifndef __GNUC__
  +               free (onealt);
  +#endif
  +               return glob (pattern, flags & ~GLOB_BRACE, errfunc, pglob);
  +             }
  +         }
  +       /* Please note that we now can be sure the brace expression
  +          is well-formed.  */
  +       rest_len = strlen (++rest) + 1;
  +
  +       /* We have a brace expression.  BEGIN points to the opening {,
  +          NEXT points past the terminator of the first element, and END
  +          points past the final }.  We will accumulate result names from
  +          recursive runs for each brace alternative in the buffer using
  +          GLOB_APPEND.  */
  +
  +       if (!(flags & GLOB_APPEND))
  +         {
  +           /* This call is to set a new vector, so clear out the
  +              vector so we can append to it.  */
  +           pglob->gl_pathc = 0;
  +           pglob->gl_pathv = NULL;
  +         }
  +       firstc = pglob->gl_pathc;
  +
  +       p = begin + 1;
  +       while (1)
  +         {
  +           int result;
  +
  +           /* Construct the new glob expression.  */
  +#ifdef HAVE_MEMPCPY
  +           mempcpy (mempcpy (alt_start, p, next - p), rest, rest_len);
  +#else
  +           memcpy (alt_start, p, next - p);
  +           memcpy (&alt_start[next - p], rest, rest_len);
  +#endif
  +
  +           result = glob (onealt,
  +                          ((flags & ~(GLOB_NOCHECK|GLOB_NOMAGIC))
  +                           | GLOB_APPEND), errfunc, pglob);
  +
  +           /* If we got an error, return it.  */
  +           if (result && result != GLOB_NOMATCH)
  +             {
  +#ifndef __GNUC__
  +               free (onealt);
  +#endif
  +               if (!(flags & GLOB_APPEND))
  +                 globfree (pglob);
  +               return result;
  +             }
  +
  +           if (*next == '}')
  +             /* We saw the last entry.  */
  +             break;
  +
  +           p = next + 1;
  +           next = next_brace_sub (p);
  +           assert (next != NULL);
  +         }
  +
  +#ifndef __GNUC__
  +       free (onealt);
  +#endif
  +
  +       if ((int)pglob->gl_pathc != firstc)
  +         /* We found some entries.  */
  +         return 0;
  +       else if (!(flags & (GLOB_NOCHECK|GLOB_NOMAGIC)))
  +         return GLOB_NOMATCH;
  +     }
  +    }
  +
  +  /* Find the filename.  */
  +  filename = strrchr (pattern, '/');
  +#if defined __MSDOS__ || defined WINDOWS32
  +  /* The case of "d:pattern".  Since `:' is not allowed in
  +     file names, we can safely assume that wherever it
  +     happens in pattern, it signals the filename part.  This
  +     is so we could some day support patterns like "[a-z]:foo".  */
  +  if (filename == NULL)
  +    filename = strchr (pattern, ':');
  +#endif /* __MSDOS__ || WINDOWS32 */
  +  if (filename == NULL)
  +    {
  +      /* This can mean two things: a simple name or "~name".  The latter
  +      case is nothing but a notation for a directory.  */
  +      if ((flags & (GLOB_TILDE|GLOB_TILDE_CHECK)) && pattern[0] == '~')
  +     {
  +       dirname = pattern;
  +       dirlen = strlen (pattern);
  +
  +       /* Set FILENAME to NULL as a special flag.  This is ugly but
  +          other solutions would require much more code.  We test for
  +          this special case below.  */
  +       filename = NULL;
  +     }
  +      else
  +     {
  +       filename = pattern;
  +#ifdef _AMIGA
  +       dirname = "";
  +#else
  +       dirname = ".";
  +#endif
  +       dirlen = 0;
  +     }
  +    }
  +  else if (filename == pattern)
  +    {
  +      /* "/pattern".  */
  +      dirname = "/";
  +      dirlen = 1;
  +      ++filename;
  +    }
  +  else
  +    {
  +      char *newp;
  +      dirlen = filename - pattern;
  +#if defined __MSDOS__ || defined WINDOWS32
  +      if (*filename == ':'
  +       || (filename > pattern + 1 && filename[-1] == ':'))
  +     {
  +       char *drive_spec;
  +
  +       ++dirlen;
  +       drive_spec = (char *) __alloca (dirlen + 1);
  +#ifdef HAVE_MEMPCPY
  +       *((char *) mempcpy (drive_spec, pattern, dirlen)) = '\0';
  +#else
  +       memcpy (drive_spec, pattern, dirlen);
  +       drive_spec[dirlen] = '\0';
  +#endif
  +       /* For now, disallow wildcards in the drive spec, to
  +          prevent infinite recursion in glob.  */
  +       if (__glob_pattern_p (drive_spec, !(flags & GLOB_NOESCAPE)))
  +         return GLOB_NOMATCH;
  +       /* If this is "d:pattern", we need to copy `:' to DIRNAME
  +          as well.  If it's "d:/pattern", don't remove the slash
  +          from "d:/", since "d:" and "d:/" are not the same.*/
  +     }
  +#endif
  +      newp = (char *) __alloca (dirlen + 1);
  +#ifdef HAVE_MEMPCPY
  +      *((char *) mempcpy (newp, pattern, dirlen)) = '\0';
  +#else
  +      memcpy (newp, pattern, dirlen);
  +      newp[dirlen] = '\0';
  +#endif
  +      dirname = newp;
  +      ++filename;
  +
  +      if (filename[0] == '\0'
  +#if defined __MSDOS__ || defined WINDOWS32
  +          && dirname[dirlen - 1] != ':'
  +       && (dirlen < 3 || dirname[dirlen - 2] != ':'
  +           || dirname[dirlen - 1] != '/')
  +#endif
  +       && dirlen > 1)
  +     /* "pattern/".  Expand "pattern", appending slashes.  */
  +     {
  +       int val = glob (dirname, flags | GLOB_MARK, errfunc, pglob);
  +       if (val == 0)
  +         pglob->gl_flags = ((pglob->gl_flags & ~GLOB_MARK)
  +                            | (flags & GLOB_MARK));
  +       return val;
  +     }
  +    }
  +
  +  if (!(flags & GLOB_APPEND))
  +    {
  +      pglob->gl_pathc = 0;
  +      pglob->gl_pathv = NULL;
  +    }
  +
  +  oldcount = pglob->gl_pathc;
  +
  +#ifndef VMS
  +  if ((flags & (GLOB_TILDE|GLOB_TILDE_CHECK)) && dirname[0] == '~')
  +    {
  +      if (dirname[1] == '\0' || dirname[1] == '/')
  +     {
  +       /* Look up home directory.  */
  +       const char *home_dir = getenv ("HOME");
  +# ifdef _AMIGA
  +       if (home_dir == NULL || home_dir[0] == '\0')
  +         home_dir = "SYS:";
  +# else
  +#  ifdef WINDOWS32
  +       if (home_dir == NULL || home_dir[0] == '\0')
  +            home_dir = "c:/users/default"; /* poor default */
  +#  else
  +       if (home_dir == NULL || home_dir[0] == '\0')
  +         {
  +           int success;
  +           char *name;
  +#   if defined HAVE_GETLOGIN_R || defined _LIBC
  +           size_t buflen = sysconf (_SC_LOGIN_NAME_MAX) + 1;
  +
  +           if (buflen == 0)
  +             /* `sysconf' does not support _SC_LOGIN_NAME_MAX.  Try
  +                a moderate value.  */
  +             buflen = 20;
  +           name = (char *) __alloca (buflen);
  +
  +           success = getlogin_r (name, buflen) >= 0;
  +#   else
  +           success = (name = getlogin ()) != NULL;
  +#   endif
  +           if (success)
  +             {
  +               struct passwd *p;
  +#   if defined HAVE_GETPWNAM_R || defined _LIBC
  +               size_t pwbuflen = sysconf (_SC_GETPW_R_SIZE_MAX);
  +               char *pwtmpbuf;
  +               struct passwd pwbuf;
  +               int save = errno;
  +
  +               if (pwbuflen == -1)
  +                 /* `sysconf' does not support _SC_GETPW_R_SIZE_MAX.
  +                    Try a moderate value.  */
  +                 pwbuflen = 1024;
  +               pwtmpbuf = (char *) __alloca (pwbuflen);
  +
  +               while (getpwnam_r (name, &pwbuf, pwtmpbuf, pwbuflen, &p)
  +                      != 0)
  +                 {
  +                   if (errno != ERANGE)
  +                     {
  +                       p = NULL;
  +                       break;
  +                     }
  +                   pwbuflen *= 2;
  +                   pwtmpbuf = (char *) __alloca (pwbuflen);
  +                   __set_errno (save);
  +                 }
  +#   else
  +               p = getpwnam (name);
  +#   endif
  +               if (p != NULL)
  +                 home_dir = p->pw_dir;
  +             }
  +         }
  +       if (home_dir == NULL || home_dir[0] == '\0')
  +         {
  +           if (flags & GLOB_TILDE_CHECK)
  +             return GLOB_NOMATCH;
  +           else
  +             home_dir = "~"; /* No luck.  */
  +         }
  +#  endif /* WINDOWS32 */
  +# endif
  +       /* Now construct the full directory.  */
  +       if (dirname[1] == '\0')
  +         dirname = home_dir;
  +       else
  +         {
  +           char *newp;
  +           size_t home_len = strlen (home_dir);
  +           newp = (char *) __alloca (home_len + dirlen);
  +# ifdef HAVE_MEMPCPY
  +           mempcpy (mempcpy (newp, home_dir, home_len),
  +                    &dirname[1], dirlen);
  +# else
  +           memcpy (newp, home_dir, home_len);
  +           memcpy (&newp[home_len], &dirname[1], dirlen);
  +# endif
  +           dirname = newp;
  +         }
  +     }
  +# if !defined _AMIGA && !defined WINDOWS32
  +      else
  +     {
  +       char * end_name = (char *) strchr (dirname, '/');
  +       const char *user_name;
  +       const char *home_dir;
  +
  +       if (end_name == NULL)
  +         user_name = dirname + 1;
  +       else
  +         {
  +           char *newp;
  +           newp = (char *) __alloca (end_name - dirname);
  +# ifdef HAVE_MEMPCPY
  +           *((char *) mempcpy (newp, dirname + 1, end_name - dirname))
  +             = '\0';
  +# else
  +           memcpy (newp, dirname + 1, end_name - dirname);
  +           newp[end_name - dirname - 1] = '\0';
  +# endif
  +           user_name = newp;
  +         }
  +
  +       /* Look up specific user's home directory.  */
  +       {
  +         struct passwd *p;
  +#  if defined HAVE_GETPWNAM_R || defined _LIBC
  +         size_t buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
  +         char *pwtmpbuf;
  +         struct passwd pwbuf;
  +         int save = errno;
  +
  +         if (buflen == -1)
  +           /* `sysconf' does not support _SC_GETPW_R_SIZE_MAX.  Try a
  +              moderate value.  */
  +           buflen = 1024;
  +         pwtmpbuf = (char *) __alloca (buflen);
  +
  +         while (getpwnam_r (user_name, &pwbuf, pwtmpbuf, buflen, &p) != 0)
  +           {
  +             if (errno != ERANGE)
  +               {
  +                 p = NULL;
  +                 break;
  +               }
  +             buflen *= 2;
  +             pwtmpbuf = __alloca (buflen);
  +             __set_errno (save);
  +           }
  +#  else
  +         p = getpwnam (user_name);
  +#  endif
  +         if (p != NULL)
  +           home_dir = p->pw_dir;
  +         else
  +           home_dir = NULL;
  +       }
  +       /* If we found a home directory use this.  */
  +       if (home_dir != NULL)
  +         {
  +           char *newp;
  +           size_t home_len = strlen (home_dir);
  +           size_t rest_len = end_name == NULL ? 0 : strlen (end_name);
  +           newp = (char *) __alloca (home_len + rest_len + 1);
  +#  ifdef HAVE_MEMPCPY
  +           *((char *) mempcpy (mempcpy (newp, home_dir, home_len),
  +                               end_name, rest_len)) = '\0';
  +#  else
  +           memcpy (newp, home_dir, home_len);
  +           memcpy (&newp[home_len], end_name, rest_len);
  +           newp[home_len + rest_len] = '\0';
  +#  endif
  +           dirname = newp;
  +         }
  +       else
  +         if (flags & GLOB_TILDE_CHECK)
  +           /* We have to regard it as an error if we cannot find the
  +              home directory.  */
  +           return GLOB_NOMATCH;
  +     }
  +# endif      /* Not Amiga && not WINDOWS32.  */
  +    }
  +#endif       /* Not VMS.  */
  +
  +  /* Now test whether we looked for "~" or "~NAME".  In this case we
  +     can give the answer now.  */
  +  if (filename == NULL)
  +    {
  +      struct stat st;
  +
  +      /* Return the directory if we don't check for error or if it exists.  
*/
  +      if ((flags & GLOB_NOCHECK)
  +       || (((flags & GLOB_ALTDIRFUNC)
  +            ? (*pglob->gl_stat) (dirname, &st)
  +            : __stat (dirname, &st)) == 0
  +           && S_ISDIR (st.st_mode)))
  +     {
  +       pglob->gl_pathv
  +         = (char **) realloc (pglob->gl_pathv,
  +                              (pglob->gl_pathc +
  +                               ((flags & GLOB_DOOFFS) ?
  +                                pglob->gl_offs : 0) +
  +                               1 + 1) *
  +                              sizeof (char *));
  +       if (pglob->gl_pathv == NULL)
  +         return GLOB_NOSPACE;
  +
  +       if (flags & GLOB_DOOFFS)
  +         while (pglob->gl_pathc < pglob->gl_offs)
  +           pglob->gl_pathv[pglob->gl_pathc++] = NULL;
  +
  +#if defined HAVE_STRDUP || defined _LIBC
  +       pglob->gl_pathv[pglob->gl_pathc] = strdup (dirname);
  +#else
  +       {
  +         size_t len = strlen (dirname) + 1;
  +         char *dircopy = malloc (len);
  +         if (dircopy != NULL)
  +           pglob->gl_pathv[pglob->gl_pathc] = memcpy (dircopy, dirname,
  +                                                      len);
  +       }
  +#endif
  +       if (pglob->gl_pathv[pglob->gl_pathc] == NULL)
  +         {
  +           free (pglob->gl_pathv);
  +           return GLOB_NOSPACE;
  +         }
  +       pglob->gl_pathv[++pglob->gl_pathc] = NULL;
  +       pglob->gl_flags = flags;
  +
  +       return 0;
  +     }
  +
  +      /* Not found.  */
  +      return GLOB_NOMATCH;
  +    }
  +
  +  if (__glob_pattern_p (dirname, !(flags & GLOB_NOESCAPE)))
  +    {
  +      /* The directory name contains metacharacters, so we
  +      have to glob for the directory, and then glob for
  +      the pattern in each directory found.  */
  +      glob_t dirs;
  +      register int i;
  +
  +      if ((flags & GLOB_ALTDIRFUNC) != 0)
  +     {
  +       /* Use the alternative access functions also in the recursive
  +          call.  */
  +       dirs.gl_opendir = pglob->gl_opendir;
  +       dirs.gl_readdir = pglob->gl_readdir;
  +       dirs.gl_closedir = pglob->gl_closedir;
  +       dirs.gl_stat = pglob->gl_stat;
  +       dirs.gl_lstat = pglob->gl_lstat;
  +     }
  +
  +      status = glob (dirname,
  +                  ((flags & (GLOB_ERR | GLOB_NOCHECK | GLOB_NOESCAPE
  +                             | GLOB_ALTDIRFUNC))
  +                   | GLOB_NOSORT | GLOB_ONLYDIR),
  +                  errfunc, &dirs);
  +      if (status != 0)
  +     return status;
  +
  +      /* We have successfully globbed the preceding directory name.
  +      For each name we found, call glob_in_dir on it and FILENAME,
  +      appending the results to PGLOB.  */
  +      for (i = 0; i < (int)dirs.gl_pathc; ++i)
  +     {
  +       int old_pathc;
  +
  +#ifdef       SHELL
  +       {
  +         /* Make globbing interruptible in the bash shell. */
  +         extern int interrupt_state;
  +
  +         if (interrupt_state)
  +           {
  +             globfree (&dirs);
  +             globfree (&files);
  +             return GLOB_ABORTED;
  +           }
  +       }
  +#endif /* SHELL.  */
  +
  +       old_pathc = pglob->gl_pathc;
  +       status = glob_in_dir (filename, dirs.gl_pathv[i],
  +                             ((flags | GLOB_APPEND)
  +                              & ~(GLOB_NOCHECK | GLOB_ERR)),
  +                             errfunc, pglob);
  +       if (status == GLOB_NOMATCH)
  +         /* No matches in this directory.  Try the next.  */
  +         continue;
  +
  +       if (status != 0)
  +         {
  +           globfree (&dirs);
  +           globfree (pglob);
  +           return status;
  +         }
  +
  +       /* Stick the directory on the front of each name.  */
  +       if (prefix_array (dirs.gl_pathv[i],
  +                         &pglob->gl_pathv[old_pathc],
  +                         pglob->gl_pathc - old_pathc))
  +         {
  +           globfree (&dirs);
  +           globfree (pglob);
  +           return GLOB_NOSPACE;
  +         }
  +     }
  +
  +      flags |= GLOB_MAGCHAR;
  +
  +      /* We have ignored the GLOB_NOCHECK flag in the `glob_in_dir' calls.
  +      But if we have not found any matching entry and thie GLOB_NOCHECK
  +      flag was set we must return the list consisting of the disrectory
  +      names followed by the filename.  */
  +      if ((int)pglob->gl_pathc == oldcount)
  +     {
  +       /* No matches.  */
  +       if (flags & GLOB_NOCHECK)
  +         {
  +           size_t filename_len = strlen (filename) + 1;
  +           char **new_pathv;
  +           struct stat st;
  +
  +           /* This is an pessimistic guess about the size.  */
  +           pglob->gl_pathv
  +             = (char **) realloc (pglob->gl_pathv,
  +                                  (pglob->gl_pathc +
  +                                   ((flags & GLOB_DOOFFS) ?
  +                                    pglob->gl_offs : 0) +
  +                                   dirs.gl_pathc + 1) *
  +                                  sizeof (char *));
  +           if (pglob->gl_pathv == NULL)
  +             {
  +               globfree (&dirs);
  +               return GLOB_NOSPACE;
  +             }
  +
  +           if (flags & GLOB_DOOFFS)
  +             while (pglob->gl_pathc < pglob->gl_offs)
  +               pglob->gl_pathv[pglob->gl_pathc++] = NULL;
  +
  +           for (i = 0; i < (int)dirs.gl_pathc; ++i)
  +             {
  +               const char *dir = dirs.gl_pathv[i];
  +               size_t dir_len = strlen (dir);
  +
  +               /* First check whether this really is a directory.  */
  +               if (((flags & GLOB_ALTDIRFUNC)
  +                    ? (*pglob->gl_stat) (dir, &st) : __stat (dir, &st)) != 0
  +                   || !S_ISDIR (st.st_mode))
  +                 /* No directory, ignore this entry.  */
  +                 continue;
  +
  +               pglob->gl_pathv[pglob->gl_pathc] = (char *) malloc (dir_len + 
1
  +                                                          + filename_len);
  +               if (pglob->gl_pathv[pglob->gl_pathc] == NULL)
  +                 {
  +                   globfree (&dirs);
  +                   globfree (pglob);
  +                   return GLOB_NOSPACE;
  +                 }
  +
  +#ifdef HAVE_MEMPCPY
  +               mempcpy (mempcpy (mempcpy (pglob->gl_pathv[pglob->gl_pathc],
  +                                          dir, dir_len),
  +                                 "/", 1),
  +                        filename, filename_len);
  +#else
  +               memcpy (pglob->gl_pathv[pglob->gl_pathc], dir, dir_len);
  +               pglob->gl_pathv[pglob->gl_pathc][dir_len] = '/';
  +               memcpy (&pglob->gl_pathv[pglob->gl_pathc][dir_len + 1],
  +                       filename, filename_len);
  +#endif
  +               ++pglob->gl_pathc;
  +             }
  +
  +           pglob->gl_pathv[pglob->gl_pathc] = NULL;
  +           pglob->gl_flags = flags;
  +
  +           /* Now we know how large the gl_pathv vector must be.  */
  +           new_pathv = (char **) realloc (pglob->gl_pathv,
  +                                          ((pglob->gl_pathc + 1)
  +                                           * sizeof (char *)));
  +           if (new_pathv != NULL)
  +             pglob->gl_pathv = new_pathv;
  +         }
  +       else
  +         return GLOB_NOMATCH;
  +     }
  +
  +      globfree (&dirs);
  +    }
  +  else
  +    {
  +      status = glob_in_dir (filename, dirname, flags, errfunc, pglob);
  +      if (status != 0)
  +     return status;
  +
  +      if (dirlen > 0)
  +     {
  +       /* Stick the directory on the front of each name.  */
  +       int ignore = oldcount;
  +
  +       if ((flags & GLOB_DOOFFS) && ignore < (int)pglob->gl_offs)
  +         ignore = pglob->gl_offs;
  +
  +       if (prefix_array (dirname,
  +                         &pglob->gl_pathv[ignore],
  +                         pglob->gl_pathc - ignore))
  +         {
  +           globfree (pglob);
  +           return GLOB_NOSPACE;
  +         }
  +     }
  +    }
  +
  +  if (flags & GLOB_MARK)
  +    {
  +      /* Append slashes to directory names.  */
  +      int i;
  +      struct stat st;
  +      for (i = oldcount; i < (int)pglob->gl_pathc; ++i)
  +     if (((flags & GLOB_ALTDIRFUNC)
  +          ? (*pglob->gl_stat) (pglob->gl_pathv[i], &st)
  +          : __stat (pglob->gl_pathv[i], &st)) == 0
  +         && S_ISDIR (st.st_mode))
  +       {
  +         size_t len = strlen (pglob->gl_pathv[i]) + 2;
  +         char *my = (char *) realloc (pglob->gl_pathv[i], len);
  +         if (my == NULL)
  +           {
  +             globfree (pglob);
  +             return GLOB_NOSPACE;
  +           }
  +         strcpy (&my[len - 2], "/");
  +         pglob->gl_pathv[i] = my;
  +       }
  +    }
  +
  +  if (!(flags & GLOB_NOSORT))
  +    {
  +      /* Sort the vector.  */
  +      int non_sort = oldcount;
  +
  +      if ((flags & GLOB_DOOFFS) && (int)pglob->gl_offs > oldcount)
  +     non_sort = pglob->gl_offs;
  +
  +      qsort ((__ptr_t) &pglob->gl_pathv[non_sort],
  +          pglob->gl_pathc - non_sort,
  +          sizeof (char *), collated_compare);
  +    }
  +
  +  return 0;
  +}
  +
  +
  +/* Free storage allocated in PGLOB by a previous `glob' call.  */
  +void
  +globfree (glob_t *pglob)
  +{
  +  if (pglob->gl_pathv != NULL)
  +    {
  +      register int i;
  +      for (i = 0; i < (int)pglob->gl_pathc; ++i)
  +     if (pglob->gl_pathv[i] != NULL)
  +       free ((__ptr_t) pglob->gl_pathv[i]);
  +      free ((__ptr_t) pglob->gl_pathv);
  +    }
  +}
  +
  +
  +/* Do a collated comparison of A and B.  */
  +static int
  +collated_compare (const __ptr_t a, const __ptr_t b)
  +{
  +  const char *const s1 = *(const char *const * const) a;
  +  const char *const s2 = *(const char *const * const) b;
  +
  +  if (s1 == s2)
  +    return 0;
  +  if (s1 == NULL)
  +    return 1;
  +  if (s2 == NULL)
  +    return -1;
  +  return strcoll (s1, s2);
  +}
  +
  +
  +/* Prepend DIRNAME to each of N members of ARRAY, replacing ARRAY's
  +   elements in place.  Return nonzero if out of memory, zero if successful.
  +   A slash is inserted between DIRNAME and each elt of ARRAY,
  +   unless DIRNAME is just "/".  Each old element of ARRAY is freed.  */
  +static int
  +prefix_array (const char *dirname, char **array, size_t n)
  +{
  +  register size_t i;
  +  size_t dirlen = strlen (dirname);
  +#if defined __MSDOS__ || defined WINDOWS32
  +  int sep_char = '/';
  +# define DIRSEP_CHAR sep_char
  +#else
  +# define DIRSEP_CHAR '/'
  +#endif
  +
  +  if (dirlen == 1 && dirname[0] == '/')
  +    /* DIRNAME is just "/", so normal prepending would get us "//foo".
  +       We want "/foo" instead, so don't prepend any chars from DIRNAME.  */
  +    dirlen = 0;
  +#if defined __MSDOS__ || defined WINDOWS32
  +  else if (dirlen > 1)
  +    {
  +      if (dirname[dirlen - 1] == '/')
  +     /* DIRNAME is "d:/".  Don't prepend the slash from DIRNAME.  */
  +     --dirlen;
  +      else if (dirname[dirlen - 1] == ':')
  +     {
  +       /* DIRNAME is "d:".  Use `:' instead of `/'.  */
  +       --dirlen;
  +       sep_char = ':';
  +     }
  +    }
  +#endif
  +
  +  for (i = 0; i < n; ++i)
  +    {
  +      size_t eltlen = strlen (array[i]) + 1;
  +      char *my = (char *) malloc (dirlen + 1 + eltlen);
  +      if (my == NULL)
  +     {
  +       while (i > 0)
  +         free ((__ptr_t) array[--i]);
  +       return 1;
  +     }
  +
  +#ifdef HAVE_MEMPCPY
  +      {
  +     char *endp = (char *) mempcpy (my, dirname, dirlen);
  +     *endp++ = DIRSEP_CHAR;
  +     mempcpy (endp, array[i], eltlen);
  +      }
  +#else
  +      memcpy (my, dirname, dirlen);
  +      my[dirlen] = DIRSEP_CHAR;
  +      memcpy (&my[dirlen + 1], array[i], eltlen);
  +#endif
  +      free ((__ptr_t) array[i]);
  +      array[i] = my;
  +    }
  +
  +  return 0;
  +}
  +
  +
  +/* We must not compile this function twice.  */
  +#if !defined _LIBC || !defined NO_GLOB_PATTERN_P
  +/* Return nonzero if PATTERN contains any metacharacters.
  +   Metacharacters can be quoted with backslashes if QUOTE is nonzero.  */
  +static int
  +__glob_pattern_p (const char *pattern, int quote)
  +{
  +  register const char *p;
  +  int open = 0;
  +
  +  for (p = pattern; *p != '\0'; ++p)
  +    switch (*p)
  +      {
  +      case '?':
  +      case '*':
  +     return 1;
  +
  +      case '\\':
  +     if (quote && p[1] != '\0')
  +       ++p;
  +     break;
  +
  +      case '[':
  +     open = 1;
  +     break;
  +
  +      case ']':
  +     if (open)
  +       return 1;
  +     break;
  +      }
  +
  +  return 0;
  +}
  +# ifdef _LIBC
  +weak_alias (__glob_pattern_p, glob_pattern_p)
  +# endif
  +#endif
  +
  +
  +/* Like `glob', but PATTERN is a final pathname component,
  +   and matches are searched for in DIRECTORY.
  +   The GLOB_NOSORT bit in FLAGS is ignored.  No sorting is ever done.
  +   The GLOB_APPEND flag is assumed to be set (always appends).  */
  +static int
  +glob_in_dir (const char *pattern, const char *directory, int flags,
  +             int (*errfunc) __P ((const char *, int)), glob_t *pglob)
  +{
  +  __ptr_t stream = NULL;
  +
  +  struct globlink
  +    {
  +      struct globlink *next;
  +      char *name;
  +    };
  +  struct globlink *names = NULL;
  +  size_t nfound;
  +  int meta;
  +  int save;
  +
  +  meta = __glob_pattern_p (pattern, !(flags & GLOB_NOESCAPE));
  +  if (meta == 0)
  +    {
  +      if (flags & (GLOB_NOCHECK|GLOB_NOMAGIC))
  +     /* We need not do any tests.  The PATTERN contains no meta
  +        characters and we must not return an error therefore the
  +        result will always contain exactly one name.  */
  +     flags |= GLOB_NOCHECK;
  +      else
  +     {
  +       /* Since we use the normal file functions we can also use stat()
  +          to verify the file is there.  */
  +       struct stat st;
  +       size_t patlen = strlen (pattern);
  +       size_t dirlen = strlen (directory);
  +       char *fullname = (char *) __alloca (dirlen + 1 + patlen + 1);
  +
  +# ifdef HAVE_MEMPCPY
  +       mempcpy (mempcpy (mempcpy (fullname, directory, dirlen),
  +                         "/", 1),
  +                pattern, patlen + 1);
  +# else
  +       memcpy (fullname, directory, dirlen);
  +       fullname[dirlen] = '/';
  +       memcpy (&fullname[dirlen + 1], pattern, patlen + 1);
  +# endif
  +       if (((flags & GLOB_ALTDIRFUNC)
  +            ? (*pglob->gl_stat) (fullname, &st)
  +            : __stat (fullname, &st)) == 0)
  +         /* We found this file to be existing.  Now tell the rest
  +            of the function to copy this name into the result.  */
  +         flags |= GLOB_NOCHECK;
  +     }
  +
  +      nfound = 0;
  +    }
  +  else
  +    {
  +      if (pattern[0] == '\0')
  +     {
  +       /* This is a special case for matching directories like in
  +          "*a/".  */
  +       names = (struct globlink *) __alloca (sizeof (struct globlink));
  +       names->name = (char *) malloc (1);
  +       if (names->name == NULL)
  +         goto memory_error;
  +       names->name[0] = '\0';
  +       names->next = NULL;
  +       nfound = 1;
  +       meta = 0;
  +     }
  +      else
  +     {
  +       stream = ((flags & GLOB_ALTDIRFUNC)
  +                 ? (*pglob->gl_opendir) (directory)
  +                 : (__ptr_t) opendir (directory));
  +       if (stream == NULL)
  +         {
  +           if (errno != ENOTDIR
  +               && ((errfunc != NULL && (*errfunc) (directory, errno))
  +                   || (flags & GLOB_ERR)))
  +             return GLOB_ABORTED;
  +           nfound = 0;
  +           meta = 0;
  +         }
  +       else
  +         {
  +           int fnm_flags = ((!(flags & GLOB_PERIOD) ? FNM_PERIOD : 0)
  +                            | ((flags & GLOB_NOESCAPE) ? FNM_NOESCAPE : 0)
  +#if defined _AMIGA || defined VMS
  +                                | FNM_CASEFOLD
  +#endif
  +                                );
  +           nfound = 0;
  +           flags |= GLOB_MAGCHAR;
  +
  +           while (1)
  +             {
  +               const char *name;
  +               size_t len;
  +#ifdef _LARGEFILE64_SOURCE
  +               struct dirent64 *d;
  +               union
  +                 {
  +                     struct dirent64 d64;
  +                             char room [offsetof (struct dirent64, d_name[0])
  +                                + NAME_MAX + 1];
  +                 }
  +               d64buf;
  +
  +               if ((flags & GLOB_ALTDIRFUNC))
  +                 {
  +                     struct dirent *d32 = (*pglob->gl_readdir) (stream);
  +                             if (d32 != NULL)
  +                       {
  +                         CONVERT_DIRENT_DIRENT64 (&d64buf.d64, d32);
  +                                 d = &d64buf.d64;
  +                               }
  +                             else
  +                       d = NULL;
  +                 }
  +               else
  +                 d = readdir64 ((DIR *)stream);
  +#else
  +               struct dirent *d = ((flags & GLOB_ALTDIRFUNC)
  +                                   ? (*pglob->gl_readdir) (stream)
  +                                   : readdir ((DIR *) stream));
  +#endif
  +               if (d == NULL)
  +                 break;
  +               if (! REAL_DIR_ENTRY (d))
  +                 continue;
  +
  +#ifdef HAVE_D_TYPE
  +               /* If we shall match only directories use the information
  +                  provided by the dirent call if possible.  */
  +               if ((flags & GLOB_ONLYDIR)
  +                   && d->d_type != DT_UNKNOWN && d->d_type != DT_DIR)
  +                 continue;
  +#endif
  +
  +               name = d->d_name;
  +
  +               if (fnmatch (pattern, name, fnm_flags) == 0)
  +                 {
  +                   struct globlink *my = (struct globlink *)
  +                     __alloca (sizeof (struct globlink));
  +                   len = NAMLEN (d);
  +                   my->name = (char *) malloc (len + 1);
  +                   if (my->name == NULL)
  +                     goto memory_error;
  +#ifdef HAVE_MEMPCPY
  +                   *((char *) mempcpy ((__ptr_t) my->name, name, len))
  +                     = '\0';
  +#else
  +                   memcpy ((__ptr_t) my->name, name, len);
  +                   my->name[len] = '\0';
  +#endif
  +                   my->next = names;
  +                   names = my;
  +                   ++nfound;
  +                 }
  +             }
  +         }
  +     }
  +    }
  +
  +  if (nfound == 0 && (flags & GLOB_NOCHECK))
  +    {
  +      size_t len = strlen (pattern);
  +      nfound = 1;
  +      names = (struct globlink *) __alloca (sizeof (struct globlink));
  +      names->next = NULL;
  +      names->name = (char *) malloc (len + 1);
  +      if (names->name == NULL)
  +     goto memory_error;
  +#ifdef HAVE_MEMPCPY
  +      *((char *) mempcpy (names->name, pattern, len)) = '\0';
  +#else
  +      memcpy (names->name, pattern, len);
  +      names->name[len] = '\0';
  +#endif
  +    }
  +
  +  if (nfound != 0)
  +    {
  +      pglob->gl_pathv
  +     = (char **) realloc (pglob->gl_pathv,
  +                          (pglob->gl_pathc +
  +                           ((flags & GLOB_DOOFFS) ? pglob->gl_offs : 0) +
  +                           nfound + 1) *
  +                          sizeof (char *));
  +      if (pglob->gl_pathv == NULL)
  +     goto memory_error;
  +
  +      if (flags & GLOB_DOOFFS)
  +     while (pglob->gl_pathc < pglob->gl_offs)
  +       pglob->gl_pathv[pglob->gl_pathc++] = NULL;
  +
  +      for (; names != NULL; names = names->next)
  +     pglob->gl_pathv[pglob->gl_pathc++] = names->name;
  +      pglob->gl_pathv[pglob->gl_pathc] = NULL;
  +
  +      pglob->gl_flags = flags;
  +    }
  +
  +  save = errno;
  +  if (stream != NULL)
  +    {
  +      if (flags & GLOB_ALTDIRFUNC)
  +     (*pglob->gl_closedir) (stream);
  +      else
  +     closedir ((DIR *) stream);
  +    }
  +  __set_errno (save);
  +
  +  return nfound == 0 ? GLOB_NOMATCH : 0;
  +
  + memory_error:
  +  {
  +    save = errno;
  +    if (flags & GLOB_ALTDIRFUNC)
  +      (*pglob->gl_closedir) (stream);
  +    else
  +      closedir ((DIR *) stream);
  +    __set_errno (save);
  +  }
  +  while (names != NULL)
  +    {
  +      if (names->name != NULL)
  +     free ((__ptr_t) names->name);
  +      names = names->next;
  +    }
  +  return GLOB_NOSPACE;
  +}
  +/*@=unrecog@*/
  +/*@=unqualifiedtrans@*/
  +/*@=type@*/
  +/*@=temptrans@*/
  +/*@=sizeoftype@*/
  +/*@=shadow@*/
  +/*@=retvalint@*/
  +/*@=retalias@*/
  +/*@=protoparammatch@*/
  +/*@=onlytrans@*/
  +/*@=nullpass@*/
  +/*@=noeffectuncon@*/
  +/*@=modunconnomods@*/
  +/*@=moduncon@*/
  +/*@=mods@*/
  +/*@=modnomods@*/
  +/*@=loopswitchbreak@*/
  +/*@=internalglobs@*/
  +/*@=immediatetrans@*/
  +/*@=compdef@*/
  +/*@=branchstate@*/
  +/*@=bounds@*/
  @@ .
  patch -p0 <<'@@ .'
  Index: rpm/misc/glob.h
  ============================================================================
  $ cvs diff -u -r0 -r1.16.2.2 glob.h
  --- /dev/null 2016-06-19 08:45:30.000000000 +0200
  +++ glob.h    2016-06-19 08:48:47.361275498 +0200
  @@ -0,0 +1,224 @@
  +/* Copyright (C) 1991, 92, 95, 96, 97, 98, 2000 Free Software Foundation, 
Inc.
  +
  +   The GNU C Library is free software; you can redistribute it and/or
  +   modify it under the terms of the GNU Library General Public License as
  +   published by the Free Software Foundation; either version 2 of the
  +   License, or (at your option) any later version.
  +
  +   The GNU C Library is distributed in the hope that it will be useful,
  +   but WITHOUT ANY WARRANTY; without even the implied warranty of
  +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  +   Library General Public License for more details.
  +
  +   You should have received a copy of the GNU Library General Public
  +   License along with the GNU C Library; see the file COPYING.LIB.  If not,
  +   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  +   Boston, MA 02111-1307, USA.  */
  +
  +#ifndef      _GLOB_H
  +#define      _GLOB_H 1
  +
  +#if defined(hpux) || defined(__hpux)
  +#define _GLOB_INCLUDED
  +#endif
  +
  +#ifdef       __cplusplus
  +extern "C" {
  +#endif
  +
  +#undef       __ptr_t
  +#if defined __cplusplus || (defined __STDC__ && __STDC__) || defined 
WINDOWS32
  +# if !defined __GLIBC__ || !defined __P || !defined __PMT
  +#  undef __P
  +#  undef __PMT
  +#  define __P(protos)        protos
  +#  define __PMT(protos)      protos
  +#  if !defined __GNUC__ || __GNUC__ < 2
  +#   undef __const
  +#   define __const const
  +#  endif
  +# endif
  +# define __ptr_t     void *
  +#else /* Not C++ or ANSI C.  */
  +# undef      __P
  +# undef __PMT
  +# define __P(protos) ()
  +# define __PMT(protos)       ()
  +# undef      __const
  +# define __const
  +# define __ptr_t     char *
  +#endif /* C++ or ANSI C.  */
  +
  +/* We need `size_t' for the following definitions.  */
  +#if !defined(__size_t) && !defined(_BSD_SIZE_T_DEFINED_)
  +# if defined __GNUC__ && __GNUC__ >= 2
  +typedef __SIZE_TYPE__ __size_t;
  +#  if 0
  +#  ifdef _XOPEN_SOURCE
  +typedef __SIZE_TYPE__ size_t;
  +#  endif
  +#  endif
  +# else
  +/* This is a guess.  */
  +typedef unsigned long int __size_t;
  +# endif
  +#else
  +/* The GNU CC stddef.h version defines __size_t as empty.  We need a real
  +   definition.  */
  +# undef __size_t
  +# define __size_t size_t
  +#endif
  +
  +/* Bits set in the FLAGS argument to `glob'.  */
  +#define      GLOB_ERR        (1 << 0)/* Return on read errors.  */
  +#define      GLOB_MARK       (1 << 1)/* Append a slash to each name.  */
  +#define      GLOB_NOSORT     (1 << 2)/* Don't sort the names.  */
  +#define      GLOB_DOOFFS     (1 << 3)/* Insert PGLOB->gl_offs NULLs.  */
  +#define      GLOB_NOCHECK    (1 << 4)/* If nothing matches, return the 
pattern.  */
  +#define      GLOB_APPEND     (1 << 5)/* Append to results of a previous 
call.  */
  +#define      GLOB_NOESCAPE   (1 << 6)/* Backslashes don't quote 
metacharacters.  */
  +#define      GLOB_PERIOD     (1 << 7)/* Leading `.' can be matched by 
metachars.  */
  +
  +#if (!defined _POSIX_C_SOURCE || _POSIX_C_SOURCE < 2 || defined _BSD_SOURCE \
  +     || defined _GNU_SOURCE)
  +# define GLOB_MAGCHAR         (1 << 8)/* Set in gl_flags if any metachars 
seen.  */
  +# define GLOB_ALTDIRFUNC (1 << 9)/* Use gl_opendir et al functions.  */
  +# define GLOB_BRACE   (1 << 10)/* Expand "{a,b}" to "a" "b".  */
  +# define GLOB_NOMAGIC         (1 << 11)/* If no magic chars, return the 
pattern.  */
  +# define GLOB_TILDE   (1 << 12)/* Expand ~user and ~ to home directories. */
  +# define GLOB_ONLYDIR         (1 << 13)/* Match only directories.  */
  +# define GLOB_TILDE_CHECK (1 << 14)/* Like GLOB_TILDE but return an error
  +                                   if the user name is not available.  */
  +# define __GLOB_FLAGS        (GLOB_ERR|GLOB_MARK|GLOB_NOSORT|GLOB_DOOFFS| \
  +                      GLOB_NOESCAPE|GLOB_NOCHECK|GLOB_APPEND|     \
  +                      GLOB_PERIOD|GLOB_ALTDIRFUNC|GLOB_BRACE|     \
  +                      GLOB_NOMAGIC|GLOB_TILDE|GLOB_ONLYDIR|GLOB_TILDE_CHECK)
  +#else
  +# define __GLOB_FLAGS        (GLOB_ERR|GLOB_MARK|GLOB_NOSORT|GLOB_DOOFFS| \
  +                      GLOB_NOESCAPE|GLOB_NOCHECK|GLOB_APPEND|     \
  +                      GLOB_PERIOD)
  +#endif
  +
  +/* Error returns from `glob'.  */
  +#define      GLOB_NOSPACE    1       /* Ran out of memory.  */
  +#define      GLOB_ABORTED    2       /* Read error.  */
  +#define      GLOB_NOMATCH    3       /* No matches found.  */
  +#define GLOB_NOSYS   4       /* Not implemented.  */
  +#ifdef _GNU_SOURCE
  +/* Previous versions of this file defined GLOB_ABEND instead of
  +   GLOB_ABORTED.  Provide a compatibility definition here.  */
  +# define GLOB_ABEND GLOB_ABORTED
  +#endif
  +
  +/* Structure describing a globbing run.  */
  +#if !defined _AMIGA && !defined VMS /* Buggy compiler.   */
  +struct stat;
  +#endif
  +typedef struct
  +  {
  +    __size_t gl_pathc;               /* Count of paths matched by the 
pattern.  */
  +    char **gl_pathv;         /* List of matched pathnames.  */
  +    __size_t gl_offs;                /* Slots to reserve in `gl_pathv'.  */
  +    int gl_flags;            /* Set to FLAGS, maybe | GLOB_MAGCHAR.  */
  +
  +    /* If the GLOB_ALTDIRFUNC flag is set, the following functions
  +       are used instead of the normal file access functions.  */
  +    void (*gl_closedir) __PMT ((void *))
  +     /*@*/;
  +    struct dirent *(*gl_readdir) __PMT ((void *))
  +     /*@*/;
  +    __ptr_t (*gl_opendir) __PMT ((__const char *))
  +     /*@*/;
  +    int (*gl_lstat) __PMT ((__const char *, struct stat *))
  +     /*@*/;
  +    int (*gl_stat) __PMT ((__const char *, struct stat *))
  +     /*@*/;
  +  } glob_t;
  +
  +#ifdef _LARGEFILE64_SOURCE
  +struct stat64;
  +typedef struct
  +  {
  +    __size_t gl_pathc;
  +    char **gl_pathv;
  +    __size_t gl_offs;
  +    int gl_flags;
  +
  +    /* If the GLOB_ALTDIRFUNC flag is set, the following functions
  +       are used instead of the normal file access functions.  */
  +    void (*gl_closedir) __PMT ((void *))
  +     /*@*/;
  +    struct dirent64 *(*gl_readdir) __PMT ((void *))
  +     /*@*/;
  +    __ptr_t (*gl_opendir) __PMT ((__const char *))
  +     /*@*/;
  +    int (*gl_lstat) __PMT ((__const char *, struct stat64 *))
  +     /*@*/;
  +    int (*gl_stat) __PMT ((__const char *, struct stat64 *))
  +     /*@*/;
  +  } glob64_t;
  +#endif
  +
  +/* Do glob searching for PATTERN, placing results in PGLOB.
  +   The bits defined above may be set in FLAGS.
  +   If a directory cannot be opened or read and ERRFUNC is not nil,
  +   it is called with the pathname that caused the error, and the
  +   `errno' value from the failing call; if it returns non-zero
  +   `glob' returns GLOB_ABEND; if it returns zero, the error is ignored.
  +   If memory cannot be allocated for PGLOB, GLOB_NOSPACE is returned.
  +   Otherwise, `glob' returns zero.  */
  +#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS != 64
  +extern int glob __P ((__const char *__pattern, int __flags,
  +                   int (*__errfunc) (__const char *, int),
  +                   glob_t *__pglob))
  +     /*@globals fileSystem @*/
  +     /*@modifies fileSystem @*/;
  +
  +/* Free storage allocated in PGLOB by a previous `glob' call.  */
  +extern void globfree __P ((glob_t *__pglob));
  +#else
  +# if defined(__GNUC__) && __GNUC__ >= 2
  +extern int glob __P ((__const char *__pattern, int __flags,
  +                   int (*__errfunc) (__const char *, int),
  +                   glob_t *__pglob)) __asm__ ("glob64")
  +     /*@globals fileSystem @*/
  +     /*@modifies fileSystem @*/;
  +
  +extern void globfree __P ((glob_t *__pglob)) __asm__ ("globfree64")
  +     /*@*/;
  +# else
  +#  define glob glob64
  +#  define globfree globfree64
  +#  define glob_t glob64_t
  +# endif
  +#endif
  +
  +#ifdef _LARGEFILE64_SOURCE
  +/*@-protoparammatch -type @*/
  +extern int glob64 __P ((__const char *__pattern, int __flags,
  +                     int (*__errfunc) (__const char *, int),
  +                     glob64_t *__pglob))
  +     /*@globals fileSystem @*/
  +     /*@modifies fileSystem @*/;
  +
  +extern void globfree64 __P ((glob64_t *__pglob))
  +     /*@*/;
  +/*@=protoparammatch =type @*/
  +#endif
  +
  +
  +#ifdef _GNU_SOURCE
  +/* Return nonzero if PATTERN contains any metacharacters.
  +   Metacharacters can be quoted with backslashes if QUOTE is nonzero.
  +
  +   This function is not part of the interface specified by POSIX.2
  +   but several programs want to use it.  */
  +extern int glob_pattern_p __P ((__const char *__pattern, int __quote))
  +     /*@*/;
  +#endif
  +
  +#ifdef       __cplusplus
  +}
  +#endif
  +
  +#endif /* glob.h  */
  @@ .
  patch -p0 <<'@@ .'
  Index: rpm/misc/librpmmisc.c
  ============================================================================
  $ cvs diff -u -r1.5 -r1.5.4.1 librpmmisc.c
  --- rpm/misc/librpmmisc.c     29 May 2009 19:04:21 -0000      1.5
  +++ rpm/misc/librpmmisc.c     19 Jun 2016 06:48:47 -0000      1.5.4.1
  @@ -76,3 +76,7 @@
   #if !defined(HAVE_MKDTEMP)
   #include "mkdtemp.c"
   #endif
  +
  +#include "glob.c"
  +
  +#include "fnmatch.c"
  @@ .
  patch -p0 <<'@@ .'
  Index: rpm/rpmio/Makefile.am
  ============================================================================
  $ cvs diff -u -r1.293.2.70 -r1.293.2.71 Makefile.am
  --- rpm/rpmio/Makefile.am     17 Jun 2016 08:07:27 -0000      1.293.2.70
  +++ rpm/rpmio/Makefile.am     19 Jun 2016 06:48:46 -0000      1.293.2.71
  @@ -11,7 +11,7 @@
   CLEANFILES = *.gcov .libs/*.gcda .libs/*.gcno *.gcno *.gcda
   
   EXTRA_DIST = librpmio.vers \
  -     fnmatch_loop.c getdate.y html-parse.c html-parse.h libsqlio.c \
  +     getdate.y html-parse.c html-parse.h libsqlio.c \
        rpmcpio.c rpmcpio.h rpmgenbasedir.c rpmgenpkglist.c rpmgensrclist.c \
        rpmjsio.msg rpmtar.c rpmtar.h \
        tdir.c tfts.c tget.c tgfs.c tgit.c tglob.c thkp.c thtml.c tinv.c tkey.c 
\
  @@ -127,7 +127,7 @@
        rpmbf.h rpmcb.h rpmio.h rpmlog.h rpmiotypes.h rpmmacro.h \
        rpmpgp.h rpmsw.h rpmutil.h
   noinst_HEADERS = \
  -     ar.h bcon.h bson.h cpio.h crc.h envvar.h fnmatch.h fts.h glob.h iosm.h \
  +     ar.h bcon.h bson.h cpio.h crc.h envvar.h fts.h iosm.h \
        blake2.h blake2-impl.h blake2-rpm.h blake2-kat.h \
        arirang.h blake.h bmw.h chi.h cubehash.h echo.h edon-r.h fugue.h \
        groestl.h hamsi.h jh.h jsmn.h keccak.h lane.h luffa.h md2.h md6.h \
  @@ -165,9 +165,7 @@
        cpio.c \
        crc.c \
        digest.c \
  -     fnmatch.c \
        fts.c \
  -     glob.c \
        gzdio.c \
        iosm.c \
        jsmn.c \
  @@ .
  rm -f rpm/rpmio/fnmatch.c <<'@@ .'
  Index: rpm/rpmio/fnmatch.c
  ============================================================================
  [NO CHANGE SUMMARY BECAUSE FILE AS A WHOLE IS JUST REMOVED]
  @@ .
  rm -f rpm/rpmio/fnmatch.h <<'@@ .'
  Index: rpm/rpmio/fnmatch.h
  ============================================================================
  [NO CHANGE SUMMARY BECAUSE FILE AS A WHOLE IS JUST REMOVED]
  @@ .
  rm -f rpm/rpmio/fnmatch_loop.c <<'@@ .'
  Index: rpm/rpmio/fnmatch_loop.c
  ============================================================================
  [NO CHANGE SUMMARY BECAUSE FILE AS A WHOLE IS JUST REMOVED]
  @@ .
  rm -f rpm/rpmio/glob.c <<'@@ .'
  Index: rpm/rpmio/glob.c
  ============================================================================
  [NO CHANGE SUMMARY BECAUSE FILE AS A WHOLE IS JUST REMOVED]
  @@ .
  rm -f rpm/rpmio/glob.h <<'@@ .'
  Index: rpm/rpmio/glob.h
  ============================================================================
  [NO CHANGE SUMMARY BECAUSE FILE AS A WHOLE IS JUST REMOVED]
  @@ .
  patch -p0 <<'@@ .'
  Index: rpm/system.h
  ============================================================================
  $ cvs diff -u -r2.129.2.19 -r2.129.2.20 system.h
  --- rpm/system.h      12 May 2016 19:43:54 -0000      2.129.2.19
  +++ rpm/system.h      19 Jun 2016 06:48:46 -0000      2.129.2.20
  @@ -115,8 +115,10 @@
   #if (!defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)) && 
defined(st_birthtime)
   #undef       st_birthtime
   #endif
  +#if !defined(st_birthtime)
   #define      st_birthtime    st_ctime        /* Use st_ctime if no 
st_birthtime. */
   #endif
  +#endif
   /* XXX retrofit the *BSD st_[acm]timespec names if not present. */
   #if !defined(HAVE_STRUCT_STAT_ST_ATIMESPEC_TV_NSEC) && 
defined(HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC)
   #define      st_atimespec    st_atim
  @@ -548,8 +550,8 @@
   /* ============== from misc/miscfn.h */
   
   /*@-noparams@*/
  -#include "rpmio/glob.h"
  -#include "rpmio/fnmatch.h"
  +#include "misc/glob.h"
  +#include "misc/fnmatch.h"
   /*@=noparams@*/
   
   #if defined(__LCLINT__)
  @@ .
______________________________________________________________________
RPM Package Manager                                    http://rpm5.org
CVS Sources Repository                                rpm-cvs@rpm5.org

Reply via email to