about summary refs log tree commit diff
path: root/nss
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>1996-11-14 02:04:07 +0000
committerUlrich Drepper <drepper@redhat.com>1996-11-14 02:04:07 +0000
commit26761c287fdf4a9997b7c62b5c64cec84ce2c329 (patch)
tree2f7ac77185952d09a03a988f3176e18e476fe7ee /nss
parentb8591d1bdf48f5560a3a8e1326758a5aa5e529cf (diff)
downloadglibc-26761c287fdf4a9997b7c62b5c64cec84ce2c329.tar.gz
glibc-26761c287fdf4a9997b7c62b5c64cec84ce2c329.tar.xz
glibc-26761c287fdf4a9997b7c62b5c64cec84ce2c329.zip
update from main archive 961113
Thu Nov 14 02:00:33 1996  Ulrich Drepper  <drepper@cygnus.com>

	* inet/Makefile (headers): Add aliases.h.
	(routines): Add getaliasent_r, getaliasent, getaliasname, and
	getaliasname_r.
	* aliases.h: New file.
	* inet/aliases.h: New file.
	* inet/getaliasent.c: New file.
	* inet/getaliasent_r.c: New file.
	* inet/getaliasname.c: New file.
	* inet/getaliasname_r.c: New file.
	* nss/Makefile (databases): Add alias.
	* nss/alias-lookup.c: New file.
	* nss/databases.def: Add aliases and publickey.
	* nss/nss_db/db-alias.c: New file.
	* nss/nss_files/files-alias.c: New file.

	* inet/getnetgrent_r.c (__internal_getnetgrent): Buffer length
	argument to lookup function is of type size_t.
	(innetgr): Likewise.
	* nss/getXXbyYY_r.c: Likewise.
	* nss/getXXent_r.c: Likewise.
	* nss/nss_db/db-XXX.c: Likewise.

	* nss/getXXbyYY.c: Don't provide static buffer.  Resize if call
	failed because buffer was too small.
	* nss/getXXent.c: Likewise.

	* nss/nss_files/files-XXX.c: Correct handling of shared file.  The
	getXXent_r function now uses f[gs]etpos to get to the correct
	position.

	* nss/nss_files/files-parse.c: Indent lines for better readability.

	* malloc/obstack.c: Add new variable obstack_alloc_failed_handler
	and new function print_and_abort.  Remove all references to
	alloc_failed field.
	Add new function _obstack_memory_used.
	* malloc/obstack.h (struct obstack): Remove field alloc_field.
	Remove all references to alloc_failed field.
	Add prototype for _obstack_memory_used.

	* posix/unistd.h: Correct typo.

Wed Nov 13 03:09:16 1996  Ulrich Drepper  <drepper@cygnus.com>

	* configure.in: Require at least autoconf-2.10.2.

Tue Nov 12 03:35:01 1996  Christian von Roques  <roques@pond.sub.org>

	* malloc/obstack.h: Add new macro `obstack_make_room'.
	* malloc/obstack.c: Add function implementation for
	`obstack_make_room'.

Mon Nov 11 13:54:04 1996  Ulrich Drepper  <drepper@cygnus.com>

	Update to BIND-4.9.5-REL.
	* resolv/Banner: Set to 4.9.5-REL.
	* resolv/inet_net_pton.c: Was doing bad things to subnets and b'casts.
	* resolv/res_debug.c (__fp_nquery): Could read past end of buffer.
	(fix from BIND 8.1)

	* config.make.in: Add definition for top_absdir.
	* Makerules (make-link): Fix path to rellns-sh script.

Sat Nov  9 02:15:24 1996  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>

	* posix/unistd.h: Fix comment.

	* manual/arith.texi: Fix misspellings.  Use `zero', not `null',
	when talking about numbers.
	* manual/users.texi: Likewise.
	* manual/creature.texi: Likewise.  Use @defvarx for a secondary
	description header.

Sat Nov  9 19:25:11 1996  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>

	* sysdeps/posix/Makefile ($(common-objpfx)mk-stdiolim): Depend on
	the real posix1_lim.h file so that it works in all subdirs, not
	only in posix.

Sat Nov  9 02:08:34 1996  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>

	* Makefile ($(includedir)/gnu/lib-names.h): Quote arguments of tr.

Sat Nov  9 02:06:17 1996  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>

	* sysdeps/unix/Makefile ($(common-objpfx)s-proto.d): Don't depend
	on $(before-compile) which hasn't been properly setup yet at this
	point.

Sat Nov  9 02:02:48 1996  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>

	* sysdeps/generic/sigset.h: Don't use implicit int which will
	probably require a diagnostic in the next revision of the C
	standard.
	* sysdeps/stub/lockfile.c: Likewise.

Sat Nov  9 01:57:17 1996  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>

	* sysdeps/unix/sysv/linux/m68k/syscall.S: Correct last change.
	* sysdeps/unix/sysv/linux/m68k/sysdep.h: Likewise.

Mon Nov 11 02:53:14 1996  Ulrich Drepper  <drepper@cygnus.com>

	* time/strftime.c: Update copyright.  Small cosmetic changes.

	char *' and `int'.
	PROJ_ID are used.
Diffstat (limited to 'nss')
-rw-r--r--nss/Makefile8
-rw-r--r--nss/alias-lookup.c22
-rw-r--r--nss/databases.def32
-rw-r--r--nss/getXXbyYY.c72
-rw-r--r--nss/getXXbyYY_r.c2
-rw-r--r--nss/getXXent.c71
-rw-r--r--nss/getXXent_r.c2
-rw-r--r--nss/nss_db/db-XXX.c32
-rw-r--r--nss/nss_db/db-alias.c235
-rw-r--r--nss/nss_files/files-XXX.c120
-rw-r--r--nss/nss_files/files-alias.c424
-rw-r--r--nss/nss_files/files-parse.c42
12 files changed, 914 insertions, 148 deletions
diff --git a/nss/Makefile b/nss/Makefile
index 93ffbaee34..9193cf2214 100644
--- a/nss/Makefile
+++ b/nss/Makefile
@@ -12,9 +12,9 @@
 # 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.
