RPM Community Forums

Mailing List Message of <rpm-cvs>

[CVS] RPM: rpm-5_1: rpm/rpmio/ fnmatch.c fnmatch.h glob.c glob.h

From: Jeff Johnson <jbj@rpm5.org>
Date: Thu 14 Aug 2008 - 22:32:05 CEST
Message-Id: <20080814203205.6A00C6977B@rpm5.org>
  RPM Package Manager, CVS Repository
  http://rpm5.org/cvs/
  ____________________________________________________________________________

  Server: rpm5.org                         Name:   Jeff Johnson
  Root:   /v/rpm/cvs                       Email:  jbj@rpm5.org
  Module: rpm                              Date:   14-Aug-2008 22:32:05
  Branch: rpm-5_1                          Handle: 2008081420320500

  Added files:              (Branch: rpm-5_1)
    rpm/rpmio               fnmatch.c fnmatch.h glob.c glob.h

  Log:
    - jbj: move glob/fnmatch into -lrpmio from -lrpmmisc.

  Summary:
    Revision    Changes     Path
    2.2.2.2     +611 -0     rpm/rpmio/fnmatch.c
    2.1.2.2     +88 -0      rpm/rpmio/fnmatch.h
    2.2.2.2     +1208 -0    rpm/rpmio/glob.c
    2.1.2.2     +205 -0     rpm/rpmio/glob.h
  ____________________________________________________________________________

  patch -p0 <<'@@ .'
  Index: rpm/rpmio/fnmatch.c
  ============================================================================
  $ cvs diff -u -r0 -r2.2.2.2 fnmatch.c
  --- /dev/null	2008-08-14 22:30:29 +0200
  +++ fnmatch.c	2008-08-14 22:32:05 +0200
  @@ -0,0 +1,611 @@
  +/*@-bounds@*/
  +/*@-retalias@*/
  +/*@-shiftimplementation@*/
  +/*@-temptrans@*/
  +/*@-unreachable@*/
  +/* Copyright (C) 1991-1993, 1996-1999, 2000 Free Software Foundation, Inc.
  +   This file is part of the GNU C Library.
  +
  +   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.  */
  +
  +# include "system.h"
  +
  +/* Find the first occurrence of C in S or the final NUL byte.  */
  +static inline char *
  +internal__strchrnul (const char *s, int c)
  +{
  +  const unsigned char *char_ptr;
  +  const unsigned long int *longword_ptr;
  +  unsigned long int longword, magic_bits, charmask;
  +
  +/*@+charint@*/
  +  c = (unsigned char) c;
  +/*@=charint@*/
  +
  +  /* Handle the first few characters by reading one character at a time.
  +     Do this until CHAR_PTR is aligned on a longword boundary.  */
  +  for (char_ptr = (const unsigned char *)s; ((unsigned long int) char_ptr
  +		      & (sizeof (longword) - 1)) != 0;
  +       ++char_ptr)
  +    if ((int)*char_ptr == c || *char_ptr == '\0')
  +      return (void *) char_ptr;
  +
  +  /* All these elucidatory comments refer to 4-byte longwords,
  +     but the theory applies equally well to 8-byte longwords.  */
  +
  +  longword_ptr = (unsigned long int *) char_ptr;
  +
  +  /* Bits 31, 24, 16, and 8 of this number are zero.  Call these bits
  +     the "holes."  Note that there is a hole just to the left of
  +     each byte, with an extra at the end:
  +
  +     bits:  01111110 11111110 11111110 11111111
  +     bytes: AAAAAAAA BBBBBBBB CCCCCCCC DDDDDDDD
  +
  +     The 1-bits make sure that carries propagate to the next 0-bit.
  +     The 0-bits provide holes for carries to fall into.  */
  +  switch (sizeof (longword))
  +    {
  +    case 4: magic_bits = 0x7efefeffL; break;
  +    case 8: magic_bits = ((0x7efefefeL << 16) << 16) | 0xfefefeffL; break;
  +    default:
  +      abort ();
  +    }
  +
  +  /* Set up a longword, each of whose bytes is C.  */
  +  charmask = c | (c << 8);
  +  charmask |= charmask << 16;
  +  if (sizeof (longword) > 4)
  +    /* Do the shift in two steps to avoid a warning if long has 32 bits.  */
  +    charmask |= (charmask << 16) << 16;
  +  if (sizeof (longword) > 8)
  +    abort ();
  +
  +  /* Instead of the traditional loop which tests each character,
  +     we will test a longword at a time.  The tricky part is testing
  +     if *any of the four* bytes in the longword in question are zero.  */
  +  for (;;)
  +    {
  +      /* We tentatively exit the loop if adding MAGIC_BITS to
  +	 LONGWORD fails to change any of the hole bits of LONGWORD.
  +
  +	 1) Is this safe?  Will it catch all the zero bytes?
  +	 Suppose there is a byte with all zeros.  Any carry bits
  +	 propagating from its left will fall into the hole at its
  +	 least significant bit and stop.  Since there will be no
  +	 carry from its most significant bit, the LSB of the
  +	 byte to the left will be unchanged, and the zero will be
  +	 detected.
  +
  +	 2) Is this worthwhile?  Will it ignore everything except
  +	 zero bytes?  Suppose every byte of LONGWORD has a bit set
  +	 somewhere.  There will be a carry into bit 8.  If bit 8
  +	 is set, this will carry into bit 16.  If bit 8 is clear,
  +	 one of bits 9-15 must be set, so there will be a carry
  +	 into bit 16.  Similarly, there will be a carry into bit
  +	 24.  If one of bits 24-30 is set, there will be a carry
  +	 into bit 31, so all of the hole bits will be changed.
  +
  +	 The one misfire occurs when bits 24-30 are clear and bit
  +	 31 is set; in this case, the hole at bit 31 is not
  +	 changed.  If we had access to the processor carry flag,
  +	 we could close this loophole by putting the fourth hole
  +	 at bit 32!
  +
  +	 So it ignores everything except 128's, when they're aligned
  +	 properly.
  +
  +	 3) But wait!  Aren't we looking for C as well as zero?
  +	 Good point.  So what we do is XOR LONGWORD with a longword,
  +	 each of whose bytes is C.  This turns each byte that is C
  +	 into a zero.  */
  +
  +      longword = *longword_ptr++;
  +
  +      /* Add MAGIC_BITS to LONGWORD.  */
  +      if ((((longword + magic_bits)
  +
  +	    /* Set those bits that were unchanged by the addition.  */
  +	    ^ ~longword)
  +
  +	   /* Look at only the hole bits.  If any of the hole bits
  +	      are unchanged, most likely one of the bytes was a
  +	      zero.  */
  +	   & ~magic_bits) != 0 ||
  +
  +	  /* That caught zeroes.  Now test for C.  */
  +	  ((((longword ^ charmask) + magic_bits) ^ ~(longword ^ charmask))
  +	   & ~magic_bits) != 0)
  +	{
  +	  /* Which of the bytes was C or zero?
  +	     If none of them were, it was a misfire; continue the search.  */
  +
  +	  const unsigned char *cp = (const unsigned char *) (longword_ptr - 1);
  +
  +	  if ((int)*cp == c || *cp == '\0')
  +	    return (char *) cp;
  +	  if ((int)*++cp == c || *cp == '\0')
  +	    return (char *) cp;
  +	  if ((int)*++cp == c || *cp == '\0')
  +	    return (char *) cp;
  +	  if ((int)*++cp == c || *cp == '\0')
  +	    return (char *) cp;
  +	  if (sizeof (longword) > 4)
  +	    {
  +	      if ((int)*++cp == c || *cp == '\0')
  +		return (char *) cp;
  +	      if ((int)*++cp == c || *cp == '\0')
  +		return (char *) cp;
  +	      if ((int)*++cp == c || *cp == '\0')
  +		return (char *) cp;
  +	      if ((int)*++cp == c || *cp == '\0')
  +		return (char *) cp;
  +	    }
  +	}
  +    }
  +
  +  /* This should never happen.  */
  +  return NULL;
  +}
  +
  +/* For platform which support the ISO C amendement 1 functionality we
  +   support user defined character classes.  */
  +#if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
  +/* Solaris 2.5 has a bug: <wchar.h> must be included before <wctype.h>.  */
  +# include <wchar.h>
  +# include <wctype.h>
  +#endif
  +
  +/* 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
  +# 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
  +
  +/* Match STRING against the filename pattern PATTERN, returning zero if
  +   it matches, nonzero if not.  */
  +static int
  +#ifdef _LIBC
  +internal_function
  +#endif
  +internal_fnmatch (const char *pattern, const char *string,
  +		  int no_leading_period, int flags)
  +{
  +  register const char *p = pattern, *n = string;
  +  register unsigned char c;
  +
  +/* 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
  +
  +  while ((c = *p++) != '\0')
  +    {
  +      c = FOLD (c);
  +
  +      switch (c)
  +	{
  +	case '?':
  +	  if (*n == '\0')
  +	    return FNM_NOMATCH;
  +	  else if (*n == '/' && (flags & FNM_FILE_NAME))
  +	    return FNM_NOMATCH;
  +	  else if (*n == '.' && no_leading_period
  +		   && (n == string
  +		       || (n[-1] == '/' && (flags & FNM_FILE_NAME))))
  +	    return FNM_NOMATCH;
  +	  break;
  +
  +	case '\\':
  +	  if (!(flags & FNM_NOESCAPE))
  +	    {
  +	      c = *p++;
  +	      if (c == '\0')
  +		/* Trailing \ loses.  */
  +		return FNM_NOMATCH;
  +	      c = FOLD (c);
  +	    }
  +	  if (FOLD ((unsigned char) *n) != c)
  +	    return FNM_NOMATCH;
  +	  break;
  +
  +	case '*':
  +	  if (*n == '.' && no_leading_period
  +	      && (n == string
  +		  || (n[-1] == '/' && (flags & FNM_FILE_NAME))))
  +	    return FNM_NOMATCH;
  +
  +	  for (c = *p++; c == '?' || c == '*'; c = *p++)
  +	    {
  +	      if (*n == '/' && (flags & FNM_FILE_NAME))
  +		/* A slash does not match a wildcard under FNM_FILE_NAME.  */
  +		return FNM_NOMATCH;
  +	      else if (c == '?')
  +		{
  +		  /* A ? needs to match one character.  */
  +		  if (*n == '\0')
  +		    /* There isn't another character; no match.  */
  +		    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 == '\0')
  +	    /* The wildcard(s) is/are the last element of the pattern.
  +	       If the name is a file name and contains another slash
  +	       this does mean it cannot match.  If the FNM_LEADING_DIR
  +	       flag is set and exactly one slash is following, we have
  +	       a match.  */
  +	    {
  +	      int result = (flags & FNM_FILE_NAME) == 0 ? 0 : FNM_NOMATCH;
  +
  +	      if (flags & FNM_FILE_NAME)
  +		{
  +		  const char *slashp = strchr (n, '/');
  +
  +		  if (flags & FNM_LEADING_DIR)
  +		    {
  +		      if (slashp != NULL
  +			  && strchr (slashp + 1, '/') == NULL)
  +			result = 0;
  +		    }
  +		  else
  +		    {
  +		      if (slashp == NULL)
  +			result = 0;
  +		    }
  +		}
  +
  +	      return result;
  +	    }
  +	  else
  +	    {
  +	      const char *endp;
  +
  +	      endp = internal__strchrnul (n, (flags & FNM_FILE_NAME) ? '/' : '\0');
  +
  +	      if (c == '[')
  +		{
  +		  int flags2 = ((flags & FNM_FILE_NAME)
  +				? flags : (flags & ~FNM_PERIOD));
  +
  +		  for (--p; n < endp; ++n)
  +		    if (internal_fnmatch (p, n,
  +					  (no_leading_period
  +					   && (n == string
  +					       || (n[-1] == '/'
  +						   && (flags
  +						       & FNM_FILE_NAME)))),
  +					  flags2)
  +			== 0)
  +		      return 0;
  +		}
  +	      else if (c == '/' && (flags & FNM_FILE_NAME))
  +		{
  +		  while (*n != '\0' && *n != '/')
  +		    ++n;
  +		  if (*n == '/'
  +		      && (internal_fnmatch (p, n + 1, flags & FNM_PERIOD,
  +					    flags) == 0))
  +		    return 0;
  +		}
  +	      else
  +		{
  +		  int flags2 = ((flags & FNM_FILE_NAME)
  +				? flags : (flags & ~FNM_PERIOD));
  +
  +		  if (c == '\\' && !(flags & FNM_NOESCAPE))
  +		    c = *p;
  +		  c = FOLD (c);
  +		  for (--p; n < endp; ++n)
  +		    if (FOLD ((unsigned char) *n) == c
  +			&& (internal_fnmatch (p, n,
  +					      (no_leading_period
  +					       && (n == string
  +						   || (n[-1] == '/'
  +						       && (flags
  +							   & FNM_FILE_NAME)))),
  +					      flags2) == 0))
  +		      return 0;
  +		}
  +	    }
  +
  +	  /* If we come here no match is possible with the wildcard.  */
  +	  return FNM_NOMATCH;
  +
  +	case '[':
  +	  {
  +	    /* Nonzero if the sense of the character class is inverted.  */
  +	    static int posixly_correct;
  +	    register int not;
  +	    char cold;
  +
  +	    if (posixly_correct == 0)
  +	      posixly_correct = getenv ("POSIXLY_CORRECT") != NULL ? 1 : -1;
  +
  +	    if (*n == '\0')
  +	      return FNM_NOMATCH;
  +
  +	    if (*n == '.' && no_leading_period && (n == string
  +						   || (n[-1] == '/'
  +						       && (flags
  +							   & FNM_FILE_NAME))))
  +	      return FNM_NOMATCH;
  +
  +	    if (*n == '/' && (flags & FNM_FILE_NAME))
  +	      /* `/' cannot be matched.  */
  +	      return FNM_NOMATCH;
  +
  +	    not = (*p == '!' || (posixly_correct < 0 && *p == '^'));
  +	    if (not)
  +	      ++p;
  +
  +	    c = *p++;
  +	    for (;;)
  +	      {
  +		unsigned char fn = FOLD ((unsigned char) *n);
  +
  +		if (!(flags & FNM_NOESCAPE) && c == '\\')
  +		  {
  +		    if (*p == '\0')
  +		      return FNM_NOMATCH;
  +		    c = FOLD ((unsigned char) *p);
  +		    ++p;
  +
  +		    if (c == fn)
  +		      goto matched;
  +		  }
  +		else if (c == '[' && *p == ':')
  +		  {
  +		    /* 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 == ':' && p[1] == ']')
  +			  {
  +			    p += 2;
  +			    break;
  +			  }
  +			if (c < 'a' || c >= 'z')
  +			  {
  +			    /* This cannot possibly be a character class name.
  +			       Match it as a normal range.  */
  +			    p = startp;
  +			    c = '[';
  +			    goto normal_bracket;
  +			  }
  +			str[c1++] = c;
  +		      }
  +		    str[c1] = '\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 (__iswctype (__btowc ((unsigned char) *n), wt))
  +		      goto matched;
  +# else
  +		    if ((STREQ (str, "alnum") && ISALNUM ((unsigned char) *n))
  +			|| (STREQ (str, "alpha") && ISALPHA ((unsigned char) *n))
  +			|| (STREQ (str, "blank") && ISBLANK ((unsigned char) *n))
  +			|| (STREQ (str, "cntrl") && ISCNTRL ((unsigned char) *n))
  +			|| (STREQ (str, "digit") && ISDIGIT ((unsigned char) *n))
  +			|| (STREQ (str, "graph") && ISGRAPH ((unsigned char) *n))
  +			|| (STREQ (str, "lower") && ISLOWER ((unsigned char) *n))
  +			|| (STREQ (str, "print") && ISPRINT ((unsigned char) *n))
  +			|| (STREQ (str, "punct") && ISPUNCT ((unsigned char) *n))
  +			|| (STREQ (str, "space") && ISSPACE ((unsigned char) *n))
  +			|| (STREQ (str, "upper") && ISUPPER ((unsigned char) *n))
  +			|| (STREQ (str, "xdigit") && ISXDIGIT ((unsigned char) *n)))
  +		      goto matched;
  +# endif
  +		  }
  +		else if (c == '\0')
  +		  /* [ (unterminated) loses.  */
  +		  return FNM_NOMATCH;
  +		else
  +		  {
  +		    c = FOLD (c);
  +		  normal_bracket:
  +		    if (c == fn)
  +		      goto matched;
  +
  +		    cold = c;
  +		    c = *p++;
  +
  +		    if (c == '-' && *p != ']')
  +		      {
  +			/* It is a range.  */
  +			char lo[2];
  +			char fc[2];
  +			unsigned char cend = *p++;
  +			if (!(flags & FNM_NOESCAPE) && cend == '\\')
  +			  cend = *p++;
  +			if (cend == '\0')
  +			  return FNM_NOMATCH;
  +
  +			lo[0] = cold;
  +			lo[1] = '\0';
  +			fc[0] = fn;
  +			fc[1] = '\0';
  +			if (strcoll (lo, fc) <= 0)
  +			  {
  +			    char hi[2];
  +			    hi[0] = FOLD (cend);
  +			    hi[1] = '\0';
  +			    if (strcoll (fc, hi) <= 0)
  +			      goto matched;
  +			  }
  +
  +			c = *p++;
  +		      }
  +		  }
  +
  +		if (c == ']')
  +		  break;
  +	      }
  +
  +	    if (!not)
  +	      return FNM_NOMATCH;
  +	    break;
  +
  +	  matched:
  +	    /* Skip the rest of the [...] that already matched.  */
  +	    while (c != ']')
  +	      {
  +		if (c == '\0')
  +		  /* [... (unterminated) loses.  */
  +		  return FNM_NOMATCH;
  +
  +		c = *p++;
  +		if (!(flags & FNM_NOESCAPE) && c == '\\')
  +		  {
  +		    if (*p == '\0')
  +		      return FNM_NOMATCH;
  +		    /* XXX 1003.2d11 is unclear if this is right.  */
  +		    ++p;
  +		  }
  +		else if (c == '[' && *p == ':')
  +		  {
  +		    do
  +		      if (*++p == '\0')
  +			return FNM_NOMATCH;
  +		    while (*p != ':' || p[1] == ']');
  +		    p += 2;
  +		    c = *p;
  +		  }
  +	      }
  +	    if (not)
  +	      return FNM_NOMATCH;
  +	  }
  +	  break;
  +
  +	default:
  +	  if (c != FOLD ((unsigned char) *n))
  +	    return FNM_NOMATCH;
  +	}
  +
  +      ++n;
  +    }
  +
  +  if (*n == '\0')
  +    return 0;
  +
  +  if ((flags & FNM_LEADING_DIR) && *n == '/')
  +    /* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz".  */
  +    return 0;
  +
  +  return FNM_NOMATCH;
  +
  +# undef FOLD
  +}
  +
  +
  +int
  +fnmatch (const char *pattern, const char *string, int flags)
  +{
  +  return internal_fnmatch (pattern, string, flags & FNM_PERIOD, flags);
  +}
  +
  +#endif	/* _LIBC or not __GNU_LIBRARY__.  */
  +/*@=unreachable@*/
  +/*@=temptrans@*/
  +/*@=shiftimplementation@*/
  +/*@=retalias@*/
  +/*@=bounds@*/
  @@ .
  patch -p0 <<'@@ .'
  Index: rpm/rpmio/fnmatch.h
  ============================================================================
  $ cvs diff -u -r0 -r2.1.2.2 fnmatch.h
  --- /dev/null	2008-08-14 22:30:29 +0200
  +++ fnmatch.h	2008-08-14 22:32:05 +0200
  @@ -0,0 +1,88 @@
  +/* Copyright (C) 1991,92,93,96,97,98,99,2001 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
  +
  +#if defined __cplusplus || (defined __STDC__ && __STDC__) || defined WINDOWS32
  +# if !defined __GLIBC__ || !defined __P
  +#  undef	__P
  +#  define __P(protos)	protos
  +# endif
  +#else /* Not C++ or ANSI C.  */
  +# undef	__P
  +# define __P(protos)	()
  +/* We can get away without defining `const' here only because in this file
  +   it is used only inside the prototype for `fnmatch', which is elided in
  +   non-ANSI C where `const' is problematical.  */
  +#endif /* C++ or ANSI C.  */
  +
  +#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 __P ((__const char *__pattern, __const char *__name,
  +			 int __flags))
  +	/*@*/;
  +/*@=redecl@*/
  +
  +#ifdef	__cplusplus
  +}
  +#endif
  +
  +#endif /* fnmatch.h */
  @@ .
  patch -p0 <<'@@ .'
  Index: rpm/rpmio/glob.c
  ============================================================================
  $ cvs diff -u -r0 -r2.2.2.2 glob.c
  --- /dev/null	2008-08-14 22:30:29 +0200
  +++ glob.c	2008-08-14 22:32:05 +0200
  @@ -0,0 +1,1208 @@
  +/*@-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"
  +
  +# include <assert.h>
  +
  +#undef __alloca
  +#define	__alloca	alloca
  +#define	__stat		stat
  +#define	NAMLEN(_d)	NLENGTH(_d)
  +
  +#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
  +
  +/* Outcomment the following line for production quality code.  */
  +/* #define NDEBUG 1 */
  +
  +#define GLOB_INTERFACE_VERSION 1
  +
  +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));
  +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 *) xmalloc (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 = 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 = 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 **) xrealloc (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] = xstrdup (dirname);
  +#else
  +	  {
  +	    size_t len = strlen (dirname) + 1;
  +	    char *dircopy = xmalloc (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 **) xrealloc (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] = xmalloc (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 **) xrealloc (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 *new = xrealloc (pglob->gl_pathv[i], len);
  + 	    if (new == NULL)
  +	      {
  +		globfree (pglob);
  +		return GLOB_NOSPACE;
  +	      }
  +	    strcpy (&new[len - 2], "/");
  +	    pglob->gl_pathv[i] = new;
  +	  }
  +    }
  +
  +  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 *new = (char *) xmalloc (dirlen + 1 + eltlen);
  +      if (new == NULL)
  +	{
  +	  while (i > 0)
  +	    free ((__ptr_t) array[--i]);
  +	  return 1;
  +	}
  +
  +#ifdef HAVE_MEMPCPY
  +      {
  +	char *endp = (char *) mempcpy (new, dirname, dirlen);
  +	*endp++ = DIRSEP_CHAR;
  +	mempcpy (endp, array[i], eltlen);
  +      }
  +#else
  +      memcpy (new, dirname, dirlen);
  +      new[dirlen] = DIRSEP_CHAR;
  +      memcpy (&new[dirlen + 1], array[i], eltlen);
  +#endif
  +      free ((__ptr_t) array[i]);
  +      array[i] = new;
  +    }
  +
  +  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 *) xmalloc (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 = ((flags & GLOB_ALTDIRFUNC)
  +				      ? (*pglob->gl_readdir) (stream)
  +				      : 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 *new = (struct globlink *)
  +			__alloca (sizeof (struct globlink));
  +		      len = NAMLEN (d);
  +		      new->name = (char *) xmalloc (len + 1);
  +		      if (new->name == NULL)
  +			goto memory_error;
  +#ifdef HAVE_MEMPCPY
  +		      *((char *) mempcpy ((__ptr_t) new->name, name, len))
  +			= '\0';
  +#else
  +		      memcpy ((__ptr_t) new->name, name, len);
  +		      new->name[len] = '\0';
  +#endif
  +		      new->next = names;
  +		      names = new;
  +		      ++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 *) xmalloc (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 **) xrealloc (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/rpmio/glob.h
  ============================================================================
  $ cvs diff -u -r0 -r2.1.2.2 glob.h
  --- /dev/null	2008-08-14 22:30:29 +0200
  +++ glob.h	2008-08-14 22:32:05 +0200
  @@ -0,0 +1,205 @@
  +/* 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));
  +
  +/* 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");
  +
  +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));
  +
  +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  */
  @@ .
Received on Thu Aug 14 22:32:05 2008
Driven by Jeff Johnson and the RPM project team.
Hosted by OpenPKG and Ralf S. Engelschall.
Powered by FreeBSD and OpenPKG.