about summary refs log tree commit diff
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>1996-10-02 01:40:17 +0000
committerUlrich Drepper <drepper@redhat.com>1996-10-02 01:40:17 +0000
commita68b0d31a37a86785b3dbeeee3fad96ee71fadcd (patch)
tree61537b1f028002a9e6e0f5354fced6128bda8b9c
parent2d07133b507b13d4a5ed6dc250f4345c8a26942a (diff)
downloadglibc-a68b0d31a37a86785b3dbeeee3fad96ee71fadcd.tar.gz
glibc-a68b0d31a37a86785b3dbeeee3fad96ee71fadcd.tar.xz
glibc-a68b0d31a37a86785b3dbeeee3fad96ee71fadcd.zip
update from main archive 961001
-rw-r--r--Makefile2
-rw-r--r--PROJECTS7
-rw-r--r--catgets/gencat.c11
-rw-r--r--csu/initfini.c12
-rw-r--r--db/makedb.c7
-rw-r--r--elf/eval.c20
-rw-r--r--gmon/gmon.c48
-rw-r--r--gmon/mcount.c1
-rw-r--r--gmon/sys/gmon_out.h18
-rw-r--r--inet/Makefile5
-rw-r--r--inet/getnetgrent.c28
-rw-r--r--inet/getnetgrent_r.c218
-rw-r--r--inet/netgroup.h30
-rw-r--r--inet/rcmd.c2
-rw-r--r--libio/clearerr_u.c4
-rw-r--r--libio/fgetc.c2
-rw-r--r--libio/fputc.c2
-rw-r--r--libio/fputc_u.c4
-rw-r--r--libio/freopen.c2
-rw-r--r--libio/fseek.c2
-rw-r--r--libio/genops.c4
-rw-r--r--libio/getc.c2
-rw-r--r--libio/getc_u.c4
-rw-r--r--libio/getchar.c3
-rw-r--r--libio/getchar_u.c4
-rw-r--r--libio/iofclose.c4
-rw-r--r--libio/iofflush.c4
-rw-r--r--libio/iofflush_u.c6
-rw-r--r--libio/iofgetpos.c2
-rw-r--r--libio/iofgets.c5
-rw-r--r--libio/iofputs.c2
-rw-r--r--libio/iofread.c2
-rw-r--r--libio/iofsetpos.c2
-rw-r--r--libio/ioftell.c2
-rw-r--r--libio/iofwrite.c2
-rw-r--r--libio/iogetdelim.c2
-rw-r--r--libio/iogetline.c4
-rw-r--r--libio/iogets.c3
-rw-r--r--libio/ioputs.c3
-rw-r--r--libio/iosetbuffer.c2
-rw-r--r--libio/iosetvbuf.c2
-rw-r--r--libio/ioungetc.c2
-rw-r--r--libio/putc.c2
-rw-r--r--libio/putchar.c3
-rw-r--r--libio/rewind.c4
-rw-r--r--libio/strops.c12
-rw-r--r--locale/programs/ld-collate.c2
-rw-r--r--locale/programs/ld-ctype.c1
-rw-r--r--locale/programs/ld-time.c17
-rw-r--r--locale/programs/locale.c7
-rw-r--r--locale/programs/localedef.c7
-rw-r--r--login/login_tty.c1
-rw-r--r--manual/filesys.texi30
-rw-r--r--misc/Makefile5
-rw-r--r--netgroup.h1
-rw-r--r--nss/Makefile2
-rw-r--r--nss/databases.def1
-rw-r--r--nss/db-Makefile10
-rw-r--r--nss/getXXent_r.c6
-rw-r--r--nss/netgrp-lookup.c (renamed from dirent/readdir_r.c)21
-rw-r--r--nss/nss.h1
-rw-r--r--nss/nss_db/db-XXX.c10
-rw-r--r--nss/nss_db/db-netgrp.c108
-rw-r--r--nss/nss_dns/dns-network.c7
-rw-r--r--nss/nss_files/files-netgrp.c262
-rw-r--r--nss/nsswitch.c3
-rw-r--r--nss/nsswitch.conf2
-rw-r--r--nss/nsswitch.h2
-rw-r--r--nsswitch.h1
-rw-r--r--posix/sys/types.h48
-rw-r--r--posix/unistd.h3
-rw-r--r--pwd/getpw.c6
-rw-r--r--resolv/base64.c4
-rw-r--r--resolv/gethnamaddr.c48
-rw-r--r--resolv/getnetnamadr.c8
-rw-r--r--resolv/inet_neta.c1
-rw-r--r--resolv/netdb.h31
-rw-r--r--resolv/res_debug.c2
-rw-r--r--resolv/res_mkquery.c2
-rw-r--r--resolv/res_query.c28
-rw-r--r--stdio-common/getline.c1
-rw-r--r--stdio-common/reg-printf.c3
-rw-r--r--stdio-common/scanf.c1
-rw-r--r--stdio-common/tmpnam.c2
-rw-r--r--stdio-common/tstgetln.c6
-rw-r--r--stdio-common/vfprintf.c1
-rw-r--r--stdio-common/vfscanf.c1
-rw-r--r--string/tester.c6
-rw-r--r--sysdeps/alpha/machine-gmon.h5
-rw-r--r--sysdeps/generic/gnu/types.h1
-rw-r--r--sysdeps/generic/machine-gmon.h2
-rw-r--r--sysdeps/generic/pty.c2
-rw-r--r--sysdeps/generic/strtok.c2
-rw-r--r--sysdeps/generic/strtok_r.c2
-rw-r--r--sysdeps/gnu/errlist.awk2
-rw-r--r--sysdeps/gnu/errlist.c2
-rw-r--r--sysdeps/posix/euidaccess.c2
-rw-r--r--sysdeps/posix/sigvec.c3
-rw-r--r--sysdeps/posix/tempname.c19
-rw-r--r--sysdeps/stub/chflags.c3
-rw-r--r--sysdeps/stub/fchflags.c3
-rw-r--r--sysdeps/stub/sstk.c3
-rw-r--r--sysdeps/unix/Makefile3
-rw-r--r--sysdeps/unix/alpha/sysdep.S7
-rw-r--r--sysdeps/unix/readdir.c6
-rw-r--r--sysdeps/unix/readdir_r.c108
-rw-r--r--sysdeps/unix/sysv/linux/gnu/types.h2
-rw-r--r--sysdeps/unix/sysv/linux/init-first.c4
-rw-r--r--sysdeps/unix/sysv/linux/syscalls.list2
109 files changed, 1137 insertions, 267 deletions
diff --git a/Makefile b/Makefile
index 87a66eea81..c9513a2684 100644
--- a/Makefile
+++ b/Makefile
@@ -125,7 +125,7 @@ $(objpfx)sysd-dirs: $(+sysdir_pfx)config.make $(all-Subdirs-files)
 all-Banner-files = $(wildcard $(addsuffix /Banner, $(subdirs)))
 $(objpfx)version-info.h: $(+sysdir_pfx)config.make $(all-Banner-files)
 	(files="$(all-Banner-files)";				\
-	 if [ test -n "$$files" ]; then				\
+	 if test -n "$$files"; then				\
 	   echo "\"Available extensions:";			\
 	   sed -e '/^#/d' -e 's/^[[:space:]]*/	/' $$files;	\
 	   echo "\"";						\
diff --git a/PROJECTS b/PROJECTS
index bf29541a03..60ab664307 100644
--- a/PROJECTS
+++ b/PROJECTS
@@ -37,7 +37,8 @@ contact <bug-glibc@prep.ai.mit.edu>
 
      The libm is in fact fdlibm (not the same as in Linux libc).
 
-**** Partly done.
+**** Partly done.  But we need someone with numerical experiences for
+     the rest.
 
 
 [ 6] If you enjoy assembler programming (as I do --drepper :-) you might
@@ -81,7 +82,7 @@ contact <bug-glibc@prep.ai.mit.edu>
      Please contact bug-glibc@prep.ai.mit.edu before starting to avoid
      duplicated work.
 
-[11] Write access function for netmasks, bootparams, netgroup, publickey,
-     automount, aliases databases for nss_files and nss_db module.
+[11] Write access function for netmasks, bootparams, publickey, automount,
+     and aliases databases for nss_files and nss_db module.
      The functions should be embedded in the nss scheme.  This is not
      hard and not all services must be supported at once.
diff --git a/catgets/gencat.c b/catgets/gencat.c
index 7fe159e5b9..9e7404295e 100644
--- a/catgets/gencat.c
+++ b/catgets/gencat.c
@@ -165,14 +165,13 @@ main (int argc, char *argv[])
   /* Version information is requested.  */
   if (do_version)
     {
-      fprintf (stderr, "gencat (GNU %s) %s\n", PACKAGE, VERSION);
-      fprintf (stderr, _("\
+      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");
-      fprintf (stderr, _("Written by %s.\n"),
-	       "Ulrich Drepper");
+      printf (_("Written by %s.\n"), "Ulrich Drepper");
 
       exit (EXIT_SUCCESS);
     }
@@ -210,7 +209,7 @@ usage (int status)
              program_invocation_name);
   else
     {
-      printf(gettext ("\
+      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\
@@ -221,7 +220,7 @@ Mandatory arguments to long options are mandatory for short options too.\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);
+	      program_invocation_name, program_invocation_name);
       fputs (gettext ("Report bugs to <bug-glibc@prep.ai.mit.edu>.\n"),
 	     stdout);
     }
diff --git a/csu/initfini.c b/csu/initfini.c
index cb2ba5308e..f816e08169 100644
--- a/csu/initfini.c
+++ b/csu/initfini.c
@@ -94,18 +94,6 @@ _init (void)
   if (__gmon_start__)
     __gmon_start__ ();
 
-#ifdef _LIBC_REENTRANT
-  {
-    /* This is a trick to generate a reference for the symbol
-       __libc_force_cancel_wrapper which can be used to force parts of
-       the thread library to be used where some functions and system
-       calls are overwritten.  The value of this variable is always 0.  */
-    extern const int __libc_force_cancel_wrapper;
-    if (__libc_force_cancel_wrapper)
-      _init ();
-  }
-#endif
-
   /* End the here document containing the .init prologue code.
      Then fetch the .section directive just written and append that
      to crtn.s-new, followed by the function epilogue.  */
diff --git a/db/makedb.c b/db/makedb.c
index 5c0d659f1a..d30ca2cef1 100644
--- a/db/makedb.c
+++ b/db/makedb.c
@@ -115,14 +115,13 @@ main (argc, argv)
   /* Version information is requested.  */
   if (do_version)
     {
-      fprintf (stderr, "makedb (GNU %s) %s\n", PACKAGE, VERSION);
-      fprintf (stderr, _("\
+      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");
-      fprintf (stderr, _("Written by %s.\n"),
-	       "Ulrich Drepper");
+      printf (_("Written by %s.\n"), "Ulrich Drepper");
 
       exit (EXIT_SUCCESS);
     }
diff --git a/elf/eval.c b/elf/eval.c
index 59eb234166..03b903b76f 100644
--- a/elf/eval.c
+++ b/elf/eval.c
@@ -1,6 +1,26 @@
+/* You don't really want to know what this hack is for.
+Copyright (C) 1996 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>
 #include <ctype.h>
 #include <stdlib.h>
+#include <string.h>
 #include <unistd.h>
 #include <dlfcn.h>
 
diff --git a/gmon/gmon.c b/gmon/gmon.c
index ecf7518bfb..00b5df5332 100644
--- a/gmon/gmon.c
+++ b/gmon/gmon.c
@@ -35,7 +35,6 @@
 #include <sys/gmon.h>
 #include <sys/gmon_out.h>
 
-#include <ansidecl.h>
 #include <stdio.h>
 #include <fcntl.h>
 #include <unistd.h>
@@ -45,7 +44,7 @@
 #include <string.h>
 #include <unistd.h>
 
-extern int __profile_frequency (void);
+extern int __profile_frequency __P ((void));
 
 struct __bb *__bb_head;	/*  Head of basic-block list or NULL. */
 
@@ -65,7 +64,8 @@ static int	s_scale;
  *	all the data structures are ready.
  */
 void
-DEFUN(moncontrol, (mode), int mode)
+moncontrol (mode)
+     int mode;
 {
   struct gmonparam *p = &_gmonparam;
 
@@ -85,7 +85,9 @@ DEFUN(moncontrol, (mode), int mode)
 
 
 void
-DEFUN(monstartup, (lowpc, highpc), u_long lowpc AND u_long highpc)
+monstartup (lowpc, highpc)
+     u_long lowpc;
+     u_long highpc;
 {
   register int o;
   char *cp;
@@ -155,21 +157,19 @@ DEFUN(monstartup, (lowpc, highpc), u_long lowpc AND u_long highpc)
 
 
 static void
-DEFUN(write_hist, (fd), int fd)
+write_hist (fd)
+     int fd;
 {
   const u_char tag = GMON_TAG_TIME_HIST;
   struct gmon_hist_hdr thdr;
-  int size, rate;
 
   if (_gmonparam.kcountsize > 0)
     {
-      size = _gmonparam.kcountsize / sizeof(HISTCOUNTER);
-      rate = __profile_frequency();
-      bcopy(&_gmonparam.lowpc, &thdr.low_pc, sizeof(thdr.low_pc));
-      bcopy(&_gmonparam.highpc, &thdr.high_pc, sizeof(thdr.high_pc));
-      bcopy(&size, &thdr.hist_size, sizeof(thdr.hist_size));
-      bcopy(&rate, &thdr.prof_rate, sizeof(thdr.prof_rate));
-      strcpy(thdr.dimen, "seconds");
+      thdr.low_pc = _gmonparam.lowpc;
+      thdr.high_pc = _gmonparam.highpc;
+      thdr.hist_size = _gmonparam.kcountsize / sizeof(HISTCOUNTER);
+      thdr.prof_rate = __profile_frequency();
+      strncpy(thdr.dimen, "seconds", sizeof(thdr.dimen));
       thdr.dimen_abbrev = 's';
 
       write(fd, &tag, sizeof(tag));
@@ -180,7 +180,8 @@ DEFUN(write_hist, (fd), int fd)
 
 
 static void
-DEFUN(write_call_graph, (fd), int fd)
+write_call_graph (fd)
+     int fd;
 {
   const u_char tag = GMON_TAG_CG_ARC;
   struct gmon_cg_arc_record raw_arc;
@@ -200,11 +201,9 @@ DEFUN(write_call_graph, (fd), int fd)
 	   to_index != 0;
 	   to_index = _gmonparam.tos[to_index].link)
 	{
-	  bcopy(&frompc, &raw_arc.from_pc, sizeof(raw_arc.from_pc));
-	  bcopy(&_gmonparam.tos[to_index].selfpc, &raw_arc.self_pc,
-		sizeof(raw_arc.self_pc));
-	  bcopy(&_gmonparam.tos[to_index].count, &raw_arc.count,
-		sizeof(raw_arc.count));
+	  raw_arc.from_pc = frompc;
+	  raw_arc.self_pc = _gmonparam.tos[to_index].selfpc;
+	  raw_arc.count = _gmonparam.tos[to_index].count;
 
 	  write(fd, &tag, sizeof(tag));
 	  write(fd, &raw_arc, sizeof(raw_arc));
@@ -214,7 +213,8 @@ DEFUN(write_call_graph, (fd), int fd)
 
 
 static void
-DEFUN(write_bb_counts, (fd), int fd)
+write_bb_counts (fd)
+     int fd;
 {
   struct __bb *grp;
   const u_char tag = GMON_TAG_BB_COUNT;
@@ -239,9 +239,8 @@ DEFUN(write_bb_counts, (fd), int fd)
 
 
 void
-DEFUN_VOID(_mcleanup)
+_mcleanup ()
 {
-    const int version = GMON_VERSION;
     struct gmon_hdr ghdr;
     int fd;
 
@@ -254,8 +253,9 @@ DEFUN_VOID(_mcleanup)
       }
 
     /* write gmon.out header: */
-    bcopy(GMON_MAGIC, &ghdr.cookie[0], 4);
-    bcopy(&version, &ghdr.version, sizeof(version));
+    memset(&ghdr, 0, sizeof(ghdr));
+    memcpy(&ghdr.cookie[0], GMON_MAGIC, sizeof(ghdr.cookie));
+    ghdr.version = GMON_VERSION;
     write(fd, &ghdr, sizeof(ghdr));
 
     /* write PC histogram: */
diff --git a/gmon/mcount.c b/gmon/mcount.c
index 00c9ff8e31..66da3d054b 100644
--- a/gmon/mcount.c
+++ b/gmon/mcount.c
@@ -58,7 +58,6 @@ static char sccsid[] = "@(#)mcount.c	8.1 (Berkeley) 6/4/93";
  * perform this optimization.
  */
 _MCOUNT_DECL(frompc, selfpc)	/* _mcount; may be static, inline, etc */
-	register u_long frompc, selfpc;
 {
 	register u_short *frompcindex;
 	register struct tostruct *top, *prevtop;
diff --git a/gmon/sys/gmon_out.h b/gmon/sys/gmon_out.h
index 4224936b58..ef5b191f3d 100644
--- a/gmon/sys/gmon_out.h
+++ b/gmon/sys/gmon_out.h
@@ -39,8 +39,8 @@ identifying the type of records, followed by records specific data. */
  */
 struct gmon_hdr {
   char cookie[4];
-  char version[4];
-  char spare[3 * 4];
+  int version;
+  int spare[3];
 };
 
 /* types of records in this file: */
@@ -49,18 +49,18 @@ typedef enum {
 } GMON_Record_Tag;
 
 struct gmon_hist_hdr {
-  char low_pc[sizeof (char *)];	/* base pc address of sample buffer */
-  char high_pc[sizeof (char *)];	/* max pc address of sampled buffer */
-  char hist_size[4];			/* size of sample buffer */
-  char prof_rate[4];			/* profiling clock rate */
+  unsigned long low_pc;			/* base pc address of sample buffer */
+  unsigned long high_pc;		/* max pc address of sampled buffer */
+  int hist_size;			/* size of sample buffer */
+  int prof_rate;			/* profiling clock rate */
   char dimen[15];			/* phys. dim., usually "seconds" */
   char dimen_abbrev;			/* usually 's' for "seconds" */
 };
 
 struct gmon_cg_arc_record {
-  char from_pc[sizeof (char *)];	/* address within caller's body */
-  char self_pc[sizeof (char *)];	/* address within callee's body */
-  char count[4];			/* number of arc traversals */
+  unsigned long from_pc;		/* address within caller's body */
+  unsigned long self_pc;		/* address within callee's body */
+  int count;				/* number of arc traversals */
 };
 
 #endif /* !_SYS_GMON_OUT_H_ */
diff --git a/inet/Makefile b/inet/Makefile
index fbac0dc4c8..c09db180f5 100644
--- a/inet/Makefile
+++ b/inet/Makefile
@@ -24,6 +24,8 @@ subdir	:= inet
 headers	:= netinet/ether.h netinet/in.h netinet/if_ether.h \
 	   netinet/tcp.h $(wildcard arpa/*.h protocols/*.h)
 
+distribute := netgroup.h
+
 routines := ntohl ntohs htonl htons		\
 	    inet_lnaof inet_mkadr	\
 	    inet_netof inet_ntoa inet_net herrno \
@@ -38,7 +40,8 @@ routines := ntohl ntohs htonl htons		\
 	    getrpcent_r getrpcbyname_r getrpcbynumber_r \
 	    ether_aton ether_aton_r ether_hton ether_line \
 	    ether_ntoa ether_ntoa_r ether_ntoh \
-	    rcmd rexec ruserpass
+	    rcmd rexec ruserpass \
+	    getnetgrent_r getnetgrent
 
 # No warnings about losing BSD code.
 override +gccwarn := -w
diff --git a/inet/getnetgrent.c b/inet/getnetgrent.c
new file mode 100644
index 0000000000..3510f015d3
--- /dev/null
+++ b/inet/getnetgrent.c
@@ -0,0 +1,28 @@
+/* Copyright (C) 1996 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 <netdb.h>
+
+
+int
+getnetgrent (char **hostp, char **userp, char **domainp)
+{
+  static char buffer[1024];	/* All three strings shouldn't use 1kB.  */
+
+  return __getnetgrent_r (hostp, userp, domainp, buffer, sizeof (buffer));
+}
diff --git a/inet/getnetgrent_r.c b/inet/getnetgrent_r.c
new file mode 100644
index 0000000000..52a90d055c
--- /dev/null
+++ b/inet/getnetgrent_r.c
@@ -0,0 +1,218 @@
+/* Copyright (C) 1996 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 <libc-lock.h>
+#include <netdb.h>
+#include "netgroup.h"
+#include "nsswitch.h"
+
+
+/* Protect above variable against multiple uses at the same time.  */
+__libc_lock_define_initialized (static, lock)
+
+/* This handle for the NSS data base is shared between all
+   set/get/endXXXent functions.  */
+static service_user *nip;
+/* Remember the first service_entry, it's always the same.  */
+static service_user *startp;
+
+
+/* The lookup function for the first entry of this service.  */
+extern int __nss_netgroup_lookup (service_user **nip, const char *name,
+				  void **fctp);
+
+/* Set up NIP to run through the services.  If ALL is zero, use NIP's
+   current location if it's not nil.  Return nonzero if there are no
+   services (left).  */
+static enum nss_status
+setup (void **fctp, const char *func_name, int all)
+{
+  int no_more;
+  if (startp == NULL)
+    {
+      no_more = __nss_netgroup_lookup (&nip, func_name, fctp);
+      startp = no_more ? (service_user *) -1 : nip;
+    }
+  else if (startp == (service_user *) -1)
+    /* No services at all.  */
+    return 1;
+  else
+    {
+      if (all || !nip)
+	/* Reset to the beginning of the service list.  */
+	nip = startp;
+      /* Look up the first function.  */
+      no_more = __nss_lookup (&nip, func_name, fctp);
+    }
+  return no_more;
+}
+
+int
+setnetgrent (const char *group)
+{
+  enum nss_status (*fct) (const char *);
+  enum nss_status status = NSS_STATUS_UNAVAIL;
+  int no_more;
+
+  __libc_lock_lock (lock);
+
+  /* Cycle through all the services and run their setnetgrent functions.  */
+  no_more = setup ((void **) &fct, "setnetgrent", 1);
+  while (! no_more)
+    {
+      /* Ignore status, we force check in __NSS_NEXT.  */
+      status = (*fct) (group);
+
+      no_more = __nss_next (&nip, "setnetgrent", (void **) &fct, status, 0);
+    }
+
+  __libc_lock_unlock (lock);
+
+  return status == NSS_STATUS_SUCCESS;
+}
+
+
+void
+endnetgrent (void)
+{
+  service_user *old_nip;
+  enum nss_status (*fct) (void);
+  int no_more;
+
+  __libc_lock_lock (lock);
+
+  /* Remember which was the last used service.  */
+  old_nip = nip;
+
+  /* Cycle through all the services and run their setnetgrent functions.  */
+  no_more = setup ((void **) &fct, "endnetgrent", 1);
+  while (! no_more)
+    {
+      /* Ignore status, we force check in __NSS_NEXT.  */
+      (void) (*fct) ();
+
+      no_more = (nip == old_nip
+		 || __nss_next (&nip, "endnetgrent", (void **) &fct, 0, 1));
+    }
+
+  __libc_lock_unlock (lock);
+}
+
+
+int
+__getnetgrent_r (char **hostp, char **userp, char **domainp,
+		 char *buffer, int buflen)
+{
+  enum nss_status (*fct) (struct __netgrent *, char *, int);
+  struct __netgrent result;
+  int no_more;
+
+  /* Initialize status to return if no more functions are found.  */
+  enum nss_status status = NSS_STATUS_NOTFOUND;
+
+  __libc_lock_lock (lock);
+
+  /* Run through available functions, starting with the same function last
+     run.  We will repeat each function as long as it succeeds, and then go
+     on to the next service action.  */
+  no_more = setup ((void **) &fct, "getnetgrent_r", 0);
+  while (! no_more)
+    {
+      status = (*fct) (&result, buffer, buflen);
+
+      no_more = __nss_next (&nip, "getnetgrent_r", (void **) &fct, status, 0);
+    }
+
+  if (status == NSS_STATUS_SUCCESS)
+    {
+      *hostp = result.host;
+      *userp = result.user;
+      *domainp = result.domain;
+    }
+
+  __libc_lock_unlock (lock);
+
+  return status == NSS_STATUS_SUCCESS ? 1 : 0;
+}
+weak_alias (__getnetgrent_r, getnetgrent_r)
+
+/* Test whether given (host,user,domain) triple is in NETGROUP.  */
+int
+innetgr (const char *netgroup, const char *host, const char *user,
+	 const char *domain)
+{
+  int (*setfct) (const char *);
+  void (*endfct) (void);
+  int (*getfct) (struct __netgrent *, char *, int);
+  int result = 0;
+  int no_more;
+
+  __libc_lock_lock (lock);
+
+  /* Walk through the services until we found an answer or we shall
+     not work further.  We can do some optimization here.  Since all
+     services must provide the `setnetgrent' function we can do all
+     the work during one walk through the service list.  */
+  no_more = setup ((void **) &setfct, "setnetgrent", 1);
+  while (! no_more)
+    {
+      enum nss_status status;
+
+      /* Open netgroup.  */
+      status = (*setfct) (netgroup);
+      if (status == NSS_STATUS_SUCCESS
+	  && __nss_lookup (&nip, "getnetgrent_r", (void **) &getfct) == 0)
+	{
+	  char buffer[1024];
+	  struct __netgrent entry;
+
+	  while ((*getfct) (&entry, buffer, sizeof buffer)
+		 == NSS_STATUS_SUCCESS)
+	    {
+	      if ((entry.host == NULL || host == NULL
+		   || strcmp (entry.host, host) == 0)
+		  && (entry.user == NULL || user == NULL
+		      || strcmp (entry.user, user) == 0)
+		  && (entry.domain == NULL || domain == NULL
+		      || strcmp (entry.domain, domain) == 0))
+		{
+		  result = 1;
+		  break;
+		}
+	    }
+
+	  if (result != 0)
+	    break;
+
+	  /* If we found one service which does know the given
+	     netgroup we don't try further.  */
+	  status = NSS_STATUS_RETURN;
+	}
+
+      /* Free all resources of the service.  */
+      if (__nss_lookup (&nip, "endnetgrent", (void **) &endfct) == 0)
+	(*endfct) ();
+
+      /* Look for the next service.  */
+      no_more = __nss_next (&nip, "setnetgrent", (void **) &setfct, status, 0);
+    }
+
+  __libc_lock_unlock (lock);
+
+  return result;
+}
diff --git a/inet/netgroup.h b/inet/netgroup.h
new file mode 100644
index 0000000000..e8ea51e957
--- /dev/null
+++ b/inet/netgroup.h
@@ -0,0 +1,30 @@
+/* Internal header for netgroup related functions.
+Copyright (C) 1996 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.  */
+
+#ifndef _NETGROUP_H
+#define _NETGROUP_H	1
+
+struct __netgrent
+{
+  const char *host;
+  const char *user;
+  const char *domain;
+};
+
+#endif /* netgroup.h */
diff --git a/inet/rcmd.c b/inet/rcmd.c
index a9756d109a..3fc8adc742 100644
--- a/inet/rcmd.c
+++ b/inet/rcmd.c
@@ -52,8 +52,6 @@ static char sccsid[] = "@(#)rcmd.c	8.3 (Berkeley) 3/26/94";
 #include <ctype.h>
 #include <string.h>
 
-#define MIN(A, B) ((A) < (B) ? (A) : (B))
-
 
 int	__ivaliduser __P((FILE *, u_int32_t, const char *, const char *));
 static int __icheckhost __P((u_int32_t, char *));
diff --git a/libio/clearerr_u.c b/libio/clearerr_u.c
index 4c8b6c29bd..189f38d515 100644
--- a/libio/clearerr_u.c
+++ b/libio/clearerr_u.c
@@ -20,11 +20,9 @@ Boston, MA 02111-1307, USA.  */
 #include "stdio.h"
 
 void
-__clearerr_unlocked (fp)
+clearerr_unlocked (fp)
      FILE *fp;
 {
   CHECK_FILE (fp, /*nothing*/);
   _IO_clearerr (fp);
 }
-
-weak_alias (__clearerr_unlocked, clearerr_unlocked)
diff --git a/libio/fgetc.c b/libio/fgetc.c
index 07fd89a516..a754c4b78b 100644
--- a/libio/fgetc.c
+++ b/libio/fgetc.c
@@ -31,7 +31,7 @@ fgetc (fp)
 {
   int result;
   CHECK_FILE (fp, EOF);
-  __libc_cleanup_region_start (_IO_funlockfile, fp);
+  __libc_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
   _IO_flockfile (fp);
   result = _IO_getc_unlocked (fp);
   __libc_cleanup_region_end (1);
diff --git a/libio/fputc.c b/libio/fputc.c
index bd871ab047..865ac8cde0 100644
--- a/libio/fputc.c
+++ b/libio/fputc.c
@@ -32,7 +32,7 @@ fputc (c, fp)
 {
   int result;
   CHECK_FILE (fp, EOF);
-  __libc_cleanup_region_start (&_IO_funlockfile, fp);
+  __libc_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
   _IO_flockfile (fp);
   result = _IO_putc_unlocked (c, fp);
   __libc_cleanup_region_end (1);
diff --git a/libio/fputc_u.c b/libio/fputc_u.c
index 97e4d94eb3..bc2cc2efb6 100644
--- a/libio/fputc_u.c
+++ b/libio/fputc_u.c
@@ -28,12 +28,10 @@ the executable file might be covered by the GNU General Public License. */
 #undef fputc_unlocked
 
 int
-__fputc_unlocked (c, fp)
+fputc_unlocked (c, fp)
      int c;
      _IO_FILE *fp;
 {
   CHECK_FILE (fp, EOF);
   return _IO_putc_unlocked (c, fp);
 }
-
-weak_alias (__fputc_unlocked, fputc_unlocked)
diff --git a/libio/freopen.c b/libio/freopen.c
index 5821e84c6f..0b782dd770 100644
--- a/libio/freopen.c
+++ b/libio/freopen.c
@@ -35,7 +35,7 @@ freopen (filename, mode, fp)
   CHECK_FILE (fp, NULL);
   if (!(fp->_flags & _IO_IS_FILEBUF))
     return NULL;
-  __libc_cleanup_region_start (&_IO_funlockfile, fp);
+  __libc_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
   _IO_flockfile (fp);
   result = _IO_freopen (filename, mode, fp);
   __libc_cleanup_region_end (1);
diff --git a/libio/fseek.c b/libio/fseek.c
index c33927a95f..61f2e9205e 100644
--- a/libio/fseek.c
+++ b/libio/fseek.c
@@ -33,7 +33,7 @@ fseek (fp, offset, whence)
 {
   int result;
   CHECK_FILE (fp, -1);
-  __libc_cleanup_region_start (&_IO_funlockfile, fp);
+  __libc_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
   _IO_flockfile (fp);
   result = _IO_fseek (fp, offset, whence);
   __libc_cleanup_region_end (1);
diff --git a/libio/genops.c b/libio/genops.c
index 7c2dcba7b4..bd741ec66e 100644
--- a/libio/genops.c
+++ b/libio/genops.c
@@ -329,7 +329,7 @@ DEFUN(_IO_default_xsputn, (f, data, n),
       _IO_ssize_t count = f->_IO_write_end - f->_IO_write_ptr; /* Space available. */
       if (count > 0)
 	{
-	  if (count > more)
+	  if ((_IO_size_t) count > more)
 	    count = more;
 	  if (count > 20)
 	    {
@@ -374,7 +374,7 @@ DEFUN(_IO_default_xsgetn, (fp, data, n),
       _IO_ssize_t count = fp->_IO_read_end - fp->_IO_read_ptr; /* Data available. */
       if (count > 0)
 	{
-	  if (count > more)
+	  if ((_IO_size_t) count > more)
 	    count = more;
 	  if (count > 20)
 	    {
diff --git a/libio/getc.c b/libio/getc.c
index 82e5756ad3..c345e44ca6 100644
--- a/libio/getc.c
+++ b/libio/getc.c
@@ -33,7 +33,7 @@ getc (fp)
 {
   int result;
   CHECK_FILE (fp, EOF);
-  __libc_cleanup_region_start (&_IO_funlockfile, fp);
+  __libc_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
   _IO_flockfile (fp);
   result = _IO_getc_unlocked (fp);
   __libc_cleanup_region_end (1);
diff --git a/libio/getc_u.c b/libio/getc_u.c
index 4aa5cd5ccd..569e063b1f 100644
--- a/libio/getc_u.c
+++ b/libio/getc_u.c
@@ -28,11 +28,9 @@ the executable file might be covered by the GNU General Public License. */
 #undef getc_unlocked
 
 int
-__getc_unlocked (fp)
+getc_unlocked (fp)
      FILE *fp;
 {
   CHECK_FILE (fp, EOF);
   return _IO_getc_unlocked (fp);
 }
-
-weak_alias (__getc_unlocked, getc_unlocked)
diff --git a/libio/getchar.c b/libio/getchar.c
index e7a236cf2e..d54ec58c1e 100644
--- a/libio/getchar.c
+++ b/libio/getchar.c
@@ -31,7 +31,8 @@ int
 getchar ()
 {
   int result;
-  __libc_cleanup_region_start (&_IO_funlockfile, stdin);
+  __libc_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
+			       stdin);
   _IO_flockfile (stdin);
   result = _IO_getc_unlocked (stdin);
   __libc_cleanup_region_end (1);
diff --git a/libio/getchar_u.c b/libio/getchar_u.c
index 0430f8119c..337f693709 100644
--- a/libio/getchar_u.c
+++ b/libio/getchar_u.c
@@ -28,9 +28,7 @@ the executable file might be covered by the GNU General Public License. */
 #undef getchar_unlocked
 
 int
-__getchar_unlocked ()
+getchar_unlocked ()
 {
   return _IO_getc_unlocked (stdin);
 }
-
-weak_alias (__getchar_unlocked, getchar_unlocked)
diff --git a/libio/iofclose.c b/libio/iofclose.c
index 9d537377a4..77c7b50088 100644
--- a/libio/iofclose.c
+++ b/libio/iofclose.c
@@ -35,19 +35,19 @@ _IO_fclose (fp)
 
   CHECK_FILE(fp, EOF);
 
-  __libc_cleanup_region_start (&_IO_funlockfile, fp);
+  __libc_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
   _IO_flockfile (fp);
   if (fp->_IO_file_flags & _IO_IS_FILEBUF)
     status = _IO_file_close_it (fp);
   else
     status = fp->_flags & _IO_ERR_SEEN ? -1 : 0;
   _IO_FINISH (fp);
+  __libc_cleanup_region_end (1);
   if (fp != _IO_stdin && fp != _IO_stdout && fp != _IO_stderr)
     {
       fp->_IO_file_flags = 0;
       free(fp);
     }
-  __libc_cleanup_region_end (1);
   return status;
 }
 
diff --git a/libio/iofflush.c b/libio/iofflush.c
index cbc5b1f6d7..385c9629eb 100644
--- a/libio/iofflush.c
+++ b/libio/iofflush.c
@@ -23,6 +23,7 @@ This exception does not however invalidate any other reasons why
 the executable file might be covered by the GNU General Public License. */
 
 #include "libioP.h"
+#include <stdio.h>
 
 int
 _IO_fflush (fp)
@@ -34,7 +35,8 @@ _IO_fflush (fp)
     {
       int result;
       CHECK_FILE (fp, EOF);
-      __libc_cleanup_region_start (&_IO_funlockfile, fp);
+      __libc_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
+				   fp);
       _IO_flockfile (fp);
       result = _IO_SYNC (fp) ? EOF : 0;
       __libc_cleanup_region_end (1);
diff --git a/libio/iofflush_u.c b/libio/iofflush_u.c
index b7a91952b4..b8af7101a1 100644
--- a/libio/iofflush_u.c
+++ b/libio/iofflush_u.c
@@ -23,9 +23,10 @@ This exception does not however invalidate any other reasons why
 the executable file might be covered by the GNU General Public License. */
 
 #include "libioP.h"
+#include <stdio.h>
 
 int
-_IO_fflush_unlocked (fp)
+fflush_unlocked (fp)
      register _IO_FILE *fp;
 {
   if (fp == NULL)
@@ -36,6 +37,3 @@ _IO_fflush_unlocked (fp)
       return _IO_SYNC (fp) ? EOF : 0;
     }
 }
-
-weak_alias (_IO_fflush_unlocked, fflush_unlocked)
-
diff --git a/libio/iofgetpos.c b/libio/iofgetpos.c
index 4cec7a73d8..07128c16a3 100644
--- a/libio/iofgetpos.c
+++ b/libio/iofgetpos.c
@@ -33,7 +33,7 @@ _IO_fgetpos (fp, posp)
 {
   _IO_fpos_t pos;
   CHECK_FILE (fp, EOF);
-  __libc_cleanup_region_start (&_IO_funlockfile, fp);
+  __libc_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
   _IO_flockfile (fp);
   pos = _IO_seekoff (fp, 0, _IO_seek_cur, 0);
   __libc_cleanup_region_end (1);
diff --git a/libio/iofgets.c b/libio/iofgets.c
index 4d4ce5c726..71d677c161 100644
--- a/libio/iofgets.c
+++ b/libio/iofgets.c
@@ -1,5 +1,5 @@
 /*
-Copyright (C) 1993, 1995 Free Software Foundation
+Copyright (C) 1993, 1995, 1996 Free Software Foundation, Inc.
 
 This file is part of the GNU IO Library.  This library is free
 software; you can redistribute it and/or modify it under the
@@ -23,6 +23,7 @@ This exception does not however invalidate any other reasons why
 the executable file might be covered by the GNU General Public License. */
 
 #include "libioP.h"
+#include <stdio.h>
 
 char*
 _IO_fgets (buf, n, fp)
@@ -35,7 +36,7 @@ _IO_fgets (buf, n, fp)
   CHECK_FILE (fp, NULL);
   if (n <= 0)
     return NULL;
-  __libc_cleanup_region_start (&__funlockfile, fp);
+  __libc_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
   __flockfile (fp);
   count = _IO_getline (fp, buf, n - 1, '\n', 1);
   if (count == 0 || (fp->_IO_file_flags & _IO_ERR_SEEN))
diff --git a/libio/iofputs.c b/libio/iofputs.c
index a9fd5f29a3..6e94223a5c 100644
--- a/libio/iofputs.c
+++ b/libio/iofputs.c
@@ -33,7 +33,7 @@ _IO_fputs (str, fp)
   _IO_size_t len = strlen (str);
   int result;
   CHECK_FILE (fp, EOF);
-  __libc_cleanup_region_start (&_IO_funlockfile, fp);
+  __libc_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
   _IO_flockfile (fp);
   if (_IO_sputn (fp, str, len) != len)
     result = EOF;
diff --git a/libio/iofread.c b/libio/iofread.c
index af6bc33f24..8610b0c87c 100644
--- a/libio/iofread.c
+++ b/libio/iofread.c
@@ -36,7 +36,7 @@ _IO_fread (buf, size, count, fp)
   CHECK_FILE (fp, 0);
   if (bytes_requested == 0)
     return 0;
-  __libc_cleanup_region_start (&_IO_funlockfile, fp);
+  __libc_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
   _IO_flockfile (fp);
   bytes_read = _IO_sgetn (fp, (char *) buf, bytes_requested);
   __libc_cleanup_region_end (1);
diff --git a/libio/iofsetpos.c b/libio/iofsetpos.c
index 9013606e72..52700f70bc 100644
--- a/libio/iofsetpos.c
+++ b/libio/iofsetpos.c
@@ -32,7 +32,7 @@ _IO_fsetpos (fp, posp)
 {
   int result;
   CHECK_FILE (fp, EOF);
-  __libc_cleanup_region_start (&_IO_funlockfile, fp);
+  __libc_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
   _IO_flockfile (fp);
   if (_IO_seekpos (fp, *posp, _IOS_INPUT|_IOS_OUTPUT) == _IO_pos_BAD)
     {
diff --git a/libio/ioftell.c b/libio/ioftell.c
index ec3b1a2f2e..1fc7c55a51 100644
--- a/libio/ioftell.c
+++ b/libio/ioftell.c
@@ -32,7 +32,7 @@ _IO_ftell (fp)
 {
   _IO_pos_t pos;
   CHECK_FILE (fp, -1L);
-  __libc_cleanup_region_start (&_IO_funlockfile, fp);
+  __libc_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
   _IO_flockfile (fp);
   pos = _IO_seekoff (fp, 0, _IO_seek_cur, 0);
   __libc_cleanup_region_end (1);
diff --git a/libio/iofwrite.c b/libio/iofwrite.c
index 4ee489d2b1..7767a94e8a 100644
--- a/libio/iofwrite.c
+++ b/libio/iofwrite.c
@@ -36,7 +36,7 @@ _IO_fwrite (buf, size, count, fp)
   CHECK_FILE (fp, 0);
   if (request == 0)
     return 0;
-  __libc_cleanup_region_start (&_IO_funlockfile, fp);
+  __libc_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
   _IO_flockfile (fp);
   written = _IO_sputn (fp, (const char *) buf, request);
   __libc_cleanup_region_end (1);
diff --git a/libio/iogetdelim.c b/libio/iogetdelim.c
index da6efa459a..d41bb6b2a9 100644
--- a/libio/iogetdelim.c
+++ b/libio/iogetdelim.c
@@ -52,7 +52,7 @@ _IO_getdelim (lineptr, n, delimiter, fp)
       return -1;
     }
   CHECK_FILE (fp, -1);
-  __libc_cleanup_region_start (&_IO_funlockfile, fp);
+  __libc_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
   _IO_flockfile (fp);
   if (_IO_ferror_unlocked (fp))
     {
diff --git a/libio/iogetline.c b/libio/iogetline.c
index 85dff7e3e7..a72707196b 100644
--- a/libio/iogetline.c
+++ b/libio/iogetline.c
@@ -1,4 +1,4 @@
-/* 
+/*
 Copyright (C) 1993 Free Software Foundation
 
 This file is part of the GNU IO Library.  This library is free
@@ -48,7 +48,7 @@ DEFUN(_IO_getline, (fp, buf, n, delim, extract_delim),
 	  break;
 	else
 	  len = fp->_IO_read_end - fp->_IO_read_ptr;
-      if (len >= n)
+      if ((_IO_size_t) len >= n)
 	len = n;
       t = (char*)memchr((void*)fp->_IO_read_ptr, delim, len);
       if (t != NULL)
diff --git a/libio/iogets.c b/libio/iogets.c
index 8fdc4350a9..e132093e48 100644
--- a/libio/iogets.c
+++ b/libio/iogets.c
@@ -32,7 +32,8 @@ _IO_gets (buf)
   _IO_size_t count;
   int ch;
 
-  __libc_cleanup_region_start (&_IO_funlockfile, _IO_stdin);
+  __libc_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
+			       _IO_stdin);
   _IO_flockfile (_IO_stdin);
   ch = _IO_getc_unlocked (_IO_stdin);
   if (ch == EOF)
diff --git a/libio/ioputs.c b/libio/ioputs.c
index 2770ab2935..34e68b9f8b 100644
--- a/libio/ioputs.c
+++ b/libio/ioputs.c
@@ -30,7 +30,8 @@ _IO_puts (str)
 {
   int result;
   _IO_size_t len = strlen (str);
-  __libc_cleanup_region_start (&_IO_funlockfile, _IO_stdout);
+  __libc_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
+			       _IO_stdout);
   _IO_flockfile (_IO_stdout);
   if (_IO_sputn (_IO_stdout, str, len) == len
       && _IO_putc_unlocked ('\n', _IO_stdout) != EOF)
diff --git a/libio/iosetbuffer.c b/libio/iosetbuffer.c
index e44f33962f..d14e5d411e 100644
--- a/libio/iosetbuffer.c
+++ b/libio/iosetbuffer.c
@@ -31,7 +31,7 @@ _IO_setbuffer (fp, buf, size)
      _IO_size_t size;
 {
   CHECK_FILE (fp, );
-  __libc_cleanup_region_start (&_IO_funlockfile, fp);
+  __libc_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
   _IO_flockfile (fp);
   fp->_flags &= ~_IO_LINE_BUF;
   if (!buf)
diff --git a/libio/iosetvbuf.c b/libio/iosetvbuf.c
index e9dccae529..3776330a88 100644
--- a/libio/iosetvbuf.c
+++ b/libio/iosetvbuf.c
@@ -37,7 +37,7 @@ _IO_setvbuf (fp, buf, mode, size)
 {
   int result;
   CHECK_FILE (fp, EOF);
-  __libc_cleanup_region_start (&_IO_funlockfile, fp);
+  __libc_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
   _IO_flockfile (fp);
   switch (mode)
     {
diff --git a/libio/ioungetc.c b/libio/ioungetc.c
index cc414083f8..180e789c27 100644
--- a/libio/ioungetc.c
+++ b/libio/ioungetc.c
@@ -33,7 +33,7 @@ _IO_ungetc (c, fp)
   CHECK_FILE (fp, EOF);
   if (c == EOF)
     return EOF;
-  __libc_cleanup_region_start (&_IO_funlockfile, fp);
+  __libc_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
   _IO_flockfile (fp);
   result = _IO_sputbackc (fp, (unsigned char) c);
   __libc_cleanup_region_end (1);
diff --git a/libio/putc.c b/libio/putc.c
index 5dff3de304..bc69e2efb7 100644
--- a/libio/putc.c
+++ b/libio/putc.c
@@ -28,7 +28,7 @@ putc (c, fp)
 {
   int result;
   CHECK_FILE (fp, EOF);
-  __libc_cleanup_region_start (&_IO_funlockfile, fp);
+  __libc_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
   _IO_flockfile (fp);
   result = _IO_putc_unlocked (c, fp);
   __libc_cleanup_region_end (1);
diff --git a/libio/putchar.c b/libio/putchar.c
index a7891a5a2a..7822a31a1a 100644
--- a/libio/putchar.c
+++ b/libio/putchar.c
@@ -26,7 +26,8 @@ putchar (c)
      int c;
 {
   int result;
-  __libc_cleanup_region_start (&_IO_funlockfile, _IO_stdout);
+  __libc_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
+			       _IO_stdout);
   _IO_flockfile (_IO_stdout);
   result = _IO_putc_unlocked (c, _IO_stdout);
   __libc_cleanup_region_end (1);
diff --git a/libio/rewind.c b/libio/rewind.c
index d30233e17e..2af2dd84d3 100644
--- a/libio/rewind.c
+++ b/libio/rewind.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993 Free Software Foundation
+/* Copyright (C) 1993, 1996 Free Software Foundation, Inc.
 
 This file is part of the GNU IO Library.  This library is free
 software; you can redistribute it and/or modify it under the
@@ -29,7 +29,7 @@ rewind (fp)
      _IO_FILE* fp;
 {
   CHECK_FILE (fp, );
-  __libc_cleanup_region_start (&_IO_funlockfile, fp);
+  __libc_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
   _IO_flockfile (fp);
   _IO_rewind (fp);
   __libc_cleanup_region_end (1);
diff --git a/libio/strops.c b/libio/strops.c
index 98c5b263d5..464063322d 100644
--- a/libio/strops.c
+++ b/libio/strops.c
@@ -1,4 +1,4 @@
-/* 
+/*
 Copyright (C) 1993 Free Software Foundation
 
 This file is part of the GNU IO Library.  This library is free
@@ -112,7 +112,7 @@ DEFUN(_IO_str_overflow, (fp, c),
       fp->_flags |= _IO_CURRENTLY_PUTTING;
       get_pos = LEN(fp);
     }
-  if (pos >= _IO_blen(fp) + flush_only)
+  if (pos >= (_IO_size_t) (_IO_blen(fp) + flush_only))
     {
       if (fp->_flags & _IO_USER_BUF) /* not allowed to enlarge */
 	{
@@ -187,10 +187,10 @@ DEFUN(_IO_str_count, (fp),
       register _IO_FILE *fp)
 {
   _IO_ssize_t put_len = fp->_IO_write_ptr - fp->_IO_write_base;
-  if (put_len < LEN(fp))
+  if (put_len < (_IO_ssize_t) LEN(fp))
     put_len = LEN(fp);
   return put_len;
-}     
+}
 
 _IO_pos_t
 DEFUN(_IO_str_seekoff, (fp, offset, dir, mode),
@@ -213,7 +213,7 @@ DEFUN(_IO_str_seekoff, (fp, offset, dir, mode),
 	default: /* case _IO_seek_set: */
 	  break;
 	}
-      if (offset < 0 || (_IO_size_t)offset > cur_size)
+      if (offset < 0 || (_IO_ssize_t)offset > cur_size)
 	return EOF;
       fp->_IO_read_ptr = fp->_IO_read_base + offset;
       fp->_IO_read_end = fp->_IO_read_base + cur_size;
@@ -234,7 +234,7 @@ DEFUN(_IO_str_seekoff, (fp, offset, dir, mode),
 	default: /* case _IO_seek_set: */
 	  break;
 	}
-      if (offset < 0 || (_IO_size_t)offset > cur_size)
+      if (offset < 0 || (_IO_ssize_t)offset > cur_size)
 	return EOF;
       LEN(fp) = cur_size;
       fp->_IO_write_ptr = fp->_IO_write_base + offset;
diff --git a/locale/programs/ld-collate.c b/locale/programs/ld-collate.c
index a948b55ed3..1bfa533d98 100644
--- a/locale/programs/ld-collate.c
+++ b/locale/programs/ld-collate.c
@@ -1341,7 +1341,7 @@ collation element `%.*s' appears more than once: ignore line"),
 	{
 	  unsigned int order = ++collate->order_cnt;
 
-	  if ((unsigned int) tmp != 0)
+	  if ((unsigned long int) tmp != 0ul)
 	    {
 	      lr_error (lr, _("\
 collation symbol `.*s' appears more than once: ignore line"),
diff --git a/locale/programs/ld-ctype.c b/locale/programs/ld-ctype.c
index 196f990745..64f73d430f 100644
--- a/locale/programs/ld-ctype.c
+++ b/locale/programs/ld-ctype.c
@@ -21,6 +21,7 @@ Boston, MA 02111-1307, USA.  */
 # include <config.h>
 #endif
 
+#include <alloca.h>
 #include <endian.h>
 #include <limits.h>
 #include <string.h>
diff --git a/locale/programs/ld-time.c b/locale/programs/ld-time.c
index 6f961b658a..6fcb06979a 100644
--- a/locale/programs/ld-time.c
+++ b/locale/programs/ld-time.c
@@ -395,7 +395,8 @@ time_output (struct localedef_t *locale, const char *output_path)
   struct iovec iov[2 + _NL_ITEM_INDEX (_NL_NUM_LC_TIME)
 		  + time->cur_num_era - 1
 		  + time->cur_num_alt_digits - 1
-		  + 1 + (time->cur_num_era * 9 - 1) * 2];
+		  + 1 + (time->cur_num_era * 9 - 1) * 2
+		  + (time->cur_num_era == 0)];
   struct locale_file data;
   u_int32_t idx[_NL_ITEM_INDEX (_NL_NUM_LC_TIME)];
   size_t cnt, last_idx, num;
@@ -635,11 +636,23 @@ time_output (struct localedef_t *locale, const char *output_path)
       /* idx[1 + last_idx] += 8 * sizeof (int32_t) + l; */
     }
 
+  /* We have a problem when no era data is present.  In this case the
+     data pointer for _NL_TIME_ERA_ENTRIES_EB and
+     _NL_TIME_ERA_ENTRIES_EL point after the end of the file.  So we
+     introduce some dummy data here.  */
+  if (time->cur_num_era == 0)
+    {
+      static u_int32_t dummy = 0;
+      iov[2 + cnt].iov_base = (void *) &dummy;
+      iov[2 + cnt].iov_len = 4;
+      ++cnt;
+    }
 
   assert (cnt == (_NL_ITEM_INDEX (_NL_NUM_LC_TIME)
 		  + time->cur_num_era - 1
 		  + time->cur_num_alt_digits - 1
-		  + 1 + (time->cur_num_era * 9 - 1) * 2)
+		  + 1 + (time->cur_num_era * 9 - 1) * 2
+		  + (time->cur_num_era == 0))
 	  && last_idx + 1 == _NL_ITEM_INDEX (_NL_NUM_LC_TIME));
 
   write_locale_data (output_path, "LC_TIME", 2 + cnt, iov);
diff --git a/locale/programs/locale.c b/locale/programs/locale.c
index 667afbd188..fa824fb96c 100644
--- a/locale/programs/locale.c
+++ b/locale/programs/locale.c
@@ -183,14 +183,13 @@ main (int argc, char *argv[])
   /* Version information is requested.  */
   if (do_version)
     {
-      fprintf (stderr, "locale (GNU %s) %s\n", PACKAGE, VERSION);
-      fprintf (stderr, _("\
+      printf ("locale (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");
-      fprintf (stderr, _("Written by %s.\n"),
-	       "Ulrich Drepper");
+      printf (_("Written by %s.\n"), "Ulrich Drepper");
 
       exit (EXIT_SUCCESS);
     }
diff --git a/locale/programs/localedef.c b/locale/programs/localedef.c
index ff9248e317..6d37a0e398 100644
--- a/locale/programs/localedef.c
+++ b/locale/programs/localedef.c
@@ -173,14 +173,13 @@ main (int argc, char *argv[])
   /* Version information is requested.  */
   if (do_version)
     {
-      fprintf (stderr, "localedef (GNU %s) %s\n", PACKAGE, VERSION);
-      fprintf (stderr, _("\
+      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");
-      fprintf (stderr, _("Written by %s.\n"),
-	       "Ulrich Drepper");
+      printf (_("Written by %s.\n"), "Ulrich Drepper");
 
       exit (0);
     }
diff --git a/login/login_tty.c b/login/login_tty.c
index e4e075c6ed..2959457c07 100644
--- a/login/login_tty.c
+++ b/login/login_tty.c
@@ -39,6 +39,7 @@ static char sccsid[] = "@(#)login_tty.c	8.1 (Berkeley) 6/4/93";
 #include <sys/ioctl.h>
 #include <unistd.h>
 #include <fcntl.h>
+#include <utmp.h>
 
 int
 login_tty(fd)
diff --git a/manual/filesys.texi b/manual/filesys.texi
index e269663e70..31325268f9 100644
--- a/manual/filesys.texi
+++ b/manual/filesys.texi
@@ -327,6 +327,36 @@ conditions are defined for this function:
 @item EBADF
 The @var{dirstream} argument is not valid.
 @end table
+
+@code{readdir} is not thread safe.  Multiple threads using
+@code{readdir} on the same @var{dirstream} may overwrite the return
+value.  Use @code{readdir_r} when this is critical.
+@end deftypefun
+
+@comment dirent.h
+@comment GNU
+@deftypefun int readdir_r (DIR *@var{dirstream}, struct *@var{entry}, struct **@var{result})
+This function is the reentrant version of @code{reentrant}.  Like
+@code{readdir} it returns the next entry from the directory.  But to
+prevent conflicts for simultanously running threads the result is not
+stored in some internal memory.  Instead the argument @var{entry} has to
+point to a place where the result is stored.
+
+The return value is @code{0} in case the next entry was read
+successfully.  In this case a pointer to the result is returned in
+*@var{result}.  It is not required that *@var{result} is the same as
+@var{entry}.  If somethings goes wrong while exeucting @code{readdir_r}
+the function return @code{-1}.  The @code{errno} variable is set like
+described for @code{readdir}.
+
+@strong{Portability Note:} On some systems, @code{readdir_r} may not
+return a terminated string as the file name even if no @code{d_reclen}
+element is available in @code{struct dirent} and the file name as the
+maximal allowed size.  Modern systems all have the @code{d_reclen} field
+and on old systems multi threading is not critical.  In any case, there
+is no such problem with the @code{readdir} function so that even on
+systems without @code{d_reclen} field one could use multiple threads by
+using external locking.
 @end deftypefun
 
 @comment dirent.h
diff --git a/misc/Makefile b/misc/Makefile
index e6ad0d06d8..343cc3ee62 100644
--- a/misc/Makefile
+++ b/misc/Makefile
@@ -56,11 +56,6 @@ routines := brk sbrk sstk ioctl \
 	    hsearch hsearch_r tsearch lsearch \
 	    err error ustat \
 	    getsysstats
-
-ifneq (,$(filter %REENTRANT, $(defines)))
-routines += force-wrapper
-endif
-
 aux := init-misc
 distribute := bsd-compat.c
 extra-objs := bsd-compat.o
diff --git a/netgroup.h b/netgroup.h
new file mode 100644
index 0000000000..4b2b284cdb
--- /dev/null
+++ b/netgroup.h
@@ -0,0 +1 @@
+#include <inet/netgroup.h>
diff --git a/nss/Makefile b/nss/Makefile
index b900e96cc3..319bad5b29 100644
--- a/nss/Makefile
+++ b/nss/Makefile
@@ -33,7 +33,7 @@ routines		= nsswitch $(addsuffix -lookup,$(databases))
 # Caution: if you add a database here, you must add its real name
 # in databases.def, too.
 databases		= proto service hosts network grp pwd rpc ethers \
-			  spwd
+			  spwd netgrp
 
 # Specify rules for the nss_* modules.  We have some services.
 services		:= files dns db
diff --git a/nss/databases.def b/nss/databases.def
index 98772bac76..8a5ede2a58 100644
--- a/nss/databases.def
+++ b/nss/databases.def
@@ -23,6 +23,7 @@ Boston, MA 02111-1307, USA.  */
 DEFINE_DATABASE (ethers)
 DEFINE_DATABASE (group)
 DEFINE_DATABASE (hosts)
+DEFINE_DATABASE (netgroup)
 DEFINE_DATABASE (networks)
 DEFINE_DATABASE (passwd)
 DEFINE_DATABASE (protocols)
diff --git a/nss/db-Makefile b/nss/db-Makefile
index 55edd66c01..756f4c6ce6 100644
--- a/nss/db-Makefile
+++ b/nss/db-Makefile
@@ -1,5 +1,5 @@
 DATABASES = $(wildcard /etc/passwd /etc/group /etc/ethers /etc/protocols \
-		       /etc/rpc /etc/services /etc/shadow)
+		       /etc/rpc /etc/services /etc/shadow /etc/netgroup)
 
 VAR_DB = /var/db
 
@@ -67,3 +67,11 @@ $(VAR_DB)/shadow.db: /etc/shadow
 		 /^[^#]/ { printf ".%s ", $$1; print }' $^ | \
 	$(MAKEDB) -o $@ -
 	@echo "done."
+
+$(VAR_DB)/netgroup.db: /etc/netgroup
+	@echo -n "$(patsubst %.db,%,$(@F))... "
+	@$(AWK) '/^[^#]/ { end=sub(/\\/, " "); \
+			   gsub(/[ \t]+/, " "); \
+			   if(end == 1) printf "%s", $$0; else print }' $^ | \
+	$(MAKEDB) -o $@ -
+	@echo "done."
diff --git a/nss/getXXent_r.c b/nss/getXXent_r.c
index ea391fe094..6bff863e07 100644
--- a/nss/getXXent_r.c
+++ b/nss/getXXent_r.c
@@ -136,7 +136,7 @@ SETFUNC_NAME (STAYOPEN)
 #ifdef NEED__RES
   if ((_res.options & RES_INIT) == 0 && res_init () == -1)
     {
-      h_errno = NETDB_INTERNAL;
+      __set_h_errno (NETDB_INTERNAL);
       return NULL;
     }
 #endif /* need _res */
@@ -166,7 +166,7 @@ ENDFUNC_NAME (void)
 #ifdef NEED__RES
   if ((_res.options & RES_INIT) == 0 && res_init () == -1)
     {
-      h_errno = NETDB_INTERNAL;
+      __set_h_errno (NETDB_INTERNAL);
       return NULL;
     }
 #endif /* need _res */
@@ -198,7 +198,7 @@ INTERNAL (REENTRANT_GETNAME) (LOOKUP_TYPE *result, char *buffer, int buflen
 #ifdef NEED__RES
   if ((_res.options & RES_INIT) == 0 && res_init () == -1)
     {
-      h_errno = NETDB_INTERNAL;
+      __set_h_errno (NETDB_INTERNAL);
       return NULL;
     }
 #endif /* need _res */
diff --git a/dirent/readdir_r.c b/nss/netgrp-lookup.c
index b9979660fa..b7ea374f1b 100644
--- a/dirent/readdir_r.c
+++ b/nss/netgrp-lookup.c
@@ -1,5 +1,4 @@
-/* readdir_r - Reentrant version of readdir.
-Copyright (C) 1996 Free Software Foundation, Inc.
+/* Copyright (C) 1996 Free Software Foundation, Inc.
 This file is part of the GNU C Library.
 Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
 
@@ -18,20 +17,6 @@ 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 <dirent.h>
+#define DATABASE_NAME netgroup
 
-/* Some systems have reentrancy problems with their `readdir'
-   implementation so they have an additional `readdir_r' version.  The
-   GNU version does not have these problems but for compatibility
-   reasons we provide this function.  It is simply a wrapper around
-   the normal function.
-
-   The actual definition of this functions varies very strong from
-   system to system.  We chose to follow the POSIX version.  */
-int
-readdir_r (DIR *dirp, struct dirent *entry, struct dirent **result)
-{
-  *result = readdir (dirp);
-
-  return *result != NULL ? 0 : -1;
-}
+#include "XXX-lookup.c"
diff --git a/nss/nss.h b/nss/nss.h
index e9acb93bcc..8246719054 100644
--- a/nss/nss.h
+++ b/nss/nss.h
@@ -37,6 +37,7 @@ enum nss_status
   NSS_STATUS_UNAVAIL,
   NSS_STATUS_NOTFOUND,
   NSS_STATUS_SUCCESS,
+  NSS_STATUS_RETURN
 };
 
 
diff --git a/nss/nss_db/db-XXX.c b/nss/nss_db/db-XXX.c
index e2bab51f5d..0c41761d67 100644
--- a/nss/nss_db/db-XXX.c
+++ b/nss/nss_db/db-XXX.c
@@ -56,10 +56,10 @@ static int keep_db;
 static unsigned int entidx;	/* Index for `getENTNAME'. */
 
 /* Open database file if not already opened.  */
-static int
+static enum nss_status
 internal_setent (int stayopen)
 {
-  int status = NSS_STATUS_SUCCESS;
+  enum nss_status status = NSS_STATUS_SUCCESS;
 
   if (db == NULL)
     {
@@ -78,10 +78,10 @@ internal_setent (int stayopen)
 
 
 /* Thread-safe, exported version of that.  */
-int
+enum nss_status
 CONCAT(_nss_db_set,ENTNAME) (int stayopen)
 {
-  int status;
+  enum nss_status status;
 
   __libc_lock_lock (lock);
 
@@ -109,7 +109,7 @@ internal_endent (void)
 
 
 /* Thread-safe, exported version of that.  */
-int
+enum nss_status
 CONCAT(_nss_db_end,ENTNAME) (void)
 {
   __libc_lock_lock (lock);
diff --git a/nss/nss_db/db-netgrp.c b/nss/nss_db/db-netgrp.c
new file mode 100644
index 0000000000..441a0bdf55
--- /dev/null
+++ b/nss/nss_db/db-netgrp.c
@@ -0,0 +1,108 @@
+/* Netgroup file parser in nss_db modules.
+Copyright (C) 1996 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
+
+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 <db.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <libc-lock.h>
+#include <paths.h>
+#include "nsswitch.h"
+#include "netgroup.h"
+
+
+#define DBFILE		_PATH_VARDB "netgroup.db"
+
+
+/* Locks the static variables in this file.  */
+__libc_lock_define_initialized (static, lock)
+
+/* Maintenance of the shared handle open on the database.  */
+static DB *db;
+static char *entry;
+static char *cursor;
+
+enum nss_status
+_nss_db_setnetgrent (const char *group)
+{
+  enum nss_status status = NSS_STATUS_SUCCESS;
+
+  __libc_lock_lock (lock);
+
+  /* Make sure the data base file is open.  */
+  if (db == NULL)
+    {
+      db = dbopen (DBFILE, O_RDONLY, 0, DB_BTREE, NULL);
+
+      if (db == NULL)
+	status = errno = EAGAIN ? NSS_STATUS_TRYAGAIN : NSS_STATUS_UNAVAIL;
+    }
+
+  if (status == NSS_STATUS_SUCCESS)
+    {
+      DBT key = { data: (void *) group, size: strlen (group) };
+      DBT value;
+
+      if ((*db->get) (db, &key, &value, 0) != 0)
+	status = NSS_STATUS_NOTFOUND;
+      else
+	cursor = entry = value.data;
+    }
+
+  __libc_lock_unlock (lock);
+
+  return status;
+
+}
+
+
+enum nss_status
+_nss_db_endnetgrent (void)
+{
+  __libc_lock_lock (lock);
+
+  if (db != NULL)
+    {
+      (*db->close) (db);
+      db = NULL;
+    }
+
+  __libc_lock_unlock (lock);
+
+  return NSS_STATUS_SUCCESS;
+}
+
+
+extern enum nss_status _nss_netgroup_parseline (char **cursor,
+						struct __netgrent *result,
+						char *buffer, int buflen);
+
+enum nss_status
+_nss_db_getnetgrent_r (struct __netgrent *result, char *buffer, int buflen)
+{
+  int status;
+
+  __libc_lock_lock (lock);
+
+  status = _nss_netgroup_parseline (&cursor, result, buffer, buflen);
+
+  __libc_lock_unlock (lock);
+
+  return status;
+}
diff --git a/nss/nss_dns/dns-network.c b/nss/nss_dns/dns-network.c
index 1b5d0ce71b..a2d9d280a5 100644
--- a/nss/nss_dns/dns-network.c
+++ b/nss/nss_dns/dns-network.c
@@ -236,12 +236,12 @@ getanswer_r (const querybuf *answer, int anslen, struct netent *result,
        OSF/1 has a per-thread h_errno variable.  */
     if (header_pointer->aa != 0)
       {
-	h_errno = HOST_NOT_FOUND;
+	__set_h_errno (HOST_NOT_FOUND);
 	return NSS_STATUS_NOTFOUND;
       }
     else
       {
-	h_errno = TRY_AGAIN;
+	__set_h_errno (TRY_AGAIN);
 	return NSS_STATUS_TRYAGAIN;
       }
 
@@ -338,7 +338,6 @@ getanswer_r (const querybuf *answer, int anslen, struct netent *result,
       return NSS_STATUS_SUCCESS;
     }
 
-  /* XXX Really use global variable??? */
-  h_errno = TRY_AGAIN;
+  __set_h_errno (TRY_AGAIN);
   return NSS_STATUS_TRYAGAIN;
 }
diff --git a/nss/nss_files/files-netgrp.c b/nss/nss_files/files-netgrp.c
new file mode 100644
index 0000000000..8af55f209f
--- /dev/null
+++ b/nss/nss_files/files-netgrp.c
@@ -0,0 +1,262 @@
+/* Netgroup file parser in nss_files modules.
+Copyright (C) 1996 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
+
+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 <ctype.h>
+#include <errno.h>
+#include <libc-lock.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "nsswitch.h"
+#include "netgroup.h"
+
+#define DATAFILE	"/etc/netgroup"
+
+
+/* Locks the static variables in this file.  */
+__libc_lock_define_initialized (static, lock)
+
+/* We share a single place where we store the data for the current
+   netgroup.  This buffer is allocated by `setnetgrent' and freed on
+   the next call of this function or when calling `endnetgrent'.  */
+static char *data;
+static size_t data_size;
+static char *cursor;
+static int first;
+
+
+#define EXPAND(needed)							      \
+  do									      \
+    {									      \
+      size_t old_cursor = cursor - data;				      \
+									      \
+      data_size += 512 > 2 * needed ? 512 : 2 * needed;			      \
+      data = realloc (data, data_size);					      \
+									      \
+      if (data == NULL)							      \
+	{								      \
+	  status = NSS_STATUS_UNAVAIL;					      \
+	  goto the_end;							      \
+	}								      \
+      									      \
+      cursor = data + old_cursor;					      \
+    }									      \
+  while (0)
+
+
+enum nss_status
+_nss_files_setnetgrent (const char *group)
+{
+  FILE *fp;
+  enum nss_status status;
+
+  if (group[0] == '\0')
+    return NSS_STATUS_UNAVAIL;
+
+  __libc_lock_lock (lock);
+
+  /* Find the netgroups file and open it.  */
+  fp = fopen (DATAFILE, "r");
+  if (fp == NULL)
+    status = errno == EAGAIN ? NSS_STATUS_TRYAGAIN : NSS_STATUS_UNAVAIL;
+  else
+    {
+      /* Read the file line by line and try to find the description
+	 GROUP.  We must take care for long lines.  */
+      char *line = NULL;
+      size_t line_len = 0;
+      const ssize_t group_len = strlen (group);
+
+      status = NSS_STATUS_NOTFOUND;
+      cursor = data;
+
+      while (!feof (fp))
+	{
+	  ssize_t curlen = getline (&line, &line_len, fp);
+	  int found;
+
+	  if (curlen < 0)
+	    {
+	      status = NSS_STATUS_NOTFOUND;
+	      break;
+	    }
+
+	  found = (curlen > group_len && strncmp (line, group, group_len) == 0
+		   && isspace (line[group_len]));
+
+	  /* Read the whole line (including continuation) and store it
+	     if FOUND in nonzero.  Otherwise we don't need it.  */
+	  if (found)
+	    {
+	      /* Store the data from the first line.  */
+	      EXPAND (curlen - group_len);
+	      memcpy (cursor, &line[group_len + 1], curlen - group_len);
+	      cursor += (curlen - group_len) - 1;
+	    }
+
+	  while (line[curlen - 1] == '\n' && line[curlen - 2] == '\\')
+	    {
+	      /* Yes, we have a continuation line.  */
+	      if (found)
+		/* Remove these characters from the stored line.  */
+		cursor -= 2;
+
+	      /* Get netxt line.  */
+	      curlen = getline (&line, &line_len, fp);
+	      if (curlen <= 0)
+		break;
+
+	      if (found)
+		{
+		  /* Make sure we have enough room.  */
+		  EXPAND (1 + curlen + 1);
+
+		  /* Add separator in case next line starts immediately.  */
+		  *cursor++ = ' ';
+
+		  /* Copy new line.  */
+		  memcpy (cursor, line, curlen + 1);
+		  cursor += curlen;
+		}
+	    }
+
+	  if (found)
+	    {
+	      /* Now we have read the line.  */
+	      status = NSS_STATUS_SUCCESS;
+	      cursor = data;
+	      first = 1;
+	      break;
+	    }
+	}
+
+    the_end:
+      /* We don't need the file and the line buffer anymore.  */
+      free (line);
+      fclose (fp);
+    }
+
+  __libc_lock_unlock (lock);
+
+  return status;
+}
+
+
+int
+_nss_files_endnetgrent (void)
+{
+  __libc_lock_lock (lock);
+
+  /* Free allocated memory for data if some is present.  */
+  if (data != NULL)
+    {
+      free (data);
+      data = NULL;
+      data_size = 0;
+      cursor = NULL;
+    }
+
+  __libc_lock_unlock (lock);
+
+  return NSS_STATUS_SUCCESS;
+}
+
+
+enum nss_status
+_nss_netgroup_parseline (char **cursor, struct __netgrent *result,
+			 char *buffer, int buflen)
+{
+  enum nss_status status;
+  const char *host, *user, *domain;
+  char *cp = *cursor;
+
+  /* First skip leading spaces.  */
+  while (isspace (*cp))
+    ++cp;
+
+  if (*cp != '(')
+    return first ? NSS_STATUS_NOTFOUND : NSS_STATUS_RETURN;
+
+  /* Match host name.  */
+  host = ++cp;
+  while (*cp != ',')
+    if (*cp++ == '\0')
+      return first ? NSS_STATUS_NOTFOUND : NSS_STATUS_RETURN;
+
+  /* Match user name.  */
+  user = ++cp;
+  while (*cp != ',')
+    if (*cp++ == '\0')
+      return first ? NSS_STATUS_NOTFOUND : NSS_STATUS_RETURN;
+
+  /* Match domain name.  */
+  domain = ++cp;
+  while (*cp != ')')
+    if (*cp++ == '\0')
+      return first ? NSS_STATUS_NOTFOUND : NSS_STATUS_RETURN;
+  ++cp;
+
+
+  /* When we got here we have found an entry.  Before we can copy it
+     to the private buffer we have to make sure it is big enough.  */
+  if (cp - host > buflen)
+    {
+      __set_errno (ERANGE);
+      status = NSS_STATUS_UNAVAIL;
+    }
+  else
+    {
+      memcpy (buffer, host, cp - host);
+
+      buffer[(user - host) - 1] = '\0';
+      result->host = *host == ',' ? NULL : buffer;
+
+      buffer[(domain - host) - 1] = '\0';
+      result->user = *user == ',' ? NULL : buffer + (user - host);
+
+      buffer[(cp - host) - 1] = '\0';
+      result->domain = *domain == ')' ? NULL : buffer + (domain - host);
+
+      status = NSS_STATUS_SUCCESS;
+
+      /* Rememember where we stopped reading.  */
+      *cursor = cp;
+
+      first = 0;
+    }
+
+  return status;
+}
+
+
+enum nss_status
+_nss_files_getnetgrent_r (struct __netgrent *result, char *buffer, int buflen)
+{
+  enum nss_status status;
+
+  __libc_lock_lock (lock);
+
+  status = _nss_netgroup_parseline (&cursor, result, buffer, buflen);
+
+  __libc_lock_unlock (lock);
+
+  return status;
+}
diff --git a/nss/nsswitch.c b/nss/nsswitch.c
index f49ddb95a6..9f27ef80ff 100644
--- a/nss/nsswitch.c
+++ b/nss/nsswitch.c
@@ -158,7 +158,7 @@ __nss_next (service_user **ni, const char *fct_name, void **fctp, int status,
   else
     {
       /* This is really only for debugging.  */
-       if (NSS_STATUS_TRYAGAIN > status || status > NSS_STATUS_SUCCESS)
+       if (NSS_STATUS_TRYAGAIN > status || status > NSS_STATUS_RETURN)
 	 __libc_fatal ("illegal status in " __FUNCTION__);
 
        if (nss_next_action (*ni, status) == NSS_ACTION_RETURN)
@@ -503,6 +503,7 @@ nss_parse_service_list (const char *line)
       new_service->actions[2 + NSS_STATUS_UNAVAIL] = NSS_ACTION_CONTINUE;
       new_service->actions[2 + NSS_STATUS_NOTFOUND] = NSS_ACTION_CONTINUE;
       new_service->actions[2 + NSS_STATUS_SUCCESS] = NSS_ACTION_RETURN;
+      new_service->actions[2 + NSS_STATUS_RETURN] = NSS_ACTION_RETURN;
       new_service->library = NULL;
       new_service->known = NULL;
       new_service->next = NULL;
diff --git a/nss/nsswitch.conf b/nss/nsswitch.conf
index 08bd96ea10..63a78758d6 100644
--- a/nss/nsswitch.conf
+++ b/nss/nsswitch.conf
@@ -14,3 +14,5 @@ protocols:	db files
 services:	db files
 ethers:		db files
 rpc:		db files
+
+netgroup:	db files
diff --git a/nss/nsswitch.h b/nss/nsswitch.h
index 0c99f147fd..df4e0f77f6 100644
--- a/nss/nsswitch.h
+++ b/nss/nsswitch.h
@@ -62,7 +62,7 @@ typedef struct service_user
   /* Name of the service (`files', `dns', `nis', ...).  */
   const char *name;
   /* Action according to result.  */
-  lookup_actions actions[4];
+  lookup_actions actions[5];
   /* Link to the underlying library object.  */
   service_library *library;
   /* Collection of known functions.  */
diff --git a/nsswitch.h b/nsswitch.h
new file mode 100644
index 0000000000..a876d23185
--- /dev/null
+++ b/nsswitch.h
@@ -0,0 +1 @@
+#include <nss/nsswitch.h>
diff --git a/posix/sys/types.h b/posix/sys/types.h
index 55b6fd0f80..234936d12f 100644
--- a/posix/sys/types.h
+++ b/posix/sys/types.h
@@ -30,31 +30,37 @@ __BEGIN_DECLS
 #include <gnu/types.h>
 
 #ifdef	__USE_BSD
-#define u_char __u_char
-#define u_short __u_short
-#define u_int __u_int
-#define u_long __u_long
-#define quad_t __quad_t
-#define u_quad_t __u_quad_t
-#define	fsid_t __fsid_t
+typedef __u_char u_char;
+typedef __u_short u_short;
+typedef __u_int u_int;
+typedef __u_long u_long;
+typedef __quad_t quad_t;
+typedef __u_quad_t u_quad_t;
+typedef __fsid_t fsid_t;
 #endif
 
-#define dev_t __dev_t
-#define gid_t __gid_t
-#define ino_t __ino_t
-#define mode_t __mode_t
-#define nlink_t __nlink_t
-#define off_t __off_t
-#define loff_t __loff_t
-#define pid_t __pid_t
-#define uid_t __uid_t
-#ifndef	ssize_t
-#define	ssize_t	__ssize_t
+typedef __dev_t dev_t;
+typedef __gid_t gid_t;
+typedef __ino_t ino_t;
+typedef __mode_t mode_t;
+typedef __nlink_t nlink_t;
+typedef __off_t off_t;
+typedef __loff_t loff_t;
+typedef __pid_t pid_t;
+typedef __uid_t uid_t;
+
+#ifndef ssize_t
+typedef __ssize_t ssize_t;
+#define ssize_t ssize_t
 #endif
 
 #ifdef	__USE_BSD
-#define daddr_t __daddr_t
-#define caddr_t __caddr_t
+typedef __daddr_t daddr_t;
+typedef __caddr_t caddr_t;
+#endif
+
+#ifdef  __USE_SVID
+typedef __key_t key_t;
 #endif
 
 #define	__need_time_t
@@ -84,8 +90,8 @@ typedef	unsigned int u_int32_t;
 #ifdef __GNUC__
 typedef long long int int64_t;
 typedef unsigned long long int u_int64_t;
-typedef int register_t __attribute__ ((__mode__ (word)));
 #endif
+typedef int register_t;
 
 #else
 
diff --git a/posix/unistd.h b/posix/unistd.h
index 3b7cb0a0fb..2147400d66 100644
--- a/posix/unistd.h
+++ b/posix/unistd.h
@@ -128,7 +128,8 @@ __BEGIN_DECLS
 #include <gnu/types.h>
 
 #ifndef	ssize_t
-#define	ssize_t	__ssize_t
+typedef __ssize_t ssize_t;
+#define	ssize_t	ssize_t
 #endif
 
 #define	__need_size_t
diff --git a/pwd/getpw.c b/pwd/getpw.c
index 0bd2ab9d0d..402fafd7f0 100644
--- a/pwd/getpw.c
+++ b/pwd/getpw.c
@@ -24,8 +24,11 @@ Cambridge, MA 02139, USA.  */
 /* Re-construct the password-file line for the given uid
    in the given buffer.  This knows the format that the caller
    will expect, but this need not be the format of the password file.  */
+
+int __getpw __P ((__uid_t uid, char *buf));
+
 int
-getpw (uid, buf)
+__getpw (uid, buf)
      __uid_t uid;
      register char *buf;
 {
@@ -47,3 +50,4 @@ getpw (uid, buf)
 
   return 0;
 }
+weak_alias (__getpw, getpw)
diff --git a/resolv/base64.c b/resolv/base64.c
index 8b01de33f4..31cd18188f 100644
--- a/resolv/base64.c
+++ b/resolv/base64.c
@@ -280,7 +280,7 @@ b64_pton(src, target, targsize)
 
 		case 2:		/* Valid, means one byte of info */
 			/* Skip any number of spaces. */
-			for (NULL; ch != '\0'; ch = *src++)
+			for ( ; ch != '\0'; ch = *src++)
 				if (!isspace(ch))
 					break;
 			/* Make sure there is another trailing = sign. */
@@ -295,7 +295,7 @@ b64_pton(src, target, targsize)
 			 * We know this char is an =.  Is there anything but
 			 * whitespace after it?
 			 */
-			for (NULL; ch != '\0'; ch = *src++)
+			for ( ; ch != '\0'; ch = *src++)
 				if (!isspace(ch))
 					return (-1);
 
diff --git a/resolv/gethnamaddr.c b/resolv/gethnamaddr.c
index fb51e31003..1cae1f7295 100644
--- a/resolv/gethnamaddr.c
+++ b/resolv/gethnamaddr.c
@@ -145,7 +145,7 @@ dprintf(msg, num)
 		int save = errno;
 
 		printf(msg, num);
-		errno = save;
+		__set_errno (save);
 	}
 }
 #else
@@ -195,12 +195,12 @@ getanswer(answer, anslen, qname, qtype)
 	buflen = sizeof hostbuf;
 	cp = answer->buf + HFIXEDSZ;
 	if (qdcount != 1) {
-		h_errno = NO_RECOVERY;
+		__set_h_errno (NO_RECOVERY);
 		return (NULL);
 	}
 	n = dn_expand(answer->buf, eom, cp, bp, buflen);
 	if ((n < 0) || !(*name_ok)(bp)) {
-		h_errno = NO_RECOVERY;
+		__set_h_errno (NO_RECOVERY);
 		return (NULL);
 	}
 	cp += n + QFIXEDSZ;
@@ -330,7 +330,7 @@ getanswer(answer, anslen, qname, qtype)
 				buflen -= n;
 				map_v4v6_hostent(&host, &bp, &buflen);
 			}
-			h_errno = NETDB_SUCCESS;
+			__set_h_errno (NETDB_SUCCESS);
 			return (&host);
 #endif
 		case T_A:
@@ -403,11 +403,11 @@ getanswer(answer, anslen, qname, qtype)
 		}
 		if (_res.options & RES_USE_INET6)
 			map_v4v6_hostent(&host, &bp, &buflen);
-		h_errno = NETDB_SUCCESS;
+		__set_h_errno (NETDB_SUCCESS);
 		return (&host);
 	}
  try_again:
-	h_errno = TRY_AGAIN;
+	__set_h_errno (TRY_AGAIN);
 	return (NULL);
 }
 
@@ -418,7 +418,7 @@ gethostbyname(name)
 	struct hostent *hp;
 
 	if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
-		h_errno = NETDB_INTERNAL;
+		__set_h_errno (NETDB_INTERNAL);
 		return (NULL);
        }
 	if (_res.options & RES_USE_INET6) {
@@ -441,7 +441,7 @@ gethostbyname2(name, af)
 	extern struct hostent *_gethtbyname2();
 
 	if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
-		h_errno = NETDB_INTERNAL;
+		__set_h_errno (NETDB_INTERNAL);
 		return (NULL);
 	}
 
@@ -455,7 +455,7 @@ gethostbyname2(name, af)
 		type = T_AAAA;
 		break;
 	default:
-		h_errno = NETDB_INTERNAL;
+		__set_h_errno (NETDB_INTERNAL);
 		errno = EAFNOSUPPORT;
 		return (NULL);
 	}
@@ -486,7 +486,7 @@ gethostbyname2(name, af)
 				 * done a lookup.
 				 */
 				if (inet_pton(af, name, host_addr) <= 0) {
-					h_errno = HOST_NOT_FOUND;
+					__set_h_errno (HOST_NOT_FOUND);
 					return (NULL);
 				}
 				strncpy(hostbuf, name, MAXDNAME);
@@ -501,7 +501,7 @@ gethostbyname2(name, af)
 				host.h_addr_list = h_addr_ptrs;
 				if (_res.options & RES_USE_INET6)
 					map_v4v6_hostent(&host, &bp, &len);
-				h_errno = NETDB_SUCCESS;
+				__set_h_errno (NETDB_SUCCESS);
 				return (&host);
 			}
 			if (!isdigit(*cp) && *cp != '.')
@@ -518,7 +518,7 @@ gethostbyname2(name, af)
 				 * done a lookup.
 				 */
 				if (inet_pton(af, name, host_addr) <= 0) {
-					h_errno = HOST_NOT_FOUND;
+					__set_h_errno (HOST_NOT_FOUND);
 					return (NULL);
 				}
 				strncpy(hostbuf, name, MAXDNAME);
@@ -531,7 +531,7 @@ gethostbyname2(name, af)
 				h_addr_ptrs[0] = (char *)host_addr;
 				h_addr_ptrs[1] = NULL;
 				host.h_addr_list = h_addr_ptrs;
-				h_errno = NETDB_SUCCESS;
+				__set_h_errno (NETDB_SUCCESS);
 				return (&host);
 			}
 			if (!isxdigit(*cp) && *cp != ':' && *cp != '.')
@@ -568,7 +568,7 @@ gethostbyaddr(addr, len, af)
 	extern struct hostent *_gethtbyaddr();
 
 	if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
-		h_errno = NETDB_INTERNAL;
+		__set_h_errno (NETDB_INTERNAL);
 		return (NULL);
 	}
 	if (af == AF_INET6 && len == IN6ADDRSZ &&
@@ -588,13 +588,13 @@ gethostbyaddr(addr, len, af)
 		size = IN6ADDRSZ;
 		break;
 	default:
-		errno = EAFNOSUPPORT;
-		h_errno = NETDB_INTERNAL;
+		__set_errno (EAFNOSUPPORT);
+		__set_h_errno (NETDB_INTERNAL);
 		return (NULL);
 	}
 	if (size != len) {
-		errno = EINVAL;
-		h_errno = NETDB_INTERNAL;
+		__set_errno (EINVAL);
+		__set_h_errno (NETDB_INTERNAL);
 		return (NULL);
 	}
 	switch (af) {
@@ -642,7 +642,7 @@ gethostbyaddr(addr, len, af)
 		       "gethostbyaddr: No A record for %s (verifying [%s])",
 		       hname2, inet_ntoa(*((struct in_addr *)addr)));
 		_res.options = old_options;
-		h_errno = HOST_NOT_FOUND;
+		__set_h_errno (HOST_NOT_FOUND);
 		return (NULL);
 	    }
 	    _res.options = old_options;
@@ -653,7 +653,7 @@ gethostbyaddr(addr, len, af)
 		syslog(LOG_NOTICE|LOG_AUTH,
 		       "gethostbyaddr: A record of %s != PTR record [%s]",
 		       hname2, inet_ntoa(*((struct in_addr *)addr)));
-		h_errno = HOST_NOT_FOUND;
+		__set_h_errno (HOST_NOT_FOUND);
 		return (NULL);
 	    }
 	}
@@ -668,7 +668,7 @@ gethostbyaddr(addr, len, af)
 		hp->h_addrtype = AF_INET6;
 		hp->h_length = IN6ADDRSZ;
 	}
-	h_errno = NETDB_SUCCESS;
+	__set_h_errno (NETDB_SUCCESS);
 	return (hp);
 }
 
@@ -700,12 +700,12 @@ _gethtent()
 	int af, len;
 
 	if (!hostf && !(hostf = fopen(_PATH_HOSTS, "r" ))) {
-		h_errno = NETDB_INTERNAL;
+		__set_h_errno (NETDB_INTERNAL);
 		return (NULL);
 	}
  again:
 	if (!(p = fgets(hostbuf, sizeof hostbuf, hostf))) {
-		h_errno = HOST_NOT_FOUND;
+		__set_h_errno (HOST_NOT_FOUND);
 		return (NULL);
 	}
 	if (*p == '#')
@@ -760,7 +760,7 @@ _gethtent()
 
 		map_v4v6_hostent(&host, &bp, &buflen);
 	}
-	h_errno = NETDB_SUCCESS;
+	__set_h_errno (NETDB_SUCCESS);
 	return (&host);
 }
 
diff --git a/resolv/getnetnamadr.c b/resolv/getnetnamadr.c
index 8e503dae12..6f5bf008c7 100644
--- a/resolv/getnetnamadr.c
+++ b/resolv/getnetnamadr.c
@@ -127,9 +127,9 @@ static	char *net_aliases[MAXALIASES], netbuf[BUFSIZ+1];
 	cp = answer->buf + HFIXEDSZ;
 	if (!qdcount) {
 		if (hp->aa)
-			h_errno = HOST_NOT_FOUND;
+			__set_h_errno (HOST_NOT_FOUND);
 		else
-			h_errno = TRY_AGAIN;
+			__set_h_errno (TRY_AGAIN);
 		return (NULL);
 	}
 	while (qdcount-- > 0)
@@ -197,7 +197,7 @@ static	char *net_aliases[MAXALIASES], netbuf[BUFSIZ+1];
 		net_entry.n_aliases++;
 		return (&net_entry);
 	}
-	h_errno = TRY_AGAIN;
+	__set_h_errno (TRY_AGAIN);
 	return (NULL);
 }
 
@@ -267,7 +267,7 @@ getnetbyname(net)
 	struct netent *net_entry;
 
 	if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
-		h_errno = NETDB_INTERNAL;
+		__set_h_errno (NETDB_INTERNAL);
 		return (NULL);
 	}
 	strcpy(&qbuf[0], net);
diff --git a/resolv/inet_neta.c b/resolv/inet_neta.c
index 27908d4a47..324c01b696 100644
--- a/resolv/inet_neta.c
+++ b/resolv/inet_neta.c
@@ -26,6 +26,7 @@ static const char rcsid[] = "$Id$";
 
 #include <errno.h>
 #include <stdio.h>
+#include <string.h>
 
 #ifdef SPRINTF_CHAR
 # define SPRINTF(x) strlen(sprintf/**/x)
diff --git a/resolv/netdb.h b/resolv/netdb.h
index 1269443cb9..954085f97d 100644
--- a/resolv/netdb.h
+++ b/resolv/netdb.h
@@ -52,6 +52,12 @@ extern int __h_errno;
 
 /* Use a macro to access always the thread specific `h_errno' variable.  */
 #define h_errno (*__h_errno_location ())
+
+/* Retain some binary compatibility with old libraries by having both the
+   global variable and the per-thread variable set on error.  */
+#define __set_h_errno(x) (h_errno = __h_errno = (x))
+#else
+#define __set_h_errno(x) (h_errno = (x))
 #endif
 
 /* Possible values left in `h_errno'.  */
@@ -326,6 +332,31 @@ extern struct protoent *getprotobynumber_r __P ((int __proto,
 #endif	/* reentrant */
 
 
+/* Establish network group NETGROUP for enumeration.  */
+extern int setnetgrent __P ((__const char *__netgroup));
+
+/* Free all space allocated by previous `setnetgrent' call.  */
+extern void endnetgrent __P ((void));
+
+/* Get next member of netgroup established by last `setnetgrent' call
+   and return pointers to elements in HOSTP, USERP, and DOMAINP.  */
+extern int getnetgrent __P ((char **__hostp, char **__userp,
+			     char **__domainp));
+
+/* Test whether NETGROUP contains the triple (HOST,USER,DOMAIN).  */
+extern int innetgr __P ((__const char *__netgroup, __const char *__host,
+			 __const char *__user, __const char *domain));
+
+#ifdef	__USE_REENTRANT
+/* Reentrant version of `getnetgrent' where result is placed in BUFFER.  */
+extern int __getnetgrent_r __P ((char **__hostp, char **__userp,
+				 char **__domainp,
+				 char *__buffer, int __buflen));
+extern int getnetgrent_r __P ((char **__hostp, char **__userp,
+			       char **__domainp,
+			       char *__buffer, int __buflen));
+#endif
+
 __END_DECLS
 
 #endif	/* netdb.h */
diff --git a/resolv/res_debug.c b/resolv/res_debug.c
index 842e63c2fb..cc6f84fea1 100644
--- a/resolv/res_debug.c
+++ b/resolv/res_debug.c
@@ -496,7 +496,7 @@ __p_rr(cp, msg, file)
 	char base64_key[MAX_KEY_BASE64];
 
 	if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
-		h_errno = NETDB_INTERNAL;
+		__set_h_errno (NETDB_INTERNAL);
 		return (NULL);
 	}
 	cp = __p_fqnname(cp, msg, MAXCDNAME, rrname, sizeof rrname);
diff --git a/resolv/res_mkquery.c b/resolv/res_mkquery.c
index 505c3914a9..d894a8b991 100644
--- a/resolv/res_mkquery.c
+++ b/resolv/res_mkquery.c
@@ -97,7 +97,7 @@ res_mkquery(op, dname, class, type, data, datalen, newrr_in, buf, buflen)
 	u_char *dnptrs[20], **dpp, **lastdnptr;
 
 	if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
-		h_errno = NETDB_INTERNAL;
+		__set_h_errno (NETDB_INTERNAL);
 		return (-1);
 	}
 #ifdef DEBUG
diff --git a/resolv/res_query.c b/resolv/res_query.c
index ac50a9c7c5..3ddeb20bb2 100644
--- a/resolv/res_query.c
+++ b/resolv/res_query.c
@@ -113,7 +113,7 @@ res_query(name, class, type, answer, anslen)
 	hp->rcode = NOERROR;	/* default */
 
 	if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
-		h_errno = NETDB_INTERNAL;
+		__set_h_errno (NETDB_INTERNAL);
 		return (-1);
 	}
 #ifdef DEBUG
@@ -128,7 +128,7 @@ res_query(name, class, type, answer, anslen)
 		if (_res.options & RES_DEBUG)
 			printf(";; res_query: mkquery failed\n");
 #endif
-		h_errno = NO_RECOVERY;
+		__set_h_errno (NO_RECOVERY);
 		return (n);
 	}
 	n = res_send(buf, n, answer, anslen);
@@ -137,7 +137,7 @@ res_query(name, class, type, answer, anslen)
 		if (_res.options & RES_DEBUG)
 			printf(";; res_query: send error\n");
 #endif
-		h_errno = TRY_AGAIN;
+		__set_h_errno (TRY_AGAIN);
 		return (n);
 	}
 
@@ -149,19 +149,19 @@ res_query(name, class, type, answer, anslen)
 #endif
 		switch (hp->rcode) {
 		case NXDOMAIN:
-			h_errno = HOST_NOT_FOUND;
+			__set_h_errno (HOST_NOT_FOUND);
 			break;
 		case SERVFAIL:
-			h_errno = TRY_AGAIN;
+			__set_h_errno (TRY_AGAIN);
 			break;
 		case NOERROR:
-			h_errno = NO_DATA;
+			__set_h_errno (NO_DATA);
 			break;
 		case FORMERR:
 		case NOTIMP:
 		case REFUSED:
 		default:
-			h_errno = NO_RECOVERY;
+			__set_h_errno (NO_RECOVERY);
 			break;
 		}
 		return (-1);
@@ -189,11 +189,11 @@ res_search(name, class, type, answer, anslen)
 	int got_nodata = 0, got_servfail = 0, tried_as_is = 0;
 
 	if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
-		h_errno = NETDB_INTERNAL;
+		__set_h_errno (NETDB_INTERNAL);
 		return (-1);
 	}
 	__set_errno (0);
-	h_errno = HOST_NOT_FOUND;	/* default, if we never query */
+	__set_h_errno (HOST_NOT_FOUND);	/* default, if we never query */
 	dots = 0;
 	for (cp = name; *cp; cp++)
 		dots += (*cp == '.');
@@ -253,7 +253,7 @@ res_search(name, class, type, answer, anslen)
 			 * fully-qualified.
 			 */
 			if (errno == ECONNREFUSED) {
-				h_errno = TRY_AGAIN;
+				__set_h_errno (TRY_AGAIN);
 				return (-1);
 			}
 
@@ -302,11 +302,11 @@ res_search(name, class, type, answer, anslen)
 	 * the last DNSRCH we did.
 	 */
 	if (saved_herrno != -1)
-		h_errno = saved_herrno;
+		__set_h_errno (saved_herrno);
 	else if (got_nodata)
-		h_errno = NO_DATA;
+		__set_h_errno (NO_DATA);
 	else if (got_servfail)
-		h_errno = TRY_AGAIN;
+		__set_h_errno (TRY_AGAIN);
 	return (-1);
 }
 
@@ -326,7 +326,7 @@ res_querydomain(name, domain, class, type, answer, anslen)
 	int n;
 
 	if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
-		h_errno = NETDB_INTERNAL;
+		__set_h_errno (NETDB_INTERNAL);
 		return (-1);
 	}
 #ifdef DEBUG
diff --git a/stdio-common/getline.c b/stdio-common/getline.c
index 7e78547c90..518398e055 100644
--- a/stdio-common/getline.c
+++ b/stdio-common/getline.c
@@ -23,6 +23,7 @@ Cambridge, MA 02139, USA.  */
 
 #ifdef USE_IN_LIBIO
 # include "../libio/libioP.h"
+# undef ssize_t
 # define ssize_t _IO_ssize_t
 # define __getdelim _IO_getdelim
 #endif
diff --git a/stdio-common/reg-printf.c b/stdio-common/reg-printf.c
index 2cb086dedf..519eec20ac 100644
--- a/stdio-common/reg-printf.c
+++ b/stdio-common/reg-printf.c
@@ -26,6 +26,9 @@ printf_arginfo_function *__printf_arginfo_table[UCHAR_MAX + 1];
 
 printf_function **__printf_function_table;
 
+int __register_printf_function __P ((int, printf_function,
+                                     printf_arginfo_function));
+
 /* Register FUNC to be called to format SPEC specifiers.  */
 int
 __register_printf_function (spec, converter, arginfo)
diff --git a/stdio-common/scanf.c b/stdio-common/scanf.c
index 8e9b90f3e7..29c9efb1c3 100644
--- a/stdio-common/scanf.c
+++ b/stdio-common/scanf.c
@@ -23,6 +23,7 @@ Cambridge, MA 02139, USA.  */
    use the protected form here.  In stdio it is called `__vscanf' and
    in libio `_IO_vscanf'.  */
 #ifdef USE_IN_LIBIO
+# include <libioP.h>
 # define VSCANF _IO_vscanf
 #else
 # define VSCANF __vscanf
diff --git a/stdio-common/tmpnam.c b/stdio-common/tmpnam.c
index 44397bc3f2..0f2199ea60 100644
--- a/stdio-common/tmpnam.c
+++ b/stdio-common/tmpnam.c
@@ -29,7 +29,7 @@ tmpnam (char *s)
   /* By using two buffers we manage to be thread safe in the case
      where S != NULL.  */
   static char buf[L_tmpnam];
-  char *tmpbuf[L_tmpnam];
+  char tmpbuf[L_tmpnam];
   char *result;
 
   /* In the following call we use the buffer pointed to by S if
diff --git a/stdio-common/tstgetln.c b/stdio-common/tstgetln.c
index a35be272e9..a76317e069 100644
--- a/stdio-common/tstgetln.c
+++ b/stdio-common/tstgetln.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992, 1995 Free Software Foundation, Inc.
+/* Copyright (C) 1992, 1995, 1996 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
@@ -16,15 +16,15 @@ License along with the GNU C Library; see the file COPYING.LIB.  If
 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
 Cambridge, MA 02139, USA.  */
 
-#include <ansidecl.h>
 #include <stdio.h>
 
 #ifdef USE_IN_LIBIO
+# undef ssize_t
 # define ssize_t _IO_ssize_t
 #endif
 
 int
-DEFUN_VOID(main)
+main ()
 {
   char *buf = NULL;
   size_t size = 0;
diff --git a/stdio-common/vfprintf.c b/stdio-common/vfprintf.c
index f47eaa2850..7714c0e67f 100644
--- a/stdio-common/vfprintf.c
+++ b/stdio-common/vfprintf.c
@@ -87,6 +87,7 @@ ssize_t __wprintf_pad __P ((FILE *, wchar_t pad, size_t n));
 # define PUTC(C, F)	_IO_putc_unlocked (C, F)
 # define vfprintf	_IO_vfprintf
 # define FILE		_IO_FILE
+# undef va_list
 # define va_list	_IO_va_list
 # undef	BUFSIZ
 # define BUFSIZ		_IO_BUFSIZ
diff --git a/stdio-common/vfscanf.c b/stdio-common/vfscanf.c
index ee2c922f6e..5564e2b0e6 100644
--- a/stdio-common/vfscanf.c
+++ b/stdio-common/vfscanf.c
@@ -51,6 +51,7 @@ Cambridge, MA 02139, USA.  */
 # include <libioP.h>
 # include <libio.h>
 
+# undef va_list
 # define va_list	_IO_va_list
 # define ungetc(c, s)	(--read_in, _IO_ungetc (c, s))
 # define inchar()	((c = _IO_getc_unlocked (s)), (void) ++read_in, c)
diff --git a/string/tester.c b/string/tester.c
index d376db2a67..b815539737 100644
--- a/string/tester.c
+++ b/string/tester.c
@@ -215,7 +215,7 @@ DEFUN(main, (argc, argv), int argc AND char **argv)
     char *p;
     for (i=0; i < 0x100; i++)
       {
-	p = (char *)((int)(buf + 0xff) & ~0xff) + i;
+	p = (char *)((unsigned long int)(buf + 0xff) & ~0xff) + i;
 	strcpy (p, "OK");
 	strcpy (p+3, "BAD/WRONG");
 	check(strlen(p) == 2, 4+i);
@@ -241,7 +241,7 @@ DEFUN(main, (argc, argv), int argc AND char **argv)
     char *p;
     for (i=0; i < 0x100; i++)
       {
-	p = (char *)((int)(buf + 0xff) & ~0xff) + i;
+	p = (char *)((unsigned long int)(buf + 0xff) & ~0xff) + i;
 	strcpy (p, "OK");
 	strcpy (p+3, "BAD/WRONG");
 	check(strchr(p, '/') == NULL, 9+i);
@@ -283,7 +283,7 @@ DEFUN(main, (argc, argv), int argc AND char **argv)
     char *p;
     for (i=0; i < 0x100; i++)
       {
-	p = (char *)((int)(buf + 0xff) & ~0xff) + i;
+	p = (char *)((unsigned long int)(buf + 0xff) & ~0xff) + i;
 	strcpy (p, "OK");
 	strcpy (p+3, "BAD/WRONG");
 	check(strrchr(p, '/') == NULL, 9+i);
diff --git a/sysdeps/alpha/machine-gmon.h b/sysdeps/alpha/machine-gmon.h
index a551e9f8b1..e902537dd6 100644
--- a/sysdeps/alpha/machine-gmon.h
+++ b/sysdeps/alpha/machine-gmon.h
@@ -1,5 +1,5 @@
 /* Machine-specific calling sequence for `mcount' profiling function.  alpha
-Copyright (C) 1995 Free Software Foundation, Inc.
+Copyright (C) 1995, 1996 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
@@ -17,7 +17,8 @@ License along with the GNU C Library; see the file COPYING.LIB.  If
 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
 Cambridge, MA 02139, USA.  */
 
-#define _MCOUNT_DECL void __mcount
+#define _MCOUNT_DECL(from, self) \
+ void __mcount (u_long from, u_long self)
 
 /* Call __mcount with our the return PC for our caller, and the return
    PC our caller will return to.  Empty since we use an assembly stub
diff --git a/sysdeps/generic/gnu/types.h b/sysdeps/generic/gnu/types.h
index 614252aaac..f42fb7f544 100644
--- a/sysdeps/generic/gnu/types.h
+++ b/sysdeps/generic/gnu/types.h
@@ -57,6 +57,7 @@ typedef long int __daddr_t;	/* The type of a disk address.  */
 typedef char *__caddr_t;
 typedef long int __time_t;
 typedef long int __swblk_t;	/* Type of a swap block maybe?  */
+typedef long int __key_t;	/* Type of an IPC key */
 
 /* fd_set for select.  */
 
diff --git a/sysdeps/generic/machine-gmon.h b/sysdeps/generic/machine-gmon.h
index 43bf62d663..31f852dece 100644
--- a/sysdeps/generic/machine-gmon.h
+++ b/sysdeps/generic/machine-gmon.h
@@ -41,7 +41,7 @@ weak_alias (_mcount, mcount)
 static void mcount_internal (u_long frompc, u_long selfpc);
 
 #define _MCOUNT_DECL(frompc, selfpc) \
-static inline void mcount_internal (frompc, selfpc)
+static inline void mcount_internal (u_long frompc, u_long selfpc)
 
 #define MCOUNT \
 void _mcount (void)							      \
diff --git a/sysdeps/generic/pty.c b/sysdeps/generic/pty.c
index 6995417d3a..8df8aba4ba 100644
--- a/sysdeps/generic/pty.c
+++ b/sysdeps/generic/pty.c
@@ -47,6 +47,7 @@ static char sccsid[] = "@(#)pty.c	8.1 (Berkeley) 6/4/93";
 #include <string.h>
 #include <grp.h>
 #include <pty.h>
+#include <utmp.h>
 
 int
 openpty(amaster, aslave, name, termp, winp)
@@ -106,7 +107,6 @@ forkpty(amaster, name, termp, winp)
 	struct termios *termp;
 	struct winsize *winp;
 {
-	extern int login_tty __P ((int fd));
 	int master, slave, pid;
 
 	if (openpty(&master, &slave, name, termp, winp) == -1)
diff --git a/sysdeps/generic/strtok.c b/sysdeps/generic/strtok.c
index cb30619a43..4f89efa6f0 100644
--- a/sysdeps/generic/strtok.c
+++ b/sysdeps/generic/strtok.c
@@ -53,7 +53,7 @@ strtok (s, delim)
   s = strpbrk (token, delim);
   if (s == NULL)
     /* This token finishes the string.  */
-    olds = NULL;
+    olds = strchr (token, '\0');
   else
     {
       /* Terminate the token and make OLDS point past it.  */
diff --git a/sysdeps/generic/strtok_r.c b/sysdeps/generic/strtok_r.c
index 488d3eacfe..870fb274eb 100644
--- a/sysdeps/generic/strtok_r.c
+++ b/sysdeps/generic/strtok_r.c
@@ -54,7 +54,7 @@ strtok_r (s, delim, save_ptr)
   s = strpbrk (token, delim);
   if (s == NULL)
     /* This token finishes the string.  */
-    *save_ptr = NULL;
+    *save_ptr = strchr (token, '\0');
   else
     {
       /* Terminate the token and make *SAVE_PTR point past it.  */
diff --git a/sysdeps/gnu/errlist.awk b/sysdeps/gnu/errlist.awk
index c68e70df9a..a640fe5a11 100644
--- a/sysdeps/gnu/errlist.awk
+++ b/sysdeps/gnu/errlist.awk
@@ -32,7 +32,7 @@ BEGIN {
     print "";
     print "#include <errno.h>";
     print "";
-    print "const char *_sys_errlist[] =";
+    print "const char *const _sys_errlist[] =";
     print "  {";
     print "    [0] = N_(\"Success\"),"
   }
diff --git a/sysdeps/gnu/errlist.c b/sysdeps/gnu/errlist.c
index 85ae7f11ac..3e62c5f127 100644
--- a/sysdeps/gnu/errlist.c
+++ b/sysdeps/gnu/errlist.c
@@ -2,7 +2,7 @@
 
 #include <errno.h>
 
-const char *_sys_errlist[] =
+const char *const _sys_errlist[] =
   {
     [0] = N_("Success"),
 #ifdef EPERM
diff --git a/sysdeps/posix/euidaccess.c b/sysdeps/posix/euidaccess.c
index 26f3af6374..f3a10c9b9c 100644
--- a/sysdeps/posix/euidaccess.c
+++ b/sysdeps/posix/euidaccess.c
@@ -67,7 +67,7 @@ gid_t getegid ();
 extern int errno;
 #endif
 #ifndef __set_errno
-#define __set_errno(val) errno = 8val)
+#define __set_errno(val) errno = (val)
 #endif
 
 #if defined(EACCES) && !defined(EACCESS)
diff --git a/sysdeps/posix/sigvec.c b/sysdeps/posix/sigvec.c
index 6a224e1733..7e9aeb368e 100644
--- a/sysdeps/posix/sigvec.c
+++ b/sysdeps/posix/sigvec.c
@@ -26,6 +26,9 @@ Cambridge, MA 02139, USA.  */
 static __sighandler_t wrapped_handlers[NSIG];
 static sigset_t wrapped_masks[NSIG];
 
+static void wrapper_handler __P ((int sig));
+static inline int convert_mask __P ((sigset_t *set, const int mask));
+
 static void
 wrapper_handler (sig)
      int sig;
diff --git a/sysdeps/posix/tempname.c b/sysdeps/posix/tempname.c
index d58024fe7e..61774a0b3e 100644
--- a/sysdeps/posix/tempname.c
+++ b/sysdeps/posix/tempname.c
@@ -150,7 +150,7 @@ __stdio_gen_tempname (char *buf, size_t bufsize, const char *dir,
   len = dlen + 1 + plen + 5 + 3;
   while (1)
     {
-      const size_t i;
+      size_t i;
 
       if (*idx >= ((sizeof (letters) - 1) * (sizeof (letters) - 1) *
 		   (sizeof (letters) - 1)))
@@ -193,11 +193,18 @@ __stdio_gen_tempname (char *buf, size_t bufsize, const char *dir,
 		 Create a stream for it.  */
 #ifdef USE_IN_LIBIO
 	      int save;
+	      struct locked_FILE
+		{
+		  struct _IO_FILE_plus fp;
+#ifdef _IO_MTSAFE_IO
+		  _IO_lock_t lock;
+#endif
+		} *new_f;
 	      struct _IO_FILE_plus *fp;
 
-	      fp = (struct _IO_FILE_plus *)
-		malloc (sizeof (struct _IO_FILE_plus));
-	      if (fp == NULL)
+	      new_f = (struct locked_FILE *)
+		malloc (sizeof (struct locked_FILE));
+	      if (new_f == NULL)
 		{
 		  /* We lost trying to create a stream (out of memory?).
 		     Nothing to do but remove the file, close the descriptor,
@@ -209,6 +216,10 @@ __stdio_gen_tempname (char *buf, size_t bufsize, const char *dir,
 		  __set_errno (save);
 		  return NULL;
 		}
+	      fp = &new_f->fp;
+#ifdef _IO_MTSAFE_IO
+	      fp->file._lock = &new_f->lock;
+#endif
 	      _IO_init (&fp->file, 0);
 	      _IO_JUMPS (&fp->file) = &_IO_file_jumps;
 	      _IO_file_init (&fp->file);
diff --git a/sysdeps/stub/chflags.c b/sysdeps/stub/chflags.c
index 9380108283..18100cad90 100644
--- a/sysdeps/stub/chflags.c
+++ b/sysdeps/stub/chflags.c
@@ -21,6 +21,9 @@ Cambridge, MA 02139, USA.  */
 #include <sys/stat.h>
 
 /* Change the flags of FILE to FLAGS.  */
+
+int chflags __P ((const char *file, int flags));
+
 int
 chflags (file, flags)
      const char *file;
diff --git a/sysdeps/stub/fchflags.c b/sysdeps/stub/fchflags.c
index 4f59ad3480..21a66e8bd5 100644
--- a/sysdeps/stub/fchflags.c
+++ b/sysdeps/stub/fchflags.c
@@ -21,6 +21,9 @@ Cambridge, MA 02139, USA.  */
 #include <sys/stat.h>
 
 /* Change the flags of the file FD refers to to FLAGS.  */
+
+int fchflags __P ((int fd, int flags));
+
 int
 fchflags (fd, flags)
      int fd;
diff --git a/sysdeps/stub/sstk.c b/sysdeps/stub/sstk.c
index d7486737fa..aa1bfb2e73 100644
--- a/sysdeps/stub/sstk.c
+++ b/sysdeps/stub/sstk.c
@@ -20,6 +20,9 @@ Cambridge, MA 02139, USA.  */
 
 /* Increase the size of the stack by INCREMENT,
    and return the address of the bottom of the stack.  */
+
+void *sstk __P ((int increment));
+
 void *
 sstk (increment)
      int increment;
diff --git a/sysdeps/unix/Makefile b/sysdeps/unix/Makefile
index d3cc46ab31..78eecd5296 100644
--- a/sysdeps/unix/Makefile
+++ b/sysdeps/unix/Makefile
@@ -302,7 +302,8 @@ ifndef no_deps
 endif
 endif
 
-$(common-objpfx)s-proto.d: $(..)sysdeps/unix/s-proto.S $(before-compile)
+$(common-objpfx)s-proto.d: $(common-objpfx)%.d: $(..)sysdeps/unix/%.S \
+			   $(before-compile)
 	$(+make-deps)
 
 endif
diff --git a/sysdeps/unix/alpha/sysdep.S b/sysdeps/unix/alpha/sysdep.S
index 8d70bda21e..08dc3b4851 100644
--- a/sysdeps/unix/alpha/sysdep.S
+++ b/sysdeps/unix/alpha/sysdep.S
@@ -27,6 +27,8 @@ errno:	.space 4
 	.type errno, @object
 	.size errno, 4
 #endif
+	.globl __errno
+__errno = errno
 
 	.text
 	.align 2
@@ -44,7 +46,10 @@ __syscall_error:
 	.mask	0x4000001, -16
 	.prologue 1
 
-	/* Find our pre-thread errno address  */
+	/* Store into the "real" variable.  */
+	stl	v0, errno
+
+	/* Find our per-thread errno address  */
 	jsr	ra, __errno_location
 
 	/* Store the error value.  */
diff --git a/sysdeps/unix/readdir.c b/sysdeps/unix/readdir.c
index 491469bcd1..97956ecd06 100644
--- a/sysdeps/unix/readdir.c
+++ b/sysdeps/unix/readdir.c
@@ -34,12 +34,6 @@ __readdir (DIR *dirp)
 {
   struct dirent *dp;
 
-  if (dirp == NULL || dirp->data == NULL)
-    {
-      __set_errno (EINVAL);
-      return NULL;
-    }
-
   __libc_lock_lock (dirp->lock);
 
   do
diff --git a/sysdeps/unix/readdir_r.c b/sysdeps/unix/readdir_r.c
new file mode 100644
index 0000000000..ef75c36234
--- /dev/null
+++ b/sysdeps/unix/readdir_r.c
@@ -0,0 +1,108 @@
+/* Copyright (C) 1991, 92, 93, 94, 95, 96 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., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <errno.h>
+#include <limits.h>
+#include <stddef.h>
+#include <string.h>
+#include <dirent.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <assert.h>
+
+#include <dirstream.h>
+
+
+/* Read a directory entry from DIRP.  */
+int
+__readdir_r (DIR *dirp, struct dirent *entry, struct dirent **result)
+{
+  struct dirent *dp;
+
+  __libc_lock_lock (dirp->lock);
+
+  do
+    {
+      size_t reclen;
+
+      if (dirp->offset >= dirp->size)
+	{
+	  /* We've emptied out our buffer.  Refill it.  */
+
+	  size_t maxread;
+	  off_t base;
+	  ssize_t bytes;
+
+#ifndef _DIRENT_HAVE_D_RECLEN
+	  /* Fixed-size struct; must read one at a time (see below).  */
+	  maxread = sizeof *dp;
+#else
+	  maxread = dirp->allocation;
+#endif
+
+	  base = dirp->filepos;
+	  bytes = __getdirentries (dirp->fd, dirp->data, maxread, &base);
+	  if (bytes <= 0)
+	    {
+	      dp = NULL;
+	      break;
+	    }
+	  dirp->size = (size_t) bytes;
+
+	  /* Reset the offset into the buffer.  */
+	  dirp->offset = 0;
+	}
+
+      dp = (struct dirent *) &dirp->data[dirp->offset];
+
+#ifdef _DIRENT_HAVE_D_RECLEN
+      reclen = dp->d_reclen;
+#else
+      /* The only version of `struct dirent' that lacks `d_reclen'
+	 is fixed-size.  */
+      assert (sizeof dp->d_name > 1);
+      reclen = sizeof *dp;
+      /* The name is not terminated if it is the largest possible size.
+	 Clobber the following byte to ensure proper null termination.  We
+	 read just one entry at a time above so we know that byte will not
+	 be used later.  */
+      dp->d_name[sizeof dp->d_name] = '\0';
+#endif
+
+      dirp->offset += reclen;
+
+#ifdef _DIRENT_HAVE_D_OFF
+      dirp->filepos = dp->d_off;
+#else
+      dirp->filepos += reclen;
+#endif
+
+      /* Skip deleted files.  */
+    } while (dp->d_ino == 0);
+
+  if (dp != NULL)
+    {
+      *entry = *dp;
+      *result = entry;
+    }
+
+  __libc_lock_unlock (dirp->lock);
+
+  return dp != NULL ? 0 : -1;
+}
+weak_alias (__readdir_r, readdir_r)
diff --git a/sysdeps/unix/sysv/linux/gnu/types.h b/sysdeps/unix/sysv/linux/gnu/types.h
index 745d2d8e2e..5495b61aa4 100644
--- a/sysdeps/unix/sysv/linux/gnu/types.h
+++ b/sysdeps/unix/sysv/linux/gnu/types.h
@@ -71,7 +71,7 @@ typedef __kernel_clock_t __clock_t;
 typedef unsigned long __fd_mask;
 
 #ifdef	__USE_SVID
-typedef int key_t;
+typedef int __key_t;
 #endif
 
 #endif /* gnu/types.h */
diff --git a/sysdeps/unix/sysv/linux/init-first.c b/sysdeps/unix/sysv/linux/init-first.c
index 75ada19610..6e1d71204c 100644
--- a/sysdeps/unix/sysv/linux/init-first.c
+++ b/sysdeps/unix/sysv/linux/init-first.c
@@ -21,7 +21,7 @@ Cambridge, MA 02139, USA.  */
 #include <sysdep.h>
 #include <fpu_control.h>
 #include <linux/personality.h>
-#include "init-first.h"
+#include <init-first.h>
 
 extern void __libc_init (int, char **, char **);
 extern void __libc_global_ctors (void);
@@ -95,7 +95,7 @@ SYSDEP_CALL_INIT(__libc_init_first, init);
    cause ld.so to gain an init function, which is not a cool thing. */
 
 void
-_dl_start ()
+_dl_start (void)
 {
   abort ();
 }
diff --git a/sysdeps/unix/sysv/linux/syscalls.list b/sysdeps/unix/sysv/linux/syscalls.list
index f831b41072..1dd2f4d7e7 100644
--- a/sysdeps/unix/sysv/linux/syscalls.list
+++ b/sysdeps/unix/sysv/linux/syscalls.list
@@ -19,7 +19,7 @@ ioperm		-	ioperm		3	ioperm
 iopl		-	iopl		1	iopl
 ipc		msgget	ipc		5	__ipc
 klogctl		EXTRA	syslog		3	klogctl
-llseek		EXTRA	_llseek		5	llseek
+llseek		EXTRA	_llseek		5	_llseek
 mlock		EXTRA	mlock		2	__mlock	mlock
 mlockall	EXTRA	mlockall	1	__mlockall	mlockall
 mount		EXTRA	mount		5	__mount	mount