+# 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.
 
 #
 #	Makefile for name service switch.
@@ -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 netgrp key
+			  spwd netgrp key alias
 
 # Specify rules for the nss_* modules.  We have some services.
 services		:= files dns db
diff --git a/nss/alias-lookup.c b/nss/alias-lookup.c
new file mode 100644
index 0000000000..6a1244eea7
--- /dev/null
+++ b/nss/alias-lookup.c
@@ -0,0 +1,22 @@
+/* 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.  */
+
+#define DATABASE_NAME aliases
+
+#include "XXX-lookup.c"
diff --git a/nss/databases.def b/nss/databases.def
index 8a5ede2a58..2ab892258d 100644
--- a/nss/databases.def
+++ b/nss/databases.def
@@ -1,25 +1,26 @@
 /* List of all databases defined for the NSS in GNU C Library.
-Copyright (C) 1996 Free Software Foundation, Inc.
-This file is part of the GNU C Library.
-Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
+   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 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.
+   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.  */
+   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.  */
 
 /* This list must be kept sorted!!!  */
 
+DEFINE_DATABASE (aliases)
 DEFINE_DATABASE (ethers)
 DEFINE_DATABASE (group)
 DEFINE_DATABASE (hosts)
@@ -27,6 +28,7 @@ DEFINE_DATABASE (netgroup)
 DEFINE_DATABASE (networks)
 DEFINE_DATABASE (passwd)
 DEFINE_DATABASE (protocols)
+DEFINE_DATABASE (publickey)
 DEFINE_DATABASE (rpc)
 DEFINE_DATABASE (services)
 DEFINE_DATABASE (shadow)
diff --git a/nss/getXXbyYY.c b/nss/getXXbyYY.c
index c300117b8c..2a84db974a 100644
--- a/nss/getXXbyYY.c
+++ b/nss/getXXbyYY.c
@@ -1,22 +1,26 @@
 /* Copyright (C) 1996 Free Software Foundation, Inc.
-This file is part of the GNU C Library.
+   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 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.
+   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.  */
+   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 "../nss/nsswitch.h"
+#include <errno.h>
+#include <libc-lock.h>
+#include <stdlib.h>
+
+#include "nsswitch.h"
 
 /*******************************************************************\
 |* Here we assume several symbols to be defined:		   *|
@@ -64,17 +68,47 @@ extern int INTERNAL (REENTRANT_NAME) (ADD_PARAMS, LOOKUP_TYPE *resbuf,
 				      char *buffer, size_t buflen,
 				      LOOKUP_TYPE **result H_ERRNO_PARM);
 
+/* We need to protect the dynamic buffer handling.  */
+__libc_lock_define_initialized (static, lock);
+
+
 LOOKUP_TYPE *
 FUNCTION_NAME (ADD_PARAMS)
 {
-  static char buffer[BUFLEN];
+  static char *buffer;
+  static size_t buffer_size;
   static LOOKUP_TYPE resbuf;
   LOOKUP_TYPE *result;
+  int save;
+
+  /* Get lock.  */
+  __libc_lock_lock (lock);
+
+  if (buffer == NULL)
+    {
+      buffer_size = BUFLEN;
+      buffer = malloc (buffer_size);
+    }
+
+  while (buffer != NULL
+	 && INTERNAL (REENTRANT_NAME) (ADD_VARIABLES, &resbuf, buffer,
+				       buffer_size, &result H_ERRNO_VAR) != 0
+	 && errno == ERANGE)
+    {
+      char *new_buf;
+      buffer_size += BUFLEN;
+      new_buf = realloc (buffer, buffer_size);
+      if (new_buf == NULL)
+	/* We are out of memory.  Free the current buffer so that the
+	   process gets a chance for a normal termination.  */
+	free (buffer);
+      buffer = new_buf;
+    }
 
-  if (INTERNAL (REENTRANT_NAME) (ADD_VARIABLES, &resbuf, buffer,
-				 BUFLEN, &result H_ERRNO_VAR) != 0)
-    /* Error occured.  */
-    return NULL;
+  /* Release lock.  Preserve error value.  */
+  save = errno;
+  __libc_lock_unlock (lock);
+  __set_errno (save);
 
   return result;
 }
diff --git a/nss/getXXbyYY_r.c b/nss/getXXbyYY_r.c
index 1295772819..f12907c244 100644
--- a/nss/getXXbyYY_r.c
+++ b/nss/getXXbyYY_r.c
@@ -71,7 +71,7 @@
 
 
 /* Type of the lookup function we need here.  */
