summary refs log tree commit diff
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>1997-02-22 01:20:46 +0000
committerUlrich Drepper <drepper@redhat.com>1997-02-22 01:20:46 +0000
commit5a97622d5e053e935af0a9715ddd941fdaafcaf9 (patch)
tree9f703f1a0c1c4ca0ed023acd33f09d152c923426
parent1fb05e3db1891142410bc58c320dfe281749fffe (diff)
downloadglibc-5a97622d5e053e935af0a9715ddd941fdaafcaf9.tar.gz
glibc-5a97622d5e053e935af0a9715ddd941fdaafcaf9.tar.xz
glibc-5a97622d5e053e935af0a9715ddd941fdaafcaf9.zip
update from main archive 970221 cvs/libc-970223 cvs/libc-970222
1997-02-22 00:17  Ulrich Drepper  <drepper@cygnus.com>

	* catgets/gencat.c: Change to use argp.
	* db/makedb: Likewise.
	* locale/programs/localedef.c: Likewise.

	* locale/programs/locale.c: Little adjustment for better usage of
	argp.

1997-02-20 20:07  Greg McGary  <gkm@eng.ascend.com>

	* Makeconfig: Add rules for libc with bounded pointers.
	* Makerules: Likewise.
	* config.make.in: Likewise.
	* configure.in: Likewise.

1997-02-21 10:41  Miles Bader  <miles@gnu.ai.mit.edu>

	* argp.h (OPTION_NO_USAGE): New macro.
	* argp-help.c (usage_long_opt, usage_argful_short_opt,
	add_argless_short_opt): Implement OPTION_NO_USAGE.

1997-02-20 16:41  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>

	* malloc/obstack.h: Fix typo.

1997-02-20 15:56  Miles Bader  <miles@gnu.ai.mit.edu>

	* argp-fmtstream.c (__argp_fmtstream_update): Account for case
	where NEXTLINE points one past the end of the active buffer.

	* argp-help.c <stddef.h>: New include.
	(__argp_failure): Only exit if STATE says it's ok.
	(print_header, hol_entry_help): Use UPARAMS fields rather than
	constants.
	(_help): Call fill_in_uparams if necessary.
	(struct hol_help_state): New type.
	(struct pentry_state): Add hhstate field.  Remove prev_entry &
	sep_groups fields.
	(hol_entry_help): Add HHSTATE parameter.  Remove prev_entry &
	sep_groups parameters.
	Suppress duplicate arguments if requested, and note the fact.
	(print_header, comma): Use PEST->hhstate fields.
	(hol_help): Add HHSTATE variable & pass to hol_entry_help.
	Remove LAST_ENTRY & SEP_GROUPS variables.
	If any suplicate arguments were suppressed, print explanatory note.
	(filter_doc): Replace PEST parameter with STATE.
	(struct uparams): New type.
	(uparams): New variable.
	(struct uparam_name): New type.
	(uparam_names): New variable.
	(fill_in_uparams): New function.
	(__argp_failure, __argp_error, __argp_state_help): Make STATE
	parameter const.
	* argp.h (argp_state_help, __argp_state_help, argp_usage,
	__argp_usage, argp_error, __argp_error, argp_failure,
	__argp_failure): Make STATE parameter const.
	(ARGP_KEY_HELP_DUP_ARGS_NOTE): New macro.

	* argp.h (argp_program_bug_address): Make const.

1997-02-20 19:20  Ulrich Drepper  <drepper@cygnus.com>

	* sysdeps/unix/mman/syscalls.list: Explain msync interface.

1997-02-19 01:37  Erik Troan  <ewt@redhat.com>

	* shadow/sgetspent_r.c: Accept empty third, fourth and fifth fields.

1997-02-20 14:44  Andreas Jaeger  <aj@arthur.pfalz.de>

	* stdio-common/test-fseek.c: Remove temporary file, add
	copyright.

1997-02-20 17:51  Ulrich Drepper  <drepper@cygnus.com>

	* sysdeps/generic/netinet/in.h: Protect contents using
	__BEGIN/END_DECLS.  Reported by a sun <asun@zoology.washington.edu>.

	* inet/net/ethernet.h: Move to sysdeps/unix/sysv/linux/net.
	* inet/Makefile (headers): Remove net/ethernet.h.
	* sysdeps/unix/sysv/linux/Makefile: Install net/ethernet.h.
	* sysdeps/unix/sysv/linux/Dist: Distribute net/ethernet.h.

1997-02-20 15:23  Thorsten Kukuk  <kukuk@weber.uni-paderborn.de>

	* nss/nsswitch.c (__nss_configure_lookup): Use correct test when
	searching in sorted array.

1997-02-20 01:24  Philip Blundell  <pjb27@cam.ac.uk>

	* inet/getnameinfo.c: Change to use reentrant getXXbyYY functions
	and protect modification of global data.

1997-02-19 18:48  Miles Bader  <miles@gnu.ai.mit.edu>

	* argp-parse.c (argp_default_parser): Set STATE->name for OPT_PROGNAME.
	(parser_init): Use the basename for PARSER->state.name.
	* argp-help.c (__argp_error, __argp_failure, __argp_state_help):
	Use PROGRAM_INVOCATION_SHORT_NAME instead of PROGRAM_INVOCATION_NAME.

	* argp-parse.c (parser_init): Set PARSER->state.flags.
	Make check whether PARSER has the prog name in argv[0] at the
	proper place.

1997-02-19 23:34  Ulrich Drepper  <drepper@cygnus.com>

	* locale/programs/ld-time.c (time_finish): t_fmt_ampm is optional.
	Use default value instead of printing a warning.

	* nss/XXX-lookup.c: Add misssing explanation.

1997-02-19 19:14  Andreas Jaeger  <aj@arthur.pfalz.de>

	* inet/in6_addr.c: Add missing braces.

	* inet/getnameinfo.c: Include <arpa/inet.h>.

	* sysdeps/posix/getaddrinfo.c: Include <arpa/inet.h>.

1997-02-19 11:46  Ulrich Drepper  <drepper@cygnus.com>

	* string/strxfrm.c (STRCOLL): Correct handling of `position'
	levels with no non-IGNOREd element and handling of NUL byte.
	* string/strcoll.c (STRXFRM): Likewise.
	* locale/weight.h: Likewise.

	* shadow/sgetspent_r.c (LINE_PARSER): Add missing ')'.
-rw-r--r--ChangeLog129
-rw-r--r--FAQ6
-rw-r--r--Makeconfig8
-rw-r--r--Makerules6
-rw-r--r--argp/argp-fmtstream.c14
-rw-r--r--argp/argp-help.c329
-rw-r--r--argp/argp-parse.c27
-rw-r--r--argp/argp-test.c2
-rw-r--r--argp/argp.h75
-rw-r--r--catgets/gencat.c168
-rw-r--r--config.make.in1
-rwxr-xr-xconfigure100
-rw-r--r--configure.in4
-rw-r--r--db/makedb.c198
-rw-r--r--inet/getnameinfo.c158
-rw-r--r--inet/in6_addr.c6
-rw-r--r--locale/programs/ld-time.c7
-rw-r--r--locale/programs/locale.c20
-rw-r--r--locale/programs/localedef.c261
-rw-r--r--locale/weight.h30
-rw-r--r--malloc/obstack.h2
-rw-r--r--nss/XXX-lookup.c5
-rw-r--r--nss/nsswitch.c2
-rw-r--r--shadow/sgetspent_r.c2
-rw-r--r--stdio-common/test-fseek.c22
-rw-r--r--string/strcoll.c34
-rw-r--r--string/strxfrm.c20
-rw-r--r--sysdeps/generic/netinet/in.h5
-rw-r--r--sysdeps/posix/getaddrinfo.c15
-rw-r--r--sysdeps/unix/mman/syscalls.list4
-rw-r--r--sysdeps/unix/sysv/linux/Dist1
-rw-r--r--sysdeps/unix/sysv/linux/Makefile2
-rw-r--r--sysdeps/unix/sysv/linux/net/ethernet.h (renamed from inet/net/ethernet.h)0
33 files changed, 1112 insertions, 551 deletions
diff --git a/ChangeLog b/ChangeLog
index 7e805491ed..74abd961cf 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,132 @@
+1997-02-22 00:17  Ulrich Drepper  <drepper@cygnus.com>
+
+	* catgets/gencat.c: Change to use argp.
+	* db/makedb: Likewise.
+	* locale/programs/localedef.c: Likewise.
+
+	* locale/programs/locale.c: Little adjustment for better usage of
+	argp.
+
+1997-02-20 20:07  Greg McGary  <gkm@eng.ascend.com>
+
+	* Makeconfig: Add rules for libc with bounded pointers.
+	* Makerules: Likewise.
+	* config.make.in: Likewise.
+	* configure.in: Likewise.
+
+1997-02-21 10:41  Miles Bader  <miles@gnu.ai.mit.edu>
+
+	* argp.h (OPTION_NO_USAGE): New macro.
+	* argp-help.c (usage_long_opt, usage_argful_short_opt,
+	add_argless_short_opt): Implement OPTION_NO_USAGE.
+
+1997-02-20 16:41  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>
+
+	* malloc/obstack.h: Fix typo.
+
+1997-02-20 15:56  Miles Bader  <miles@gnu.ai.mit.edu>
+
+	* argp-fmtstream.c (__argp_fmtstream_update): Account for case
+	where NEXTLINE points one past the end of the active buffer.
+
+	* argp-help.c <stddef.h>: New include.
+	(__argp_failure): Only exit if STATE says it's ok.
+	(print_header, hol_entry_help): Use UPARAMS fields rather than
+	constants.
+	(_help): Call fill_in_uparams if necessary.
+	(struct hol_help_state): New type.
+	(struct pentry_state): Add hhstate field.  Remove prev_entry &
+	sep_groups fields.
+	(hol_entry_help): Add HHSTATE parameter.  Remove prev_entry &
+	sep_groups parameters.
+	Suppress duplicate arguments if requested, and note the fact.
+	(print_header, comma): Use PEST->hhstate fields.
+	(hol_help): Add HHSTATE variable & pass to hol_entry_help.
+	Remove LAST_ENTRY & SEP_GROUPS variables.
+	If any suplicate arguments were suppressed, print explanatory note.
+	(filter_doc): Replace PEST parameter with STATE.
+	(struct uparams): New type.
+	(uparams): New variable.
+	(struct uparam_name): New type.
+	(uparam_names): New variable.
+	(fill_in_uparams): New function.
+	(__argp_failure, __argp_error, __argp_state_help): Make STATE
+	parameter const.
+	* argp.h (argp_state_help, __argp_state_help, argp_usage,
+	__argp_usage, argp_error, __argp_error, argp_failure,
+	__argp_failure): Make STATE parameter const.
+	(ARGP_KEY_HELP_DUP_ARGS_NOTE): New macro.
+
+	* argp.h (argp_program_bug_address): Make const.
+
+1997-02-20 19:20  Ulrich Drepper  <drepper@cygnus.com>
+
+	* sysdeps/unix/mman/syscalls.list: Explain msync interface.
+
+1997-02-19 01:37  Erik Troan  <ewt@redhat.com>
+
+	* shadow/sgetspent_r.c: Accept empty third, fourth and fifth fields.
+
+1997-02-20 14:44  Andreas Jaeger  <aj@arthur.pfalz.de>
+
+	* stdio-common/test-fseek.c: Remove temporary file, add
+	copyright.
+
+1997-02-20 17:51  Ulrich Drepper  <drepper@cygnus.com>
+
+	* sysdeps/generic/netinet/in.h: Protect contents using
+	__BEGIN/END_DECLS.  Reported by a sun <asun@zoology.washington.edu>.
+
+	* inet/net/ethernet.h: Move to sysdeps/unix/sysv/linux/net.
+	* inet/Makefile (headers): Remove net/ethernet.h.
+	* sysdeps/unix/sysv/linux/Makefile: Install net/ethernet.h.
+	* sysdeps/unix/sysv/linux/Dist: Distribute net/ethernet.h.
+
+1997-02-20 15:23  Thorsten Kukuk  <kukuk@weber.uni-paderborn.de>
+
+	* nss/nsswitch.c (__nss_configure_lookup): Use correct test when
+	searching in sorted array.
+
+1997-02-20 01:24  Philip Blundell  <pjb27@cam.ac.uk>
+
+	* inet/getnameinfo.c: Change to use reentrant getXXbyYY functions
+	and protect modification of global data.
+
+1997-02-19 18:48  Miles Bader  <miles@gnu.ai.mit.edu>
+
+	* argp-parse.c (argp_default_parser): Set STATE->name for OPT_PROGNAME.
+	(parser_init): Use the basename for PARSER->state.name.
+	* argp-help.c (__argp_error, __argp_failure, __argp_state_help):
+	Use PROGRAM_INVOCATION_SHORT_NAME instead of PROGRAM_INVOCATION_NAME.
+
+	* argp-parse.c (parser_init): Set PARSER->state.flags.
+	Make check whether PARSER has the prog name in argv[0] at the
+	proper place.
+
+1997-02-19 23:34  Ulrich Drepper  <drepper@cygnus.com>
+
+	* locale/programs/ld-time.c (time_finish): t_fmt_ampm is optional.
+	Use default value instead of printing a warning.
+
+	* nss/XXX-lookup.c: Add misssing explanation.
+
+1997-02-19 19:14  Andreas Jaeger  <aj@arthur.pfalz.de>
+
+	* inet/in6_addr.c: Add missing braces.
+
+	* inet/getnameinfo.c: Include <arpa/inet.h>.
+
+	* sysdeps/posix/getaddrinfo.c: Include <arpa/inet.h>.
+
+1997-02-19 11:46  Ulrich Drepper  <drepper@cygnus.com>
+
+	* string/strxfrm.c (STRCOLL): Correct handling of `position'
+	levels with no non-IGNOREd element and handling of NUL byte.
+	* string/strcoll.c (STRXFRM): Likewise.
+	* locale/weight.h: Likewise.
+
+	* shadow/sgetspent_r.c (LINE_PARSER): Add missing ')'.
+
 1997-02-19 03:28  Miles Bader  <miles@gnu.ai.mit.edu>
 
 	* argp/argp-help.c: Add support for user provided filter of help
diff --git a/FAQ b/FAQ
index 2f2f0a9234..68043f8d9b 100644
--- a/FAQ
+++ b/FAQ
@@ -568,12 +568,6 @@ something like this:
 GROUP ( libc.so.6 ld.so.1 libc.a )
 
 
-{UD} The Linux ldconfig file probably generates a link libc.so ->
-libc.so.6 in /lib.  This is not correct.  There must not be such a
-link.  The linker script with the above contents is placed in
-/usr/lib which is enough for the linker.
-
-
 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
 [Q18]	``The prototypes for `connect', `accept', `getsockopt',
 	  `setsockopt', `getsockname', `getpeername', `send',
diff --git a/Makeconfig b/Makeconfig
index 2feb2b7088..811392b13e 100644
--- a/Makeconfig
+++ b/Makeconfig
@@ -509,6 +509,14 @@ CFLAGS-.o = -g0 -O99 -fomit-frame-pointer
 CFLAGS-.so += $(CFLAGS-.o)
 libtype.go = lib%_g.a
 endif
+ifeq (yes,$(build-bounded))
+# Under --enable-bounded, we build the library with `-fbounded-pointers -g'
+# to runtime bounds checking.  The bounded-pointer objects are named foo.bo.
+object-suffixes += .bo
+CPPFLAGS-.bo = -DBOUNDED_POINTERS
+CFLAGS-.bo = -g -fbounded-pointers
+libtype.bo = lib%_b.a
+endif
 
 
 +gnu-stabs = $(shell echo>&2 '*** BARF ON ME')
