[Nagiosplug-checkins] nagiosplug/gl Makefile.am, NONE, 1.1 alloca.c, NONE, 1.1 alloca_.h, NONE, 1.1 asnprintf.c, NONE, 1.1 asprintf.c, NONE, 1.1 basename.c, NONE, 1.1 c-strtod.c, NONE, 1.1 c-strtod.h, NONE, 1.1 cloexec.c, NONE, 1.1 cloexec.h, NONE, 1.1 creat-safer.c, NONE, 1.1 dirname.c, NONE, 1.1 dirname.h, NONE, 1.1 dup-safer.c, NONE, 1.1 error.c, NONE, 1.1 error.h, NONE, 1.1 exit.h, NONE, 1.1 exitfail.c, NONE, 1.1 exitfail.h, NONE, 1.1 fcntl--.h, NONE, 1.1 fcntl-safer.h, NONE, 1.1 fd-safer.c, NONE, 1.1 fsusage.c, NONE, 1.1 fsusage.h, NONE, 1.1 full-read.c, NONE, 1.1 full-read.h, NONE, 1.1 full-write.c, NONE, 1.1 full-write.h, NONE, 1.1 gai_strerror.c, NONE, 1.1 getaddrinfo.c, NONE, 1.1 getaddrinfo.h, NONE, 1.1 gethostname.c, NONE, 1.1 getloadavg.c, NONE, 1.1 getopt.c, NONE, 1.1 getopt1.c, NONE, 1.1 getopt_.h, NONE, 1.1 getopt_int.h, NONE, 1.1 gettext.h, NONE, 1.1 inet_ntop.c, NONE, 1.1 inet_ntop.h, NONE, 1.1 intprops.h, NONE, 1.1 malloc.c, NONE, 1.1 mbchar.c, NONE, 1.1 mbchar.h, NONE, 1.1 mbuiter.h, NONE, 1.1 memchr.c, NONE, 1.1 minmax.h, NONE, 1.1 mountlist.c, NONE, 1.1 mountlist.h, NONE, 1.1 open-safer.c, NONE, 1.1 pipe-safer.c, NONE, 1.1 printf-args.c, NONE, 1.1 printf-args.h, NONE, 1.1 printf-parse.c, NONE, 1.1 printf-parse.h, NONE, 1.1 regcomp.c, NONE, 1.1 regex.c, NONE, 1.1 regex.h, NONE, 1.1 regex_internal.c, NONE, 1.1 regex_internal.h, NONE, 1.1 regexec.c, NONE, 1.1 safe-read.c, NONE, 1.1 safe-read.h, NONE, 1.1 safe-write.c, NONE, 1.1 safe-write.h, NONE, 1.1 size_max.h, NONE, 1.1 snprintf.c, NONE, 1.1 snprintf.h, NONE, 1.1 socket_.h, NONE, 1.1 stdbool_.h, NONE, 1.1 stdint_.h, NONE, 1.1 strcase.h, NONE, 1.1 strcasecmp.c, NONE, 1.1 strdup.c, NONE, 1.1 strdup.h, NONE, 1.1 stripslash.c, NONE, 1.1 strncasecmp.c, NONE, 1.1 strndup.c, NONE, 1.1 strndup.h, NONE, 1.1 strnlen.c, NONE, 1.1 strnlen.h, NONE, 1.1 strnlen1.c, NONE, 1.1 strnlen1.h, NONE, 1.1 unistd--.h, NONE, 1.1 unistd-safer.h, NONE, 1.1 unistd_.h, NONE, 1.1 vasnprintf.c, NONE, 1.1 vasnprintf.h, NONE, 1.1 vasprintf.c, NONE, 1.1 vasprintf.h, NONE, 1.1 vsnprintf.c, NONE, 1.1 vsnprintf.h, NONE, 1.1 wchar_.h, NONE, 1.1 wctype_.h, NONE, 1.1 wcwidth.h, NONE, 1.1 xalloc-die.c, NONE, 1.1 xalloc.h, NONE, 1.1 xmalloc.c, NONE, 1.1 xsize.h, NONE, 1.1 xstrndup.c, NONE, 1.1 xstrndup.h, NONE, 1.1

Ton Voon tonvoon at users.sourceforge.net
Wed Jan 24 23:46:44 CET 2007


Update of /cvsroot/nagiosplug/nagiosplug/gl
In directory sc8-pr-cvs7.sourceforge.net:/tmp/cvs-serv9154/gl

Added Files:
	Makefile.am alloca.c alloca_.h asnprintf.c asprintf.c 
	basename.c c-strtod.c c-strtod.h cloexec.c cloexec.h 
	creat-safer.c dirname.c dirname.h dup-safer.c error.c error.h 
	exit.h exitfail.c exitfail.h fcntl--.h fcntl-safer.h 
	fd-safer.c fsusage.c fsusage.h full-read.c full-read.h 
	full-write.c full-write.h gai_strerror.c getaddrinfo.c 
	getaddrinfo.h gethostname.c getloadavg.c getopt.c getopt1.c 
	getopt_.h getopt_int.h gettext.h inet_ntop.c inet_ntop.h 
	intprops.h malloc.c mbchar.c mbchar.h mbuiter.h memchr.c 
	minmax.h mountlist.c mountlist.h open-safer.c pipe-safer.c 
	printf-args.c printf-args.h printf-parse.c printf-parse.h 
	regcomp.c regex.c regex.h regex_internal.c regex_internal.h 
	regexec.c safe-read.c safe-read.h safe-write.c safe-write.h 
	size_max.h snprintf.c snprintf.h socket_.h stdbool_.h 
	stdint_.h strcase.h strcasecmp.c strdup.c strdup.h 
	stripslash.c strncasecmp.c strndup.c strndup.h strnlen.c 
	strnlen.h strnlen1.c strnlen1.h unistd--.h unistd-safer.h 
	unistd_.h vasnprintf.c vasnprintf.h vasprintf.c vasprintf.h 
	vsnprintf.c vsnprintf.h wchar_.h wctype_.h wcwidth.h 
	xalloc-die.c xalloc.h xmalloc.c xsize.h xstrndup.c xstrndup.h 
Log Message:
Sync with gnulib - lots of extraneous code removed in preference to GNU code


--- NEW FILE: fd-safer.c ---
/* Return a safer copy of a file descriptor.

   Copyright (C) 2005, 2006 Free Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

/* Written by Paul Eggert.  */

#include <config.h>

#include "unistd-safer.h"

#include <errno.h>

#include <unistd.h>
#ifndef STDIN_FILENO
# define STDIN_FILENO 0
#endif
#ifndef STDERR_FILENO
# define STDERR_FILENO 2
#endif

/* Return FD, unless FD would be a copy of standard input, output, or
   error; in that case, return a duplicate of FD, closing FD.  On
   failure to duplicate, close FD, set errno, and return -1.  Preserve
   errno if FD is negative, so that the caller can always inspect
   errno when the returned value is negative.

   This function is usefully wrapped around functions that return file
   descriptors, e.g., fd_safer (open ("file", O_RDONLY)).  */

int
fd_safer (int fd)
{
  if (STDIN_FILENO <= fd && fd <= STDERR_FILENO)
    {
      int f = dup_safer (fd);
      int e = errno;
      close (fd);
      errno = e;
      fd = f;
    }

  return fd;
}

--- NEW FILE: xalloc.h ---
/* xalloc.h -- malloc with out-of-memory checking

   Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
   1999, 2000, 2003, 2004, 2006 Free Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

#ifndef XALLOC_H_
# define XALLOC_H_

# include <stddef.h>


# ifdef __cplusplus
extern "C" {
# endif


# ifndef __attribute__
#  if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) || __STRICT_ANSI__
#   define __attribute__(x)
#  endif
# endif

# ifndef ATTRIBUTE_NORETURN
#  define ATTRIBUTE_NORETURN __attribute__ ((__noreturn__))
# endif

/* This function is always triggered when memory is exhausted.
   It must be defined by the application, either explicitly
   or by using gnulib's xalloc-die module.  This is the
   function to call when one wants the program to die because of a
   memory allocation failure.  */
extern void xalloc_die (void) ATTRIBUTE_NORETURN;

void *xmalloc (size_t s);
void *xzalloc (size_t s);
void *xcalloc (size_t n, size_t s);
void *xrealloc (void *p, size_t s);
void *x2realloc (void *p, size_t *pn);
void *xmemdup (void const *p, size_t s);
char *xstrdup (char const *str);

/* Return 1 if an array of N objects, each of size S, cannot exist due
   to size arithmetic overflow.  S must be positive and N must be
   nonnegative.  This is a macro, not an inline function, so that it
   works correctly even when SIZE_MAX < N.

   By gnulib convention, SIZE_MAX represents overflow in size
   calculations, so the conservative dividend to use here is
   SIZE_MAX - 1, since SIZE_MAX might represent an overflowed value.
   However, malloc (SIZE_MAX) fails on all known hosts where
   sizeof (ptrdiff_t) <= sizeof (size_t), so do not bother to test for
   exactly-SIZE_MAX allocations on such hosts; this avoids a test and
   branch when S is known to be 1.  */
# define xalloc_oversized(n, s) \
    ((size_t) (sizeof (ptrdiff_t) <= sizeof (size_t) ? -1 : -2) / (s) < (n))


/* In the following macros, T must be an elementary or structure/union or
   typedef'ed type, or a pointer to such a type.  To apply one of the
   following macros to a function pointer or array type, you need to typedef
   it first and use the typedef name.  */

/* Allocate an object of type T dynamically, with error checking.  */
/* extern t *XMALLOC (typename t); */
# define XMALLOC(t) ((t *) xmalloc (sizeof (t)))

/* Allocate memory for N elements of type T, with error checking.  */
/* extern t *XNMALLOC (size_t n, typename t); */
# define XNMALLOC(n, t) \
    ((t *) (sizeof (t) == 1 ? xmalloc (n) : xnmalloc (n, sizeof (t))))

/* Allocate an object of type T dynamically, with error checking,
   and zero it.  */
/* extern t *XZALLOC (typename t); */
# define XZALLOC(t) ((t *) xzalloc (sizeof (t)))

/* Allocate memory for N elements of type T, with error checking,
   and zero it.  */
/* extern t *XCALLOC (size_t n, typename t); */
# define XCALLOC(n, t) \
    ((t *) (sizeof (t) == 1 ? xzalloc (n) : xcalloc (n, sizeof (t))))


# if HAVE_INLINE
#  define static_inline static inline
# else
   void *xnmalloc (size_t n, size_t s);
   void *xnrealloc (void *p, size_t n, size_t s);
   void *x2nrealloc (void *p, size_t *pn, size_t s);
   char *xcharalloc (size_t n);
# endif

# ifdef static_inline

/* Allocate an array of N objects, each with S bytes of memory,
   dynamically, with error checking.  S must be nonzero.  */

static_inline void *
xnmalloc (size_t n, size_t s)
{
  if (xalloc_oversized (n, s))
    xalloc_die ();
  return xmalloc (n * s);
}

/* Change the size of an allocated block of memory P to an array of N
   objects each of S bytes, with error checking.  S must be nonzero.  */

static_inline void *
xnrealloc (void *p, size_t n, size_t s)
{
  if (xalloc_oversized (n, s))
    xalloc_die ();
  return xrealloc (p, n * s);
}

/* If P is null, allocate a block of at least *PN such objects;
   otherwise, reallocate P so that it contains more than *PN objects
   each of S bytes.  *PN must be nonzero unless P is null, and S must
   be nonzero.  Set *PN to the new number of objects, and return the
   pointer to the new block.  *PN is never set to zero, and the
   returned pointer is never null.

   Repeated reallocations are guaranteed to make progress, either by
   allocating an initial block with a nonzero size, or by allocating a
   larger block.

   In the following implementation, nonzero sizes are doubled so that
   repeated reallocations have O(N log N) overall cost rather than
   O(N**2) cost, but the specification for this function does not
   guarantee that sizes are doubled.

   Here is an example of use:

     int *p = NULL;
     size_t used = 0;
     size_t allocated = 0;

     void
     append_int (int value)
       {
	 if (used == allocated)
	   p = x2nrealloc (p, &allocated, sizeof *p);
	 p[used++] = value;
       }

   This causes x2nrealloc to allocate a block of some nonzero size the
   first time it is called.

   To have finer-grained control over the initial size, set *PN to a
   nonzero value before calling this function with P == NULL.  For
   example:

     int *p = NULL;
     size_t used = 0;
     size_t allocated = 0;
     size_t allocated1 = 1000;

     void
     append_int (int value)
       {
	 if (used == allocated)
	   {
	     p = x2nrealloc (p, &allocated1, sizeof *p);
	     allocated = allocated1;
	   }
	 p[used++] = value;
       }

   */

static_inline void *
x2nrealloc (void *p, size_t *pn, size_t s)
{
  size_t n = *pn;

  if (! p)
    {
      if (! n)
	{
	  /* The approximate size to use for initial small allocation
	     requests, when the invoking code specifies an old size of
	     zero.  64 bytes is the largest "small" request for the
	     GNU C library malloc.  */
	  enum { DEFAULT_MXFAST = 64 };

	  n = DEFAULT_MXFAST / s;
	  n += !n;
	}
    }
  else
    {
      if (((size_t) -1) / 2 / s < n)
	xalloc_die ();
      n *= 2;
    }

  *pn = n;
  return xrealloc (p, n * s);
}

/* Return a pointer to a new buffer of N bytes.  This is like xmalloc,
   except it returns char *.  */

static_inline char *
xcharalloc (size_t n)
{
  return XNMALLOC (n, char);
}

# endif

# ifdef __cplusplus
}

/* C++ does not allow conversions from void * to other pointer types
   without a cast.  Use templates to work around the problem when
   possible.  */

template <typename T> inline T *
xrealloc (T *p, size_t s)
{
  return (T *) xrealloc ((void *) p, s);
}

template <typename T> inline T *
xnrealloc (T *p, size_t n, size_t s)
{
  return (T *) xnrealloc ((void *) p, n, s);
}

template <typename T> inline T *
x2realloc (T *p, size_t *pn)
{
  return (T *) x2realloc ((void *) p, pn);
}

template <typename T> inline T *
x2nrealloc (T *p, size_t *pn, size_t s)
{
  return (T *) x2nrealloc ((void *) p, pn, s);
}

template <typename T> inline T *
xmemdup (T const *p, size_t s)
{
  return (T *) xmemdup ((void const *) p, s);
}

# endif


#endif /* !XALLOC_H_ */

--- NEW FILE: gettext.h ---
/* Convenience header for conditional use of GNU <libintl.h>.
   Copyright (C) 1995-1998, 2000-2002, 2004-2006 Free Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License along
   with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

#ifndef _LIBGETTEXT_H
#define _LIBGETTEXT_H 1

/* NLS can be disabled through the configure --disable-nls option.  */
#if ENABLE_NLS

/* Get declarations of GNU message catalog functions.  */
# include <libintl.h>

/* You can set the DEFAULT_TEXT_DOMAIN macro to specify the domain used by
   the gettext() and ngettext() macros.  This is an alternative to calling
   textdomain(), and is useful for libraries.  */
# ifdef DEFAULT_TEXT_DOMAIN
#  undef gettext
#  define gettext(Msgid) \
     dgettext (DEFAULT_TEXT_DOMAIN, Msgid)
#  undef ngettext
#  define ngettext(Msgid1, Msgid2, N) \
     dngettext (DEFAULT_TEXT_DOMAIN, Msgid1, Msgid2, N)
# endif

#else

/* Solaris /usr/include/locale.h includes /usr/include/libintl.h, which
   chokes if dcgettext is defined as a macro.  So include it now, to make
   later inclusions of <locale.h> a NOP.  We don't include <libintl.h>
   as well because people using "gettext.h" will not include <libintl.h>,
   and also including <libintl.h> would fail on SunOS 4, whereas <locale.h>
   is OK.  */
#if defined(__sun)
# include <locale.h>
#endif

/* Many header files from the libstdc++ coming with g++ 3.3 or newer include
   <libintl.h>, which chokes if dcgettext is defined as a macro.  So include
   it now, to make later inclusions of <libintl.h> a NOP.  */
#if defined(__cplusplus) && defined(__GNUG__) && (__GNUC__ >= 3)
# include <cstdlib>
# if (__GLIBC__ >= 2) || _GLIBCXX_HAVE_LIBINTL_H
#  include <libintl.h>
# endif
#endif

/* Disabled NLS.
   The casts to 'const char *' serve the purpose of producing warnings
   for invalid uses of the value returned from these functions.
   On pre-ANSI systems without 'const', the config.h file is supposed to
   contain "#define const".  */
# define gettext(Msgid) ((const char *) (Msgid))
# define dgettext(Domainname, Msgid) ((void) (Domainname), gettext (Msgid))
# define dcgettext(Domainname, Msgid, Category) \
    ((void) (Category), dgettext (Domainname, Msgid))
# define ngettext(Msgid1, Msgid2, N) \
    ((N) == 1 \
     ? ((void) (Msgid2), (const char *) (Msgid1)) \
     : ((void) (Msgid1), (const char *) (Msgid2)))
# define dngettext(Domainname, Msgid1, Msgid2, N) \
    ((void) (Domainname), ngettext (Msgid1, Msgid2, N))
# define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \
    ((void) (Category), dngettext(Domainname, Msgid1, Msgid2, N))
# define textdomain(Domainname) ((const char *) (Domainname))
# define bindtextdomain(Domainname, Dirname) \
    ((void) (Domainname), (const char *) (Dirname))
# define bind_textdomain_codeset(Domainname, Codeset) \
    ((void) (Domainname), (const char *) (Codeset))

#endif

/* A pseudo function call that serves as a marker for the automated
   extraction of messages, but does not call gettext().  The run-time
   translation is done at a different place in the code.
   The argument, String, should be a literal string.  Concatenated strings
   and other string expressions won't work.
   The macro's expansion is not parenthesized, so that it is suitable as
   initializer for static 'char[]' or 'const char[]' variables.  */
#define gettext_noop(String) String

/* The separator between msgctxt and msgid in a .mo file.  */
#define GETTEXT_CONTEXT_GLUE "\004"

/* Pseudo function calls, taking a MSGCTXT and a MSGID instead of just a
   MSGID.  MSGCTXT and MSGID must be string literals.  MSGCTXT should be
   short and rarely need to change.
   The letter 'p' stands for 'particular' or 'special'.  */
#ifdef DEFAULT_TEXT_DOMAIN
# define pgettext(Msgctxt, Msgid) \
   pgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
#else
# define pgettext(Msgctxt, Msgid) \
   pgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
#endif
#define dpgettext(Domainname, Msgctxt, Msgid) \
  pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
#define dcpgettext(Domainname, Msgctxt, Msgid, Category) \
  pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, Category)
#ifdef DEFAULT_TEXT_DOMAIN
# define npgettext(Msgctxt, Msgid, MsgidPlural, N) \
   npgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
#else
# define npgettext(Msgctxt, Msgid, MsgidPlural, N) \
   npgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
#endif
#define dnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N) \
  npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
#define dcnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N, Category) \
  npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, Category)

#ifdef __GNUC__
__inline
#else
#ifdef __cplusplus
inline
#endif
#endif
static const char *
pgettext_aux (const char *domain,
	      const char *msg_ctxt_id, const char *msgid,
	      int category)
{
  const char *translation = dcgettext (domain, msg_ctxt_id, category);
  if (translation == msg_ctxt_id)
    return msgid;
  else
    return translation;
}

#ifdef __GNUC__
__inline
#else
#ifdef __cplusplus
inline
#endif
#endif
static const char *
npgettext_aux (const char *domain,
	       const char *msg_ctxt_id, const char *msgid,
	       const char *msgid_plural, unsigned long int n,
	       int category)
{
  const char *translation =
    dcngettext (domain, msg_ctxt_id, msgid_plural, n, category);
  if (translation == msg_ctxt_id || translation == msgid_plural)
    return (n == 1 ? msgid : msgid_plural);
  else
    return translation;
}

/* The same thing extended for non-constant arguments.  Here MSGCTXT and MSGID
   can be arbitrary expressions.  But for string literals these macros are
   less efficient than those above.  */

#include <string.h>

#define _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS \
  (((__GNUC__ >= 3 || __GNUG__ >= 2) && !__STRICT_ANSI__) \
   /* || __STDC_VERSION__ >= 199901L */ )

#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
#include <stdlib.h>
#endif

#define pgettext_expr(Msgctxt, Msgid) \
  dcpgettext_expr (NULL, Msgctxt, Msgid, LC_MESSAGES)
#define dpgettext_expr(Domainname, Msgctxt, Msgid) \
  dcpgettext_expr (Domainname, Msgctxt, Msgid, LC_MESSAGES)

#ifdef __GNUC__
__inline
#else
#ifdef __cplusplus
inline
#endif
#endif
static const char *
dcpgettext_expr (const char *domain,
		 const char *msgctxt, const char *msgid,
		 int category)
{
  size_t msgctxt_len = strlen (msgctxt) + 1;
  size_t msgid_len = strlen (msgid) + 1;
  const char *translation;
#if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
  char msg_ctxt_id[msgctxt_len + msgid_len];
#else
  char buf[1024];
  char *msg_ctxt_id =
    (msgctxt_len + msgid_len <= sizeof (buf)
     ? buf
     : (char *) malloc (msgctxt_len + msgid_len));
  if (msg_ctxt_id != NULL)
#endif
    {
      memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1);
      msg_ctxt_id[msgctxt_len - 1] = '\004';
      memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len);
      translation = dcgettext (domain, msg_ctxt_id, category);
#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
      if (msg_ctxt_id != buf)
	free (msg_ctxt_id);
#endif
      if (translation != msg_ctxt_id)
	return translation;
    }
  return msgid;
}

#define npgettext_expr(Msgctxt, Msgid, MsgidPlural, N) \
  dcnpgettext_expr (NULL, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES)
#define dnpgettext_expr(Domainname, Msgctxt, Msgid, MsgidPlural, N) \
  dcnpgettext_expr (Domainname, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES)

#ifdef __GNUC__
__inline
#else
#ifdef __cplusplus
inline
#endif
#endif
static const char *
dcnpgettext_expr (const char *domain,
		  const char *msgctxt, const char *msgid,
		  const char *msgid_plural, unsigned long int n,
		  int category)
{
  size_t msgctxt_len = strlen (msgctxt) + 1;
  size_t msgid_len = strlen (msgid) + 1;
  const char *translation;
#if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
  char msg_ctxt_id[msgctxt_len + msgid_len];
#else
  char buf[1024];
  char *msg_ctxt_id =
    (msgctxt_len + msgid_len <= sizeof (buf)
     ? buf
     : (char *) malloc (msgctxt_len + msgid_len));
  if (msg_ctxt_id != NULL)
#endif
    {
      memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1);
      msg_ctxt_id[msgctxt_len - 1] = '\004';
      memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len);
      translation = dcngettext (domain, msg_ctxt_id, msgid_plural, n, category);
#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
      if (msg_ctxt_id != buf)
	free (msg_ctxt_id);
#endif
      if (!(translation == msg_ctxt_id || translation == msgid_plural))
	return translation;
    }
  return (n == 1 ? msgid : msgid_plural);
}

#endif /* _LIBGETTEXT_H */

--- NEW FILE: regexec.c ---
/* Extended regular expression matching and search library.
   Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
   This file is part of the GNU C Library.
   Contributed by Isamu Hasegawa <isamu at yamato.ibm.com>.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License along
   with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */

[...4359 lines suppressed...]
    {
      subtop->lasts[subtop->nlasts] = new_entry;
      new_entry->node = node;
      new_entry->str_idx = str_idx;
      ++subtop->nlasts;
    }
  return new_entry;
}

static void
internal_function
sift_ctx_init (re_sift_context_t *sctx, re_dfastate_t **sifted_sts,
	       re_dfastate_t **limited_sts, Idx last_node, Idx last_str_idx)
{
  sctx->sifted_states = sifted_sts;
  sctx->limited_states = limited_sts;
  sctx->last_node = last_node;
  sctx->last_str_idx = last_str_idx;
  re_node_set_init_empty (&sctx->limits);
}

--- NEW FILE: strdup.c ---
/* Copyright (C) 1991, 1996, 1997, 1998, 2002, 2003, 2004, 2006 Free
   Software Foundation, Inc.

   This file is part of the GNU C Library.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License along
   with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

#ifndef _LIBC
# include <config.h>
/* Get specification.  */
# include "strdup.h"
#endif

#include <stdlib.h>
#include <string.h>

#undef __strdup
#ifdef _LIBC
# undef strdup
#endif

#ifndef weak_alias
# define __strdup strdup
#endif

/* Duplicate S, returning an identical malloc'd string.  */
char *
__strdup (const char *s)
{
  size_t len = strlen (s) + 1;
  void *new = malloc (len);

  if (new == NULL)
    return NULL;

  return (char *) memcpy (new, s, len);
}
#ifdef libc_hidden_def
libc_hidden_def (__strdup)
#endif
#ifdef weak_alias
weak_alias (__strdup, strdup)
#endif

--- NEW FILE: mbuiter.h ---
/* Iterating through multibyte strings: macros for multi-byte encodings.
   Copyright (C) 2001, 2005 Free Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software Foundation,
   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */

/* Written by Bruno Haible <bruno at clisp.org>.  */

/* The macros in this file implement forward iteration through a
   multi-byte string, without knowing its length a-priori.

   With these macros, an iteration loop that looks like

      char *iter;
      for (iter = buf; *iter != '\0'; iter++)
        {
          do_something (*iter);
        }

   becomes

      mbui_iterator_t iter;
      for (mbui_init (iter, buf); mbui_avail (iter); mbui_advance (iter))
        {
          do_something (mbui_cur_ptr (iter), mb_len (mbui_cur (iter)));
        }

   The benefit of these macros over plain use of mbrtowc is:
   - Handling of invalid multibyte sequences is possible without
     making the code more complicated, while still preserving the
     invalid multibyte sequences.

   Compared to mbiter.h, the macros here don't need to know the string's
   length a-priori.  The downside is that at each step, the look-ahead
   that guards against overrunning the terminating '\0' is more expensive.
   The mbui_* macros are therefore suitable when there is a high probability
   that only the first few multibyte characters need to be inspected.
   Whereas the mbi_* macros are better if usually the iteration runs
   through the entire string.

   mbui_iterator_t
     is a type usable for variable declarations.

   mbui_init (iter, startptr)
     initializes the iterator, starting at startptr.

   mbui_avail (iter)
     returns true if there are more multibyte chracters available before
     the end of string is reached. In this case, mbui_cur (iter) is
     initialized to the next multibyte chracter.

   mbui_advance (iter)
     advances the iterator by one multibyte character.

   mbui_cur (iter)
     returns the current multibyte character, of type mbchar_t.  All the
     macros defined in mbchar.h can be used on it.

   mbui_cur_ptr (iter)
     return a pointer to the beginning of the current multibyte character.

   mbui_reloc (iter, ptrdiff)
     relocates iterator when the string is moved by ptrdiff bytes.

   Here are the function prototypes of the macros.

   extern void		mbui_init (mbui_iterator_t iter, const char *startptr);
   extern bool		mbui_avail (mbui_iterator_t iter);
   extern void		mbui_advance (mbui_iterator_t iter);
   extern mbchar_t	mbui_cur (mbui_iterator_t iter);
   extern const char *	mbui_cur_ptr (mbui_iterator_t iter);
   extern void		mbui_reloc (mbui_iterator_t iter, ptrdiff_t ptrdiff);
 */

#ifndef _MBUITER_H
#define _MBUITER_H 1

#include <assert.h>
#include <stdbool.h>
#include <stdlib.h>

/* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
   <wchar.h>.
   BSD/OS 4.1 has a bug: <stdio.h> and <time.h> must be included before
   <wchar.h>.  */
#include <stdio.h>
#include <time.h>
#include <wchar.h>

#include "mbchar.h"
#include "strnlen1.h"

struct mbuiter_multi
{
  bool in_shift;	/* true if next byte may not be interpreted as ASCII */
  mbstate_t state;	/* if in_shift: current shift state */
  bool next_done;	/* true if mbui_avail has already filled the following */
  struct mbchar cur;	/* the current character:
	const char *cur.ptr		pointer to current character
	The following are only valid after mbui_avail.
	size_t cur.bytes		number of bytes of current character
	bool cur.wc_valid		true if wc is a valid wide character
	wchar_t cur.wc			if wc_valid: the current character
	*/
};

static inline void
mbuiter_multi_next (struct mbuiter_multi *iter)
{
  if (iter->next_done)
    return;
  if (iter->in_shift)
    goto with_shift;
  /* Handle most ASCII characters quickly, without calling mbrtowc().  */
  if (is_basic (*iter->cur.ptr))
    {
      /* These characters are part of the basic character set.  ISO C 99
	 guarantees that their wide character code is identical to their
	 char code.  */
      iter->cur.bytes = 1;
      iter->cur.wc = *iter->cur.ptr;
      iter->cur.wc_valid = true;
    }
  else
    {
      assert (mbsinit (&iter->state));
      iter->in_shift = true;
    with_shift:
      iter->cur.bytes = mbrtowc (&iter->cur.wc, iter->cur.ptr,
				 strnlen1 (iter->cur.ptr, MB_CUR_MAX),
				 &iter->state);
      if (iter->cur.bytes == (size_t) -1)
	{
	  /* An invalid multibyte sequence was encountered.  */
	  iter->cur.bytes = 1;
	  iter->cur.wc_valid = false;
	  /* Whether to set iter->in_shift = false and reset iter->state
	     or not is not very important; the string is bogus anyway.  */
	}
      else if (iter->cur.bytes == (size_t) -2)
	{
	  /* An incomplete multibyte character at the end.  */
	  iter->cur.bytes = strlen (iter->cur.ptr);
	  iter->cur.wc_valid = false;
	  /* Whether to set iter->in_shift = false and reset iter->state
	     or not is not important; the string end is reached anyway.  */
	}
      else
	{
	  if (iter->cur.bytes == 0)
	    {
	      /* A null wide character was encountered.  */
	      iter->cur.bytes = 1;
	      assert (*iter->cur.ptr == '\0');
	      assert (iter->cur.wc == 0);
	    }
	  iter->cur.wc_valid = true;

	  /* When in the initial state, we can go back treating ASCII
	     characters more quickly.  */
	  if (mbsinit (&iter->state))
	    iter->in_shift = false;
	}
    }
  iter->next_done = true;
}

static inline void
mbuiter_multi_reloc (struct mbuiter_multi *iter, ptrdiff_t ptrdiff)
{
  iter->cur.ptr += ptrdiff;
}

/* Iteration macros.  */
typedef struct mbuiter_multi mbui_iterator_t;
#define mbui_init(iter, startptr) \
  ((iter).cur.ptr = (startptr), \
   (iter).in_shift = false, memset (&(iter).state, '\0', sizeof (mbstate_t)), \
   (iter).next_done = false)
#define mbui_avail(iter) \
  (mbuiter_multi_next (&(iter)), !mb_isnul ((iter).cur))
#define mbui_advance(iter) \
  ((iter).cur.ptr += (iter).cur.bytes, (iter).next_done = false)

/* Access to the current character.  */
#define mbui_cur(iter) (iter).cur
#define mbui_cur_ptr(iter) (iter).cur.ptr

/* Relocation.  */
#define mbui_reloc(iter, ptrdiff) mbuiter_multi_reloc (&iter, ptrdiff)

#endif /* _MBUITER_H */

--- NEW FILE: strdup.h ---
/* strdup.h -- duplicate a string
   Copyright (C) 2004, 2006 Free Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

#ifndef STRDUP_H_
#define STRDUP_H_

/* Get strdup declaration, if available.  */
#include <string.h>

#ifdef __cplusplus
extern "C" {
#endif


#if defined HAVE_DECL_STRDUP && !HAVE_DECL_STRDUP && !defined strdup
/* Duplicate S, returning an identical malloc'd string.  */
extern char *strdup (const char *s);
#endif


#ifdef __cplusplus
}
#endif

#endif /* STRDUP_H_ */

--- NEW FILE: getopt1.c ---
/* getopt_long and getopt_long_only entry points for GNU getopt.
   Copyright (C) 1987,88,89,90,91,92,93,94,96,97,98,2004,2006
     Free Software Foundation, Inc.
   This file is part of the GNU C Library.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License along
   with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

#ifdef _LIBC
# include <getopt.h>
#else
# include <config.h>
# include "getopt.h"
#endif
#include "getopt_int.h"

#include <stdio.h>

/* This needs to come after some library #include
   to get __GNU_LIBRARY__ defined.  */
#ifdef __GNU_LIBRARY__
#include <stdlib.h>
#endif

#ifndef	NULL
#define NULL 0
#endif

int
getopt_long (int argc, char *__getopt_argv_const *argv, const char *options,
	     const struct option *long_options, int *opt_index)
{
  return _getopt_internal (argc, (char **) argv, options, long_options,
			   opt_index, 0, 0);
}

int
_getopt_long_r (int argc, char **argv, const char *options,
		const struct option *long_options, int *opt_index,
		struct _getopt_data *d)
{
  return _getopt_internal_r (argc, argv, options, long_options, opt_index,
			     0, 0, d);
}

/* Like getopt_long, but '-' as well as '--' can indicate a long option.
   If an option that starts with '-' (not '--') doesn't match a long option,
   but does match a short option, it is parsed as a short option
   instead.  */

int
getopt_long_only (int argc, char *__getopt_argv_const *argv,
		  const char *options,
		  const struct option *long_options, int *opt_index)
{
  return _getopt_internal (argc, (char **) argv, options, long_options,
			   opt_index, 1, 0);
}

int
_getopt_long_only_r (int argc, char **argv, const char *options,
		     const struct option *long_options, int *opt_index,
		     struct _getopt_data *d)
{
  return _getopt_internal_r (argc, argv, options, long_options, opt_index,
			     1, 0, d);
}


#ifdef TEST

#include <stdio.h>

int
main (int argc, char **argv)
{
  int c;
  int digit_optind = 0;

  while (1)
    {
      int this_option_optind = optind ? optind : 1;
      int option_index = 0;
      static struct option long_options[] =
      {
	{"add", 1, 0, 0},
	{"append", 0, 0, 0},
	{"delete", 1, 0, 0},
	{"verbose", 0, 0, 0},
	{"create", 0, 0, 0},
	{"file", 1, 0, 0},
	{0, 0, 0, 0}
      };

      c = getopt_long (argc, argv, "abc:d:0123456789",
		       long_options, &option_index);
      if (c == -1)
	break;

      switch (c)
	{
	case 0:
	  printf ("option %s", long_options[option_index].name);
	  if (optarg)
	    printf (" with arg %s", optarg);
	  printf ("\n");
	  break;

	case '0':
	case '1':
	case '2':
	case '3':
	case '4':
	case '5':
	case '6':
	case '7':
	case '8':
	case '9':
	  if (digit_optind != 0 && digit_optind != this_option_optind)
	    printf ("digits occur in two different argv-elements.\n");
	  digit_optind = this_option_optind;
	  printf ("option %c\n", c);
	  break;

	case 'a':
	  printf ("option a\n");
	  break;

	case 'b':
	  printf ("option b\n");
	  break;

	case 'c':
	  printf ("option c with value `%s'\n", optarg);
	  break;

	case 'd':
	  printf ("option d with value `%s'\n", optarg);
	  break;

	case '?':
	  break;

	default:
	  printf ("?? getopt returned character code 0%o ??\n", c);
	}
    }

  if (optind < argc)
    {
      printf ("non-option ARGV-elements: ");
      while (optind < argc)
	printf ("%s ", argv[optind++]);
      printf ("\n");
    }

  exit (0);
}

#endif /* TEST */

--- NEW FILE: regex_internal.h ---
/* Extended regular expression matching and search library.
   Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
   This file is part of the GNU C Library.
   Contributed by Isamu Hasegawa <isamu at yamato.ibm.com>.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License along
   with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */

#ifndef _REGEX_INTERNAL_H
#define _REGEX_INTERNAL_H 1

#include <assert.h>
#include <ctype.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#ifndef _LIBC
# include "strcase.h"
#endif

#if defined HAVE_LANGINFO_H || defined HAVE_LANGINFO_CODESET || defined _LIBC
# include <langinfo.h>
#endif
#if defined HAVE_LOCALE_H || defined _LIBC
# include <locale.h>
#endif

#include <wchar.h>
#include <wctype.h>
#include <stdint.h>
#if defined _LIBC
# include <bits/libc-lock.h>
#else
# define __libc_lock_init(NAME) do { } while (0)
# define __libc_lock_lock(NAME) do { } while (0)
# define __libc_lock_unlock(NAME) do { } while (0)
#endif

/* In case that the system doesn't have isblank().  */
#if !defined _LIBC && !HAVE_DECL_ISBLANK && !defined isblank
# define isblank(ch) ((ch) == ' ' || (ch) == '\t')
#endif

#ifdef _LIBC
# ifndef _RE_DEFINE_LOCALE_FUNCTIONS
#  define _RE_DEFINE_LOCALE_FUNCTIONS 1
#   include <locale/localeinfo.h>
#   include <locale/elem-hash.h>
#   include <locale/coll-lookup.h>
# endif
#endif

/* This is for other GNU distributions with internationalized messages.  */
#if (HAVE_LIBINTL_H && ENABLE_NLS) || defined _LIBC
# include <libintl.h>
# ifdef _LIBC
#  undef gettext
#  define gettext(msgid) \
  INTUSE(__dcgettext) (_libc_intl_domainname, msgid, LC_MESSAGES)
# endif
#else
# define gettext(msgid) (msgid)
#endif

#ifndef gettext_noop
/* This define is so xgettext can find the internationalizable
   strings.  */
# define gettext_noop(String) String
#endif

/* For loser systems without the definition.  */
#ifndef SIZE_MAX
# define SIZE_MAX ((size_t) -1)
#endif

#if (defined MB_CUR_MAX && HAVE_LOCALE_H && HAVE_WCTYPE_H && HAVE_ISWCTYPE && HAVE_WCRTOMB && HAVE_MBRTOWC && HAVE_WCSCOLL) || _LIBC
# define RE_ENABLE_I18N
#endif

#if __GNUC__ >= 3
# define BE(expr, val) __builtin_expect (expr, val)
#else
# define BE(expr, val) (expr)
# ifdef _LIBC
#  define inline
# endif
#endif

/* Number of ASCII characters.  */
#define ASCII_CHARS 0x80

/* Number of single byte characters.  */
#define SBC_MAX (UCHAR_MAX + 1)

#define COLL_ELEM_LEN_MAX 8

/* The character which represents newline.  */
#define NEWLINE_CHAR '\n'
#define WIDE_NEWLINE_CHAR L'\n'

/* Rename to standard API for using out of glibc.  */
#ifndef _LIBC
# define __wctype wctype
# define __iswctype iswctype
# define __btowc btowc
# ifndef __mempcpy
#  define __mempcpy mempcpy
# endif
# define __wcrtomb wcrtomb
# define __regfree regfree
# define attribute_hidden
#endif /* not _LIBC */

#if __GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)
# define __attribute(arg) __attribute__ (arg)
#else
# define __attribute(arg)
#endif

typedef __re_idx_t Idx;

/* Special return value for failure to match.  */
#define REG_MISSING ((Idx) -1)

/* Special return value for internal error.  */
#define REG_ERROR ((Idx) -2)

/* Test whether N is a valid index, and is not one of the above.  */
#ifdef _REGEX_LARGE_OFFSETS
# define REG_VALID_INDEX(n) ((Idx) (n) < REG_ERROR)
#else
# define REG_VALID_INDEX(n) (0 <= (n))
#endif

/* Test whether N is a valid nonzero index.  */
#ifdef _REGEX_LARGE_OFFSETS
# define REG_VALID_NONZERO_INDEX(n) ((Idx) ((n) - 1) < (Idx) (REG_ERROR - 1))
#else
# define REG_VALID_NONZERO_INDEX(n) (0 < (n))
#endif

/* A hash value, suitable for computing hash tables.  */
typedef __re_size_t re_hashval_t;

/* An integer used to represent a set of bits.  It must be unsigned,
   and must be at least as wide as unsigned int.  */
typedef unsigned long int bitset_word_t;
/* All bits set in a bitset_word_t.  */
#define BITSET_WORD_MAX ULONG_MAX

/* Number of bits in a bitset_word_t.  For portability to hosts with
   padding bits, do not use '(sizeof (bitset_word_t) * CHAR_BIT)';
   instead, deduce it directly from BITSET_WORD_MAX.  Avoid
   greater-than-32-bit integers and unconditional shifts by more than
   31 bits, as they're not portable.  */
#if BITSET_WORD_MAX == 0xffffffff
# define BITSET_WORD_BITS 32
#elif BITSET_WORD_MAX >> 31 >> 5 == 1
# define BITSET_WORD_BITS 36
#elif BITSET_WORD_MAX >> 31 >> 16 == 1
# define BITSET_WORD_BITS 48
#elif BITSET_WORD_MAX >> 31 >> 28 == 1
# define BITSET_WORD_BITS 60
#elif BITSET_WORD_MAX >> 31 >> 31 >> 1 == 1
# define BITSET_WORD_BITS 64
#elif BITSET_WORD_MAX >> 31 >> 31 >> 9 == 1
# define BITSET_WORD_BITS 72
#elif BITSET_WORD_MAX >> 31 >> 31 >> 31 >> 31 >> 3 == 1
# define BITSET_WORD_BITS 128
#elif BITSET_WORD_MAX >> 31 >> 31 >> 31 >> 31 >> 31 >> 31 >> 31 >> 31 >> 7 == 1
# define BITSET_WORD_BITS 256
#elif BITSET_WORD_MAX >> 31 >> 31 >> 31 >> 31 >> 31 >> 31 >> 31 >> 31 >> 7 > 1
# define BITSET_WORD_BITS 257 /* any value > SBC_MAX will do here */
# if BITSET_WORD_BITS <= SBC_MAX
#  error "Invalid SBC_MAX"
# endif
#elif BITSET_WORD_MAX == (0xffffffff + 2) * 0xffffffff
/* Work around a bug in 64-bit PGC (before version 6.1-2), where the
   preprocessor mishandles large unsigned values as if they were signed.  */
# define BITSET_WORD_BITS 64
#else
# error "Add case for new bitset_word_t size"
#endif

/* Number of bitset_word_t values in a bitset_t.  */
#define BITSET_WORDS ((SBC_MAX + BITSET_WORD_BITS - 1) / BITSET_WORD_BITS)

typedef bitset_word_t bitset_t[BITSET_WORDS];
typedef bitset_word_t *re_bitset_ptr_t;
typedef const bitset_word_t *re_const_bitset_ptr_t;

#define PREV_WORD_CONSTRAINT 0x0001
#define PREV_NOTWORD_CONSTRAINT 0x0002
#define NEXT_WORD_CONSTRAINT 0x0004
#define NEXT_NOTWORD_CONSTRAINT 0x0008
#define PREV_NEWLINE_CONSTRAINT 0x0010
#define NEXT_NEWLINE_CONSTRAINT 0x0020
#define PREV_BEGBUF_CONSTRAINT 0x0040
#define NEXT_ENDBUF_CONSTRAINT 0x0080
#define WORD_DELIM_CONSTRAINT 0x0100
#define NOT_WORD_DELIM_CONSTRAINT 0x0200

typedef enum
{
  INSIDE_WORD = PREV_WORD_CONSTRAINT | NEXT_WORD_CONSTRAINT,
  WORD_FIRST = PREV_NOTWORD_CONSTRAINT | NEXT_WORD_CONSTRAINT,
  WORD_LAST = PREV_WORD_CONSTRAINT | NEXT_NOTWORD_CONSTRAINT,
  INSIDE_NOTWORD = PREV_NOTWORD_CONSTRAINT | NEXT_NOTWORD_CONSTRAINT,
  LINE_FIRST = PREV_NEWLINE_CONSTRAINT,
  LINE_LAST = NEXT_NEWLINE_CONSTRAINT,
  BUF_FIRST = PREV_BEGBUF_CONSTRAINT,
  BUF_LAST = NEXT_ENDBUF_CONSTRAINT,
  WORD_DELIM = WORD_DELIM_CONSTRAINT,
  NOT_WORD_DELIM = NOT_WORD_DELIM_CONSTRAINT
} re_context_type;

typedef struct
{
  Idx alloc;
  Idx nelem;
  Idx *elems;
} re_node_set;

typedef enum
{
  NON_TYPE = 0,

  /* Node type, These are used by token, node, tree.  */
  CHARACTER = 1,
  END_OF_RE = 2,
  SIMPLE_BRACKET = 3,
  OP_BACK_REF = 4,
  OP_PERIOD = 5,
#ifdef RE_ENABLE_I18N
  COMPLEX_BRACKET = 6,
  OP_UTF8_PERIOD = 7,
#endif /* RE_ENABLE_I18N */

  /* We define EPSILON_BIT as a macro so that OP_OPEN_SUBEXP is used
     when the debugger shows values of this enum type.  */
#define EPSILON_BIT 8
  OP_OPEN_SUBEXP = EPSILON_BIT | 0,
  OP_CLOSE_SUBEXP = EPSILON_BIT | 1,
  OP_ALT = EPSILON_BIT | 2,
  OP_DUP_ASTERISK = EPSILON_BIT | 3,
  ANCHOR = EPSILON_BIT | 4,

  /* Tree type, these are used only by tree. */
  CONCAT = 16,
  SUBEXP = 17,

  /* Token type, these are used only by token.  */
  OP_DUP_PLUS = 18,
  OP_DUP_QUESTION,
  OP_OPEN_BRACKET,
  OP_CLOSE_BRACKET,
  OP_CHARSET_RANGE,
  OP_OPEN_DUP_NUM,
  OP_CLOSE_DUP_NUM,
  OP_NON_MATCH_LIST,
  OP_OPEN_COLL_ELEM,
  OP_CLOSE_COLL_ELEM,
  OP_OPEN_EQUIV_CLASS,
  OP_CLOSE_EQUIV_CLASS,
  OP_OPEN_CHAR_CLASS,
  OP_CLOSE_CHAR_CLASS,
  OP_WORD,
  OP_NOTWORD,
  OP_SPACE,
  OP_NOTSPACE,
  BACK_SLASH

} re_token_type_t;

#ifdef RE_ENABLE_I18N
typedef struct
{
  /* Multibyte characters.  */
  wchar_t *mbchars;

  /* Collating symbols.  */
# ifdef _LIBC
  int32_t *coll_syms;
# endif

  /* Equivalence classes. */
# ifdef _LIBC
  int32_t *equiv_classes;
# endif

  /* Range expressions. */
# ifdef _LIBC
  uint32_t *range_starts;
  uint32_t *range_ends;
# else /* not _LIBC */
  wchar_t *range_starts;
  wchar_t *range_ends;
# endif /* not _LIBC */

  /* Character classes. */
  wctype_t *char_classes;

  /* If this character set is the non-matching list.  */
  unsigned int non_match : 1;

  /* # of multibyte characters.  */
  Idx nmbchars;

  /* # of collating symbols.  */
  Idx ncoll_syms;

  /* # of equivalence classes. */
  Idx nequiv_classes;

  /* # of range expressions. */
  Idx nranges;

  /* # of character classes. */
  Idx nchar_classes;
} re_charset_t;
#endif /* RE_ENABLE_I18N */

typedef struct
{
  union
  {
    unsigned char c;		/* for CHARACTER */
    re_bitset_ptr_t sbcset;	/* for SIMPLE_BRACKET */
#ifdef RE_ENABLE_I18N
    re_charset_t *mbcset;	/* for COMPLEX_BRACKET */
#endif /* RE_ENABLE_I18N */
    Idx idx;			/* for BACK_REF */
    re_context_type ctx_type;	/* for ANCHOR */
  } opr;
#if __GNUC__ >= 2 && !__STRICT_ANSI__
  re_token_type_t type : 8;
#else
  re_token_type_t type;
#endif
  unsigned int constraint : 10;	/* context constraint */
  unsigned int duplicated : 1;
  unsigned int opt_subexp : 1;
#ifdef RE_ENABLE_I18N
  unsigned int accept_mb : 1;
  /* These 2 bits can be moved into the union if needed (e.g. if running out
     of bits; move opr.c to opr.c.c and move the flags to opr.c.flags).  */
  unsigned int mb_partial : 1;
#endif
  unsigned int word_char : 1;
} re_token_t;

#define IS_EPSILON_NODE(type) ((type) & EPSILON_BIT)

struct re_string_t
{
  /* Indicate the raw buffer which is the original string passed as an
     argument of regexec(), re_search(), etc..  */
  const unsigned char *raw_mbs;
  /* Store the multibyte string.  In case of "case insensitive mode" like
     REG_ICASE, upper cases of the string are stored, otherwise MBS points
     the same address that RAW_MBS points.  */
  unsigned char *mbs;
#ifdef RE_ENABLE_I18N
  /* Store the wide character string which is corresponding to MBS.  */
  wint_t *wcs;
  Idx *offsets;
  mbstate_t cur_state;
#endif
  /* Index in RAW_MBS.  Each character mbs[i] corresponds to
     raw_mbs[raw_mbs_idx + i].  */
  Idx raw_mbs_idx;
  /* The length of the valid characters in the buffers.  */
  Idx valid_len;
  /* The corresponding number of bytes in raw_mbs array.  */
  Idx valid_raw_len;
  /* The length of the buffers MBS and WCS.  */
  Idx bufs_len;
  /* The index in MBS, which is updated by re_string_fetch_byte.  */
  Idx cur_idx;
  /* length of RAW_MBS array.  */
  Idx raw_len;
  /* This is RAW_LEN - RAW_MBS_IDX + VALID_LEN - VALID_RAW_LEN.  */
  Idx len;
  /* End of the buffer may be shorter than its length in the cases such
     as re_match_2, re_search_2.  Then, we use STOP for end of the buffer
     instead of LEN.  */
  Idx raw_stop;
  /* This is RAW_STOP - RAW_MBS_IDX adjusted through OFFSETS.  */
  Idx stop;

  /* The context of mbs[0].  We store the context independently, since
     the context of mbs[0] may be different from raw_mbs[0], which is
     the beginning of the input string.  */
  unsigned int tip_context;
  /* The translation passed as a part of an argument of re_compile_pattern.  */
  RE_TRANSLATE_TYPE trans;
  /* Copy of re_dfa_t's word_char.  */
  re_const_bitset_ptr_t word_char;
  /* true if REG_ICASE.  */
  unsigned char icase;
  unsigned char is_utf8;
  unsigned char map_notascii;
  unsigned char mbs_allocated;
  unsigned char offsets_needed;
  unsigned char newline_anchor;
  unsigned char word_ops_used;
  int mb_cur_max;
};
typedef struct re_string_t re_string_t;


struct re_dfa_t;
typedef struct re_dfa_t re_dfa_t;

#ifndef _LIBC
# ifdef __i386__
#  define internal_function   __attribute ((regparm (3), stdcall))
# else
#  define internal_function
# endif
#endif

static reg_errcode_t re_string_realloc_buffers (re_string_t *pstr,
						Idx new_buf_len)
     internal_function;
#ifdef RE_ENABLE_I18N
static void build_wcs_buffer (re_string_t *pstr) internal_function;
static reg_errcode_t build_wcs_upper_buffer (re_string_t *pstr)
     internal_function;
#endif /* RE_ENABLE_I18N */
static void build_upper_buffer (re_string_t *pstr) internal_function;
static void re_string_translate_buffer (re_string_t *pstr) internal_function;
static unsigned int re_string_context_at (const re_string_t *input, Idx idx,
					  int eflags)
     internal_function __attribute ((pure));
#define re_string_peek_byte(pstr, offset) \
  ((pstr)->mbs[(pstr)->cur_idx + offset])
#define re_string_fetch_byte(pstr) \
  ((pstr)->mbs[(pstr)->cur_idx++])
#define re_string_first_byte(pstr, idx) \
  ((idx) == (pstr)->valid_len || (pstr)->wcs[idx] != WEOF)
#define re_string_is_single_byte_char(pstr, idx) \
  ((pstr)->wcs[idx] != WEOF && ((pstr)->valid_len == (idx) + 1 \
				|| (pstr)->wcs[(idx) + 1] != WEOF))
#define re_string_eoi(pstr) ((pstr)->stop <= (pstr)->cur_idx)
#define re_string_cur_idx(pstr) ((pstr)->cur_idx)
#define re_string_get_buffer(pstr) ((pstr)->mbs)
#define re_string_length(pstr) ((pstr)->len)
#define re_string_byte_at(pstr,idx) ((pstr)->mbs[idx])
#define re_string_skip_bytes(pstr,idx) ((pstr)->cur_idx += (idx))
#define re_string_set_index(pstr,idx) ((pstr)->cur_idx = (idx))

#include <alloca.h>

#ifndef _LIBC
# if HAVE_ALLOCA
/* The OS usually guarantees only one guard page at the bottom of the stack,
   and a page size can be as small as 4096 bytes.  So we cannot safely
   allocate anything larger than 4096 bytes.  Also care for the possibility
   of a few compiler-allocated temporary stack slots.  */
#  define __libc_use_alloca(n) ((n) < 4032)
# else
/* alloca is implemented with malloc, so just use malloc.  */
#  define __libc_use_alloca(n) 0
# endif
#endif

#ifndef MAX
# define MAX(a,b) ((a) < (b) ? (b) : (a))
#endif

#define re_malloc(t,n) ((t *) malloc ((n) * sizeof (t)))
#define re_realloc(p,t,n) ((t *) realloc (p, (n) * sizeof (t)))
#define re_free(p) free (p)

struct bin_tree_t
{
  struct bin_tree_t *parent;
  struct bin_tree_t *left;
  struct bin_tree_t *right;
  struct bin_tree_t *first;
  struct bin_tree_t *next;

  re_token_t token;

  /* `node_idx' is the index in dfa->nodes, if `type' == 0.
     Otherwise `type' indicate the type of this node.  */
  Idx node_idx;
};
typedef struct bin_tree_t bin_tree_t;

#define BIN_TREE_STORAGE_SIZE \
  ((1024 - sizeof (void *)) / sizeof (bin_tree_t))

struct bin_tree_storage_t
{
  struct bin_tree_storage_t *next;
  bin_tree_t data[BIN_TREE_STORAGE_SIZE];
};
typedef struct bin_tree_storage_t bin_tree_storage_t;

#define CONTEXT_WORD 1
#define CONTEXT_NEWLINE (CONTEXT_WORD << 1)
#define CONTEXT_BEGBUF (CONTEXT_NEWLINE << 1)
#define CONTEXT_ENDBUF (CONTEXT_BEGBUF << 1)

#define IS_WORD_CONTEXT(c) ((c) & CONTEXT_WORD)
#define IS_NEWLINE_CONTEXT(c) ((c) & CONTEXT_NEWLINE)
#define IS_BEGBUF_CONTEXT(c) ((c) & CONTEXT_BEGBUF)
#define IS_ENDBUF_CONTEXT(c) ((c) & CONTEXT_ENDBUF)
#define IS_ORDINARY_CONTEXT(c) ((c) == 0)

#define IS_WORD_CHAR(ch) (isalnum (ch) || (ch) == '_')
#define IS_NEWLINE(ch) ((ch) == NEWLINE_CHAR)
#define IS_WIDE_WORD_CHAR(ch) (iswalnum (ch) || (ch) == L'_')
#define IS_WIDE_NEWLINE(ch) ((ch) == WIDE_NEWLINE_CHAR)

#define NOT_SATISFY_PREV_CONSTRAINT(constraint,context) \
 ((((constraint) & PREV_WORD_CONSTRAINT) && !IS_WORD_CONTEXT (context)) \
  || ((constraint & PREV_NOTWORD_CONSTRAINT) && IS_WORD_CONTEXT (context)) \
  || ((constraint & PREV_NEWLINE_CONSTRAINT) && !IS_NEWLINE_CONTEXT (context))\
  || ((constraint & PREV_BEGBUF_CONSTRAINT) && !IS_BEGBUF_CONTEXT (context)))

#define NOT_SATISFY_NEXT_CONSTRAINT(constraint,context) \
 ((((constraint) & NEXT_WORD_CONSTRAINT) && !IS_WORD_CONTEXT (context)) \
  || (((constraint) & NEXT_NOTWORD_CONSTRAINT) && IS_WORD_CONTEXT (context)) \
  || (((constraint) & NEXT_NEWLINE_CONSTRAINT) && !IS_NEWLINE_CONTEXT (context)) \
  || (((constraint) & NEXT_ENDBUF_CONSTRAINT) && !IS_ENDBUF_CONTEXT (context)))

struct re_dfastate_t
{
  re_hashval_t hash;
  re_node_set nodes;
  re_node_set non_eps_nodes;
  re_node_set inveclosure;
  re_node_set *entrance_nodes;
  struct re_dfastate_t **trtable, **word_trtable;
  unsigned int context : 4;
  unsigned int halt : 1;
  /* If this state can accept `multi byte'.
     Note that we refer to multibyte characters, and multi character
     collating elements as `multi byte'.  */
  unsigned int accept_mb : 1;
  /* If this state has backreference node(s).  */
  unsigned int has_backref : 1;
  unsigned int has_constraint : 1;
};
typedef struct re_dfastate_t re_dfastate_t;

struct re_state_table_entry
{
  Idx num;
  Idx alloc;
  re_dfastate_t **array;
};

/* Array type used in re_sub_match_last_t and re_sub_match_top_t.  */

typedef struct
{
  Idx next_idx;
  Idx alloc;
  re_dfastate_t **array;
} state_array_t;

/* Store information about the node NODE whose type is OP_CLOSE_SUBEXP.  */

typedef struct
{
  Idx node;
  Idx str_idx; /* The position NODE match at.  */
  state_array_t path;
} re_sub_match_last_t;

/* Store information about the node NODE whose type is OP_OPEN_SUBEXP.
   And information about the node, whose type is OP_CLOSE_SUBEXP,
   corresponding to NODE is stored in LASTS.  */

typedef struct
{
  Idx str_idx;
  Idx node;
  state_array_t *path;
  Idx alasts; /* Allocation size of LASTS.  */
  Idx nlasts; /* The number of LASTS.  */
  re_sub_match_last_t **lasts;
} re_sub_match_top_t;

struct re_backref_cache_entry
{
  Idx node;
  Idx str_idx;
  Idx subexp_from;
  Idx subexp_to;
  char more;
  char unused;
  unsigned short int eps_reachable_subexps_map;
};

typedef struct
{
  /* The string object corresponding to the input string.  */
  re_string_t input;
#if defined _LIBC || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L)
  const re_dfa_t *const dfa;
#else
  const re_dfa_t *dfa;
#endif
  /* EFLAGS of the argument of regexec.  */
  int eflags;
  /* Where the matching ends.  */
  Idx match_last;
  Idx last_node;
  /* The state log used by the matcher.  */
  re_dfastate_t **state_log;
  Idx state_log_top;
  /* Back reference cache.  */
  Idx nbkref_ents;
  Idx abkref_ents;
  struct re_backref_cache_entry *bkref_ents;
  int max_mb_elem_len;
  Idx nsub_tops;
  Idx asub_tops;
  re_sub_match_top_t **sub_tops;
} re_match_context_t;

typedef struct
{
  re_dfastate_t **sifted_states;
  re_dfastate_t **limited_states;
  Idx last_node;
  Idx last_str_idx;
  re_node_set limits;
} re_sift_context_t;

struct re_fail_stack_ent_t
{
  Idx idx;
  Idx node;
  regmatch_t *regs;
  re_node_set eps_via_nodes;
};

struct re_fail_stack_t
{
  Idx num;
  Idx alloc;
  struct re_fail_stack_ent_t *stack;
};

struct re_dfa_t
{
  re_token_t *nodes;
  size_t nodes_alloc;
  size_t nodes_len;
  Idx *nexts;
  Idx *org_indices;
  re_node_set *edests;
  re_node_set *eclosures;
  re_node_set *inveclosures;
  struct re_state_table_entry *state_table;
  re_dfastate_t *init_state;
  re_dfastate_t *init_state_word;
  re_dfastate_t *init_state_nl;
  re_dfastate_t *init_state_begbuf;
  bin_tree_t *str_tree;
  bin_tree_storage_t *str_tree_storage;
  re_bitset_ptr_t sb_char;
  int str_tree_storage_idx;

  /* number of subexpressions `re_nsub' is in regex_t.  */
  re_hashval_t state_hash_mask;
  Idx init_node;
  Idx nbackref; /* The number of backreference in this dfa.  */

  /* Bitmap expressing which backreference is used.  */
  bitset_word_t used_bkref_map;
  bitset_word_t completed_bkref_map;

  unsigned int has_plural_match : 1;
  /* If this dfa has "multibyte node", which is a backreference or
     a node which can accept multibyte character or multi character
     collating element.  */
  unsigned int has_mb_node : 1;
  unsigned int is_utf8 : 1;
  unsigned int map_notascii : 1;
  unsigned int word_ops_used : 1;
  int mb_cur_max;
  bitset_t word_char;
  reg_syntax_t syntax;
  Idx *subexp_map;
#ifdef DEBUG
  char* re_str;
#endif
#ifdef _LIBC
  __libc_lock_define (, lock)
#endif
};

#define re_node_set_init_empty(set) memset (set, '\0', sizeof (re_node_set))
#define re_node_set_remove(set,id) \
  (re_node_set_remove_at (set, re_node_set_contains (set, id) - 1))
#define re_node_set_empty(p) ((p)->nelem = 0)
#define re_node_set_free(set) re_free ((set)->elems)


typedef enum
{
  SB_CHAR,
  MB_CHAR,
  EQUIV_CLASS,
  COLL_SYM,
  CHAR_CLASS
} bracket_elem_type;

typedef struct
{
  bracket_elem_type type;
  union
  {
    unsigned char ch;
    unsigned char *name;
    wchar_t wch;
  } opr;
} bracket_elem_t;


/* Inline functions for bitset_t operation.  */

static inline void
bitset_set (bitset_t set, Idx i)
{
  set[i / BITSET_WORD_BITS] |= (bitset_word_t) 1 << i % BITSET_WORD_BITS;
}

static inline void
bitset_clear (bitset_t set, Idx i)
{
  set[i / BITSET_WORD_BITS] &= ~ ((bitset_word_t) 1 << i % BITSET_WORD_BITS);
}

static inline bool
bitset_contain (const bitset_t set, Idx i)
{
  return (set[i / BITSET_WORD_BITS] >> i % BITSET_WORD_BITS) & 1;
}

static inline void
bitset_empty (bitset_t set)
{
  memset (set, '\0', sizeof (bitset_t));
}

static inline void
bitset_set_all (bitset_t set)
{
  memset (set, -1, sizeof (bitset_word_t) * (SBC_MAX / BITSET_WORD_BITS));
  if (SBC_MAX % BITSET_WORD_BITS != 0)
    set[BITSET_WORDS - 1] =
      ((bitset_word_t) 1 << SBC_MAX % BITSET_WORD_BITS) - 1;
}

static inline void
bitset_copy (bitset_t dest, const bitset_t src)
{
  memcpy (dest, src, sizeof (bitset_t));
}

static inline void
bitset_not (bitset_t set)
{
  int bitset_i;
  for (bitset_i = 0; bitset_i < SBC_MAX / BITSET_WORD_BITS; ++bitset_i)
    set[bitset_i] = ~set[bitset_i];
  if (SBC_MAX % BITSET_WORD_BITS != 0)
    set[BITSET_WORDS - 1] =
      ((((bitset_word_t) 1 << SBC_MAX % BITSET_WORD_BITS) - 1)
       & ~set[BITSET_WORDS - 1]);
}

static inline void
bitset_merge (bitset_t dest, const bitset_t src)
{
  int bitset_i;
  for (bitset_i = 0; bitset_i < BITSET_WORDS; ++bitset_i)
    dest[bitset_i] |= src[bitset_i];
}

static inline void
bitset_mask (bitset_t dest, const bitset_t src)
{
  int bitset_i;
  for (bitset_i = 0; bitset_i < BITSET_WORDS; ++bitset_i)
    dest[bitset_i] &= src[bitset_i];
}

#ifdef RE_ENABLE_I18N
/* Inline functions for re_string.  */
static inline int
internal_function __attribute ((pure))
re_string_char_size_at (const re_string_t *pstr, Idx idx)
{
  int byte_idx;
  if (pstr->mb_cur_max == 1)
    return 1;
  for (byte_idx = 1; idx + byte_idx < pstr->valid_len; ++byte_idx)
    if (pstr->wcs[idx + byte_idx] != WEOF)
      break;
  return byte_idx;
}

static inline wint_t
internal_function __attribute ((pure))
re_string_wchar_at (const re_string_t *pstr, Idx idx)
{
  if (pstr->mb_cur_max == 1)
    return (wint_t) pstr->mbs[idx];
  return (wint_t) pstr->wcs[idx];
}

static int
internal_function __attribute ((pure))
re_string_elem_size_at (const re_string_t *pstr, Idx idx)
{
# ifdef _LIBC
  const unsigned char *p, *extra;
  const int32_t *table, *indirect;
  int32_t tmp;
#  include <locale/weight.h>
  uint_fast32_t nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);

  if (nrules != 0)
    {
      table = (const int32_t *) _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB);
      extra = (const unsigned char *)
	_NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAMB);
      indirect = (const int32_t *) _NL_CURRENT (LC_COLLATE,
						_NL_COLLATE_INDIRECTMB);
      p = pstr->mbs + idx;
      tmp = findidx (&p);
      return p - pstr->mbs - idx;
    }
  else
# endif /* _LIBC */
    return 1;
}
#endif /* RE_ENABLE_I18N */

#endif /*  _REGEX_INTERNAL_H */

--- NEW FILE: strncasecmp.c ---
/* strncasecmp.c -- case insensitive string comparator
   Copyright (C) 1998-1999, 2005-2006 Free Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

#include <config.h>

/* Specification.  */
#include "strcase.h"

#include <ctype.h>
#include <limits.h>

#define TOLOWER(Ch) (isupper (Ch) ? tolower (Ch) : (Ch))

/* Compare no more than N bytes of strings S1 and S2,
   ignoring case, returning less than, equal to or
   greater than zero if S1 is lexicographically less
   than, equal to or greater than S2.  */

int
strncasecmp (const char *s1, const char *s2, size_t n)
{
  register const unsigned char *p1 = (const unsigned char *) s1;
  register const unsigned char *p2 = (const unsigned char *) s2;
  unsigned char c1, c2;

  if (p1 == p2 || n == 0)
    return 0;

  do
    {
      c1 = TOLOWER (*p1);
      c2 = TOLOWER (*p2);

      if (--n == 0 || c1 == '\0')
	break;

      ++p1;
      ++p2;
    }
  while (c1 == c2);

  if (UCHAR_MAX <= INT_MAX)
    return c1 - c2;
  else
    /* On machines where 'char' and 'int' are types of the same size, the
       difference of two 'unsigned char' values - including the sign bit -
       doesn't fit in an 'int'.  */
    return (c1 > c2 ? 1 : c1 < c2 ? -1 : 0);
}

--- NEW FILE: full-read.h ---
/* An interface to read() that reads all it is asked to read.

   Copyright (C) 2002 Free Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, read to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

#include <stddef.h>

/* Read COUNT bytes at BUF to descriptor FD, retrying if interrupted
   or if partial reads occur.  Return the number of bytes successfully
   read, setting errno if that is less than COUNT.  errno = 0 means EOF.  */
extern size_t full_read (int fd, void *buf, size_t count);

--- NEW FILE: stdbool_.h ---
/* Copyright (C) 2001, 2002, 2003, 2006 Free Software Foundation, Inc.
   Written by Bruno Haible <haible at clisp.cons.org>, 2001.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

#ifndef _STDBOOL_H
#define _STDBOOL_H

/* ISO C 99 <stdbool.h> for platforms that lack it.  */

/* Usage suggestions:

   Programs that use <stdbool.h> should be aware of some limitations
   and standards compliance issues.

   Standards compliance:

       - <stdbool.h> must be #included before 'bool', 'false', 'true'
         can be used.

       - You cannot assume that sizeof (bool) == 1.

       - Programs should not undefine the macros bool, true, and false,
         as C99 lists that as an "obsolescent feature".

   Limitations of this substitute, when used in a C89 environment:

       - <stdbool.h> must be #included before the '_Bool' type can be used.

       - You cannot assume that _Bool is a typedef; it might be a macro.

       - In C99, casts and automatic conversions to '_Bool' or 'bool' are
         performed in such a way that every nonzero value gets converted
         to 'true', and zero gets converted to 'false'.  This doesn't work
         with this substitute.  With this substitute, only the values 0 and 1
         give the expected result when converted to _Bool' or 'bool'.

   Also, it is suggested that programs use 'bool' rather than '_Bool';
   this isn't required, but 'bool' is more common.  */


/* 7.16. Boolean type and values */

/* BeOS <sys/socket.h> already #defines false 0, true 1.  We use the same
   definitions below, but temporarily we have to #undef them.  */
#ifdef __BEOS__
# include <OS.h> /* defines bool but not _Bool */
# undef false
# undef true
#endif

/* For the sake of symbolic names in gdb, we define true and false as
   enum constants, not only as macros.
   It is tempting to write
      typedef enum { false = 0, true = 1 } _Bool;
   so that gdb prints values of type 'bool' symbolically. But if we do
   this, values of type '_Bool' may promote to 'int' or 'unsigned int'
   (see ISO C 99 6.7.2.2.(4)); however, '_Bool' must promote to 'int'
   (see ISO C 99 6.3.1.1.(2)).  So we add a negative value to the
   enum; this ensures that '_Bool' promotes to 'int'.  */
#if defined __cplusplus || defined __BEOS__
  /* A compiler known to have 'bool'.  */
  /* If the compiler already has both 'bool' and '_Bool', we can assume they
     are the same types.  */
# if !@HAVE__BOOL@
typedef bool _Bool;
# endif
#else
# if !defined __GNUC__
   /* If @HAVE__BOOL@:
        Some HP-UX cc and AIX IBM C compiler versions have compiler bugs when
        the built-in _Bool type is used.  See
          http://gcc.gnu.org/ml/gcc-patches/2003-12/msg02303.html
          http://lists.gnu.org/archive/html/bug-coreutils/2005-11/msg00161.html
          http://lists.gnu.org/archive/html/bug-coreutils/2005-10/msg00086.html
        Similar bugs are likely with other compilers as well; this file
        wouldn't be used if <stdbool.h> was working.
        So we override the _Bool type.
      If !@HAVE__BOOL@:
        Need to define _Bool ourselves. As 'signed char' or as an enum type?
        Use of a typedef, with SunPRO C, leads to a stupid
          "warning: _Bool is a keyword in ISO C99".
        Use of an enum type, with IRIX cc, leads to a stupid
          "warning(1185): enumerated type mixed with another type".
        The only benefit of the enum type, debuggability, is not important
        with these compilers.  So use 'signed char' and no typedef.  */
#  define _Bool signed char
enum { false = 0, true = 1 };
# else
   /* With this compiler, trust the _Bool type if the compiler has it.  */
#  if !@HAVE__BOOL@
typedef enum { _Bool_must_promote_to_int = -1, false = 0, true = 1 } _Bool;
#  endif
# endif
#endif
#define bool _Bool

/* The other macros must be usable in preprocessor directives.  */
#define false 0
#define true 1
#define __bool_true_false_are_defined 1

#endif /* _STDBOOL_H */

--- NEW FILE: full-read.c ---
/* An interface to read that retries after partial reads and interrupts.
   Copyright (C) 2002, 2003 Free Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

#define FULL_READ
#include "full-write.c"

--- NEW FILE: malloc.c ---
/* malloc() function that is glibc compatible.

   Copyright (C) 1997, 1998, 2006 Free Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

/* written by Jim Meyering */

#include <config.h>
#undef malloc

#include <stdlib.h>

/* Allocate an N-byte block of memory from the heap.
   If N is zero, allocate a 1-byte block.  */

void *
rpl_malloc (size_t n)
{
  if (n == 0)
    n = 1;
  return malloc (n);
}

--- NEW FILE: stripslash.c ---
/* stripslash.c -- remove redundant trailing slashes from a file name

   Copyright (C) 1990, 2001, 2003-2006 Free Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

#include <config.h>

#include "dirname.h"

/* Remove trailing slashes from FILE.  Return true if a trailing slash
   was removed.  This is useful when using file name completion from a
   shell that adds a "/" after directory names (such as tcsh and
   bash), because on symlinks to directories, several system calls
   have different semantics according to whether a trailing slash is
   present.  */

bool
strip_trailing_slashes (char *file)
{
  char *base = last_component (file);
  char *base_lim;
  bool had_slash;

  /* last_component returns "" for file system roots, but we need to turn
     `///' into `/'.  */
  if (! *base)
    base = file;
  base_lim = base + base_len (base);
  had_slash = (*base_lim != '\0');
  *base_lim = '\0';
  return had_slash;
}

--- NEW FILE: exit.h ---
/* exit() function.
   Copyright (C) 1995, 2001 Free Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

#ifndef _EXIT_H
#define _EXIT_H

/* Get exit() declaration.  */
#include <stdlib.h>

/* Some systems do not define EXIT_*, despite otherwise supporting C89.  */
#ifndef EXIT_SUCCESS
# define EXIT_SUCCESS 0
#endif
#ifndef EXIT_FAILURE
# define EXIT_FAILURE 1
#endif

#endif /* _EXIT_H */

--- NEW FILE: inet_ntop.h ---
/* Convert internet address from internal to printable, presentable format.
   Copyright (C) 2005, 2006 Free Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

/* Converts an internet address from internal format to a printable,
   presentable format.
   AF is an internet address family, such as AF_INET or AF_INET6.
   SRC points to a 'struct in_addr' (for AF_INET) or 'struct in6_addr'
   (for AF_INET6).
   DST points to a buffer having room for CNT bytes.
   The printable representation of the address (in numeric form, not
   surrounded by [...], no reverse DNS is done) is placed in DST, and
   DST is returned.  If an error occurs, the return value is NULL and
   errno is set.  If CNT bytes are not sufficient to hold the result,
   the return value is NULL and errno is set to ENOSPC.  A good value
   for CNT is 46.

   For more details, see the POSIX:2001 specification
   <http://www.opengroup.org/susv3xsh/inet_ntop.html>.  */

#if !HAVE_DECL_INET_NTOP
extern const char *inet_ntop (int af, const void *restrict src,
			      char *restrict dst, socklen_t cnt);
#endif

--- NEW FILE: cloexec.h ---
#include <stdbool.h>
int set_cloexec_flag (int desc, bool value);

--- NEW FILE: stdint_.h ---
/* Copyright (C) 2001-2002, 2004-2007 Free Software Foundation, Inc.
   Written by Paul Eggert, Bruno Haible, Sam Steingold, Peter Burwood.
   This file is part of gnulib.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

#ifndef _GL_STDINT_H
#define _GL_STDINT_H

/*
 * ISO C 99 <stdint.h> for platforms that lack it.
 * <http://www.opengroup.org/susv3xbd/stdint.h.html>
 */

/* Get those types that are already defined in other system include
   files, so that we can "#define int8_t signed char" below without
   worrying about a later system include file containing a "typedef
   signed char int8_t;" that will get messed up by our macro.  Our
   macros should all be consistent with the system versions, except
   for the "fast" types and macros, which we recommend against using
   in public interfaces due to compiler differences.  */

#if @HAVE_STDINT_H@
# if defined __sgi && ! defined __c99
   /* Bypass IRIX's <stdint.h> if in C89 mode, since it merely annoys users
      with "This header file is to be used only for c99 mode compilations"
      diagnostics.  */
#  define __STDINT_H__
# endif
  /* Other systems may have an incomplete or buggy <stdint.h>.
     Include it before <inttypes.h>, since any "#include <stdint.h>"
     in <inttypes.h> would reinclude us, skipping our contents because
     _GL_STDINT_H is defined.  */
# include @ABSOLUTE_STDINT_H@
#endif

/* <sys/types.h> defines some of the stdint.h types as well, on glibc,
   IRIX 6.5, and OpenBSD 3.8 (via <machine/types.h>).
   AIX 5.2 <sys/types.h> isn't needed and causes troubles.
   MacOS X 10.4.6 <sys/types.h> includes <stdint.h> (which is us), but
   relies on the system <stdint.h> definitions, so include
   <sys/types.h> after @ABSOLUTE_STDINT_H at .  */
#if @HAVE_SYS_TYPES_H@ && ! defined _AIX
# include <sys/types.h>
#endif

/* Get LONG_MIN, LONG_MAX, ULONG_MAX.  */
#include <limits.h>

#if @HAVE_INTTYPES_H@
  /* In OpenBSD 3.8, <inttypes.h> includes <machine/types.h>, which defines
     int{8,16,32,64}_t, uint{8,16,32,64}_t and __BIT_TYPES_DEFINED__.
     <inttypes.h> also defines intptr_t and uintptr_t.  */
# define _GL_JUST_INCLUDE_ABSOLUTE_INTTYPES_H
# include <inttypes.h>
# undef _GL_JUST_INCLUDE_ABSOLUTE_INTTYPES_H
#elif @HAVE_SYS_INTTYPES_H@
  /* Solaris 7 <sys/inttypes.h> has the types except the *_fast*_t types, and
     the macros except for *_FAST*_*, INTPTR_MIN, PTRDIFF_MIN, PTRDIFF_MAX.  */
# include <sys/inttypes.h>
#endif

#if @HAVE_SYS_BITYPES_H@ && ! defined __BIT_TYPES_DEFINED__
  /* Linux libc4 >= 4.6.7 and libc5 have a <sys/bitypes.h> that defines
     int{8,16,32,64}_t and __BIT_TYPES_DEFINED__.  In libc5 >= 5.2.2 it is
     included by <sys/types.h>.  */
# include <sys/bitypes.h>
#endif

#if ! defined __cplusplus || defined __STDC_CONSTANT_MACROS

/* Get WCHAR_MIN, WCHAR_MAX.  */
# if ! (defined WCHAR_MIN && defined WCHAR_MAX)
#  include <wchar.h>
# endif

#endif

/* Minimum and maximum values for a integer type under the usual assumption.
   Return an unspecified value if BITS == 0, adding a check to pacify
   picky compilers.  */

#define _STDINT_MIN(signed, bits, zero) \
  ((signed) ? (- ((zero) + 1) << ((bits) ? (bits) - 1 : 0)) : (zero))

#define _STDINT_MAX(signed, bits, zero) \
  ((signed) \
   ? ~ _STDINT_MIN (signed, bits, zero) \
   : ((((zero) + 1) << ((bits) ? (bits) - 1 : 0)) - 1) * 2 + 1)

/* 7.18.1.1. Exact-width integer types */

/* Here we assume a standard architecture where the hardware integer
   types have 8, 16, 32, optionally 64 bits.  */

#undef int8_t
#undef uint8_t
#define int8_t signed char
#define uint8_t unsigned char

#undef int16_t
#undef uint16_t
#define int16_t short int
#define uint16_t unsigned short int

#undef int32_t
#undef uint32_t
#define int32_t int
#define uint32_t unsigned int

#undef int64_t
#if LONG_MAX >> 31 >> 31 == 1
# define int64_t long int
#elif defined _MSC_VER
# define int64_t __int64
#elif @HAVE_LONG_LONG_INT@
# define int64_t long long int
#endif

#undef uint64_t
#if ULONG_MAX >> 31 >> 31 >> 1 == 1
# define uint64_t unsigned long int
#elif defined _MSC_VER
# define uint64_t unsigned __int64
#elif @HAVE_UNSIGNED_LONG_LONG_INT@
# define uint64_t unsigned long long int
#endif

/* Avoid collision with Solaris 2.5.1 <pthread.h> etc.  */
#define _UINT8_T
#define _UINT32_T
#define _UINT64_T


/* 7.18.1.2. Minimum-width integer types */

/* Here we assume a standard architecture where the hardware integer
   types have 8, 16, 32, optionally 64 bits. Therefore the leastN_t types
   are the same as the corresponding N_t types.  */

#undef int_least8_t
#undef uint_least8_t
#undef int_least16_t
#undef uint_least16_t
#undef int_least32_t
#undef uint_least32_t
#undef int_least64_t
#undef uint_least64_t
#define int_least8_t int8_t
#define uint_least8_t uint8_t
#define int_least16_t int16_t
#define uint_least16_t uint16_t
#define int_least32_t int32_t
#define uint_least32_t uint32_t
#ifdef int64_t
# define int_least64_t int64_t
#endif
#ifdef uint64_t
# define uint_least64_t uint64_t
#endif

/* 7.18.1.3. Fastest minimum-width integer types */

/* Note: Other <stdint.h> substitutes may define these types differently.
   It is not recommended to use these types in public header files. */

/* Here we assume a standard architecture where the hardware integer
   types have 8, 16, 32, optionally 64 bits. Therefore the fastN_t types
   are taken from the same list of types.  Assume that 'long int'
   is fast enough for all narrower integers.  */

#undef int_fast8_t
#undef uint_fast8_t
#undef int_fast16_t
#undef uint_fast16_t
#undef int_fast32_t
#undef uint_fast32_t
#undef int_fast64_t
#undef uint_fast64_t
#define int_fast8_t long int
#define uint_fast8_t unsigned int_fast8_t
#define int_fast16_t long int
#define uint_fast16_t unsigned int_fast16_t
#define int_fast32_t long int
#define uint_fast32_t unsigned int_fast32_t
#ifdef int64_t
# define int_fast64_t int64_t
#endif
#ifdef uint64_t
# define uint_fast64_t uint64_t
#endif

/* 7.18.1.4. Integer types capable of holding object pointers */

#undef intptr_t
#undef uintptr_t
#define intptr_t long int
#define uintptr_t unsigned long int

/* 7.18.1.5. Greatest-width integer types */

/* Note: These types are compiler dependent. It may be unwise to use them in
   public header files. */

#undef intmax_t
#if @HAVE_LONG_LONG_INT@ && LONG_MAX >> 30 == 1
# define intmax_t long long int
#elif defined int64_t
# define intmax_t int64_t
#else
# define intmax_t long int
#endif

#undef uintmax_t
#if @HAVE_UNSIGNED_LONG_LONG_INT@ && ULONG_MAX >> 31 == 1
# define uintmax_t unsigned long long int
#elif defined uint64_t
# define uintmax_t uint64_t
#else
# define uintmax_t unsigned long int
#endif

/* 7.18.2. Limits of specified-width integer types */

#if ! defined __cplusplus || defined __STDC_LIMIT_MACROS

/* 7.18.2.1. Limits of exact-width integer types */

/* Here we assume a standard architecture where the hardware integer
   types have 8, 16, 32, optionally 64 bits.  */

#undef INT8_MIN
#undef INT8_MAX
#undef UINT8_MAX
#define INT8_MIN  (~ INT8_MAX)
#define INT8_MAX  127
#define UINT8_MAX  255

#undef INT16_MIN
#undef INT16_MAX
#undef UINT16_MAX
#define INT16_MIN  (~ INT16_MAX)
#define INT16_MAX  32767
#define UINT16_MAX  65535

#undef INT32_MIN
#undef INT32_MAX
#undef UINT32_MAX
#define INT32_MIN  (~ INT32_MAX)
#define INT32_MAX  2147483647
#define UINT32_MAX  4294967295U

#undef INT64_MIN
#undef INT64_MAX
#ifdef int64_t
# define INT64_MIN  (~ INT64_MAX)
# define INT64_MAX  INTMAX_C (9223372036854775807)
#endif

#undef UINT64_MAX
#ifdef uint64_t
# define UINT64_MAX  UINTMAX_C (18446744073709551615)
#endif

/* 7.18.2.2. Limits of minimum-width integer types */

/* Here we assume a standard architecture where the hardware integer
   types have 8, 16, 32, optionally 64 bits. Therefore the leastN_t types
   are the same as the corresponding N_t types.  */

#undef INT_LEAST8_MIN
#undef INT_LEAST8_MAX
#undef UINT_LEAST8_MAX
#define INT_LEAST8_MIN  INT8_MIN
#define INT_LEAST8_MAX  INT8_MAX
#define UINT_LEAST8_MAX  UINT8_MAX

#undef INT_LEAST16_MIN
#undef INT_LEAST16_MAX
#undef UINT_LEAST16_MAX
#define INT_LEAST16_MIN  INT16_MIN
#define INT_LEAST16_MAX  INT16_MAX
#define UINT_LEAST16_MAX  UINT16_MAX

#undef INT_LEAST32_MIN
#undef INT_LEAST32_MAX
#undef UINT_LEAST32_MAX
#define INT_LEAST32_MIN  INT32_MIN
#define INT_LEAST32_MAX  INT32_MAX
#define UINT_LEAST32_MAX  UINT32_MAX

#undef INT_LEAST64_MIN
#undef INT_LEAST64_MAX
#ifdef int64_t
# define INT_LEAST64_MIN  INT64_MIN
# define INT_LEAST64_MAX  INT64_MAX
#endif

#undef UINT_LEAST64_MAX
#ifdef uint64_t
# define UINT_LEAST64_MAX  UINT64_MAX
#endif

/* 7.18.2.3. Limits of fastest minimum-width integer types */

/* Here we assume a standard architecture where the hardware integer
   types have 8, 16, 32, optionally 64 bits. Therefore the fastN_t types
   are taken from the same list of types.  */

#undef INT_FAST8_MIN
#undef INT_FAST8_MAX
#undef UINT_FAST8_MAX
#define INT_FAST8_MIN  LONG_MIN
#define INT_FAST8_MAX  LONG_MAX
#define UINT_FAST8_MAX  ULONG_MAX

#undef INT_FAST16_MIN
#undef INT_FAST16_MAX
#undef UINT_FAST16_MAX
#define INT_FAST16_MIN  LONG_MIN
#define INT_FAST16_MAX  LONG_MAX
#define UINT_FAST16_MAX  ULONG_MAX

#undef INT_FAST32_MIN
#undef INT_FAST32_MAX
#undef UINT_FAST32_MAX
#define INT_FAST32_MIN  LONG_MIN
#define INT_FAST32_MAX  LONG_MAX
#define UINT_FAST32_MAX  ULONG_MAX

#undef INT_FAST64_MIN
#undef INT_FAST64_MAX
#ifdef int64_t
# define INT_FAST64_MIN  INT64_MIN
# define INT_FAST64_MAX  INT64_MAX
#endif

#undef UINT_FAST64_MAX
#ifdef uint64_t
# define UINT_FAST64_MAX  UINT64_MAX
#endif

/* 7.18.2.4. Limits of integer types capable of holding object pointers */

#undef INTPTR_MIN
#undef INTPTR_MAX
#undef UINTPTR_MAX
#define INTPTR_MIN  LONG_MIN
#define INTPTR_MAX  LONG_MAX
#define UINTPTR_MAX  ULONG_MAX

/* 7.18.2.5. Limits of greatest-width integer types */

#undef INTMAX_MIN
#undef INTMAX_MAX
#define INTMAX_MIN  (~ INTMAX_MAX)
#ifdef INT64_MAX
# define INTMAX_MAX  INT64_MAX
#else
# define INTMAX_MAX  INT32_MAX
#endif

#undef UINTMAX_MAX
#ifdef UINT64_MAX
# define UINTMAX_MAX  UINT64_MAX
#else
# define UINTMAX_MAX  UINT32_MAX
#endif

/* 7.18.3. Limits of other integer types */

/* ptrdiff_t limits */
#undef PTRDIFF_MIN
#undef PTRDIFF_MAX
#define PTRDIFF_MIN  \
   _STDINT_MIN (1, @BITSIZEOF_PTRDIFF_T@, 0 at PTRDIFF_T_SUFFIX@)
#define PTRDIFF_MAX  \
   _STDINT_MAX (1, @BITSIZEOF_PTRDIFF_T@, 0 at PTRDIFF_T_SUFFIX@)

/* sig_atomic_t limits */
#undef SIG_ATOMIC_MIN
#undef SIG_ATOMIC_MAX
#define SIG_ATOMIC_MIN  \
   _STDINT_MIN (@HAVE_SIGNED_SIG_ATOMIC_T@, @BITSIZEOF_SIG_ATOMIC_T@, \
		0 at SIG_ATOMIC_T_SUFFIX@)
#define SIG_ATOMIC_MAX  \
   _STDINT_MAX (@HAVE_SIGNED_SIG_ATOMIC_T@, @BITSIZEOF_SIG_ATOMIC_T@, \
		0 at SIG_ATOMIC_T_SUFFIX@)


/* size_t limit */
#undef SIZE_MAX
#define SIZE_MAX  _STDINT_MAX (0, @BITSIZEOF_SIZE_T@, 0 at SIZE_T_SUFFIX@)

/* wchar_t limits */
#undef WCHAR_MIN
#undef WCHAR_MAX
#define WCHAR_MIN  \
   _STDINT_MIN (@HAVE_SIGNED_WCHAR_T@, @BITSIZEOF_WCHAR_T@, 0 at WCHAR_T_SUFFIX@)
#define WCHAR_MAX  \
   _STDINT_MAX (@HAVE_SIGNED_WCHAR_T@, @BITSIZEOF_WCHAR_T@, 0 at WCHAR_T_SUFFIX@)

/* wint_t limits */
#undef WINT_MIN
#undef WINT_MAX
#define WINT_MIN  \
   _STDINT_MIN (@HAVE_SIGNED_WINT_T@, @BITSIZEOF_WINT_T@, 0 at WINT_T_SUFFIX@)
#define WINT_MAX  \
   _STDINT_MAX (@HAVE_SIGNED_WINT_T@, @BITSIZEOF_WINT_T@, 0 at WINT_T_SUFFIX@)

#endif /* !defined __cplusplus || defined __STDC_LIMIT_MACROS */

/* 7.18.4. Macros for integer constants */

#if ! defined __cplusplus || defined __STDC_CONSTANT_MACROS

/* 7.18.4.1. Macros for minimum-width integer constants */
/* According to ISO C 99 Technical Corrigendum 1 */

/* Here we assume a standard architecture where the hardware integer
   types have 8, 16, 32, optionally 64 bits, and int is 32 bits.  */

#undef INT8_C
#undef UINT8_C
#define INT8_C(x) x
#define UINT8_C(x) x

#undef INT16_C
#undef UINT16_C
#define INT16_C(x) x
#define UINT16_C(x) x

#undef INT32_C
#undef UINT32_C
#define INT32_C(x) x
#define UINT32_C(x) x ## U

#undef INT64_C
#undef UINT64_C
#if LONG_MAX >> 31 >> 31 == 1
# define INT64_C(x) x##L
#elif defined _MSC_VER
# define INT64_C(x) x##i64
#elif @HAVE_LONG_LONG_INT@
# define INT64_C(x) x##LL
#endif
#if ULONG_MAX >> 31 >> 31 >> 1 == 1
# define UINT64_C(x) x##UL
#elif defined _MSC_VER
# define UINT64_C(x) x##ui64
#elif @HAVE_UNSIGNED_LONG_LONG_INT@
# define UINT64_C(x) x##ULL
#endif

/* 7.18.4.2. Macros for greatest-width integer constants */

#undef INTMAX_C
#if @HAVE_LONG_LONG_INT@ && LONG_MAX >> 30 == 1
# define INTMAX_C(x)   x##LL
#elif defined int64_t
# define INTMAX_C(x)   INT64_C(x)
#else
# define INTMAX_C(x)   x##L
#endif

#undef UINTMAX_C
#if @HAVE_UNSIGNED_LONG_LONG_INT@ && ULONG_MAX >> 31 == 1
# define UINTMAX_C(x)  x##ULL
#elif defined uint64_t
# define UINTMAX_C(x)  UINT64_C(x)
#else
# define UINTMAX_C(x)  x##UL
#endif

#endif /* !defined __cplusplus || defined __STDC_CONSTANT_MACROS */

#endif /* _GL_STDINT_H */

--- NEW FILE: xmalloc.c ---
/* xmalloc.c -- malloc with out of memory checking

   Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
   1999, 2000, 2002, 2003, 2004, 2005, 2006 Free Software Foundation,
   Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

#include <config.h>

#if ! HAVE_INLINE
# define static_inline
#endif
#include "xalloc.h"
#undef static_inline

#include <stdlib.h>
#include <string.h>

#ifndef SIZE_MAX
# define SIZE_MAX ((size_t) -1)
#endif

/* 1 if calloc is known to be compatible with GNU calloc.  This
   matters if we are not also using the calloc module, which defines
   HAVE_CALLOC and supports the GNU API even on non-GNU platforms.  */
#if defined HAVE_CALLOC || defined __GLIBC__
enum { HAVE_GNU_CALLOC = 1 };
#else
enum { HAVE_GNU_CALLOC = 0 };
#endif

/* Allocate N bytes of memory dynamically, with error checking.  */

void *
xmalloc (size_t n)
{
  void *p = malloc (n);
  if (!p && n != 0)
    xalloc_die ();
  return p;
}

/* Change the size of an allocated block of memory P to N bytes,
   with error checking.  */

void *
xrealloc (void *p, size_t n)
{
  p = realloc (p, n);
  if (!p && n != 0)
    xalloc_die ();
  return p;
}

/* If P is null, allocate a block of at least *PN bytes; otherwise,
   reallocate P so that it contains more than *PN bytes.  *PN must be
   nonzero unless P is null.  Set *PN to the new block's size, and
   return the pointer to the new block.  *PN is never set to zero, and
   the returned pointer is never null.  */

void *
x2realloc (void *p, size_t *pn)
{
  return x2nrealloc (p, pn, 1);
}

/* Allocate S bytes of zeroed memory dynamically, with error checking.
   There's no need for xnzalloc (N, S), since it would be equivalent
   to xcalloc (N, S).  */

void *
xzalloc (size_t s)
{
  return memset (xmalloc (s), 0, s);
}

/* Allocate zeroed memory for N elements of S bytes, with error
   checking.  S must be nonzero.  */

void *
xcalloc (size_t n, size_t s)
{
  void *p;
  /* Test for overflow, since some calloc implementations don't have
     proper overflow checks.  But omit overflow and size-zero tests if
     HAVE_GNU_CALLOC, since GNU calloc catches overflow and never
     returns NULL if successful.  */
  if ((! HAVE_GNU_CALLOC && xalloc_oversized (n, s))
      || (! (p = calloc (n, s)) && (HAVE_GNU_CALLOC || n != 0)))
    xalloc_die ();
  return p;
}

/* Clone an object P of size S, with error checking.  There's no need
   for xnmemdup (P, N, S), since xmemdup (P, N * S) works without any
   need for an arithmetic overflow check.  */

void *
xmemdup (void const *p, size_t s)
{
  return memcpy (xmalloc (s), p, s);
}

/* Clone STRING.  */

char *
xstrdup (char const *string)
{
  return xmemdup (string, strlen (string) + 1);
}

--- NEW FILE: snprintf.c ---
/* Formatted output to strings.
   Copyright (C) 2004, 2006 Free Software Foundation, Inc.
   Written by Simon Josefsson and Paul Eggert.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License along
   with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

#include <config.h>

#include "snprintf.h"

#include <errno.h>
#include <limits.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>

#include "vasnprintf.h"

/* Some systems, like OSF/1 4.0 and Woe32, don't have EOVERFLOW.  */
#ifndef EOVERFLOW
# define EOVERFLOW E2BIG
#endif

/* Print formatted output to string STR.  Similar to sprintf, but
   additional length SIZE limit how much is written into STR.  Returns
   string length of formatted string (which may be larger than SIZE).
   STR may be NULL, in which case nothing will be written.  On error,
   return a negative value. */
int
snprintf (char *str, size_t size, const char *format, ...)
{
  char *output;
  size_t len;
  size_t lenbuf = size;
  va_list args;

  va_start (args, format);
  output = vasnprintf (str, &lenbuf, format, args);
  len = lenbuf;
  va_end (args);

  if (!output)
    return -1;

  if (output != str)
    {
      if (size)
	{
	  size_t pruned_len = (len < size ? len : size - 1);
	  memcpy (str, output, pruned_len);
	  str[pruned_len] = '\0';
	}

      free (output);
    }

  if (INT_MAX < len)
    {
      errno = EOVERFLOW;
      return -1;
    }

  return len;
}

--- NEW FILE: xsize.h ---
/* xsize.h -- Checked size_t computations.

   Copyright (C) 2003 Free Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

#ifndef _XSIZE_H
#define _XSIZE_H

/* Get size_t.  */
#include <stddef.h>

/* Get SIZE_MAX.  */
#include <limits.h>
#if HAVE_STDINT_H
# include <stdint.h>
#endif

/* The size of memory objects is often computed through expressions of
   type size_t. Example:
      void* p = malloc (header_size + n * element_size).
   These computations can lead to overflow.  When this happens, malloc()
   returns a piece of memory that is way too small, and the program then
   crashes while attempting to fill the memory.
   To avoid this, the functions and macros in this file check for overflow.
   The convention is that SIZE_MAX represents overflow.
   malloc (SIZE_MAX) is not guaranteed to fail -- think of a malloc
   implementation that uses mmap --, it's recommended to use size_overflow_p()
   or size_in_bounds_p() before invoking malloc().
   The example thus becomes:
      size_t size = xsum (header_size, xtimes (n, element_size));
      void *p = (size_in_bounds_p (size) ? malloc (size) : NULL);
*/

/* Convert an arbitrary value >= 0 to type size_t.  */
#define xcast_size_t(N) \
  ((N) <= SIZE_MAX ? (size_t) (N) : SIZE_MAX)

/* Sum of two sizes, with overflow check.  */
static inline size_t
#if __GNUC__ >= 3
__attribute__ ((__pure__))
#endif
xsum (size_t size1, size_t size2)
{
  size_t sum = size1 + size2;
  return (sum >= size1 ? sum : SIZE_MAX);
}

/* Sum of three sizes, with overflow check.  */
static inline size_t
#if __GNUC__ >= 3
__attribute__ ((__pure__))
#endif
xsum3 (size_t size1, size_t size2, size_t size3)
{
  return xsum (xsum (size1, size2), size3);
}

/* Sum of four sizes, with overflow check.  */
static inline size_t
#if __GNUC__ >= 3
__attribute__ ((__pure__))
#endif
xsum4 (size_t size1, size_t size2, size_t size3, size_t size4)
{
  return xsum (xsum (xsum (size1, size2), size3), size4);
}

/* Maximum of two sizes, with overflow check.  */
static inline size_t
#if __GNUC__ >= 3
__attribute__ ((__pure__))
#endif
xmax (size_t size1, size_t size2)
{
  /* No explicit check is needed here, because for any n:
     max (SIZE_MAX, n) == SIZE_MAX and max (n, SIZE_MAX) == SIZE_MAX.  */
  return (size1 >= size2 ? size1 : size2);
}

/* Multiplication of a count with an element size, with overflow check.
   The count must be >= 0 and the element size must be > 0.
   This is a macro, not an inline function, so that it works correctly even
   when N is of a wider tupe and N > SIZE_MAX.  */
#define xtimes(N, ELSIZE) \
  ((N) <= SIZE_MAX / (ELSIZE) ? (size_t) (N) * (ELSIZE) : SIZE_MAX)

/* Check for overflow.  */
#define size_overflow_p(SIZE) \
  ((SIZE) == SIZE_MAX)
/* Check against overflow.  */
#define size_in_bounds_p(SIZE) \
  ((SIZE) != SIZE_MAX)

#endif /* _XSIZE_H */

--- NEW FILE: snprintf.h ---
/* Formatted output to strings.
   Copyright (C) 2004 Free Software Foundation, Inc.
   Written by Simon Josefsson.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License along
   with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

#ifndef SNPRINTF_H
#define SNPRINTF_H

/* Get snprintf declaration, if available.  */
#include <stdio.h>

#if defined HAVE_DECL_SNPRINTF && !HAVE_DECL_SNPRINTF
int snprintf (char *str, size_t size, const char *format, ...);
#endif

#endif /* SNPRINTF_H */

--- NEW FILE: printf-parse.c ---
/* Formatted output to strings.
   Copyright (C) 1999-2000, 2002-2003, 2006 Free Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License along
   with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

#include <config.h>

/* Specification.  */
#if WIDE_CHAR_VERSION
# include "wprintf-parse.h"
#else
# include "printf-parse.h"
#endif

/* Get size_t, NULL.  */
#include <stddef.h>

/* Get intmax_t.  */
#if HAVE_STDINT_H_WITH_UINTMAX
# include <stdint.h>
#endif
#if HAVE_INTTYPES_H_WITH_UINTMAX
# include <inttypes.h>
#endif

/* malloc(), realloc(), free().  */
#include <stdlib.h>

/* Checked size_t computations.  */
#include "xsize.h"

#if WIDE_CHAR_VERSION
# define PRINTF_PARSE wprintf_parse
# define CHAR_T wchar_t
# define DIRECTIVE wchar_t_directive
# define DIRECTIVES wchar_t_directives
#else
# define PRINTF_PARSE printf_parse
# define CHAR_T char
# define DIRECTIVE char_directive
# define DIRECTIVES char_directives
#endif

#ifdef STATIC
STATIC
#endif
int
PRINTF_PARSE (const CHAR_T *format, DIRECTIVES *d, arguments *a)
{
  const CHAR_T *cp = format;		/* pointer into format */
  size_t arg_posn = 0;		/* number of regular arguments consumed */
  size_t d_allocated;			/* allocated elements of d->dir */
  size_t a_allocated;			/* allocated elements of a->arg */
  size_t max_width_length = 0;
  size_t max_precision_length = 0;

  d->count = 0;
  d_allocated = 1;
  d->dir = (DIRECTIVE *) malloc (d_allocated * sizeof (DIRECTIVE));
  if (d->dir == NULL)
    /* Out of memory.  */
    return -1;

  a->count = 0;
  a_allocated = 0;
  a->arg = NULL;

#define REGISTER_ARG(_index_,_type_) \
  {									\
    size_t n = (_index_);						\
    if (n >= a_allocated)						\
      {									\
	size_t memory_size;						\
	argument *memory;						\
									\
	a_allocated = xtimes (a_allocated, 2);				\
	if (a_allocated <= n)						\
	  a_allocated = xsum (n, 1);					\
	memory_size = xtimes (a_allocated, sizeof (argument));		\
	if (size_overflow_p (memory_size))				\
	  /* Overflow, would lead to out of memory.  */			\
	  goto error;							\
	memory = (argument *) (a->arg					\
			       ? realloc (a->arg, memory_size)		\
			       : malloc (memory_size));			\
	if (memory == NULL)						\
	  /* Out of memory.  */						\
	  goto error;							\
	a->arg = memory;						\
      }									\
    while (a->count <= n)						\
      a->arg[a->count++].type = TYPE_NONE;				\
    if (a->arg[n].type == TYPE_NONE)					\
      a->arg[n].type = (_type_);					\
    else if (a->arg[n].type != (_type_))				\
      /* Ambiguous type for positional argument.  */			\
      goto error;							\
  }

  while (*cp != '\0')
    {
      CHAR_T c = *cp++;
      if (c == '%')
	{
	  size_t arg_index = ARG_NONE;
	  DIRECTIVE *dp = &d->dir[d->count];/* pointer to next directive */

	  /* Initialize the next directive.  */
	  dp->dir_start = cp - 1;
	  dp->flags = 0;
	  dp->width_start = NULL;
	  dp->width_end = NULL;
	  dp->width_arg_index = ARG_NONE;
	  dp->precision_start = NULL;
	  dp->precision_end = NULL;
	  dp->precision_arg_index = ARG_NONE;
	  dp->arg_index = ARG_NONE;

	  /* Test for positional argument.  */
	  if (*cp >= '0' && *cp <= '9')
	    {
	      const CHAR_T *np;

	      for (np = cp; *np >= '0' && *np <= '9'; np++)
		;
	      if (*np == '$')
		{
		  size_t n = 0;

		  for (np = cp; *np >= '0' && *np <= '9'; np++)
		    n = xsum (xtimes (n, 10), *np - '0');
		  if (n == 0)
		    /* Positional argument 0.  */
		    goto error;
		  if (size_overflow_p (n))
		    /* n too large, would lead to out of memory later.  */
		    goto error;
		  arg_index = n - 1;
		  cp = np + 1;
		}
	    }

	  /* Read the flags.  */
	  for (;;)
	    {
	      if (*cp == '\'')
		{
		  dp->flags |= FLAG_GROUP;
		  cp++;
		}
	      else if (*cp == '-')
		{
		  dp->flags |= FLAG_LEFT;
		  cp++;
		}
	      else if (*cp == '+')
		{
		  dp->flags |= FLAG_SHOWSIGN;
		  cp++;
		}
	      else if (*cp == ' ')
		{
		  dp->flags |= FLAG_SPACE;
		  cp++;
		}
	      else if (*cp == '#')
		{
		  dp->flags |= FLAG_ALT;
		  cp++;
		}
	      else if (*cp == '0')
		{
		  dp->flags |= FLAG_ZERO;
		  cp++;
		}
	      else
		break;
	    }

	  /* Parse the field width.  */
	  if (*cp == '*')
	    {
	      dp->width_start = cp;
	      cp++;
	      dp->width_end = cp;
	      if (max_width_length < 1)
		max_width_length = 1;

	      /* Test for positional argument.  */
	      if (*cp >= '0' && *cp <= '9')
		{
		  const CHAR_T *np;

		  for (np = cp; *np >= '0' && *np <= '9'; np++)
		    ;
		  if (*np == '$')
		    {
		      size_t n = 0;

		      for (np = cp; *np >= '0' && *np <= '9'; np++)
			n = xsum (xtimes (n, 10), *np - '0');
		      if (n == 0)
			/* Positional argument 0.  */
			goto error;
		      if (size_overflow_p (n))
			/* n too large, would lead to out of memory later.  */
			goto error;
		      dp->width_arg_index = n - 1;
		      cp = np + 1;
		    }
		}
	      if (dp->width_arg_index == ARG_NONE)
		{
		  dp->width_arg_index = arg_posn++;
		  if (dp->width_arg_index == ARG_NONE)
		    /* arg_posn wrapped around.  */
		    goto error;
		}
	      REGISTER_ARG (dp->width_arg_index, TYPE_INT);
	    }
	  else if (*cp >= '0' && *cp <= '9')
	    {
	      size_t width_length;

	      dp->width_start = cp;
	      for (; *cp >= '0' && *cp <= '9'; cp++)
		;
	      dp->width_end = cp;
	      width_length = dp->width_end - dp->width_start;
	      if (max_width_length < width_length)
		max_width_length = width_length;
	    }

	  /* Parse the precision.  */
	  if (*cp == '.')
	    {
	      cp++;
	      if (*cp == '*')
		{
		  dp->precision_start = cp - 1;
		  cp++;
		  dp->precision_end = cp;
		  if (max_precision_length < 2)
		    max_precision_length = 2;

		  /* Test for positional argument.  */
		  if (*cp >= '0' && *cp <= '9')
		    {
		      const CHAR_T *np;

		      for (np = cp; *np >= '0' && *np <= '9'; np++)
			;
		      if (*np == '$')
			{
			  size_t n = 0;

			  for (np = cp; *np >= '0' && *np <= '9'; np++)
			    n = xsum (xtimes (n, 10), *np - '0');
			  if (n == 0)
			    /* Positional argument 0.  */
			    goto error;
			  if (size_overflow_p (n))
			    /* n too large, would lead to out of memory
			       later.  */
			    goto error;
			  dp->precision_arg_index = n - 1;
			  cp = np + 1;
			}
		    }
		  if (dp->precision_arg_index == ARG_NONE)
		    {
		      dp->precision_arg_index = arg_posn++;
		      if (dp->precision_arg_index == ARG_NONE)
			/* arg_posn wrapped around.  */
			goto error;
		    }
		  REGISTER_ARG (dp->precision_arg_index, TYPE_INT);
		}
	      else
		{
		  size_t precision_length;

		  dp->precision_start = cp - 1;
		  for (; *cp >= '0' && *cp <= '9'; cp++)
		    ;
		  dp->precision_end = cp;
		  precision_length = dp->precision_end - dp->precision_start;
		  if (max_precision_length < precision_length)
		    max_precision_length = precision_length;
		}
	    }

	  {
	    arg_type type;

	    /* Parse argument type/size specifiers.  */
	    {
	      int flags = 0;

	      for (;;)
		{
		  if (*cp == 'h')
		    {
		      flags |= (1 << (flags & 1));
		      cp++;
		    }
		  else if (*cp == 'L')
		    {
		      flags |= 4;
		      cp++;
		    }
		  else if (*cp == 'l')
		    {
		      flags += 8;
		      cp++;
		    }
#ifdef HAVE_INTMAX_T
		  else if (*cp == 'j')
		    {
		      if (sizeof (intmax_t) > sizeof (long))
			{
			  /* intmax_t = long long */
			  flags += 16;
			}
		      else if (sizeof (intmax_t) > sizeof (int))
			{
			  /* intmax_t = long */
			  flags += 8;
			}
		      cp++;
		    }
#endif
		  else if (*cp == 'z' || *cp == 'Z')
		    {
		      /* 'z' is standardized in ISO C 99, but glibc uses 'Z'
			 because the warning facility in gcc-2.95.2 understands
			 only 'Z' (see gcc-2.95.2/gcc/c-common.c:1784).  */
		      if (sizeof (size_t) > sizeof (long))
			{
			  /* size_t = long long */
			  flags += 16;
			}
		      else if (sizeof (size_t) > sizeof (int))
			{
			  /* size_t = long */
			  flags += 8;
			}
		      cp++;
		    }
		  else if (*cp == 't')
		    {
		      if (sizeof (ptrdiff_t) > sizeof (long))
			{
			  /* ptrdiff_t = long long */
			  flags += 16;
			}
		      else if (sizeof (ptrdiff_t) > sizeof (int))
			{
			  /* ptrdiff_t = long */
			  flags += 8;
			}
		      cp++;
		    }
		  else
		    break;
		}

	      /* Read the conversion character.  */
	      c = *cp++;
	      switch (c)
		{
		case 'd': case 'i':
#ifdef HAVE_LONG_LONG_INT
		  /* If 'long long' exists and is larger than 'long':  */
		  if (flags >= 16 || (flags & 4))
		    type = TYPE_LONGLONGINT;
		  else
#endif
		  /* If 'long long' exists and is the same as 'long', we parse
		     "lld" into TYPE_LONGINT.  */
		  if (flags >= 8)
		    type = TYPE_LONGINT;
		  else if (flags & 2)
		    type = TYPE_SCHAR;
		  else if (flags & 1)
		    type = TYPE_SHORT;
		  else
		    type = TYPE_INT;
		  break;
		case 'o': case 'u': case 'x': case 'X':
#ifdef HAVE_LONG_LONG_INT
		  /* If 'long long' exists and is larger than 'long':  */
		  if (flags >= 16 || (flags & 4))
		    type = TYPE_ULONGLONGINT;
		  else
#endif
		  /* If 'unsigned long long' exists and is the same as
		     'unsigned long', we parse "llu" into TYPE_ULONGINT.  */
		  if (flags >= 8)
		    type = TYPE_ULONGINT;
		  else if (flags & 2)
		    type = TYPE_UCHAR;
		  else if (flags & 1)
		    type = TYPE_USHORT;
		  else
		    type = TYPE_UINT;
		  break;
		case 'f': case 'F': case 'e': case 'E': case 'g': case 'G':
		case 'a': case 'A':
#ifdef HAVE_LONG_DOUBLE
		  if (flags >= 16 || (flags & 4))
		    type = TYPE_LONGDOUBLE;
		  else
#endif
		  type = TYPE_DOUBLE;
		  break;
		case 'c':
		  if (flags >= 8)
#ifdef HAVE_WINT_T
		    type = TYPE_WIDE_CHAR;
#else
		    goto error;
#endif
		  else
		    type = TYPE_CHAR;
		  break;
#ifdef HAVE_WINT_T
		case 'C':
		  type = TYPE_WIDE_CHAR;
		  c = 'c';
		  break;
#endif
		case 's':
		  if (flags >= 8)
#ifdef HAVE_WCHAR_T
		    type = TYPE_WIDE_STRING;
#else
		    goto error;
#endif
		  else
		    type = TYPE_STRING;
		  break;
#ifdef HAVE_WCHAR_T
		case 'S':
		  type = TYPE_WIDE_STRING;
		  c = 's';
		  break;
#endif
		case 'p':
		  type = TYPE_POINTER;
		  break;
		case 'n':
#ifdef HAVE_LONG_LONG_INT
		  /* If 'long long' exists and is larger than 'long':  */
		  if (flags >= 16 || (flags & 4))
		    type = TYPE_COUNT_LONGLONGINT_POINTER;
		  else
#endif
		  /* If 'long long' exists and is the same as 'long', we parse
		     "lln" into TYPE_COUNT_LONGINT_POINTER.  */
		  if (flags >= 8)
		    type = TYPE_COUNT_LONGINT_POINTER;
		  else if (flags & 2)
		    type = TYPE_COUNT_SCHAR_POINTER;
		  else if (flags & 1)
		    type = TYPE_COUNT_SHORT_POINTER;
		  else
		    type = TYPE_COUNT_INT_POINTER;
		  break;
		case '%':
		  type = TYPE_NONE;
		  break;
		default:
		  /* Unknown conversion character.  */
		  goto error;
		}
	    }

	    if (type != TYPE_NONE)
	      {
		dp->arg_index = arg_index;
		if (dp->arg_index == ARG_NONE)
		  {
		    dp->arg_index = arg_posn++;
		    if (dp->arg_index == ARG_NONE)
		      /* arg_posn wrapped around.  */
		      goto error;
		  }
		REGISTER_ARG (dp->arg_index, type);
	      }
	    dp->conversion = c;
	    dp->dir_end = cp;
	  }

	  d->count++;
	  if (d->count >= d_allocated)
	    {
	      size_t memory_size;
	      DIRECTIVE *memory;

	      d_allocated = xtimes (d_allocated, 2);
	      memory_size = xtimes (d_allocated, sizeof (DIRECTIVE));
	      if (size_overflow_p (memory_size))
		/* Overflow, would lead to out of memory.  */
		goto error;
	      memory = (DIRECTIVE *) realloc (d->dir, memory_size);
	      if (memory == NULL)
		/* Out of memory.  */
		goto error;
	      d->dir = memory;
	    }
	}
    }
  d->dir[d->count].dir_start = cp;

  d->max_width_length = max_width_length;
  d->max_precision_length = max_precision_length;
  return 0;

error:
  if (a->arg)
    free (a->arg);
  if (d->dir)
    free (d->dir);
  return -1;
}

#undef DIRECTIVES
#undef DIRECTIVE
#undef CHAR_T
#undef PRINTF_PARSE

--- NEW FILE: regex_internal.c ---
/* Extended regular expression matching and search library.
   Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
   This file is part of the GNU C Library.
   Contributed by Isamu Hasegawa <isamu at yamato.ibm.com>.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License along
   with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */

[...1703 lines suppressed...]
	      re_node_set_init_copy (newstate->entrance_nodes, nodes);
	      nctx_nodes = 0;
	      newstate->has_constraint = 1;
	    }

	  if (NOT_SATISFY_PREV_CONSTRAINT (constraint,context))
	    {
	      re_node_set_remove_at (&newstate->nodes, i - nctx_nodes);
	      ++nctx_nodes;
	    }
	}
    }
  err = register_state (dfa, newstate, hash);
  if (BE (err != REG_NOERROR, 0))
    {
      free_state (newstate);
      newstate = NULL;
    }
  return  newstate;
}

--- NEW FILE: printf-parse.h ---
/* Parse printf format string.
   Copyright (C) 1999, 2002-2003 Free Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License along
   with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

#ifndef _PRINTF_PARSE_H
#define _PRINTF_PARSE_H

#include "printf-args.h"


/* Flags */
#define FLAG_GROUP	 1	/* ' flag */
#define FLAG_LEFT	 2	/* - flag */
#define FLAG_SHOWSIGN	 4	/* + flag */
#define FLAG_SPACE	 8	/* space flag */
#define FLAG_ALT	16	/* # flag */
#define FLAG_ZERO	32

/* arg_index value indicating that no argument is consumed.  */
#define ARG_NONE	(~(size_t)0)

/* A parsed directive.  */
typedef struct
{
  const char* dir_start;
  const char* dir_end;
  int flags;
  const char* width_start;
  const char* width_end;
  size_t width_arg_index;
  const char* precision_start;
  const char* precision_end;
  size_t precision_arg_index;
  char conversion; /* d i o u x X f e E g G c s p n U % but not C S */
  size_t arg_index;
}
char_directive;

/* A parsed format string.  */
typedef struct
{
  size_t count;
  char_directive *dir;
  size_t max_width_length;
  size_t max_precision_length;
}
char_directives;


/* Parses the format string.  Fills in the number N of directives, and fills
   in directives[0], ..., directives[N-1], and sets directives[N].dir_start
   to the end of the format string.  Also fills in the arg_type fields of the
   arguments and the needed count of arguments.  */
#ifdef STATIC
STATIC
#else
extern
#endif
int printf_parse (const char *format, char_directives *d, arguments *a);

#endif /* _PRINTF_PARSE_H */

--- NEW FILE: gethostname.c ---
/* gethostname emulation for SysV and POSIX.1.

   Copyright (C) 1992, 2003, 2006 Free Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

/* David MacKenzie <djm at gnu.ai.mit.edu> */

#include <config.h>

#ifdef HAVE_UNAME
# include <sys/utsname.h>
#endif

/* Put up to LEN chars of the host name into NAME.
   Null terminate it if the name is shorter than LEN.
   Return 0 if ok, -1 if error.  */

#include <stddef.h>

int
gethostname (char *name, size_t len)
{
#ifdef HAVE_UNAME
  struct utsname uts;

  if (uname (&uts) == -1)
    return -1;
  if (len > sizeof (uts.nodename))
    {
      /* More space than we need is available.  */
      name[sizeof (uts.nodename)] = '\0';
      len = sizeof (uts.nodename);
    }
  strncpy (name, uts.nodename, len);
#else
  strcpy (name, "");		/* Hardcode your system name if you want.  */
#endif
  return 0;
}

--- NEW FILE: error.c ---
/* Error handler for noninteractive utilities
   Copyright (C) 1990-1998, 2000-2005, 2006 Free Software Foundation, Inc.
   This file is part of the GNU C Library.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License along
   with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

/* Written by David MacKenzie <djm at gnu.ai.mit.edu>.  */

#if !_LIBC
# include <config.h>
#endif

#include "error.h"

#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#if !_LIBC && ENABLE_NLS
# include "gettext.h"
#endif

#ifdef _LIBC
# include <libintl.h>
# include <stdbool.h>
# include <stdint.h>
# include <wchar.h>
# define mbsrtowcs __mbsrtowcs
#endif

#if USE_UNLOCKED_IO
# include "unlocked-io.h"
#endif

#ifndef _
# define _(String) String
#endif

/* If NULL, error will flush stdout, then print on stderr the program
   name, a colon and a space.  Otherwise, error will call this
   function without parameters instead.  */
void (*error_print_progname) (void);

/* This variable is incremented each time `error' is called.  */
unsigned int error_message_count;

#ifdef _LIBC
/* In the GNU C library, there is a predefined variable for this.  */

# define program_name program_invocation_name
# include <errno.h>
# include <limits.h>
# include <libio/libioP.h>

/* In GNU libc we want do not want to use the common name `error' directly.
   Instead make it a weak alias.  */
extern void __error (int status, int errnum, const char *message, ...)
     __attribute__ ((__format__ (__printf__, 3, 4)));
extern void __error_at_line (int status, int errnum, const char *file_name,
			     unsigned int line_number, const char *message,
			     ...)
     __attribute__ ((__format__ (__printf__, 5, 6)));;
# define error __error
# define error_at_line __error_at_line

# include <libio/iolibio.h>
# define fflush(s) INTUSE(_IO_fflush) (s)
# undef putc
# define putc(c, fp) INTUSE(_IO_putc) (c, fp)

# include <bits/libc-lock.h>

#else /* not _LIBC */

# if !HAVE_DECL_STRERROR_R && STRERROR_R_CHAR_P
#  ifndef HAVE_DECL_STRERROR_R
"this configure-time declaration test was not run"
#  endif
char *strerror_r ();
# endif

/* The calling program should define program_name and set it to the
   name of the executing program.  */
extern char *program_name;

# if HAVE_STRERROR_R || defined strerror_r
#  define __strerror_r strerror_r
# endif	/* HAVE_STRERROR_R || defined strerror_r */
#endif	/* not _LIBC */

static void
print_errno_message (int errnum)
{
  char const *s;

#if defined HAVE_STRERROR_R || _LIBC
  char errbuf[1024];
# if STRERROR_R_CHAR_P || _LIBC
  s = __strerror_r (errnum, errbuf, sizeof errbuf);
# else
  if (__strerror_r (errnum, errbuf, sizeof errbuf) == 0)
    s = errbuf;
  else
    s = 0;
# endif
#else
  s = strerror (errnum);
#endif

#if !_LIBC
  if (! s)
    s = _("Unknown system error");
#endif

#if _LIBC
  __fxprintf (NULL, ": %s", s);
#else
  fprintf (stderr, ": %s", s);
#endif
}

static void
error_tail (int status, int errnum, const char *message, va_list args)
{
#if _LIBC
  if (_IO_fwide (stderr, 0) > 0)
    {
# define ALLOCA_LIMIT 2000
      size_t len = strlen (message) + 1;
      wchar_t *wmessage = NULL;
      mbstate_t st;
      size_t res;
      const char *tmp;
      bool use_malloc = false;

      while (1)
	{
	  if (__libc_use_alloca (len * sizeof (wchar_t)))
	    wmessage = (wchar_t *) alloca (len * sizeof (wchar_t));
	  else
	    {
	      if (!use_malloc)
		wmessage = NULL;

	      wchar_t *p = (wchar_t *) realloc (wmessage,
						len * sizeof (wchar_t));
	      if (p == NULL)
		{
		  free (wmessage);
		  fputws_unlocked (L"out of memory\n", stderr);
		  return;
		}
	      wmessage = p;
	      use_malloc = true;
	    }

	  memset (&st, '\0', sizeof (st));
	  tmp = message;

	  res = mbsrtowcs (wmessage, &tmp, len, &st);
	  if (res != len)
	    break;

	  if (__builtin_expect (len >= SIZE_MAX / 2, 0))
	    {
	      /* This really should not happen if everything is fine.  */
	      res = (size_t) -1;
	      break;
	    }

	  len *= 2;
	}

      if (res == (size_t) -1)
	{
	  /* The string cannot be converted.  */
	  if (use_malloc)
	    {
	      free (wmessage);
	      use_malloc = false;
	    }
	  wmessage = (wchar_t *) L"???";
	}

      __vfwprintf (stderr, wmessage, args);

      if (use_malloc)
	free (wmessage);
    }
  else
#endif
    vfprintf (stderr, message, args);
  va_end (args);

  ++error_message_count;
  if (errnum)
    print_errno_message (errnum);
#if _LIBC
  __fxprintf (NULL, "\n");
#else
  putc ('\n', stderr);
#endif
  fflush (stderr);
  if (status)
    exit (status);
}


/* Print the program name and error message MESSAGE, which is a printf-style
   format string with optional args.
   If ERRNUM is nonzero, print its corresponding system error message.
   Exit with status STATUS if it is nonzero.  */
void
error (int status, int errnum, const char *message, ...)
{
  va_list args;

#if defined _LIBC && defined __libc_ptf_call
  /* We do not want this call to be cut short by a thread
     cancellation.  Therefore disable cancellation for now.  */
  int state = PTHREAD_CANCEL_ENABLE;
  __libc_ptf_call (pthread_setcancelstate, (PTHREAD_CANCEL_DISABLE, &state),
		   0);
#endif

  fflush (stdout);
#ifdef _LIBC
  _IO_flockfile (stderr);
#endif
  if (error_print_progname)
    (*error_print_progname) ();
  else
    {
#if _LIBC
      __fxprintf (NULL, "%s: ", program_name);
#else
      fprintf (stderr, "%s: ", program_name);
#endif
    }

  va_start (args, message);
  error_tail (status, errnum, message, args);

#ifdef _LIBC
  _IO_funlockfile (stderr);
# ifdef __libc_ptf_call
  __libc_ptf_call (pthread_setcancelstate, (state, NULL), 0);
# endif
#endif
}

/* Sometimes we want to have at most one error per line.  This
   variable controls whether this mode is selected or not.  */
int error_one_per_line;

void
error_at_line (int status, int errnum, const char *file_name,
	       unsigned int line_number, const char *message, ...)
{
  va_list args;

  if (error_one_per_line)
    {
      static const char *old_file_name;
      static unsigned int old_line_number;

      if (old_line_number == line_number
	  && (file_name == old_file_name
	      || strcmp (old_file_name, file_name) == 0))
	/* Simply return and print nothing.  */
	return;

      old_file_name = file_name;
      old_line_number = line_number;
    }

#if defined _LIBC && defined __libc_ptf_call
  /* We do not want this call to be cut short by a thread
     cancellation.  Therefore disable cancellation for now.  */
  int state = PTHREAD_CANCEL_ENABLE;
  __libc_ptf_call (pthread_setcancelstate, (PTHREAD_CANCEL_DISABLE, &state),
		   0);
#endif

  fflush (stdout);
#ifdef _LIBC
  _IO_flockfile (stderr);
#endif
  if (error_print_progname)
    (*error_print_progname) ();
  else
    {
#if _LIBC
      __fxprintf (NULL, "%s:", program_name);
#else
      fprintf (stderr, "%s:", program_name);
#endif
    }

#if _LIBC
  __fxprintf (NULL, file_name != NULL ? "%s:%d: " : " ",
	      file_name, line_number);
#else
  fprintf (stderr, file_name != NULL ? "%s:%d: " : " ",
	   file_name, line_number);
#endif

  va_start (args, message);
  error_tail (status, errnum, message, args);

#ifdef _LIBC
  _IO_funlockfile (stderr);
# ifdef __libc_ptf_call
  __libc_ptf_call (pthread_setcancelstate, (state, NULL), 0);
# endif
#endif
}

#ifdef _LIBC
/* Make the weak alias.  */
# undef error
# undef error_at_line
weak_alias (__error, error)
weak_alias (__error_at_line, error_at_line)
#endif

--- NEW FILE: full-write.c ---
/* An interface to read and write that retries (if necessary) until complete.

   Copyright (C) 1993, 1994, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
   2004, 2005, 2006 Free Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

#include <config.h>

/* Specification.  */
#ifdef FULL_READ
# include "full-read.h"
#else
# include "full-write.h"
#endif

#include <errno.h>

#ifdef FULL_READ
# include "safe-read.h"
# define safe_rw safe_read
# define full_rw full_read
# undef const
# define const /* empty */
#else
# include "safe-write.h"
# define safe_rw safe_write
# define full_rw full_write
#endif

#ifdef FULL_READ
/* Set errno to zero upon EOF.  */
# define ZERO_BYTE_TRANSFER_ERRNO 0
#else
/* Some buggy drivers return 0 when one tries to write beyond
   a device's end.  (Example: Linux 1.2.13 on /dev/fd0.)
   Set errno to ENOSPC so they get a sensible diagnostic.  */
# define ZERO_BYTE_TRANSFER_ERRNO ENOSPC
#endif

/* Write(read) COUNT bytes at BUF to(from) descriptor FD, retrying if
   interrupted or if a partial write(read) occurs.  Return the number
   of bytes transferred.
   When writing, set errno if fewer than COUNT bytes are written.
   When reading, if fewer than COUNT bytes are read, you must examine
   errno to distinguish failure from EOF (errno == 0).  */
size_t
full_rw (int fd, const void *buf, size_t count)
{
  size_t total = 0;
  const char *ptr = (const char *) buf;

  while (count > 0)
    {
      size_t n_rw = safe_rw (fd, ptr, count);
      if (n_rw == (size_t) -1)
	break;
      if (n_rw == 0)
	{
	  errno = ZERO_BYTE_TRANSFER_ERRNO;
	  break;
	}
      total += n_rw;
      ptr += n_rw;
      count -= n_rw;
    }

  return total;
}

--- NEW FILE: strnlen1.h ---
/* Find the length of STRING + 1, but scan at most MAXLEN bytes.
   Copyright (C) 2005 Free Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

#ifndef _STRNLEN1_H
#define _STRNLEN1_H

#include <stddef.h>


#ifdef __cplusplus
extern "C" {
#endif


/* Find the length of STRING + 1, but scan at most MAXLEN bytes.
   If no '\0' terminator is found in that many characters, return MAXLEN.  */
/* This is the same as strnlen (string, maxlen - 1) + 1.  */
extern size_t strnlen1 (const char *string, size_t maxlen);


#ifdef __cplusplus
}
#endif


#endif /* _STRNLEN1_H */

--- NEW FILE: strnlen1.c ---
/* Find the length of STRING + 1, but scan at most MAXLEN bytes.
   Copyright (C) 2005-2006 Free Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

#include <config.h>

/* Specification.  */
#include "strnlen1.h"

#include <string.h>

/* Find the length of STRING + 1, but scan at most MAXLEN bytes.
   If no '\0' terminator is found in that many characters, return MAXLEN.  */
/* This is the same as strnlen (string, maxlen - 1) + 1.  */
size_t
strnlen1 (const char *string, size_t maxlen)
{
  const char *end = (const char *) memchr (string, '\0', maxlen);
  if (end != NULL)
    return end - string + 1;
  else
    return maxlen;
}

--- NEW FILE: getloadavg.c ---
/* Get the system load averages.

   Copyright (C) 1985, 1986, 1987, 1988, 1989, 1991, 1992, 1993, 1994,
   1995, 1997, 1999, 2000, 2003, 2004, 2005, 2006 Free Software
   Foundation, Inc.

   NOTE: The canonical source of this file is maintained with gnulib.
   Bugs can be reported to bug-gnulib at gnu.org.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

[...981 lines suppressed...]
	  perror ("Error getting load average");
	  return EXIT_FAILURE;
	}
      if (loads > 0)
	printf ("1-minute: %f  ", avg[0]);
      if (loads > 1)
	printf ("5-minute: %f  ", avg[1]);
      if (loads > 2)
	printf ("15-minute: %f  ", avg[2]);
      if (loads > 0)
	putchar ('\n');

      if (naptime == 0)
	break;
      sleep (naptime);
    }

  return EXIT_SUCCESS;
}
#endif /* TEST */

--- NEW FILE: full-write.h ---
/* An interface to write() that writes all it is asked to write.

   Copyright (C) 2002-2003 Free Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

#include <stddef.h>


#ifdef __cplusplus
extern "C" {
#endif


/* Write COUNT bytes at BUF to descriptor FD, retrying if interrupted
   or if partial writes occur.  Return the number of bytes successfully
   written, setting errno if that is less than COUNT.  */
extern size_t full_write (int fd, const void *buf, size_t count);


#ifdef __cplusplus
}
#endif

--- NEW FILE: getopt_int.h ---
/* Internal declarations for getopt.
   Copyright (C) 1989-1994,1996-1999,2001,2003,2004
   Free Software Foundation, Inc.
   This file is part of the GNU C Library.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License along
   with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

#ifndef _GETOPT_INT_H
#define _GETOPT_INT_H	1

extern int _getopt_internal (int ___argc, char **___argv,
			     const char *__shortopts,
		             const struct option *__longopts, int *__longind,
			     int __long_only, int __posixly_correct);


/* Reentrant versions which can handle parsing multiple argument
   vectors at the same time.  */

/* Data type for reentrant functions.  */
struct _getopt_data
{
  /* These have exactly the same meaning as the corresponding global
     variables, except that they are used for the reentrant
     versions of getopt.  */
  int optind;
  int opterr;
  int optopt;
  char *optarg;

  /* Internal members.  */

  /* True if the internal members have been initialized.  */
  int __initialized;

  /* The next char to be scanned in the option-element
     in which the last option character we returned was found.
     This allows us to pick up the scan where we left off.

     If this is zero, or a null string, it means resume the scan
     by advancing to the next ARGV-element.  */
  char *__nextchar;

  /* Describe how to deal with options that follow non-option ARGV-elements.

     If the caller did not specify anything,
     the default is REQUIRE_ORDER if the environment variable
     POSIXLY_CORRECT is defined, PERMUTE otherwise.

     REQUIRE_ORDER means don't recognize them as options;
     stop option processing when the first non-option is seen.
     This is what Unix does.
     This mode of operation is selected by either setting the environment
     variable POSIXLY_CORRECT, or using `+' as the first character
     of the list of option characters, or by calling getopt.

     PERMUTE is the default.  We permute the contents of ARGV as we
     scan, so that eventually all the non-options are at the end.
     This allows options to be given in any order, even with programs
     that were not written to expect this.

     RETURN_IN_ORDER is an option available to programs that were
     written to expect options and other ARGV-elements in any order
     and that care about the ordering of the two.  We describe each
     non-option ARGV-element as if it were the argument of an option
     with character code 1.  Using `-' as the first character of the
     list of option characters selects this mode of operation.

     The special argument `--' forces an end of option-scanning regardless
     of the value of `ordering'.  In the case of RETURN_IN_ORDER, only
     `--' can cause `getopt' to return -1 with `optind' != ARGC.  */

  enum
    {
      REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
    } __ordering;

  /* If the POSIXLY_CORRECT environment variable is set
     or getopt was called.  */
  int __posixly_correct;


  /* Handle permutation of arguments.  */

  /* Describe the part of ARGV that contains non-options that have
     been skipped.  `first_nonopt' is the index in ARGV of the first
     of them; `last_nonopt' is the index after the last of them.  */

  int __first_nonopt;
  int __last_nonopt;

#if defined _LIBC && defined USE_NONOPTION_FLAGS
  int __nonoption_flags_max_len;
  int __nonoption_flags_len;
# endif
};

/* The initializer is necessary to set OPTIND and OPTERR to their
   default values and to clear the initialization flag.  */
#define _GETOPT_DATA_INITIALIZER	{ 1, 1 }

extern int _getopt_internal_r (int ___argc, char **___argv,
			       const char *__shortopts,
			       const struct option *__longopts, int *__longind,
			       int __long_only, int __posixly_correct,
			       struct _getopt_data *__data);

extern int _getopt_long_r (int ___argc, char **___argv,
			   const char *__shortopts,
			   const struct option *__longopts, int *__longind,
			   struct _getopt_data *__data);

extern int _getopt_long_only_r (int ___argc, char **___argv,
				const char *__shortopts,
				const struct option *__longopts,
				int *__longind,
				struct _getopt_data *__data);

#endif /* getopt_int.h */

--- NEW FILE: c-strtod.c ---
/* Convert string to double, using the C locale.

   Copyright (C) 2003, 2004, 2006 Free Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

/* Written by Paul Eggert.  */

#include <config.h>

#include "c-strtod.h"

#include <locale.h>
#include <stdlib.h>

#include "xalloc.h"

#if LONG
# define C_STRTOD c_strtold
# define DOUBLE long double
# define STRTOD_L strtold_l
#else
# define C_STRTOD c_strtod
# define DOUBLE double
# define STRTOD_L strtod_l
#endif

/* c_strtold falls back on strtod if strtold doesn't conform to C99.  */
#if LONG && HAVE_C99_STRTOLD
# define STRTOD strtold
#else
# define STRTOD strtod
#endif

DOUBLE
C_STRTOD (char const *nptr, char **endptr)
{
  DOUBLE r;

#ifdef LC_ALL_MASK

  locale_t c_locale = newlocale (LC_ALL_MASK, "C", 0);
  r = STRTOD_L (nptr, endptr, c_locale);
  freelocale (c_locale);

#else

  char *saved_locale = setlocale (LC_NUMERIC, NULL);

  if (saved_locale)
    {
      saved_locale = xstrdup (saved_locale);
      setlocale (LC_NUMERIC, "C");
    }

  r = STRTOD (nptr, endptr);

  if (saved_locale)
    {
      setlocale (LC_NUMERIC, saved_locale);
      free (saved_locale);
    }

#endif

  return r;
}

--- NEW FILE: strnlen.h ---
/* Find the length of STRING, but scan at most MAXLEN characters.
   Copyright (C) 2005 Free Software Foundation, Inc.
   Written by Simon Josefsson.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

#ifndef STRNLEN_H
#define STRNLEN_H

/* Get strnlen declaration, if available.  */
#include <string.h>

#if defined HAVE_DECL_STRNLEN && !HAVE_DECL_STRNLEN
/* Find the length (number of bytes) of STRING, but scan at most
   MAXLEN bytes.  If no '\0' terminator is found in that many bytes,
   return MAXLEN.  */
extern size_t strnlen(const char *string, size_t maxlen);
#endif

#endif /* STRNLEN_H */

--- NEW FILE: getopt_.h ---
/* Declarations for getopt.
   Copyright (C) 1989-1994,1996-1999,2001,2003,2004,2005,2006
   Free Software Foundation, Inc.
   This file is part of the GNU C Library.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License along
   with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

#ifndef _GETOPT_H

#ifndef __need_getopt
# define _GETOPT_H 1
#endif

/* Standalone applications should #define __GETOPT_PREFIX to an
   identifier that prefixes the external functions and variables
   defined in this header.  When this happens, include the
   headers that might declare getopt so that they will not cause
   confusion if included after this file.  Then systematically rename
   identifiers so that they do not collide with the system functions
   and variables.  Renaming avoids problems with some compilers and
   linkers.  */
#if defined __GETOPT_PREFIX && !defined __need_getopt
# include <stdlib.h>
# include <stdio.h>
# include <unistd.h>
# undef __need_getopt
# undef getopt
# undef getopt_long
# undef getopt_long_only
# undef optarg
# undef opterr
# undef optind
# undef optopt
# define __GETOPT_CONCAT(x, y) x ## y
# define __GETOPT_XCONCAT(x, y) __GETOPT_CONCAT (x, y)
# define __GETOPT_ID(y) __GETOPT_XCONCAT (__GETOPT_PREFIX, y)
# define getopt __GETOPT_ID (getopt)
# define getopt_long __GETOPT_ID (getopt_long)
# define getopt_long_only __GETOPT_ID (getopt_long_only)
# define optarg __GETOPT_ID (optarg)
# define opterr __GETOPT_ID (opterr)
# define optind __GETOPT_ID (optind)
# define optopt __GETOPT_ID (optopt)
#endif

/* Standalone applications get correct prototypes for getopt_long and
   getopt_long_only; they declare "char **argv".  libc uses prototypes
   with "char *const *argv" that are incorrect because getopt_long and
   getopt_long_only can permute argv; this is required for backward
   compatibility (e.g., for LSB 2.0.1).

   This used to be `#if defined __GETOPT_PREFIX && !defined __need_getopt',
   but it caused redefinition warnings if both unistd.h and getopt.h were
   included, since unistd.h includes getopt.h having previously defined
   __need_getopt.

   The only place where __getopt_argv_const is used is in definitions
   of getopt_long and getopt_long_only below, but these are visible
   only if __need_getopt is not defined, so it is quite safe to rewrite
   the conditional as follows:
*/
#if !defined __need_getopt
# if defined __GETOPT_PREFIX
#  define __getopt_argv_const /* empty */
# else
#  define __getopt_argv_const const
# endif
#endif

/* If __GNU_LIBRARY__ is not already defined, either we are being used
   standalone, or this is the first header included in the source file.
   If we are being used with glibc, we need to include <features.h>, but
   that does not exist if we are standalone.  So: if __GNU_LIBRARY__ is
   not defined, include <ctype.h>, which will pull in <features.h> for us
   if it's from glibc.  (Why ctype.h?  It's guaranteed to exist and it
   doesn't flood the namespace with stuff the way some other headers do.)  */
#if !defined __GNU_LIBRARY__
# include <ctype.h>
#endif

#ifndef __THROW
# ifndef __GNUC_PREREQ
#  define __GNUC_PREREQ(maj, min) (0)
# endif
# if defined __cplusplus && __GNUC_PREREQ (2,8)
#  define __THROW	throw ()
# else
#  define __THROW
# endif
#endif

#ifdef	__cplusplus
extern "C" {
#endif

/* For communication from `getopt' to the caller.
   When `getopt' finds an option that takes an argument,
   the argument value is returned here.
   Also, when `ordering' is RETURN_IN_ORDER,
   each non-option ARGV-element is returned here.  */

extern char *optarg;

/* Index in ARGV of the next element to be scanned.
   This is used for communication to and from the caller
   and for communication between successive calls to `getopt'.

   On entry to `getopt', zero means this is the first call; initialize.

   When `getopt' returns -1, this is the index of the first of the
   non-option elements that the caller should itself scan.

   Otherwise, `optind' communicates from one call to the next
   how much of ARGV has been scanned so far.  */

extern int optind;

/* Callers store zero here to inhibit the error message `getopt' prints
   for unrecognized options.  */

extern int opterr;

/* Set to an option character which was unrecognized.  */

extern int optopt;

#ifndef __need_getopt
/* Describe the long-named options requested by the application.
   The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
   of `struct option' terminated by an element containing a name which is
   zero.

   The field `has_arg' is:
   no_argument		(or 0) if the option does not take an argument,
   required_argument	(or 1) if the option requires an argument,
   optional_argument	(or 2) if the option takes an optional argument.

   If the field `flag' is not NULL, it points to a variable that is set
   to the value given in the field `val' when the option is found, but
   left unchanged if the option is not found.

   To have a long-named option do something other than set an `int' to
   a compiled-in constant, such as set a value from `optarg', set the
   option's `flag' field to zero and its `val' field to a nonzero
   value (the equivalent single-letter option character, if there is
   one).  For long options that have a zero `flag' field, `getopt'
   returns the contents of the `val' field.  */

struct option
{
  const char *name;
  /* has_arg can't be an enum because some compilers complain about
     type mismatches in all the code that assumes it is an int.  */
  int has_arg;
  int *flag;
  int val;
};

/* Names for the values of the `has_arg' field of `struct option'.  */

# define no_argument		0
# define required_argument	1
# define optional_argument	2
#endif	/* need getopt */


/* Get definitions and prototypes for functions to process the
   arguments in ARGV (ARGC of them, minus the program name) for
   options given in OPTS.

   Return the option character from OPTS just read.  Return -1 when
   there are no more options.  For unrecognized options, or options
   missing arguments, `optopt' is set to the option letter, and '?' is
   returned.

   The OPTS string is a list of characters which are recognized option
   letters, optionally followed by colons, specifying that that letter
   takes an argument, to be placed in `optarg'.

   If a letter in OPTS is followed by two colons, its argument is
   optional.  This behavior is specific to the GNU `getopt'.

   The argument `--' causes premature termination of argument
   scanning, explicitly telling `getopt' that there are no more
   options.

   If OPTS begins with `-', then non-option arguments are treated as
   arguments to the option '\1'.  This behavior is specific to the GNU
   `getopt'.  If OPTS begins with `+', or POSIXLY_CORRECT is set in
   the environment, then do not permute arguments.  */

extern int getopt (int ___argc, char *const *___argv, const char *__shortopts)
       __THROW;

#ifndef __need_getopt
extern int getopt_long (int ___argc, char *__getopt_argv_const *___argv,
			const char *__shortopts,
		        const struct option *__longopts, int *__longind)
       __THROW;
extern int getopt_long_only (int ___argc, char *__getopt_argv_const *___argv,
			     const char *__shortopts,
		             const struct option *__longopts, int *__longind)
       __THROW;

#endif

#ifdef	__cplusplus
}
#endif

/* Make sure we later can get all the definitions and declarations.  */
#undef __need_getopt

#endif /* getopt.h */

--- NEW FILE: c-strtod.h ---
double c_strtod (char const *, char **);
long double c_strtold (char const *, char **);

--- NEW FILE: minmax.h ---
/* MIN, MAX macros.
   Copyright (C) 1995, 1998, 2001, 2003, 2005 Free Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

#ifndef _MINMAX_H
#define _MINMAX_H

/* Note: MIN, MAX are also defined in <sys/param.h> on some systems
   (glibc, IRIX, HP-UX, OSF/1).  Therefore you might get warnings about
   MIN, MAX macro redefinitions on some systems; the workaround is to
   #include this file as the last one among the #include list.  */

/* Before we define the following symbols we get the <limits.h> file
   since otherwise we get redefinitions on some systems if <limits.h> is
   included after this file.  Likewise for <sys/param.h>.
   If more than one of these system headers define MIN and MAX, pick just
   one of the headers (because the definitions most likely are the same).  */
#if HAVE_MINMAX_IN_LIMITS_H
# include <limits.h>
#elif HAVE_MINMAX_IN_SYS_PARAM_H
# include <sys/param.h>
#endif

/* Note: MIN and MAX should be used with two arguments of the
   same type.  They might not return the minimum and maximum of their two
   arguments, if the arguments have different types or have unusual
   floating-point values.  For example, on a typical host with 32-bit 'int',
   64-bit 'long long', and 64-bit IEEE 754 'double' types:

     MAX (-1, 2147483648) returns 4294967295.
     MAX (9007199254740992.0, 9007199254740993) returns 9007199254740992.0.
     MAX (NaN, 0.0) returns 0.0.
     MAX (+0.0, -0.0) returns -0.0.

   and in each case the answer is in some sense bogus.  */

/* MAX(a,b) returns the maximum of A and B.  */
#ifndef MAX
# define MAX(a,b) ((a) > (b) ? (a) : (b))
#endif

/* MIN(a,b) returns the minimum of A and B.  */
#ifndef MIN
# define MIN(a,b) ((a) < (b) ? (a) : (b))
#endif

#endif /* _MINMAX_H */

--- NEW FILE: strnlen.c ---
/* Find the length of STRING, but scan at most MAXLEN characters.
   Copyright (C) 2005, 2006 Free Software Foundation, Inc.
   Written by Simon Josefsson.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

#include <config.h>

#include "strnlen.h"

/* Find the length of STRING, but scan at most MAXLEN characters.
   If no '\0' terminator is found in that many characters, return MAXLEN.  */

size_t
strnlen (const char *string, size_t maxlen)
{
  const char *end = memchr (string, '\0', maxlen);
  return end ? (size_t) (end - string) : maxlen;
}

--- NEW FILE: regcomp.c ---
/* Extended regular expression matching and search library.
   Copyright (C) 2002,2003,2004,2005,2006 Free Software Foundation, Inc.
   This file is part of the GNU C Library.
   Contributed by Isamu Hasegawa <isamu at yamato.ibm.com>.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License along
   with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */

[...3819 lines suppressed...]
	{
	  node = node->left;
	  p_new = &dup_node->left;
	}
      else
	{
	  const bin_tree_t *prev = NULL;
	  while (node->right == prev || node->right == NULL)
	    {
	      prev = node;
	      node = node->parent;
	      dup_node = dup_node->parent;
	      if (!node)
	        return dup_root;
	    }
	  node = node->right;
	  p_new = &dup_node->right;
	}
    }
}

--- NEW FILE: alloca.c ---
/* alloca.c -- allocate automatically reclaimed memory
   (Mostly) portable public-domain implementation -- D A Gwyn

   This implementation of the PWB library alloca function,
   which is used to allocate space off the run-time stack so
   that it is automatically reclaimed upon procedure exit,
   was inspired by discussions with J. Q. Johnson of Cornell.
   J.Otto Tennant <jot at cray.com> contributed the Cray support.

   There are some preprocessor constants that can
   be defined when compiling for your specific system, for
   improved efficiency; however, the defaults should be okay.

   The general concept of this implementation is to keep
   track of all alloca-allocated blocks, and reclaim any
   that are found to be deeper in the stack than the current
   invocation.  This heuristic does not reclaim storage as
   soon as it becomes invalid, but it will do so eventually.

   As a special case, alloca(0) reclaims storage without
   allocating any.  It is a good idea to use alloca(0) in
   your main control loop, etc. to force garbage collection.  */

#include <config.h>

#include <alloca.h>

#include <string.h>
#include <stdlib.h>

#ifdef emacs
# include "lisp.h"
# include "blockinput.h"
# ifdef EMACS_FREE
#  undef free
#  define free EMACS_FREE
# endif
#else
# define memory_full() abort ()
#endif

/* If compiling with GCC 2, this file's not needed.  */
#if !defined (__GNUC__) || __GNUC__ < 2

/* If someone has defined alloca as a macro,
   there must be some other way alloca is supposed to work.  */
# ifndef alloca

#  ifdef emacs
#   ifdef static
/* actually, only want this if static is defined as ""
   -- this is for usg, in which emacs must undefine static
   in order to make unexec workable
   */
#    ifndef STACK_DIRECTION
you
lose
-- must know STACK_DIRECTION at compile-time
/* Using #error here is not wise since this file should work for
   old and obscure compilers.  */
#    endif /* STACK_DIRECTION undefined */
#   endif /* static */
#  endif /* emacs */

/* If your stack is a linked list of frames, you have to
   provide an "address metric" ADDRESS_FUNCTION macro.  */

#  if defined (CRAY) && defined (CRAY_STACKSEG_END)
long i00afunc ();
#   define ADDRESS_FUNCTION(arg) (char *) i00afunc (&(arg))
#  else
#   define ADDRESS_FUNCTION(arg) &(arg)
#  endif

/* Define STACK_DIRECTION if you know the direction of stack
   growth for your system; otherwise it will be automatically
   deduced at run-time.

   STACK_DIRECTION > 0 => grows toward higher addresses
   STACK_DIRECTION < 0 => grows toward lower addresses
   STACK_DIRECTION = 0 => direction of growth unknown  */

#  ifndef STACK_DIRECTION
#   define STACK_DIRECTION	0	/* Direction unknown.  */
#  endif

#  if STACK_DIRECTION != 0

#   define STACK_DIR	STACK_DIRECTION	/* Known at compile-time.  */

#  else /* STACK_DIRECTION == 0; need run-time code.  */

static int stack_dir;		/* 1 or -1 once known.  */
#   define STACK_DIR	stack_dir

static void
find_stack_direction (void)
{
  static char *addr = NULL;	/* Address of first `dummy', once known.  */
  auto char dummy;		/* To get stack address.  */

  if (addr == NULL)
    {				/* Initial entry.  */
      addr = ADDRESS_FUNCTION (dummy);

      find_stack_direction ();	/* Recurse once.  */
    }
  else
    {
      /* Second entry.  */
      if (ADDRESS_FUNCTION (dummy) > addr)
	stack_dir = 1;		/* Stack grew upward.  */
      else
	stack_dir = -1;		/* Stack grew downward.  */
    }
}

#  endif /* STACK_DIRECTION == 0 */

/* An "alloca header" is used to:
   (a) chain together all alloca'ed blocks;
   (b) keep track of stack depth.

   It is very important that sizeof(header) agree with malloc
   alignment chunk size.  The following default should work okay.  */

#  ifndef	ALIGN_SIZE
#   define ALIGN_SIZE	sizeof(double)
#  endif

typedef union hdr
{
  char align[ALIGN_SIZE];	/* To force sizeof(header).  */
  struct
    {
      union hdr *next;		/* For chaining headers.  */
      char *deep;		/* For stack depth measure.  */
    } h;
} header;

static header *last_alloca_header = NULL;	/* -> last alloca header.  */

/* Return a pointer to at least SIZE bytes of storage,
   which will be automatically reclaimed upon exit from
   the procedure that called alloca.  Originally, this space
   was supposed to be taken from the current stack frame of the
   caller, but that method cannot be made to work for some
   implementations of C, for example under Gould's UTX/32.  */

void *
alloca (size_t size)
{
  auto char probe;		/* Probes stack depth: */
  register char *depth = ADDRESS_FUNCTION (probe);

#  if STACK_DIRECTION == 0
  if (STACK_DIR == 0)		/* Unknown growth direction.  */
    find_stack_direction ();
#  endif

  /* Reclaim garbage, defined as all alloca'd storage that
     was allocated from deeper in the stack than currently.  */

  {
    register header *hp;	/* Traverses linked list.  */

#  ifdef emacs
    BLOCK_INPUT;
#  endif

    for (hp = last_alloca_header; hp != NULL;)
      if ((STACK_DIR > 0 && hp->h.deep > depth)
	  || (STACK_DIR < 0 && hp->h.deep < depth))
	{
	  register header *np = hp->h.next;

	  free (hp);		/* Collect garbage.  */

	  hp = np;		/* -> next header.  */
	}
      else
	break;			/* Rest are not deeper.  */

    last_alloca_header = hp;	/* -> last valid storage.  */

#  ifdef emacs
    UNBLOCK_INPUT;
#  endif
  }

  if (size == 0)
    return NULL;		/* No allocation required.  */

  /* Allocate combined header + user data storage.  */

  {
    /* Address of header.  */
    register header *new;

    size_t combined_size = sizeof (header) + size;
    if (combined_size < sizeof (header))
      memory_full ();

    new = malloc (combined_size);

    if (! new)
      memory_full ();

    new->h.next = last_alloca_header;
    new->h.deep = depth;

    last_alloca_header = new;

    /* User storage begins just after header.  */

    return (void *) (new + 1);
  }
}

#  if defined (CRAY) && defined (CRAY_STACKSEG_END)

#   ifdef DEBUG_I00AFUNC
#    include <stdio.h>
#   endif

#   ifndef CRAY_STACK
#    define CRAY_STACK
#    ifndef CRAY2
/* Stack structures for CRAY-1, CRAY X-MP, and CRAY Y-MP */
struct stack_control_header
  {
    long shgrow:32;		/* Number of times stack has grown.  */
    long shaseg:32;		/* Size of increments to stack.  */
    long shhwm:32;		/* High water mark of stack.  */
    long shsize:32;		/* Current size of stack (all segments).  */
  };

/* The stack segment linkage control information occurs at
   the high-address end of a stack segment.  (The stack
   grows from low addresses to high addresses.)  The initial
   part of the stack segment linkage control information is
   0200 (octal) words.  This provides for register storage
   for the routine which overflows the stack.  */

struct stack_segment_linkage
  {
    long ss[0200];		/* 0200 overflow words.  */
    long sssize:32;		/* Number of words in this segment.  */
    long ssbase:32;		/* Offset to stack base.  */
    long:32;
    long sspseg:32;		/* Offset to linkage control of previous
				   segment of stack.  */
    long:32;
    long sstcpt:32;		/* Pointer to task common address block.  */
    long sscsnm;		/* Private control structure number for
				   microtasking.  */
    long ssusr1;		/* Reserved for user.  */
    long ssusr2;		/* Reserved for user.  */
    long sstpid;		/* Process ID for pid based multi-tasking.  */
    long ssgvup;		/* Pointer to multitasking thread giveup.  */
    long sscray[7];		/* Reserved for Cray Research.  */
    long ssa0;
    long ssa1;
    long ssa2;
    long ssa3;
    long ssa4;
    long ssa5;
    long ssa6;
    long ssa7;
    long sss0;
    long sss1;
    long sss2;
    long sss3;
    long sss4;
    long sss5;
    long sss6;
    long sss7;
  };

#    else /* CRAY2 */
/* The following structure defines the vector of words
   returned by the STKSTAT library routine.  */
struct stk_stat
  {
    long now;			/* Current total stack size.  */
    long maxc;			/* Amount of contiguous space which would
				   be required to satisfy the maximum
				   stack demand to date.  */
    long high_water;		/* Stack high-water mark.  */
    long overflows;		/* Number of stack overflow ($STKOFEN) calls.  */
    long hits;			/* Number of internal buffer hits.  */
    long extends;		/* Number of block extensions.  */
    long stko_mallocs;		/* Block allocations by $STKOFEN.  */
    long underflows;		/* Number of stack underflow calls ($STKRETN).  */
    long stko_free;		/* Number of deallocations by $STKRETN.  */
    long stkm_free;		/* Number of deallocations by $STKMRET.  */
    long segments;		/* Current number of stack segments.  */
    long maxs;			/* Maximum number of stack segments so far.  */
    long pad_size;		/* Stack pad size.  */
    long current_address;	/* Current stack segment address.  */
    long current_size;		/* Current stack segment size.  This
				   number is actually corrupted by STKSTAT to
				   include the fifteen word trailer area.  */
    long initial_address;	/* Address of initial segment.  */
    long initial_size;		/* Size of initial segment.  */
  };

/* The following structure describes the data structure which trails
   any stack segment.  I think that the description in 'asdef' is
   out of date.  I only describe the parts that I am sure about.  */

struct stk_trailer
  {
    long this_address;		/* Address of this block.  */
    long this_size;		/* Size of this block (does not include
				   this trailer).  */
    long unknown2;
    long unknown3;
    long link;			/* Address of trailer block of previous
				   segment.  */
    long unknown5;
    long unknown6;
    long unknown7;
    long unknown8;
    long unknown9;
    long unknown10;
    long unknown11;
    long unknown12;
    long unknown13;
    long unknown14;
  };

#    endif /* CRAY2 */
#   endif /* not CRAY_STACK */

#   ifdef CRAY2
/* Determine a "stack measure" for an arbitrary ADDRESS.
   I doubt that "lint" will like this much.  */

static long
i00afunc (long *address)
{
  struct stk_stat status;
  struct stk_trailer *trailer;
  long *block, size;
  long result = 0;

  /* We want to iterate through all of the segments.  The first
     step is to get the stack status structure.  We could do this
     more quickly and more directly, perhaps, by referencing the
     $LM00 common block, but I know that this works.  */

  STKSTAT (&status);

  /* Set up the iteration.  */

  trailer = (struct stk_trailer *) (status.current_address
				    + status.current_size
				    - 15);

  /* There must be at least one stack segment.  Therefore it is
     a fatal error if "trailer" is null.  */

  if (trailer == 0)
    abort ();

  /* Discard segments that do not contain our argument address.  */

  while (trailer != 0)
    {
      block = (long *) trailer->this_address;
      size = trailer->this_size;
      if (block == 0 || size == 0)
	abort ();
      trailer = (struct stk_trailer *) trailer->link;
      if ((block <= address) && (address < (block + size)))
	break;
    }

  /* Set the result to the offset in this segment and add the sizes
     of all predecessor segments.  */

  result = address - block;

  if (trailer == 0)
    {
      return result;
    }

  do
    {
      if (trailer->this_size <= 0)
	abort ();
      result += trailer->this_size;
      trailer = (struct stk_trailer *) trailer->link;
    }
  while (trailer != 0);

  /* We are done.  Note that if you present a bogus address (one
     not in any segment), you will get a different number back, formed
     from subtracting the address of the first block.  This is probably
     not what you want.  */

  return (result);
}

#   else /* not CRAY2 */
/* Stack address function for a CRAY-1, CRAY X-MP, or CRAY Y-MP.
   Determine the number of the cell within the stack,
   given the address of the cell.  The purpose of this
   routine is to linearize, in some sense, stack addresses
   for alloca.  */

static long
i00afunc (long address)
{
  long stkl = 0;

  long size, pseg, this_segment, stack;
  long result = 0;

  struct stack_segment_linkage *ssptr;

  /* Register B67 contains the address of the end of the
     current stack segment.  If you (as a subprogram) store
     your registers on the stack and find that you are past
     the contents of B67, you have overflowed the segment.

     B67 also points to the stack segment linkage control
     area, which is what we are really interested in.  */

  stkl = CRAY_STACKSEG_END ();
  ssptr = (struct stack_segment_linkage *) stkl;

  /* If one subtracts 'size' from the end of the segment,
     one has the address of the first word of the segment.

     If this is not the first segment, 'pseg' will be
     nonzero.  */

  pseg = ssptr->sspseg;
  size = ssptr->sssize;

  this_segment = stkl - size;

  /* It is possible that calling this routine itself caused
     a stack overflow.  Discard stack segments which do not
     contain the target address.  */

  while (!(this_segment <= address && address <= stkl))
    {
#    ifdef DEBUG_I00AFUNC
      fprintf (stderr, "%011o %011o %011o\n", this_segment, address, stkl);
#    endif
      if (pseg == 0)
	break;
      stkl = stkl - pseg;
      ssptr = (struct stack_segment_linkage *) stkl;
      size = ssptr->sssize;
      pseg = ssptr->sspseg;
      this_segment = stkl - size;
    }

  result = address - this_segment;

  /* If you subtract pseg from the current end of the stack,
     you get the address of the previous stack segment's end.
     This seems a little convoluted to me, but I'll bet you save
     a cycle somewhere.  */

  while (pseg != 0)
    {
#    ifdef DEBUG_I00AFUNC
      fprintf (stderr, "%011o %011o\n", pseg, size);
#    endif
      stkl = stkl - pseg;
      ssptr = (struct stack_segment_linkage *) stkl;
      size = ssptr->sssize;
      pseg = ssptr->sspseg;
      result += size;
    }
  return (result);
}

#   endif /* not CRAY2 */
#  endif /* CRAY */

# endif /* no alloca */
#endif /* not GCC version 2 */

--- NEW FILE: size_max.h ---
/* size_max.h -- declare SIZE_MAX through system headers
   Copyright (C) 2005-2006 Free Software Foundation, Inc.
   Written by Simon Josefsson.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

#ifndef GNULIB_SIZE_MAX_H
#define GNULIB_SIZE_MAX_H

/* Get SIZE_MAX declaration on systems like Solaris 7/8/9.  */
# include <limits.h>
/* Get SIZE_MAX declaration on systems like glibc 2.  */
# if HAVE_STDINT_H
#  include <stdint.h>
# endif
/* On systems where these include files don't define it, SIZE_MAX is defined
   in config.h.  */

#endif /* GNULIB_SIZE_MAX_H */

--- NEW FILE: fsusage.h ---
/* fsusage.h -- declarations for file system space usage info

   Copyright (C) 1991, 1992, 1997, 2003, 2004, 2005, 2006 Free Software
   Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

/* Space usage statistics for a file system.  Blocks are 512-byte. */

#if !defined FSUSAGE_H_
# define FSUSAGE_H_

# include <stdint.h>
# include <stdbool.h>

struct fs_usage
{
  uintmax_t fsu_blocksize;	/* Size of a block.  */
  uintmax_t fsu_blocks;		/* Total blocks. */
  uintmax_t fsu_bfree;		/* Free blocks available to superuser. */
  uintmax_t fsu_bavail;		/* Free blocks available to non-superuser. */
  bool fsu_bavail_top_bit_set;	/* 1 if fsu_bavail represents a value < 0.  */
  uintmax_t fsu_files;		/* Total file nodes. */
  uintmax_t fsu_ffree;		/* Free file nodes. */
};

int get_fs_usage (char const *file, char const *disk, struct fs_usage *fsp);

#endif

--- NEW FILE: unistd-safer.h ---
/* Invoke unistd-like functions, but avoid some glitches.

   Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

/* Written by Paul Eggert.  */

int dup_safer (int);
int fd_safer (int);
int pipe_safer (int[2]);

--- NEW FILE: fsusage.c ---
/* fsusage.c -- return space usage of mounted file systems

   Copyright (C) 1991, 1992, 1996, 1998, 1999, 2002, 2003, 2004, 2005, 2006
   Free Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

#include <config.h>

#include "fsusage.h"

#include <limits.h>
#include <sys/types.h>

#if STAT_STATVFS		/* POSIX 1003.1-2001 (and later) with XSI */
# include <sys/statvfs.h>
#else
/* Don't include backward-compatibility files unless they're needed.
   Eventually we'd like to remove all this cruft.  */
# include <fcntl.h>
# include <unistd.h>
# include <sys/stat.h>
# if HAVE_SYS_PARAM_H
#  include <sys/param.h>
# endif
# if HAVE_SYS_MOUNT_H
#  include <sys/mount.h>
# endif
# if HAVE_SYS_VFS_H
#  include <sys/vfs.h>
# endif
# if HAVE_SYS_FS_S5PARAM_H	/* Fujitsu UXP/V */
#  include <sys/fs/s5param.h>
# endif
# if defined HAVE_SYS_FILSYS_H && !defined _CRAY
#  include <sys/filsys.h>	/* SVR2 */
# endif
# if HAVE_SYS_STATFS_H
#  include <sys/statfs.h>
# endif
# if HAVE_DUSTAT_H		/* AIX PS/2 */
#  include <sys/dustat.h>
# endif
# include "full-read.h"
#endif

/* The results of open() in this file are not used with fchdir,
   therefore save some unnecessary work in fchdir.c.  */
#undef open
#undef close

/* Many space usage primitives use all 1 bits to denote a value that is
   not applicable or unknown.  Propagate this information by returning
   a uintmax_t value that is all 1 bits if X is all 1 bits, even if X
   is unsigned and narrower than uintmax_t.  */
#define PROPAGATE_ALL_ONES(x) \
  ((sizeof (x) < sizeof (uintmax_t) \
    && (~ (x) == (sizeof (x) < sizeof (int) \
		  ? - (1 << (sizeof (x) * CHAR_BIT)) \
		  : 0))) \
   ? UINTMAX_MAX : (uintmax_t) (x))

/* Extract the top bit of X as an uintmax_t value.  */
#define EXTRACT_TOP_BIT(x) ((x) \
			    & ((uintmax_t) 1 << (sizeof (x) * CHAR_BIT - 1)))

/* If a value is negative, many space usage primitives store it into an
   integer variable by assignment, even if the variable's type is unsigned.
   So, if a space usage variable X's top bit is set, convert X to the
   uintmax_t value V such that (- (uintmax_t) V) is the negative of
   the original value.  If X's top bit is clear, just yield X.
   Use PROPAGATE_TOP_BIT if the original value might be negative;
   otherwise, use PROPAGATE_ALL_ONES.  */
#define PROPAGATE_TOP_BIT(x) ((x) | ~ (EXTRACT_TOP_BIT (x) - 1))

/* Fill in the fields of FSP with information about space usage for
   the file system on which FILE resides.
   DISK is the device on which FILE is mounted, for space-getting
   methods that need to know it.
   Return 0 if successful, -1 if not.  When returning -1, ensure that
   ERRNO is either a system error value, or zero if DISK is NULL
   on a system that requires a non-NULL value.  */
int
get_fs_usage (char const *file, char const *disk, struct fs_usage *fsp)
{
#if defined STAT_STATVFS		/* POSIX */

  struct statvfs fsd;

  if (statvfs (file, &fsd) < 0)
    return -1;

  /* f_frsize isn't guaranteed to be supported.  */
  fsp->fsu_blocksize = (fsd.f_frsize
			? PROPAGATE_ALL_ONES (fsd.f_frsize)
			: PROPAGATE_ALL_ONES (fsd.f_bsize));

#elif defined STAT_STATFS2_FS_DATA	/* Ultrix */

  struct fs_data fsd;

  if (statfs (file, &fsd) != 1)
    return -1;

  fsp->fsu_blocksize = 1024;
  fsp->fsu_blocks = PROPAGATE_ALL_ONES (fsd.fd_req.btot);
  fsp->fsu_bfree = PROPAGATE_ALL_ONES (fsd.fd_req.bfree);
  fsp->fsu_bavail = PROPAGATE_TOP_BIT (fsd.fd_req.bfreen);
  fsp->fsu_bavail_top_bit_set = EXTRACT_TOP_BIT (fsd.fd_req.bfreen) != 0;
  fsp->fsu_files = PROPAGATE_ALL_ONES (fsd.fd_req.gtot);
  fsp->fsu_ffree = PROPAGATE_ALL_ONES (fsd.fd_req.gfree);

#elif defined STAT_READ_FILSYS		/* SVR2 */
# ifndef SUPERBOFF
#  define SUPERBOFF (SUPERB * 512)
# endif

  struct filsys fsd;
  int fd;

  if (! disk)
    {
      errno = 0;
      return -1;
    }

  fd = open (disk, O_RDONLY);
  if (fd < 0)
    return -1;
  lseek (fd, (off_t) SUPERBOFF, 0);
  if (full_read (fd, (char *) &fsd, sizeof fsd) != sizeof fsd)
    {
      close (fd);
      return -1;
    }
  close (fd);

  fsp->fsu_blocksize = (fsd.s_type == Fs2b ? 1024 : 512);
  fsp->fsu_blocks = PROPAGATE_ALL_ONES (fsd.s_fsize);
  fsp->fsu_bfree = PROPAGATE_ALL_ONES (fsd.s_tfree);
  fsp->fsu_bavail = PROPAGATE_TOP_BIT (fsd.s_tfree);
  fsp->fsu_bavail_top_bit_set = EXTRACT_TOP_BIT (fsd.s_tfree) != 0;
  fsp->fsu_files = (fsd.s_isize == -1
		    ? UINTMAX_MAX
		    : (fsd.s_isize - 2) * INOPB * (fsd.s_type == Fs2b ? 2 : 1));
  fsp->fsu_ffree = PROPAGATE_ALL_ONES (fsd.s_tinode);

#elif defined STAT_STATFS3_OSF1

  struct statfs fsd;

  if (statfs (file, &fsd, sizeof (struct statfs)) != 0)
    return -1;

  fsp->fsu_blocksize = PROPAGATE_ALL_ONES (fsd.f_fsize);

#elif defined STAT_STATFS2_BSIZE	/* 4.3BSD, SunOS 4, HP-UX, AIX */

  struct statfs fsd;

  if (statfs (file, &fsd) < 0)
    return -1;

  fsp->fsu_blocksize = PROPAGATE_ALL_ONES (fsd.f_bsize);

# ifdef STATFS_TRUNCATES_BLOCK_COUNTS

  /* In SunOS 4.1.2, 4.1.3, and 4.1.3_U1, the block counts in the
     struct statfs are truncated to 2GB.  These conditions detect that
     truncation, presumably without botching the 4.1.1 case, in which
     the values are not truncated.  The correct counts are stored in
     undocumented spare fields.  */
  if (fsd.f_blocks == 0x7fffffff / fsd.f_bsize && fsd.f_spare[0] > 0)
    {
      fsd.f_blocks = fsd.f_spare[0];
      fsd.f_bfree = fsd.f_spare[1];
      fsd.f_bavail = fsd.f_spare[2];
    }
# endif /* STATFS_TRUNCATES_BLOCK_COUNTS */

#elif defined STAT_STATFS2_FSIZE	/* 4.4BSD */

  struct statfs fsd;

  if (statfs (file, &fsd) < 0)
    return -1;

  fsp->fsu_blocksize = PROPAGATE_ALL_ONES (fsd.f_fsize);

#elif defined STAT_STATFS4		/* SVR3, Dynix, Irix, AIX */

# if !_AIX && !defined _SEQUENT_ && !defined DOLPHIN
#  define f_bavail f_bfree
# endif

  struct statfs fsd;

  if (statfs (file, &fsd, sizeof fsd, 0) < 0)
    return -1;

  /* Empirically, the block counts on most SVR3 and SVR3-derived
     systems seem to always be in terms of 512-byte blocks,
     no matter what value f_bsize has.  */
# if _AIX || defined _CRAY
   fsp->fsu_blocksize = PROPAGATE_ALL_ONES (fsd.f_bsize);
# else
   fsp->fsu_blocksize = 512;
# endif

#endif

#if (defined STAT_STATVFS \
     || (!defined STAT_STATFS2_FS_DATA && !defined STAT_READ_FILSYS))

  fsp->fsu_blocks = PROPAGATE_ALL_ONES (fsd.f_blocks);
  fsp->fsu_bfree = PROPAGATE_ALL_ONES (fsd.f_bfree);
  fsp->fsu_bavail = PROPAGATE_TOP_BIT (fsd.f_bavail);
  fsp->fsu_bavail_top_bit_set = EXTRACT_TOP_BIT (fsd.f_bavail) != 0;
  fsp->fsu_files = PROPAGATE_ALL_ONES (fsd.f_files);
  fsp->fsu_ffree = PROPAGATE_ALL_ONES (fsd.f_ffree);

#endif

  return 0;
}

#if defined _AIX && defined _I386
/* AIX PS/2 does not supply statfs.  */

int
statfs (char *file, struct statfs *fsb)
{
  struct stat stats;
  struct dustat fsd;

  if (stat (file, &stats) != 0)
    return -1;
  if (dustat (stats.st_dev, 0, &fsd, sizeof (fsd)))
    return -1;
  fsb->f_type   = 0;
  fsb->f_bsize  = fsd.du_bsize;
  fsb->f_blocks = fsd.du_fsize - fsd.du_isize;
  fsb->f_bfree  = fsd.du_tfree;
  fsb->f_bavail = fsd.du_tfree;
  fsb->f_files  = (fsd.du_isize - 2) * fsd.du_inopb;
  fsb->f_ffree  = fsd.du_tinode;
  fsb->f_fsid.val[0] = fsd.du_site;
  fsb->f_fsid.val[1] = fsd.du_pckno;
  return 0;
}

#endif /* _AIX && _I386 */

--- NEW FILE: getaddrinfo.c ---
/* Get address information (partial implementation).
   Copyright (C) 1997, 2001, 2002, 2004, 2005, 2006 Free Software
   Foundation, Inc.
   Contributed by Simon Josefsson <simon at josefsson.org>.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

#include <config.h>

#include "getaddrinfo.h"

#if HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif

/* Get calloc. */
#include <stdlib.h>

/* Get memcpy. */
#include <string.h>

#include <stdbool.h>

#include "gettext.h"
#define _(String) gettext (String)
#define N_(String) String

#include "inet_ntop.h"
#include "snprintf.h"
#include "strdup.h"

/* BeOS has AF_INET, but not PF_INET.  */
#ifndef PF_INET
# define PF_INET AF_INET
#endif
/* BeOS also lacks PF_UNSPEC.  */
#ifndef PF_UNSPEC
# define PF_UNSPEC 0
#endif

#if defined _WIN32 || defined __WIN32__
# define WIN32_NATIVE
#endif

#ifdef WIN32_NATIVE
typedef int (WSAAPI *getaddrinfo_func) (const char*, const char*,
					const struct addrinfo*,
					struct addrinfo**);
typedef void (WSAAPI *freeaddrinfo_func) (struct addrinfo*);
typedef int (WSAAPI *getnameinfo_func) (const struct sockaddr*,
					socklen_t, char*, DWORD,
					char*, DWORD, int);

static getaddrinfo_func getaddrinfo_ptr = NULL;
static freeaddrinfo_func freeaddrinfo_ptr = NULL;
static getnameinfo_func getnameinfo_ptr = NULL;

static int
use_win32_p (void)
{
  static int done = 0;
  HMODULE h;

  if (done)
    return getaddrinfo_ptr ? 1 : 0;

  done = 1;

  h = GetModuleHandle ("ws2_32.dll");

  if (h)
    {
      getaddrinfo_ptr = (getaddrinfo_func) GetProcAddress (h, "getaddrinfo");
      freeaddrinfo_ptr = (freeaddrinfo_func) GetProcAddress (h, "freeaddrinfo");
      getnameinfo_ptr = (getnameinfo_func) GetProcAddress (h, "getnameinfo");
    }

  /* If either is missing, something is odd. */
  if (!getaddrinfo_ptr || !freeaddrinfo_ptr || !getnameinfo_ptr)
    {
      getaddrinfo_ptr = NULL;
      freeaddrinfo_ptr = NULL;
      getnameinfo_ptr = NULL;
      return 0;
    }

  return 1;
}
#endif

static inline bool
validate_family (int family)
{
  /* FIXME: Support more families. */
#if HAVE_IPV4
     if (family == PF_INET)
       return true;
#endif
#if HAVE_IPV6
     if (family == PF_INET6)
       return true;
#endif
     if (family == PF_UNSPEC)
       return true;
     return false;
}

/* Translate name of a service location and/or a service name to set of
   socket addresses. */
int
getaddrinfo (const char *restrict nodename,
	     const char *restrict servname,
	     const struct addrinfo *restrict hints,
	     struct addrinfo **restrict res)
{
  struct addrinfo *tmp;
  int port = 0;
  struct hostent *he;
  void *storage;
  size_t size;
#if HAVE_IPV6
  struct v6_pair {
    struct addrinfo addrinfo;
    struct sockaddr_in6 sockaddr_in6;
  };
#endif
#if HAVE_IPV4
  struct v4_pair {
    struct addrinfo addrinfo;
    struct sockaddr_in sockaddr_in;
  };
#endif

#ifdef WIN32_NATIVE
  if (use_win32_p ())
    return getaddrinfo_ptr (nodename, servname, hints, res);
#endif

  if (hints && (hints->ai_flags & ~(AI_CANONNAME|AI_PASSIVE)))
    /* FIXME: Support more flags. */
    return EAI_BADFLAGS;

  if (hints && !validate_family (hints->ai_family))
    return EAI_FAMILY;

  if (hints &&
      hints->ai_socktype != SOCK_STREAM && hints->ai_socktype != SOCK_DGRAM)
    /* FIXME: Support other socktype. */
    return EAI_SOCKTYPE; /* FIXME: Better return code? */

  if (!nodename)
    {
      if (!(hints->ai_flags & AI_PASSIVE))
	return EAI_NONAME;

#ifdef HAVE_IPV6
      nodename = (hints->ai_family == AF_INET6) ? "::" : "0.0.0.0";
#else
      nodename = "0.0.0.0";
#endif
    }

  if (servname)
    {
      struct servent *se = NULL;
      const char *proto =
	(hints && hints->ai_socktype == SOCK_DGRAM) ? "udp" : "tcp";

      if (!(hints->ai_flags & AI_NUMERICSERV))
	/* FIXME: Use getservbyname_r if available. */
	se = getservbyname (servname, proto);

      if (!se)
	{
	  char *c;
	  if (!(*servname >= '0' && *servname <= '9'))
	    return EAI_NONAME;
	  port = strtoul (servname, &c, 10);
	  if (*c || port > 0xffff)
	    return EAI_NONAME;
	  port = htons (port);
	}
      else
	port = se->s_port;
    }

  /* FIXME: Use gethostbyname_r if available. */
  he = gethostbyname (nodename);
  if (!he || he->h_addr_list[0] == NULL)
    return EAI_NONAME;

  switch (he->h_addrtype)
    {
#if HAVE_IPV6
    case PF_INET6:
      size = sizeof (struct v6_pair);
      break;
#endif

#if HAVE_IPV4
    case PF_INET:
      size = sizeof (struct v4_pair);
      break;
#endif

    default:
      return EAI_NODATA;
    }

  storage = calloc (1, size);
  if (!storage)
    return EAI_MEMORY;

  switch (he->h_addrtype)
    {
#if HAVE_IPV6
    case PF_INET6:
      {
	struct v6_pair *p = storage;
	struct sockaddr_in6 *sinp = &p->sockaddr_in6;
	tmp = &p->addrinfo;

	if (port)
	  sinp->sin6_port = port;

	if (he->h_length != sizeof (sinp->sin6_addr))
	  {
	    free (storage);
	    return EAI_SYSTEM; /* FIXME: Better return code?  Set errno? */
	  }

	memcpy (&sinp->sin6_addr, he->h_addr_list[0], sizeof sinp->sin6_addr);

	tmp->ai_addr = (struct sockaddr *) sinp;
	tmp->ai_addrlen = sizeof *sinp;
      }
      break;
#endif

#if HAVE_IPV4
    case PF_INET:
      {
	struct v4_pair *p = storage;
	struct sockaddr_in *sinp = &p->sockaddr_in;
	tmp = &p->addrinfo;

	if (port)
	  sinp->sin_port = port;

	if (he->h_length != sizeof (sinp->sin_addr))
	  {
	    free (storage);
	    return EAI_SYSTEM; /* FIXME: Better return code?  Set errno? */
	  }

	memcpy (&sinp->sin_addr, he->h_addr_list[0], sizeof sinp->sin_addr);

	tmp->ai_addr = (struct sockaddr *) sinp;
	tmp->ai_addrlen = sizeof *sinp;
      }
      break;
#endif

    default:
      free (storage);
      return EAI_NODATA;
    }

  if (hints && hints->ai_flags & AI_CANONNAME)
    {
      const char *cn;
      if (he->h_name)
	cn = he->h_name;
      else
	cn = nodename;

      tmp->ai_canonname = strdup (cn);
      if (!tmp->ai_canonname)
	{
	  free (storage);
	  return EAI_MEMORY;
	}
    }

  tmp->ai_protocol = (hints) ? hints->ai_protocol : 0;
  tmp->ai_socktype = (hints) ? hints->ai_socktype : 0;
  tmp->ai_addr->sa_family = he->h_addrtype;
  tmp->ai_family = he->h_addrtype;

  /* FIXME: If more than one address, create linked list of addrinfo's. */

  *res = tmp;

  return 0;
}

/* Free `addrinfo' structure AI including associated storage.  */
void
freeaddrinfo (struct addrinfo *ai)
{
#ifdef WIN32_NATIVE
  if (use_win32_p ())
    {
      freeaddrinfo_ptr (ai);
      return;
    }
#endif

  while (ai)
    {
      struct addrinfo *cur;

      cur = ai;
      ai = ai->ai_next;

      if (cur->ai_canonname) free (cur->ai_canonname);
      free (cur);
    }
}

int getnameinfo(const struct sockaddr *restrict sa, socklen_t salen,
		char *restrict node, socklen_t nodelen,
		char *restrict service, socklen_t servicelen,
		int flags)
{
#ifdef WIN32_NATIVE
  if (use_win32_p ())
    return getnameinfo_ptr (sa, salen, node, nodelen,
			    service, servicelen, flags);
#endif

  /* FIXME: Support other flags. */
  if ((node && nodelen > 0 && !(flags & NI_NUMERICHOST)) ||
      (service && servicelen > 0 && !(flags & NI_NUMERICHOST)) ||
      (flags & ~(NI_NUMERICHOST|NI_NUMERICSERV)))
    return EAI_BADFLAGS;

  if (sa == NULL || salen < sizeof (sa->sa_family))
    return EAI_FAMILY;

  switch (sa->sa_family)
    {
#if HAVE_IPV4
    case AF_INET:
      if (salen < sizeof (struct sockaddr_in))
	return EAI_FAMILY;
      break;
#endif
#if HAVE_IPV6
    case AF_INET6:
      if (salen < sizeof (struct sockaddr_in6))
	return EAI_FAMILY;
      break;
#endif
    default:
      return EAI_FAMILY;
    }

  if (node && nodelen > 0 && flags & NI_NUMERICHOST)
    {
      switch (sa->sa_family)
	{
#if HAVE_IPV4
	case AF_INET:
	  if (!inet_ntop (AF_INET,
			  &(((const struct sockaddr_in *) sa)->sin_addr),
			  node, nodelen))
	    return EAI_SYSTEM;
	  break;
#endif

#if HAVE_IPV6
	case AF_INET6:
	  if (!inet_ntop (AF_INET6,
			  &(((const struct sockaddr_in6 *) sa)->sin6_addr),
			  node, nodelen))
	    return EAI_SYSTEM;
	  break;
#endif

	default:
	  return EAI_FAMILY;
	}
    }

  if (service && servicelen > 0 && flags & NI_NUMERICSERV)
    switch (sa->sa_family)
      {
#if HAVE_IPV4
      case AF_INET:
#endif
#if HAVE_IPV6
      case AF_INET6:
#endif
	{
	  unsigned short int port
	    = ntohs (((const struct sockaddr_in *) sa)->sin_port);
	  if (servicelen <= snprintf (service, servicelen, "%u", port))
	    return EAI_OVERFLOW;
	}
	break;
      }

  return 0;
}

--- NEW FILE: vasnprintf.h ---
/* vsprintf with automatic memory allocation.
   Copyright (C) 2002-2004 Free Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License along
   with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

#ifndef _VASNPRINTF_H
#define _VASNPRINTF_H

/* Get va_list.  */
#include <stdarg.h>

/* Get size_t.  */
#include <stddef.h>

#ifndef __attribute__
/* This feature is available in gcc versions 2.5 and later.  */
# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) || __STRICT_ANSI__
#  define __attribute__(Spec) /* empty */
# endif
/* The __-protected variants of `format' and `printf' attributes
   are accepted by gcc versions 2.6.4 (effectively 2.7) and later.  */
# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7)
#  define __format__ format
#  define __printf__ printf
# endif
#endif

#ifdef	__cplusplus
extern "C" {
#endif

/* Write formatted output to a string dynamically allocated with malloc().
   You can pass a preallocated buffer for the result in RESULTBUF and its
   size in *LENGTHP; otherwise you pass RESULTBUF = NULL.
   If successful, return the address of the string (this may be = RESULTBUF
   if no dynamic memory allocation was necessary) and set *LENGTHP to the
   number of resulting bytes, excluding the trailing NUL.  Upon error, set
   errno and return NULL.

   When dynamic memory allocation occurs, the preallocated buffer is left
   alone (with possibly modified contents).  This makes it possible to use
   a statically allocated or stack-allocated buffer, like this:

          char buf[100];
          size_t len = sizeof (buf);
          char *output = vasnprintf (buf, &len, format, args);
          if (output == NULL)
            ... error handling ...;
          else
            {
              ... use the output string ...;
              if (output != buf)
                free (output);
            }
  */
extern char * asnprintf (char *resultbuf, size_t *lengthp, const char *format, ...)
       __attribute__ ((__format__ (__printf__, 3, 4)));
extern char * vasnprintf (char *resultbuf, size_t *lengthp, const char *format, va_list args)
       __attribute__ ((__format__ (__printf__, 3, 0)));

#ifdef	__cplusplus
}
#endif

#endif /* _VASNPRINTF_H */

--- NEW FILE: safe-write.h ---
/* An interface to write() that retries after interrupts.
   Copyright (C) 2002 Free Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

#include <stddef.h>

#define SAFE_WRITE_ERROR ((size_t) -1)

/* Write up to COUNT bytes at BUF to descriptor FD, retrying if interrupted.
   Return the actual number of bytes written, zero for EOF, or SAFE_WRITE_ERROR
   upon error.  */
extern size_t safe_write (int fd, const void *buf, size_t count);

--- NEW FILE: vasnprintf.c ---
/* vsprintf with automatic memory allocation.
   Copyright (C) 1999, 2002-2006 Free Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License along
   with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

/* Tell glibc's <stdio.h> to provide a prototype for snprintf().
   This must come before <config.h> because <config.h> may include
   <features.h>, and once <features.h> has been included, it's too late.  */
#ifndef _GNU_SOURCE
# define _GNU_SOURCE    1
#endif

#include <config.h>
#ifndef IN_LIBINTL
# include <alloca.h>
#endif

/* Specification.  */
#if WIDE_CHAR_VERSION
# include "vasnwprintf.h"
#else
# include "vasnprintf.h"
#endif

#include <stdio.h>	/* snprintf(), sprintf() */
#include <stdlib.h>	/* abort(), malloc(), realloc(), free() */
#include <string.h>	/* memcpy(), strlen() */
#include <errno.h>	/* errno */
#include <limits.h>	/* CHAR_BIT */
#include <float.h>	/* DBL_MAX_EXP, LDBL_MAX_EXP */
#if WIDE_CHAR_VERSION
# include "wprintf-parse.h"
#else
# include "printf-parse.h"
#endif

/* Checked size_t computations.  */
#include "xsize.h"

#ifdef HAVE_WCHAR_T
# ifdef HAVE_WCSLEN
#  define local_wcslen wcslen
# else
   /* Solaris 2.5.1 has wcslen() in a separate library libw.so. To avoid
      a dependency towards this library, here is a local substitute.
      Define this substitute only once, even if this file is included
      twice in the same compilation unit.  */
#  ifndef local_wcslen_defined
#   define local_wcslen_defined 1
static size_t
local_wcslen (const wchar_t *s)
{
  const wchar_t *ptr;

  for (ptr = s; *ptr != (wchar_t) 0; ptr++)
    ;
  return ptr - s;
}
#  endif
# endif
#endif

#if WIDE_CHAR_VERSION
# define VASNPRINTF vasnwprintf
# define CHAR_T wchar_t
# define DIRECTIVE wchar_t_directive
# define DIRECTIVES wchar_t_directives
# define PRINTF_PARSE wprintf_parse
# define USE_SNPRINTF 1
# if HAVE_DECL__SNWPRINTF
   /* On Windows, the function swprintf() has a different signature than
      on Unix; we use the _snwprintf() function instead.  */
#  define SNPRINTF _snwprintf
# else
   /* Unix.  */
#  define SNPRINTF swprintf
# endif
#else
# define VASNPRINTF vasnprintf
# define CHAR_T char
# define DIRECTIVE char_directive
# define DIRECTIVES char_directives
# define PRINTF_PARSE printf_parse
# define USE_SNPRINTF (HAVE_DECL__SNPRINTF || HAVE_SNPRINTF)
# if HAVE_DECL__SNPRINTF
   /* Windows.  */
#  define SNPRINTF _snprintf
# else
   /* Unix.  */
#  define SNPRINTF snprintf
# endif
#endif

CHAR_T *
VASNPRINTF (CHAR_T *resultbuf, size_t *lengthp, const CHAR_T *format, va_list args)
{
  DIRECTIVES d;
  arguments a;

  if (PRINTF_PARSE (format, &d, &a) < 0)
    {
      errno = EINVAL;
      return NULL;
    }

#define CLEANUP() \
  free (d.dir);								\
  if (a.arg)								\
    free (a.arg);

  if (printf_fetchargs (args, &a) < 0)
    {
      CLEANUP ();
      errno = EINVAL;
      return NULL;
    }

  {
    size_t buf_neededlength;
    CHAR_T *buf;
    CHAR_T *buf_malloced;
    const CHAR_T *cp;
    size_t i;
    DIRECTIVE *dp;
    /* Output string accumulator.  */
    CHAR_T *result;
    size_t allocated;
    size_t length;

    /* Allocate a small buffer that will hold a directive passed to
       sprintf or snprintf.  */
    buf_neededlength =
      xsum4 (7, d.max_width_length, d.max_precision_length, 6);
#if HAVE_ALLOCA
    if (buf_neededlength < 4000 / sizeof (CHAR_T))
      {
	buf = (CHAR_T *) alloca (buf_neededlength * sizeof (CHAR_T));
	buf_malloced = NULL;
      }
    else
#endif
      {
	size_t buf_memsize = xtimes (buf_neededlength, sizeof (CHAR_T));
	if (size_overflow_p (buf_memsize))
	  goto out_of_memory_1;
	buf = (CHAR_T *) malloc (buf_memsize);
	if (buf == NULL)
	  goto out_of_memory_1;
	buf_malloced = buf;
      }

    if (resultbuf != NULL)
      {
	result = resultbuf;
	allocated = *lengthp;
      }
    else
      {
	result = NULL;
	allocated = 0;
      }
    length = 0;
    /* Invariants:
       result is either == resultbuf or == NULL or malloc-allocated.
       If length > 0, then result != NULL.  */

    /* Ensures that allocated >= needed.  Aborts through a jump to
       out_of_memory if needed is SIZE_MAX or otherwise too big.  */
#define ENSURE_ALLOCATION(needed) \
    if ((needed) > allocated)						     \
      {									     \
	size_t memory_size;						     \
	CHAR_T *memory;							     \
									     \
	allocated = (allocated > 0 ? xtimes (allocated, 2) : 12);	     \
	if ((needed) > allocated)					     \
	  allocated = (needed);						     \
	memory_size = xtimes (allocated, sizeof (CHAR_T));		     \
	if (size_overflow_p (memory_size))				     \
	  goto out_of_memory;						     \
	if (result == resultbuf || result == NULL)			     \
	  memory = (CHAR_T *) malloc (memory_size);			     \
	else								     \
	  memory = (CHAR_T *) realloc (result, memory_size);		     \
	if (memory == NULL)						     \
	  goto out_of_memory;						     \
	if (result == resultbuf && length > 0)				     \
	  memcpy (memory, result, length * sizeof (CHAR_T));		     \
	result = memory;						     \
      }

    for (cp = format, i = 0, dp = &d.dir[0]; ; cp = dp->dir_end, i++, dp++)
      {
	if (cp != dp->dir_start)
	  {
	    size_t n = dp->dir_start - cp;
	    size_t augmented_length = xsum (length, n);

	    ENSURE_ALLOCATION (augmented_length);
	    memcpy (result + length, cp, n * sizeof (CHAR_T));
	    length = augmented_length;
	  }
	if (i == d.count)
	  break;

	/* Execute a single directive.  */
	if (dp->conversion == '%')
	  {
	    size_t augmented_length;

	    if (!(dp->arg_index == ARG_NONE))
	      abort ();
	    augmented_length = xsum (length, 1);
	    ENSURE_ALLOCATION (augmented_length);
	    result[length] = '%';
	    length = augmented_length;
	  }
	else
	  {
	    if (!(dp->arg_index != ARG_NONE))
	      abort ();

	    if (dp->conversion == 'n')
	      {
		switch (a.arg[dp->arg_index].type)
		  {
		  case TYPE_COUNT_SCHAR_POINTER:
		    *a.arg[dp->arg_index].a.a_count_schar_pointer = length;
		    break;
		  case TYPE_COUNT_SHORT_POINTER:
		    *a.arg[dp->arg_index].a.a_count_short_pointer = length;
		    break;
		  case TYPE_COUNT_INT_POINTER:
		    *a.arg[dp->arg_index].a.a_count_int_pointer = length;
		    break;
		  case TYPE_COUNT_LONGINT_POINTER:
		    *a.arg[dp->arg_index].a.a_count_longint_pointer = length;
		    break;
#ifdef HAVE_LONG_LONG_INT
		  case TYPE_COUNT_LONGLONGINT_POINTER:
		    *a.arg[dp->arg_index].a.a_count_longlongint_pointer = length;
		    break;
#endif
		  default:
		    abort ();
		  }
	      }
	    else
	      {
		arg_type type = a.arg[dp->arg_index].type;
		CHAR_T *p;
		unsigned int prefix_count;
		int prefixes[2];
#if !USE_SNPRINTF
		size_t tmp_length;
		CHAR_T tmpbuf[700];
		CHAR_T *tmp;

		/* Allocate a temporary buffer of sufficient size for calling
		   sprintf.  */
		{
		  size_t width;
		  size_t precision;

		  width = 0;
		  if (dp->width_start != dp->width_end)
		    {
		      if (dp->width_arg_index != ARG_NONE)
			{
			  int arg;

			  if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
			    abort ();
			  arg = a.arg[dp->width_arg_index].a.a_int;
			  width = (arg < 0 ? (unsigned int) (-arg) : arg);
			}
		      else
			{
			  const CHAR_T *digitp = dp->width_start;

			  do
			    width = xsum (xtimes (width, 10), *digitp++ - '0');
			  while (digitp != dp->width_end);
			}
		    }

		  precision = 6;
		  if (dp->precision_start != dp->precision_end)
		    {
		      if (dp->precision_arg_index != ARG_NONE)
			{
			  int arg;

			  if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
			    abort ();
			  arg = a.arg[dp->precision_arg_index].a.a_int;
			  precision = (arg < 0 ? 0 : arg);
			}
		      else
			{
			  const CHAR_T *digitp = dp->precision_start + 1;

			  precision = 0;
			  while (digitp != dp->precision_end)
			    precision = xsum (xtimes (precision, 10), *digitp++ - '0');
			}
		    }

		  switch (dp->conversion)
		    {

		    case 'd': case 'i': case 'u':
# ifdef HAVE_LONG_LONG_INT
		      if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
			tmp_length =
			  (unsigned int) (sizeof (unsigned long long) * CHAR_BIT
					  * 0.30103 /* binary -> decimal */
					 )
			  + 1; /* turn floor into ceil */
		      else
# endif
		      if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
			tmp_length =
			  (unsigned int) (sizeof (unsigned long) * CHAR_BIT
					  * 0.30103 /* binary -> decimal */
					 )
			  + 1; /* turn floor into ceil */
		      else
			tmp_length =
			  (unsigned int) (sizeof (unsigned int) * CHAR_BIT
					  * 0.30103 /* binary -> decimal */
					 )
			  + 1; /* turn floor into ceil */
		      if (tmp_length < precision)
			tmp_length = precision;
		      /* Multiply by 2, as an estimate for FLAG_GROUP.  */
		      tmp_length = xsum (tmp_length, tmp_length);
		      /* Add 1, to account for a leading sign.  */
		      tmp_length = xsum (tmp_length, 1);
		      break;

		    case 'o':
# ifdef HAVE_LONG_LONG_INT
		      if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
			tmp_length =
			  (unsigned int) (sizeof (unsigned long long) * CHAR_BIT
					  * 0.333334 /* binary -> octal */
					 )
			  + 1; /* turn floor into ceil */
		      else
# endif
		      if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
			tmp_length =
			  (unsigned int) (sizeof (unsigned long) * CHAR_BIT
					  * 0.333334 /* binary -> octal */
					 )
			  + 1; /* turn floor into ceil */
		      else
			tmp_length =
			  (unsigned int) (sizeof (unsigned int) * CHAR_BIT
					  * 0.333334 /* binary -> octal */
					 )
			  + 1; /* turn floor into ceil */
		      if (tmp_length < precision)
			tmp_length = precision;
		      /* Add 1, to account for a leading sign.  */
		      tmp_length = xsum (tmp_length, 1);
		      break;

		    case 'x': case 'X':
# ifdef HAVE_LONG_LONG_INT
		      if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
			tmp_length =
			  (unsigned int) (sizeof (unsigned long long) * CHAR_BIT
					  * 0.25 /* binary -> hexadecimal */
					 )
			  + 1; /* turn floor into ceil */
		      else
# endif
		      if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
			tmp_length =
			  (unsigned int) (sizeof (unsigned long) * CHAR_BIT
					  * 0.25 /* binary -> hexadecimal */
					 )
			  + 1; /* turn floor into ceil */
		      else
			tmp_length =
			  (unsigned int) (sizeof (unsigned int) * CHAR_BIT
					  * 0.25 /* binary -> hexadecimal */
					 )
			  + 1; /* turn floor into ceil */
		      if (tmp_length < precision)
			tmp_length = precision;
		      /* Add 2, to account for a leading sign or alternate form.  */
		      tmp_length = xsum (tmp_length, 2);
		      break;

		    case 'f': case 'F':
# ifdef HAVE_LONG_DOUBLE
		      if (type == TYPE_LONGDOUBLE)
			tmp_length =
			  (unsigned int) (LDBL_MAX_EXP
					  * 0.30103 /* binary -> decimal */
					  * 2 /* estimate for FLAG_GROUP */
					 )
			  + 1 /* turn floor into ceil */
			  + 10; /* sign, decimal point etc. */
		      else
# endif
			tmp_length =
			  (unsigned int) (DBL_MAX_EXP
					  * 0.30103 /* binary -> decimal */
					  * 2 /* estimate for FLAG_GROUP */
					 )
			  + 1 /* turn floor into ceil */
			  + 10; /* sign, decimal point etc. */
		      tmp_length = xsum (tmp_length, precision);
		      break;

		    case 'e': case 'E': case 'g': case 'G':
		    case 'a': case 'A':
		      tmp_length =
			12; /* sign, decimal point, exponent etc. */
		      tmp_length = xsum (tmp_length, precision);
		      break;

		    case 'c':
# if defined HAVE_WINT_T && !WIDE_CHAR_VERSION
		      if (type == TYPE_WIDE_CHAR)
			tmp_length = MB_CUR_MAX;
		      else
# endif
			tmp_length = 1;
		      break;

		    case 's':
# ifdef HAVE_WCHAR_T
		      if (type == TYPE_WIDE_STRING)
			{
			  tmp_length =
			    local_wcslen (a.arg[dp->arg_index].a.a_wide_string);

#  if !WIDE_CHAR_VERSION
			  tmp_length = xtimes (tmp_length, MB_CUR_MAX);
#  endif
			}
		      else
# endif
			tmp_length = strlen (a.arg[dp->arg_index].a.a_string);
		      break;

		    case 'p':
		      tmp_length =
			(unsigned int) (sizeof (void *) * CHAR_BIT
					* 0.25 /* binary -> hexadecimal */
				       )
			  + 1 /* turn floor into ceil */
			  + 2; /* account for leading 0x */
		      break;

		    default:
		      abort ();
		    }

		  if (tmp_length < width)
		    tmp_length = width;

		  tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */
		}

		if (tmp_length <= sizeof (tmpbuf) / sizeof (CHAR_T))
		  tmp = tmpbuf;
		else
		  {
		    size_t tmp_memsize = xtimes (tmp_length, sizeof (CHAR_T));

		    if (size_overflow_p (tmp_memsize))
		      /* Overflow, would lead to out of memory.  */
		      goto out_of_memory;
		    tmp = (CHAR_T *) malloc (tmp_memsize);
		    if (tmp == NULL)
		      /* Out of memory.  */
		      goto out_of_memory;
		  }
#endif

		/* Construct the format string for calling snprintf or
		   sprintf.  */
		p = buf;
		*p++ = '%';
		if (dp->flags & FLAG_GROUP)
		  *p++ = '\'';
		if (dp->flags & FLAG_LEFT)
		  *p++ = '-';
		if (dp->flags & FLAG_SHOWSIGN)
		  *p++ = '+';
		if (dp->flags & FLAG_SPACE)
		  *p++ = ' ';
		if (dp->flags & FLAG_ALT)
		  *p++ = '#';
		if (dp->flags & FLAG_ZERO)
		  *p++ = '0';
		if (dp->width_start != dp->width_end)
		  {
		    size_t n = dp->width_end - dp->width_start;
		    memcpy (p, dp->width_start, n * sizeof (CHAR_T));
		    p += n;
		  }
		if (dp->precision_start != dp->precision_end)
		  {
		    size_t n = dp->precision_end - dp->precision_start;
		    memcpy (p, dp->precision_start, n * sizeof (CHAR_T));
		    p += n;
		  }

		switch (type)
		  {
#ifdef HAVE_LONG_LONG_INT
		  case TYPE_LONGLONGINT:
		  case TYPE_ULONGLONGINT:
		    *p++ = 'l';
		    /*FALLTHROUGH*/
#endif
		  case TYPE_LONGINT:
		  case TYPE_ULONGINT:
#ifdef HAVE_WINT_T
		  case TYPE_WIDE_CHAR:
#endif
#ifdef HAVE_WCHAR_T
		  case TYPE_WIDE_STRING:
#endif
		    *p++ = 'l';
		    break;
#ifdef HAVE_LONG_DOUBLE
		  case TYPE_LONGDOUBLE:
		    *p++ = 'L';
		    break;
#endif
		  default:
		    break;
		  }
		*p = dp->conversion;
#if USE_SNPRINTF
		p[1] = '%';
		p[2] = 'n';
		p[3] = '\0';
#else
		p[1] = '\0';
#endif

		/* Construct the arguments for calling snprintf or sprintf.  */
		prefix_count = 0;
		if (dp->width_arg_index != ARG_NONE)
		  {
		    if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
		      abort ();
		    prefixes[prefix_count++] = a.arg[dp->width_arg_index].a.a_int;
		  }
		if (dp->precision_arg_index != ARG_NONE)
		  {
		    if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
		      abort ();
		    prefixes[prefix_count++] = a.arg[dp->precision_arg_index].a.a_int;
		  }

#if USE_SNPRINTF
		/* Prepare checking whether snprintf returns the count
		   via %n.  */
		ENSURE_ALLOCATION (xsum (length, 1));
		result[length] = '\0';
#endif

		for (;;)
		  {
		    size_t maxlen;
		    int count;
		    int retcount;

		    maxlen = allocated - length;
		    count = -1;
		    retcount = 0;

#if USE_SNPRINTF
# define SNPRINTF_BUF(arg) \
		    switch (prefix_count)				    \
		      {							    \
		      case 0:						    \
			retcount = SNPRINTF (result + length, maxlen, buf,  \
					     arg, &count);		    \
			break;						    \
		      case 1:						    \
			retcount = SNPRINTF (result + length, maxlen, buf,  \
					     prefixes[0], arg, &count);	    \
			break;						    \
		      case 2:						    \
			retcount = SNPRINTF (result + length, maxlen, buf,  \
					     prefixes[0], prefixes[1], arg, \
					     &count);			    \
			break;						    \
		      default:						    \
			abort ();					    \
		      }
#else
# define SNPRINTF_BUF(arg) \
		    switch (prefix_count)				    \
		      {							    \
		      case 0:						    \
			count = sprintf (tmp, buf, arg);		    \
			break;						    \
		      case 1:						    \
			count = sprintf (tmp, buf, prefixes[0], arg);	    \
			break;						    \
		      case 2:						    \
			count = sprintf (tmp, buf, prefixes[0], prefixes[1],\
					 arg);				    \
			break;						    \
		      default:						    \
			abort ();					    \
		      }
#endif

		    switch (type)
		      {
		      case TYPE_SCHAR:
			{
			  int arg = a.arg[dp->arg_index].a.a_schar;
			  SNPRINTF_BUF (arg);
			}
			break;
		      case TYPE_UCHAR:
			{
			  unsigned int arg = a.arg[dp->arg_index].a.a_uchar;
			  SNPRINTF_BUF (arg);
			}
			break;
		      case TYPE_SHORT:
			{
			  int arg = a.arg[dp->arg_index].a.a_short;
			  SNPRINTF_BUF (arg);
			}
			break;
		      case TYPE_USHORT:
			{
			  unsigned int arg = a.arg[dp->arg_index].a.a_ushort;
			  SNPRINTF_BUF (arg);
			}
			break;
		      case TYPE_INT:
			{
			  int arg = a.arg[dp->arg_index].a.a_int;
			  SNPRINTF_BUF (arg);
			}
			break;
		      case TYPE_UINT:
			{
			  unsigned int arg = a.arg[dp->arg_index].a.a_uint;
			  SNPRINTF_BUF (arg);
			}
			break;
		      case TYPE_LONGINT:
			{
			  long int arg = a.arg[dp->arg_index].a.a_longint;
			  SNPRINTF_BUF (arg);
			}
			break;
		      case TYPE_ULONGINT:
			{
			  unsigned long int arg = a.arg[dp->arg_index].a.a_ulongint;
			  SNPRINTF_BUF (arg);
			}
			break;
#ifdef HAVE_LONG_LONG_INT
		      case TYPE_LONGLONGINT:
			{
			  long long int arg = a.arg[dp->arg_index].a.a_longlongint;
			  SNPRINTF_BUF (arg);
			}
			break;
		      case TYPE_ULONGLONGINT:
			{
			  unsigned long long int arg = a.arg[dp->arg_index].a.a_ulonglongint;
			  SNPRINTF_BUF (arg);
			}
			break;
#endif
		      case TYPE_DOUBLE:
			{
			  double arg = a.arg[dp->arg_index].a.a_double;
			  SNPRINTF_BUF (arg);
			}
			break;
#ifdef HAVE_LONG_DOUBLE
		      case TYPE_LONGDOUBLE:
			{
			  long double arg = a.arg[dp->arg_index].a.a_longdouble;
			  SNPRINTF_BUF (arg);
			}
			break;
#endif
		      case TYPE_CHAR:
			{
			  int arg = a.arg[dp->arg_index].a.a_char;
			  SNPRINTF_BUF (arg);
			}
			break;
#ifdef HAVE_WINT_T
		      case TYPE_WIDE_CHAR:
			{
			  wint_t arg = a.arg[dp->arg_index].a.a_wide_char;
			  SNPRINTF_BUF (arg);
			}
			break;
#endif
		      case TYPE_STRING:
			{
			  const char *arg = a.arg[dp->arg_index].a.a_string;
			  SNPRINTF_BUF (arg);
			}
			break;
#ifdef HAVE_WCHAR_T
		      case TYPE_WIDE_STRING:
			{
			  const wchar_t *arg = a.arg[dp->arg_index].a.a_wide_string;
			  SNPRINTF_BUF (arg);
			}
			break;
#endif
		      case TYPE_POINTER:
			{
			  void *arg = a.arg[dp->arg_index].a.a_pointer;
			  SNPRINTF_BUF (arg);
			}
			break;
		      default:
			abort ();
		      }

#if USE_SNPRINTF
		    /* Portability: Not all implementations of snprintf()
		       are ISO C 99 compliant.  Determine the number of
		       bytes that snprintf() has produced or would have
		       produced.  */
		    if (count >= 0)
		      {
			/* Verify that snprintf() has NUL-terminated its
			   result.  */
			if (count < maxlen && result[length + count] != '\0')
			  abort ();
			/* Portability hack.  */
			if (retcount > count)
			  count = retcount;
		      }
		    else
		      {
			/* snprintf() doesn't understand the '%n'
			   directive.  */
			if (p[1] != '\0')
			  {
			    /* Don't use the '%n' directive; instead, look
			       at the snprintf() return value.  */
			    p[1] = '\0';
			    continue;
			  }
			else
			  {
			    /* Look at the snprintf() return value.  */
			    if (retcount < 0)
			      {
				/* HP-UX 10.20 snprintf() is doubly deficient:
				   It doesn't understand the '%n' directive,
				   *and* it returns -1 (rather than the length
				   that would have been required) when the
				   buffer is too small.  */
				size_t bigger_need =
				  xsum (xtimes (allocated, 2), 12);
				ENSURE_ALLOCATION (bigger_need);
				continue;
			      }
			    else
			      count = retcount;
			  }
		      }
#endif

		    /* Attempt to handle failure.  */
		    if (count < 0)
		      {
			if (!(result == resultbuf || result == NULL))
			  free (result);
			if (buf_malloced != NULL)
			  free (buf_malloced);
			CLEANUP ();
			errno = EINVAL;
			return NULL;
		      }

#if !USE_SNPRINTF
		    if (count >= tmp_length)
		      /* tmp_length was incorrectly calculated - fix the
			 code above!  */
		      abort ();
#endif

		    /* Make room for the result.  */
		    if (count >= maxlen)
		      {
			/* Need at least count bytes.  But allocate
			   proportionally, to avoid looping eternally if
			   snprintf() reports a too small count.  */
			size_t n =
			  xmax (xsum (length, count), xtimes (allocated, 2));

			ENSURE_ALLOCATION (n);
#if USE_SNPRINTF
			continue;
#endif
		      }

#if USE_SNPRINTF
		    /* The snprintf() result did fit.  */
#else
		    /* Append the sprintf() result.  */
		    memcpy (result + length, tmp, count * sizeof (CHAR_T));
		    if (tmp != tmpbuf)
		      free (tmp);
#endif

		    length += count;
		    break;
		  }
	      }
	  }
      }

    /* Add the final NUL.  */
    ENSURE_ALLOCATION (xsum (length, 1));
    result[length] = '\0';

    if (result != resultbuf && length + 1 < allocated)
      {
	/* Shrink the allocated memory if possible.  */
	CHAR_T *memory;

	memory = (CHAR_T *) realloc (result, (length + 1) * sizeof (CHAR_T));
	if (memory != NULL)
	  result = memory;
      }

    if (buf_malloced != NULL)
      free (buf_malloced);
    CLEANUP ();
    *lengthp = length;
    /* Note that we can produce a big string of a length > INT_MAX.  POSIX
       says that snprintf() fails with errno = EOVERFLOW in this case, but
       that's only because snprintf() returns an 'int'.  This function does
       not have this limitation.  */
    return result;

  out_of_memory:
    if (!(result == resultbuf || result == NULL))
      free (result);
    if (buf_malloced != NULL)
      free (buf_malloced);
  out_of_memory_1:
    CLEANUP ();
    errno = ENOMEM;
    return NULL;
  }
}

#undef SNPRINTF
#undef USE_SNPRINTF
#undef PRINTF_PARSE
#undef DIRECTIVES
#undef DIRECTIVE
#undef CHAR_T
#undef VASNPRINTF

--- NEW FILE: getaddrinfo.h ---
/* Get address information.
   Copyright (C) 1996-2002, 2003, 2004, 2005, 2006
                 Free Software Foundation, Inc.
   Contributed by Simon Josefsson <simon at josefsson.org>.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

#ifndef GETADDRINFO_H
#define GETADDRINFO_H

/* sys/socket.h in i386-unknown-freebsd4.10 and
   powerpc-apple-darwin5.5 require sys/types.h, so include it first.
   Then we'll also get 'socklen_t' and 'struct sockaddr' which are
   used below. */
#include <sys/types.h>
/* Get all getaddrinfo related declarations, if available.  */
#include <sys/socket.h>
#ifdef HAVE_NETDB_H
# include <netdb.h>
#endif

#ifndef HAVE_STRUCT_ADDRINFO

/* Structure to contain information about address of a service provider.  */
struct addrinfo
{
  int ai_flags;			/* Input flags.  */
  int ai_family;		/* Protocol family for socket.  */
  int ai_socktype;		/* Socket type.  */
  int ai_protocol;		/* Protocol for socket.  */
  socklen_t ai_addrlen;		/* Length of socket address.  */
  struct sockaddr *ai_addr;	/* Socket address for socket.  */
  char *ai_canonname;		/* Canonical name for service location.  */
  struct addrinfo *ai_next;	/* Pointer to next in list.  */
};
#endif

/* Possible values for `ai_flags' field in `addrinfo' structure.  */
#ifndef AI_PASSIVE
# define AI_PASSIVE	0x0001	/* Socket address is intended for `bind'.  */
#endif
#ifndef AI_CANONNAME
# define AI_CANONNAME	0x0002	/* Request for canonical name.  */
#endif
#ifndef AI_NUMERICSERV
# define AI_NUMERICSERV	0x0400	/* Don't use name resolution.  */
#endif

#if 0
/* The commented out definitions below are not yet implemented in the
   GNULIB getaddrinfo() replacement, so are not yet needed and may, in fact,
   cause conflicts on systems with a getaddrinfo() function which does not
   define them.

   If they are restored, be sure to protect the definitions with #ifndef.  */
#define AI_NUMERICHOST	0x0004	/* Don't use name resolution.  */
#define AI_V4MAPPED	0x0008	/* IPv4 mapped addresses are acceptable.  */
#define AI_ALL		0x0010	/* Return IPv4 mapped and IPv6 addresses.  */
#define AI_ADDRCONFIG	0x0020	/* Use configuration of this host to choose
				   returned address type..  */
#endif /* 0 */

/* Error values for `getaddrinfo' function.  */
#ifndef EAI_BADFLAGS
# define EAI_BADFLAGS	  -1	/* Invalid value for `ai_flags' field.  */
# define EAI_NONAME	  -2	/* NAME or SERVICE is unknown.  */
# define EAI_AGAIN	  -3	/* Temporary failure in name resolution.  */
# define EAI_FAIL	  -4	/* Non-recoverable failure in name res.  */
# define EAI_NODATA	  -5	/* No address associated with NAME.  */
# define EAI_FAMILY	  -6	/* `ai_family' not supported.  */
# define EAI_SOCKTYPE	  -7	/* `ai_socktype' not supported.  */
# define EAI_SERVICE	  -8	/* SERVICE not supported for `ai_socktype'.  */
# define EAI_MEMORY	  -10	/* Memory allocation failure.  */
#endif
#ifndef EAI_OVERFLOW
/* Not defined on mingw32. */
# define EAI_OVERFLOW	  -12	/* Argument buffer overflow.  */
#endif
#ifndef EAI_ADDRFAMILY
/* Not defined on mingw32. */
# define EAI_ADDRFAMILY  -9	/* Address family for NAME not supported.  */
#endif
#ifndef EAI_SYSTEM
/* Not defined on mingw32. */
# define EAI_SYSTEM	  -11	/* System error returned in `errno'.  */
#endif

#ifdef __USE_GNU
# ifndef EAI_INPROGRESS
#  define EAI_INPROGRESS	-100	/* Processing request in progress.  */
#  define EAI_CANCELED		-101	/* Request canceled.  */
#  define EAI_NOTCANCELED	-102	/* Request not canceled.  */
#  define EAI_ALLDONE		-103	/* All requests done.  */
#  define EAI_INTR		-104	/* Interrupted by a signal.  */
#  define EAI_IDN_ENCODE	-105	/* IDN encoding failed.  */
# endif
#endif

#if !HAVE_DECL_GETADDRINFO
/* Translate name of a service location and/or a service name to set of
   socket addresses.
   For more details, see the POSIX:2001 specification
   <http://www.opengroup.org/susv3xsh/getaddrinfo.html>.  */
extern int getaddrinfo (const char *restrict nodename,
			const char *restrict servname,
			const struct addrinfo *restrict hints,
			struct addrinfo **restrict res);
#endif

#if !HAVE_DECL_FREEADDRINFO
/* Free `addrinfo' structure AI including associated storage.
   For more details, see the POSIX:2001 specification
   <http://www.opengroup.org/susv3xsh/getaddrinfo.html>.  */
extern void freeaddrinfo (struct addrinfo *ai);
#endif

#if !HAVE_DECL_GAI_STRERROR
/* Convert error return from getaddrinfo() to a string.
   For more details, see the POSIX:2001 specification
   <http://www.opengroup.org/susv3xsh/gai_strerror.html>.  */
extern const char *gai_strerror (int ecode);
#endif

#if !HAVE_DECL_GETNAMEINFO
/* Convert socket address to printable node and service names.
   For more details, see the POSIX:2001 specification
   <http://www.opengroup.org/susv3xsh/getnameinfo.html>.  */
extern int getnameinfo(const struct sockaddr *restrict sa, socklen_t salen,
		       char *restrict node, socklen_t nodelen,
		       char *restrict service, socklen_t servicelen,
		       int flags);

#endif

/* Possible flags for getnameinfo.  */
#ifndef NI_NUMERICHOST
# define NI_NUMERICHOST 1
#endif
#ifndef NI_NUMERICSERV
# define NI_NUMERICSERV 2
#endif

#endif /* GETADDRINFO_H */

--- NEW FILE: cloexec.c ---
/* closexec.c - set or clear the close-on-exec descriptor flag

   Copyright (C) 1991, 2004, 2005, 2006 Free Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

   The code is taken from glibc/manual/llio.texi  */

#include <config.h>

#include "cloexec.h"

#include <unistd.h>
#include <fcntl.h>

#ifndef FD_CLOEXEC
# define FD_CLOEXEC 1
#endif

/* Set the `FD_CLOEXEC' flag of DESC if VALUE is true,
   or clear the flag if VALUE is false.
   Return 0 on success, or -1 on error with `errno' set. */

int
set_cloexec_flag (int desc, bool value)
{
#if defined F_GETFD && defined F_SETFD

  int flags = fcntl (desc, F_GETFD, 0);

  if (0 <= flags)
    {
      int newflags = (value ? flags | FD_CLOEXEC : flags & ~FD_CLOEXEC);

      if (flags == newflags
	  || fcntl (desc, F_SETFD, newflags) != -1)
	return 0;
    }

  return -1;

#else

  return 0;

#endif
}

--- NEW FILE: safe-write.c ---
/* An interface to write that retries after interrupts.
   Copyright (C) 2002 Free Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

#define SAFE_WRITE
#include "safe-read.c"

--- NEW FILE: dirname.c ---
/* dirname.c -- return all but the last element in a file name

   Copyright (C) 1990, 1998, 2000, 2001, 2003, 2004, 2005, 2006 Free Software
   Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

#include <config.h>

#include "dirname.h"

#include <string.h>
#include "xalloc.h"

/* Return the length of the prefix of FILE that will be used by
   dir_name.  If FILE is in the working directory, this returns zero
   even though `dir_name (FILE)' will return ".".  Works properly even
   if there are trailing slashes (by effectively ignoring them).  */

size_t
dir_len (char const *file)
{
  size_t prefix_length = FILE_SYSTEM_PREFIX_LEN (file);
  size_t length;

  /* Advance prefix_length beyond important leading slashes.  */
  prefix_length += (prefix_length != 0
		    ? (FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE
		       && ISSLASH (file[prefix_length]))
		    : (ISSLASH (file[0])
		       ? ((DOUBLE_SLASH_IS_DISTINCT_ROOT
			   && ISSLASH (file[1]) && ! ISSLASH (file[2])
			   ? 2 : 1))
		       : 0));

  /* Strip the basename and any redundant slashes before it.  */
  for (length = last_component (file) - file;
       prefix_length < length; length--)
    if (! ISSLASH (file[length - 1]))
      break;
  return length;
}


/* In general, we can't use the builtin `dirname' function if available,
   since it has different meanings in different environments.
   In some environments the builtin `dirname' modifies its argument.

   Return the leading directories part of FILE, allocated with xmalloc.
   Works properly even if there are trailing slashes (by effectively
   ignoring them).  Unlike POSIX dirname(), FILE cannot be NULL.

   If lstat (FILE) would succeed, then { chdir (dir_name (FILE));
   lstat (base_name (FILE)); } will access the same file.  Likewise,
   if the sequence { chdir (dir_name (FILE));
   rename (base_name (FILE), "foo"); } succeeds, you have renamed FILE
   to "foo" in the same directory FILE was in.  */

char *
dir_name (char const *file)
{
  size_t length = dir_len (file);
  bool append_dot = (length == 0
		     || (FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE
			 && length == FILE_SYSTEM_PREFIX_LEN (file)
			 && file[2] != '\0' && ! ISSLASH (file[2])));
  char *dir = xmalloc (length + append_dot + 1);
  memcpy (dir, file, length);
  if (append_dot)
    dir[length++] = '.';
  dir[length] = '\0';
  return dir;
}

--- NEW FILE: mountlist.h ---
/* mountlist.h -- declarations for list of mounted file systems

   Copyright (C) 1991, 1992, 1998, 2000, 2001, 2002, 2003, 2004, 2005
   Free Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

#ifndef MOUNTLIST_H_
# define MOUNTLIST_H_

# include <stdbool.h>
# include <sys/types.h>

/* A mount table entry. */
struct mount_entry
{
  char *me_devname;		/* Device node name, including "/dev/". */
  char *me_mountdir;		/* Mount point directory name. */
  char *me_type;		/* "nfs", "4.2", etc. */
  dev_t me_dev;			/* Device number of me_mountdir. */
  unsigned int me_dummy : 1;	/* Nonzero for dummy file systems. */
  unsigned int me_remote : 1;	/* Nonzero for remote fileystems. */
  unsigned int me_type_malloced : 1; /* Nonzero if me_type was malloced. */
  struct mount_entry *me_next;
};

struct mount_entry *read_file_system_list (bool need_fs_type);

#endif

--- NEW FILE: unistd--.h ---
/* Like unistd.h, but redefine some names to avoid glitches.

   Copyright (C) 2005 Free Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

/* Written by Paul Eggert.  */

#include <unistd.h>
#include "unistd-safer.h"

#undef dup
#define dup dup_safer

#undef pipe
#define pipe pipe_safer

--- NEW FILE: wctype_.h ---
/* A substitute for ISO C99 <wctype.h>, for platforms that lack it.

   Copyright (C) 2006, 2007 Free Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

/* Written by Bruno Haible and Paul Eggert.  */

/*
 * ISO C 99 <wctype.h> for platforms that lack it.
 * <http://www.opengroup.org/susv3xbd/wctype.h.html>
 *
 * iswctype, towctrans, towlower, towupper, wctrans, wctype,
 * wctrans_t, and wctype_t are not yet implemented.
 */

#ifndef _GL_WCTYPE_H
#define _GL_WCTYPE_H

#if @HAVE_WINT_T@
/* Solaris 2.5 has a bug: <wchar.h> must be included before <wctype.h>.
   Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
   <wchar.h>.
   BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be
   included before <wchar.h>.  */
# include <stddef.h>
# include <stdio.h>
# include <time.h>
# include <wchar.h>
typedef wint_t __wctype_wint_t;
#else
typedef int __wctype_wint_t;
#endif

/* Include the original <wctype.h> if it exists.
   BeOS 5 has the functions but no <wctype.h>.  */
#if @HAVE_WCTYPE_H@
# include @ABSOLUTE_WCTYPE_H@
#endif

/* FreeBSD 4.4 to 4.11 has <wctype.h> but lacks the functions.
   Assume all 12 functions are implemented the same way, or not at all.  */
#if ! HAVE_ISWCNTRL

/* IRIX 5.3 has macros but no functions, its isw* macros refer to an
   undefined variable _ctmp_ and to <ctype.h> macros like _P, and they
   refer to system functions like _iswctype that are not in the
   standard C library.  Rather than try to get ancient buggy
   implementations like this to work, just disable them.  */
#  undef iswalnum
#  undef iswalpha
#  undef iswblank
#  undef iswcntrl
#  undef iswdigit
#  undef iswgraph
#  undef iswlower
#  undef iswprint
#  undef iswpunct
#  undef iswspace
#  undef iswupper
#  undef iswxdigit

static inline int
iswalnum (__wctype_wint_t wc)
{
  return ((wc >= '0' && wc <= '9')
	  || ((wc & ~0x20) >= 'A' && (wc & ~0x20) <= 'Z'));
}

static inline int
iswalpha (__wctype_wint_t wc)
{
  return (wc & ~0x20) >= 'A' && (wc & ~0x20) <= 'Z';
}

static inline int
iswblank (__wctype_wint_t wc)
{
  return wc == ' ' || wc == '\t';
}

static inline int
iswcntrl (__wctype_wint_t wc)
{
  return (wc & ~0x1f) == 0 || wc == 0x7f;
}

static inline int
iswdigit (__wctype_wint_t wc)
{
  return wc >= '0' && wc <= '9';
}

static inline int
iswgraph (__wctype_wint_t wc)
{
  return wc >= '!' && wc <= '~';
}

static inline int
iswlower (__wctype_wint_t wc)
{
  return wc >= 'a' && wc <= 'z';
}

static inline int
iswprint (__wctype_wint_t wc)
{
  return wc >= ' ' && wc <= '~';
}

static inline int
iswpunct (__wctype_wint_t wc)
{
  return (wc >= '!' && wc <= '~'
	  && !((wc >= '0' && wc <= '9')
	       || ((wc & ~0x20) >= 'A' && (wc & ~0x20) <= 'Z')));
}

static inline int
iswspace (__wctype_wint_t wc)
{
  return (wc == ' ' || wc == '\t'
	  || wc == '\n' || wc == '\v' || wc == '\f' || wc == '\r');
}

static inline int
iswupper (__wctype_wint_t wc)
{
  return wc >= 'A' && wc <= 'Z';
}

static inline int
iswxdigit (__wctype_wint_t wc)
{
  return ((wc >= '0' && wc <= '9')
	  || ((wc & ~0x20) >= 'A' && (wc & ~0x20) <= 'F'));
}

# endif /* ! HAVE_ISWCNTRL */

#endif /* _GL_WCTYPE_H */

--- NEW FILE: intprops.h ---
/* intprops.h -- properties of integer types

   Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

/* Written by Paul Eggert.  */

#include <limits.h>

/* The extra casts in the following macros work around compiler bugs,
   e.g., in Cray C 5.0.3.0.  */

/* True if the arithmetic type T is an integer type.  bool counts as
   an integer.  */
#define TYPE_IS_INTEGER(t) ((t) 1.5 == 1)

/* True if negative values of the signed integer type T use two's
   complement, ones' complement, or signed magnitude representation,
   respectively.  Much GNU code assumes two's complement, but some
   people like to be portable to all possible C hosts.  */
#define TYPE_TWOS_COMPLEMENT(t) ((t) ~ (t) 0 == (t) -1)
#define TYPE_ONES_COMPLEMENT(t) ((t) ~ (t) 0 == 0)
#define TYPE_SIGNED_MAGNITUDE(t) ((t) ~ (t) 0 < (t) -1)

/* True if the arithmetic type T is signed.  */
#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))

/* The maximum and minimum values for the integer type T.  These
   macros have undefined behavior if T is signed and has padding bits.
   If this is a problem for you, please let us know how to fix it for
   your host.  */
#define TYPE_MINIMUM(t) \
  ((t) (! TYPE_SIGNED (t) \
	? (t) 0 \
	: TYPE_SIGNED_MAGNITUDE (t) \
	? ~ (t) 0 \
	: ~ (t) 0 << (sizeof (t) * CHAR_BIT - 1)))
#define TYPE_MAXIMUM(t) \
  ((t) (! TYPE_SIGNED (t) \
	? (t) -1 \
	: ~ (~ (t) 0 << (sizeof (t) * CHAR_BIT - 1))))

/* Return zero if T can be determined to be an unsigned type.
   Otherwise, return 1.
   When compiling with GCC, INT_STRLEN_BOUND uses this macro to obtain a
   tighter bound.  Otherwise, it overestimates the true bound by one byte
   when applied to unsigned types of size 2, 4, 16, ... bytes.
   The symbol signed_type_or_expr__ is private to this header file.  */
#if __GNUC__ >= 2
# define signed_type_or_expr__(t) TYPE_SIGNED (__typeof__ (t))
#else
# define signed_type_or_expr__(t) 1
#endif

/* Bound on length of the string representing an integer type or expression T.
   Subtract 1 for the sign bit if T is signed; log10 (2.0) < 146/485;
   add 1 for integer division truncation; add 1 more for a minus sign
   if needed.  */
#define INT_STRLEN_BOUND(t) \
  ((sizeof (t) * CHAR_BIT - signed_type_or_expr__ (t)) * 146 / 485 \
   + signed_type_or_expr__ (t) + 1)

/* Bound on buffer size needed to represent an integer type or expression T,
   including the terminating null.  */
#define INT_BUFSIZE_BOUND(t) (INT_STRLEN_BOUND (t) + 1)

--- NEW FILE: fcntl--.h ---
/* Like fcntl.h, but redefine some names to avoid glitches.

   Copyright (C) 2005 Free Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

/* Written by Paul Eggert.  */

#include <fcntl.h>
#include "fcntl-safer.h"

#undef open
#define open open_safer

#undef creat
#define creat creat_safer

--- NEW FILE: mountlist.c ---
/* mountlist.c -- return a list of mounted file systems

   Copyright (C) 1991, 1992, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
   2004, 2005, 2006 Free Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

#include <config.h>

#include "mountlist.h"

#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "xalloc.h"

#ifndef strstr
char *strstr ();
#endif

#include <errno.h>

#include <fcntl.h>

#include <unistd.h>

#if HAVE_SYS_PARAM_H
# include <sys/param.h>
#endif

#if defined MOUNTED_GETFSSTAT	/* OSF_1 and Darwin1.3.x */
# if HAVE_SYS_UCRED_H
#  include <grp.h> /* needed on OSF V4.0 for definition of NGROUPS,
		      NGROUPS is used as an array dimension in ucred.h */
#  include <sys/ucred.h> /* needed by powerpc-apple-darwin1.3.7 */
# endif
# if HAVE_SYS_MOUNT_H
#  include <sys/mount.h>
# endif
# if HAVE_SYS_FS_TYPES_H
#  include <sys/fs_types.h> /* needed by powerpc-apple-darwin1.3.7 */
# endif
# if HAVE_STRUCT_FSSTAT_F_FSTYPENAME
#  define FS_TYPE(Ent) ((Ent).f_fstypename)
# else
#  define FS_TYPE(Ent) mnt_names[(Ent).f_type]
# endif
#endif /* MOUNTED_GETFSSTAT */

#ifdef MOUNTED_GETMNTENT1	/* 4.3BSD, SunOS, HP-UX, Dynix, Irix.  */
# include <mntent.h>
# if !defined MOUNTED
#  if defined _PATH_MOUNTED	/* GNU libc  */
#   define MOUNTED _PATH_MOUNTED
#  endif
#  if defined MNT_MNTTAB	/* HP-UX.  */
#   define MOUNTED MNT_MNTTAB
#  endif
#  if defined MNTTABNAME	/* Dynix.  */
#   define MOUNTED MNTTABNAME
#  endif
# endif
#endif

#ifdef MOUNTED_GETMNTINFO	/* 4.4BSD.  */
# include <sys/mount.h>
#endif

#ifdef MOUNTED_GETMNTINFO2	/* NetBSD 3.0.  */
# include <sys/statvfs.h>
#endif

#ifdef MOUNTED_GETMNT		/* Ultrix.  */
# include <sys/mount.h>
# include <sys/fs_types.h>
#endif

#ifdef MOUNTED_FS_STAT_DEV	/* BeOS.  */
# include <fs_info.h>
# include <dirent.h>
#endif

#ifdef MOUNTED_FREAD		/* SVR2.  */
# include <mnttab.h>
#endif

#ifdef MOUNTED_FREAD_FSTYP	/* SVR3.  */
# include <mnttab.h>
# include <sys/fstyp.h>
# include <sys/statfs.h>
#endif

#ifdef MOUNTED_LISTMNTENT
# include <mntent.h>
#endif

#ifdef MOUNTED_GETMNTENT2	/* SVR4.  */
# include <sys/mnttab.h>
#endif

#ifdef MOUNTED_VMOUNT		/* AIX.  */
# include <fshelp.h>
# include <sys/vfs.h>
#endif

#ifdef DOLPHIN
/* So special that it's not worth putting this in autoconf.  */
# undef MOUNTED_FREAD_FSTYP
# define MOUNTED_GETMNTTBL
#endif

#if HAVE_SYS_MNTENT_H
/* This is to get MNTOPT_IGNORE on e.g. SVR4.  */
# include <sys/mntent.h>
#endif

#undef MNT_IGNORE
#if defined MNTOPT_IGNORE && defined HAVE_HASMNTOPT
# define MNT_IGNORE(M) hasmntopt ((M), MNTOPT_IGNORE)
#else
# define MNT_IGNORE(M) 0
#endif

#if USE_UNLOCKED_IO
# include "unlocked-io.h"
#endif

#ifndef SIZE_MAX
# define SIZE_MAX ((size_t) -1)
#endif

/* The results of open() in this file are not used with fchdir,
   therefore save some unnecessary work in fchdir.c.  */
#undef open
#undef close

/* The results of opendir() in this file are not used with dirfd and fchdir,
   therefore save some unnecessary work in fchdir.c.  */
#undef opendir
#undef closedir

#ifndef ME_DUMMY
# define ME_DUMMY(Fs_name, Fs_type)		\
    (strcmp (Fs_type, "autofs") == 0		\
     || strcmp (Fs_type, "none") == 0		\
     || strcmp (Fs_type, "proc") == 0		\
     || strcmp (Fs_type, "subfs") == 0		\
     /* for NetBSD 3.0 */			\
     || strcmp (Fs_type, "kernfs") == 0		\
     /* for Irix 6.5 */				\
     || strcmp (Fs_type, "ignore") == 0)
#endif

#ifndef ME_REMOTE
/* A file system is `remote' if its Fs_name contains a `:'
   or if (it is of type (smbfs or cifs) and its Fs_name starts with `//').  */
# define ME_REMOTE(Fs_name, Fs_type)		\
    (strchr (Fs_name, ':') != NULL		\
     || ((Fs_name)[0] == '/'			\
	 && (Fs_name)[1] == '/'			\
	 && (strcmp (Fs_type, "smbfs") == 0	\
	     || strcmp (Fs_type, "cifs") == 0)))
#endif

#if MOUNTED_GETMNTINFO

# if ! HAVE_STRUCT_STATFS_F_FSTYPENAME
static char *
fstype_to_string (short int t)
{
  switch (t)
    {
#  ifdef MOUNT_PC
    case MOUNT_PC:
      return "pc";
#  endif
#  ifdef MOUNT_MFS
    case MOUNT_MFS:
      return "mfs";
#  endif
#  ifdef MOUNT_LO
    case MOUNT_LO:
      return "lo";
#  endif
#  ifdef MOUNT_TFS
    case MOUNT_TFS:
      return "tfs";
#  endif
#  ifdef MOUNT_TMP
    case MOUNT_TMP:
      return "tmp";
#  endif
#  ifdef MOUNT_UFS
   case MOUNT_UFS:
     return "ufs" ;
#  endif
#  ifdef MOUNT_NFS
   case MOUNT_NFS:
     return "nfs" ;
#  endif
#  ifdef MOUNT_MSDOS
   case MOUNT_MSDOS:
     return "msdos" ;
#  endif
#  ifdef MOUNT_LFS
   case MOUNT_LFS:
     return "lfs" ;
#  endif
#  ifdef MOUNT_LOFS
   case MOUNT_LOFS:
     return "lofs" ;
#  endif
#  ifdef MOUNT_FDESC
   case MOUNT_FDESC:
     return "fdesc" ;
#  endif
#  ifdef MOUNT_PORTAL
   case MOUNT_PORTAL:
     return "portal" ;
#  endif
#  ifdef MOUNT_NULL
   case MOUNT_NULL:
     return "null" ;
#  endif
#  ifdef MOUNT_UMAP
   case MOUNT_UMAP:
     return "umap" ;
#  endif
#  ifdef MOUNT_KERNFS
   case MOUNT_KERNFS:
     return "kernfs" ;
#  endif
#  ifdef MOUNT_PROCFS
   case MOUNT_PROCFS:
     return "procfs" ;
#  endif
#  ifdef MOUNT_AFS
   case MOUNT_AFS:
     return "afs" ;
#  endif
#  ifdef MOUNT_CD9660
   case MOUNT_CD9660:
     return "cd9660" ;
#  endif
#  ifdef MOUNT_UNION
   case MOUNT_UNION:
     return "union" ;
#  endif
#  ifdef MOUNT_DEVFS
   case MOUNT_DEVFS:
     return "devfs" ;
#  endif
#  ifdef MOUNT_EXT2FS
   case MOUNT_EXT2FS:
     return "ext2fs" ;
#  endif
    default:
      return "?";
    }
}
# endif

static char *
fsp_to_string (const struct statfs *fsp)
{
# if HAVE_STRUCT_STATFS_F_FSTYPENAME
  return (char *) (fsp->f_fstypename);
# else
  return fstype_to_string (fsp->f_type);
# endif
}

#endif /* MOUNTED_GETMNTINFO */

#ifdef MOUNTED_VMOUNT		/* AIX.  */
static char *
fstype_to_string (int t)
{
  struct vfs_ent *e;

  e = getvfsbytype (t);
  if (!e || !e->vfsent_name)
    return "none";
  else
    return e->vfsent_name;
}
#endif /* MOUNTED_VMOUNT */


#if defined MOUNTED_GETMNTENT1 || defined MOUNTED_GETMNTENT2

/* Return the device number from MOUNT_OPTIONS, if possible.
   Otherwise return (dev_t) -1.  */

static dev_t
dev_from_mount_options (char const *mount_options)
{
  /* GNU/Linux allows file system implementations to define their own
     meaning for "dev=" mount options, so don't trust the meaning
     here.  */
# ifndef __linux__

  static char const dev_pattern[] = ",dev=";
  char const *devopt = strstr (mount_options, dev_pattern);

  if (devopt)
    {
      char const *optval = devopt + sizeof dev_pattern - 1;
      char *optvalend;
      unsigned long int dev;
      errno = 0;
      dev = strtoul (optval, &optvalend, 16);
      if (optval != optvalend
	  && (*optvalend == '\0' || *optvalend == ',')
	  && ! (dev == ULONG_MAX && errno == ERANGE)
	  && dev == (dev_t) dev)
	return dev;
    }

# endif

  return -1;
}

#endif

/* Return a list of the currently mounted file systems, or NULL on error.
   Add each entry to the tail of the list so that they stay in order.
   If NEED_FS_TYPE is true, ensure that the file system type fields in
   the returned list are valid.  Otherwise, they might not be.  */

struct mount_entry *
read_file_system_list (bool need_fs_type)
{
  struct mount_entry *mount_list;
  struct mount_entry *me;
  struct mount_entry **mtail = &mount_list;

#ifdef MOUNTED_LISTMNTENT
  {
    struct tabmntent *mntlist, *p;
    struct mntent *mnt;
    struct mount_entry *me;

    /* the third and fourth arguments could be used to filter mounts,
       but Crays doesn't seem to have any mounts that we want to
       remove. Specifically, automount create normal NFS mounts.
       */

    if (listmntent (&mntlist, KMTAB, NULL, NULL) < 0)
      return NULL;
    for (p = mntlist; p; p = p->next) {
      mnt = p->ment;
      me = xmalloc (sizeof *me);
      me->me_devname = xstrdup (mnt->mnt_fsname);
      me->me_mountdir = xstrdup (mnt->mnt_dir);
      me->me_type = xstrdup (mnt->mnt_type);
      me->me_type_malloced = 1;
      me->me_dummy = ME_DUMMY (me->me_devname, me->me_type);
      me->me_remote = ME_REMOTE (me->me_devname, me->me_type);
      me->me_dev = -1;
      *mtail = me;
      mtail = &me->me_next;
    }
    freemntlist (mntlist);
  }
#endif

#ifdef MOUNTED_GETMNTENT1 /* GNU/Linux, 4.3BSD, SunOS, HP-UX, Dynix, Irix.  */
  {
    struct mntent *mnt;
    char *table = MOUNTED;
    FILE *fp;

    fp = setmntent (table, "r");
    if (fp == NULL)
      return NULL;

    while ((mnt = getmntent (fp)))
      {
	me = xmalloc (sizeof *me);
	me->me_devname = xstrdup (mnt->mnt_fsname);
	me->me_mountdir = xstrdup (mnt->mnt_dir);
	me->me_type = xstrdup (mnt->mnt_type);
	me->me_type_malloced = 1;
	me->me_dummy = ME_DUMMY (me->me_devname, me->me_type);
	me->me_remote = ME_REMOTE (me->me_devname, me->me_type);
	me->me_dev = dev_from_mount_options (mnt->mnt_opts);

	/* Add to the linked list. */
	*mtail = me;
	mtail = &me->me_next;
      }

    if (endmntent (fp) == 0)
      goto free_then_fail;
  }
#endif /* MOUNTED_GETMNTENT1. */

#ifdef MOUNTED_GETMNTINFO	/* 4.4BSD.  */
  {
    struct statfs *fsp;
    int entries;

    entries = getmntinfo (&fsp, MNT_NOWAIT);
    if (entries < 0)
      return NULL;
    for (; entries-- > 0; fsp++)
      {
	char *fs_type = fsp_to_string (fsp);

	me = xmalloc (sizeof *me);
	me->me_devname = xstrdup (fsp->f_mntfromname);
	me->me_mountdir = xstrdup (fsp->f_mntonname);
	me->me_type = fs_type;
	me->me_type_malloced = 0;
	me->me_dummy = ME_DUMMY (me->me_devname, me->me_type);
	me->me_remote = ME_REMOTE (me->me_devname, me->me_type);
	me->me_dev = (dev_t) -1;	/* Magic; means not known yet. */

	/* Add to the linked list. */
	*mtail = me;
	mtail = &me->me_next;
      }
  }
#endif /* MOUNTED_GETMNTINFO */

#ifdef MOUNTED_GETMNTINFO2	/* NetBSD 3.0.  */
  {
    struct statvfs *fsp;
    int entries;

    entries = getmntinfo (&fsp, MNT_NOWAIT);
    if (entries < 0)
      return NULL;
    for (; entries-- > 0; fsp++)
      {
	me = xmalloc (sizeof *me);
	me->me_devname = xstrdup (fsp->f_mntfromname);
	me->me_mountdir = xstrdup (fsp->f_mntonname);
	me->me_type = xstrdup (fsp->f_fstypename);
	me->me_type_malloced = 1;
	me->me_dummy = ME_DUMMY (me->me_devname, me->me_type);
	me->me_remote = ME_REMOTE (me->me_devname, me->me_type);
	me->me_dev = (dev_t) -1;	/* Magic; means not known yet. */

	/* Add to the linked list. */
	*mtail = me;
	mtail = &me->me_next;
      }
  }
#endif /* MOUNTED_GETMNTINFO2 */

#ifdef MOUNTED_GETMNT		/* Ultrix.  */
  {
    int offset = 0;
    int val;
    struct fs_data fsd;

    while (errno = 0,
	   0 < (val = getmnt (&offset, &fsd, sizeof (fsd), NOSTAT_MANY,
			      (char *) 0)))
      {
	me = xmalloc (sizeof *me);
	me->me_devname = xstrdup (fsd.fd_req.devname);
	me->me_mountdir = xstrdup (fsd.fd_req.path);
	me->me_type = gt_names[fsd.fd_req.fstype];
	me->me_type_malloced = 0;
	me->me_dummy = ME_DUMMY (me->me_devname, me->me_type);
	me->me_remote = ME_REMOTE (me->me_devname, me->me_type);
	me->me_dev = fsd.fd_req.dev;

	/* Add to the linked list. */
	*mtail = me;
	mtail = &me->me_next;
      }
    if (val < 0)
      goto free_then_fail;
  }
#endif /* MOUNTED_GETMNT. */

#if defined MOUNTED_FS_STAT_DEV /* BeOS */
  {
    /* The next_dev() and fs_stat_dev() system calls give the list of
       all file systems, including the information returned by statvfs()
       (fs type, total blocks, free blocks etc.), but without the mount
       point. But on BeOS all file systems except / are mounted in the
       rootfs, directly under /.
       The directory name of the mount point is often, but not always,
       identical to the volume name of the device.
       We therefore get the list of subdirectories of /, and the list
       of all file systems, and match the two lists.  */

    DIR *dirp;
    struct rootdir_entry
      {
        char *name;
        dev_t dev;
        ino_t ino;
        struct rootdir_entry *next;
      };
    struct rootdir_entry *rootdir_list;
    struct rootdir_entry **rootdir_tail;
    int32 pos;
    dev_t dev;
    fs_info fi;

    /* All volumes are mounted in the rootfs, directly under /. */
    rootdir_list = NULL;
    rootdir_tail = &rootdir_list;
    dirp = opendir ("/");
    if (dirp)
      {
        struct dirent *d;

        while ((d = readdir (dirp)) != NULL)
          {
            char *name;
            struct stat statbuf;

            if (strcmp (d->d_name, "..") == 0)
              continue;

            if (strcmp (d->d_name, ".") == 0)
              name = xstrdup ("/");
            else
              {
                name = xmalloc (1 + strlen (d->d_name) + 1);
                name[0] = '/';
                strcpy (name + 1, d->d_name);
              }

            if (lstat (name, &statbuf) >= 0 && S_ISDIR (statbuf.st_mode))
              {
		struct rootdir_entry *re = xmalloc (sizeof *re);
                re->name = name;
                re->dev = statbuf.st_dev;
                re->ino = statbuf.st_ino;

                /* Add to the linked list.  */
                *rootdir_tail = re;
                rootdir_tail = &re->next;
              }
            else
              free (name);
          }
        closedir (dirp);
      }
    *rootdir_tail = NULL;

    for (pos = 0; (dev = next_dev (&pos)) >= 0; )
      if (fs_stat_dev (dev, &fi) >= 0)
        {
          /* Note: fi.dev == dev. */
          struct rootdir_entry *re;

          for (re = rootdir_list; re; re = re->next)
            if (re->dev == fi.dev && re->ino == fi.root)
              break;

	  me = xmalloc (sizeof *me);
          me->me_devname = xstrdup (fi.device_name[0] != '\0' ? fi.device_name : fi.fsh_name);
          me->me_mountdir = xstrdup (re != NULL ? re->name : fi.fsh_name);
          me->me_type = xstrdup (fi.fsh_name);
	  me->me_type_malloced = 1;
          me->me_dev = fi.dev;
          me->me_dummy = 0;
          me->me_remote = (fi.flags & B_FS_IS_SHARED) != 0;

          /* Add to the linked list. */
          *mtail = me;
          mtail = &me->me_next;
        }
    *mtail = NULL;

    while (rootdir_list != NULL)
      {
        struct rootdir_entry *re = rootdir_list;
        rootdir_list = re->next;
        free (re->name);
        free (re);
      }
  }
#endif /* MOUNTED_FS_STAT_DEV */

#if defined MOUNTED_GETFSSTAT	/* __alpha running OSF_1 */
  {
    int numsys, counter;
    size_t bufsize;
    struct statfs *stats;

    numsys = getfsstat ((struct statfs *)0, 0L, MNT_NOWAIT);
    if (numsys < 0)
      return (NULL);
    if (SIZE_MAX / sizeof *stats <= numsys)
      xalloc_die ();

    bufsize = (1 + numsys) * sizeof *stats;
    stats = xmalloc (bufsize);
    numsys = getfsstat (stats, bufsize, MNT_NOWAIT);

    if (numsys < 0)
      {
	free (stats);
	return (NULL);
      }

    for (counter = 0; counter < numsys; counter++)
      {
	me = xmalloc (sizeof *me);
	me->me_devname = xstrdup (stats[counter].f_mntfromname);
	me->me_mountdir = xstrdup (stats[counter].f_mntonname);
	me->me_type = xstrdup (FS_TYPE (stats[counter]));
	me->me_type_malloced = 1;
	me->me_dummy = ME_DUMMY (me->me_devname, me->me_type);
	me->me_remote = ME_REMOTE (me->me_devname, me->me_type);
	me->me_dev = (dev_t) -1;	/* Magic; means not known yet. */

	/* Add to the linked list. */
	*mtail = me;
	mtail = &me->me_next;
      }

    free (stats);
  }
#endif /* MOUNTED_GETFSSTAT */

#if defined MOUNTED_FREAD || defined MOUNTED_FREAD_FSTYP /* SVR[23].  */
  {
    struct mnttab mnt;
    char *table = "/etc/mnttab";
    FILE *fp;

    fp = fopen (table, "r");
    if (fp == NULL)
      return NULL;

    while (fread (&mnt, sizeof mnt, 1, fp) > 0)
      {
	me = xmalloc (sizeof *me);
# ifdef GETFSTYP			/* SVR3.  */
	me->me_devname = xstrdup (mnt.mt_dev);
# else
	me->me_devname = xmalloc (strlen (mnt.mt_dev) + 6);
	strcpy (me->me_devname, "/dev/");
	strcpy (me->me_devname + 5, mnt.mt_dev);
# endif
	me->me_mountdir = xstrdup (mnt.mt_filsys);
	me->me_dev = (dev_t) -1;	/* Magic; means not known yet. */
	me->me_type = "";
	me->me_type_malloced = 0;
# ifdef GETFSTYP			/* SVR3.  */
	if (need_fs_type)
	  {
	    struct statfs fsd;
	    char typebuf[FSTYPSZ];

	    if (statfs (me->me_mountdir, &fsd, sizeof fsd, 0) != -1
		&& sysfs (GETFSTYP, fsd.f_fstyp, typebuf) != -1)
	      {
		me->me_type = xstrdup (typebuf);
		me->me_type_malloced = 1;
	      }
	  }
# endif
	me->me_dummy = ME_DUMMY (me->me_devname, me->me_type);
	me->me_remote = ME_REMOTE (me->me_devname, me->me_type);

	/* Add to the linked list. */
	*mtail = me;
	mtail = &me->me_next;
      }

    if (ferror (fp))
      {
	/* The last fread() call must have failed.  */
	int saved_errno = errno;
	fclose (fp);
	errno = saved_errno;
	goto free_then_fail;
      }

    if (fclose (fp) == EOF)
      goto free_then_fail;
  }
#endif /* MOUNTED_FREAD || MOUNTED_FREAD_FSTYP.  */

#ifdef MOUNTED_GETMNTTBL	/* DolphinOS goes its own way.  */
  {
    struct mntent **mnttbl = getmnttbl (), **ent;
    for (ent=mnttbl;*ent;ent++)
      {
	me = xmalloc (sizeof *me);
	me->me_devname = xstrdup ( (*ent)->mt_resource);
	me->me_mountdir = xstrdup ( (*ent)->mt_directory);
	me->me_type = xstrdup ((*ent)->mt_fstype);
	me->me_type_malloced = 1;
	me->me_dummy = ME_DUMMY (me->me_devname, me->me_type);
	me->me_remote = ME_REMOTE (me->me_devname, me->me_type);
	me->me_dev = (dev_t) -1;	/* Magic; means not known yet. */

	/* Add to the linked list. */
	*mtail = me;
	mtail = &me->me_next;
      }
    endmnttbl ();
  }
#endif

#ifdef MOUNTED_GETMNTENT2	/* SVR4.  */
  {
    struct mnttab mnt;
    char *table = MNTTAB;
    FILE *fp;
    int ret;
    int lockfd = -1;

# if defined F_RDLCK && defined F_SETLKW
    /* MNTTAB_LOCK is a macro name of our own invention; it's not present in
       e.g. Solaris 2.6.  If the SVR4 folks ever define a macro
       for this file name, we should use their macro name instead.
       (Why not just lock MNTTAB directly?  We don't know.)  */
#  ifndef MNTTAB_LOCK
#   define MNTTAB_LOCK "/etc/.mnttab.lock"
#  endif
    lockfd = open (MNTTAB_LOCK, O_RDONLY);
    if (0 <= lockfd)
      {
	struct flock flock;
	flock.l_type = F_RDLCK;
	flock.l_whence = SEEK_SET;
	flock.l_start = 0;
	flock.l_len = 0;
	while (fcntl (lockfd, F_SETLKW, &flock) == -1)
	  if (errno != EINTR)
	    {
	      int saved_errno = errno;
	      close (lockfd);
	      errno = saved_errno;
	      return NULL;
	    }
      }
    else if (errno != ENOENT)
      return NULL;
# endif

    errno = 0;
    fp = fopen (table, "r");
    if (fp == NULL)
      ret = errno;
    else
      {
	while ((ret = getmntent (fp, &mnt)) == 0)
	  {
	    me = xmalloc (sizeof *me);
	    me->me_devname = xstrdup (mnt.mnt_special);
	    me->me_mountdir = xstrdup (mnt.mnt_mountp);
	    me->me_type = xstrdup (mnt.mnt_fstype);
	    me->me_type_malloced = 1;
	    me->me_dummy = MNT_IGNORE (&mnt) != 0;
	    me->me_remote = ME_REMOTE (me->me_devname, me->me_type);
	    me->me_dev = dev_from_mount_options (mnt.mnt_mntopts);

	    /* Add to the linked list. */
	    *mtail = me;
	    mtail = &me->me_next;
	  }

	ret = fclose (fp) == EOF ? errno : 0 < ret ? 0 : -1;
      }

    if (0 <= lockfd && close (lockfd) != 0)
      ret = errno;

    if (0 <= ret)
      {
	errno = ret;
	goto free_then_fail;
      }
  }
#endif /* MOUNTED_GETMNTENT2.  */

#ifdef MOUNTED_VMOUNT		/* AIX.  */
  {
    int bufsize;
    char *entries, *thisent;
    struct vmount *vmp;
    int n_entries;
    int i;

    /* Ask how many bytes to allocate for the mounted file system info.  */
    if (mntctl (MCTL_QUERY, sizeof bufsize, (struct vmount *) &bufsize) != 0)
      return NULL;
    entries = xmalloc (bufsize);

    /* Get the list of mounted file systems.  */
    n_entries = mntctl (MCTL_QUERY, bufsize, (struct vmount *) entries);
    if (n_entries < 0)
      {
	int saved_errno = errno;
	free (entries);
	errno = saved_errno;
	return NULL;
      }

    for (i = 0, thisent = entries;
	 i < n_entries;
	 i++, thisent += vmp->vmt_length)
      {
	char *options, *ignore;

	vmp = (struct vmount *) thisent;
	me = xmalloc (sizeof *me);
	if (vmp->vmt_flags & MNT_REMOTE)
	  {
	    char *host, *dir;

	    me->me_remote = 1;
	    /* Prepend the remote dirname.  */
	    host = thisent + vmp->vmt_data[VMT_HOSTNAME].vmt_off;
	    dir = thisent + vmp->vmt_data[VMT_OBJECT].vmt_off;
	    me->me_devname = xmalloc (strlen (host) + strlen (dir) + 2);
	    strcpy (me->me_devname, host);
	    strcat (me->me_devname, ":");
	    strcat (me->me_devname, dir);
	  }
	else
	  {
	    me->me_remote = 0;
	    me->me_devname = xstrdup (thisent +
				      vmp->vmt_data[VMT_OBJECT].vmt_off);
	  }
	me->me_mountdir = xstrdup (thisent + vmp->vmt_data[VMT_STUB].vmt_off);
	me->me_type = xstrdup (fstype_to_string (vmp->vmt_gfstype));
	me->me_type_malloced = 1;
	options = thisent + vmp->vmt_data[VMT_ARGS].vmt_off;
	ignore = strstr (options, "ignore");
	me->me_dummy = (ignore
			&& (ignore == options || ignore[-1] == ',')
			&& (ignore[sizeof "ignore" - 1] == ','
			    || ignore[sizeof "ignore" - 1] == '\0'));
	me->me_dev = (dev_t) -1; /* vmt_fsid might be the info we want.  */

	/* Add to the linked list. */
	*mtail = me;
	mtail = &me->me_next;
      }
    free (entries);
  }
#endif /* MOUNTED_VMOUNT. */

  *mtail = NULL;
  return mount_list;


 free_then_fail:
  {
    int saved_errno = errno;
    *mtail = NULL;

    while (mount_list)
      {
	me = mount_list->me_next;
	free (mount_list->me_devname);
	free (mount_list->me_mountdir);
	if (mount_list->me_type_malloced)
	  free (mount_list->me_type);
	free (mount_list);
	mount_list = me;
      }

    errno = saved_errno;
    return NULL;
  }
}

--- NEW FILE: dirname.h ---
/*  Take file names apart into directory and base names.

    Copyright (C) 1998, 2001, 2003-2006 Free Software Foundation, Inc.

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2, or (at your option)
    any later version.

    This program 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 General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software Foundation,
    Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

#ifndef DIRNAME_H_
# define DIRNAME_H_ 1

# include <stdbool.h>
# include <stddef.h>

# ifndef DIRECTORY_SEPARATOR
#  define DIRECTORY_SEPARATOR '/'
# endif

# ifndef ISSLASH
#  define ISSLASH(C) ((C) == DIRECTORY_SEPARATOR)
# endif

# ifndef FILE_SYSTEM_PREFIX_LEN
#  if FILE_SYSTEM_ACCEPTS_DRIVE_LETTER_PREFIX
    /* This internal macro assumes ASCII, but all hosts that support drive
       letters use ASCII.  */
#   define _IS_DRIVE_LETTER(c) (((unsigned int) (c) | ('a' - 'A')) - 'a' \
				<= 'z' - 'a')
#   define FILE_SYSTEM_PREFIX_LEN(Filename) \
	   (_IS_DRIVE_LETTER ((Filename)[0]) && (Filename)[1] == ':' ? 2 : 0)
#  else
#   define FILE_SYSTEM_PREFIX_LEN(Filename) 0
#  endif
# endif

# ifndef FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE
#  define FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE 0
# endif

# ifndef DOUBLE_SLASH_IS_DISTINCT_ROOT
#  define DOUBLE_SLASH_IS_DISTINCT_ROOT 0
# endif

# if FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE
#  define IS_ABSOLUTE_FILE_NAME(F) ISSLASH ((F)[FILE_SYSTEM_PREFIX_LEN (F)])
# else
#  define IS_ABSOLUTE_FILE_NAME(F) \
	  (ISSLASH ((F)[0]) || 0 < FILE_SYSTEM_PREFIX_LEN (F))
# endif
# define IS_RELATIVE_FILE_NAME(F) (! IS_ABSOLUTE_FILE_NAME (F))

char *base_name (char const *file);
char *dir_name (char const *file);
size_t base_len (char const *file);
size_t dir_len (char const *file);
char *last_component (char const *file);

bool strip_trailing_slashes (char *file);

#endif /* not DIRNAME_H_ */

--- NEW FILE: wchar_.h ---
/* A substitute for ISO C99 <wchar.h>, for platforms that have issues.

   Copyright (C) 2007 Free Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

/* Written by Eric Blake.  */

/*
 * ISO C 99 <wchar.h> for platforms that have issues.
 * <http://www.opengroup.org/susv3xbd/wchar.h.html>
 *
 * For now, this just ensures proper prerequisite inclusion order.
 */

#ifndef _GL_WCHAR_H
#define _GL_WCHAR_H

/* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
   <wchar.h>.
   BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be
   included before <wchar.h>.  */
#include <stddef.h>
#include <stdio.h>
#include <time.h>

/* Include the original <wchar.h>.  */
#include @ABSOLUTE_WCHAR_H@

#endif /* _GL_WCHAR_H */

--- NEW FILE: open-safer.c ---
/* Invoke open, but avoid some glitches.

   Copyright (C) 2005, 2006 Free Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

/* Written by Paul Eggert.  */

#include <config.h>

#include "fcntl-safer.h"

#include <fcntl.h>
#include <stdarg.h>
#include "unistd-safer.h"

int
open_safer (char const *file, int flags, ...)
{
  mode_t mode = 0;

  if (flags & O_CREAT)
    {
      va_list ap;
      va_start (ap, flags);

      /* Assume mode_t promotes to int if and only if it is smaller.
	 This assumption isn't guaranteed by the C standard, but we
	 don't know of any real-world counterexamples.  */
      mode = (sizeof (mode_t) < sizeof (int)
	      ? va_arg (ap, int)
	      : va_arg (ap, mode_t));

      va_end (ap);
    }

  return fd_safer (open (file, flags, mode));
}

--- NEW FILE: mbchar.c ---
/* Copyright (C) 2001, 2006 Free Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software Foundation,
   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */


#include <config.h>

#include <limits.h>

#include "mbchar.h"

#if IS_BASIC_ASCII

/* Bit table of characters in the ISO C "basic character set".  */
const unsigned int is_basic_table [UCHAR_MAX / 32 + 1] =
{
  0x00001a00,		/* '\t' '\v' '\f' */
  0xffffffef,		/* ' '...'#' '%'...'?' */
  0xfffffffe,		/* 'A'...'Z' '[' '\\' ']' '^' '_' */
  0x7ffffffe		/* 'a'...'z' '{' '|' '}' '~' */
  /* The remaining bits are 0.  */
};

#endif /* IS_BASIC_ASCII */

--- NEW FILE: strcase.h ---
/* Case-insensitive string comparison functions.
   Copyright (C) 1995-1996, 2001, 2003, 2005-2006 Free Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

#ifndef _STRCASE_H
#define _STRCASE_H

#include <stddef.h>
/* Include header files with a possibly conflicting declarations of strcasecmp
   before we define it as a macro, so that they will be no-ops if included
   after strcasecmp is defined as a macro.  */
#include <string.h>

#ifdef __cplusplus
extern "C" {
#endif


/* No known system has a strcasecmp() function that works correctly in
   multibyte locales.  Therefore we use our version always.  */
#define strcasecmp rpl_strcasecmp
/* Compare strings S1 and S2, ignoring case, returning less than, equal to or
   greater than zero if S1 is lexicographically less than, equal to or greater
   than S2.
   Note: This function may, in multibyte locales, return 0 for strings of
   different lengths!  */
extern int strcasecmp (const char *s1, const char *s2);

/* Compare no more than N characters of strings S1 and S2, ignoring case,
   returning less than, equal to or greater than zero if S1 is
   lexicographically less than, equal to or greater than S2.
   Note: This function can not work correctly in multibyte locales.  */
#if ! HAVE_DECL_STRNCASECMP
extern int strncasecmp (const char *s1, const char *s2, size_t n);
#endif


#ifdef __cplusplus
}
#endif


#endif /* _STRCASE_H */

--- NEW FILE: mbchar.h ---
/* Multibyte character data type.
   Copyright (C) 2001, 2005-2006 Free Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software Foundation,
   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */

/* Written by Bruno Haible <bruno at clisp.org>.  */

/* A multibyte character is a short subsequence of a char* string,
   representing a single wide character.

   We use multibyte characters instead of wide characters because of
   the following goals:
   1) correct multibyte handling, i.e. operate according to the LC_CTYPE
      locale,
   2) ease of maintenance, i.e. the maintainer needs not know all details
      of the ISO C 99 standard,
   3) don't fail grossly if the input is not in the encoding set by the
      locale, because often different encodings are in use in the same
      countries (ISO-8859-1/UTF-8, EUC-JP/Shift_JIS, ...),
   4) fast in the case of ASCII characters,
   5) portability, i.e. don't make unportable assumptions about wchar_t.

   Multibyte characters are only accessed through the mb* macros.

   mb_ptr (mbc)
     return a pointer to the beginning of the multibyte sequence.

   mb_len (mbc)
     returns the number of bytes occupied by the multibyte sequence.
     Always > 0.

   mb_iseq (mbc, sc)
     returns true if mbc is the standard ASCII character sc.

   mb_isnul (mbc)
     returns true if mbc is the nul character.

   mb_cmp (mbc1, mbc2)
     returns a positive, zero, or negative value depending on whether mbc1
     sorts after, same or before mbc2.

   mb_casecmp (mbc1, mbc2)
     returns a positive, zero, or negative value depending on whether mbc1
     sorts after, same or before mbc2, modulo upper/lowercase conversion.

   mb_equal (mbc1, mbc2)
     returns true if mbc1 and mbc2 are equal.

   mb_caseequal (mbc1, mbc2)
     returns true if mbc1 and mbc2 are equal modulo upper/lowercase conversion.

   mb_isalnum (mbc)
     returns true if mbc is alphanumeric.

   mb_isalpha (mbc)
     returns true if mbc is alphabetic.

   mb_isascii(mbc)
     returns true if mbc is plain ASCII.

   mb_isblank (mbc)
     returns true if mbc is a blank.

   mb_iscntrl (mbc)
     returns true if mbc is a control character.

   mb_isdigit (mbc)
     returns true if mbc is a decimal digit.

   mb_isgraph (mbc)
     returns true if mbc is a graphic character.

   mb_islower (mbc)
     returns true if mbc is lowercase.

   mb_isprint (mbc)
     returns true if mbc is a printable character.

   mb_ispunct (mbc)
     returns true if mbc is a punctuation character.

   mb_isspace (mbc)
     returns true if mbc is a space character.

   mb_isupper (mbc)
     returns true if mbc is uppercase.

   mb_isxdigit (mbc)
     returns true if mbc is a hexadecimal digit.

   mb_width (mbc)
     returns the number of columns on the output device occupied by mbc.
     Always >= 0.

   mb_putc (mbc, stream)
     outputs mbc on stream, a byte oriented FILE stream opened for output.

   mb_setascii (&mbc, sc)
     assigns the standard ASCII character sc to mbc.

   mb_copy (&destmbc, &srcmbc)
     copies srcmbc to destmbc.

   Here are the function prototypes of the macros.

   extern const char *	mb_ptr (const mbchar_t mbc);
   extern size_t	mb_len (const mbchar_t mbc);
   extern bool		mb_iseq (const mbchar_t mbc, char sc);
   extern bool		mb_isnul (const mbchar_t mbc);
   extern int		mb_cmp (const mbchar_t mbc1, const mbchar_t mbc2);
   extern int		mb_casecmp (const mbchar_t mbc1, const mbchar_t mbc2);
   extern bool		mb_equal (const mbchar_t mbc1, const mbchar_t mbc2);
   extern bool		mb_caseequal (const mbchar_t mbc1, const mbchar_t mbc2);
   extern bool		mb_isalnum (const mbchar_t mbc);
   extern bool		mb_isalpha (const mbchar_t mbc);
   extern bool		mb_isascii (const mbchar_t mbc);
   extern bool		mb_isblank (const mbchar_t mbc);
   extern bool		mb_iscntrl (const mbchar_t mbc);
   extern bool		mb_isdigit (const mbchar_t mbc);
   extern bool		mb_isgraph (const mbchar_t mbc);
   extern bool		mb_islower (const mbchar_t mbc);
   extern bool		mb_isprint (const mbchar_t mbc);
   extern bool		mb_ispunct (const mbchar_t mbc);
   extern bool		mb_isspace (const mbchar_t mbc);
   extern bool		mb_isupper (const mbchar_t mbc);
   extern bool		mb_isxdigit (const mbchar_t mbc);
   extern int		mb_width (const mbchar_t mbc);
   extern void		mb_putc (const mbchar_t mbc, FILE *stream);
   extern void          mb_setascii (mbchar_t *new, char sc);
   extern void		mb_copy (mbchar_t *new, const mbchar_t *old);
 */

#ifndef _MBCHAR_H
#define _MBCHAR_H 1

#include <stdbool.h>
#include <string.h>

/* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
   <wchar.h>.
   BSD/OS 4.1 has a bug: <stdio.h> and <time.h> must be included before
   <wchar.h>.  */
#include <stdio.h>
#include <time.h>
#include <wchar.h>
#include <wctype.h>

#include "wcwidth.h"

#define MBCHAR_BUF_SIZE 24

struct mbchar
{
  const char *ptr;	/* pointer to current character */
  size_t bytes;		/* number of bytes of current character, > 0 */
  bool wc_valid;	/* true if wc is a valid wide character */
  wchar_t wc;		/* if wc_valid: the current character */
  char buf[MBCHAR_BUF_SIZE]; /* room for the bytes, used for file input only */
};

/* EOF (not a real character) is represented with bytes = 0 and
   wc_valid = false.  */

typedef struct mbchar mbchar_t;

/* Access the current character.  */
#define mb_ptr(mbc) ((mbc).ptr)
#define mb_len(mbc) ((mbc).bytes)

/* Comparison of characters.  */
#define mb_iseq(mbc, sc) ((mbc).wc_valid && (mbc).wc == (sc))
#define mb_isnul(mbc) ((mbc).wc_valid && (mbc).wc == 0)
#define mb_cmp(mbc1, mbc2) \
  ((mbc1).wc_valid							\
   ? ((mbc2).wc_valid							\
      ? (int) (mbc1).wc - (int) (mbc2).wc				\
      : -1)								\
   : ((mbc2).wc_valid							\
      ? 1								\
      : (mbc1).bytes == (mbc2).bytes					\
        ? memcmp ((mbc1).ptr, (mbc2).ptr, (mbc1).bytes)			\
        : (mbc1).bytes < (mbc2).bytes					\
          ? (memcmp ((mbc1).ptr, (mbc2).ptr, (mbc1).bytes) > 0 ? 1 : -1) \
          : (memcmp ((mbc1).ptr, (mbc2).ptr, (mbc2).bytes) >= 0 ? 1 : -1)))
#define mb_casecmp(mbc1, mbc2) \
  ((mbc1).wc_valid							\
   ? ((mbc2).wc_valid							\
      ? (int) towlower ((mbc1).wc) - (int) towlower ((mbc2).wc)		\
      : -1)								\
   : ((mbc2).wc_valid							\
      ? 1								\
      : (mbc1).bytes == (mbc2).bytes					\
        ? memcmp ((mbc1).ptr, (mbc2).ptr, (mbc1).bytes)			\
        : (mbc1).bytes < (mbc2).bytes					\
          ? (memcmp ((mbc1).ptr, (mbc2).ptr, (mbc1).bytes) > 0 ? 1 : -1) \
          : (memcmp ((mbc1).ptr, (mbc2).ptr, (mbc2).bytes) >= 0 ? 1 : -1)))
#define mb_equal(mbc1, mbc2) \
  ((mbc1).wc_valid && (mbc2).wc_valid					\
   ? (mbc1).wc == (mbc2).wc						\
   : (mbc1).bytes == (mbc2).bytes					\
     && memcmp ((mbc1).ptr, (mbc2).ptr, (mbc1).bytes) == 0)
#define mb_caseequal(mbc1, mbc2) \
  ((mbc1).wc_valid && (mbc2).wc_valid					\
   ? towlower ((mbc1).wc) == towlower ((mbc2).wc)			\
   : (mbc1).bytes == (mbc2).bytes					\
     && memcmp ((mbc1).ptr, (mbc2).ptr, (mbc1).bytes) == 0)

/* <ctype.h>, <wctype.h> classification.  */
#define mb_isascii(mbc) \
  ((mbc).wc_valid && (mbc).wc >= 0 && (mbc).wc <= 127)
#define mb_isalnum(mbc) ((mbc).wc_valid && iswalnum ((mbc).wc))
#define mb_isalpha(mbc) ((mbc).wc_valid && iswalpha ((mbc).wc))
#define mb_isblank(mbc) ((mbc).wc_valid && iswblank ((mbc).wc))
#define mb_iscntrl(mbc) ((mbc).wc_valid && iswcntrl ((mbc).wc))
#define mb_isdigit(mbc) ((mbc).wc_valid && iswdigit ((mbc).wc))
#define mb_isgraph(mbc) ((mbc).wc_valid && iswgraph ((mbc).wc))
#define mb_islower(mbc) ((mbc).wc_valid && iswlower ((mbc).wc))
#define mb_isprint(mbc) ((mbc).wc_valid && iswprint ((mbc).wc))
#define mb_ispunct(mbc) ((mbc).wc_valid && iswpunct ((mbc).wc))
#define mb_isspace(mbc) ((mbc).wc_valid && iswspace ((mbc).wc))
#define mb_isupper(mbc) ((mbc).wc_valid && iswupper ((mbc).wc))
#define mb_isxdigit(mbc) ((mbc).wc_valid && iswxdigit ((mbc).wc))

/* Extra <wchar.h> function.  */

/* Unprintable characters appear as a small box of width 1.  */
#define MB_UNPRINTABLE_WIDTH 1

static inline int
mb_width_aux (wint_t wc)
{
  int w = wcwidth (wc);
  /* For unprintable characters, arbitrarily return 0 for control characters
     and MB_UNPRINTABLE_WIDTH otherwise.  */
  return (w >= 0 ? w : iswcntrl (wc) ? 0 : MB_UNPRINTABLE_WIDTH);
}

#define mb_width(mbc) \
  ((mbc).wc_valid ? mb_width_aux ((mbc).wc) : MB_UNPRINTABLE_WIDTH)

/* Output.  */
#define mb_putc(mbc, stream)  fwrite ((mbc).ptr, 1, (mbc).bytes, (stream))

/* Assignment.  */
#define mb_setascii(mbc, sc) \
  ((mbc)->ptr = (mbc)->buf, (mbc)->bytes = 1, (mbc)->wc_valid = 1, \
   (mbc)->wc = (mbc)->buf[0] = (sc))

/* Copying a character.  */
static inline void
mb_copy (mbchar_t *new_mbc, const mbchar_t *old_mbc)
{
  if (old_mbc->ptr == &old_mbc->buf[0])
    {
      memcpy (&new_mbc->buf[0], &old_mbc->buf[0], old_mbc->bytes);
      new_mbc->ptr = &new_mbc->buf[0];
    }
  else
    new_mbc->ptr = old_mbc->ptr;
  new_mbc->bytes = old_mbc->bytes;
  if ((new_mbc->wc_valid = old_mbc->wc_valid))
    new_mbc->wc = old_mbc->wc;
}


/* is_basic(c) tests whether the single-byte character c is in the
   ISO C "basic character set".
   This is a convenience function, and is in this file only to share code
   between mbiter_multi.h and mbfile_multi.h.  */
#if (' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
    && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \
    && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \
    && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \
    && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \
    && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \
    && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \
    && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \
    && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \
    && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \
    && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \
    && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \
    && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \
    && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \
    && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \
    && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \
    && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \
    && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \
    && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \
    && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \
    && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \
    && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \
    && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126)
/* The character set is ISO-646, not EBCDIC. */
# define IS_BASIC_ASCII 1

extern const unsigned int is_basic_table[];

static inline bool
is_basic (char c)
{
  return (is_basic_table [(unsigned char) c >> 5] >> ((unsigned char) c & 31))
	 & 1;
}

#else

static inline bool
is_basic (char c)
{
  switch (c)
    {
    case '\t': case '\v': case '\f':
    case ' ': case '!': case '"': case '#': case '%':
    case '&': case '\'': case '(': case ')': case '*':
    case '+': case ',': case '-': case '.': case '/':
    case '0': case '1': case '2': case '3': case '4':
    case '5': case '6': case '7': case '8': case '9':
    case ':': case ';': case '<': case '=': case '>':
    case '?':
    case 'A': case 'B': case 'C': case 'D': case 'E':
    case 'F': case 'G': case 'H': case 'I': case 'J':
    case 'K': case 'L': case 'M': case 'N': case 'O':
    case 'P': case 'Q': case 'R': case 'S': case 'T':
    case 'U': case 'V': case 'W': case 'X': case 'Y':
    case 'Z':
    case '[': case '\\': case ']': case '^': case '_':
    case 'a': case 'b': case 'c': case 'd': case 'e':
    case 'f': case 'g': case 'h': case 'i': case 'j':
    case 'k': case 'l': case 'm': case 'n': case 'o':
    case 'p': case 'q': case 'r': case 's': case 't':
    case 'u': case 'v': case 'w': case 'x': case 'y':
    case 'z': case '{': case '|': case '}': case '~':
      return 1;
    default:
      return 0;
    }
}

#endif

#endif /* _MBCHAR_H */

--- NEW FILE: asprintf.c ---
/* Formatted output to strings.
   Copyright (C) 1999, 2002, 2006 Free Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License along
   with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

#include <config.h>

/* Specification.  */
#include "vasprintf.h"

#include <stdarg.h>

int
asprintf (char **resultp, const char *format, ...)
{
  va_list args;
  int result;

  va_start (args, format);
  result = vasprintf (resultp, format, args);
  va_end (args);
  return result;
}

--- NEW FILE: safe-read.c ---
/* An interface to read and write that retries after interrupts.

   Copyright (C) 1993, 1994, 1998, 2002, 2003, 2004, 2005, 2006 Free
   Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

#include <config.h>

/* Specification.  */
#ifdef SAFE_WRITE
# include "safe-write.h"
#else
# include "safe-read.h"
#endif

/* Get ssize_t.  */
#include <sys/types.h>
#include <unistd.h>

#include <errno.h>

#ifdef EINTR
# define IS_EINTR(x) ((x) == EINTR)
#else
# define IS_EINTR(x) 0
#endif

#include <limits.h>

#ifdef SAFE_WRITE
# define safe_rw safe_write
# define rw write
#else
# define safe_rw safe_read
# define rw read
# undef const
# define const /* empty */
#endif

/* Read(write) up to COUNT bytes at BUF from(to) descriptor FD, retrying if
   interrupted.  Return the actual number of bytes read(written), zero for EOF,
   or SAFE_READ_ERROR(SAFE_WRITE_ERROR) upon error.  */
size_t
safe_rw (int fd, void const *buf, size_t count)
{
  /* Work around a bug in Tru64 5.1.  Attempting to read more than
     INT_MAX bytes fails with errno == EINVAL.  See
     <http://lists.gnu.org/archive/html/bug-gnu-utils/2002-04/msg00010.html>.
     When decreasing COUNT, keep it block-aligned.  */
  enum { BUGGY_READ_MAXIMUM = INT_MAX & ~8191 };

  for (;;)
    {
      ssize_t result = rw (fd, buf, count);

      if (0 <= result)
	return result;
      else if (IS_EINTR (errno))
	continue;
      else if (errno == EINVAL && BUGGY_READ_MAXIMUM < count)
	count = BUGGY_READ_MAXIMUM;
      else
	return result;
    }
}

--- NEW FILE: memchr.c ---
/* Copyright (C) 1991, 1993, 1996, 1997, 1999, 2000, 2003, 2004, 2006 Free
   Software Foundation, Inc.

   Based on strlen implementation by Torbjorn Granlund (tege at sics.se),
   with help from Dan Sahlin (dan at sics.se) and
   commentary by Jim Blandy (jimb at ai.mit.edu);
   adaptation to memchr suggested by Dick Karpinski (dick at cca.ucsf.edu),
   and implemented by Roland McGrath (roland at ai.mit.edu).

NOTE: The canonical source of this file is maintained with the GNU C Library.
Bugs can be reported to bug-glibc at prep.ai.mit.edu.

This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.

This program 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 General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

#ifndef _LIBC
# include <config.h>
#endif

#include <string.h>

#include <stddef.h>

#if defined _LIBC
# include <memcopy.h>
#else
# define reg_char char
#endif

#include <limits.h>

#if HAVE_BP_SYM_H || defined _LIBC
# include <bp-sym.h>
#else
# define BP_SYM(sym) sym
#endif

#undef memchr
#undef __memchr

/* Search no more than N bytes of S for C.  */
void *
__memchr (void const *s, int c_in, size_t n)
{
  const unsigned char *char_ptr;
  const unsigned long int *longword_ptr;
  unsigned long int longword, magic_bits, charmask;
  unsigned reg_char c;
  int i;

  c = (unsigned char) c_in;

  /* 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;
       n > 0 && (size_t) char_ptr % sizeof longword != 0;
       --n, ++char_ptr)
    if (*char_ptr == c)
      return (void *) char_ptr;

  /* All these elucidatory comments refer to 4-byte longwords,
     but the theory applies equally well to any size longwords.  */

  longword_ptr = (const 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.  */

  /* Set MAGIC_BITS to be this pattern of 1 and 0 bits.
     Set CHARMASK to be a longword, each of whose bytes is C.  */

  magic_bits = 0xfefefefe;
  charmask = c | (c << 8);
  charmask |= charmask << 16;
#if 0xffffffffU < ULONG_MAX
  magic_bits |= magic_bits << 32;
  charmask |= charmask << 32;
  if (8 < sizeof longword)
    for (i = 64; i < sizeof longword * 8; i *= 2)
      {
	magic_bits |= magic_bits << i;
	charmask |= charmask << i;
      }
#endif
  magic_bits = (ULONG_MAX >> 1) & (magic_bits | 1);

  /* 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.  */
  while (n >= sizeof longword)
    {
      /* 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, not 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++ ^ charmask;

      /* 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)
	{
	  /* Which of the bytes was C?  If none of them were, it was
	     a misfire; continue the search.  */

	  const unsigned char *cp = (const unsigned char *) (longword_ptr - 1);

	  if (cp[0] == c)
	    return (void *) cp;
	  if (cp[1] == c)
	    return (void *) &cp[1];
	  if (cp[2] == c)
	    return (void *) &cp[2];
	  if (cp[3] == c)
	    return (void *) &cp[3];
	  if (4 < sizeof longword && cp[4] == c)
	    return (void *) &cp[4];
	  if (5 < sizeof longword && cp[5] == c)
	    return (void *) &cp[5];
	  if (6 < sizeof longword && cp[6] == c)
	    return (void *) &cp[6];
	  if (7 < sizeof longword && cp[7] == c)
	    return (void *) &cp[7];
	  if (8 < sizeof longword)
	    for (i = 8; i < sizeof longword; i++)
	      if (cp[i] == c)
		return (void *) &cp[i];
	}

      n -= sizeof longword;
    }

  char_ptr = (const unsigned char *) longword_ptr;

  while (n-- > 0)
    {
      if (*char_ptr == c)
	return (void *) char_ptr;
      else
	++char_ptr;
    }

  return 0;
}
#ifdef weak_alias
weak_alias (__memchr, BP_SYM (memchr))
#endif

--- NEW FILE: safe-read.h ---
/* An interface to read() that retries after interrupts.
   Copyright (C) 2002, 2006 Free Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

#include <stddef.h>

#ifdef __cplusplus
extern "C" {
#endif


#define SAFE_READ_ERROR ((size_t) -1)

/* Read up to COUNT bytes at BUF from descriptor FD, retrying if interrupted.
   Return the actual number of bytes read, zero for EOF, or SAFE_READ_ERROR
   upon error.  */
extern size_t safe_read (int fd, void *buf, size_t count);


#ifdef __cplusplus
}
#endif

--- NEW FILE: wcwidth.h ---
/* Determine the number of screen columns needed for a character.
   Copyright (C) 2006, 2007 Free Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

#ifndef _gl_WCWIDTH_H
#define _gl_WCWIDTH_H

#if HAVE_WCHAR_T

/* Get wcwidth if available, along with wchar_t.  */
# include <wchar.h>

/* Get iswprint.  */
# include <wctype.h>

# ifndef HAVE_DECL_WCWIDTH
"this configure-time declaration test was not run"
# endif
# ifndef wcwidth
#  if !HAVE_WCWIDTH

/* wcwidth doesn't exist, so assume all printable characters have
   width 1.  */
static inline int
wcwidth (wchar_t wc)
{
  return wc == 0 ? 0 : iswprint (wc) ? 1 : -1;
}

#  elif !HAVE_DECL_WCWIDTH

/* wcwidth exists but is not declared.  */
extern
#   ifdef __cplusplus
"C"
#   endif
int wcwidth (int /* actually wchar_t */);

#  endif
# endif

#endif /* HAVE_WCHAR_T */

#endif /* _gl_WCWIDTH_H */

--- NEW FILE: getopt.c ---
/* Getopt for GNU.
   NOTE: getopt is now part of the C library, so if you don't know what
   "Keep this file name-space clean" means, talk to drepper at gnu.org
   before changing it!
   Copyright (C) 1987,88,89,90,91,92,93,94,95,96,98,99,2000,2001,2002,2003,2004,2006
	Free Software Foundation, Inc.
   This file is part of the GNU C Library.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License along
[...1152 lines suppressed...]
	case '?':
	  break;

	default:
	  printf ("?? getopt returned character code 0%o ??\n", c);
	}
    }

  if (optind < argc)
    {
      printf ("non-option ARGV-elements: ");
      while (optind < argc)
	printf ("%s ", argv[optind++]);
      printf ("\n");
    }

  exit (0);
}

#endif /* TEST */

--- NEW FILE: error.h ---
/* Declaration for error-reporting function
   Copyright (C) 1995, 1996, 1997, 2003, 2006 Free Software Foundation, Inc.
   This file is part of the GNU C Library.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License along
   with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

#ifndef _ERROR_H
#define _ERROR_H 1

#ifndef __attribute__
/* This feature is available in gcc versions 2.5 and later.  */
# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) || __STRICT_ANSI__
#  define __attribute__(Spec) /* empty */
# endif
/* The __-protected variants of `format' and `printf' attributes
   are accepted by gcc versions 2.6.4 (effectively 2.7) and later.  */
# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7)
#  define __format__ format
#  define __printf__ printf
# endif
#endif

#ifdef	__cplusplus
extern "C" {
#endif

/* Print a message with `fprintf (stderr, FORMAT, ...)';
   if ERRNUM is nonzero, follow it with ": " and strerror (ERRNUM).
   If STATUS is nonzero, terminate the program with `exit (STATUS)'.  */

extern void error (int __status, int __errnum, const char *__format, ...)
     __attribute__ ((__format__ (__printf__, 3, 4)));

extern void error_at_line (int __status, int __errnum, const char *__fname,
			   unsigned int __lineno, const char *__format, ...)
     __attribute__ ((__format__ (__printf__, 5, 6)));

/* If NULL, error will flush stdout, then print on stderr the program
   name, a colon and a space.  Otherwise, error will call this
   function without parameters instead.  */
extern void (*error_print_progname) (void);

/* This variable is incremented each time `error' is called.  */
extern unsigned int error_message_count;

/* Sometimes we want to have at most one error per line.  This
   variable controls whether this mode is selected or not.  */
extern int error_one_per_line;

#ifdef	__cplusplus
}
#endif

#endif /* error.h */

--- NEW FILE: printf-args.c ---
/* Decomposed printf argument list.
   Copyright (C) 1999, 2002-2003, 2005-2006 Free Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License along
   with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

#include <config.h>

/* Specification.  */
#include "printf-args.h"

#ifdef STATIC
STATIC
#endif
int
printf_fetchargs (va_list args, arguments *a)
{
  size_t i;
  argument *ap;

  for (i = 0, ap = &a->arg[0]; i < a->count; i++, ap++)
    switch (ap->type)
      {
      case TYPE_SCHAR:
	ap->a.a_schar = va_arg (args, /*signed char*/ int);
	break;
      case TYPE_UCHAR:
	ap->a.a_uchar = va_arg (args, /*unsigned char*/ int);
	break;
      case TYPE_SHORT:
	ap->a.a_short = va_arg (args, /*short*/ int);
	break;
      case TYPE_USHORT:
	ap->a.a_ushort = va_arg (args, /*unsigned short*/ int);
	break;
      case TYPE_INT:
	ap->a.a_int = va_arg (args, int);
	break;
      case TYPE_UINT:
	ap->a.a_uint = va_arg (args, unsigned int);
	break;
      case TYPE_LONGINT:
	ap->a.a_longint = va_arg (args, long int);
	break;
      case TYPE_ULONGINT:
	ap->a.a_ulongint = va_arg (args, unsigned long int);
	break;
#ifdef HAVE_LONG_LONG_INT
      case TYPE_LONGLONGINT:
	ap->a.a_longlongint = va_arg (args, long long int);
	break;
      case TYPE_ULONGLONGINT:
	ap->a.a_ulonglongint = va_arg (args, unsigned long long int);
	break;
#endif
      case TYPE_DOUBLE:
	ap->a.a_double = va_arg (args, double);
	break;
#ifdef HAVE_LONG_DOUBLE
      case TYPE_LONGDOUBLE:
	ap->a.a_longdouble = va_arg (args, long double);
	break;
#endif
      case TYPE_CHAR:
	ap->a.a_char = va_arg (args, int);
	break;
#ifdef HAVE_WINT_T
      case TYPE_WIDE_CHAR:
	/* Although ISO C 99 7.24.1.(2) says that wint_t is "unchanged by
	   default argument promotions", this is not the case in mingw32,
	   where wint_t is 'unsigned short'.  */
	ap->a.a_wide_char =
	  (sizeof (wint_t) < sizeof (int)
	   ? va_arg (args, int)
	   : va_arg (args, wint_t));
	break;
#endif
      case TYPE_STRING:
	ap->a.a_string = va_arg (args, const char *);
	/* A null pointer is an invalid argument for "%s", but in practice
	   it occurs quite frequently in printf statements that produce
	   debug output.  Use a fallback in this case.  */
	if (ap->a.a_string == NULL)
	  ap->a.a_string = "(NULL)";
	break;
#ifdef HAVE_WCHAR_T
      case TYPE_WIDE_STRING:
	ap->a.a_wide_string = va_arg (args, const wchar_t *);
	/* A null pointer is an invalid argument for "%ls", but in practice
	   it occurs quite frequently in printf statements that produce
	   debug output.  Use a fallback in this case.  */
	if (ap->a.a_wide_string == NULL)
	  {
	    static const wchar_t wide_null_string[] =
	      {
		(wchar_t)'(',
		(wchar_t)'N', (wchar_t)'U', (wchar_t)'L', (wchar_t)'L',
		(wchar_t)')',
		(wchar_t)0
	      };
	    ap->a.a_wide_string = wide_null_string;
	  }
	break;
#endif
      case TYPE_POINTER:
	ap->a.a_pointer = va_arg (args, void *);
	break;
      case TYPE_COUNT_SCHAR_POINTER:
	ap->a.a_count_schar_pointer = va_arg (args, signed char *);
	break;
      case TYPE_COUNT_SHORT_POINTER:
	ap->a.a_count_short_pointer = va_arg (args, short *);
	break;
      case TYPE_COUNT_INT_POINTER:
	ap->a.a_count_int_pointer = va_arg (args, int *);
	break;
      case TYPE_COUNT_LONGINT_POINTER:
	ap->a.a_count_longint_pointer = va_arg (args, long int *);
	break;
#ifdef HAVE_LONG_LONG_INT
      case TYPE_COUNT_LONGLONGINT_POINTER:
	ap->a.a_count_longlongint_pointer = va_arg (args, long long int *);
	break;
#endif
      default:
	/* Unknown type.  */
	return -1;
      }
  return 0;
}

--- NEW FILE: asnprintf.c ---
/* Formatted output to strings.
   Copyright (C) 1999, 2002, 2006 Free Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License along
   with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

#include <config.h>

/* Specification.  */
#include "vasnprintf.h"

#include <stdarg.h>

char *
asnprintf (char *resultbuf, size_t *lengthp, const char *format, ...)
{
  va_list args;
  char *result;

  va_start (args, format);
  result = vasnprintf (resultbuf, lengthp, format, args);
  va_end (args);
  return result;
}

--- NEW FILE: printf-args.h ---
/* Decomposed printf argument list.
   Copyright (C) 1999, 2002-2003, 2006 Free Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License along
   with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

#ifndef _PRINTF_ARGS_H
#define _PRINTF_ARGS_H

/* Get size_t.  */
#include <stddef.h>

/* Get wchar_t.  */
#ifdef HAVE_WCHAR_T
# include <stddef.h>
#endif

/* Get wint_t.  */
#ifdef HAVE_WINT_T
# include <wchar.h>
#endif

/* Get va_list.  */
#include <stdarg.h>


/* Argument types */
typedef enum
{
  TYPE_NONE,
  TYPE_SCHAR,
  TYPE_UCHAR,
  TYPE_SHORT,
  TYPE_USHORT,
  TYPE_INT,
  TYPE_UINT,
  TYPE_LONGINT,
  TYPE_ULONGINT,
#ifdef HAVE_LONG_LONG_INT
  TYPE_LONGLONGINT,
  TYPE_ULONGLONGINT,
#endif
  TYPE_DOUBLE,
#ifdef HAVE_LONG_DOUBLE
  TYPE_LONGDOUBLE,
#endif
  TYPE_CHAR,
#ifdef HAVE_WINT_T
  TYPE_WIDE_CHAR,
#endif
  TYPE_STRING,
#ifdef HAVE_WCHAR_T
  TYPE_WIDE_STRING,
#endif
  TYPE_POINTER,
  TYPE_COUNT_SCHAR_POINTER,
  TYPE_COUNT_SHORT_POINTER,
  TYPE_COUNT_INT_POINTER,
  TYPE_COUNT_LONGINT_POINTER
#ifdef HAVE_LONG_LONG_INT
, TYPE_COUNT_LONGLONGINT_POINTER
#endif
} arg_type;

/* Polymorphic argument */
typedef struct
{
  arg_type type;
  union
  {
    signed char			a_schar;
    unsigned char		a_uchar;
    short			a_short;
    unsigned short		a_ushort;
    int				a_int;
    unsigned int		a_uint;
    long int			a_longint;
    unsigned long int		a_ulongint;
#ifdef HAVE_LONG_LONG_INT
    long long int		a_longlongint;
    unsigned long long int	a_ulonglongint;
#endif
    float			a_float;
    double			a_double;
#ifdef HAVE_LONG_DOUBLE
    long double			a_longdouble;
#endif
    int				a_char;
#ifdef HAVE_WINT_T
    wint_t			a_wide_char;
#endif
    const char*			a_string;
#ifdef HAVE_WCHAR_T
    const wchar_t*		a_wide_string;
#endif
    void*			a_pointer;
    signed char *		a_count_schar_pointer;
    short *			a_count_short_pointer;
    int *			a_count_int_pointer;
    long int *			a_count_longint_pointer;
#ifdef HAVE_LONG_LONG_INT
    long long int *		a_count_longlongint_pointer;
#endif
  }
  a;
}
argument;

typedef struct
{
  size_t count;
  argument *arg;
}
arguments;


/* Fetch the arguments, putting them into a. */
#ifdef STATIC
STATIC
#else
extern
#endif
int printf_fetchargs (va_list args, arguments *a);

#endif /* _PRINTF_ARGS_H */

--- NEW FILE: strcasecmp.c ---
/* Case-insensitive string comparison function.
   Copyright (C) 1998-1999, 2005-2006 Free Software Foundation, Inc.
   Written by Bruno Haible <bruno at clisp.org>, 2005,
   based on earlier glibc code.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

#include <config.h>

/* Specification.  */
#include "strcase.h"

#include <ctype.h>
#include <limits.h>

#if HAVE_MBRTOWC
# include "mbuiter.h"
#endif

#define TOLOWER(Ch) (isupper (Ch) ? tolower (Ch) : (Ch))

/* Compare strings S1 and S2, ignoring case, returning less than, equal to or
   greater than zero if S1 is lexicographically less than, equal to or greater
   than S2.
   Note: This function may, in multibyte locales, return 0 for strings of
   different lengths!  */
int
strcasecmp (const char *s1, const char *s2)
{
  if (s1 == s2)
    return 0;

  /* Be careful not to look at the entire extent of s1 or s2 until needed.
     This is useful because when two strings differ, the difference is
     most often already in the very few first characters.  */
#if HAVE_MBRTOWC
  if (MB_CUR_MAX > 1)
    {
      mbui_iterator_t iter1;
      mbui_iterator_t iter2;

      mbui_init (iter1, s1);
      mbui_init (iter2, s2);

      while (mbui_avail (iter1) && mbui_avail (iter2))
	{
	  int cmp = mb_casecmp (mbui_cur (iter1), mbui_cur (iter2));

	  if (cmp != 0)
	    return cmp;

	  mbui_advance (iter1);
	  mbui_advance (iter2);
	}
      if (mbui_avail (iter1))
	/* s2 terminated before s1.  */
	return 1;
      if (mbui_avail (iter2))
	/* s1 terminated before s2.  */
	return -1;
      return 0;
    }
  else
#endif
    {
      const unsigned char *p1 = (const unsigned char *) s1;
      const unsigned char *p2 = (const unsigned char *) s2;
      unsigned char c1, c2;

      do
	{
	  c1 = TOLOWER (*p1);
	  c2 = TOLOWER (*p2);

	  if (c1 == '\0')
	    break;

	  ++p1;
	  ++p2;
	}
      while (c1 == c2);

      if (UCHAR_MAX <= INT_MAX)
	return c1 - c2;
      else
	/* On machines where 'char' and 'int' are types of the same size, the
	   difference of two 'unsigned char' values - including the sign bit -
	   doesn't fit in an 'int'.  */
	return (c1 > c2 ? 1 : c1 < c2 ? -1 : 0);
    }
}

--- NEW FILE: unistd_.h ---
/* Substitute for and wrapper around <unistd.h>.
   Copyright (C) 2006 Free Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

#ifndef _GL_UNISTD_H
#define _GL_UNISTD_H

#if HAVE_UNISTD_H
# include @ABSOLUTE_UNISTD_H@
#endif


/* Declare overridden functions.  */

#ifdef __cplusplus
extern "C" {
#endif

#ifdef FCHDIR_REPLACEMENT

/* Change the process' current working directory to the directory on which
   the given file descriptor is open.  */
extern int fchdir (int /*fd*/);

# define close rpl_close
extern int close (int);
# define dup rpl_dup
extern int dup (int);
# define dup2 rpl_dup2
extern int dup2 (int, int);

#endif

#ifdef __cplusplus
}
#endif


#endif /* _GL_UNISTD_H */

--- NEW FILE: alloca_.h ---
/* Memory allocation on the stack.

   Copyright (C) 1995, 1999, 2001, 2002, 2003, 2004, 2006 Free Software
   Foundation, Inc.

   This program is free software; you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published
   by the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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
   General Public License for more details.

   You should have received a copy of the GNU General Public
   License along with this program; if not, write to the Free Software
   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
   USA.  */

/* Avoid using the symbol _ALLOCA_H here, as Bison assumes _ALLOCA_H
   means there is a real alloca function.  */
#ifndef _GNULIB_ALLOCA_H
# define _GNULIB_ALLOCA_H

/* alloca (N) returns a pointer to N bytes of memory
   allocated on the stack, which will last until the function returns.
   Use of alloca should be avoided:
     - inside arguments of function calls - undefined behaviour,
     - in inline functions - the allocation may actually last until the
       calling function returns,
     - for huge N (say, N >= 65536) - you never know how large (or small)
       the stack is, and when the stack cannot fulfill the memory allocation
       request, the program just crashes.
 */

#ifndef alloca
# ifdef __GNUC__
#  define alloca __builtin_alloca
# elif defined _AIX
#  define alloca __alloca
# elif defined _MSC_VER
#  include <malloc.h>
#  define alloca _alloca
# else
#  include <stddef.h>
#  ifdef  __cplusplus
extern "C"
#  endif
void *alloca (size_t);
# endif
#endif

#endif /* _GNULIB_ALLOCA_H */

--- NEW FILE: basename.c ---
/* basename.c -- return the last element in a file name

   Copyright (C) 1990, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006 Free
   Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

#include <config.h>

#include "dirname.h"

#include <string.h>
#include "xalloc.h"
#include "xstrndup.h"

/* Return the address of the last file name component of NAME.  If
   NAME has no relative file name components because it is a file
   system root, return the empty string.  */

char *
last_component (char const *name)
{
  char const *base = name + FILE_SYSTEM_PREFIX_LEN (name);
  char const *p;
  bool saw_slash = false;

  while (ISSLASH (*base))
    base++;

  for (p = base; *p; p++)
    {
      if (ISSLASH (*p))
	saw_slash = true;
      else if (saw_slash)
	{
	  base = p;
	  saw_slash = false;
	}
    }

  return (char *) base;
}


/* In general, we can't use the builtin `basename' function if available,
   since it has different meanings in different environments.
   In some environments the builtin `basename' modifies its argument.

   Return the last file name component of NAME, allocated with
   xmalloc.  On systems with drive letters, a leading "./"
   distinguishes relative names that would otherwise look like a drive
   letter.  Unlike POSIX basename(), NAME cannot be NULL,
   base_name("") returns "", and the first trailing slash is not
   stripped.

   If lstat (NAME) would succeed, then { chdir (dir_name (NAME));
   lstat (base_name (NAME)); } will access the same file.  Likewise,
   if the sequence { chdir (dir_name (NAME));
   rename (base_name (NAME), "foo"); } succeeds, you have renamed NAME
   to "foo" in the same directory NAME was in.  */

char *
base_name (char const *name)
{
  char const *base = last_component (name);
  size_t length;

  /* If there is no last component, then name is a file system root or the
     empty string.  */
  if (! *base)
    return xstrndup (name, base_len (name));

  /* Collapse a sequence of trailing slashes into one.  */
  length = base_len (base);
  if (ISSLASH (base[length]))
    length++;

  /* On systems with drive letters, `a/b:c' must return `./b:c' rather
     than `b:c' to avoid confusion with a drive letter.  On systems
     with pure POSIX semantics, this is not an issue.  */
  if (FILE_SYSTEM_PREFIX_LEN (base))
    {
      char *p = xmalloc (length + 3);
      p[0] = '.';
      p[1] = '/';
      memcpy (p + 2, base, length);
      p[length + 2] = '\0';
      return p;
    }

  /* Finally, copy the basename.  */
  return xstrndup (base, length);
}

/* Return the length of the basename NAME.  Typically NAME is the
   value returned by base_name or last_component.  Act like strlen
   (NAME), except omit all trailing slashes.  */

size_t
base_len (char const *name)
{
  size_t len;
  size_t prefix_len = FILE_SYSTEM_PREFIX_LEN (name);

  for (len = strlen (name);  1 < len && ISSLASH (name[len - 1]);  len--)
    continue;

  if (DOUBLE_SLASH_IS_DISTINCT_ROOT && len == 1
      && ISSLASH (name[0]) && ISSLASH (name[1]) && ! name[2])
    return 2;

  if (FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE && prefix_len
      && len == prefix_len && ISSLASH (name[prefix_len]))
    return prefix_len + 1;

  return len;
}

--- NEW FILE: socket_.h ---
/* Provide a sys/socket header file for systems lacking it (read: MinGW).
   Copyright (C) 2005, 2006 Free Software Foundation, Inc.
   Written by Simon Josefsson.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

#ifndef _SYS_SOCKET_H
#define _SYS_SOCKET_H

/* This file is supposed to be used on platforms that lack
   sys/socket.h.  It is intended to provide definitions and prototypes
   needed by an application.

   Currently only MinGW is supported.  See the gnulib manual regarding
   Windows sockets.  MinGW has the header files winsock2.h and
   ws2tcpip.h that declare the sys/socket.h definitions we need.  Note
   that you can influence which definitions you get by setting the
   WINVER symbol before including these two files.  For example,
   getaddrinfo is only available if _WIN32_WINNT >= 0x0501 (that
   symbol is set indiriectly through WINVER).  You can set this by
   adding AC_DEFINE(WINVER, 0x0501) to configure.ac.  Note that your
   code may not run on older Windows releases then.  My Windows 2000
   box was not able to run the code, for example.  The situation is
   slightly confusing because:
   http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winsock/winsock/getaddrinfo_2.asp
   suggests that getaddrinfo should be available on all Windows
   releases. */


#if HAVE_WINSOCK2_H
# include <winsock2.h>
#endif
#if HAVE_WS2TCPIP_H
# include <ws2tcpip.h>
#endif

/* For shutdown(). */
#if !defined SHUT_RD && defined SD_RECEIVE
# define SHUT_RD SD_RECEIVE
#endif
#if !defined SHUT_WR && defined SD_SEND
# define SHUT_WR SD_SEND
#endif
#if !defined SHUT_RDWR && defined SD_BOTH
# define SHUT_RDWR SD_BOTH
#endif

#if defined _WIN32 || defined __WIN32__
# define ENOTSOCK                WSAENOTSOCK
# define EADDRINUSE              WSAEADDRINUSE
# define ENETRESET               WSAENETRESET
# define ECONNABORTED            WSAECONNABORTED
# define ECONNRESET              WSAECONNRESET
# define ENOTCONN                WSAENOTCONN
# define ESHUTDOWN               WSAESHUTDOWN
#endif

#endif /* _SYS_SOCKET_H */

--- NEW FILE: vasprintf.c ---
/* Formatted output to strings.
   Copyright (C) 1999, 2002, 2006 Free Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License along
   with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

#include <config.h>

/* Specification.  */
#include "vasprintf.h"

#include <errno.h>
#include <limits.h>
#include <stdlib.h>

#include "vasnprintf.h"

/* Some systems, like OSF/1 4.0 and Woe32, don't have EOVERFLOW.  */
#ifndef EOVERFLOW
# define EOVERFLOW E2BIG
#endif

int
vasprintf (char **resultp, const char *format, va_list args)
{
  size_t length;
  char *result = vasnprintf (NULL, &length, format, args);
  if (result == NULL)
    return -1;

  if (length > INT_MAX)
    {
      free (result);
      errno = EOVERFLOW;
      return -1;
    }

  *resultp = result;
  /* Return the number of resulting bytes, excluding the trailing NUL.  */
  return length;
}

--- NEW FILE: fcntl-safer.h ---
/* Invoke fcntl-like functions, but avoid some glitches.

   Copyright (C) 2005 Free Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

/* Written by Paul Eggert.  */

#include <sys/types.h>

int open_safer (char const *, int, ...);
int creat_safer (char const *, mode_t);

--- NEW FILE: regex.c ---
/* Extended regular expression matching and search library.
   Copyright (C) 2002, 2003, 2005, 2006 Free Software Foundation, Inc.
   This file is part of the GNU C Library.
   Contributed by Isamu Hasegawa <isamu at yamato.ibm.com>.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License along
   with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */

#include <config.h>

/* Make sure noone compiles this code with a C++ compiler.  */
#if defined __cplusplus && defined _LIBC
# error "This is C code, use a C compiler"
#endif

#ifdef _LIBC
/* We have to keep the namespace clean.  */
# define regfree(preg) __regfree (preg)
# define regexec(pr, st, nm, pm, ef) __regexec (pr, st, nm, pm, ef)
# define regcomp(preg, pattern, cflags) __regcomp (preg, pattern, cflags)
# define regerror(errcode, preg, errbuf, errbuf_size) \
	__regerror(errcode, preg, errbuf, errbuf_size)
# define re_set_registers(bu, re, nu, st, en) \
	__re_set_registers (bu, re, nu, st, en)
# define re_match_2(bufp, string1, size1, string2, size2, pos, regs, stop) \
	__re_match_2 (bufp, string1, size1, string2, size2, pos, regs, stop)
# define re_match(bufp, string, size, pos, regs) \
	__re_match (bufp, string, size, pos, regs)
# define re_search(bufp, string, size, startpos, range, regs) \
	__re_search (bufp, string, size, startpos, range, regs)
# define re_compile_pattern(pattern, length, bufp) \
	__re_compile_pattern (pattern, length, bufp)
# define re_set_syntax(syntax) __re_set_syntax (syntax)
# define re_search_2(bufp, st1, s1, st2, s2, startpos, range, regs, stop) \
	__re_search_2 (bufp, st1, s1, st2, s2, startpos, range, regs, stop)
# define re_compile_fastmap(bufp) __re_compile_fastmap (bufp)

# include "../locale/localeinfo.h"
#endif

/* On some systems, limits.h sets RE_DUP_MAX to a lower value than
   GNU regex allows.  Include it before <regex.h>, which correctly
   #undefs RE_DUP_MAX and sets it to the right value.  */
#include <limits.h>

#include <regex.h>
#include "regex_internal.h"

#include "regex_internal.c"
#include "regcomp.c"
#include "regexec.c"

/* Binary backward compatibility.  */
#if _LIBC
# include <shlib-compat.h>
# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3)
link_warning (re_max_failures, "the 're_max_failures' variable is obsolete and will go away.")
int re_max_failures = 2000;
# endif
#endif

--- NEW FILE: vasprintf.h ---
/* vsprintf with automatic memory allocation.
   Copyright (C) 2002-2003 Free Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

#ifndef _VASPRINTF_H
#define _VASPRINTF_H

#if HAVE_VASPRINTF

/* Get asprintf(), vasprintf() declarations.  */
#include <stdio.h>

#else

/* Get va_list.  */
#include <stdarg.h>

#ifndef __attribute__
/* This feature is available in gcc versions 2.5 and later.  */
# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) || __STRICT_ANSI__
#  define __attribute__(Spec) /* empty */
# endif
/* The __-protected variants of `format' and `printf' attributes
   are accepted by gcc versions 2.6.4 (effectively 2.7) and later.  */
# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7)
#  define __format__ format
#  define __printf__ printf
# endif
#endif

#ifdef	__cplusplus
extern "C" {
#endif

/* Write formatted output to a string dynamically allocated with malloc().
   If the memory allocation succeeds, store the address of the string in
   *RESULT and return the number of resulting bytes, excluding the trailing
   NUL.  Upon memory allocation error, or some other error, return -1.  */
extern int asprintf (char **result, const char *format, ...)
       __attribute__ ((__format__ (__printf__, 2, 3)));
extern int vasprintf (char **result, const char *format, va_list args)
       __attribute__ ((__format__ (__printf__, 2, 0)));

#ifdef	__cplusplus
}
#endif

#endif

#endif /* _VASPRINTF_H */

--- NEW FILE: regex.h ---
/* Definitions for data structures and routines for the regular
   expression library.
   Copyright (C) 1985,1989-93,1995-98,2000,2001,2002,2003,2005,2006
   Free Software Foundation, Inc.
   This file is part of the GNU C Library.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License along
   with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */

#ifndef _REGEX_H
#define _REGEX_H 1

#include <sys/types.h>

/* Allow the use in C++ code.  */
#ifdef __cplusplus
extern "C" {
#endif

/* Define __USE_GNU_REGEX to declare GNU extensions that violate the
   POSIX name space rules.  */
#undef __USE_GNU_REGEX
#if (defined _GNU_SOURCE					\
     || (!defined _POSIX_C_SOURCE && !defined _POSIX_SOURCE	\
	 && !defined _XOPEN_SOURCE))
# define __USE_GNU_REGEX 1
#endif

#ifdef _REGEX_LARGE_OFFSETS

/* Use types and values that are wide enough to represent signed and
   unsigned byte offsets in memory.  This currently works only when
   the regex code is used outside of the GNU C library; it is not yet
   supported within glibc itself, and glibc users should not define
   _REGEX_LARGE_OFFSETS.  */

/* The type of the offset of a byte within a string.
   For historical reasons POSIX 1003.1-2004 requires that regoff_t be
   at least as wide as off_t.  However, many common POSIX platforms set
   regoff_t to the more-sensible ssize_t and the Open Group has
   signalled its intention to change the requirement to be that
   regoff_t be at least as wide as ptrdiff_t and ssize_t; see XBD ERN
   60 (2005-08-25).  We don't know of any hosts where ssize_t or
   ptrdiff_t is wider than ssize_t, so ssize_t is safe.  */
typedef ssize_t regoff_t;

/* The type of nonnegative object indexes.  Traditionally, GNU regex
   uses 'int' for these.  Code that uses __re_idx_t should work
   regardless of whether the type is signed.  */
typedef size_t __re_idx_t;

/* The type of object sizes.  */
typedef size_t __re_size_t;

/* The type of object sizes, in places where the traditional code
   uses unsigned long int.  */
typedef size_t __re_long_size_t;

#else

/* Use types that are binary-compatible with the traditional GNU regex
   implementation, which mishandles strings longer than INT_MAX.  */

typedef int regoff_t;
typedef int __re_idx_t;
typedef unsigned int __re_size_t;
typedef unsigned long int __re_long_size_t;

#endif

/* The following two types have to be signed and unsigned integer type
   wide enough to hold a value of a pointer.  For most ANSI compilers
   ptrdiff_t and size_t should be likely OK.  Still size of these two
   types is 2 for Microsoft C.  Ugh... */
typedef long int s_reg_t;
typedef unsigned long int active_reg_t;

/* The following bits are used to determine the regexp syntax we
   recognize.  The set/not-set meanings are chosen so that Emacs syntax
   remains the value 0.  The bits are given in alphabetical order, and
   the definitions shifted by one from the previous bit; thus, when we
   add or remove a bit, only one other definition need change.  */
typedef unsigned long int reg_syntax_t;

#ifdef __USE_GNU_REGEX

/* If this bit is not set, then \ inside a bracket expression is literal.
   If set, then such a \ quotes the following character.  */
# define RE_BACKSLASH_ESCAPE_IN_LISTS ((unsigned long int) 1)

/* If this bit is not set, then + and ? are operators, and \+ and \? are
     literals.
   If set, then \+ and \? are operators and + and ? are literals.  */
# define RE_BK_PLUS_QM (RE_BACKSLASH_ESCAPE_IN_LISTS << 1)

/* If this bit is set, then character classes are supported.  They are:
     [:alpha:], [:upper:], [:lower:],  [:digit:], [:alnum:], [:xdigit:],
     [:space:], [:print:], [:punct:], [:graph:], and [:cntrl:].
   If not set, then character classes are not supported.  */
# define RE_CHAR_CLASSES (RE_BK_PLUS_QM << 1)

/* If this bit is set, then ^ and $ are always anchors (outside bracket
     expressions, of course).
   If this bit is not set, then it depends:
        ^  is an anchor if it is at the beginning of a regular
           expression or after an open-group or an alternation operator;
        $  is an anchor if it is at the end of a regular expression, or
           before a close-group or an alternation operator.

   This bit could be (re)combined with RE_CONTEXT_INDEP_OPS, because
   POSIX draft 11.2 says that * etc. in leading positions is undefined.
   We already implemented a previous draft which made those constructs
   invalid, though, so we haven't changed the code back.  */
# define RE_CONTEXT_INDEP_ANCHORS (RE_CHAR_CLASSES << 1)

/* If this bit is set, then special characters are always special
     regardless of where they are in the pattern.
   If this bit is not set, then special characters are special only in
     some contexts; otherwise they are ordinary.  Specifically,
     * + ? and intervals are only special when not after the beginning,
     open-group, or alternation operator.  */
# define RE_CONTEXT_INDEP_OPS (RE_CONTEXT_INDEP_ANCHORS << 1)

/* If this bit is set, then *, +, ?, and { cannot be first in an re or
     immediately after an alternation or begin-group operator.  */
# define RE_CONTEXT_INVALID_OPS (RE_CONTEXT_INDEP_OPS << 1)

/* If this bit is set, then . matches newline.
   If not set, then it doesn't.  */
# define RE_DOT_NEWLINE (RE_CONTEXT_INVALID_OPS << 1)

/* If this bit is set, then . doesn't match NUL.
   If not set, then it does.  */
# define RE_DOT_NOT_NULL (RE_DOT_NEWLINE << 1)

/* If this bit is set, nonmatching lists [^...] do not match newline.
   If not set, they do.  */
# define RE_HAT_LISTS_NOT_NEWLINE (RE_DOT_NOT_NULL << 1)

/* If this bit is set, either \{...\} or {...} defines an
     interval, depending on RE_NO_BK_BRACES.
   If not set, \{, \}, {, and } are literals.  */
# define RE_INTERVALS (RE_HAT_LISTS_NOT_NEWLINE << 1)

/* If this bit is set, +, ? and | aren't recognized as operators.
   If not set, they are.  */
# define RE_LIMITED_OPS (RE_INTERVALS << 1)

/* If this bit is set, newline is an alternation operator.
   If not set, newline is literal.  */
# define RE_NEWLINE_ALT (RE_LIMITED_OPS << 1)

/* If this bit is set, then `{...}' defines an interval, and \{ and \}
     are literals.
  If not set, then `\{...\}' defines an interval.  */
# define RE_NO_BK_BRACES (RE_NEWLINE_ALT << 1)

/* If this bit is set, (...) defines a group, and \( and \) are literals.
   If not set, \(...\) defines a group, and ( and ) are literals.  */
# define RE_NO_BK_PARENS (RE_NO_BK_BRACES << 1)

/* If this bit is set, then \<digit> matches <digit>.
   If not set, then \<digit> is a back-reference.  */
# define RE_NO_BK_REFS (RE_NO_BK_PARENS << 1)

/* If this bit is set, then | is an alternation operator, and \| is literal.
   If not set, then \| is an alternation operator, and | is literal.  */
# define RE_NO_BK_VBAR (RE_NO_BK_REFS << 1)

/* If this bit is set, then an ending range point collating higher
     than the starting range point, as in [z-a], is invalid.
   If not set, then when ending range point collates higher than the
     starting range point, the range is ignored.  */
# define RE_NO_EMPTY_RANGES (RE_NO_BK_VBAR << 1)

/* If this bit is set, then an unmatched ) is ordinary.
   If not set, then an unmatched ) is invalid.  */
# define RE_UNMATCHED_RIGHT_PAREN_ORD (RE_NO_EMPTY_RANGES << 1)

/* If this bit is set, succeed as soon as we match the whole pattern,
   without further backtracking.  */
# define RE_NO_POSIX_BACKTRACKING (RE_UNMATCHED_RIGHT_PAREN_ORD << 1)

/* If this bit is set, do not process the GNU regex operators.
   If not set, then the GNU regex operators are recognized. */
# define RE_NO_GNU_OPS (RE_NO_POSIX_BACKTRACKING << 1)

/* If this bit is set, turn on internal regex debugging.
   If not set, and debugging was on, turn it off.
   This only works if regex.c is compiled -DDEBUG.
   We define this bit always, so that all that's needed to turn on
   debugging is to recompile regex.c; the calling code can always have
   this bit set, and it won't affect anything in the normal case. */
# define RE_DEBUG (RE_NO_GNU_OPS << 1)

/* If this bit is set, a syntactically invalid interval is treated as
   a string of ordinary characters.  For example, the ERE 'a{1' is
   treated as 'a\{1'.  */
# define RE_INVALID_INTERVAL_ORD (RE_DEBUG << 1)

/* If this bit is set, then ignore case when matching.
   If not set, then case is significant.  */
# define RE_ICASE (RE_INVALID_INTERVAL_ORD << 1)

/* This bit is used internally like RE_CONTEXT_INDEP_ANCHORS but only
   for ^, because it is difficult to scan the regex backwards to find
   whether ^ should be special.  */
# define RE_CARET_ANCHORS_HERE (RE_ICASE << 1)

/* If this bit is set, then \{ cannot be first in an bre or
   immediately after an alternation or begin-group operator.  */
# define RE_CONTEXT_INVALID_DUP (RE_CARET_ANCHORS_HERE << 1)

/* If this bit is set, then no_sub will be set to 1 during
   re_compile_pattern.  */
# define RE_NO_SUB (RE_CONTEXT_INVALID_DUP << 1)

#endif /* defined __USE_GNU_REGEX */

/* This global variable defines the particular regexp syntax to use (for
   some interfaces).  When a regexp is compiled, the syntax used is
   stored in the pattern buffer, so changing this does not affect
   already-compiled regexps.  */
extern reg_syntax_t re_syntax_options;

#ifdef __USE_GNU_REGEX
/* Define combinations of the above bits for the standard possibilities.
   (The [[[ comments delimit what gets put into the Texinfo file, so
   don't delete them!)  */
/* [[[begin syntaxes]]] */
# define RE_SYNTAX_EMACS 0

# define RE_SYNTAX_AWK							\
  (RE_BACKSLASH_ESCAPE_IN_LISTS   | RE_DOT_NOT_NULL			\
   | RE_NO_BK_PARENS              | RE_NO_BK_REFS			\
   | RE_NO_BK_VBAR                | RE_NO_EMPTY_RANGES			\
   | RE_DOT_NEWLINE		  | RE_CONTEXT_INDEP_ANCHORS		\
   | RE_UNMATCHED_RIGHT_PAREN_ORD | RE_NO_GNU_OPS)

# define RE_SYNTAX_GNU_AWK						\
  ((RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS | RE_DEBUG)	\
   & ~(RE_DOT_NOT_NULL | RE_INTERVALS | RE_CONTEXT_INDEP_OPS		\
       | RE_CONTEXT_INVALID_OPS ))

# define RE_SYNTAX_POSIX_AWK						\
  (RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS		\
   | RE_INTERVALS	    | RE_NO_GNU_OPS)

# define RE_SYNTAX_GREP							\
  (RE_BK_PLUS_QM              | RE_CHAR_CLASSES				\
   | RE_HAT_LISTS_NOT_NEWLINE | RE_INTERVALS				\
   | RE_NEWLINE_ALT)

# define RE_SYNTAX_EGREP						\
  (RE_CHAR_CLASSES        | RE_CONTEXT_INDEP_ANCHORS			\
   | RE_CONTEXT_INDEP_OPS | RE_HAT_LISTS_NOT_NEWLINE			\
   | RE_NEWLINE_ALT       | RE_NO_BK_PARENS				\
   | RE_NO_BK_VBAR)

# define RE_SYNTAX_POSIX_EGREP						\
  (RE_SYNTAX_EGREP | RE_INTERVALS | RE_NO_BK_BRACES			\
   | RE_INVALID_INTERVAL_ORD)

/* P1003.2/D11.2, section 4.20.7.1, lines 5078ff.  */
# define RE_SYNTAX_ED RE_SYNTAX_POSIX_BASIC

# define RE_SYNTAX_SED RE_SYNTAX_POSIX_BASIC

/* Syntax bits common to both basic and extended POSIX regex syntax.  */
# define _RE_SYNTAX_POSIX_COMMON					\
  (RE_CHAR_CLASSES | RE_DOT_NEWLINE      | RE_DOT_NOT_NULL		\
   | RE_INTERVALS  | RE_NO_EMPTY_RANGES)

# define RE_SYNTAX_POSIX_BASIC						\
  (_RE_SYNTAX_POSIX_COMMON | RE_BK_PLUS_QM | RE_CONTEXT_INVALID_DUP)

/* Differs from ..._POSIX_BASIC only in that RE_BK_PLUS_QM becomes
   RE_LIMITED_OPS, i.e., \? \+ \| are not recognized.  Actually, this
   isn't minimal, since other operators, such as \`, aren't disabled.  */
# define RE_SYNTAX_POSIX_MINIMAL_BASIC					\
  (_RE_SYNTAX_POSIX_COMMON | RE_LIMITED_OPS)

# define RE_SYNTAX_POSIX_EXTENDED					\
  (_RE_SYNTAX_POSIX_COMMON  | RE_CONTEXT_INDEP_ANCHORS			\
   | RE_CONTEXT_INDEP_OPS   | RE_NO_BK_BRACES				\
   | RE_NO_BK_PARENS        | RE_NO_BK_VBAR				\
   | RE_CONTEXT_INVALID_OPS | RE_UNMATCHED_RIGHT_PAREN_ORD)

/* Differs from ..._POSIX_EXTENDED in that RE_CONTEXT_INDEP_OPS is
   removed and RE_NO_BK_REFS is added.  */
# define RE_SYNTAX_POSIX_MINIMAL_EXTENDED				\
  (_RE_SYNTAX_POSIX_COMMON  | RE_CONTEXT_INDEP_ANCHORS			\
   | RE_CONTEXT_INVALID_OPS | RE_NO_BK_BRACES				\
   | RE_NO_BK_PARENS        | RE_NO_BK_REFS				\
   | RE_NO_BK_VBAR	    | RE_UNMATCHED_RIGHT_PAREN_ORD)
/* [[[end syntaxes]]] */

#endif /* defined __USE_GNU_REGEX */

#ifdef __USE_GNU_REGEX

/* Maximum number of duplicates an interval can allow.  POSIX-conforming
   systems might define this in <limits.h>, but we want our
   value, so remove any previous define.  */
# ifdef RE_DUP_MAX
#  undef RE_DUP_MAX
# endif

/* RE_DUP_MAX is 2**15 - 1 because an earlier implementation stored
   the counter as a 2-byte signed integer.  This is no longer true, so
   RE_DUP_MAX could be increased to (INT_MAX / 10 - 1), or to
   ((SIZE_MAX - 2) / 10 - 1) if _REGEX_LARGE_OFFSETS is defined.
   However, there would be a huge performance problem if someone
   actually used a pattern like a\{214748363\}, so RE_DUP_MAX retains
   its historical value.  */
# define RE_DUP_MAX (0x7fff)

#endif /* defined __USE_GNU_REGEX */


/* POSIX `cflags' bits (i.e., information for `regcomp').  */

/* If this bit is set, then use extended regular expression syntax.
   If not set, then use basic regular expression syntax.  */
#define REG_EXTENDED 1

/* If this bit is set, then ignore case when matching.
   If not set, then case is significant.  */
#define REG_ICASE (1 << 1)

/* If this bit is set, then anchors do not match at newline
     characters in the string.
   If not set, then anchors do match at newlines.  */
#define REG_NEWLINE (1 << 2)

/* If this bit is set, then report only success or fail in regexec.
   If not set, then returns differ between not matching and errors.  */
#define REG_NOSUB (1 << 3)


/* POSIX `eflags' bits (i.e., information for regexec).  */

/* If this bit is set, then the beginning-of-line operator doesn't match
     the beginning of the string (presumably because it's not the
     beginning of a line).
   If not set, then the beginning-of-line operator does match the
     beginning of the string.  */
#define REG_NOTBOL 1

/* Like REG_NOTBOL, except for the end-of-line.  */
#define REG_NOTEOL (1 << 1)

/* Use PMATCH[0] to delimit the start and end of the search in the
   buffer.  */
#define REG_STARTEND (1 << 2)


/* If any error codes are removed, changed, or added, update the
   `__re_error_msgid' table in regcomp.c.  */

typedef enum
{
  _REG_ENOSYS = -1,	/* This will never happen for this implementation.  */
  _REG_NOERROR = 0,	/* Success.  */
  _REG_NOMATCH,		/* Didn't find a match (for regexec).  */

  /* POSIX regcomp return error codes.  (In the order listed in the
     standard.)  */
  _REG_BADPAT,		/* Invalid pattern.  */
  _REG_ECOLLATE,	/* Invalid collating element.  */
  _REG_ECTYPE,		/* Invalid character class name.  */
  _REG_EESCAPE,		/* Trailing backslash.  */
  _REG_ESUBREG,		/* Invalid back reference.  */
  _REG_EBRACK,		/* Unmatched left bracket.  */
  _REG_EPAREN,		/* Parenthesis imbalance.  */
  _REG_EBRACE,		/* Unmatched \{.  */
  _REG_BADBR,		/* Invalid contents of \{\}.  */
  _REG_ERANGE,		/* Invalid range end.  */
  _REG_ESPACE,		/* Ran out of memory.  */
  _REG_BADRPT,		/* No preceding re for repetition op.  */

  /* Error codes we've added.  */
  _REG_EEND,		/* Premature end.  */
  _REG_ESIZE,		/* Compiled pattern bigger than 2^16 bytes.  */
  _REG_ERPAREN		/* Unmatched ) or \); not returned from regcomp.  */
} reg_errcode_t;

#ifdef _XOPEN_SOURCE
# define REG_ENOSYS	_REG_ENOSYS
#endif
#define REG_NOERROR	_REG_NOERROR
#define REG_NOMATCH	_REG_NOMATCH
#define REG_BADPAT	_REG_BADPAT
#define REG_ECOLLATE	_REG_ECOLLATE
#define REG_ECTYPE	_REG_ECTYPE
#define REG_EESCAPE	_REG_EESCAPE
#define REG_ESUBREG	_REG_ESUBREG
#define REG_EBRACK	_REG_EBRACK
#define REG_EPAREN	_REG_EPAREN
#define REG_EBRACE	_REG_EBRACE
#define REG_BADBR	_REG_BADBR
#define REG_ERANGE	_REG_ERANGE
#define REG_ESPACE	_REG_ESPACE
#define REG_BADRPT	_REG_BADRPT
#define REG_EEND	_REG_EEND
#define REG_ESIZE	_REG_ESIZE
#define REG_ERPAREN	_REG_ERPAREN

/* struct re_pattern_buffer normally uses member names like `buffer'
   that POSIX does not allow.  In POSIX mode these members have names
   with leading `re_' (e.g., `re_buffer').  */
#ifdef __USE_GNU_REGEX
# define _REG_RE_NAME(id) id
# define _REG_RM_NAME(id) id
#else
# define _REG_RE_NAME(id) re_##id
# define _REG_RM_NAME(id) rm_##id
#endif

/* The user can specify the type of the re_translate member by
   defining the macro RE_TRANSLATE_TYPE, which defaults to unsigned
   char *.  This pollutes the POSIX name space, so in POSIX mode just
   use unsigned char *.  */
#ifdef __USE_GNU_REGEX
# ifndef RE_TRANSLATE_TYPE
#  define RE_TRANSLATE_TYPE unsigned char *
# endif
# define REG_TRANSLATE_TYPE RE_TRANSLATE_TYPE
#else
# define REG_TRANSLATE_TYPE unsigned char *
#endif

/* This data structure represents a compiled pattern.  Before calling
   the pattern compiler, the fields `buffer', `allocated', `fastmap',
   `translate', and `no_sub' can be set.  After the pattern has been
   compiled, the `re_nsub' field is available.  All other fields are
   private to the regex routines.  */

struct re_pattern_buffer
{
  /* Space that holds the compiled pattern.  It is declared as
     `unsigned char *' because its elements are sometimes used as
     array indexes.  */
  unsigned char *_REG_RE_NAME (buffer);

  /* Number of bytes to which `buffer' points.  */
  __re_long_size_t _REG_RE_NAME (allocated);

  /* Number of bytes actually used in `buffer'.  */
  __re_long_size_t _REG_RE_NAME (used);

  /* Syntax setting with which the pattern was compiled.  */
  reg_syntax_t _REG_RE_NAME (syntax);

  /* Pointer to a fastmap, if any, otherwise zero.  re_search uses the
     fastmap, if there is one, to skip over impossible starting points
     for matches.  */
  char *_REG_RE_NAME (fastmap);

  /* Either a translate table to apply to all characters before
     comparing them, or zero for no translation.  The translation is
     applied to a pattern when it is compiled and to a string when it
     is matched.  */
  REG_TRANSLATE_TYPE _REG_RE_NAME (translate);

  /* Number of subexpressions found by the compiler.  */
  size_t re_nsub;

  /* Zero if this pattern cannot match the empty string, one else.
     Well, in truth it's used only in `re_search_2', to see whether or
     not we should use the fastmap, so we don't set this absolutely
     perfectly; see `re_compile_fastmap' (the `duplicate' case).  */
  unsigned int _REG_RE_NAME (can_be_null) : 1;

  /* If REGS_UNALLOCATED, allocate space in the `regs' structure
     for `max (RE_NREGS, re_nsub + 1)' groups.
     If REGS_REALLOCATE, reallocate space if necessary.
     If REGS_FIXED, use what's there.  */
#ifdef __USE_GNU_REGEX
# define REGS_UNALLOCATED 0
# define REGS_REALLOCATE 1
# define REGS_FIXED 2
#endif
  unsigned int _REG_RE_NAME (regs_allocated) : 2;

  /* Set to zero when `regex_compile' compiles a pattern; set to one
     by `re_compile_fastmap' if it updates the fastmap.  */
  unsigned int _REG_RE_NAME (fastmap_accurate) : 1;

  /* If set, `re_match_2' does not return information about
     subexpressions.  */
  unsigned int _REG_RE_NAME (no_sub) : 1;

  /* If set, a beginning-of-line anchor doesn't match at the beginning
     of the string.  */
  unsigned int _REG_RE_NAME (not_bol) : 1;

  /* Similarly for an end-of-line anchor.  */
  unsigned int _REG_RE_NAME (not_eol) : 1;

  /* If true, an anchor at a newline matches.  */
  unsigned int _REG_RE_NAME (newline_anchor) : 1;

/* [[[end pattern_buffer]]] */
};

typedef struct re_pattern_buffer regex_t;

/* This is the structure we store register match data in.  See
   regex.texinfo for a full description of what registers match.  */
struct re_registers
{
  __re_size_t _REG_RM_NAME (num_regs);
  regoff_t *_REG_RM_NAME (start);
  regoff_t *_REG_RM_NAME (end);
};


/* If `regs_allocated' is REGS_UNALLOCATED in the pattern buffer,
   `re_match_2' returns information about at least this many registers
   the first time a `regs' structure is passed.  */
#if !defined RE_NREGS && defined __USE_GNU_REGEX
# define RE_NREGS 30
#endif


/* POSIX specification for registers.  Aside from the different names than
   `re_registers', POSIX uses an array of structures, instead of a
   structure of arrays.  */
typedef struct
{
  regoff_t rm_so;  /* Byte offset from string's start to substring's start.  */
  regoff_t rm_eo;  /* Byte offset from string's start to substring's end.  */
} regmatch_t;

/* Declarations for routines.  */

/* Sets the current default syntax to SYNTAX, and return the old syntax.
   You can also simply assign to the `re_syntax_options' variable.  */
extern reg_syntax_t re_set_syntax (reg_syntax_t __syntax);

/* Compile the regular expression PATTERN, with length LENGTH
   and syntax given by the global `re_syntax_options', into the buffer
   BUFFER.  Return NULL if successful, and an error string if not.  */
extern const char *re_compile_pattern (const char *__pattern, size_t __length,
				       struct re_pattern_buffer *__buffer);


/* Compile a fastmap for the compiled pattern in BUFFER; used to
   accelerate searches.  Return 0 if successful and -2 if was an
   internal error.  */
extern int re_compile_fastmap (struct re_pattern_buffer *__buffer);


/* Search in the string STRING (with length LENGTH) for the pattern
   compiled into BUFFER.  Start searching at position START, for RANGE
   characters.  Return the starting position of the match, -1 for no
   match, or -2 for an internal error.  Also return register
   information in REGS (if REGS and BUFFER->no_sub are nonzero).  */
extern regoff_t re_search (struct re_pattern_buffer *__buffer,
			   const char *__string, __re_idx_t __length,
			   __re_idx_t __start, regoff_t __range,
			   struct re_registers *__regs);


/* Like `re_search', but search in the concatenation of STRING1 and
   STRING2.  Also, stop searching at index START + STOP.  */
extern regoff_t re_search_2 (struct re_pattern_buffer *__buffer,
			     const char *__string1, __re_idx_t __length1,
			     const char *__string2, __re_idx_t __length2,
			     __re_idx_t __start, regoff_t __range,
			     struct re_registers *__regs,
			     __re_idx_t __stop);


/* Like `re_search', but return how many characters in STRING the regexp
   in BUFFER matched, starting at position START.  */
extern regoff_t re_match (struct re_pattern_buffer *__buffer,
			  const char *__string, __re_idx_t __length,
			  __re_idx_t __start, struct re_registers *__regs);


/* Relates to `re_match' as `re_search_2' relates to `re_search'.  */
extern regoff_t re_match_2 (struct re_pattern_buffer *__buffer,
			    const char *__string1, __re_idx_t __length1,
			    const char *__string2, __re_idx_t __length2,
			    __re_idx_t __start, struct re_registers *__regs,
			    __re_idx_t __stop);


/* Set REGS to hold NUM_REGS registers, storing them in STARTS and
   ENDS.  Subsequent matches using BUFFER and REGS will use this memory
   for recording register information.  STARTS and ENDS must be
   allocated with malloc, and must each be at least `NUM_REGS * sizeof
   (regoff_t)' bytes long.

   If NUM_REGS == 0, then subsequent matches should allocate their own
   register data.

   Unless this function is called, the first search or match using
   PATTERN_BUFFER will allocate its own register data, without
   freeing the old data.  */
extern void re_set_registers (struct re_pattern_buffer *__buffer,
			      struct re_registers *__regs,
			      __re_size_t __num_regs,
			      regoff_t *__starts, regoff_t *__ends);

#if defined _REGEX_RE_COMP || defined _LIBC
# ifndef _CRAY
/* 4.2 bsd compatibility.  */
extern char *re_comp (const char *);
extern int re_exec (const char *);
# endif
#endif

/* GCC 2.95 and later have "__restrict"; C99 compilers have
   "restrict", and "configure" may have defined "restrict".  */
#ifndef __restrict
# if ! (2 < __GNUC__ || (2 == __GNUC__ && 95 <= __GNUC_MINOR__))
#  if defined restrict || 199901L <= __STDC_VERSION__
#   define __restrict restrict
#  else
#   define __restrict
#  endif
# endif
#endif
/* gcc 3.1 and up support the [restrict] syntax.  Don't trust
   sys/cdefs.h's definition of __restrict_arr, though, as it
   mishandles gcc -ansi -pedantic.  */
#undef __restrict_arr
#if ((199901L <= __STDC_VERSION__					\
      || ((3 < __GNUC__ || (3 == __GNUC__ && 1 <= __GNUC_MINOR__))	\
	  && !__STRICT_ANSI__))						\
     && !defined __GNUG__)
# define __restrict_arr __restrict
#else
# define __restrict_arr
#endif

/* POSIX compatibility.  */
extern int regcomp (regex_t *__restrict __preg,
		    const char *__restrict __pattern,
		    int __cflags);

extern int regexec (const regex_t *__restrict __preg,
		    const char *__restrict __string, size_t __nmatch,
		    regmatch_t __pmatch[__restrict_arr],
		    int __eflags);

extern size_t regerror (int __errcode, const regex_t *__restrict __preg,
			char *__restrict __errbuf, size_t __errbuf_size);

extern void regfree (regex_t *__preg);


#ifdef __cplusplus
}
#endif	/* C++ */

#endif /* regex.h */

--- NEW FILE: xstrndup.h ---
/* Duplicate a bounded initial segment of a string, with out-of-memory
   checking.
   Copyright (C) 2003 Free Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

#include <stddef.h>

/* Return a newly allocated copy of at most N bytes of STRING.
   In other words, return a copy of the initial segment of length N of
   STRING.  */
extern char *xstrndup (const char *string, size_t n);

--- NEW FILE: Makefile.am ---
## DO NOT EDIT! GENERATED AUTOMATICALLY!
## Process this file with automake to produce Makefile.in.
# Copyright (C) 2004-2007 Free Software Foundation, Inc.
#
# This file is free software, distributed under the terms of the GNU
# General Public License.  As a special exception to the GNU General
# Public License, this file may be distributed as part of a program
# that contains a configuration script generated by Autoconf, under
# the same distribution terms as the rest of that program.
#
# Generated by gnulib-tool.
# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=gl --m4-base=gl/m4 --doc-base=doc --aux-dir=. --no-libtool --macro-prefix=gl dirname fsusage getaddrinfo gethostname getloadavg getopt gettext mountlist regex vasprintf vsnprintf

AUTOMAKE_OPTIONS = 1.5 gnits

noinst_HEADERS =
noinst_LIBRARIES =
noinst_LTLIBRARIES =
EXTRA_DIST =
BUILT_SOURCES =
SUFFIXES =
MOSTLYCLEANFILES = core *.stackdump
MOSTLYCLEANDIRS =
CLEANFILES =
DISTCLEANFILES =
MAINTAINERCLEANFILES =

AM_CPPFLAGS =

noinst_LIBRARIES += libgnu.a

libgnu_a_SOURCES =
libgnu_a_LIBADD = $(gl_LIBOBJS)
libgnu_a_DEPENDENCIES = $(gl_LIBOBJS)
EXTRA_libgnu_a_SOURCES =

## begin gnulib module alloca


EXTRA_DIST += alloca.c

EXTRA_libgnu_a_SOURCES += alloca.c

libgnu_a_LIBADD += @ALLOCA@
libgnu_a_DEPENDENCIES += @ALLOCA@
## end   gnulib module alloca

## begin gnulib module alloca-opt

BUILT_SOURCES += $(ALLOCA_H)

# We need the following in order to create <alloca.h> when the system
# doesn't have one that works with the given compiler.
alloca.h: alloca_.h
	{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
	  cat $(srcdir)/alloca_.h; \
	} > $@-t
	mv -f $@-t $@
MOSTLYCLEANFILES += alloca.h alloca.h-t

EXTRA_DIST += alloca_.h

## end   gnulib module alloca-opt

## begin gnulib module arpa_inet

BUILT_SOURCES += $(ARPA_INET_H)

# We need the following in order to create <arpa/inet.h> when the system
# doesn't have one.
arpa/inet.h:
	test -d arpa || mkdir arpa
	rm -f $@-t $@
	{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
	  echo '#include <sys/socket.h>'; \
	} > $@-t
	mv $@-t $@
MOSTLYCLEANFILES += arpa/inet.h arpa/inet.h-t
MOSTLYCLEANDIRS += arpa

## end   gnulib module arpa_inet

## begin gnulib module c-strtod


EXTRA_DIST += c-strtod.c c-strtod.h

EXTRA_libgnu_a_SOURCES += c-strtod.c

## end   gnulib module c-strtod

## begin gnulib module cloexec


EXTRA_DIST += cloexec.c cloexec.h

EXTRA_libgnu_a_SOURCES += cloexec.c

## end   gnulib module cloexec

## begin gnulib module dirname


EXTRA_DIST += basename.c dirname.c dirname.h stripslash.c

EXTRA_libgnu_a_SOURCES += basename.c dirname.c stripslash.c

## end   gnulib module dirname

## begin gnulib module error


EXTRA_DIST += error.c error.h

EXTRA_libgnu_a_SOURCES += error.c

## end   gnulib module error

## begin gnulib module exit

libgnu_a_SOURCES += exit.h

## end   gnulib module exit

## begin gnulib module exitfail


EXTRA_DIST += exitfail.c exitfail.h

EXTRA_libgnu_a_SOURCES += exitfail.c

## end   gnulib module exitfail

## begin gnulib module fcntl-safer


EXTRA_DIST += creat-safer.c fcntl--.h fcntl-safer.h open-safer.c

EXTRA_libgnu_a_SOURCES += creat-safer.c open-safer.c

## end   gnulib module fcntl-safer

## begin gnulib module fsusage


EXTRA_DIST += fsusage.c fsusage.h

EXTRA_libgnu_a_SOURCES += fsusage.c

## end   gnulib module fsusage

## begin gnulib module full-read

libgnu_a_SOURCES += full-read.h full-read.c

## end   gnulib module full-read

## begin gnulib module full-write

libgnu_a_SOURCES += full-write.h full-write.c

## end   gnulib module full-write

## begin gnulib module getaddrinfo


EXTRA_DIST += gai_strerror.c getaddrinfo.c getaddrinfo.h

EXTRA_libgnu_a_SOURCES += gai_strerror.c getaddrinfo.c

## end   gnulib module getaddrinfo

## begin gnulib module gethostname


EXTRA_DIST += gethostname.c

EXTRA_libgnu_a_SOURCES += gethostname.c

## end   gnulib module gethostname

## begin gnulib module getloadavg


EXTRA_DIST += getloadavg.c

EXTRA_libgnu_a_SOURCES += getloadavg.c

## end   gnulib module getloadavg

## begin gnulib module getopt

BUILT_SOURCES += $(GETOPT_H)

# We need the following in order to create <getopt.h> when the system
# doesn't have one that works with the given compiler.
getopt.h: getopt_.h
	{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
	  cat $(srcdir)/getopt_.h; \
	} > $@-t
	mv -f $@-t $@
MOSTLYCLEANFILES += getopt.h getopt.h-t

EXTRA_DIST += getopt.c getopt1.c getopt_.h getopt_int.h

EXTRA_libgnu_a_SOURCES += getopt.c getopt1.c

## end   gnulib module getopt

## begin gnulib module gettext

# This is for those projects which use "gettextize --intl" to put a source-code
# copy of libintl into their package. In such projects, every Makefile.am needs
# -I$(top_builddir)/intl, so that <libintl.h> can be found in this directory.
# For the Makefile.ams in other directories it is the maintainer's
# responsibility; for the one from gnulib we do it here.
# This option has no effect when the user disables NLS (because then the intl
# directory contains no libintl.h file) or when the project does not use
# "gettextize --intl".
AM_CPPFLAGS += -I$(top_builddir)/intl

## end   gnulib module gettext

## begin gnulib module gettext-h

libgnu_a_SOURCES += gettext.h

## end   gnulib module gettext-h

## begin gnulib module inet_ntop


EXTRA_DIST += inet_ntop.c inet_ntop.h

EXTRA_libgnu_a_SOURCES += inet_ntop.c

## end   gnulib module inet_ntop

## begin gnulib module intprops


EXTRA_DIST += intprops.h

## end   gnulib module intprops

## begin gnulib module malloc


EXTRA_DIST += malloc.c

EXTRA_libgnu_a_SOURCES += malloc.c

## end   gnulib module malloc

## begin gnulib module mbchar


EXTRA_DIST += mbchar.c mbchar.h

EXTRA_libgnu_a_SOURCES += mbchar.c

## end   gnulib module mbchar

## begin gnulib module mbuiter

libgnu_a_SOURCES += mbuiter.h

## end   gnulib module mbuiter

## begin gnulib module memchr


EXTRA_DIST += memchr.c

EXTRA_libgnu_a_SOURCES += memchr.c

## end   gnulib module memchr

## begin gnulib module minmax

libgnu_a_SOURCES += minmax.h

## end   gnulib module minmax

## begin gnulib module mountlist


EXTRA_DIST += mountlist.c mountlist.h

EXTRA_libgnu_a_SOURCES += mountlist.c

## end   gnulib module mountlist

## begin gnulib module netinet_in

BUILT_SOURCES += $(NETINET_IN_H)

# We need the following in order to create <netinet/in.h> when the system
# doesn't have one.
netinet/in.h:
	test -d netinet || mkdir netinet
	rm -f $@-t $@
	{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
	  echo '#include <sys/socket.h>'; \
	} > $@-t
	mv $@-t $@
MOSTLYCLEANFILES += netinet/in.h netinet/in.h-t
MOSTLYCLEANDIRS += netinet

## end   gnulib module netinet_in

## begin gnulib module regex


EXTRA_DIST += regcomp.c regex.c regex.h regex_internal.c regex_internal.h regexec.c

EXTRA_libgnu_a_SOURCES += regcomp.c regex.c regex_internal.c regexec.c

## end   gnulib module regex

## begin gnulib module safe-read


EXTRA_DIST += safe-read.c safe-read.h

EXTRA_libgnu_a_SOURCES += safe-read.c

## end   gnulib module safe-read

## begin gnulib module safe-write


EXTRA_DIST += safe-write.c safe-write.h

EXTRA_libgnu_a_SOURCES += safe-write.c

## end   gnulib module safe-write

## begin gnulib module size_max

libgnu_a_SOURCES += size_max.h

## end   gnulib module size_max

## begin gnulib module snprintf


EXTRA_DIST += snprintf.c snprintf.h

EXTRA_libgnu_a_SOURCES += snprintf.c

## end   gnulib module snprintf

## begin gnulib module stdbool

BUILT_SOURCES += $(STDBOOL_H)

# We need the following in order to create <stdbool.h> when the system
# doesn't have one that works.
stdbool.h: stdbool_.h
	rm -f $@-t $@
	{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
	  sed -e 's/@''HAVE__BOOL''@/$(HAVE__BOOL)/g' < $(srcdir)/stdbool_.h; \
	} > $@-t
	mv $@-t $@
MOSTLYCLEANFILES += stdbool.h stdbool.h-t

EXTRA_DIST += stdbool_.h

## end   gnulib module stdbool

## begin gnulib module stdint

BUILT_SOURCES += $(STDINT_H)

# We need the following in order to create <stdint.h> when the system
# doesn't have one that works with the given compiler.
stdint.h: stdint_.h
	rm -f $@-t $@
	{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
	  sed -e 's/@''HAVE_STDINT_H''@/$(HAVE_STDINT_H)/g' \
	      -e 's|@''ABSOLUTE_STDINT_H''@|$(ABSOLUTE_STDINT_H)|g' \
	      -e 's/@''HAVE_SYS_TYPES_H''@/$(HAVE_SYS_TYPES_H)/g' \
	      -e 's/@''HAVE_INTTYPES_H''@/$(HAVE_INTTYPES_H)/g' \
	      -e 's/@''HAVE_SYS_INTTYPES_H''@/$(HAVE_SYS_INTTYPES_H)/g' \
	      -e 's/@''HAVE_SYS_BITYPES_H''@/$(HAVE_SYS_BITYPES_H)/g' \
	      -e 's/@''HAVE_LONG_LONG_INT''@/$(HAVE_LONG_LONG_INT)/g' \
	      -e 's/@''HAVE_UNSIGNED_LONG_LONG_INT''@/$(HAVE_UNSIGNED_LONG_LONG_INT)/g' \
	      -e 's/@''BITSIZEOF_PTRDIFF_T''@/$(BITSIZEOF_PTRDIFF_T)/g' \
	      -e 's/@''PTRDIFF_T_SUFFIX''@/$(PTRDIFF_T_SUFFIX)/g' \
	      -e 's/@''BITSIZEOF_SIG_ATOMIC_T''@/$(BITSIZEOF_SIG_ATOMIC_T)/g' \
	      -e 's/@''HAVE_SIGNED_SIG_ATOMIC_T''@/$(HAVE_SIGNED_SIG_ATOMIC_T)/g' \
	      -e 's/@''SIG_ATOMIC_T_SUFFIX''@/$(SIG_ATOMIC_T_SUFFIX)/g' \
	      -e 's/@''BITSIZEOF_SIZE_T''@/$(BITSIZEOF_SIZE_T)/g' \
	      -e 's/@''SIZE_T_SUFFIX''@/$(SIZE_T_SUFFIX)/g' \
	      -e 's/@''BITSIZEOF_WCHAR_T''@/$(BITSIZEOF_WCHAR_T)/g' \
	      -e 's/@''HAVE_SIGNED_WCHAR_T''@/$(HAVE_SIGNED_WCHAR_T)/g' \
	      -e 's/@''WCHAR_T_SUFFIX''@/$(WCHAR_T_SUFFIX)/g' \
	      -e 's/@''BITSIZEOF_WINT_T''@/$(BITSIZEOF_WINT_T)/g' \
	      -e 's/@''HAVE_SIGNED_WINT_T''@/$(HAVE_SIGNED_WINT_T)/g' \
	      -e 's/@''WINT_T_SUFFIX''@/$(WINT_T_SUFFIX)/g' \
	      < $(srcdir)/stdint_.h; \
	} > $@-t
	mv $@-t $@
MOSTLYCLEANFILES += stdint.h stdint.h-t

EXTRA_DIST += stdint_.h

## end   gnulib module stdint

## begin gnulib module strcase


EXTRA_DIST += strcase.h strcasecmp.c strncasecmp.c

EXTRA_libgnu_a_SOURCES += strcasecmp.c strncasecmp.c

## end   gnulib module strcase

## begin gnulib module strdup


EXTRA_DIST += strdup.c strdup.h

EXTRA_libgnu_a_SOURCES += strdup.c

## end   gnulib module strdup

## begin gnulib module strndup


EXTRA_DIST += strndup.c strndup.h

EXTRA_libgnu_a_SOURCES += strndup.c

## end   gnulib module strndup

## begin gnulib module strnlen


EXTRA_DIST += strnlen.c strnlen.h

EXTRA_libgnu_a_SOURCES += strnlen.c

## end   gnulib module strnlen

## begin gnulib module strnlen1

libgnu_a_SOURCES += strnlen1.h strnlen1.c

## end   gnulib module strnlen1

## begin gnulib module sys_socket

BUILT_SOURCES += $(SYS_SOCKET_H)

# We need the following in order to create <sys/socket.h> when the system
# doesn't have one that works with the given compiler.
sys/socket.h: socket_.h
	@MKDIR_P@ sys
	{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
	  cat $(srcdir)/socket_.h; \
	} > $@-t
	mv -f $@-t $@
MOSTLYCLEANFILES += sys/socket.h sys/socket.h-t
MOSTLYCLEANDIRS += sys

EXTRA_DIST += socket_.h

## end   gnulib module sys_socket

## begin gnulib module unistd

BUILT_SOURCES += $(UNISTD_H)

# We need the following in order to create an empty placeholder for
# <unistd.h> when the system doesn't have one.
unistd.h: unistd_.h
	rm -f $@-t $@
	{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
	  sed -e 's|@''ABSOLUTE_UNISTD_H''@|$(ABSOLUTE_UNISTD_H)|g' \
	      < $(srcdir)/unistd_.h; \
	} > $@-t
	mv $@-t $@
MOSTLYCLEANFILES += unistd.h unistd.h-t

EXTRA_DIST += unistd_.h

## end   gnulib module unistd

## begin gnulib module unistd-safer


EXTRA_DIST += dup-safer.c fd-safer.c pipe-safer.c unistd--.h unistd-safer.h

EXTRA_libgnu_a_SOURCES += dup-safer.c fd-safer.c pipe-safer.c

## end   gnulib module unistd-safer

## begin gnulib module vasnprintf


EXTRA_DIST += asnprintf.c printf-args.c printf-args.h printf-parse.c printf-parse.h vasnprintf.c vasnprintf.h

EXTRA_libgnu_a_SOURCES += asnprintf.c printf-args.c printf-parse.c vasnprintf.c

## end   gnulib module vasnprintf

## begin gnulib module vasprintf


EXTRA_DIST += asprintf.c vasprintf.c vasprintf.h

EXTRA_libgnu_a_SOURCES += asprintf.c vasprintf.c

## end   gnulib module vasprintf

## begin gnulib module vsnprintf


EXTRA_DIST += vsnprintf.c vsnprintf.h

EXTRA_libgnu_a_SOURCES += vsnprintf.c

## end   gnulib module vsnprintf

## begin gnulib module wchar

BUILT_SOURCES += $(WCHAR_H)

# We need the following in order to create <wchar.h> when the system
# version does not work standalone.
wchar.h: wchar_.h
	rm -f $@-t $@
	{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
	  sed -e 's|@''ABSOLUTE_WCHAR_H''@|$(ABSOLUTE_WCHAR_H)|g' \
	    < $(srcdir)/wchar_.h; \
	} > $@-t
	mv $@-t $@
MOSTLYCLEANFILES += wchar.h wchar.h-t

EXTRA_DIST += wchar_.h

## end   gnulib module wchar

## begin gnulib module wctype

BUILT_SOURCES += $(WCTYPE_H)

# We need the following in order to create <wctype.h> when the system
# doesn't have one that works with the given compiler.
wctype.h: wctype_.h
	rm -f $@-t $@
	{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
	  sed -e 's/@''HAVE_WCTYPE_H''@/$(HAVE_WCTYPE_H)/g' \
	      -e 's|@''ABSOLUTE_WCTYPE_H''@|$(ABSOLUTE_WCTYPE_H)|g' \
	      -e 's/@''HAVE_WCTYPE_CTMP_BUG''@/$(HAVE_WCTYPE_CTMP_BUG)/g' \
	      -e 's/@''HAVE_WINT_T''@/$(HAVE_WINT_T)/g' \
	      < $(srcdir)/wctype_.h; \
	} > $@-t
	mv $@-t $@
MOSTLYCLEANFILES += wctype.h wctype.h-t

EXTRA_DIST += wctype_.h

## end   gnulib module wctype

## begin gnulib module wcwidth

libgnu_a_SOURCES += wcwidth.h

## end   gnulib module wcwidth

## begin gnulib module xalloc


EXTRA_DIST += xalloc.h xmalloc.c

EXTRA_libgnu_a_SOURCES += xmalloc.c

## end   gnulib module xalloc

## begin gnulib module xalloc-die

libgnu_a_SOURCES += xalloc-die.c

## end   gnulib module xalloc-die

## begin gnulib module xsize

libgnu_a_SOURCES += xsize.h

## end   gnulib module xsize

## begin gnulib module xstrndup

libgnu_a_SOURCES += xstrndup.h xstrndup.c

## end   gnulib module xstrndup


mostlyclean-local: mostlyclean-generic
	@for dir in '' $(MOSTLYCLEANDIRS); do \
	  if test -n "$$dir" && test -d $$dir; then \
	    echo "rmdir $$dir"; rmdir $$dir; \
	  fi; \
	done

--- NEW FILE: xstrndup.c ---
/* Duplicate a bounded initial segment of a string, with out-of-memory
   checking.
   Copyright (C) 2003, 2006 Free Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

#include <config.h>

/* Specification.  */
#include "xstrndup.h"

#include "strndup.h"
#include "xalloc.h"

/* Return a newly allocated copy of at most N bytes of STRING.
   In other words, return a copy of the initial segment of length N of
   STRING.  */
char *
xstrndup (const char *string, size_t n)
{
  char *s = strndup (string, n);
  if (! s)
    xalloc_die ();
  return s;
}

--- NEW FILE: vsnprintf.h ---
/* Formatted output to strings.
   Copyright (C) 2004 Free Software Foundation, Inc.
   Written by Simon Josefsson and Yoann Vandoorselaere <yoann at prelude-ids.org>.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License along
   with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

#ifndef VSNPRINTF_H
#define VSNPRINTF_H

#include <stdarg.h>

/* Get vsnprintf declaration, if available.  */
#include <stdio.h>

#if defined HAVE_DECL_VSNPRINTF && !HAVE_DECL_VSNPRINTF
int vsnprintf (char *str, size_t size, const char *format, va_list args);
#endif

#endif /* VSNPRINTF_H */

--- NEW FILE: creat-safer.c ---
/* Invoke creat, but avoid some glitches.

   Copyright (C) 2005, 2006 Free Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

/* Written by Jim Meyering.  */

#include <config.h>

#include "fcntl-safer.h"

#include <fcntl.h>
#include "unistd-safer.h"

int
creat_safer (char const *file, mode_t mode)
{
  return fd_safer (creat (file, mode));
}

--- NEW FILE: vsnprintf.c ---
/* Formatted output to strings.
   Copyright (C) 2004, 2006 Free Software Foundation, Inc.
   Written by Simon Josefsson and Yoann Vandoorselaere <yoann at prelude-ids.org>.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License along
   with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

#ifdef HAVE_CONFIG_H
# include <config.h>
#endif

/* Specification.  */
#include "vsnprintf.h"

#include <errno.h>
#include <limits.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "vasnprintf.h"

/* Some systems, like OSF/1 4.0 and Woe32, don't have EOVERFLOW.  */
#ifndef EOVERFLOW
# define EOVERFLOW E2BIG
#endif

/* Print formatted output to string STR.  Similar to vsprintf, but
   additional length SIZE limit how much is written into STR.  Returns
   string length of formatted string (which may be larger than SIZE).
   STR may be NULL, in which case nothing will be written.  On error,
   return a negative value. */
int
vsnprintf (char *str, size_t size, const char *format, va_list args)
{
  char *output;
  size_t len;
  size_t lenbuf = size;

  output = vasnprintf (str, &lenbuf, format, args);
  len = lenbuf;

  if (!output)
    return -1;

  if (output != str)
    {
      if (size)
	{
	  size_t pruned_len = (len < size ? len : size - 1);
	  memcpy (str, output, pruned_len);
	  str[pruned_len] = '\0';
	}

      free (output);
    }

  if (len > INT_MAX)
    {
      errno = EOVERFLOW;
      return -1;
    }

  return len;
}

--- NEW FILE: gai_strerror.c ---
/* Copyright (C) 1997, 2001, 2002, 2004, 2005, 2006 Free Software Foundation, Inc.
   This file is part of the GNU C Library.
   Contributed by Philip Blundell <pjb27 at cam.ac.uk>, 1997.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

#ifndef _LIBC
# include <config.h>
# include "getaddrinfo.h"
#endif

#include <stdio.h>
#ifdef HAVE_NETDB_H
# include <netdb.h>
#endif

#ifdef _LIBC
# include <libintl.h>
#else
# include "gettext.h"
# define _(String) gettext (String)
# define N_(String) String
#endif

static struct
  {
    int code;
    const char *msg;
  }
values[] =
  {
    { EAI_ADDRFAMILY, N_("Address family for hostname not supported") },
    { EAI_AGAIN, N_("Temporary failure in name resolution") },
    { EAI_BADFLAGS, N_("Bad value for ai_flags") },
    { EAI_FAIL, N_("Non-recoverable failure in name resolution") },
    { EAI_FAMILY, N_("ai_family not supported") },
    { EAI_MEMORY, N_("Memory allocation failure") },
    { EAI_NODATA, N_("No address associated with hostname") },
    { EAI_NONAME, N_("Name or service not known") },
    { EAI_SERVICE, N_("Servname not supported for ai_socktype") },
    { EAI_SOCKTYPE, N_("ai_socktype not supported") },
    { EAI_SYSTEM, N_("System error") },
#ifdef __USE_GNU
    { EAI_INPROGRESS, N_("Processing request in progress") },
    { EAI_CANCELED, N_("Request canceled") },
    { EAI_NOTCANCELED, N_("Request not canceled") },
    { EAI_ALLDONE, N_("All requests done") },
    { EAI_INTR, N_("Interrupted by a signal") },
    { EAI_IDN_ENCODE, N_("Parameter string not correctly encoded") }
#endif
  };

const char *
gai_strerror (int code)
{
  size_t i;
  for (i = 0; i < sizeof (values) / sizeof (values[0]); ++i)
    if (values[i].code == code)
      return _(values[i].msg);

  return _("Unknown error");
}
#ifdef _LIBC
libc_hidden_def (gai_strerror)
#endif

--- NEW FILE: xalloc-die.c ---
/* Report a memory allocation failure and exit.

   Copyright (C) 1997, 1998, 1999, 2000, 2002, 2003, 2004, 2006 Free
   Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

#include <config.h>

#include "xalloc.h"

#include <stdlib.h>

#include "error.h"
#include "exitfail.h"

#include "gettext.h"
#define _(msgid) gettext (msgid)

void
xalloc_die (void)
{
  error (exit_failure, 0, "%s", _("memory exhausted"));

  /* The `noreturn' cannot be given to error, since it may return if
     its first argument is 0.  To help compilers understand the
     xalloc_die does not return, call abort.  Also, the abort is a
     safety feature if exit_failure is 0 (which shouldn't happen).  */
  abort ();
}

--- NEW FILE: strndup.c ---
/* A replacement function, for systems that lack strndup.

   Copyright (C) 1996, 1997, 1998, 2001, 2002, 2003, 2005, 2006 Free
   Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by the
   Free Software Foundation; either version 2, or (at your option) any
   later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

#include <config.h>
#include "strndup.h"

#include <stdlib.h>
#include <string.h>

#include "strnlen.h"

char *
strndup (char const *s, size_t n)
{
  size_t len = strnlen (s, n);
  char *new = malloc (len + 1);

  if (new == NULL)
    return NULL;

  new[len] = '\0';
  return memcpy (new, s, len);
}

--- NEW FILE: inet_ntop.c ---
/* inet_ntop.c -- convert IPv4 and IPv6 addresses from binary to text form

   Copyright (C) 2005, 2006  Free Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

/*
 * Copyright (c) 1996-1999 by Internet Software Consortium.
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
 * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
 * SOFTWARE.
 */

#include <config.h>

/* Specification.  */
#include "inet_ntop.h"

#include <stdio.h>
#include <string.h>
#include <errno.h>

#ifndef EAFNOSUPPORT
# define EAFNOSUPPORT EINVAL
#endif

#define NS_IN6ADDRSZ 16
#define NS_INT16SZ 2

/*
 * WARNING: Don't even consider trying to compile this on a system where
 * sizeof(int) < 4.  sizeof(int) > 4 is fine; all the world's not a VAX.
 */
typedef int verify_int_size[2 * sizeof (int) - 7];

static const char *inet_ntop4 (const unsigned char *src, char *dst, socklen_t size);
#if HAVE_IPV6
static const char *inet_ntop6 (const unsigned char *src, char *dst, socklen_t size);
#endif


/* char *
 * inet_ntop(af, src, dst, size)
 *	convert a network format address to presentation format.
 * return:
 *	pointer to presentation format address (`dst'), or NULL (see errno).
 * author:
 *	Paul Vixie, 1996.
 */
const char *
inet_ntop (int af, const void *restrict src,
	   char *restrict dst, socklen_t cnt)
{
  switch (af)
    {
#if HAVE_IPV4
    case AF_INET:
      return (inet_ntop4 (src, dst, cnt));
#endif

#if HAVE_IPV6
    case AF_INET6:
      return (inet_ntop6 (src, dst, cnt));
#endif

    default:
      errno = EAFNOSUPPORT;
      return (NULL);
    }
  /* NOTREACHED */
}

/* const char *
 * inet_ntop4(src, dst, size)
 *	format an IPv4 address
 * return:
 *	`dst' (as a const)
 * notes:
 *	(1) uses no statics
 *	(2) takes a u_char* not an in_addr as input
 * author:
 *	Paul Vixie, 1996.
 */
static const char *
inet_ntop4 (const unsigned char *src, char *dst, socklen_t size)
{
  char tmp[sizeof "255.255.255.255"];
  int len;

  len = sprintf (tmp, "%u.%u.%u.%u", src[0], src[1], src[2], src[3]);
  if (len < 0)
    return NULL;

  if (len > size)
    {
      errno = ENOSPC;
      return NULL;
    }

  return strcpy (dst, tmp);
}

#if HAVE_IPV6

/* const char *
 * inet_ntop6(src, dst, size)
 *	convert IPv6 binary address into presentation (printable) format
 * author:
 *	Paul Vixie, 1996.
 */
static const char *
inet_ntop6 (const unsigned char *src, char *dst, socklen_t size)
{
  /*
   * Note that int32_t and int16_t need only be "at least" large enough
   * to contain a value of the specified size.  On some systems, like
   * Crays, there is no such thing as an integer variable with 16 bits.
   * Keep this in mind if you think this function should have been coded
   * to use pointer overlays.  All the world's not a VAX.
   */
  char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp;
  struct
  {
    int base, len;
  } best, cur;
  unsigned int words[NS_IN6ADDRSZ / NS_INT16SZ];
  int i;

  /*
   * Preprocess:
   *      Copy the input (bytewise) array into a wordwise array.
   *      Find the longest run of 0x00's in src[] for :: shorthanding.
   */
  memset (words, '\0', sizeof words);
  for (i = 0; i < NS_IN6ADDRSZ; i += 2)
    words[i / 2] = (src[i] << 8) | src[i + 1];
  best.base = -1;
  cur.base = -1;
  for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++)
    {
      if (words[i] == 0)
	{
	  if (cur.base == -1)
	    cur.base = i, cur.len = 1;
	  else
	    cur.len++;
	}
      else
	{
	  if (cur.base != -1)
	    {
	      if (best.base == -1 || cur.len > best.len)
		best = cur;
	      cur.base = -1;
	    }
	}
    }
  if (cur.base != -1)
    {
      if (best.base == -1 || cur.len > best.len)
	best = cur;
    }
  if (best.base != -1 && best.len < 2)
    best.base = -1;

  /*
   * Format the result.
   */
  tp = tmp;
  for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++)
    {
      /* Are we inside the best run of 0x00's? */
      if (best.base != -1 && i >= best.base && i < (best.base + best.len))
	{
	  if (i == best.base)
	    *tp++ = ':';
	  continue;
	}
      /* Are we following an initial run of 0x00s or any real hex? */
      if (i != 0)
	*tp++ = ':';
      /* Is this address an encapsulated IPv4? */
      if (i == 6 && best.base == 0 &&
	  (best.len == 6 || (best.len == 5 && words[5] == 0xffff)))
	{
	  if (!inet_ntop4 (src + 12, tp, sizeof tmp - (tp - tmp)))
	    return (NULL);
	  tp += strlen (tp);
	  break;
	}
      {
	int len = sprintf (tp, "%x", words[i]);
	if (len < 0)
	  return NULL;
	tp += len;
      }
    }
  /* Was it a trailing run of 0x00's? */
  if (best.base != -1 && (best.base + best.len) ==
      (NS_IN6ADDRSZ / NS_INT16SZ))
    *tp++ = ':';
  *tp++ = '\0';

  /*
   * Check for overflow, copy, and we're done.
   */
  if ((socklen_t) (tp - tmp) > size)
    {
      errno = ENOSPC;
      return NULL;
    }

  return strcpy (dst, tmp);
}

#endif

--- NEW FILE: dup-safer.c ---
/* Invoke dup, but avoid some glitches.

   Copyright (C) 2001, 2004, 2005, 2006 Free Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

/* Written by Paul Eggert.  */

#include <config.h>

#include "unistd-safer.h"

#include <fcntl.h>

#include <unistd.h>
#ifndef STDERR_FILENO
# define STDERR_FILENO 2
#endif

/* Like dup, but do not return STDIN_FILENO, STDOUT_FILENO, or
   STDERR_FILENO.  */

int
dup_safer (int fd)
{
#if defined F_DUPFD && !defined FCHDIR_REPLACEMENT
  return fcntl (fd, F_DUPFD, STDERR_FILENO + 1);
#else
  /* fd_safer calls us back, but eventually the recursion unwinds and
     does the right thing.  */
  return fd_safer (dup (fd));
#endif
}

--- NEW FILE: pipe-safer.c ---
/* Invoke pipe, but avoid some glitches.
   Copyright (C) 2005, 2006 Free Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

/* Written by Jim Meyering.  */

#include <config.h>

#include "unistd-safer.h"

#include <unistd.h>
#include <errno.h>

/* Like pipe, but ensure that neither of the file descriptors is
   STDIN_FILENO, STDOUT_FILENO, or STDERR_FILENO.  Fail with ENOSYS on
   platforms that lack pipe.  */

int
pipe_safer (int fd[2])
{
#if HAVE_PIPE
  if (pipe (fd) == 0)
    {
      int i;
      for (i = 0; i < 2; i++)
	{
	  fd[i] = fd_safer (fd[i]);
	  if (fd[i] < 0)
	    {
	      int e = errno;
	      close (fd[1 - i]);
	      errno = e;
	      return -1;
	    }
	}

      return 0;
    }
#else
  errno = ENOSYS;
#endif

  return -1;
}

--- NEW FILE: strndup.h ---
/* Duplicate a size-bounded string.
   Copyright (C) 2003, 2006 Free Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

/* Get size_t.  */
#include <stddef.h>
/* If HAVE_STRNDUP, get the strndup declaration.
   If !HAVE_STRNDUP, include <string.h> now so that it doesn't cause
   trouble if included later.  */
#include <string.h>

#if !HAVE_STRNDUP
# undef strndup
# define strndup rpl_strndup
# if !HAVE_DECL_STRNDUP  /* Don't risk conflicting declarations.  */
/* Return a newly allocated copy of at most N bytes of STRING.  */
extern char *strndup (const char *string, size_t n);
# endif
#endif

--- NEW FILE: exitfail.c ---
/* Failure exit status

   Copyright (C) 2002, 2003, 2005, 2006 Free Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; see the file COPYING.
   If not, write to the Free Software Foundation,
   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

#include <config.h>

#include "exitfail.h"
#include "exit.h"

int volatile exit_failure = EXIT_FAILURE;

--- NEW FILE: exitfail.h ---
/* Failure exit status

   Copyright (C) 2002 Free Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; see the file COPYING.
   If not, write to the Free Software Foundation,
   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */

extern int volatile exit_failure;





More information about the Commits mailing list