-typedef int (*lookup_function) (ADD_PARAMS, LOOKUP_TYPE *, char *, int
+typedef int (*lookup_function) (ADD_PARAMS, LOOKUP_TYPE *, char *, size_t
 				H_ERRNO_PARM);
 
 /* Some usages of this file might use this variable.  */
diff --git a/nss/getXXent.c b/nss/getXXent.c
index 7e291e6298..2d6d1c32e6 100644
--- a/nss/getXXent.c
+++ b/nss/getXXent.c
@@ -1,20 +1,24 @@
 /* Copyright (C) 1996 Free Software Foundation, Inc.
-This file is part of the GNU C Library.
+   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 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.
+   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.  */
+   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 <errno.h>
+#include <libc-lock.h>
+#include <stdlib.h>
 
 #include "nsswitch.h"
 
@@ -55,18 +59,47 @@ extern int INTERNAL (REENTRANT_GETNAME) (LOOKUP_TYPE *resbuf, char *buffer,
 					 size_t buflen, LOOKUP_TYPE **result
 					 H_ERRNO_PARM);
 
+/* We need to protect the dynamic buffer handling.  */
+__libc_lock_define_initialized (static, lock);
+
 
 LOOKUP_TYPE *
 GETFUNC_NAME (void)
 {
-  static char buffer[BUFLEN];
+  static char *buffer;
+  static size_t buffer_size;
   static LOOKUP_TYPE resbuf;
-  LOOKUP_TYPE *result;
+  LOOKUP_TYPE *result = NULL;
+  int save;
+
+  /* Get lock.  */
+  __libc_lock_lock (lock);
+
+  if (buffer == NULL)
+    {
+      buffer_size = BUFLEN;
+      buffer = malloc (buffer_size);
+    }
+
+  while (buffer != NULL
+	 && INTERNAL (REENTRANT_GETNAME) (&resbuf, buffer, buffer_size, &result
+					  H_ERRNO_VAR) != 0
+	 && errno == ERANGE)
+    {
+      char *new_buf;
+      buffer_size += BUFLEN;
+      new_buf = realloc (buffer, buffer_size);
+      if (new_buf == NULL)
+	/* We are out of memory.  Free the current buffer so that the
+	   process gets a chance for a normal termination.  */
+	free (buffer);
+      buffer = new_buf;
+    }
 
-  if (INTERNAL (REENTRANT_GETNAME) (&resbuf, buffer, BUFLEN, &result
-				    H_ERRNO_VAR) != 0)
-    /* Errors occured.  */
-    return NULL;
+  /* Release lock.  Preserve error value.  */
+  save = errno;
+  __libc_lock_unlock (lock);
+  __set_errno (save);
 
   return result;
 }
diff --git a/nss/getXXent_r.c b/nss/getXXent_r.c
index 0db0a8bf28..cc47537129 100644
--- a/nss/getXXent_r.c
+++ b/nss/getXXent_r.c
@@ -90,7 +90,7 @@ typedef int (*set_function) (STAYOPEN);
 typedef int (*end_function) (void);
 
 /* Prototype for the setXXXent functions we use here.  */
-typedef int (*get_function) (LOOKUP_TYPE *, char *, int H_ERRNO_PARM);
+typedef int (*get_function) (LOOKUP_TYPE *, char *, size_t H_ERRNO_PARM);
 
 
 /* This handle for the NSS data base is shared between all
diff --git a/nss/nss_db/db-XXX.c b/nss/nss_db/db-XXX.c
index 0c41761d67..1596be560a 100644
--- a/nss/nss_db/db-XXX.c
+++ b/nss/nss_db/db-XXX.c
@@ -1,21 +1,21 @@
 /* Common code for DB-based databases in nss_db module.
-Copyright (C) 1996 Free Software Foundation, Inc.
-This file is part of the GNU C Library.
+   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 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.
+   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.  */
+   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 <fcntl.h>
@@ -168,7 +168,7 @@ lookup (const DBT *key, struct STRUCTURE *result,
 enum nss_status								      \
 _nss_db_get##name##_r (proto,						      \
 		       struct STRUCTURE *result,			      \
-		       char *buffer, int buflen H_ERRNO_PROTO)		      \
+		       char *buffer, size_t buflen H_ERRNO_PROTO)	      \
 {									      \
   DBT key;								      \
   enum nss_status status;						      \
@@ -189,7 +189,7 @@ _nss_db_get##name##_r (proto,						      \
 /* Return the next entry from the database file, doing locking.  */
 enum nss_status
 CONCAT(_nss_db_get,ENTNAME_r) (struct STRUCTURE *result,
-			       char *buffer, int buflen H_ERRNO_PROTO)
+			       char *buffer, size_t buflen H_ERRNO_PROTO)
 {
   /* Return next entry in host file.  */
   enum nss_status status;
diff --git a/nss/nss_db/db-alias.c b/nss/nss_db/db-alias.c
new file mode 100644
index 0000000000..2c44f4df79
--- /dev/null
+++ b/nss/nss_db/db-alias.c
@@ -0,0 +1,235 @@
+/* Mail alias file parser in nss_db module.
+   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 <aliases.h>
+#include <alloca.h>
+#include <ctype.h>
+#include <db.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <libc-lock.h>
+#include <paths.h>
+#include <string.h>
+
+#include "nsswitch.h"
+
+/* 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 int keep_db;
+static unsigned int entidx;	/* Index for `getaliasent_r'. */
+
+/* Open database file if not already opened.  */
+static enum nss_status
+internal_setent (int stayopen)
+{
+  enum nss_status status = NSS_STATUS_SUCCESS;
+
+  if (db == NULL)
+    {
+      db = dbopen (_PATH_VARDB "aliases.db", O_RDONLY, 0, DB_BTREE, NULL);
+
+      if (db == NULL)
+	status = NSS_STATUS_UNAVAIL;
+    }
+
+  /* Remember STAYOPEN flag.  */
+  if (db != NULL)
+    keep_db |= stayopen;
+
+  return status;
+}
+
+
+/* Thread-safe, exported version of that.  */
+enum nss_status
+_nss_db_setaliasent (int stayopen)
+{
+  enum nss_status status;
+
+  __libc_lock_lock (lock);
+
+  status = internal_setent (stayopen);
+
+  /* Reset the sequential index.  */
+  entidx = 0;
+
+  __libc_lock_unlock (lock);
+
+  return status;
+}
+
+
+/* Close the database file.  */
+static void
+internal_endent (void)
+{
+  if (db != NULL)
+    {
+      (*db->close) (db);
+      db = NULL;
+    }
+}
+
+
+/* Thread-safe, exported version of that.  */
+enum nss_status
+_nss_db_endaliasent (void)
+{
+  __libc_lock_lock (lock);
+
+  internal_endent ();
+
+  /* Reset STAYOPEN flag.  */
+  keep_db = 0;
+
+  __libc_lock_unlock (lock);
+
+  return NSS_STATUS_SUCCESS;
+}
+
+/* We provide the parse function here.  The parser in libnss_files
+   cannot be used.  The generation of the db file already resolved all
+   :include: statements so we simply have to parse the list and store
+   the result.  */
+static enum nss_status
+lookup (const DBT *key, struct aliasent *result, char *buffer,
+	    size_t buflen)
+{
+  enum nss_status status;
+  DBT value;
+
+  /* Open the database.  */
+  status = internal_setent (keep_db);
+  if (status != NSS_STATUS_SUCCESS)
+    return status;
+
+  if ((*db->get) (db, key, &value, 0) == 0)
+    {
+      const char *src = value.data;
+
+      result->alias_members_len = 0;
+
+      /* We now have to fill the BUFFER with all the information. */
+      if (buflen < key->size + 1)
+	{
+	no_more_room:
+	  __set_errno (ERANGE);
+	  return NSS_STATUS_TRYAGAIN;
+	}
+
+      if (status == NSS_STATUS_SUCCESS)
+	{
+	  char *cp;
+	  size_t cnt;
+
+	  buffer = stpncpy (buffer, key->data, key->size) + 1;
+	  buflen -= key->size + 1;
+
+	  while (*src != '\0')
+	    {
+	      const char *end, *upto;
+	      while (isspace (*src))
+		++src;
+
+	      end = strchr (src, ',');
+	      if (end == NULL)
+		end = strchr (src, '\0');
+	      for (upto = end; upto > src && isspace (upto[-1]); --upto);
+
+	      if (upto != src)
+		{
+		  if ((upto - src) + __alignof__ (char *) > buflen)
+		    goto no_more_room;
+		  buffer = stpncpy (buffer, src, upto - src) + 1;
+		  buflen -= (upto - src) + __alignof (char *);
+		  ++result->alias_members_len;
+		}
+	      src = end + (*end != '\0');
+	    }
+
+	  /* Now prepare the return.  Provide string pointers for the
+	     currently selected aliases.  */
+
+	  /* Adjust the pointer so it is aligned for storing pointers.  */
+	  buffer += __alignof__ (char *) - 1;
+	  buffer -= ((buffer - (char *) 0) % __alignof__ (char *));
+	  result->alias_members = (char **) buffer;
+
+	  /* Compute addresses of alias entry strings.  */
+	  cp = result->alias_name;
+	  for (cnt = 0; cnt < result->alias_members_len; ++cnt)
+	    {
+	      cp = strchr (cp, '\0') + 1;
+	      result->alias_members[cnt] = cp;
+	    }
+
+	  status = (result->alias_members_len == 0
+		    ? NSS_STATUS_RETURN : NSS_STATUS_SUCCESS);
+	}
+    }
+  else
+    status = NSS_STATUS_NOTFOUND;
+
+  if (! keep_db)
+    internal_endent ();
+
+  return status;
+}
+
+enum nss_status
+_nss_db_getaliasent_r (struct aliasent *result, char *buffer, size_t buflen)
+{
+  /* Return next entry in host file.  */
+  enum nss_status status;
+  char buf[20];
+  DBT key;
+
+  __libc_lock_lock (lock);
+  key.size = 1 + snprintf (key.data = buf, sizeof buf, "0%u", entidx++);
+  status = lookup (&key, result, buffer, buflen);
+  __libc_lock_unlock (lock);
+
+  return status;
+}
+
+
+enum nss_status
+_nss_db_getaliasbyname_r (const char *name, struct aliasent *result,
+			  char *buffer, size_t buflen)
+{
+  DBT key;
+  enum nss_status status;
+
+  key.size = 1 + strlen (name);
+
+  key.data = __alloca (key.size);
+  ((char *) key.data)[0] = '.';
+  memcpy (&((char *) key.data)[1], name, key.size - 1);
+
+  __libc_lock_lock (lock);
+  status = lookup (&key, result, buffer, buflen);
+  __libc_lock_unlock (lock);
+
+  return status;
+}
diff --git a/nss/nss_files/files-XXX.c b/nss/nss_files/files-XXX.c
index b6702b0366..c741ab6f48 100644
--- a/nss/nss_files/files-XXX.c
+++ b/nss/nss_files/files-XXX.c
@@ -20,6 +20,7 @@
 #include <stdio.h>
 #include <ctype.h>
 #include <assert.h>
+#include <errno.h>
 #include <libc-lock.h>
 #include "nsswitch.h"
 
@@ -39,13 +40,13 @@
 #define DATAFILE	"/etc/" DATABASE
 
 #ifdef NEED_H_ERRNO
-#define H_ERRNO_PROTO	, int *herrnop
-#define H_ERRNO_ARG	, herrnop
-#define H_ERRNO_SET(val) (*herrnop = (val))
+# define H_ERRNO_PROTO	, int *herrnop
+# define H_ERRNO_ARG	, herrnop
+# define H_ERRNO_SET(val) (*herrnop = (val))
 #else
-#define H_ERRNO_PROTO
-#define H_ERRNO_ARG
-#define H_ERRNO_SET(val) ((void) 0)
+# define H_ERRNO_PROTO
+# define H_ERRNO_ARG
+# define H_ERRNO_SET(val) ((void) 0)
 #endif
 
 /* Locks the static variables in this file.  */
@@ -59,10 +60,10 @@ static enum { none, getent, getby } last_use;
 static int keep_stream;
 
 /* 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 (stream == NULL)
     {
@@ -83,10 +84,10 @@ internal_setent (int stayopen)
 
 
 /* Thread-safe, exported version of that.  */
-int
+enum nss_status
 CONCAT(_nss_files_set,ENTNAME) (int stayopen)
 {
-  int status;
+  enum nss_status status;
 
   __libc_lock_lock (lock);
 
@@ -120,7 +121,7 @@ internal_endent (void)
 
 
 /* Thread-safe, exported version of that.  */
-int
+enum nss_status
 CONCAT(_nss_files_end,ENTNAME) (void)
 {
   __libc_lock_lock (lock);
@@ -145,16 +146,6 @@ internal_getent (struct STRUCTURE *result,
   struct parser_data *data = (void *) buffer;
   int linebuflen = buffer + buflen - data->linebuffer;
 
-  /* Be prepared that the set*ent function was not called before.  */
-  if (stream == NULL)
-    {
-      enum nss_status status;
-
-      status = internal_setent (0);
-      if (status != NSS_STATUS_SUCCESS)
-	return status;
-    }
-
   if (buflen < (int) sizeof *data + 1)
     {
       __set_errno (ERANGE);
@@ -163,6 +154,9 @@ internal_getent (struct STRUCTURE *result,
 
   do
     {
+      /* Terminate the line so that we can test for overflow.  */
+      data->linebuffer[linebuflen - 1] = '\0';
+
       p = fgets (data->linebuffer, linebuflen, stream);
       if (p == NULL)
 	{
@@ -170,17 +164,23 @@ internal_getent (struct STRUCTURE *result,
 	  H_ERRNO_SET (HOST_NOT_FOUND);
 	  return NSS_STATUS_NOTFOUND;
 	}
-
-      /* Terminate the line for any case.  */
-      data->linebuffer[linebuflen - 1] = '\0';
+      else if (data->linebuffer[linebuflen - 1] != '\0')
+	{
+	  /* The line is too long.  Give the user the opportunity to
+	     enlarge the buffer.  */
+	  __set_errno (ERANGE);
+	  H_ERRNO_SET (NETDB_INTERNAL);
+	  return NSS_STATUS_TRYAGAIN;
+	}
 
       /* Skip leading blanks.  */
       while (isspace (*p))
 	++p;
-    } while (*p == '\0' || *p == '#' ||	/* Ignore empty and comment lines.  */
-	     /* Parse the line.  If it is invalid, loop to
-		get the next line of the file to parse.  */
-	     ! parse_line (p, result, data, buflen));
+    }
+  while (*p == '\0' || *p == '#' /* Ignore empty and comment lines.  */
+	 /* Parse the line.  If it is invalid, loop to get the next
+	    line of the file to parse.  */
+	 || ! parse_line (p, result, data, buflen));
 
   /* Filled in RESULT with the next entry from the database file.  */
   return NSS_STATUS_SUCCESS;
@@ -188,29 +188,42 @@ internal_getent (struct STRUCTURE *result,
 
 
 /* Return the next entry from the database file, doing locking.  */
-int
+enum nss_status
 CONCAT(_nss_files_get,ENTNAME_r) (struct STRUCTURE *result,
-				  char *buffer, int buflen H_ERRNO_PROTO)
+				  char *buffer, size_t buflen H_ERRNO_PROTO)
 {
   /* Return next entry in host file.  */
-  int status = NSS_STATUS_SUCCESS;
+  enum nss_status status = NSS_STATUS_SUCCESS;
 
   __libc_lock_lock (lock);
 
-  /* If the last use was not by the getent function we need the
-     position the stream.  */
-  if (last_use != getent)
-    if (fsetpos (stream, &position) < 0)
-      status = NSS_STATUS_UNAVAIL;
-    else
-      last_use = getent;
+  /* Be prepared that the set*ent function was not called before.  */
+  if (stream == NULL)
+    status = internal_setent (0);
 
-  if (status == NSS_STATUS_SUCCESS)
+  if (status != NSS_STATUS_SUCCESS)
     {
-      status = internal_getent (result, buffer, buflen H_ERRNO_ARG);
-
-      /* Remember this position.  */
-      fgetpos (stream, &position);
+      /* If the last use was not by the getent function we need the
+	 position the stream.  */
+      if (last_use != getent)
+	if (fsetpos (stream, &position) < 0)
+	  status = NSS_STATUS_UNAVAIL;
+	else
+	  last_use = getent;
+
+      if (status == NSS_STATUS_SUCCESS)
+	{
+	  status = internal_getent (result, buffer, buflen H_ERRNO_ARG);
+
+	  /* Remember this position if we were successful.  If the
+	     operation failed we give the user a chance to repeat the
+	     operation (perhaps the buffer was too small).  */
+	  if (status == NSS_STATUS_SUCCESS)
+	    fgetpos (stream, &position);
+	  else
+	    /* We must make sure we reposition the stream the next call.  */
+	    last_use = none;
+	}
     }
 
   __libc_lock_unlock (lock);
@@ -234,24 +247,27 @@ CONCAT(_nss_files_get,ENTNAME_r) (struct STRUCTURE *result,
 enum nss_status								      \
 _nss_files_get##name##_r (proto,					      \
 			  struct STRUCTURE *result,			      \
-			  char *buffer, int buflen H_ERRNO_PROTO)	      \
+			  char *buffer, size_t buflen H_ERRNO_PROTO)	      \
 {									      \
   enum nss_status status;						      \
 									      \
   __libc_lock_lock (lock);						      \
 									      \
   /* Reset file pointer to beginning or open file.  */			      \
-  internal_setent (keep_stream);					      \
+  status = internal_setent (keep_stream);				      \
 									      \
-  /* Tell getent function that we have repositioned the file pointer.  */     \
-  last_use = getby;							      \
+  if (status == NSS_STATUS_SUCCESS)					      \
+    {									      \
+      /* Tell getent function that we have repositioned the file pointer.  */ \
+      last_use = getby;							      \
 									      \
-  while ((status = internal_getent (result, buffer, buflen H_ERRNO_ARG))      \
-	 == NSS_STATUS_SUCCESS)						      \
-    { break_if_match }							      \
+      while ((status = internal_getent (result, buffer, buflen H_ERRNO_ARG))  \
+	     == NSS_STATUS_SUCCESS)					      \
+	{ break_if_match }						      \
 									      \
-  if (! keep_stream)							      \
-    internal_endent ();							      \
+      if (! keep_stream)						      \
+	internal_endent ();						      \
+    }									      \
 									      \
   __libc_lock_unlock (lock);						      \
 									      \
diff --git a/nss/nss_files/files-alias.c b/nss/nss_files/files-alias.c
new file mode 100644
index 0000000000..c6ef49c621
--- /dev/null
+++ b/nss/nss_files/files-alias.c
@@ -0,0 +1,424 @@
+/* Mail alias file parser in nss_files module.
+   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 <aliases.h>
+#include <ctype.h>
+#include <libc-lock.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "nsswitch.h"
+
+/* Locks the static variables in this file.  */
+__libc_lock_define_initialized (static, lock)
+
+/* Maintenance of the shared stream open on the database file.  */
+
+static FILE *stream;
+static fpos_t position;
+static enum { none, getent, getby } last_use;
+
+
+static enum nss_status
+internal_setent (void)
+{
+  enum nss_status status = NSS_STATUS_SUCCESS;
+
+  if (stream == NULL)
+    {
+      stream = fopen ("/etc/aliases", "r");
+
+      if (stream == NULL)
+	status = NSS_STATUS_UNAVAIL;
+    }
+  else
+    rewind (stream);
+
+  return status;
+}
+
+
+/* Thread-safe, exported version of that.  */
+enum nss_status
+_nss_files_setaliasent (void)
+{
+  enum nss_status status;
+
+  __libc_lock_lock (lock);
+
+  status = internal_setent ();
+
+  if (status == NSS_STATUS_SUCCESS && fgetpos (stream, &position) < 0)
+    {
+      fclose (stream);
+      stream = NULL;
+      status = NSS_STATUS_UNAVAIL;
+    }
+
+  last_use = getent;
+
+  __libc_lock_unlock (lock);
+
+  return status;
+}
+
+
+/* Close the database file.  */
+static void
+internal_endent (void)
+{
+  if (stream != NULL)
+    {
+      fclose (stream);
+      stream = NULL;
+    }
+}
+
+
+/* Thread-safe, exported version of that.  */
+enum nss_status
+_nss_files_endaliasent (void)
+{
+  __libc_lock_lock (lock);
+
+  internal_endent ();
+
+  __libc_lock_unlock (lock);
+
+  return NSS_STATUS_SUCCESS;
+}
+
+/* Parsing the database file into `struct aliasent' data structures.  */
+static enum nss_status
+get_next_alias (const char *match, struct aliasent *result,
+		char *buffer, size_t buflen)
+{
+  enum nss_status status = NSS_STATUS_NOTFOUND;
+  int ignore = 0;
+
+  result->alias_members_len = 0;
+
+  while (1)
+    {
+      /* Now we are ready to process the input.  We have to read a
+	 line and all its continuations and construct the array of
+	 string pointers.  This pointers and the names itself have to
+	 be placed in BUFFER.  */
+      char *first_unused = buffer;
+      size_t room_left = buflen - (buflen % __alignof__ (char *));
+      char *line;
+
+      /* Read the first line.  It must contain the alias name and
+	 possibly some alias names.  */
+      first_unused[room_left - 1] = '\0';
+      line = fgets (first_unused, room_left, stream);
+      if (line == NULL)
+	/* Nothing to read.  */
+	break;
+      else if (first_unused[room_left - 1] != '\0')
+	{
+	  /* The line is too long for our buffer.  */
+	no_more_room:
+	  __set_errno (ERANGE);
+	  status = NSS_STATUS_TRYAGAIN;
+	  break;
+	}
+      else
+	{
+	  char *cp;
+
+	  /* If we are in IGNORE mode and the first character in the
+	     line is a white space we ignore the line and start
+	     reading the next.  */
+	  if (ignore && isspace (first_unused))
+	    continue;
+
+	  /* Terminate the line for any case.  */
+	  cp = strpbrk (first_unused, "#\n");
+	  if (cp != NULL)
+	    *cp = '\0';
+
+	  /* Skip leading blanks.  */
+	  while (isspace (*line))
+	    ++line;
+
+	  result->alias_name = first_unused;
+	  while (*line != '\0' && *line != ':')
+	    *first_unused++ = *line++;
+	  if (*line == '\0' || result->alias_name == first_unused)
+	    /* No valid name.  Ignore the line.  */
+	    continue;
+
+	  *first_unused++ = '\0';
+	  if (room_left < (size_t) (first_unused - result->alias_name))
+	    goto no_more_room;
+	  room_left -= first_unused - result->alias_name;
+	  ++line;
+
+	  /* When we search for a specific alias we can avoid all the
+	     difficult parts and compare now with the name we are
+	     looking for.  If it does not match we simply ignore all
+	     lines until the next line containing the start of a new
+	     alias is found.  */
+	  ignore = match != NULL && strcmp (result->alias_name, match) == 0;
+
+	  while (! ignore)
+	    {
+	      while (isspace (*line))
+		++line;
+
+	      cp = first_unused;
+	      while (*line != '\0' && *line != ',')
+		*first_unused++ = *line++;
+
+	      if (first_unused != cp)
+		{
+		  if (*line != '\0')
+		    {
+		      /* OK, we can have a regular entry or an include
+			 request.  */
+		      *first_unused++ = '\0';
+		      ++line;
+		    }
+		  else
+		    ++first_unused;
+
+
+		  if (strncmp (cp, ":include:", 9) != 0)
+		    {
+		      if (room_left < (first_unused - cp) + sizeof (char *))
+			goto no_more_room;
+		      room_left -= (first_unused - cp) + sizeof (char *);
+
+		      ++result->alias_members_len;
+		    }
+		  else
+		    {
+		      /* Oh well, we have to read the addressed file.  */
+		      FILE *listfile;
+		      char *old_line = NULL;
+
+		      first_unused = cp;
+
+		      listfile = fopen (&cp[9], "r");
+		      /* If the file does not exist we simply ignore
+			 the statement.  */
+		      if (listfile != NULL
+			  && (old_line = strdup (line)) != NULL)
+			{
+			  while (! feof (listfile))
+			    {
+			      first_unused[room_left - 1] = '\0';
+			      line = fgets (first_unused, room_left, listfile);
+			      if (line == NULL)
+				break;
+			      if (first_unused[room_left - 1] != '\0')
+				{
+				  free (old_line);
+				  goto no_more_room;
+				}
+
+			      /* Parse the line.  */
+			      cp = strpbrk (line, "#\n");
+			      if (cp != NULL)
+				*cp = '\0';
+
+			      do
+				{
+				  while (isspace (*line))
+				    ++line;
+
+				  cp = first_unused;
+				  while (*line != '\0' && *line != ',')
+				    *first_unused++ = *line++;
+
+				  if (*line != '\0')
+				    ++line;
+
+				  if (first_unused != cp)
+				    {
+				      *first_unused++ = '\0';
+				      if (room_left < ((first_unused - cp)
+						       + __alignof__ (char *)))
+					{
+					  free (old_line);
+					  goto no_more_room;
+					}
+				      room_left -= ((first_unused - cp)
+						    + __alignof__ (char *));
+				      ++result->alias_members_len;
+				    }
+				}
+			      while (*line != '\0');
+			    }
+			  fclose (listfile);
+
+			  first_unused[room_left - 1] = '\0';
+			  strncpy (first_unused, old_line, room_left);
+
+			  if (old_line != NULL)
+			    free (old_line);
+
+			  if (first_unused[room_left - 1] != '\0')
+			    goto no_more_room;
+			}
+		    }
+		}
+
+	      if (*line == '\0')
+		{
+		  /* Get the next line.  But we must be careful.  We
+		     must not read the whole line at once since it
+		     might belong to the current alias.  Simply read
+		     the first character.  If it is a white space we
+		     have a continuation line.  Otherwise it is the
+		     beginning of a new alias and we can push back the
+		     just read character.  */
+		  int ch;
+
+		  first_unused[room_left - 1] = '\0';
+		  line = first_unused;
+		  ch = fgetc (stream);
+		  if (ch == EOF || !isspace (ch))
+		    {
+		      size_t cnt;
+
+		      /* Now prepare the return.  Provide string
+			 pointers for the currently selected aliases.  */
+		      if (ch != EOF)
+			ungetc (ch, stream);
+
+		      /* Adjust the pointer so it is aligned for
+			 storing pointers.  */
+		      first_unused += __alignof__ (char *) - 1;
+		      first_unused -= ((first_unused - (char *) 0)
+				       % __alignof__ (char *));
+		      result->alias_members = (char **) first_unused;
+
+		      /* Compute addresses of alias entry strings.  */
+		      cp = result->alias_name;
+		      for (cnt = 0; cnt < result->alias_members_len; ++cnt)
+			{
+			  cp = strchr (cp, '\0') + 1;
+			  result->alias_members[cnt] = cp;
+			}
+
+		      status = (result->alias_members_len == 0
+				? NSS_STATUS_RETURN : NSS_STATUS_SUCCESS);
+		      break;
+		    }
+
+		  /* The just read character is a white space and so
+		     can be ignored.  */
+		  cp = strpbrk (line, "#\n");
+		  if (cp != NULL)
+		    *cp = '\0';
+		}
+	    }
+	}
+
+      if (status != NSS_STATUS_NOTFOUND)
+	/* We read something.  In any case break here.  */
+	break;
+    }
+
+  return status;
+}
+
+
+enum nss_status
+_nss_files_getaliasent_r (struct aliasent *result, char *buffer, size_t buflen)
+{
+  /* Return next entry in host file.  */
+  enum nss_status status = NSS_STATUS_SUCCESS;
+
+  __libc_lock_lock (lock);
+
+  /* Be prepared that the set*ent function was not called before.  */
+  if (stream == NULL)
+    status = internal_setent ();
+
+  if (status == NSS_STATUS_SUCCESS)
+    {
+      /* If the last use was not by the getent function we need the
+	 position the stream.  */
+      if (last_use != getent)
+	if (fsetpos (stream, &position) < 0)
+	  status = NSS_STATUS_UNAVAIL;
+	else
+	  last_use = getent;
+
+      if (status == NSS_STATUS_SUCCESS)
+	{
+	  result->alias_local = 1;
+
+	  /* Read lines until we get a definite result.  */
+	  do
+	    status = get_next_alias (NULL, result, buffer, buflen);
+	  while (status == NSS_STATUS_RETURN);
+
+	  /* If we successfully read an entry remember this position.  */
+	  if (status == NSS_STATUS_SUCCESS)
+	    fgetpos (stream, &position);
+	  else
+	    last_use = none;
+	}
+    }
+
+  __libc_lock_unlock (lock);
+
+  return status;
+}
+
+
+enum nss_status
+_nss_files_getaliasbyname_r (const char *name, struct aliasent *result,
+			     char *buffer, size_t buflen)
+{
+  /* Return next entry in host file.  */
+  enum nss_status status = NSS_STATUS_SUCCESS;
+
+  if (name == NULL)
+    {
+      __set_errno (EINVAL);
+      return NSS_STATUS_UNAVAIL;
+    }
+
+  __libc_lock_lock (lock);
+
+  /* Open the stream or rest it.  */
+  status = internal_setent ();
+  last_use = getby;
+
+  if (status == NSS_STATUS_SUCCESS)
+    {
+      result->alias_local = 1;
+
+      /* Read lines until we get a definite result.  */
+      do
+	status = get_next_alias (name, result, buffer, buflen);
+      while (status == NSS_STATUS_RETURN);
+    }
+
+  __libc_lock_unlock (lock);
+
+  return status;
+}
diff --git a/nss/nss_files/files-parse.c b/nss/nss_files/files-parse.c
index 1250bb9572..83a80f35c0 100644
--- a/nss/nss_files/files-parse.c
+++ b/nss/nss_files/files-parse.c
@@ -39,7 +39,7 @@
 #define CONCAT1(a,b) a##b
 
 #ifndef STRUCTURE
-#define STRUCTURE ENTNAME
+# define STRUCTURE ENTNAME
 #endif
 
 
@@ -47,9 +47,9 @@ struct parser_data
   {
 #ifdef ENTDATA
     struct ENTDATA entdata;
-#define ENTDATA_DECL(data) struct ENTDATA *const entdata = &data->entdata;
+# define ENTDATA_DECL(data) struct ENTDATA *const entdata = &data->entdata;
 #else
-#define ENTDATA_DECL(data)
+# define ENTDATA_DECL(data)
 #endif
     char linebuffer[0];
   };
@@ -57,11 +57,11 @@ struct parser_data
 #ifdef ENTDATA
 /* The function can't be exported, because the entdata structure
    is defined only in files-foo.c.  */
-#define parser_stclass static inline
+# define parser_stclass static inline
 #else
 /* Export the line parser function so it can be used in nss_db.  */
-#define parser_stclass /* Global */
-#define parse_line CONCAT(_nss_files_parse_,ENTNAME)
+# define parser_stclass /* Global */
+# define parse_line CONCAT(_nss_files_parse_,ENTNAME)
 #endif
 
 
@@ -71,20 +71,20 @@ struct parser_data
 extern int parse_line (char *line, struct STRUCTURE *result,
 		       struct parser_data *data, int datalen);
 
-#define LINE_PARSER(EOLSET, BODY) /* Do nothing */
+# define LINE_PARSER(EOLSET, BODY) /* Do nothing */
 
 #else
 
 /* Define a line parsing function.  */
 
-#define LINE_PARSER(EOLSET, BODY)					      \
+# define LINE_PARSER(EOLSET, BODY)					      \
 parser_stclass int							      \
 parse_line (char *line, struct STRUCTURE *result,			      \
 	    struct parser_data *data, int datalen)			      \
 {									      \
   ENTDATA_DECL (data)							      \
   char *p = strpbrk (line, EOLSET "\n");				      \
-  if (p)								      \
+  if (p != NULL)							      \
     *p = '\0';								      \
   BODY;									      \
   TRAILING_LIST_PARSER;							      \
@@ -92,7 +92,7 @@ parse_line (char *line, struct STRUCTURE *result,			      \
 }
 
 
-#define STRING_FIELD(variable, terminator_p, swallow)			      \
+# define STRING_FIELD(variable, terminator_p, swallow)			      \
   {									      \
     variable = line;							      \
     while (*line != '\0' && !terminator_p (*line))			      \
@@ -106,7 +106,7 @@ parse_line (char *line, struct STRUCTURE *result,			      \
       }									      \
   }
 
-#define INT_FIELD(variable, terminator_p, swallow, base, convert)	      \
+# define INT_FIELD(variable, terminator_p, swallow, base, convert)	      \
   {									      \
     char *endp;								      \
     variable = convert (strtol (line, &endp, base));			      \
@@ -121,7 +121,7 @@ parse_line (char *line, struct STRUCTURE *result,			      \
     line = endp;							      \
   }
 
-#define INT_FIELD_MAYBE_NULL(variable, terminator_p, swallow, base, convert, default)	      \
+# define INT_FIELD_MAYBE_NULL(variable, terminator_p, swallow, base, convert, default)	      \
   {									      \
     char *endp;								      \
     if (*line == '\0')							      \
@@ -139,14 +139,14 @@ parse_line (char *line, struct STRUCTURE *result,			      \
     line = endp;							      \
   }
 
-#define ISCOLON(c) ((c) == ':')
+# define ISCOLON(c) ((c) == ':')
 
 
-#ifndef TRAILING_LIST_MEMBER
-#define TRAILING_LIST_PARSER /* Nothing to do.  */
-#else
+# ifndef TRAILING_LIST_MEMBER
+#  define TRAILING_LIST_PARSER /* Nothing to do.  */
+# else
 
-#define TRAILING_LIST_PARSER						      \
+#  define TRAILING_LIST_PARSER						      \
 {									      \
   char **list = parse_list (line, data, datalen);			      \
   if (list)								      \
@@ -198,10 +198,10 @@ parse_list (char *line, struct parser_data *data, int datalen)
 	      *line = '\0';
 	      do
 		++line;
-	      while (TRAILING_LIST_SEPARATOR_P (*line));
+	      while (isspace (*line));
 	      elt = line;
 	    }
-	  else if (*line == '\0' || *line == '\n')
+	  else if (*line == '\0')
 	    {
 	      /* End of the line.  */
 	      if (line > elt)
@@ -219,7 +219,7 @@ parse_list (char *line, struct parser_data *data, int datalen)
   return list;
 }
 
-#endif	/* TRAILING_LIST_MEMBER */
+# endif	/* TRAILING_LIST_MEMBER */
 #endif	/* EXTERN_PARSER */
 
 
@@ -238,5 +238,5 @@ parse_list (char *line, struct parser_data *data, int datalen)
 
 /* This is defined by db-*.c to include "../nss_db/db-XXX.c" instead.  */
 #ifndef GENERIC
-#define GENERIC "files-XXX.c"
+# define GENERIC "files-XXX.c"
 #endif