diff --git a/Makerules b/Makerules
index 3854af79a7..c5d5663bda 100644
--- a/Makerules
+++ b/Makerules
@@ -171,16 +171,19 @@ $(objpfx)%.o: %.S $(before-compile); $(compile-command.S)
 $(objpfx)%.so: %.S $(before-compile); $(compile-command.S)
 $(objpfx)%.po: %.S $(before-compile); $(compile-command.S)
 $(objpfx)%.go: %.S $(before-compile); $(compile-command.S)
+$(objpfx)%.bo: %.S $(before-compile); $(compile-command.S)
 $(objpfx)%.d: %.S $(before-compile); $(+make-deps)
 $(objpfx)%.o: %.s $(before-compile); $(compile-command.s)
 $(objpfx)%.so: %.s $(before-compile); $(compile-command.s)
 $(objpfx)%.po: %.s $(before-compile); $(compile-command.s)
 $(objpfx)%.go: %.s $(before-compile); $(compile-command.s)
+$(objpfx)%.bo: %.s $(before-compile); $(compile-command.s)
 $(objpfx)%.d: %.s $(common-objpfx)dummy.d; $(make-dummy-dep)
 $(objpfx)%.o: %.c $(before-compile); $(compile-command.c)
 $(objpfx)%.so: %.c $(before-compile); $(compile-command.c)
 $(objpfx)%.po: %.c $(before-compile); $(compile-command.c)
 $(objpfx)%.go: %.c $(before-compile); $(compile-command.c)
+$(objpfx)%.bo: %.c $(before-compile); $(compile-command.c)
 $(objpfx)%.d: %.c $(before-compile); $(+make-deps)
 
 # Omit the objpfx rules when building in the source tree, because
@@ -192,16 +195,19 @@ $(objpfx)%.o: $(objpfx)%.S $(before-compile); $(compile-command.S)
 $(objpfx)%.so: $(objpfx)%.S $(before-compile); $(compile-command.S)
 $(objpfx)%.po: $(objpfx)%.S $(before-compile); $(compile-command.S)
 $(objpfx)%.go: $(objpfx)%.S $(before-compile); $(compile-command.S)
+$(objpfx)%.bo: $(objpfx)%.S $(before-compile); $(compile-command.S)
 $(objpfx)%.d: $(objpfx)%.S $(before-compile); $(+make-deps)
 $(objpfx)%.o: $(objpfx)%.s $(before-compile); $(compile-command.s)
 $(objpfx)%.so: $(objpfx)%.s $(before-compile); $(compile-command.s)
 $(objpfx)%.po: $(objpfx)%.s $(before-compile); $(compile-command.s)
 $(objpfx)%.go: $(objpfx)%.s $(before-compile); $(compile-command.s)
+$(objpfx)%.bo: $(objpfx)%.s $(before-compile); $(compile-command.s)
 $(objpfx)%.d: $(objpfx)%.s $(common-objpfx)dummy.d; $(make-dummy-dep)
 $(objpfx)%.o: $(objpfx)%.c $(before-compile); $(compile-command.c)
 $(objpfx)%.so: $(objpfx)%.c $(before-compile); $(compile-command.c)
 $(objpfx)%.po: $(objpfx)%.c $(before-compile); $(compile-command.c)
 $(objpfx)%.go: $(objpfx)%.c $(before-compile); $(compile-command.c)
+$(objpfx)%.bo: $(objpfx)%.c $(before-compile); $(compile-command.c)
 $(objpfx)%.d: $(objpfx)%.c $(before-compile); $(+make-deps)
 endif
 
diff --git a/argp/argp-fmtstream.c b/argp/argp-fmtstream.c
index c7203deac6..ab2e870af8 100644
--- a/argp/argp-fmtstream.c
+++ b/argp/argp-fmtstream.c
@@ -240,7 +240,14 @@ __argp_fmtstream_update (argp_fmtstream_t fs)
 	      nextline = p;
 	    }
 
-	  if (nextline - (nl + 1) < fs->wmargin)
+	  /* Note: There are a bunch of tests below for
+	     NEXTLINE == BUF + LEN + 1; this case is where NL happens to fall
+	     at the end of the buffer, and NEXTLINE is in fact empty (and so
+	     we need not be careful to maintain its contents).  */
+
+	  if (nextline == buf + len + 1
+	      ? fs->end - nl < fs->wmargin + 1
+	      : nextline - (nl + 1) < fs->wmargin)
 	    /* The margin needs more blanks than we removed.  */
 	    if (fs->end - fs->p > fs->wmargin + 1)
 	      /* Make some space for them.  */
@@ -265,7 +272,8 @@ __argp_fmtstream_update (argp_fmtstream_t fs)
 	       the next word.  */
 	    *nl++ = '\n';
 
-	  if (nextline - nl >= fs->wmargin)
+	  if (nextline - nl >= fs->wmargin
+	      || (nextline == buf + len + 1 && fs->end - nextline >= fs->wmargin))
 	    /* Add blanks up to the wrap margin column.  */
 	    for (i = 0; i < fs->wmargin; ++i)
 	      *nl++ = ' ';
@@ -275,7 +283,7 @@ __argp_fmtstream_update (argp_fmtstream_t fs)
 
 	  /* Copy the tail of the original buffer into the current buffer
 	     position.  */
-	  if (nl != nextline)
+	  if (nl < nextline)
 	    memmove (nl, nextline, buf + len - nextline);
 	  len -= nextline - buf;
 
diff --git a/argp/argp-help.c b/argp/argp-help.c
index 84f9ca51c9..e954beb5a9 100644
--- a/argp/argp-help.c
+++ b/argp/argp-help.c
@@ -22,6 +22,7 @@
 #include <config.h>
 #endif
 
+#include <stddef.h>
 #include <stdlib.h>
 #include <string.h>
 #include <assert.h>
@@ -44,7 +45,17 @@
 #include "argp.h"
 #include "argp-fmtstream.h"
 #include "argp-namefrob.h"
+
+/* User-selectable (using an environment variable) formatting parameters.
+
+   These may be specified in an environment variable called `ARGP_HELP_FMT',
+   with a contents like:  VAR1=VAL1,VAR2=VAL2,BOOLVAR2,no-BOOLVAR2
+   Where VALn must be a positive integer.  The list of variables is in the
+   UPARAM_NAMES vector, below.  */
 
+/* Default parameters.  */
+#define DUP_ARGS      0		/* True if option argument can be duplicated. */
+#define DUP_ARGS_NOTE 1		/* True to print a note about duplicate args. */
 #define SHORT_OPT_COL 2		/* column in which short options start */
 #define LONG_OPT_COL  6		/* column in which long options start */
 #define DOC_OPT_COL   2		/* column in which doc options start */
@@ -53,6 +64,146 @@
 #define USAGE_INDENT 12		/* indentation of wrapped usage lines */
 #define RMARGIN      79		/* right margin used for wrapping */
 
+/* User-selectable (using an environment variable) formatting parameters.
+   They must all be of type `int' for the parsing code to work.  */
+struct uparams
+{
+  /* If true, arguments for an option are shown with both short and long
+     options, even when a given option has both, e.g. `-x ARG, --longx=ARG'.
+     If false, then if an option has both, the argument is only shown with
+     the long one, e.g., `-x, --longx=ARG', and a message indicating that
+     this really means both is printed below the options.  */
+  int dup_args;
+
+  /* This is true if when DUP_ARGS is false, and some duplicate arguments have
+     been suppressed, an explanatory message should be printed.  */
+  int dup_args_note;
+
+  /* Various output columns.  */
+  int short_opt_col;
+  int long_opt_col;
+  int doc_opt_col;
+  int opt_doc_col;
+  int header_col;
+  int usage_indent;
+  int rmargin;
+
+  int valid;			/* True when the values in here are valid.  */
+};
+
+/* This is a global variable, as user options are only ever read once.  */
+static struct uparams uparams = {
+  DUP_ARGS, DUP_ARGS_NOTE,
+  SHORT_OPT_COL, LONG_OPT_COL, DOC_OPT_COL, OPT_DOC_COL, HEADER_COL,
+  USAGE_INDENT, RMARGIN,
+  0
+};
+
+/* A particular uparam, and what the user name is.  */
+struct uparam_name
+{
+  const char *name;		/* User name.  */
+  int is_bool;			/* Whether it's `boolean'.  */
+  size_t uparams_offs;		/* Location of the (int) field in UPARAMS.  */
+};
+
+/* The name-field mappings we know about.  */
+static const struct uparam_name uparam_names[] =
+{
+  { "dup-args",       1, offsetof (struct uparams, dup_args) },
+  { "dup-args-note",  1, offsetof (struct uparams, dup_args_note) },
+  { "short-opt-col",  0, offsetof (struct uparams, short_opt_col) },
+  { "long-opt-col",   0, offsetof (struct uparams, long_opt_col) },
+  { "doc-opt-col",    0, offsetof (struct uparams, doc_opt_col) },
+  { "opt-doc-col",    0, offsetof (struct uparams, opt_doc_col) },
+  { "header-col",     0, offsetof (struct uparams, header_col) },
+  { "usage-indent",   0, offsetof (struct uparams, usage_indent) },
+  { "rmargin",        0, offsetof (struct uparams, rmargin) },
+  { 0 }
+};
+
+/* Read user options from the environment, and fill in UPARAMS appropiately.  */
+static void
+fill_in_uparams (const struct argp_state *state)
+{
+  const char *var = getenv ("ARGP_HELP_FMT");
+
+#define SKIPWS(p) do { while (isspace (*p)) p++; } while (0);
+
+  if (var)
+    /* Parse var. */
+    while (*var)
+      {
+	SKIPWS (var);
+
+	if (isalpha (*var))
+	  {
+	    size_t var_len;
+	    const struct uparam_name *un;
+	    int unspec = 0, val = 0;
+	    const char *arg = var;
+
+	    while (isalnum (*arg) || *arg == '-' || *arg == '_')
+	      arg++;
+	    var_len = arg - var;
+
+	    SKIPWS (arg);
+
+	    if (*arg == '\0' || *arg == ',')
+	      unspec = 1;
+	    else if (*arg == '=')
+	      {
+		arg++;
+		SKIPWS (arg);
+	      }
+	    
+	    if (unspec)
+	      if (var[0] == 'n' && var[1] == 'o' && var[2] == '-')
+		{
+		  val = 0;
+		  var += 3;
+		  var_len -= 3;
+		}
+	      else
+		val = 1;
+	    else if (isdigit (*arg))
+	      {
+		val = atoi (arg);
+		while (isdigit (*arg))
+		  arg++;
+		SKIPWS (arg);
+	      }
+
+	    for (un = uparam_names; un->name; un++)
+	      if (strlen (un->name) == var_len
+		  && strncmp (var, un->name, var_len) == 0)
+		{
+		  if (unspec && !un->is_bool)
+		    __argp_failure (state, 0, 0,
+			   _("%.*s: ARGP_HELP_FMT parameter requires a value"),
+				    (int)var_len, var);
+		  else
+		    *(int *)((char *)&uparams + un->uparams_offs) = val;
+		  break;
+		}
+	    if (! un->name)
+	      __argp_failure (state, 0, 0,
+			      _("%.*s: Unknown ARGP_HELP_FMT parameter"),
+			      (int)var_len, var);
+
+	    var = arg;
+	    if (*var == ',')
+	      var++;
+	  }
+	else if (*var)
+	  {
+	    __argp_failure (state, 0, 0,
+			    _("Garbage in ARGP_HELP_FMT: %s"), var);
+	    break;
+	  }
+      }
+}
+
 /* Returns true if OPT hasn't been marked invisible.  Visibility only affects
    whether OPT is displayed or used in sorting, not option shadowing.  */
 #define ovisible(opt) (! ((opt)->flags & OPTION_HIDDEN))
@@ -719,13 +870,28 @@ arg (const struct argp_option *real, const char *req_fmt, const char *opt_fmt,
 {
   if (real->arg)
     if (real->flags & OPTION_ARG_OPTIONAL)
-      __argp_fmtstream_printf (stream, opt_fmt, _(real->arg));
+      __argp_fmtstream_printf (stream, opt_fmt, gettext (real->arg));
     else
-      __argp_fmtstream_printf (stream, req_fmt, _(real->arg));
+      __argp_fmtstream_printf (stream, req_fmt, gettext (real->arg));
 }
 
 /* Helper functions for hol_entry_help.  */
 
+/* State used during the execution of hol_help.  */
+struct hol_help_state 
+{
+  /* PREV_ENTRY should contain the previous entry printed, or 0.  */
+  struct hol_entry *prev_entry;
+
+  /* If an entry is in a different group from the previous one, and SEP_GROUPS
+     is true, then a blank line will be printed before any output. */
+  int sep_groups;
+
+  /* True if a duplicate option argument was suppressed (only ever set if
+     UPARAMS.dup_args is false).  */
+  int suppressed_dup_arg;
+};
+
 /* Some state used while printing a help entry (used to communicate with
    helper functions).  See the doc for hol_entry_help for more info, as most
    of the fields are copied from its arguments.  */
@@ -733,8 +899,7 @@ struct pentry_state
 {
   const struct hol_entry *entry;
   argp_fmtstream_t stream;
-  struct hol_entry **prev_entry;
-  int *sep_groups;
+  struct hol_help_state *hhstate;
 
   /* True if nothing's been printed so far.  */
   int first;
@@ -746,12 +911,12 @@ struct pentry_state
 /* If a user doc filter should be applied to DOC, do so.  */
 static const char *
 filter_doc (const char *doc, int key, const struct argp *argp,
-	    struct pentry_state *pest)
+	    const struct argp_state *state)
 {
   if (argp->help_filter)
     /* We must apply a user filter to this output.  */
     {
-      void *input = __argp_input (argp, pest->state);
+      void *input = __argp_input (argp, state);
       return (*argp->help_filter) (key, doc, input);
     }
   else
@@ -769,25 +934,24 @@ print_header (const char *str, const struct argp *argp,
 	      struct pentry_state *pest)
 {
   const char *tstr = gettext (str);
-  const char *fstr = filter_doc (tstr, ARGP_KEY_HELP_HEADER, argp, pest);
+  const char *fstr = filter_doc (tstr, ARGP_KEY_HELP_HEADER, argp, pest->state);
 
   if (fstr)
     {
       if (*fstr)
 	{
-	  if (pest->prev_entry && *pest->prev_entry)
+	  if (pest->hhstate->prev_entry)
 	    /* Precede with a blank line.  */
 	    __argp_fmtstream_putc (pest->stream, '\n');
-	  indent_to (pest->stream, HEADER_COL);
-	  __argp_fmtstream_set_lmargin (pest->stream, HEADER_COL);
-	  __argp_fmtstream_set_wmargin (pest->stream, HEADER_COL);
+	  indent_to (pest->stream, uparams.header_col);
+	  __argp_fmtstream_set_lmargin (pest->stream, uparams.header_col);
+	  __argp_fmtstream_set_wmargin (pest->stream, uparams.header_col);
 	  __argp_fmtstream_puts (pest->stream, fstr);
 	  __argp_fmtstream_set_lmargin (pest->stream, 0);
 	  __argp_fmtstream_putc (pest->stream, '\n');
 	}
 
-      if (pest->sep_groups)
-	*pest->sep_groups = 1;	/* Separate subsequent groups. */
+      pest->hhstate->sep_groups = 1; /* Separate subsequent groups. */
     }
 
   if (fstr != tstr)
@@ -803,11 +967,10 @@ comma (unsigned col, struct pentry_state *pest)
 {
   if (pest->first)
     {
-      const struct hol_entry *pe = pest->prev_entry ? *pest->prev_entry : 0;
+      const struct hol_entry *pe = pest->hhstate->prev_entry;
       const struct hol_cluster *cl = pest->entry->cluster;
 
-      if (pest->sep_groups && *pest->sep_groups
-	  && pe && pest->entry->group != pe->group)
+      if (pest->hhstate->sep_groups && pe && pest->entry->group != pe->group)
 	__argp_fmtstream_putc (pest->stream, '\n');
 
       if (pe && cl && pe->cluster != cl && cl->header && *cl->header
@@ -830,38 +993,45 @@ comma (unsigned col, struct pentry_state *pest)
   indent_to (pest->stream, col);
 }
 
-/* Print help for ENTRY to STREAM.  *PREV_ENTRY should contain the last entry
-   printed before this, or null if it's the first, and if ENTRY is in a
-   different group, and *SEP_GROUPS is true, then a blank line will be
-   printed before any output.  *SEP_GROUPS is also set to true if a
-   user-specified group header is printed.  */
+/* Print help for ENTRY to STREAM.  */
 static void
 hol_entry_help (struct hol_entry *entry, const struct argp_state *state,
-		argp_fmtstream_t stream,
-		struct hol_entry **prev_entry, int *sep_groups)
+		argp_fmtstream_t stream, struct hol_help_state *hhstate)
 {
   unsigned num;
   const struct argp_option *real = entry->opt, *opt;
   char *so = entry->short_options;
+  int have_long_opt = 0;	/* We have any long options.  */
   /* Saved margins.  */
   int old_lm = __argp_fmtstream_set_lmargin (stream, 0);
   int old_wm = __argp_fmtstream_wmargin (stream);
   /* PEST is a state block holding some of our variables that we'd like to
      share with helper functions.  */
-  struct pentry_state pest = { entry, stream, prev_entry, sep_groups, 1, state };
+  struct pentry_state pest = { entry, stream, hhstate, 1, state };
+
+  if (! odoc (real))
+    for (opt = real, num = entry->num; num > 0; opt++, num--)
+      if (opt->name && ovisible (opt))
+	{
+	  have_long_opt = 1;
+	  break;
+	}
 
   /* First emit short options.  */
-  __argp_fmtstream_set_wmargin (stream, SHORT_OPT_COL); /* For truly bizarre cases. */
+  __argp_fmtstream_set_wmargin (stream, uparams.short_opt_col); /* For truly bizarre cases. */
   for (opt = real, num = entry->num; num > 0; opt++, num--)
     if (oshort (opt) && opt->key == *so)
       /* OPT has a valid (non shadowed) short option.  */
       {
 	if (ovisible (opt))
 	  {
-	    comma (SHORT_OPT_COL, &pest);
+	    comma (uparams.short_opt_col, &pest);
 	    __argp_fmtstream_putc (stream, '-');
 	    __argp_fmtstream_putc (stream, *so);
-	    arg (real, " %s", "[%s]", stream);
+	    if (!have_long_opt || uparams.dup_args)
+	      arg (real, " %s", "[%s]", stream);
+	    else if (real->arg)
+	      hhstate->suppressed_dup_arg = 1;
 	  }
 	so++;
       }
@@ -870,27 +1040,32 @@ hol_entry_help (struct hol_entry *entry, const struct argp_state *state,
   if (odoc (real))
     /* A `documentation' option.  */
     {
-      __argp_fmtstream_set_wmargin (stream, DOC_OPT_COL);
+      __argp_fmtstream_set_wmargin (stream, uparams.doc_opt_col);
       for (opt = real, num = entry->num; num > 0; opt++, num--)
 	if (opt->name && ovisible (opt))
 	  {
-	    comma (DOC_OPT_COL, &pest);
+	    comma (uparams.doc_opt_col, &pest);
 	    /* Calling gettext here isn't quite right, since sorting will
 	       have been done on the original; but documentation options
 	       should be pretty rare anyway...  */
-	    __argp_fmtstream_puts (stream, _(opt->name));
+	    __argp_fmtstream_puts (stream, gettext (opt->name));
 	  }
     }
   else
     /* A real long option.  */
     {
-      __argp_fmtstream_set_wmargin (stream, LONG_OPT_COL);
+      int first_long_opt = 1;
+
+      __argp_fmtstream_set_wmargin (stream, uparams.long_opt_col);
       for (opt = real, num = entry->num; num > 0; opt++, num--)
 	if (opt->name && ovisible (opt))
 	  {
-	    comma (LONG_OPT_COL, &pest);
+	    comma (uparams.long_opt_col, &pest);
 	    __argp_fmtstream_printf (stream, "--%s", opt->name);
-	    arg (real, "=%s", "[=%s]", stream);
+	    if (first_long_opt || uparams.dup_args)
+	      arg (real, "=%s", "[=%s]", stream);
+	    else if (real->arg)
+	      hhstate->suppressed_dup_arg = 1;
 	  }
     }
 
@@ -908,20 +1083,20 @@ hol_entry_help (struct hol_entry *entry, const struct argp_state *state,
   else
     {
       const char *tstr = real->doc ? gettext (real->doc) : 0;
-      const char *fstr = filter_doc (tstr, real->key, entry->argp, &pest);
+      const char *fstr = filter_doc (tstr, real->key, entry->argp, state);
       if (fstr && *fstr)
 	{
 	  unsigned col = __argp_fmtstream_point (stream);
 
-	  __argp_fmtstream_set_lmargin (stream, OPT_DOC_COL);
-	  __argp_fmtstream_set_wmargin (stream, OPT_DOC_COL);
+	  __argp_fmtstream_set_lmargin (stream, uparams.opt_doc_col);
+	  __argp_fmtstream_set_wmargin (stream, uparams.opt_doc_col);
 
-	  if (col > OPT_DOC_COL + 3)
+	  if (col > uparams.opt_doc_col + 3)
 	    __argp_fmtstream_putc (stream, '\n');
-	  else if (col >= OPT_DOC_COL)
+	  else if (col >= uparams.opt_doc_col)
 	    __argp_fmtstream_puts (stream, "   ");
 	  else
-	    indent_to (stream, OPT_DOC_COL);
+	    indent_to (stream, uparams.opt_doc_col);
 
 	  __argp_fmtstream_puts (stream, fstr);
 	}
@@ -933,8 +1108,7 @@ hol_entry_help (struct hol_entry *entry, const struct argp_state *state,
       __argp_fmtstream_putc (stream, '\n');
     }
 
-  if (prev_entry)
-    *prev_entry = entry;
+  hhstate->prev_entry = entry;
 
 cleanup:
   __argp_fmtstream_set_lmargin (stream, old_lm);
@@ -948,11 +1122,27 @@ hol_help (struct hol *hol, const struct argp_state *state,
 {
   unsigned num;
   struct hol_entry *entry;
-  struct hol_entry *last_entry = 0;
-  int sep_groups = 0;		/* True if we should separate different
-				   sections with blank lines.   */
+  struct hol_help_state hhstate = { 0, 0, 0 };
+
   for (entry = hol->entries, num = hol->num_entries; num > 0; entry++, num--)
-    hol_entry_help (entry, state, stream, &last_entry, &sep_groups);
+    hol_entry_help (entry, state, stream, &hhstate);
+
+  if (hhstate.suppressed_dup_arg && uparams.dup_args_note)
+    {
+      const char *tstr = _("\
+Mandatory or optional arguments to long options are also mandatory or \
+optional for any corresponding short options.");
+      const char *fstr = filter_doc (tstr, ARGP_KEY_HELP_DUP_ARGS_NOTE,
+				     state ? state->argp : 0, state);
+      if (fstr && *fstr)
+	{
+	  __argp_fmtstream_putc (stream, '\n');
+	  __argp_fmtstream_puts (stream, fstr);
+	  __argp_fmtstream_putc (stream, '\n');
+	}
+      if (fstr && fstr != tstr)
+	free ((char *) fstr);
+    }
 }
 
 /* Helper functions for hol_usage.  */
@@ -965,7 +1155,8 @@ add_argless_short_opt (const struct argp_option *opt,
 		       void *cookie)
 {
   char **snao_end = cookie;
-  if (! (opt->arg || real->arg))
+  if (!(opt->arg || real->arg)
+      && !((opt->flags | real->flags) & OPTION_NO_USAGE))
     *(*snao_end)++ = opt->key;
   return 0;
 }
@@ -979,15 +1170,16 @@ usage_argful_short_opt (const struct argp_option *opt,
 {
   argp_fmtstream_t stream = cookie;
   const char *arg = opt->arg;
+  int flags = opt->flags | real->flags;
 
   if (! arg)
     arg = real->arg;
 
-  if (arg)
+  if (arg && !(flags & OPTION_NO_USAGE))
     {
-      arg = _(arg);
+      arg = gettext (arg);
 
-      if ((opt->flags | real->flags) & OPTION_ARG_OPTIONAL)
+      if (flags & OPTION_ARG_OPTIONAL)
 	__argp_fmtstream_printf (stream, " [-%c[%s]]", opt->key, arg);
       else
 	{
@@ -1010,20 +1202,22 @@ usage_long_opt (const struct argp_option *opt,
 {
   argp_fmtstream_t stream = cookie;
   const char *arg = opt->arg;
+  int flags = opt->flags | real->flags;
 
   if (! arg)
     arg = real->arg;
 
-  if (arg)
-    {
-      arg = gettext (arg);
-      if ((opt->flags | real->flags) & OPTION_ARG_OPTIONAL)
-	__argp_fmtstream_printf (stream, " [--%s[=%s]]", opt->name, arg);
-      else
-	__argp_fmtstream_printf (stream, " [--%s=%s]", opt->name, arg);
-    }
-  else
-    __argp_fmtstream_printf (stream, " [--%s]", opt->name);
+  if (! (flags & OPTION_NO_USAGE))
+    if (arg)
+      {
+	arg = gettext (arg);
+	if (flags & OPTION_ARG_OPTIONAL)
+	  __argp_fmtstream_printf (stream, " [--%s[=%s]]", opt->name, arg);
+	else
+	  __argp_fmtstream_printf (stream, " [--%s=%s]", opt->name, arg);
+      }
+    else
+      __argp_fmtstream_printf (stream, " [--%s]", opt->name);
 
   return 0;
 }
@@ -1117,7 +1311,7 @@ argp_args_usage (const struct argp *argp, char **levels, int advance,
   char *our_level = *levels;
   int multiple = 0;
   const struct argp_child *child = argp->children;
-  const char *doc = _(argp->args_doc), *nl = 0;
+  const char *doc = gettext (argp->args_doc), *nl = 0;
 
   if (doc)
     {
@@ -1269,7 +1463,10 @@ _help (const struct argp *argp, const struct argp_state *state, FILE *stream,
   if (! stream)
     return;
 
-  fs = __argp_make_fmtstream (stream, 0, RMARGIN, 0);
+  if (! uparams.valid)
+    fill_in_uparams (state);
+
+  fs = __argp_make_fmtstream (stream, 0, uparams.rmargin, 0);
   if (! fs)
     return;
 
@@ -1390,7 +1587,7 @@ weak_alias (__argp_help, argp_help)
 /* Output, if appropriate, a usage message for STATE to STREAM.  FLAGS are
    from the set ARGP_HELP_*.  */
 void
-__argp_state_help (struct argp_state *state, FILE *stream, unsigned flags)
+__argp_state_help (const struct argp_state *state, FILE *stream, unsigned flags)
 {
   if ((!state || ! (state->flags & ARGP_NO_ERRS)) && stream)
     {
@@ -1417,7 +1614,7 @@ weak_alias (__argp_state_help, argp_state_help)
    by the program name and `:', to stderr, and followed by a `Try ... --help'
    message, then exit (1).  */
 void
-__argp_error (struct argp_state *state, const char *fmt, ...)
+__argp_error (const struct argp_state *state, const char *fmt, ...)
 {
   if (!state || !(state->flags & ARGP_NO_ERRS))
     {
@@ -1454,8 +1651,8 @@ weak_alias (__argp_error, argp_error)
    *parsing errors*, and the former is for other problems that occur during
    parsing but don't reflect a (syntactic) problem with the input.  */
 void
-__argp_failure (struct argp_state *state, int status, int errnum,
-	      const char *fmt, ...)
+__argp_failure (const struct argp_state *state, int status, int errnum,
+		const char *fmt, ...)
 {
   if (!state || !(state->flags & ARGP_NO_ERRS))
     {
@@ -1486,7 +1683,7 @@ __argp_failure (struct argp_state *state, int status, int errnum,
 
 	  putc ('\n', stream);
 
-	  if (status)
+	  if (status && (!state || !(state->flags & ARGP_NO_EXIT)))
 	    exit (status);
 	}
     }
diff --git a/argp/argp-parse.c b/argp/argp-parse.c
index af27757273..11c36be705 100644
--- a/argp/argp-parse.c
+++ b/argp/argp-parse.c
@@ -106,7 +106,7 @@ argp_default_parser (int key, char *arg, struct argp_state *state)
       break;
 
     case OPT_PROGNAME:		/* Set the program name.  */
-      program_invocation_short_name = arg;
+      program_invocation_name = arg;
 
       /* [Note that some systems only have PROGRAM_INVOCATION_SHORT_NAME (aka
 	 __PROGNAME), in which case, PROGRAM_INVOCATION_NAME is just defined
@@ -117,10 +117,13 @@ argp_default_parser (int key, char *arg, struct argp_state *state)
       else
 	program_invocation_short_name = program_invocation_name;
 
+      /* Update what we use for messages.  */
+      state->name = program_invocation_short_name;
+
       if ((state->flags & (ARGP_PARSE_ARGV0 | ARGP_NO_ERRS))
 	  == ARGP_PARSE_ARGV0)
 	/* Update what getopt uses too.  */
-	state->argv[0] = program_invocation_short_name;
+	state->argv[0] = program_invocation_name;
 
       break;
 
@@ -522,17 +525,18 @@ parser_init (struct parser *parser, const struct argp *argp,
   memset (parser->child_inputs, 0, szs.num_child_inputs * sizeof (void *));
   parser_convert (parser, argp, flags);
 
-  parser->try_getopt = 1;
-
   memset (&parser->state, 0, sizeof (struct argp_state));
   parser->state.argp = parser->argp;
   parser->state.argc = argc;
   parser->state.argv = argv;
+  parser->state.flags = flags;
   parser->state.err_stream = stderr;
   parser->state.out_stream = stdout;
   parser->state.next = 0;	/* Tell getopt to initialize.  */
   parser->state.pstate = parser;
 
+  parser->try_getopt = 1;
+
   /* Call each parser for the first time, giving it a chance to propagate
      values to child parsers.  */
   if (parser->groups < parser->egroup)
@@ -552,12 +556,6 @@ parser_init (struct parser *parser, const struct argp *argp,
   if (err)
     return err;
 
-  if (parser->state.argv == argv && argv[0])
-    /* There's an argv[0]; use it for messages.  */
-    parser->state.name = argv[0];
-  else
-    parser->state.name = program_invocation_name;
-
   /* Getopt is (currently) non-reentrant.  */
   LOCK_GETOPT;
 
@@ -572,6 +570,15 @@ parser_init (struct parser *parser, const struct argp *argp,
   else
     opterr = 1;		/* Print error messages.  */
 
+  if (parser->state.argv == argv && argv[0])
+    /* There's an argv[0]; use it for messages.  */
+    {
+      char *short_name = strrchr (argv[0], '/');
+      parser->state.name = short_name ? short_name + 1 : argv[0];
+    }
+  else
+    parser->state.name = program_invocation_short_name;
+
   return 0;
 }
 
diff --git a/argp/argp-test.c b/argp/argp-test.c
index 1ce48c3e3f..702ae9aa85 100644
--- a/argp/argp-test.c
+++ b/argp/argp-test.c
@@ -187,7 +187,7 @@ help_filter (int key, const char *text, void *input)
     asprintf (&new_text, "%s (ZOT defaults to %x)",
 	      text, params->foonly_default);
   else
-    new_text = (char *) text;
+    new_text = (char *)text;
 
   return new_text;
 }
diff --git a/argp/argp.h b/argp/argp.h
index 2e20ea67f3..cdb32b799a 100644
--- a/argp/argp.h
+++ b/argp/argp.h
@@ -108,6 +108,15 @@ struct argp_option
    is displayed after all options (and OPTION_DOC entries with a leading `-')
    in the same group.  */
 #define OPTION_DOC		0x8
+
+/* This option shouldn't be included in `long' usage messages (but is still
+   included in help messages).  This is mainly intended for options that are
+   completely documented in an argp's ARGS_DOC field, in which case including
+   the option in the generic usage list would be redundant.  For instance,
+   if ARGS_DOC is "FOO BAR\n-x BLAH", and the `-x' option's purpose is to
+   distinguish these two cases, -x should probably be marked
+   OPTION_NO_USAGE.  */
+#define OPTION_NO_USAGE		0x10
 
 struct argp;			/* fwd declare this type */
 struct argp_state;		/* " */
@@ -126,12 +135,21 @@ typedef error_t (*argp_parser_t)(int key, char *arg, struct argp_state *state);
 /* Special values for the KEY argument to an argument parsing function.
    ARGP_ERR_UNKNOWN should be returned if they aren't understood.
 
-   The sequence of keys to parser calls is either (where opt is a user key):
-       ARGP_KEY_INIT (opt | ARGP_KEY_ARG)... ARGP_KEY_END
-   or  ARGP_KEY_INIT opt... ARGP_KEY_NO_ARGS ARGP_KEY_END
+   The sequence of keys to a parsing function is either (where each
+   uppercased word should be prefixed by `ARGP_KEY_' and opt is a user key):
+
+       INIT opt... NO_ARGS END SUCCESS  -- No non-option arguments at all
+   or  INIT (opt | ARG)... END SUCCESS  -- All non-option args parsed
+   or  INIT (opt | ARG)... SUCCESS      -- Some non-option arg unrecognized
 
-   If an error occurs, then the parser is called with ARGP_KEY_ERR, and no
-   other calls are made.  */
+   The third case is where every parser returned ARGP_KEY_UNKNOWN for an
+   argument, in which case parsing stops at that argument (returning the
+   unparsed arguments to the caller of argp_parse if requested, or stopping
+   with an error message if not).
+
+   If an error occurs (either detected by argp, or because the parsing
+   function returned an error value), then the parser is called with
+   ARGP_KEY_ERROR, and no further calls are made.  */
 
 /* This is not an option at all, but rather a command line argument.  If a
    parser receiving this key returns success, the fact is recorded, and the
@@ -160,12 +178,12 @@ typedef error_t (*argp_parser_t)(int key, char *arg, struct argp_state *state);
    never made, so any cleanup must be done here).  */
 #define ARGP_KEY_ERROR		0x1000005
 
-/* An argp structure contains a set of getopt options declarations, a
-   function to deal with getting one, and an optional pointer to another
-   argp structure.  When actually parsing options, getopt is called with
-   the union of all the argp structures chained together through their
-   CHILD pointers, with conflicts being resolved in favor of the first
-   occurance in the chain.  */
+/* An argp structure contains a set of options declarations, a function to
+   deal with parsing one, documentation string, a possible vector of child
+   argp's, and perhaps a function to filter help output.  When actually
+   parsing options, getopt is called with the union of all the argp
+   structures chained together through their CHILD pointers, with conflicts
+   being resolved in favor of the first occurance in the chain.  */
 struct argp
 {
   /* An array of argp_option structures, terminated by an entry with both
@@ -220,6 +238,9 @@ struct argp
 #define ARGP_KEY_HELP_HEADER	0x2000003 /* Option header string. */
 #define ARGP_KEY_HELP_EXTRA	0x2000004 /* After all other documentation;
 					     TEXT is NULL for this key.  */
+/* Explanatory note emitted when duplicate option arguments have been
+   suppressed.  */
+#define ARGP_KEY_HELP_DUP_ARGS_NOTE 0x2000005 
 
 /* When an argp has a non-zero CHILDREN field, it should point to a vector of
    argp_child structures, each of which describes a subsidiary argp.  */
@@ -373,7 +394,7 @@ extern void (*argp_program_version_hook) __P ((FILE *__stream,
    argp_help if the ARGP_HELP_BUG_ADDR flag is set (as it is by various
    standard help messages), embedded in a sentence that says something like
    `Report bugs to ADDR.'.  */
-extern char *argp_program_bug_address;
+__const extern char *argp_program_bug_address;
 
 /* Flags for argp_help.  */
 #define ARGP_HELP_USAGE		0x01 /* a Usage: message. */
@@ -421,22 +442,22 @@ extern void __argp_help __P ((__const struct argp *__argp, FILE *__stream,
 
 /* Output, if appropriate, a usage message for STATE to STREAM.  FLAGS are
    from the set ARGP_HELP_*.  */
-extern void argp_state_help __P ((struct argp_state *__state, FILE *__stream,
-				  unsigned __flags));
-extern void __argp_state_help __P ((struct argp_state *__state, FILE *__stream,
-				    unsigned __flags));
+extern void argp_state_help __P ((__const struct argp_state *__state,
+				  FILE *__stream, unsigned __flags));
+extern void __argp_state_help __P ((__const struct argp_state *__state,
+				    FILE *__stream, unsigned __flags));
 
 /* Possibly output the standard usage message for ARGP to stderr and exit.  */
-extern void argp_usage __P ((struct argp_state *__state));
-extern void __argp_usage __P ((struct argp_state *__state));
+extern void argp_usage __P ((__const struct argp_state *__state));
+extern void __argp_usage __P ((__const struct argp_state *__state));
 
 /* If appropriate, print the printf string FMT and following args, preceded
    by the program name and `:', to stderr, and followed by a `Try ... --help'
    message, then exit (1).  */
-extern void argp_error __P ((struct argp_state *__state, __const char *__fmt,
-			     ...))
+extern void argp_error __P ((__const struct argp_state *__state,
+			     __const char *__fmt, ...))
      __attribute__ ((__format__ (__printf__, 2, 3)));
-extern void __argp_error __P ((struct argp_state *__state,
+extern void __argp_error __P ((__const struct argp_state *__state,
 			       __const char *__fmt, ...))
      __attribute__ ((__format__ (__printf__, 2, 3)));
 
@@ -448,11 +469,13 @@ extern void __argp_error __P ((struct argp_state *__state,
    difference between this function and argp_error is that the latter is for
    *parsing errors*, and the former is for other problems that occur during
    parsing but don't reflect a (syntactic) problem with the input.  */
-extern void argp_failure __P ((struct argp_state *__state, int __status,
-			       int __errnum, __const char *__fmt, ...))
+extern void argp_failure __P ((__const struct argp_state *__state,
+			       int __status, int __errnum,
+			       __const char *__fmt, ...))
      __attribute__ ((__format__ (__printf__, 4, 5)));
-extern void __argp_failure __P ((struct argp_state *__state, int __status,
-				 int __errnum, __const char *__fmt, ...))
+extern void __argp_failure __P ((__const struct argp_state *__state,
+				 int __status, int __errnum,
+				 __const char *__fmt, ...))
      __attribute__ ((__format__ (__printf__, 4, 5)));
 
 /* Returns true if the option OPT is a valid short option.  */
@@ -485,7 +508,7 @@ extern void *__argp_input __P ((__const struct argp *argp,
 #endif
 
 ARGP_EI void
-__argp_usage (struct argp_state *__state)
+__argp_usage (__const struct argp_state *__state)
 {
   __argp_state_help (__state, stderr, ARGP_HELP_STD_USAGE);
 }
diff --git a/catgets/gencat.c b/catgets/gencat.c
index 7047057832..9f1e762f53 100644
--- a/catgets/gencat.c
+++ b/catgets/gencat.c
@@ -21,12 +21,12 @@
 # include <config.h>
 #endif
 
+#include <argp.h>
 #include <ctype.h>
 #include <endian.h>
 #include <errno.h>
 #include <error.h>
 #include <fcntl.h>
-#include <getopt.h>
 #include <locale.h>
 #include <libintl.h>
 #include <limits.h>
@@ -88,22 +88,55 @@ struct catalog
 /* If non-zero force creation of new file, not using existing one.  */
 static int force_new;
 
-/* Long options.  */
-static const struct option long_options[] =
+/* Name of output file.  */
+static const char *output_name;
+
+/* Name of generated C header file.  */
+static const char *header_name;
+
+/* Name and version of program.  */
+static void print_version (FILE *stream, struct argp_state *state);
+void (*argp_program_version_hook) (FILE *, struct argp_state *) = print_version;
+
+#define OPT_NEW 1
+
+/* Definitions of arguments for argp functions.  */
+static const struct argp_option options[] =
+{
+  { "header", 'H', N_("NAME"), 0,
+    N_("Create C header file NAME containing symbol definitions") },
+  { "new", OPT_NEW, NULL, 0,
+    N_("Do not use existing catalog, force new output file") },
+  { "output", 'o', N_("NAME"), 0, N_("Write output to file NAME") },
+  { NULL, 0, NULL, 0, NULL }
+};
+
+/* Short description of program.  */
+static const char doc[] = N_("Generate message catalog.\
+\vIf INPUT-FILE is -, input is read from standard input.  If OUTPUT-FILE\n\
+is -, output is written to standard output.\n");
+
+/* Strings for arguments in help texts.  */
+static const char args_doc[] = N_("\
+-o OUTPUT-FILE [INPUT-FILE]...\n[OUTPUT-FILE [INPUT-FILE]...]");
+
+/* Prototype for option handler.  */
+static error_t parse_opt (int key, char *arg, struct argp_state *state);
+
+/* Function to print some extra text in the help message.  */
+static char *more_help (int key, const char *text, void *input);
+
+/* Data structure to communicate with argp functions.  */
+static struct argp argp =
 {
-  { "header", required_argument, NULL, 'H' },
-  { "help", no_argument, NULL, 'h' },
-  { "new", no_argument, &force_new, 1 },
-  { "output", required_argument, NULL, 'o' },
-  { "version", no_argument, NULL, 'V' },
-  { NULL, 0, NULL, 0 }
+  options, parse_opt, args_doc, doc, NULL, more_help
 };
 
+
 /* Wrapper functions with error checking for standard functions.  */
 extern void *xmalloc (size_t n);
 
 /* Prototypes for local functions.  */
-static void usage (int status) __attribute__ ((noreturn));
 static void error_print (void);
 static struct catalog *read_input_file (struct catalog *current,
 					const char *fname);
@@ -119,11 +152,6 @@ int
 main (int argc, char *argv[])
 {
   struct catalog *result;
-  const char *output_name;
-  const char *header_name;
-  int do_help;
-  int do_version;
-  int opt;
 
   /* Set program name for messages.  */
   error_print_progname = error_print;
@@ -135,50 +163,10 @@ main (int argc, char *argv[])
   textdomain (PACKAGE);
 
   /* Initialize local variables.  */
-  do_help = 0;
-  do_version = 0;
-  output_name = NULL;
-  header_name = NULL;
   result = NULL;
 
-  while ((opt = getopt_long (argc, argv, "hH:o:V", long_options, NULL)) != -1)
-    switch (opt)
-      {
-      case '\0':	/* Long option.  */
-	break;
-      case 'h':
-	do_help = 1;
-	break;
-      case 'H':
-	header_name = optarg;
-	break;
-      case 'o':
-	output_name = optarg;
-	break;
-      case 'V':
-	do_version = 1;
-	break;
-      default:
-	usage (EXIT_FAILURE);
-      }
-
-  /* Version information is requested.  */
-  if (do_version)
-    {
-      printf ("gencat (GNU %s) %s\n", PACKAGE, VERSION);
-      printf (_("\
-Copyright (C) %s Free Software Foundation, Inc.\n\
-This is free software; see the source for copying conditions.  There is NO\n\
-warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
-"), "1996, 1997");
-      printf (_("Written by %s.\n"), "Ulrich Drepper");
-
-      exit (EXIT_SUCCESS);
-    }
-
-  /* Help is requested.  */
-  if (do_help)
-    usage (EXIT_SUCCESS);
+  /* Parse and process arguments.  */
+  argp_parse (&argp, argc, argv, 0, 0, NULL);
 
   /* Determine output file.  */
   if (output_name == NULL)
@@ -201,32 +189,54 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
 }
 
 
-static void
-usage (int status)
+/* Handle program arguments.  */
+static error_t
+parse_opt (int key, char *arg, struct argp_state *state)
 {
-  if (status != EXIT_SUCCESS)
-    fprintf (stderr, gettext ("Try `%s --help' for more information.\n"),
-             program_invocation_name);
-  else
+  switch (key)
     {
-      printf (gettext ("\
-Usage: %s [OPTION]... -o OUTPUT-FILE [INPUT-FILE]...\n\
-       %s [OPTION]... [OUTPUT-FILE [INPUT-FILE]...]\n\
-Mandatory arguments to long options are mandatory for short options too.\n\
-  -H, --header        create C header file containing symbol definitions\n\
-  -h, --help          display this help and exit\n\
-      --new           do not use existing catalog, force new output file\n\
-  -o, --output=NAME   write output to file NAME\n\
-  -V, --version       output version information and exit\n\
-If INPUT-FILE is -, input is read from standard input.  If OUTPUT-FILE\n\
-is -, output is written to standard output.\n"),
-	      program_invocation_name, program_invocation_name);
-      fputs (gettext ("\
-Report bugs using the `glibcbug' script to <bugs@gnu.ai.mit.edu>.\n"),
-	     stdout);
+    case 'H':
+      header_name = arg;
+      break;
+    case OPT_NEW:
+      force_new = 1;
+      break;
+    case 'o':
+      output_name = arg;
+      break;
+    default:
+      return ARGP_ERR_UNKNOWN;
     }
+  return 0;
+}
 
-  exit (status);
+
+static char *
+more_help (int key, const char *text, void *input)
+{
+  switch (key)
+    {
+    case ARGP_KEY_HELP_EXTRA:
+      /* We print some extra information.  */
+      return strdup (gettext ("\
+Report bugs using the `glibcbug' script to <bugs@gnu.ai.mit.edu>.\n"));
+    default:
+      break;
+    }
+  return (char *) text;
+}
+
+/* Print the version information.  */
+static void
+print_version (FILE *stream, struct argp_state *state)
+{
+  fprintf (stream, "gencat (GNU %s) %s\n", PACKAGE, VERSION);
+  fprintf (stream, gettext ("\
+Copyright (C) %s Free Software Foundation, Inc.\n\
+This is free software; see the source for copying conditions.  There is NO\n\
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
+"), "1996, 1997");
+  fprintf (stream, gettext ("Written by %s.\n"), "Ulrich Drepper");
 }
 
 
diff --git a/config.make.in b/config.make.in
index d714bf7974..58f2f474f8 100644
--- a/config.make.in
+++ b/config.make.in
@@ -37,6 +37,7 @@ gnu-ld = @gnu_ld@
 build-shared = @shared@
 build-profile = @profile@
 build-omitfp = @omitfp@
+build-bounded = @bounded@
 stdio = @stdio@
 add-ons = @subdirs@
 
diff --git a/configure b/configure
index 72faab8238..a757ce72a7 100755
--- a/configure
+++ b/configure
@@ -38,6 +38,8 @@ ac_help="$ac_help
 ac_help="$ac_help
   --enable-omitfp         build undebuggable optimized library [default=no]"
 ac_help="$ac_help
+  --enable-bounded        build with runtime bounds checking [default=no]"
+ac_help="$ac_help
   --enable-add-ons=DIR... configure and build named extra directories"
 
 # Initialize some variables set by options.
@@ -676,6 +678,14 @@ else
   omitfp=no
 fi
 
+# Check whether --enable-bounded or --disable-bounded was given.
+if test "${enable_bounded+set}" = set; then
+  enableval="$enable_bounded"
+  bounded=$enableval
+else
+  bounded=no
+fi
+
 
 # Check whether --enable-add-ons or --disable-add-ons was given.
 if test "${enable_add_ons+set}" = set; then
@@ -720,7 +730,7 @@ else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
 fi
 
 echo $ac_n "checking host system type""... $ac_c" 1>&6
-echo "configure:724: checking host system type" >&5
+echo "configure:734: checking host system type" >&5
 
 host_alias=$host
 case "$host_alias" in
@@ -800,7 +810,7 @@ esac
 # This can take a while to compute.
 sysdep_dir=$srcdir/sysdeps
 echo $ac_n "checking sysdep dirs""... $ac_c" 1>&6
-echo "configure:804: checking sysdep dirs" >&5
+echo "configure:814: checking sysdep dirs" >&5
 # Make sco3.2v4 become sco3.2.4 and sunos4.1.1_U1 become sunos4.1.1.U1.
 os="`echo $os | sed 's/\([0-9A-Z]\)[v_]\([0-9A-Z]\)/\1.\2/g'`"
 
@@ -1001,7 +1011,7 @@ echo "$ac_t""sysdeps/generic sysdeps/stub" 1>&6
 # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
 # ./install, which can be erroneously created by make from ./install.sh.
 echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
-echo "configure:1005: checking for a BSD compatible install" >&5
+echo "configure:1015: checking for a BSD compatible install" >&5
 if test -z "$INSTALL"; then
 if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -1055,7 +1065,7 @@ if test "$INSTALL" = "${srcdir}/install-sh -c"; then
   INSTALL='$(..)./install-sh -c'
 fi
 echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6
-echo "configure:1059: checking whether ln -s works" >&5
+echo "configure:1069: checking whether ln -s works" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1080,7 +1090,7 @@ do
 # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1084: checking for $ac_word" >&5
+echo "configure:1094: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_MSGFMT'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1111,7 +1121,7 @@ test -n "$MSGFMT" || MSGFMT=":"
 
 
 echo $ac_n "checking build system type""... $ac_c" 1>&6
-echo "configure:1115: checking build system type" >&5
+echo "configure:1125: checking build system type" >&5
 
 build_alias=$build
 case "$build_alias" in
@@ -1137,7 +1147,7 @@ fi
 # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
 set dummy ${ac_tool_prefix}gcc; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1141: checking for $ac_word" >&5
+echo "configure:1151: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1169,7 +1179,7 @@ if test $host != $build; then
   # Extract the first word of "gcc cc", so it can be a program name with args.
 set dummy gcc cc; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1173: checking for $ac_word" >&5
+echo "configure:1183: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_BUILD_CC'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1196,7 +1206,7 @@ fi
 
 fi
 echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
-echo "configure:1200: checking how to run the C preprocessor" >&5
+echo "configure:1210: checking how to run the C preprocessor" >&5
 # On Suns, sometimes $CPP names a directory.
 if test -n "$CPP" && test -d "$CPP"; then
   CPP=
@@ -1211,13 +1221,13 @@ else
   # On the NeXT, cc -E runs the code through the compiler's parser,
   # not just through cpp.
   cat > conftest.$ac_ext <<EOF
-#line 1215 "configure"
+#line 1225 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1221: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1231: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   :
@@ -1228,13 +1238,13 @@ else
   rm -rf conftest*
   CPP="${CC-cc} -E -traditional-cpp"
   cat > conftest.$ac_ext <<EOF
-#line 1232 "configure"
+#line 1242 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1238: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1248: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   :
@@ -1259,7 +1269,7 @@ echo "$ac_t""$CPP" 1>&6
 # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args.
 set dummy ${ac_tool_prefix}ar; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1263: checking for $ac_word" >&5
+echo "configure:1273: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_AR'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1290,7 +1300,7 @@ fi
 # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
 set dummy ${ac_tool_prefix}ranlib; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1294: checking for $ac_word" >&5
+echo "configure:1304: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1321,7 +1331,7 @@ if test -n "$ac_tool_prefix"; then
   # Extract the first word of "ranlib", so it can be a program name with args.
 set dummy ranlib; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1325: checking for $ac_word" >&5
+echo "configure:1335: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1356,7 +1366,7 @@ fi
 # Extract the first word of "bash", so it can be a program name with args.
 set dummy bash; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1360: checking for $ac_word" >&5
+echo "configure:1370: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_BASH'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1397,7 +1407,7 @@ if test "$BASH" = no; then
   # Extract the first word of "ksh", so it can be a program name with args.
 set dummy ksh; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1401: checking for $ac_word" >&5
+echo "configure:1411: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_KSH'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1439,7 +1449,7 @@ fi
 
 
 echo $ac_n "checking for signed size_t type""... $ac_c" 1>&6
-echo "configure:1443: checking for signed size_t type" >&5
+echo "configure:1453: checking for signed size_t type" >&5
 if eval "test \"`echo '$''{'libc_cv_signed_size_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1463,12 +1473,12 @@ EOF
 fi
 
 echo $ac_n "checking for libc-friendly stddef.h""... $ac_c" 1>&6
-echo "configure:1467: checking for libc-friendly stddef.h" >&5
+echo "configure:1477: checking for libc-friendly stddef.h" >&5
 if eval "test \"`echo '$''{'libc_cv_friendly_stddef'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1472 "configure"
+#line 1482 "configure"
 #include "confdefs.h"
 #define __need_size_t
 #define __need_wchar_t
@@ -1483,7 +1493,7 @@ size_t size; wchar_t wchar;
 if (&size == NULL || &wchar == NULL) abort ();
 ; return 0; }
 EOF
-if { (eval echo configure:1487: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1497: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   libc_cv_friendly_stddef=yes
 else
@@ -1502,7 +1512,7 @@ override stddef.h = # The installed <stddef.h> seems to be libc-friendly."
 fi
 
 echo $ac_n "checking whether we need to use -P to assemble .S files""... $ac_c" 1>&6
-echo "configure:1506: checking whether we need to use -P to assemble .S files" >&5
+echo "configure:1516: checking whether we need to use -P to assemble .S files" >&5
 if eval "test \"`echo '$''{'libc_cv_need_minus_P'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1525,7 +1535,7 @@ asm-CPPFLAGS = -P # The assembler can't grok cpp's # line directives."
 fi
 
 echo $ac_n "checking for assembler global-symbol directive""... $ac_c" 1>&6
-echo "configure:1529: checking for assembler global-symbol directive" >&5
+echo "configure:1539: checking for assembler global-symbol directive" >&5
 if eval "test \"`echo '$''{'libc_cv_asm_global_directive'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1555,7 +1565,7 @@ EOF
 fi
 
 echo $ac_n "checking for .set assembler directive""... $ac_c" 1>&6
-echo "configure:1559: checking for .set assembler directive" >&5
+echo "configure:1569: checking for .set assembler directive" >&5
 if eval "test \"`echo '$''{'libc_cv_asm_set_directive'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1590,7 +1600,7 @@ fi
 
 if test $elf = yes; then
   echo $ac_n "checking for .previous assembler directive""... $ac_c" 1>&6
-echo "configure:1594: checking for .previous assembler directive" >&5
+echo "configure:1604: checking for .previous assembler directive" >&5
 if eval "test \"`echo '$''{'libc_cv_asm_previous_directive'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1598,7 +1608,7 @@ else
 .section foo_section
 .previous
 EOF
-  if { ac_try='${CC-cc} -c $CFLAGS conftest.s 1>&5'; { (eval echo configure:1602: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
+  if { ac_try='${CC-cc} -c $CFLAGS conftest.s 1>&5'; { (eval echo configure:1612: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
     libc_cv_asm_previous_directive=yes
   else
     libc_cv_asm_previous_directive=no
@@ -1614,7 +1624,7 @@ EOF
 
   else
     echo $ac_n "checking for .popsection assembler directive""... $ac_c" 1>&6
-echo "configure:1618: checking for .popsection assembler directive" >&5
+echo "configure:1628: checking for .popsection assembler directive" >&5
 if eval "test \"`echo '$''{'libc_cv_asm_popsection_directive'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1622,7 +1632,7 @@ else
 .pushsection foo_section
 .popsection
 EOF
-    if { ac_try='${CC-cc} -c $CFLAGS conftest.s 1>&5'; { (eval echo configure:1626: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
+    if { ac_try='${CC-cc} -c $CFLAGS conftest.s 1>&5'; { (eval echo configure:1636: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
       libc_cv_asm_popsection_directive=yes
     else
       libc_cv_asm_popsection_directive=no
@@ -1642,12 +1652,12 @@ fi
 
 if test $elf != yes; then
   echo $ac_n "checking for .init and .fini sections""... $ac_c" 1>&6
-echo "configure:1646: checking for .init and .fini sections" >&5
+echo "configure:1656: checking for .init and .fini sections" >&5
 if eval "test \"`echo '$''{'libc_cv_have_initfini'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1651 "configure"
+#line 1661 "configure"
 #include "confdefs.h"
 
 int main() {
@@ -1656,7 +1666,7 @@ asm (".section .init");
 				    asm (".text");
 ; return 0; }
 EOF
-if { (eval echo configure:1660: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1670: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   libc_cv_have_initfini=yes
 else
@@ -1681,19 +1691,19 @@ if test $elf = yes; then
   libc_cv_asm_underscores=no
 else
   echo $ac_n "checking for _ prefix on C symbol names""... $ac_c" 1>&6
-echo "configure:1685: checking for _ prefix on C symbol names" >&5
+echo "configure:1695: checking for _ prefix on C symbol names" >&5
 if eval "test \"`echo '$''{'libc_cv_asm_underscores'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1690 "configure"
+#line 1700 "configure"
 #include "confdefs.h"
 asm ("_glibc_foobar:");
 int main() {
 glibc_foobar ();
 ; return 0; }
 EOF
-if { (eval echo configure:1697: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:1707: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   libc_cv_asm_underscores=yes
 else
@@ -1720,7 +1730,7 @@ if test $elf = yes; then
   libc_cv_asm_weakext_directive=no
 else
   echo $ac_n "checking for assembler .weak directive""... $ac_c" 1>&6
-echo "configure:1724: checking for assembler .weak directive" >&5
+echo "configure:1734: checking for assembler .weak directive" >&5
 if eval "test \"`echo '$''{'libc_cv_asm_weak_directive'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1743,7 +1753,7 @@ echo "$ac_t""$libc_cv_asm_weak_directive" 1>&6
 
 if test $libc_cv_asm_weak_directive = no; then
   echo $ac_n "checking for assembler .weakext directive""... $ac_c" 1>&6
-echo "configure:1747: checking for assembler .weakext directive" >&5
+echo "configure:1757: checking for assembler .weakext directive" >&5
 if eval "test \"`echo '$''{'libc_cv_asm_weakext_directive'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1780,7 +1790,7 @@ EOF
 fi
 
 echo $ac_n "checking for ld --no-whole-archive""... $ac_c" 1>&6
-echo "configure:1784: checking for ld --no-whole-archive" >&5
+echo "configure:1794: checking for ld --no-whole-archive" >&5
 if eval "test \"`echo '$''{'libc_cv_ld_no_whole_archive'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1791,7 +1801,7 @@ __throw () {}
 EOF
 if { ac_try='${CC-cc} $CFLAGS
 			    -nostdlib -nostartfiles -Wl,--no-whole-archive
-			    -o conftest conftest.c'; { (eval echo configure:1795: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
+			    -o conftest conftest.c'; { (eval echo configure:1805: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
   libc_cv_ld_no_whole_archive=yes
 else
   libc_cv_ld_no_whole_archive=no
@@ -1802,7 +1812,7 @@ fi
 echo "$ac_t""$libc_cv_ld_no_whole_archive" 1>&6
 
 echo $ac_n "checking for gcc -fno-exceptions""... $ac_c" 1>&6
-echo "configure:1806: checking for gcc -fno-exceptions" >&5
+echo "configure:1816: checking for gcc -fno-exceptions" >&5
 if eval "test \"`echo '$''{'libc_cv_gcc_no_exceptions'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1813,7 +1823,7 @@ __throw () {}
 EOF
 if { ac_try='${CC-cc} $CFLAGS
 			    -nostdlib -nostartfiles -fno-exceptions
-			    -o conftest conftest.c'; { (eval echo configure:1817: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
+			    -o conftest conftest.c'; { (eval echo configure:1827: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
   libc_cv_gcc_no_exceptions=yes
 else
   libc_cv_gcc_no_exceptions=no
@@ -1865,7 +1875,7 @@ if test "$uname" = generic; then
   fi
 
   echo $ac_n "checking OS release for uname""... $ac_c" 1>&6
-echo "configure:1869: checking OS release for uname" >&5
+echo "configure:1879: checking OS release for uname" >&5
 if eval "test \"`echo '$''{'libc_cv_uname_release'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1887,7 +1897,7 @@ echo "$ac_t""$libc_cv_uname_release" 1>&6
   uname_release="$libc_cv_uname_release"
 
   echo $ac_n "checking OS version for uname""... $ac_c" 1>&6
-echo "configure:1891: checking OS version for uname" >&5
+echo "configure:1901: checking OS version for uname" >&5
 if eval "test \"`echo '$''{'libc_cv_uname_version'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1909,7 +1919,7 @@ else
 fi
 
 echo $ac_n "checking stdio selection""... $ac_c" 1>&6
-echo "configure:1913: checking stdio selection" >&5
+echo "configure:1923: checking stdio selection" >&5
 
 case $stdio in
 libio) cat >> confdefs.h <<\EOF
@@ -1961,6 +1971,7 @@ fi
 
 
 
+
 if test "`(cd $srcdir; pwd)`" = "`pwd`"; then
   config_makefile=
 else
@@ -2144,6 +2155,7 @@ s%@elf@%$elf%g
 s%@shared@%$shared%g
 s%@profile@%$profile%g
 s%@omitfp@%$omitfp%g
+s%@bounded@%$bounded%g
 s%@DEFINES@%$DEFINES%g
 s%@VERSION@%$VERSION%g
 
diff --git a/configure.in b/configure.in
index f3e97798e6..8b797c792e 100644
--- a/configure.in
+++ b/configure.in
@@ -75,6 +75,9 @@ AC_ARG_ENABLE(profile, dnl
 AC_ARG_ENABLE(omitfp, dnl
 [  --enable-omitfp         build undebuggable optimized library [default=no]],
 	      omitfp=$enableval, omitfp=no)
+AC_ARG_ENABLE(bounded, dnl
+[  --enable-bounded        build with runtime bounds checking [default=no]],
+	      bounded=$enableval, bounded=no)
 
 dnl Generic infrastructure for drop-in additions to libc.
 AC_ARG_ENABLE(add-ons, dnl
@@ -755,6 +758,7 @@ if test $shared = default; then
 fi
 AC_SUBST(profile)
 AC_SUBST(omitfp)
+AC_SUBST(bounded)
 
 AC_SUBST(DEFINES)
 
diff --git a/db/makedb.c b/db/makedb.c
index 7ce9548788..9f84ea39fc 100644
--- a/db/makedb.c
+++ b/db/makedb.c
@@ -1,4 +1,4 @@
-/* makedb -- create simple DB database from textual input.
+/* Create simple DB database from textual input.
    Copyright (C) 1996, 1997 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
@@ -18,12 +18,12 @@
    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.  */
 
-#include <db.h>
+#include <argp.h>
 #include <ctype.h>
+#include <db.h>
 #include <errno.h>
 #include <error.h>
 #include <fcntl.h>
-#include <getopt.h>
 #include <libintl.h>
 #include <locale.h>
 #include <stdio.h>
@@ -35,20 +35,55 @@
 
 #define PACKAGE _libc_intl_domainname
 
-/* Long options.  */
-static const struct option long_options[] =
+/* If non-zero convert key to lower case.  */
+static int to_lowercase;
+
+/* If non-zero print content of input file, one entry per line.  */
+static int do_undo;
+
+/* If non-zero do not print informational messages.  */
+static int be_quiet;
+
+/* Name of output file.  */
+static const char *output_name;
+
+/* Name and version of program.  */
+static void print_version (FILE *stream, struct argp_state *state);
+void (*argp_program_version_hook) (FILE *, struct argp_state *) = print_version;
+
+/* Definitions of arguments for argp functions.  */
+static const struct argp_option options[] =
+{
+  { "fold-case", 'f', NULL, 0, N_("Convert key to lower case") },
+  { "output", 'o', N_("NAME"), 0, N_("Write output to file NAME") },
+  { "quiet", 'q', NULL, 0,
+    N_("Do not print messages while building database") },
+  { "undo", 'u', NULL, 0,
+    N_("Print content of database file, one entry a line") },
+  { NULL, 0, NULL, 0, NULL }
+};
+
+/* Short description of program.  */
+static const char doc[] = N_("Create simple DB database from textual input.");
+
+/* Strings for arguments in help texts.  */
+static const char args_doc[] = N_("\
+INPUT-FILE OUTPUT-FILE\n-o OUTPUT-FILE INPUT-FILE\n-u INPUT-FILE");
+
+/* Prototype for option handler.  */
+static error_t parse_opt __P ((int key, char *arg, struct argp_state *state));
+
+/* Function to print some extra text in the help message.  */
+static char *more_help __P ((int key, const char *text, void *input));
+
+/* Data structure to communicate with argp functions.  */
+static struct argp argp =
 {
-  { "help", no_argument, NULL, 'h' },
-  { "fold-case", no_argument, NULL, 'f' },
-  { "output", required_argument, NULL, 'o' },
-  { "quiet", no_argument, NULL, 'q' },
-  { "undo", no_argument, NULL, 'u' },
-  { "version", no_argument, NULL, 'V' },
-  { NULL, 0, NULL, 0}
+  options, parse_opt, args_doc, doc, NULL, more_help
 };
 
+
 /* Prototypes for local functions.  */
-static void usage __P ((int status)) __attribute__ ((noreturn));
 static int process_input __P ((FILE *input, const char *inname, DB *output,
 			       int to_lowercase, int be_quiet));
 static int print_database __P ((DB *db));
@@ -60,17 +95,10 @@ main (argc, argv)
      int argc;
      char *argv[];
 {
-  const char *output_name;
   const char *input_name;
   FILE *input_file;
   DB *db_file;
-  int do_help;
-  int do_version;
-  int to_lowercase;
-  int do_undo;
-  int be_quiet;
   int status;
-  int opt;
 
   /* Set locale via LC_ALL.  */
   setlocale (LC_ALL, "");
@@ -79,59 +107,10 @@ main (argc, argv)
   textdomain (_libc_intl_domainname);
 
   /* Initialize local variables.  */
-  do_help = 0;
-  do_version = 0;
-  to_lowercase = 0;
-  do_undo = 0;
-  be_quiet = 0;
-  output_name = NULL;
-
-  while ((opt = getopt_long (argc, argv, "fho:uV", long_options, NULL)) != -1)
-    switch (opt)
-      {
-      case '\0':        /* Long option.  */
-        break;
-      case 'h':
-        do_help = 1;
-        break;
-      case 'f':
-	to_lowercase = 1;
-	break;
-      case 'o':
-        output_name = optarg;
-        break;
-      case 'q':
-	be_quiet = 1;
-	break;
-      case 'u':
-	do_undo = 1;
-	break;
-      case 'V':
-        do_version = 1;
-        break;
-      default:
-        usage (EXIT_FAILURE);
-      }
-
-  /* Version information is requested.  */
-  if (do_version)
-    {
-      printf ("makedb (GNU %s) %s\n", PACKAGE, VERSION);
-      printf (_("\
-Copyright (C) %s Free Software Foundation, Inc.\n\
-This is free software; see the source for copying conditions.  There is NO\n\
-warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
-"), "1996, 1997");
-      printf (_("Written by %s.\n"), "Ulrich Drepper");
-
-      exit (EXIT_SUCCESS);
-    }
+  input_name = NULL;
 
-  /* Help is requested.  */
-  if (do_help)
-    usage (EXIT_SUCCESS);
-  else if (do_version)
-    exit (EXIT_SUCCESS);
+  /* Parse and process arguments.  */
+  argp_parse (&argp, argc, argv, 0, 0, NULL);
 
   /* Determine file names.  */
   if (do_undo || output_name != NULL)
@@ -140,7 +119,8 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
 	{
 	wrong_arguments:
 	  error (0, 0, gettext ("wrong number of arguments"));
-	  usage (EXIT_FAILURE);
+	  argp_help (&argp, stdout, ARGP_HELP_SEE,
+		     program_invocation_short_name);
 	}
       input_name = argv[optind];
     }
@@ -201,35 +181,57 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
 }
 
 
-static void
-usage (status)
-     int status;
+/* Handle program arguments.  */
+static error_t
+parse_opt (int key, char *arg, struct argp_state *state)
 {
-  if (status != EXIT_SUCCESS)
-    fprintf (stderr, gettext ("Try `%s --help' for more information.\n"),
-             program_invocation_name);
-  else
+  switch (key)
+    {
+    case 'f':
+      to_lowercase = 1;
+      break;
+    case 'o':
+      output_name = arg;
+      break;
+    case 'q':
+      be_quiet = 1;
+      break;
+    case 'u':
+      do_undo = 1;
+      break;
+    default:
+      return ARGP_ERR_UNKNOWN;
+    }
+  return 0;
+}
+
+
+static char *
+more_help (int key, const char *text, void *input)
+{
+  switch (key)
     {
-      printf (gettext ("\
-Usage: %s [OPTION]... INPUT-FILE OUTPUT-FILE\n\
-       %s [OPTION]... -o OUTPUT-FILE INPUT-FILE\n\
-       %s [OPTION]... -u INPUT-FILE\n\
-Mandatory arguments to long options are mandatory for short options too.\n\
-  -f, --fold-case     convert key to lower case\n\
-  -h, --help          display this help and exit\n\
-  -o, --output=NAME   write output to file NAME\n\
-      --quiet         don't print messages while building database\n\
-  -u, --undo          print content of database file, one entry a line\n\
-  -V, --version       output version information and exit\n\
-If INPUT-FILE is -, input is read from standard input.\n"),
-	      program_invocation_name, program_invocation_name,
-	      program_invocation_name);
-      fputs (gettext ("\
-Report bugs using the `glibcbug' script to <bugs@gnu.ai.mit.edu>.\n"),
-	     stdout);
+    case ARGP_KEY_HELP_EXTRA:
+      /* We print some extra information.  */
+      return strdup (gettext ("\
+Report bugs using the `glibcbug' script to <bugs@gnu.ai.mit.edu>.\n"));
+    default:
+      break;
     }
+  return (char *) text;
+}
 
-  exit (status);
+/* Print the version information.  */
+static void
+print_version (FILE *stream, struct argp_state *state)
+{
+  fprintf (stream, "makedb (GNU %s) %s\n", PACKAGE, VERSION);
+  fprintf (stream, gettext ("\
+Copyright (C) %s Free Software Foundation, Inc.\n\
+This is free software; see the source for copying conditions.  There is NO\n\
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
+"), "1996, 1997");
+  fprintf (stream, gettext ("Written by %s.\n"), "Ulrich Drepper");
 }
 
 
diff --git a/inet/getnameinfo.c b/inet/getnameinfo.c
index b9454f6396..95ed6bf3f9 100644
--- a/inet/getnameinfo.c
+++ b/inet/getnameinfo.c
@@ -45,6 +45,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #define INET6 1
 #define LOCAL 1
 #define HOSTTABLE 0
+#define RESOLVER 1
 
 #include <sys/types.h>
 #include <sys/socket.h>
@@ -59,6 +60,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <string.h>
 #include <stdio.h>
 #include <unistd.h>
+#include <alloca.h>
+#include <libc-lock.h>
+#include <arpa/inet.h>
 
 #ifndef AF_LOCAL
 #define AF_LOCAL AF_UNIX
@@ -79,39 +83,91 @@ struct hostent *_addr2hostname_hosts(const char *, int, int);
 static char *domain;
 static char domainbuffer[MAXHOSTNAMELEN];
 
-
-static char *
-nrl_domainname (void)
+static char *nrl_domainname(void)
 {
   static int first = 1;
 
   if (first) {
-    char *c;
-    struct hostent *h;
-
-    first = 0;
-
-    if ((h = gethostbyname("localhost")) && (c = strchr(h->h_name, '.')))
-      return strcpy(domain = domainbuffer, ++c);
-
-    if (!gethostname(domainbuffer, sizeof(domainbuffer))) {
-      if (c = strchr(domainbuffer, '.'))
-        return (domain = ++c);
-
-      if ((h = gethostbyname(domainbuffer)) && (c = strchr(h->h_name, '.')))
-        return strcpy(domain = domainbuffer, ++c);
-    }
 
-    {
-      struct in_addr in_addr;
+    __libc_lock_define_initialized (static, lock);
+    __libc_lock_lock (lock);
+
+    if (first) {
+      char *c;
+      struct hostent *h, th;
+      int tmpbuflen = 1024;
+      char *tmpbuf = __alloca(tmpbuflen);
+      int herror;
+
+      first = 0;
+
+      while (__gethostbyname_r("localhost", &th, tmpbuf, tmpbuflen, &h,
+			       &herror)) {
+	if (herror == NETDB_INTERNAL) {
+	  if (errno == ERANGE) {
+	    tmpbuflen *= 2;
+	    tmpbuf = __alloca(tmpbuflen);
+	  }
+	} else {
+	  break;
+	}
+      }
+
+      if (h && (c = strchr(h->h_name, '.'))) {
+	strcpy(domain = domainbuffer, ++c);
+	goto ret;
+      }
+
+      if (!gethostname(domainbuffer, sizeof(domainbuffer))) {
+	if (c = strchr(domainbuffer, '.')) {
+	  domain = ++c;
+	  goto ret;
+	}
+
+	while (__gethostbyname_r(domainbuffer, &th, tmpbuf, tmpbuflen, &h,
+				 &herror)) {
+	  if (herror == NETDB_INTERNAL) {
+	    if (errno == ERANGE) {
+	      tmpbuflen *= 2;
+	      tmpbuf = __alloca(tmpbuflen);
+	    }
+	  } else {
+	    break;
+	  }
+	}
+
+	if (h && (c = strchr(h->h_name, '.'))) {
+	  strcpy(domain = domainbuffer, ++c);
+	  goto ret;
+	}
+      }
+
+      {
+	struct in_addr in_addr;
+
+	in_addr.s_addr = htonl(0x7f000001);
+
+	while (__gethostbyaddr_r((const char *)&in_addr, sizeof(struct in_addr), AF_INET, &th, tmpbuf, tmpbuflen, &h, &herror)) {
+	  if (herror == NETDB_INTERNAL) {
+	    if (errno == ERANGE) {
+	      tmpbuflen *= 2;
+	      tmpbuf = __alloca(tmpbuflen);
+	    }
+	  } else {
+	    break;
+	  }
+	}
 
-      in_addr.s_addr = htonl(0x7f000001);
+	if (h && (c = strchr(h->h_name, '.'))) {
+	  domain = domainbuffer, ++c;
+	  goto ret;
+	}
+      }
 
-      if ((h = gethostbyaddr((const char *)&in_addr, sizeof(struct in_addr), AF_INET)) && (c = strchr(h->h_name, '.')))
-        return strcpy(domain = domainbuffer, ++c);
     }
 
-    return NULL;
+  ret:
+    __libc_lock_unlock (lock);
   };
 
   return domain;
@@ -120,6 +176,10 @@ nrl_domainname (void)
 int getnameinfo(const struct sockaddr *sa, size_t addrlen, char *host, size_t hostlen, char *serv, size_t servlen, int flags)
 {
   int serrno = errno;
+  int tmpbuflen = 1024;
+  int herrno;
+  char *tmpbuf = __alloca(tmpbuflen);
+  struct hostent th;
 
   if (!sa)
     return -1;
@@ -144,20 +204,39 @@ int getnameinfo(const struct sockaddr *sa, size_t addrlen, char *host, size_t ho
 #if RESOLVER
 	  if (!h) {
 #if INET6
-	    if (sa->sa_family == AF_INET6)
-	      h = gethostbyaddr((void *)&(((struct sockaddr_in6 *)sa)->sin6_addr), sizeof(struct in6_addr), AF_INET6);
-	    else
+	    if (sa->sa_family == AF_INET6) {
+	      while (__gethostbyaddr_r((void *)&(((struct sockaddr_in6 *)sa)->sin6_addr), sizeof(struct in6_addr), AF_INET6, &th, tmpbuf, tmpbuflen, &h, &herrno)) {
+		if (herrno == NETDB_INTERNAL) {
+		  if (errno == ERANGE) {
+		    tmpbuflen *= 2;
+		    tmpbuf = __alloca(tmpbuflen);
+		  } else {
+		    __set_h_errno(herrno);
+		    goto fail;
+		  }
+		} else {
+		  break;
+		}
+	      }
+	    } else {
 #endif /* INET6 */
-	      h = gethostbyaddr((void *)&(((struct sockaddr_in *)sa)->sin_addr), sizeof(struct in_addr), AF_INET);
-	    endhostent();
-	  };
+	      while (__gethostbyaddr_r((void *)&(((struct sockaddr_in *)sa)->sin_addr), sizeof(struct in_addr), AF_INET, &th, tmpbuf, tmpbuflen, &h, &herrno)) {
+		if (errno == ERANGE) {
+		  tmpbuflen *= 2;
+		  tmpbuf = __alloca(tmpbuflen);
+		} else {
+		  break;
+		}
+	      }
+	    }
+	  }
 #endif /* RESOLVER */
 
 	  if (h) {
 	    if (flags & NI_NOFQDN) {
 	      char *c;
 	      if ((c = nrl_domainname()) && (c = strstr(h->h_name, c)) && (c != h->h_name) && (*(--c) == '.')) {
-		strncpy(host, h->h_name, min(hostlen, (c - h->h_name)));
+		strncpy(host, h->h_name, min(hostlen, (size_t) (c - h->h_name)));
 		break;
 	      };
 	    };
@@ -210,8 +289,20 @@ int getnameinfo(const struct sockaddr *sa, size_t addrlen, char *host, size_t ho
       case AF_INET6:
 #endif /* INET6 */
 	if (!(flags & NI_NUMERICSERV)) {
-	  struct servent *s;
-	  if (s = getservbyport(((struct sockaddr_in *)sa)->sin_port, (flags & NI_DGRAM) ? "udp" : "tcp")) {
+	  struct servent *s, ts;
+	  while (__getservbyport_r(((struct sockaddr_in *)sa)->sin_port, ((flags & NI_DGRAM) ? "udp" : "tcp"), &ts, tmpbuf, tmpbuflen, &s)) {
+	    if (herrno == NETDB_INTERNAL) {
+	      if (errno == ERANGE) {
+		tmpbuflen *= 2;
+		tmpbuf = __alloca(tmpbuflen);
+	      } else {
+		goto fail;
+	      }
+	    } else {
+	      break;
+	    }
+	  }
+	  if (s) {
 	    strncpy(serv, s->s_name, servlen);
 	    break;
 	  };
@@ -224,7 +315,6 @@ int getnameinfo(const struct sockaddr *sa, size_t addrlen, char *host, size_t ho
 	break;
 #endif /* LOCAL */
     };
-
   if (host && (hostlen > 0))
     host[hostlen-1] = 0;
   if (serv && (servlen > 0))
diff --git a/inet/in6_addr.c b/inet/in6_addr.c
index a68990e160..69c9c0b468 100644
--- a/inet/in6_addr.c
+++ b/inet/in6_addr.c
@@ -19,8 +19,10 @@
 
 #include <netinet/in.h>
 
-const struct in6_addr in6addr_any = { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } };
-const struct in6_addr in6addr_loopback = { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } };
+const struct in6_addr in6addr_any =
+{ { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } } };
+const struct in6_addr in6addr_loopback =
+{ { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } } };
 
 int inet6_isipv4mapped(const struct in6_addr *addr)
 {
diff --git a/locale/programs/ld-time.c b/locale/programs/ld-time.c
index b977763433..60c54deb3a 100644
--- a/locale/programs/ld-time.c
+++ b/locale/programs/ld-time.c
@@ -127,7 +127,12 @@ time_finish (struct localedef_t *locale)
   TEST_ELEM (d_t_fmt);
   TEST_ELEM (d_fmt);
   TEST_ELEM (t_fmt);
-  TEST_ELEM (t_fmt_ampm);
+
+  /* According to C.Y.Alexis Cheng <alexis@vnet.ibm.com> the T_FMT_AMPM
+     field is optional.  */
+  if (time->t_fmt_ampm == NULL)
+    /* Use the 24h format as default.  */
+    time->t_fmt_ampm = time->t_fmt;
 
   /* Now process the era entries.  */
   if (time->cur_num_era != 0)
diff --git a/locale/programs/locale.c b/locale/programs/locale.c
index 5a68c562ef..e2157311c1 100644
--- a/locale/programs/locale.c
+++ b/locale/programs/locale.c
@@ -58,22 +58,24 @@ static void print_version (FILE *stream, struct argp_state *state);
 void (*argp_program_version_hook) (FILE *, struct argp_state *) = print_version;
 
 /* Definitions of arguments for argp functions.  */
-static struct argp_option options[] =
+static const struct argp_option options[] =
 {
-  { NULL, 0, NULL, 0, "System information:" },
-  { "all-locales", 'a', NULL, 0, "Write names of available locales" },
-  { "charmaps", 'm', NULL, 0, "Write names of available charmaps" },
-  { NULL, 0, NULL, 0, "Modify output format:" },
-  { "category-name", 'c', NULL, 0, "Write names of selected categories" },
-  { "keyword-name", 'k', NULL, 0, "Write names of selected keywords" },
+  { NULL, 0, NULL, 0, N_("System information:") },
+  { "all-locales", 'a', NULL, OPTION_NO_USAGE,
+    N_("Write names of available locales") },
+  { "charmaps", 'm', NULL, OPTION_NO_USAGE,
+    N_("Write names of available charmaps") },
+  { NULL, 0, NULL, 0, N_("Modify output format:") },
+  { "category-name", 'c', NULL, 0, N_("Write names of selected categories") },
+  { "keyword-name", 'k', NULL, 0, N_("Write names of selected keywords") },
   { NULL, 0, NULL, 0, NULL }
 };
 
 /* Short description of program.  */
-static const char doc[] = "Get locale-specific information.";
+static const char doc[] = N_("Get locale-specific information.");
 
 /* Strings for arguments in help texts.  */
-static const char args_doc[] = "NAME\n[-a|-m]";
+static const char args_doc[] = N_("NAME\n[-a|-m]");
 
 /* Prototype for option handler.  */
 static error_t parse_opt (int key, char *arg, struct argp_state *state);
diff --git a/locale/programs/localedef.c b/locale/programs/localedef.c
index da01d4c974..656377f9df 100644
--- a/locale/programs/localedef.c
+++ b/locale/programs/localedef.c
@@ -21,9 +21,9 @@
 # include <config.h>
 #endif
 
+#include <argp.h>
 #include <errno.h>
 #include <fcntl.h>
-#include <getopt.h>
 #include <libintl.h>
 #include <locale.h>
 #include <stdio.h>
@@ -73,20 +73,62 @@ int verbose;
 /* If not zero suppress warnings and information messages.  */
 int be_quiet;
 
+/* If not zero force output even if warning were issued.  */
+static int force_output;
 
-/* Long options.  */
-static const struct option long_options[] =
+/* Name of the character map file.  */
+static const char *charmap_file;
+
+/* Name of the locale definition file.  */
+static const char *input_file;
+
+/* Name of the UCS file.  */
+static const char *ucs_csn;
+
+
+/* Name and version of program.  */
+static void print_version (FILE *stream, struct argp_state *state);
+void (*argp_program_version_hook) (FILE *, struct argp_state *) = print_version;
+
+#define OPT_POSIX 1
+#define OPT_QUIET 2
+
+/* Definitions of arguments for argp functions.  */
+static const struct argp_option options[] =
+{
+  { NULL, 0, NULL, 0, N_("Input Files:") },
+  { "charmap", 'f', "FILE", 0,
+    N_("Symbolic character names defined in FILE") },
+  { "inputfile", 'i', "FILE", 0, N_("Source definitions are found in FILE") },
+  { "code-set-name", 'u', "NAME", OPTION_HIDDEN,
+    N_("Specify code set for mapping ISO 10646 elements") },
+
+  { NULL, 0, NULL, 0, N_("Output control:") },
+  { "force", 'c', NULL, 0,
+    N_("Create output even if warning messages were issued") },
+  { "posix", OPT_POSIX, NULL, 0, N_("Be strictly POSIX conform") },
+  { "quiet", OPT_QUIET, NULL, 0,
+    N_("Suppress warnings and information messages") },
+  { "verbose", 'V', NULL, 0, N_("print more messages") },
+  { NULL, 0, NULL, 0, NULL }
+};
+
+/* Short description of program.  */
+static const char doc[] = N_("Compile locale specification");
+
+/* Strings for arguments in help texts.  */
+static const char args_doc[] = N_("NAME");
+
+/* Prototype for option handler.  */
+static error_t parse_opt (int key, char *arg, struct argp_state *state);
+
+/* Function to print some extra text in the help message.  */
+static char *more_help (int key, const char *text, void *input);
+
+/* Data structure to communicate with argp functions.  */
+static struct argp argp =
 {
-  { "charmap", required_argument, NULL, 'f' },
-  { "code-set-name", required_argument, NULL, 'u' },
-  { "help", no_argument, NULL, 'h' },
-  { "force", no_argument, NULL, 'c' },
-  { "inputfile", required_argument, NULL, 'i' },
-  { "posix", no_argument, &posix_conformance, 1 },
-  { "quiet", no_argument, NULL, 'q' },
-  { "verbose", no_argument, &verbose, 1},
-  { "version", no_argument, NULL, 'V' },
-  { NULL, 0, NULL, 0 }
+  options, parse_opt, args_doc, doc, NULL, more_help
 };
 
 
@@ -94,7 +136,6 @@ static const struct option long_options[] =
 void *xmalloc (size_t __n);
 
 /* Prototypes for local functions.  */
-static void usage (int status) __attribute__ ((noreturn));
 static void error_print (void);
 static const char *construct_output_path (char *path);
 
@@ -102,13 +143,6 @@ static const char *construct_output_path (char *path);
 int
 main (int argc, char *argv[])
 {
-  int optchar;
-  int do_help = 0;
-  int do_version = 0;
-  int force_output = 0;
-  const char *charmap_file = NULL;
-  const char *input_file = NULL;
-  const char *ucs_csn = NULL;
   const char *output_path;
   int cannot_write_why;
   struct charset_t *charset;
@@ -119,7 +153,6 @@ main (int argc, char *argv[])
   copy_list = NULL;
   posix_conformance = getenv ("POSIXLY_CORRECT") != NULL;
   error_print_progname = error_print;
-  verbose = 0;
 
   /* Set locale.  Do not set LC_ALL because the other categories must
      not be affected (according to POSIX.2).  */
@@ -129,83 +162,27 @@ main (int argc, char *argv[])
   /* Initialize the message catalog.  */
   textdomain (_libc_intl_domainname);
 
-  while ((optchar = getopt_long (argc, argv, "cf:hi:u:vV", long_options, NULL))
-         != -1)
-    switch (optchar)
-      {
-      case '\0':		/* Long option.  */
-        break;
-
-      case 'c':
-	force_output = 1;
-	break;
-
-      case 'f':
-        charmap_file = optarg;
-        break;
-
-      case 'h':
-        do_help = 1;
-        break;
-
-      case 'i':
-	input_file = optarg;
-        break;
-
-      case 'q':
-	be_quiet = 1;
-	verbose = 0;
-	break;
-
-      case 'u':
-	ucs_csn = optarg;
-	break;
-
-      case 'v':
-        verbose = 1;
-	be_quiet = 0;
-        break;
-
-      case 'V':
-        do_version = 1;
-        break;
-
-      default:
-        usage (4);	/* A value >3 is forced by POSIX.  */
-        break;
-      }
+  /* Parse and process arguments.  */
+  argp_parse (&argp, argc, argv, 0, 0, NULL);
+
+  /* XXX POSIX is violated since for unknown option a exit value > 3
+     must be used.  */
 
   /* POSIX.2 requires to be verbose about missing characters in the
      character map.  */
   verbose |= posix_conformance;
 
-  /* Version information is requested.  */
-  if (do_version)
+  if (argc - optind != 1)
     {
-      printf ("localedef (GNU %s) %s\n", PACKAGE, VERSION);
-      printf (_("\
-Copyright (C) %s Free Software Foundation, Inc.\n\
-This is free software; see the source for copying conditions.  There is NO\n\
-warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
-"), "1995, 1996, 1997");
-      printf (_("Written by %s.\n"), "Ulrich Drepper");
+      /* We need exactly one non-option parameter.  */
+      argp_help (&argp, stdout, ARGP_HELP_SEE,
+		 program_invocation_short_name);
 
-      exit (0);
+      /* XXX Currently POSIX is violated.  We must exit with code 4
+	 but the argp_help function currently does not allow this.  */
+      exit (4);
     }
 
-  /* Help is requested.  */
-  if (do_help)
-    /* Possible violation: POSIX.2 4.35.8 defines the return value 0 as
-       "No errors occurred and the locale(s) were successfully created."
-       But giving a other value than 0 does not make sense here.  It
-       is perhaps not that important because POSIX does not specify the
-       -h option for localedef.  */
-    usage (0);
-
-  if (argc - optind != 1)
-    /* We need exactly one non-option parameter.  */
-    usage (4);
-
   /* The parameter describes the output path of the constructed files.
      If the described files cannot be written return a NULL pointer.  */
   output_path  = construct_output_path (argv[optind]);
@@ -353,6 +330,76 @@ cannot `stat' locale file `%s'"),
 }
 
 
+/* Handle program arguments.  */
+static error_t
+parse_opt (int key, char *arg, struct argp_state *state)
+{
+  switch (key)
+    {
+    case OPT_QUIET:
+      be_quiet = 1;
+      break;
+    case OPT_POSIX:
+      posix_conformance = 1;
+      break;
+    case 'c':
+      force_output = 1;
+      break;
+    case 'f':
+      charmap_file = arg;
+      break;
+    case 'i':
+      input_file = arg;
+      break;
+    case 'u':
+      ucs_csn = arg;
+      break;
+    case 'v':
+      verbose = 1;
+      break;
+    default:
+      return ARGP_ERR_UNKNOWN;
+    }
+  return 0;
+}
+
+
+static char *
+more_help (int key, const char *text, void *input)
+{
+  char *cp;
+
+  switch (key)
+    {
+    case ARGP_KEY_HELP_EXTRA:
+      /* We print some extra information.  */
+      asprintf (&cp, gettext ("\
+System's directory for character maps: %s\n\
+                       locale files  : %s\n\
+%s"),
+		CHARMAP_PATH, LOCALE_PATH, gettext ("\
+Report bugs using the `glibcbug' script to <bugs@gnu.ai.mit.edu>.\n"));
+      return cp;
+    default:
+      break;
+    }
+  return (char *) text;
+}
+
+/* Print the version information.  */
+static void
+print_version (FILE *stream, struct argp_state *state)
+{
+  fprintf (stream, "localedef (GNU %s) %s\n", PACKAGE, VERSION);
+  fprintf (stream, gettext ("\
+Copyright (C) %s Free Software Foundation, Inc.\n\
+This is free software; see the source for copying conditions.  There is NO\n\
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
+"), "1995, 1996, 1997");
+  fprintf (stream, gettext ("Written by %s.\n"), "Ulrich Drepper");
+}
+
+
 void
 def_to_process (const char *name, int category)
 {
@@ -390,40 +437,6 @@ category data requested more than once: should not happen"));
 }
 
 
-/* Display usage information and exit.  */
-static void
-usage (int status)
-{
-  if (status != 0)
-    fprintf (stderr, _("Try `%s --help' for more information.\n"),
-	     program_invocation_name);
-  else
-    {
-      printf (_("\
-Usage: %s [OPTION]... name\n\
-Mandatory arguments to long options are mandatory for short options too.\n\
-  -c, --force               create output even if warning messages were issued\n\
-  -h, --help                display this help and exit\n\
-  -f, --charmap=FILE        symbolic character names defined in FILE\n\
-  -i, --inputfile=FILE      source definitions are found in FILE\n\
-      --quiet               Suppress warnings and information messages\n\
-  -u, --code-set-name=NAME  specify code set for mapping ISO 10646 elements\n\
-  -v, --verbose             print more messages\n\
-  -V, --version             output version information and exit\n\
-      --posix               be strictly POSIX conform\n\
-\n\
-System's directory for character maps: %s\n\
-                       locale files  : %s\n"),
-	      program_invocation_name, CHARMAP_PATH, LOCALE_PATH);
-      fputs (gettext ("\
-Report bugs using the `glibcbug' script to <bugs@gnu.ai.mit.edu>.\n"),
-	     stdout);
-    }
-
-  exit (status);
-}
-
-
 /* The address of this function will be assigned to the hook in the error
    functions.  */
 static void
diff --git a/locale/weight.h b/locale/weight.h
index 76e6537762..96fb28e987 100644
--- a/locale/weight.h
+++ b/locale/weight.h
@@ -55,8 +55,8 @@ typedef struct weight_t
 # define collate_rules \
   ((u_int32_t *) _NL_CURRENT (LC_COLLATE, _NL_COLLATE_RULES))
 
-static __inline int get_weight (const STRING_TYPE **str, weight_t *result);
-static __inline int
+static __inline void get_weight (const STRING_TYPE **str, weight_t *result);
+static __inline void
 get_weight (const STRING_TYPE **str, weight_t *result)
 #else
 # define collate_nrules \
@@ -70,11 +70,11 @@ get_weight (const STRING_TYPE **str, weight_t *result)
 # define collate_rules \
   ((u_int32_t *) current->values[_NL_ITEM_INDEX (_NL_COLLATE_RULES)].string)
 
-static __inline int get_weight (const STRING_TYPE **str, weight_t *result,
-				struct locale_data *current,
-				const u_int32_t *__collate_table,
-				const u_int32_t *__collate_extra);
-static __inline int
+static __inline void get_weight (const STRING_TYPE **str, weight_t *result,
+				 struct locale_data *current,
+				 const u_int32_t *__collate_table,
+				 const u_int32_t *__collate_extra);
+static __inline void
 get_weight (const STRING_TYPE **str, weight_t *result,
 	    struct locale_data *current, const u_int32_t *__collate_table,
 	    const u_int32_t *__collate_extra)
@@ -107,7 +107,7 @@ get_weight (const STRING_TYPE **str, weight_t *result,
 		  result->data[cnt].value = &__collate_extra[idx];
 		  idx += result->data[cnt].number;
 		}
-	      return 0;
+	      return;
 	    }
 	  slot += level_size;
 	}
@@ -123,7 +123,7 @@ get_weight (const STRING_TYPE **str, weight_t *result,
 	  result->data[cnt].number = 1;
 	  result->data[cnt].value = &__collate_table[slot + 1 + cnt];
 	}
-      return ch == 0;
+      return;
     }
 
   /* We now look for any collation element which starts with CH.
@@ -156,14 +156,12 @@ get_weight (const STRING_TYPE **str, weight_t *result,
 	      result->data[cnt].value = &__collate_extra[idx];
 	      idx += result->data[cnt].number;
 	    }
-	  return 0;
+	  return;
 	}
 
       /* To next entry in list.  */
       slot += __collate_extra[slot];
     }
-  /* NOTREACHED */
-  return 0;	/* To calm down gcc.  */
 }
 
 
@@ -174,7 +172,7 @@ get_weight (const STRING_TYPE **str, weight_t *result,
    order.
 
    We have this strange extra macro since the functions which use the
-   given locale (not the global one) canot use the global tables.  */
+   given locale (not the global one) cannot use the global tables.  */
 #ifndef USE_IN_EXTENDED_LOCALE_MODEL
 # define call_get_weight(strp, newp) get_weight ((strp), (newp))
 #else
@@ -182,11 +180,11 @@ get_weight (const STRING_TYPE **str, weight_t *result,
   get_weight ((strp), (newp), current, collate_table, collate_extra)
 #endif
 
-#define get_string(str, forw, backw)					      \
+#define get_string(str, forw, backw) \
   do									      \
     {									      \
       weight_t *newp;							      \
-      do								      \
+      while (*str != '\0')						      \
 	{								      \
 	  newp = (weight_t *) alloca (sizeof (weight_t)			      \
 				      + (collate_nrules			      \
@@ -199,7 +197,7 @@ get_weight (const STRING_TYPE **str, weight_t *result,
 	    backw->next = newp;						      \
 	  newp->next = NULL;						      \
 	  backw = newp;							      \
+	  call_get_weight (&str, newp);					      \
 	}								      \
-      while (call_get_weight (&str, newp) == 0);			      \
     }									      \
   while (0)
diff --git a/malloc/obstack.h b/malloc/obstack.h
index b67f0545f1..ea45664c02 100644
--- a/malloc/obstack.h
+++ b/malloc/obstack.h
@@ -107,7 +107,7 @@ Summary:
 #ifndef __OBSTACK_H__
 #define __OBSTACK_H__
 
-#ifdef __cpluscplus
+#ifdef __cplusplus
 extern "C" {
 #endif
 
diff --git a/nss/XXX-lookup.c b/nss/XXX-lookup.c
index cfb89a2702..900bc307b9 100644
--- a/nss/XXX-lookup.c
+++ b/nss/XXX-lookup.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1996 Free Software Foundation, Inc.
+/* Copyright (C) 1996, 1997 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
 
@@ -27,6 +27,9 @@
 |* 								   *|
 |* One additional symbol may optionally be defined:		   *|
 |* 								   *|
+|* ALTERNATE_NAME - name of another service which is examined in   *|
+|*                  case DATABASE_NAME is not found                *|
+|* 								   *|
 |* DEFAULT_CONFIG - string for default conf (e.g. "dns files")	   *|
 |* 								   *|
 \*******************************************************************/
diff --git a/nss/nsswitch.c b/nss/nsswitch.c
index 77fc4f0916..9c7a2d7909 100644
--- a/nss/nsswitch.c
+++ b/nss/nsswitch.c
@@ -201,7 +201,7 @@ __nss_configure_lookup (const char *dbname, const char *service_line)
       int cmp = strcmp (dbname, databases[cnt].name);
       if (cmp == 0)
 	break;
-      if (cmp > 0)
+      if (cmp < 0)
 	{
 	  __set_errno (EINVAL);
 	  return -1;
diff --git a/shadow/sgetspent_r.c b/shadow/sgetspent_r.c
index 8678ac816a..fb7d0158d9 100644
--- a/shadow/sgetspent_r.c
+++ b/shadow/sgetspent_r.c
@@ -56,7 +56,7 @@ LINE_PARSER
      INT_FIELD_MAYBE_NULL (result->sp_min, ISCOLON, 0, 10, (long int),
 			   (long int) -1);
      INT_FIELD_MAYBE_NULL (result->sp_max, ISCOLON, 0, 10, (long int),
-			   (long int -1);
+			   (long int) -1);
      while (isspace (*line))
        ++line;
      if (*line == '\0')
diff --git a/stdio-common/test-fseek.c b/stdio-common/test-fseek.c
index d56c669a54..e736ed7cdc 100644
--- a/stdio-common/test-fseek.c
+++ b/stdio-common/test-fseek.c
@@ -1,10 +1,27 @@
-#include <ansidecl.h>
+/* Copyright (C) 1991, 1992, 1996, 1997 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
 #include <stdio.h>
 
 #define TESTFILE "/tmp/test.dat"
 
 int
-main __P((void))
+main (void)
 {
   FILE *fp;
   int i, j;
@@ -61,6 +78,7 @@ main __P((void))
 	}
     }
   fclose (fp);
+  remove (TESTFILE);
 
   puts ((i > 255) ? "Test succeeded." : "Test FAILED!");
   return (i > 255) ? 0 : 1;
diff --git a/string/strcoll.c b/string/strcoll.c
index e58b74cf51..6b18567e8a 100644
--- a/string/strcoll.c
+++ b/string/strcoll.c
@@ -96,16 +96,18 @@ STRCOLL (s1, s2, l)
       int s1idx = forward ? 0 : s1run->data[pass].number - 1;
       int s2idx = forward ? 0 : s2run->data[pass].number - 1;
 
-      do
+      while (1)
 	{
 	  int s1ignore = 0;
 	  int s2ignore = 0;
-	  u_int32_t w1, w2;
+	  u_int32_t w1 = 0;
+	  u_int32_t w2 = 0;
 
 	  /* Here we have to check for IGNORE entries.  If these are
 	     found we count them and go on with the next value.  */
-	  while ((w1 = s1run->data[pass].value[s1idx])
-		 == (u_int32_t) IGNORE_CHAR)
+	  while (s1run != NULL
+		 && ((w1 = s1run->data[pass].value[s1idx])
+		     == (u_int32_t) IGNORE_CHAR))
 	    {
 	      ++s1ignore;
 	      if ((forward && ++s1idx >= s1run->data[pass].number)
@@ -115,15 +117,19 @@ STRCOLL (s1, s2, l)
 		  if (nextp == NULL)
 		    {
 		      w1 = 0;
-		      break;
+		      /* No more non-INGOREd elements means lowest
+			 possible value.  */
+		      s1ignore = -1;
 		    }
+		  else
+		    s1idx = forward ? 0 : nextp->data[pass].number - 1;
 		  s1run = nextp;
-		  s1idx = forward ? 0 : s1run->data[pass].number - 1;
 		}
 	    }
 
-	  while ((w2 = s2run->data[pass].value[s2idx])
-		 == (u_int32_t) IGNORE_CHAR)
+	  while (s2run != NULL
+		 && ((w2 = s2run->data[pass].value[s2idx])
+		     == (u_int32_t) IGNORE_CHAR))
 	    {
 	      ++s2ignore;
 	      if ((forward && ++s2idx >= s2run->data[pass].number)
@@ -133,13 +139,20 @@ STRCOLL (s1, s2, l)
 		  if (nextp == NULL)
 		    {
 		      w2 = 0;
-		      break;
+		      /* No more non-INGOREd elements means lowest
+			 possible value.  */
+		      s2ignore = -1;
 		    }
+		  else
+		    s2idx = forward ? 0 : nextp->data[pass].number - 1;
 		  s2run = nextp;
-		  s2idx = forward ? 0 : s2run->data[pass].number - 1;
 		}
 	    }
 
+	  /* If one string is completely processed stop.  */
+	  if (s1run == NULL || s2run == NULL)
+	    break;
+
 	  /* Now we have information of the number of ignored
 	     weights and the value of the next weight.  */
 	  if ((collate_rules[pass] & sort_position) != 0
@@ -179,7 +192,6 @@ STRCOLL (s1, s2, l)
 	      }
 
 	}
-      while (s1run != NULL && s2run != NULL);
 
       if (s1run != s2run)
 	return s1run != NULL ? 1 : -1;
diff --git a/string/strxfrm.c b/string/strxfrm.c
index e22738667c..8222adf435 100644
--- a/string/strxfrm.c
+++ b/string/strxfrm.c
@@ -197,14 +197,16 @@ STRXFRM (STRING_TYPE *dest, const STRING_TYPE *src, size_t n, __locale_t l)
       const weight_t *run = forward ? forw : backw;
       int idx = forward ? 0 : run->data[pass].number - 1;
 
-      do
+      while (1)
 	{
 	  int ignore = 0;
-	  u_int32_t w;
+	  u_int32_t w = 0;
 
 	  /* Here we have to check for IGNORE entries.  If these are
 	     found we count them and go on with he next value.  */
-	  while ((w = run->data[pass].value[idx]) == (u_int32_t) IGNORE_CHAR)
+	  while (run != NULL
+		 && ((w = run->data[pass].value[idx])
+		     == (u_int32_t) IGNORE_CHAR))
 	    {
 	      ++ignore;
 	      if ((forward && ++idx >= run->data[pass].number)
@@ -214,13 +216,20 @@ STRXFRM (STRING_TYPE *dest, const STRING_TYPE *src, size_t n, __locale_t l)
 		  if (nextp == NULL)
 		    {
 		      w = 0;
-		      break;
+		      /* No more non-INGOREd elements means lowest
+			 possible value.  */
+		      ignore = -1;
 		    }
+		  else
+		    idx = forward ? 0 : nextp->data[pass].number - 1;
 		  run = nextp;
-		  idx = forward ? 0 : run->data[pass].number - 1;
 		}
 	    }
 
+	  /* Stop if all characters are processed.  */
+	  if (run == NULL)
+	    break;
+
 	  /* Now we have information of the number of ignored weights
 	     and the value of the next weight.  We have to add 2
 	     because 0 means EOS and 1 is the intermediate string end.  */
@@ -245,7 +254,6 @@ STRXFRM (STRING_TYPE *dest, const STRING_TYPE *src, size_t n, __locale_t l)
 		  idx = run->data[pass].number - 1;
 	      }
 	}
-      while (run != NULL);
 
       /* Write marker for end of word.  */
       if (pass + 1 < collate_nrules)
diff --git a/sysdeps/generic/netinet/in.h b/sysdeps/generic/netinet/in.h
index bc8af8809e..ad77c8be7d 100644
--- a/sysdeps/generic/netinet/in.h
+++ b/sysdeps/generic/netinet/in.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 92, 93, 94, 95, 96 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 92, 93, 94, 95, 96, 97 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or modify
@@ -23,6 +23,7 @@
 
 #include <sys/socket.h>
 
+__BEGIN_DECLS
 
 /* Standard well-defined IP protocols.  */
 enum
@@ -207,4 +208,6 @@ extern unsigned short int htons __P ((unsigned short int));
 #define	htons(x)	(x)
 #endif
 
+__END_DECLS
+
 #endif	/* netinet/in.h */
diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
index 042e0a5ef8..4d32ee02ac 100644
--- a/sysdeps/posix/getaddrinfo.c
+++ b/sysdeps/posix/getaddrinfo.c
@@ -64,6 +64,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <netinet/in.h>
 #include <netdb.h>
 #include <errno.h>
+#include <arpa/inet.h>
 
 #ifndef AF_LOCAL
 #define AF_LOCAL AF_UNIX
@@ -202,7 +203,7 @@ static int gaih_inet(const char *name, const struct gaih_service *service,
 
   if (req->ai_protocol || req->ai_socktype) {
     for (tp++; tp->name &&
-	  ((req->ai_socktype != tp->socktype) || !req->ai_socktype) && 
+	  ((req->ai_socktype != tp->socktype) || !req->ai_socktype) &&
 	  ((req->ai_protocol != tp->protocol) || !req->ai_protocol); tp++);
     if (!tp->name)
       if (req->ai_socktype)
@@ -414,7 +415,7 @@ static int gaih_inet(const char *name, const struct gaih_service *service,
 
   if (!pai) {
     i = 0;
-    goto ret; 
+    goto ret;
   };
 
   {
@@ -438,9 +439,9 @@ static int gaih_inet(const char *name, const struct gaih_service *service,
 	char *tmpbuf = __alloca(tmpbuflen);
 	while (__gethostbyaddr_r(at2->addr,
 #if INET6
-	    (at2->family == AF_INET6) ? sizeof(struct in6_addr) : 
+	    (at2->family == AF_INET6) ? sizeof(struct in6_addr) :
 #endif /* INET6 */
-				 sizeof(struct in_addr), at2->family, 
+				 sizeof(struct in_addr), at2->family,
 				 &th, tmpbuf, tmpbuflen, &h, &herrno)) {
 	  if (herrno == NETDB_INTERNAL) {
 	    if (errno == ERANGE) {
@@ -454,7 +455,7 @@ static int gaih_inet(const char *name, const struct gaih_service *service,
 	      goto ret;
 	    }
 	  } else {
-	    break; 
+	    break;
 	  }
 	}
 #endif /* RESOLVER */
@@ -462,7 +463,7 @@ static int gaih_inet(const char *name, const struct gaih_service *service,
 	if (!h)
 	  h = _addr2hostname_hosts(at2->addr,
 #if INET6
-	    (at2->family == AF_INET6) ? sizeof(struct in6_addr) : 
+	    (at2->family == AF_INET6) ? sizeof(struct in6_addr) :
 #endif /* INET6 */
 	    sizeof(struct in_addr), at2->family);
 #endif /* HOSTTABLE */
@@ -516,7 +517,7 @@ static int gaih_inet(const char *name, const struct gaih_service *service,
 	  memcpy(&((struct sockaddr_in *)(*pai)->ai_addr)->sin_addr, at2->addr, sizeof(struct in_addr));
 	  memset(((struct sockaddr_in *)(*pai)->ai_addr)->sin_zero, 0, sizeof(((struct sockaddr_in *)(*pai)->ai_addr)->sin_zero));
 	}
-	
+
 	if (c) {
 	  (*pai)->ai_canonname = (void *)(*pai) + sizeof(struct addrinfo) + i;
 	  strcpy((*pai)->ai_canonname, c);
diff --git a/sysdeps/unix/mman/syscalls.list b/sysdeps/unix/mman/syscalls.list
index dc63d89d7d..1d3173eafd 100644
--- a/sysdeps/unix/mman/syscalls.list
+++ b/sysdeps/unix/mman/syscalls.list
@@ -1,3 +1,7 @@
+# This interface desciption corresponds to the POSIX.1 description.  The
+# 4.4BSD interface is slightly different since the `msync' function takes
+# only 2 arguments.
+
 # File name	Caller	Syscall name	# args	Strong name	Weak names
 
 madvise		-	madvise		3	madvise
diff --git a/sysdeps/unix/sysv/linux/Dist b/sysdeps/unix/sysv/linux/Dist
index 0c5903dc89..9c41e50b4c 100644
--- a/sysdeps/unix/sysv/linux/Dist
+++ b/sysdeps/unix/sysv/linux/Dist
@@ -5,6 +5,7 @@ llseek.c
 siglist.h
 sysctl.c
 termio.h
+net/ethernet.h
 net/if.h
 net/if_arp.h
 net/if_ppp.h
diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
index ad77f8872c..888ab9bd85 100644
--- a/sysdeps/unix/sysv/linux/Makefile
+++ b/sysdeps/unix/sysv/linux/Makefile
@@ -35,7 +35,7 @@ endif
 
 ifeq ($(subdir),socket)
 sysdep_headers += sys/socketcall.h net/if.h net/if_ppp.h net/ppp-comp.h \
-		  net/ppp_defs.h net/if_arp.h net/route.h
+		  net/ppp_defs.h net/if_arp.h net/route.h net/ethernet.h
 sysdep_routines += cmsg_nxthdr
 endif
 
diff --git a/inet/net/ethernet.h b/sysdeps/unix/sysv/linux/net/ethernet.h
index 89a92c53f1..89a92c53f1 100644
--- a/inet/net/ethernet.h
+++ b/sysdeps/unix/sysv/linux/net/ethernet.h