]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
Reenable nss_db with a completely new implementation
authorUlrich Drepper <drepper@gmail.com>
Wed, 15 Jun 2011 02:21:51 +0000 (22:21 -0400)
committerUlrich Drepper <drepper@gmail.com>
Thu, 16 Jun 2011 01:06:18 +0000 (21:06 -0400)
No longer is Berkeley db used.  Instead a simple hash function is used.
The database files are not updated once they are created and therefore
no complicated database is needed.

24 files changed:
ChangeLog
Versions.def
nss/Makefile
nss/Versions
nss/db-Makefile
nss/makedb.c
nss/nss_db/db-XXX.c
nss/nss_db/db-alias.c [deleted file]
nss/nss_db/db-netgrp.c
nss/nss_db/db-open.c
nss/nss_db/dummy-db.h [deleted file]
nss/nss_db/nss_db.h
nss/nss_files/files-XXX.c
nss/nss_files/files-ethers.c
nss/nss_files/files-grp.c
nss/nss_files/files-hosts.c
nss/nss_files/files-network.c
nss/nss_files/files-proto.c
nss/nss_files/files-pwd.c
nss/nss_files/files-rpc.c
nss/nss_files/files-service.c
nss/nss_files/files-sgrp.c
nss/nss_files/files-spwd.c
shlib-versions

index 9ce38a851651cb59a331dc4282000f61033d433d..60ad9ae1f0c0177c42fa98c6fd92931202f6a565 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,35 @@
+2011-06-14  Ulrich Drepper  <drepper@gmail.com>
+
+       * Versions.def: Add entry for libnss_db.
+       * shlib-versions: Likewise.
+       * nss/Makefile: Add rules to build libnss_db.
+       * nss/Versions: Add libnss_db information.  Organize libnss_files
+       entries better.
+       * nss/db-Makefile: Add gshadow support.  Change rules for the new
+       makedb progra.  Some minor improvements to generate smaller files.
+       * nss/nss_db/nss_db.h: Move NSS database header data structures to
+       here from...
+       * nss/makedb.c: ...here.
+       Improve database format to be smaller and require less memory at
+       runtime.
+       * nss/nss_db/db-XXX.x: Adjust for new database format.  Don't use
+       db anymore.
+       * nss/nss_db/db-netgrp.c: Likewise.
+       * nss/nss_db/db-open.c: Likewise.
+       * nss/nss_files/flies-XXX.x: Adjust comments.
+       * nss/nss_files/files-ethers.c: Adjust for new DB_LOOKUP definition.
+       * nss/nss_files/files-grp.c: Likewise.
+       * nss/nss_files/files-hosts.c: Likewise.
+       * nss/nss_files/files-network.c: Likewise.
+       * nss/nss_files/files-proto.c: Likewise.
+       * nss/nss_files/files-pwd.c: Likewise.
+       * nss/nss_files/files-rpc.c: Likewise.
+       * nss/nss_files/files-service.c: Likewise.
+       * nss/nss_files/files-sgrp.c: Likewise.
+       * nss/nss_files/files-spwd.c: Likewise.
+       * nss/nss_db/db-alias.c: Removed.
+       * nss/nss_db/dummy-db.h: Removed.
+
 2011-06-02  Ulrich Drepper  <drepper@gmail.com>
 
        * nss/makedb.c: Rewritten to not use database library.
index e478fdd9e54e917dfaad29c83496d4f6e721413a..666ea7310860b1c4e3d4130766a323f9782371f5 100644 (file)
@@ -67,6 +67,9 @@ libnss_compat {
 libnss_dns {
   GLIBC_PRIVATE
 }
+libnss_db {
+  GLIBC_PRIVATE
+}
 libnss_files {
   GLIBC_PRIVATE
 }
index 16578a3548c596d18a0c265dce291bd3fec67a6b..a925cb5bf7b0ee7fd309572af0748fa5e1744cfc 100644 (file)
@@ -53,7 +53,7 @@ otherlibs += $(nssobjdir)/libnss_files.a $(resolvobjdir)/libnss_dns.a \
 endif
 
 # Specify rules for the nss_* modules.  We have some services.
-services               := files
+services               := files db
 
 extra-libs             = $(services:%=libnss_%)
 # These libraries will be built in the `others' pass rather than
@@ -69,10 +69,18 @@ libnss_files-routines       := $(addprefix files-,$(databases)) \
                           files-initgroups files-have_o_cloexec
 distribute             += files-XXX.c files-parse.c
 
+libnss_db-dbs          := $(addprefix db-,\
+                                      $(filter-out hosts network key alias,\
+                                                   $(databases)))
+libnss_db-routines     := $(libnss_db-dbs) db-open hash-string
+generated              += $(filter-out db-alias.c db-netgrp.c, \
+                                       $(addsuffix .c,$(libnss_db-dbs)))
+distribute             += $(addprefix nss_db/, db-XXX.c nss_db.h)
 
 # Build static module if requested
 ifneq ($(build-static-nss),yes)
 libnss_files-inhibit-o = $(filter-out .os,$(object-suffixes))
+libnss_db-inhibit-o    = $(filter-out .os,$(object-suffixes))
 endif
 
 include ../Rules
@@ -93,6 +101,15 @@ libnss-libc = $(common-objpfx)linkobj/libc.so
 $(services:%=$(objpfx)libnss_%.so): $(libnss-libc) \
                                    $(common-objpfx)libc_nonshared.a
 
+$(objpfx)libnss_db.so: $(objpfx)libnss_files.so
+
+$(libnss_db-dbs:%=$(objpfx)%.c): $(objpfx)db-%.c: nss_files/files-%.c
+       @rm -f $@.new
+       (echo '#define EXTERN_PARSER';\
+        echo '#define GENERIC "../nss_db/db-XXX.c"';\
+        echo '#include "$<"') > $@.new
+       mv -f $@.new $@
+
 
 $(objpfx)makedb: $(makedb-modules:%=$(objpfx)%.o)
 
index 1c6fd686f317d9e867c3b9fd5fe15ba4a78a109f..2f3a671af6e57475c137170f6b1ab4db0ccac842 100644 (file)
@@ -27,6 +27,8 @@ libnss_files {
     _nss_files_endetherent;
     _nss_files_getetherent_r;
     _nss_files_parse_etherent;
+    _nss_files_gethostton_r;
+    _nss_files_getntohost_r;
 
     _nss_files_setgrent;
     _nss_files_endgrent;
@@ -41,14 +43,12 @@ libnss_files {
     _nss_files_gethostbyname4_r;
     _nss_files_gethostbyname_r;
     _nss_files_gethostent_r;
-    _nss_files_gethostton_r;
 
     _nss_files_setnetent;
     _nss_files_endnetent;
     _nss_files_getnetbyaddr_r;
     _nss_files_getnetbyname_r;
     _nss_files_getnetent_r;
-    _nss_files_getntohost_r;
     _nss_files_parse_netent;
 
     _nss_files_setnetgrent;
@@ -99,3 +99,57 @@ libnss_files {
     _nss_files_initgroups_dyn;
   }
 }
+
+libnss_db {
+  GLIBC_PRIVATE {
+    _nss_db_setetherent;
+    _nss_db_endetherent;
+    _nss_db_getetherent_r;
+    _nss_db_gethostton_r;
+    _nss_db_getntohost_r;
+
+    _nss_db_setgrent;
+    _nss_db_endgrent;
+    _nss_db_getgrent_r;
+    _nss_db_getgrgid_r;
+    _nss_db_getgrnam_r;
+
+    _nss_db_setnetgrent;
+    _nss_db_endnetgrent;
+    _nss_db_getnetgrent_r;
+
+    _nss_db_setprotoent;
+    _nss_db_endprotoent;
+    _nss_db_getprotoent_r;
+    _nss_db_getprotobyname_r;
+    _nss_db_getprotobynumber_r;
+
+    _nss_db_setpwent;
+    _nss_db_endpwent;
+    _nss_db_getpwent_r;
+    _nss_db_getpwnam_r;
+    _nss_db_getpwuid_r;
+
+    _nss_db_setrpcent;
+    _nss_db_endrpcent;
+    _nss_db_getrpcent_r;
+    _nss_db_getrpcbyname_r;
+    _nss_db_getrpcbynumber_r;
+
+    _nss_db_setservent;
+    _nss_db_endservent;
+    _nss_db_getservent_r;
+    _nss_db_getservbyname_r;
+    _nss_db_getservbyport_r;
+
+    _nss_db_setsgent;
+    _nss_db_endsgent;
+    _nss_db_getsgent_r;
+    _nss_db_getsgnam_r;
+
+    _nss_db_setspent;
+    _nss_db_endspent;
+    _nss_db_getspent_r;
+    _nss_db_getspnam_r;
+  }
+}
index f9c6bd37d7db9c050ccbaedca01f1ff85696ce3f..649e09ced660dfd8a0be9d4f7729a532b9af11d8 100644 (file)
@@ -1,5 +1,5 @@
 # Makefile to (re-)generate db versions of system database files.
-# Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
+# Copyright (C) 1996, 1997, 1998, 2011 Free Software Foundation, Inc.
 # This file is part of the GNU C Library.
 # Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
 #
@@ -20,7 +20,8 @@
 # 02111-1307 USA.
 
 DATABASES = $(wildcard /etc/passwd /etc/group /etc/ethers /etc/protocols \
-                      /etc/rpc /etc/services /etc/shadow /etc/netgroup)
+                      /etc/rpc /etc/services /etc/shadow /etc/gshadow \
+                      /etc/netgroup)
 
 VAR_DB = /var/db
 
@@ -32,10 +33,9 @@ all: $(patsubst %,$(VAR_DB)/%.db,$(notdir $(DATABASES)))
 
 $(VAR_DB)/passwd.db: /etc/passwd
        @echo -n "$(patsubst %.db,%,$(@F))... "
-       @$(AWK) 'BEGIN { FS=":"; OFS=":"; cnt=0 } \
+       @$(AWK) 'BEGIN { FS=":"; OFS=":" } \
                 /^[ \t]*$$/ { next } \
                 /^[ \t]*#/ { next } \
-                { printf "0%u ", cnt++; print } \
                 /^[^#]/ { printf ".%s ", $$1; print; \
                           printf "=%s ", $$3; print }' $^ | \
        $(MAKEDB) -o $@ -
@@ -43,10 +43,9 @@ $(VAR_DB)/passwd.db: /etc/passwd
 
 $(VAR_DB)/group.db: /etc/group
        @echo -n "$(patsubst %.db,%,$(@F))... "
-       @$(AWK) 'BEGIN { FS=":"; OFS=":"; cnt=0 } \
+       @$(AWK) 'BEGIN { FS=":"; OFS=":" } \
                 /^[ \t]*$$/ { next } \
                 /^[ \t]*#/ { next } \
-                { printf "0%u ", cnt++; print } \
                 /^[^#]/ { printf ".%s ", $$1; print; \
                           printf "=%s ", $$3; print }' $^ | \
        $(MAKEDB) -o $@ -
@@ -54,10 +53,8 @@ $(VAR_DB)/group.db: /etc/group
 
 $(VAR_DB)/ethers.db: /etc/ethers
        @echo -n "$(patsubst %.db,%,$(@F))... "
-       @$(AWK) 'BEGIN { cnt=0 } \
-                /^[ \t]*$$/ { next } \
+       @$(AWK) '/^[ \t]*$$/ { next } \
                 /^[ \t]*#/ { next } \
-                { printf "0%u ", cnt++; print } \
                 /^[^#]/ { printf ".%s ", $$1; print; \
                           printf "=%s ", $$2; print }' $^ | \
        $(MAKEDB) -o $@ -
@@ -65,10 +62,8 @@ $(VAR_DB)/ethers.db: /etc/ethers
 
 $(VAR_DB)/protocols.db: /etc/protocols
        @echo -n "$(patsubst %.db,%,$(@F))... "
-       @$(AWK) 'BEGIN { cnt=0 } \
-                /^[ \t]*$$/ { next } \
+       @$(AWK) '/^[ \t]*$$/ { next } \
                 /^[ \t]*#/ { next } \
-                { printf "0%u ", cnt++; print } \
                 /^[^#]/ { printf ".%s ", $$1; print; \
                           printf "=%s ", $$2; print; \
                           for (i = 3; i <= NF && !($$i ~ /^#/); ++i) \
@@ -78,10 +73,8 @@ $(VAR_DB)/protocols.db: /etc/protocols
 
 $(VAR_DB)/rpc.db: /etc/rpc
        @echo -n "$(patsubst %.db,%,$(@F))... "
-       @$(AWK) 'BEGIN { cnt=0 } \
-                /^[ \t]*$$/ { next } \
+       @$(AWK) '/^[ \t]*$$/ { next } \
                 /^[ \t]*#/ { next } \
-                { printf "0%u ", cnt++; print } \
                 /^[^#]/ { printf ".%s ", $$1; print; \
                           printf "=%s ", $$2; print; \
                           for (i = 3; i <= NF && !($$i ~ /^#/); ++i) \
@@ -91,26 +84,25 @@ $(VAR_DB)/rpc.db: /etc/rpc
 
 $(VAR_DB)/services.db: /etc/services
        @echo -n "$(patsubst %.db,%,$(@F))... "
-       @$(AWK) 'BEGIN { FS="[ \t/]+"; cnt=0 } \
+       @$(AWK) 'BEGIN { FS="[ \t/]+" } \
                 /^[ \t]*$$/ { next } \
                 /^[ \t]*#/ { next } \
-                { printf "0%u ", cnt++; print } \
-                /^[^#]/ { printf ".%s/%s ", $$1, $$3; print; \
-                          printf ".%s/ ", $$1; print; \
+                /^[^#]/ { sub(/[ \t]*#.*$$/, "");\
+                          printf ":%s/%s ", $$1, $$3; print; \
+                          printf ":%s/ ", $$1; print; \
                           printf "=%s/%s ", $$2, $$3; print; \
                           printf "=%s/ ", $$2; print; \
                           for (i = 4; i <= NF && !($$i ~ /^#/); ++i) \
-                            { printf ".%s/%s ", $$i, $$3; print; \
-                              printf ".%s/ ", $$i; print } }' $^ | \
+                            { printf ":%s/%s ", $$i, $$3; print; \
+                              printf ":%s/ ", $$i; print } }' $^ | \
        $(MAKEDB) -o $@ -
        @echo "done."
 
 $(VAR_DB)/shadow.db: /etc/shadow
        @echo -n "$(patsubst %.db,%,$(@F))... "
-       @$(AWK) 'BEGIN { FS=":"; OFS=":"; cnt=0 } \
+       @$(AWK) 'BEGIN { FS=":"; OFS=":" } \
                 /^[ \t]*$$/ { next } \
                 /^[ \t]*#/ { next } \
-                { printf "0%u ", cnt++; print } \
                 /^[^#]/ { printf ".%s ", $$1; print }' $^ | \
        (umask 077 && $(MAKEDB) -o $@ -)
        @echo "done."
@@ -126,14 +118,38 @@ $(VAR_DB)/shadow.db: /etc/shadow
          echo; \
        fi
 
+$(VAR_DB)/gshadow.db: /etc/gshadow
+       @echo -n "$(patsubst %.db,%,$(@F))... "
+       @$(AWK) 'BEGIN { FS=":"; OFS=":" } \
+                /^[ \t]*$$/ { next } \
+                /^[ \t]*#/ { next } \
+                /^[^#]/ { printf ".%s ", $$1; print }' $^ | \
+       (umask 077 && $(MAKEDB) -o $@ -)
+       @echo "done."
+       @if chgrp shadow $@ 2>/dev/null; then \
+         chmod g+r $@; \
+       else \
+         chown 0 $@; chgrp 0 $@; chmod 600 $@; \
+         echo; \
+         echo "Warning: The shadow group database $@"; \
+         echo "has been set to be readable only by root.  You may want"; \
+         echo "to make it readable by the \`shadow' group depending"; \
+         echo "on your configuration."; \
+         echo; \
+       fi
+
 $(VAR_DB)/netgroup.db: /etc/netgroup
        @echo -n "$(patsubst %.db,%,$(@F))... "
-       @$(AWK) 'BEGIN { cnt=0 } \
+       @$(AWK) 'BEGIN { ini=1 } \
                 /^[ \t]*$$/ { next } \
                 /^[ \t]*#/ { next } \
-                { printf "0%u ", cnt++; print } \
-                /^[^#]/ { end=sub(/\\/, " "); \
+                /^[^#]/ { if (sub(/[ \t]*\\$$/, " ") == 0) end="\n"; \
+                          else end=""; \
                           gsub(/[ \t]+/, " "); \
-                          if(end == 1) printf "%s", $$0; else print }' $^ | \
+                          sub(/^[ \t]*/, ""); \
+                          if (ini == 0) printf "%s%s", $$0, end; \
+                          else printf ".%s %s%s", $$1, $$0, end; \
+                          ini=end == "" ? 0 : 1; } \
+                          END { if (ini==0) printf "\n" }' $^ | \
        $(MAKEDB) -o $@ -
        @echo "done."
index a01b2350aac555c187072aa07239156d4b699471..687414b74ff1e95694a3ad6a69ee7a2d4c6b56d7 100644 (file)
@@ -34,7 +34,7 @@
 #include <unistd.h>
 #include <sys/mman.h>
 #include <sys/stat.h>
-#include "nss_db/dummy-db.h"
+#include "nss_db/nss_db.h"
 
 /* Get libc version number.  */
 #include "../version.h"
 
 #define PACKAGE _libc_intl_domainname
 
-/* String table index type.  */
-typedef uint32_t stridx_t;
-
-/* Database file header.  */
-struct nss_db_header
-{
-  uint32_t magic;
-#define NSS_DB_MAGIC 0xdd110601
-  uint32_t ndbs;
-  uint64_t valstroffset;
-  uint64_t valstrlen;
-  struct
-  {
-    char id;
-    enum nss_db_type { nss_db_type_hash = 0,
-                      nss_db_type_iterate,
-                      nss_db_type_int4 } type:8;
-    char pad[sizeof (uint32_t) - 2];
-    uint32_t hashsize;
-    uint64_t hashoffset;
-    uint64_t stroffset;
-  } dbs[0];
-};
-
-struct nss_db_entry
-{
-  stridx_t keyidx;
-  stridx_t dataidx;
-};
-
-
 /* List of data bases.  */
 struct database
 {
   char dbid;
-  enum nss_db_type type;
   struct database *next;
   void *entries;
   size_t nentries;
-  size_t keystrlen;
   size_t nhashentries;
-  struct nss_db_entry *hashtable;
+  stridx_t *hashtable;
+  size_t keystrlen;
+  stridx_t *keyidxtab;
   char *keystrtab;
 } *databases;
 static size_t ndatabases;
+static size_t nhashentries;
 static size_t valstrlen;
 static void *valstrtree;
 static char *valstrtab;
@@ -101,7 +71,6 @@ static char *valstrtab;
 /* Database entry.  */
 struct dbentry
 {
-  size_t keylen;
   stridx_t validx;
   uint32_t hashval;
   char str[0];
@@ -115,16 +84,6 @@ struct valstrentry
 };
 
 
-/* Database type specifiers.  */
-struct dbtype
-{
-  char dbid;
-  enum nss_db_type type;
-  struct dbtype *next;
-};
-static struct dbtype *dbtypes;
-
-
 /* True if any entry has been added.  */
 static bool any_dbentry;
 
@@ -154,10 +113,6 @@ static const struct argp_option options[] =
   { "undo", 'u', NULL, 0,
     N_("Print content of database file, one entry a line") },
   { NULL, 0, NULL, 0, N_("Select index type") },
-  { "iterate", 'I', "KEY", 0,
-    N_("Index identified by KEY used to iterate over database") },
-  { "binary", 'B', "KEY", 0,
-    N_("Index identified by KEY has binary key value") },
   { NULL, 0, NULL, 0, NULL }
 };
 
@@ -210,7 +165,7 @@ main (int argc, char *argv[])
   const char *input_name;
   FILE *input_file;
   int remaining;
-  int mode = 0666;
+  int mode = 0644;
 
   /* Set locale via LC_ALL.  */
   setlocale (LC_ALL, "");
@@ -292,7 +247,12 @@ main (int argc, char *argv[])
 
   /* Bail out if nothing is to be done.  */
   if (!any_dbentry)
-    error (EXIT_SUCCESS, 0, gettext ("no entries to be processed"));
+    {
+      if (be_quiet)
+       return EXIT_SUCCESS;
+      else
+       error (EXIT_SUCCESS, 0, gettext ("no entries to be processed"));
+    }
 
   /* Compute hash and string tables.  */
   compute_tables ();
@@ -308,7 +268,6 @@ main (int argc, char *argv[])
   reset_file_creation_context ();
   if (fd == -1)
     error (EXIT_FAILURE, errno, gettext ("cannot create temporary file"));
-  // XXX SELinux context
 
   status = write_output (fd);
 
@@ -352,7 +311,6 @@ main (int argc, char *argv[])
 static error_t
 parse_opt (int key, char *arg, struct argp_state *state)
 {
-  struct dbtype *newtype;
   switch (key)
     {
     case 'f':
@@ -367,17 +325,6 @@ parse_opt (int key, char *arg, struct argp_state *state)
     case 'u':
       do_undo = 1;
       break;
-    case 'I':
-    case 'B':
-      if (arg[0] == '\0' || arg[1] != '\0')
-       error (EXIT_FAILURE, 0, gettext ("\
-argument for option to specify database type must be a single-byte character"));
-      newtype = xmalloc (sizeof (struct dbtype));
-      newtype->dbid = arg[0];
-      newtype->type = key == 'I' ? nss_db_type_iterate : nss_db_type_int4;
-      newtype->next = dbtypes;
-      dbtypes = newtype;
-      break;
     default:
       return ARGP_ERR_UNKNOWN;
     }
@@ -424,13 +371,7 @@ dbentry_compare (const void *p1, const void *p2)
   if (d1->hashval != d2->hashval)
     return d1->hashval < d2->hashval ? -1 : 1;
 
-  if (d1->keylen < d2->keylen)
-    return -1;
-
-  if (d1->keylen > d2->keylen)
-    return 1;
-
-  return memcmp (d1->str, d2->str, d1->keylen);
+  return strcmp (d1->str, d2->str);
 }
 
 
@@ -522,22 +463,11 @@ process_input (input, inname, to_lowercase, be_quiet)
            {
              last_database = xmalloc (sizeof (*last_database));
              last_database->dbid = key[0];
-             last_database->type = nss_db_type_hash;   /* Default.  */
              last_database->next = databases;
              last_database->entries = NULL;
              last_database->nentries = 0;
              last_database->keystrlen = 0;
              databases = last_database;
-
-             struct dbtype *typeit = dbtypes;
-             while (typeit != NULL)
-               if (typeit->dbid == last_database->dbid)
-                 {
-                   last_database->type = typeit->type;
-                   break;
-                 }
-               else
-                 typeit = typeit->next;
            }
        }
 
@@ -545,24 +475,6 @@ process_input (input, inname, to_lowercase, be_quiet)
       ++key;
       --keylen;
 
-      /* Check the key value if it has to be numeric.  */
-      unsigned long int keyvalue = 0;
-      if (last_database->type != nss_db_type_hash)
-       {
-         char *endp;
-         errno = 0;
-         keyvalue = strtoul (key, &endp, 0);
-         if ((keyvalue == ULONG_MAX && errno == ERANGE)
-             || keyvalue > ~((stridx_t) 0))
-           error (EXIT_FAILURE, 0,
-                  gettext ("index value in line %zu too large"), linenr);
-
-         if (*endp != '\0')
-           error (EXIT_FAILURE, 0,
-                  gettext ("index value in line %zu is not a number"),
-                  linenr);
-       }
-
       /* Store the data.  */
       struct valstrentry *nentry = xmalloc (sizeof (struct valstrentry)
                                            + datalen);
@@ -584,24 +496,10 @@ process_input (input, inname, to_lowercase, be_quiet)
        valstrlen += datalen;
 
       /* Store the key.  */
-      struct dbentry *newp;
-      if (last_database->type == nss_db_type_hash)
-       {
-         newp = xmalloc (sizeof (struct dbentry) + keylen);
-         newp->keylen = keylen;
-         newp->validx = nentry->idx;
-         newp->hashval = __hash_string (key);
-         memcpy (newp->str, key, keylen);
-       }
-      else
-       {
-         newp = xmalloc (sizeof (struct dbentry) + sizeof (stridx_t));
-         newp->keylen = keylen = sizeof (stridx_t);
-         newp->validx = nentry->idx;
-         newp->hashval = keyvalue;
-         stridx_t value = keyvalue;
-         memcpy (newp->str, &value, sizeof (stridx_t));
-       }
+      struct dbentry *newp = xmalloc (sizeof (struct dbentry) + keylen);
+      newp->validx = nentry->idx;
+      newp->hashval = __hash_string (key);
+      memcpy (newp->str, key, keylen);
 
       struct dbentry **found = tsearch (newp, &last_database->entries,
                                        dbentry_compare);
@@ -657,29 +555,14 @@ compute_tables (void)
       {
        ++ndatabases;
 
-       if (db->type == nss_db_type_iterate)
-         {
-           /* We need no hash table and no key value table in this case.  */
-           db->nhashentries = 0;
-           db->hashtable = NULL;
-           db->keystrtab = NULL;
-           db->keystrlen = 0;
-           continue;
-         }
-
-       if (db->keystrlen > ~((stridx_t) 0))
-         error (EXIT_FAILURE, 0, gettext ("\
-table size too large; recompile with larger stridx_t"));
-
        /* We simply use an odd number large than twice the number of
           elements to store in the hash table for the size.  This gives
           enough efficiency.  */
        db->nhashentries = db->nentries * 2 + 1;
-       db->hashtable = xmalloc (db->nhashentries
-                                * sizeof (struct nss_db_entry));
-       memset (db->hashtable, '\xff',
-               db->nhashentries * sizeof (struct nss_db_entry));
-       db->keystrlen = roundup (db->keystrlen, sizeof (stridx_t));
+       db->hashtable = xmalloc (db->nhashentries * sizeof (stridx_t));
+       memset (db->hashtable, '\xff', db->nhashentries * sizeof (stridx_t));
+       db->keyidxtab = xmalloc (db->nhashentries * sizeof (stridx_t));
+       memset (db->keyidxtab, '\xff', db->nhashentries * sizeof (stridx_t));
        db->keystrtab = xmalloc (db->keystrlen);
 
        size_t max_chainlength = 0;
@@ -693,21 +576,21 @@ table size too large; recompile with larger stridx_t"));
          const struct dbentry *dbe = *(const struct dbentry **) nodep;
 
          ptrdiff_t stridx = wp - db->keystrtab;
-         wp = mempcpy (wp, dbe->str, dbe->keylen);
+         wp = stpcpy (wp, dbe->str) + 1;
 
          size_t hidx = dbe->hashval % db->nhashentries;
          size_t hval2 = 1 + dbe->hashval % (db->nhashentries - 2);
          size_t chainlength = 0;
 
-         while (db->hashtable[hidx].keyidx != ~((stridx_t) 0))
+         while (db->hashtable[hidx] != ~((stridx_t) 0))
            {
              ++chainlength;
              if ((hidx += hval2) >= db->nhashentries)
                hidx -= db->nhashentries;
            }
 
-         db->hashtable[hidx].keyidx = stridx;
-         db->hashtable[hidx].dataidx = dbe->validx;
+         db->hashtable[hidx] = dbe->validx;
+         db->keyidxtab[hidx] = stridx;
 
          max_chainlength = MAX (max_chainlength, chainlength);
        }
@@ -716,8 +599,7 @@ table size too large; recompile with larger stridx_t"));
 
        // XXX if hash length is too long resize table and start again
 
-       while ((wp - db->keystrtab) % sizeof (stridx_t) != 0)
-         *wp++ = '\0';
+       nhashentries += db->nhashentries;
     }
 }
 
@@ -736,7 +618,7 @@ write_output (int fd)
   header->valstrlen = valstrlen;
 
   size_t filled_dbs = 0;
-  struct iovec iov[2 + 2 * ndatabases];
+  struct iovec iov[2 + ndatabases * 3];
   iov[0].iov_base = header;
   iov[0].iov_len = file_offset;
 
@@ -744,6 +626,7 @@ write_output (int fd)
   iov[1].iov_len = valstrlen;
   file_offset += valstrlen;
 
+  size_t keydataoffset = file_offset + nhashentries * sizeof (stridx_t);
   for (struct database *db = databases; db != NULL; db = db->next)
     if (db->entries != NULL)
       {
@@ -751,28 +634,35 @@ write_output (int fd)
        assert (filled_dbs < ndatabases);
 
        header->dbs[filled_dbs].id = db->dbid;
-       header->dbs[filled_dbs].type = db->type;
        memset (header->dbs[filled_dbs].pad, '\0',
                sizeof (header->dbs[0].pad));
        header->dbs[filled_dbs].hashsize = db->nhashentries;
 
-       iov[2 + filled_dbs * 2].iov_base = db->hashtable;
-       iov[2 + filled_dbs * 2].iov_len = (db->nhashentries
-                                          * sizeof (struct nss_db_entry));
+       iov[2 + filled_dbs].iov_base = db->hashtable;
+       iov[2 + filled_dbs].iov_len = db-> nhashentries * sizeof (stridx_t);
        header->dbs[filled_dbs].hashoffset = file_offset;
-       file_offset += iov[2 + filled_dbs * 2].iov_len;
+       file_offset += iov[2 + filled_dbs].iov_len;
 
-       iov[3 + filled_dbs * 2].iov_base = db->keystrtab;
-       iov[3 + filled_dbs * 2].iov_len = db->keystrlen;
-       header->dbs[filled_dbs].stroffset = file_offset;
-       file_offset += iov[3 + filled_dbs * 2].iov_len;
+       iov[2 + ndatabases + filled_dbs * 2].iov_base = db->keyidxtab;
+       iov[2 + ndatabases + filled_dbs * 2].iov_len
+         = db-> nhashentries * sizeof (stridx_t);
+       header->dbs[filled_dbs].keyidxoffset = keydataoffset;
+       keydataoffset += iov[2 + ndatabases + filled_dbs * 2].iov_len;
+
+       iov[3 + ndatabases + filled_dbs * 2].iov_base = db->keystrtab;
+       iov[3 + ndatabases + filled_dbs * 2].iov_len = db->keystrlen;
+       header->dbs[filled_dbs].keystroffset = keydataoffset;
+       keydataoffset += iov[3 + ndatabases + filled_dbs * 2].iov_len;
 
        ++filled_dbs;
       }
 
   assert (filled_dbs == ndatabases);
+  assert (file_offset == (iov[0].iov_len + iov[1].iov_len
+                         + nhashentries * sizeof (stridx_t)));
+  header->allocate = file_offset;
 
-  if (writev (fd, iov, 2 + 2 * ndatabases) != file_offset)
+  if (writev (fd, iov, 2 + ndatabases * 3) != keydataoffset)
     {
       error (0, errno, gettext ("failed to write new database file"));
       return EXIT_FAILURE;
@@ -801,42 +691,21 @@ print_database (int fd)
 
   for (unsigned int dbidx = 0; dbidx < header->ndbs; ++dbidx)
     {
+      const stridx_t *stridxtab
+       = ((const stridx_t *) ((const char *) header
+                              + header->dbs[dbidx].keyidxoffset));
       const char *keystrtab
-       = (const char *) header + header->dbs[dbidx].stroffset;
-      const struct nss_db_entry *hashtab
-       = (const struct nss_db_entry *) ((const char *) header
-                                        + header->dbs[dbidx].hashoffset);
-
-      if (header->dbs[dbidx].type == nss_db_type_hash)
-       {
-         for (uint32_t hidx = 0; hidx < header->dbs[dbidx].hashsize; ++hidx)
-           if (hashtab[hidx].keyidx != ~((stridx_t) 0))
-             printf ("%c%s %s\n",
-                     header->dbs[dbidx].id,
-                     keystrtab + hashtab[hidx].keyidx,
-                     valstrtab + hashtab[hidx].dataidx);
-       }
-      else if (header->dbs[dbidx].type == nss_db_type_iterate)
-       {
-         const char *endvalstrtab = valstrtab + header->valstrlen;
-         const char *cp = valstrtab;
-         unsigned int count = 0;
-         while (cp < endvalstrtab && *cp != '\0')
-           {
-             printf ("%c%u %s\n", header->dbs[dbidx].id, count++, cp);
-             cp = rawmemchr (cp, '\0') + 1;
-           }
-       }
-      else
-       {
-         assert (header->dbs[dbidx].type == nss_db_type_int4);
-         for (uint32_t hidx = 0; hidx < header->dbs[dbidx].hashsize; ++hidx)
-           if (hashtab[hidx].keyidx != ~((stridx_t) 0))
-             printf ("%c%" PRIu32 " %s\n",
-                     header->dbs[dbidx].id,
-                     *((uint32_t *) (keystrtab + hashtab[hidx].keyidx)),
-                     valstrtab + hashtab[hidx].dataidx);
-       }
+       = (const char *) header + header->dbs[dbidx].keystroffset;
+      const stridx_t *hashtab
+       = (const stridx_t *) ((const char *) header
+                             + header->dbs[dbidx].hashoffset);
+
+      for (uint32_t hidx = 0; hidx < header->dbs[dbidx].hashsize; ++hidx)
+       if (hashtab[hidx] != ~((stridx_t) 0))
+         printf ("%c%s %s\n",
+                 header->dbs[dbidx].id,
+                 keystrtab + stridxtab[hidx],
+                 valstrtab + hashtab[hidx]);
     }
 
   return EXIT_SUCCESS;
index aa8cfd0746db6041f9d7add572fbef98bc1df0d7..30026b1866a62cb1a349c399c0f42ea655cd1aea 100644 (file)
@@ -1,5 +1,5 @@
 /* Common code for DB-based databases in nss_db module.
-   Copyright (C) 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
+   Copyright (C) 1996-2000, 2011 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
 
 #include <dlfcn.h>
 #include <fcntl.h>
+#include <sys/mman.h>
 #include <bits/libc-lock.h>
 #include "nsswitch.h"
 #include "nss_db.h"
 
+/* The hashing function we use.  */
+#include "../intl/hash-string.h"
+
 /* These symbols are defined by the including source file:
 
    ENTNAME -- database name of the structure and functions (hostent, pwent).
 #define        DBFILE          _PATH_VARDB DATABASE ".db"
 
 #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.  */
-__libc_lock_define_initialized (static, lock)
-\f
-/* Maintenance of the shared handle open on the database.  */
+/* State for this database.  */
+static struct nss_db_map state;
+/* Lock to protect the state and global variables.  */
+__libc_lock_define (static , lock);
 
-static NSS_DB *db;
+/* Maintenance of the shared handle open on the database.  */
 static int keep_db;
-static int entidx;
-
+static const char *entidx;
 
+\f
 /* Open the database.  */
 enum nss_status
 CONCAT(_nss_db_set,ENTNAME) (int stayopen)
@@ -65,13 +69,13 @@ CONCAT(_nss_db_set,ENTNAME) (int stayopen)
 
   __libc_lock_lock (lock);
 
-  status = internal_setent (DBFILE, &db);
+  status = internal_setent (DBFILE, &state);
 
   /* Remember STAYOPEN flag.  */
-  if (db != NULL)
+  if (status == NSS_STATUS_SUCCESS)
     keep_db |= stayopen;
   /* Reset the sequential index.  */
-  entidx = 0;
+  entidx  = (const char *) state.header + state.header->valstroffset;
 
   __libc_lock_unlock (lock);
 
@@ -85,7 +89,7 @@ CONCAT(_nss_db_end,ENTNAME) (void)
 {
   __libc_lock_lock (lock);
 
-  internal_endent (&db);
+  internal_endent (&state);
 
   /* Reset STAYOPEN flag.  */
   keep_db = 0;
@@ -94,132 +98,128 @@ CONCAT(_nss_db_end,ENTNAME) (void)
 
   return NSS_STATUS_SUCCESS;
 }
-\f
-/* Do a database lookup for KEY.  */
-static enum nss_status
-lookup (DBT *key, struct STRUCTURE *result,
-       void *buffer, size_t buflen, int *errnop H_ERRNO_PROTO EXTRA_ARGS_DECL)
-{
-  char *p;
-  enum nss_status status;
-  int err;
-  DBT value;
-
-  /* Open the database.  */
-  if (db == NULL)
-    {
-      status = internal_setent (DBFILE, &db);
-      if (status != NSS_STATUS_SUCCESS)
-       {
-         *errnop = errno;
-         H_ERRNO_SET (NETDB_INTERNAL);
-         return status;
-       }
-    }
-
-  /* Succeed iff it matches a value that parses correctly.  */
-  value.flags = 0;
-  err = DL_CALL_FCT (db->get, (db->db, NULL, key, &value, 0));
-  if (err != 0)
-    {
-      if (err == db_notfound)
-       {
-         H_ERRNO_SET (HOST_NOT_FOUND);
-         status = NSS_STATUS_NOTFOUND;
-       }
-      else
-       {
-         *errnop = err;
-         H_ERRNO_SET (NETDB_INTERNAL);
-         status = NSS_STATUS_UNAVAIL;
-       }
-    }
-  else if (buflen < value.size)
-    {
-      /* No room to copy the data to.  */
-      *errnop = ERANGE;
-      H_ERRNO_SET (NETDB_INTERNAL);
-      status = NSS_STATUS_TRYAGAIN;
-    }
-  else
-    {
-      /* Copy the result to a safe place.  */
-      p = (char *) memcpy (buffer, value.data, value.size);
-
-      /* Skip leading blanks.  */
-      while (isspace (*p))
-       ++p;
-
-      err = parse_line (p, result, buffer, buflen, errnop EXTRA_ARGS);
-
-      if (err == 0)
-       {
-         /* If the key begins with '0' we are trying to get the next
-            entry.  We want to ignore unparsable lines in this case.  */
-         if (((char *) key->data)[0] == '0')
-           {
-             /* Super magical return value.  We need to tell our caller
-                that it should continue looping.  This value cannot
-                happen in other cases.  */
-             status = NSS_STATUS_RETURN;
-           }
-         else
-           {
-             H_ERRNO_SET (HOST_NOT_FOUND);
-             status = NSS_STATUS_NOTFOUND;
-           }
-       }
-      else if (err < 0)
-       {
-         H_ERRNO_SET (NETDB_INTERNAL);
-         status = NSS_STATUS_TRYAGAIN;
-       }
-      else
-       status = NSS_STATUS_SUCCESS;
-    }
-
-  if (! keep_db)
-    internal_endent (&db);
-
-  return status;
-}
 
 
 /* Macro for defining lookup functions for this DB-based database.
 
    NAME is the name of the lookup; e.g. `pwnam'.
 
+   DB_CHAR is index indicator for the database.
+
    KEYPATTERN gives `printf' args to construct a key string;
-   e.g. `(".%s", name)'.
+   e.g. `("%d", id)'.
 
    KEYSIZE gives the allocation size of a buffer to construct it in;
-   e.g. `1 + strlen (name)'.
+   e.g. `1 + sizeof (id) * 4'.
 
-   PROTO describes the arguments for the lookup key;
-   e.g. `const char *name'.
+   PROTO is the potentially empty list of other parameters.
 
-   BREAK_IF_MATCH is ignored, but used by ../nss_files/files-XXX.c.  */
+   BREAK_IF_MATCH is a block of code which compares `struct STRUCTURE *result'
+   to the lookup key arguments and does `break;' if they match.  */
 
-#define DB_LOOKUP(name, keysize, keypattern, break_if_match, proto...)       \
+#define DB_LOOKUP(name, db_char, keysize, keypattern, break_if_match, proto...)\
 enum nss_status                                                                      \
-_nss_db_get##name##_r (proto,                                                \
-                      struct STRUCTURE *result,                              \
-                      char *buffer, size_t buflen, int *errnop H_ERRNO_PROTO)\
+ _nss_db_get##name##_r (proto, struct STRUCTURE *result,                     \
+                       char *buffer, size_t buflen, int *errnop H_ERRNO_PROTO)\
 {                                                                            \
-  DBT key;                                                                   \
-  enum nss_status status;                                                    \
-  const size_t size = (keysize) + 1;                                         \
-  key.data = __alloca (size);                                                \
-  key.size = KEYPRINTF keypattern;                                           \
-  key.flags = 0;                                                             \
-  __libc_lock_lock (lock);                                                   \
-  status = lookup (&key, result, buffer, buflen, errnop H_ERRNO_ARG          \
-                  EXTRA_ARGS_VALUE);                                         \
-  __libc_lock_unlock (lock);                                                 \
+  enum nss_status status = NSS_STATUS_SUCCESS;                               \
+  struct nss_db_map state = { NULL, 0 };                                     \
+  struct parser_data *data = (void *) buffer;                                \
+                                                                             \
+  if (buflen < sizeof *data)                                                 \
+    {                                                                        \
+      *errnop = ERANGE;                                                              \
+      H_ERRNO_SET (NETDB_INTERNAL);                                          \
+      return NSS_STATUS_TRYAGAIN;                                            \
+    }                                                                        \
+                                                                             \
+  status = internal_setent (DBFILE, &state);                                 \
+  if (status != NSS_STATUS_SUCCESS)                                          \
+    {                                                                        \
+      *errnop = errno;                                                       \
+      H_ERRNO_SET (NETDB_INTERNAL);                                          \
+      return status;                                                         \
+    }                                                                        \
+                                                                             \
+  if (status == NSS_STATUS_SUCCESS)                                          \
+    {                                                                        \
+      const struct nss_db_header *header = state.header;                     \
+      int i;                                                                 \
+      for (i = 0; i < header->ndbs; ++i)                                     \
+       if (header->dbs[i].id == db_char)                                     \
+         break;                                                              \
+      if (i == header->ndbs)                                                 \
+       {                                                                     \
+         status = NSS_STATUS_UNAVAIL;                                        \
+         goto out;                                                           \
+       }                                                                     \
+                                                                             \
+      char *key;                                                             \
+      if (db_char == '.')                                                    \
+       key = (char *) IGNOREPATTERN keypattern;                              \
+      else                                                                   \
+       {                                                                     \
+         const size_t size = (keysize) + 1;                                  \
+         key = alloca (size);                                                \
+                                                                             \
+         KEYPRINTF keypattern;                                               \
+       }                                                                     \
+                                                                             \
+      const stridx_t *hashtable                                                      \
+       = (const stridx_t *) ((const char *) header                           \
+                             + header->dbs[i].hashoffset);                   \
+      const char *valstrtab = (const char *) header + header->valstroffset;   \
+      uint32_t hashval = __hash_string (key);                                \
+      size_t hidx = hashval % header->dbs[i].hashsize;                       \
+      size_t hval2 = 1 + hashval % (header->dbs[i].hashsize - 2);            \
+                                                                             \
+      status = NSS_STATUS_NOTFOUND;                                          \
+      while (hashtable[hidx] != ~((stridx_t) 0))                             \
+       {                                                                     \
+         const char *valstr = valstrtab + hashtable[hidx];                   \
+         size_t len = strlen (valstr) + 1;                                   \
+         if (len > buflen)                                                   \
+           {                                                                 \
+             /* No room to copy the data to.  */                             \
+             *errnop = ERANGE;                                               \
+             H_ERRNO_SET (NETDB_INTERNAL);                                   \
+             status = NSS_STATUS_TRYAGAIN;                                   \
+             break;                                                          \
+           }                                                                 \
+                                                                             \
+         /* Copy the string to a place where it can be modified.  */         \
+         char *p = memcpy (buffer, valstr, len);                             \
+                                                                             \
+         int err = parse_line (p, result, data, buflen, errnop               \
+                               EXTRA_ARGS);                                  \
+         if (err > 0)                                                        \
+           {                                                                 \
+             status = NSS_STATUS_SUCCESS;                                    \
+             break_if_match;                                                 \
+             status = NSS_STATUS_NOTFOUND;                                   \
+           }                                                                 \
+         else if (err == -1)                                                 \
+           {                                                                 \
+             H_ERRNO_SET (NETDB_INTERNAL);                                   \
+             status = NSS_STATUS_TRYAGAIN;                                   \
+             break;                                                          \
+           }                                                                 \
+                                                                             \
+         if ((hidx += hval2) >= header->dbs[i].hashsize)                     \
+           hidx -= header->dbs[i].hashsize;                                  \
+       }                                                                     \
+                                                                             \
+      if (status == NSS_STATUS_NOTFOUND)                                     \
+       H_ERRNO_SET (HOST_NOT_FOUND);                                         \
+    }                                                                        \
+ out:                                                                        \
+  internal_endent (&state);                                                  \
+                                                                             \
   return status;                                                             \
 }
 
-#define KEYPRINTF(pattern, args...) snprintf (key.data, size, pattern ,##args)
+#define KEYPRINTF(pattern, args...) snprintf (key, size, pattern ,##args)
+#define IGNOREPATTERN(pattern, arg1, args...) (char *) (uintptr_t) arg1
 \f
 
 
@@ -231,30 +231,72 @@ CONCAT(_nss_db_get,ENTNAME_r) (struct STRUCTURE *result, char *buffer,
 {
   /* Return next entry in host file.  */
   enum nss_status status;
-  char buf[20];
-  DBT key;
+  struct parser_data *data = (void *) buffer;
+
+  if (buflen < sizeof *data)
+    {
+      *errnop = ERANGE;
+      H_ERRNO_SET (NETDB_INTERNAL);
+      return NSS_STATUS_TRYAGAIN;
+    }
 
   __libc_lock_lock (lock);
 
-  /* Loop until we find a valid entry or hit EOF.  See above for the
-     special meaning of the status value.  */
-  do
+  if (state.header == NULL)
     {
-      key.size = snprintf (key.data = buf, sizeof buf, "0%u", entidx++);
-      key.flags = 0;
-      status = lookup (&key, result, buffer, buflen, errnop H_ERRNO_ARG
-                      EXTRA_ARGS_VALUE);
-      if (status == NSS_STATUS_TRYAGAIN
-#ifdef NEED_H_ERRNO
-         && *herrnop == NETDB_INTERNAL
-#endif
-         && *errnop == ERANGE)
-       /* Give the user a chance to get the same entry with a larger
-          buffer.  */
-       --entidx;
+      status = internal_setent (DBFILE, &state);
+      if (status != NSS_STATUS_SUCCESS)
+       {
+         *errnop = errno;
+         H_ERRNO_SET (NETDB_INTERNAL);
+         goto out;
+       }
+    }
+
+  status = NSS_STATUS_UNAVAIL;
+  if (state.header != MAP_FAILED)
+    {
+      const char *const end = ((const char *) state.header
+                              + state.header->valstroffset
+                              + state.header->valstrlen);
+      while (entidx < end)
+       {
+         const char *next = rawmemchr (entidx, '\0') + 1;
+         size_t len = next - entidx;
+
+         if (len > buflen)
+           {
+             /* No room to copy the data to.  */
+             *errnop = ERANGE;
+             H_ERRNO_SET (NETDB_INTERNAL);
+             status = NSS_STATUS_TRYAGAIN;
+             break;
+           }
+
+         /* Copy the string to a place where it can be modified.  */
+         char *p = memcpy (buffer, entidx, len);
+
+         int err = parse_line (p, result, data, buflen, errnop EXTRA_ARGS);
+
+         if (err > 0)
+           {
+             status = NSS_STATUS_SUCCESS;
+             entidx = next;
+             break;
+           }
+         if (err < 0)
+           {
+             H_ERRNO_SET (HOST_NOT_FOUND);
+             status = NSS_STATUS_NOTFOUND;
+             break;
+           }
+
+         /* Continue with the next record, this one is ill-formed.  */
+         entidx = next;
+       }
     }
-  while (status == NSS_STATUS_RETURN);
 
+ out:
   __libc_lock_unlock (lock);
 
   return status;
diff --git a/nss/nss_db/db-alias.c b/nss/nss_db/db-alias.c
deleted file mode 100644 (file)
index de468cc..0000000
+++ /dev/null
@@ -1,215 +0,0 @@
-/* Mail alias file parser in nss_db module.
-   Copyright (C) 1996, 1997, 1998, 1999, 2000 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 Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-   02111-1307 USA.  */
-
-#include <aliases.h>
-#include <alloca.h>
-#include <ctype.h>
-#include <dlfcn.h>
-#include <errno.h>
-#include <bits/libc-lock.h>
-#include <paths.h>
-#include <string.h>
-
-#include "nsswitch.h"
-#include "nss_db.h"
-
-/* Locks the static variables in this file.  */
-__libc_lock_define_initialized (static, lock)
-\f
-/* Maintenance of the shared handle open on the database.  */
-
-static NSS_DB *db;
-static int keep_db;
-static unsigned int entidx;    /* Index for `getaliasent_r'. */
-
-
-/* Open database.  */
-enum nss_status
-_nss_db_setaliasent (int stayopen)
-{
-  enum nss_status status;
-
-  __libc_lock_lock (lock);
-
-  status = internal_setent (_PATH_VARDB "aliases.db", &db);
-
-  /* Remember STAYOPEN flag.  */
-  if (db != NULL)
-    keep_db |= stayopen;
-
-  /* Reset the sequential index.  */
-  entidx = 0;
-
-  __libc_lock_unlock (lock);
-
-  return status;
-}
-
-
-/* Close it again.  */
-enum nss_status
-_nss_db_endaliasent (void)
-{
-  __libc_lock_lock (lock);
-
-  internal_endent (&db);
-
-  /* Reset STAYOPEN flag.  */
-  keep_db = 0;
-
-  __libc_lock_unlock (lock);
-
-  return NSS_STATUS_SUCCESS;
-}
-\f
-/* 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 (DBT *key, struct aliasent *result, char *buffer,
-       size_t buflen, int *errnop)
-{
-  enum nss_status status;
-  DBT value;
-
-  /* Open the database.  */
-  if (db == NULL)
-    {
-      status = internal_setent (_PATH_VARDB "aliases.db", &db);
-      if (status != NSS_STATUS_SUCCESS)
-       {
-         *errnop = errno;
-         return status;
-       }
-    }
-
-  value.flags = 0;
-  if (DL_CALL_FCT (db->get, (db->db, NULL, key, &value, 0)) == 0)
-    {
-      const char *src = value.data;
-      char *cp;
-      size_t cnt;
-
-      result->alias_members_len = 0;
-
-      /* We now have to fill the BUFFER with all the information. */
-      if (buflen < key->size + 1)
-       {
-       no_more_room:
-         *errnop = ERANGE;
-         return NSS_STATUS_TRYAGAIN;
-       }
-
-      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 (&db);
-
-  return status;
-}
-\f
-enum nss_status
-_nss_db_getaliasent_r (struct aliasent *result, char *buffer, size_t buflen,
-                      int *errnop)
-{
-  /* Return next entry in alias file.  */
-  enum nss_status status;
-  char buf[20];
-  DBT key;
-
-  __libc_lock_lock (lock);
-  key.size = snprintf (key.data = buf, sizeof buf, "0%u", entidx++);
-  key.flags = 0;
-  status = lookup (&key, result, buffer, buflen, errnop);
-  if (status == NSS_STATUS_TRYAGAIN && *errnop == ERANGE)
-    /* Give the user a chance to get the same entry with a larger buffer.  */
-    --entidx;
-  __libc_lock_unlock (lock);
-
-  return status;
-}
-
-
-enum nss_status
-_nss_db_getaliasbyname_r (const char *name, struct aliasent *result,
-                         char *buffer, size_t buflen, int *errnop)
-{
-  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);
-  key.flags = 0;
-
-  __libc_lock_lock (lock);
-  status = lookup (&key, result, buffer, buflen, errnop);
-  __libc_lock_unlock (lock);
-
-  return status;
-}
index 47e845a6b900ae1d343fe4ca2387f6a7de638e6d..901d4f50b08393ffaea9f23a7118f6ab57273b87 100644 (file)
@@ -1,5 +1,5 @@
 /* Netgroup file parser in nss_db modules.
-   Copyright (C) 1996, 1997, 1999, 2000 Free Software Foundation, Inc.
+   Copyright (C) 1996, 1997, 1999, 2000, 2011 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
 
@@ -18,6 +18,7 @@
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA.  */
 
+#include <ctype.h>
 #include <dlfcn.h>
 #include <errno.h>
 #include <fcntl.h>
 #include "nsswitch.h"
 #include "nss_db.h"
 
-
-#define DBFILE         _PATH_VARDB "netgroup.db"
+/* The hashing function we use.  */
+#include "../intl/hash-string.h"
 
 
-/* Locks the static variables in this file.  */
-__libc_lock_define_initialized (static, lock)
+#define DBFILE         _PATH_VARDB "netgroup.db"
 \f
 /* Maintenance of the shared handle open on the database.  */
-static NSS_DB *db;
-static char *entry;
-static char *cursor;
-
 enum nss_status
-_nss_db_setnetgrent (const char *group)
+_nss_db_setnetgrent (const char *group, struct __netgrent *result)
 {
-  enum nss_status status;
-
-  __libc_lock_lock (lock);
-
-  status = internal_setent (DBFILE, &db);
+  struct nss_db_map state;
+  enum nss_status status = internal_setent (DBFILE, &state);
 
   if (status == NSS_STATUS_SUCCESS)
     {
-      DBT key = { data: (void *) group, size: strlen (group), flags: 0 };
-      DBT value;
-
-      value.flags = 0;
-      if (DL_CALL_FCT (db->get, (db->db, NULL, &key, &value, 0)) != 0)
-       status = NSS_STATUS_NOTFOUND;
-      else
-       cursor = entry = value.data;
+      const struct nss_db_header *header = state.header;
+      const stridx_t *hashtable
+       = (const stridx_t *) ((const char *) header
+                             + header->dbs[0].hashoffset);
+      const char *valstrtab = (const char *) header + header->valstroffset;
+      uint32_t hashval = __hash_string (group);
+      size_t grouplen = strlen (group);
+      size_t hidx = hashval % header->dbs[0].hashsize;
+      size_t hval2 = 1 + hashval % (header->dbs[0].hashsize - 2);
+
+      status = NSS_STATUS_NOTFOUND;
+      while (hashtable[hidx] != ~((stridx_t) 0))
+       {
+         const char *valstr = valstrtab + hashtable[hidx];
+
+         if (strncmp (valstr, group, grouplen) == 0
+             && isblank (valstr[grouplen]))
+           {
+             const char *cp = &valstr[grouplen + 1];
+             while (isblank (*cp))
+               ++cp;
+             if (*cp != '\0')
+               {
+                 result->data = strdup (cp);
+                 if (result->data == NULL)
+                   status = NSS_STATUS_TRYAGAIN;
+                 else
+                   {
+                     status = NSS_STATUS_SUCCESS;
+                     result->cursor = result->data;
+                   }
+                 break;
+               }
+           }
+
+         if ((hidx += hval2) >= header->dbs[0].hashsize)
+           hidx -= header->dbs[0].hashsize;
+       }
+
+      internal_endent (&state);
     }
 
-  __libc_lock_unlock (lock);
-
   return status;
 
 }
 
 
 enum nss_status
-_nss_db_endnetgrent (void)
+_nss_db_endnetgrent (struct __netgrent *result)
 {
-  __libc_lock_lock (lock);
-
-  internal_endent (&db);
-
-  __libc_lock_unlock (lock);
-
+  free (result->data);
+  result->data = NULL;
+  result->data_size = 0;
+  result->cursor = NULL;
   return NSS_STATUS_SUCCESS;
 }
 
@@ -91,13 +112,10 @@ enum nss_status
 _nss_db_getnetgrent_r (struct __netgrent *result, char *buffer, size_t buflen,
                       int *errnop)
 {
-  int status;
-
-  __libc_lock_lock (lock);
-
-  status = _nss_netgroup_parseline (&cursor, result, buffer, buflen, errnop);
+  enum nss_status status;
 
-  __libc_lock_unlock (lock);
+  status = _nss_netgroup_parseline (&result->cursor, result, buffer, buflen,
+                                   errnop);
 
   return status;
 }
index 94dfe5b7da77a4f87360eeb2afc8dd71d3c0ddc9..36ce494d0267935651302bdd5176187c4f45eaf4 100644 (file)
@@ -1,5 +1,5 @@
 /* Common database routines for nss_db.
-   Copyright (C) 2000 Free Software Foundation, Inc.
+   Copyright (C) 2000, 2011 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
 #include <dlfcn.h>
 #include <stdlib.h>
 #include <string.h>
-#include <bits/libc-lock.h>
+#include <sys/mman.h>
+#include <not-cancel.h>
 
-#include "dummy-db.h"
+#include <kernel-features.h>
 #include "nss_db.h"
 
-/* This file contains the functions used to open and close the databases
-   read by the rest of libnss_db.  Not all of them are thread safe;
-   make sure the caller does the appropriate locking.
-
-   We dynamically load the database library, so that it does not have
-   to be present when glibc is compiled.  Once loaded, the database
-   library is never never unloaded again until the libnss_db module is
-   unloaded (from the free_mem routine in nsswitch.c) -- we catch the
-   unload by providing a shlib destructor.  (XXX Does that actually
-   work?)  */
-
-/* Handle for the shared Berkeley DB library.  If non-null, the
-   database library is completely loaded and ready to be used by
-   multithreaded code.  */
-static void *libdb_handle;
-
-/* The version of the Berkeley DB library we are using.  */
-enum {
-  nodb,
-  db24,
-  db27,
-  db30
-} libdb_version;
-
-/* Pointer to the db_open function.  For use with DB 2.x.  */
-static int (*libdb_db_open) (const char *, int,
-                            uint32_t, int, void *, void *, void **);
-
-/* Pointer to the db_create function.  For use with DB 3.x.  */
-static int (*libdb_db_create) (void *, void *, uint32_t);
-
-/* Constants which vary from version to version are actually variables
-   here.  */
-int db_first;
-int db_next;
-int db_nooverwrite;
-int db_truncate;
-int db_rdonly;
-/* Variables which keep track of the error values.  */
-int db_keyexist;
-int db_notfound;
-
-/* Locks the static variables in this file.  */
-__libc_lock_define_initialized (static, lock)
-
-/* Dynamically load the database library.  Return zero if successful,
-   non-zero if no suitable version of the library could be loaded.
-   Must be called with the above lock held if it might run in a
-   multithreaded context.
-
-   We try currently:
-   - libdb.so.3: the name used by glibc 2.1
-   - libdb-3.0.so: the name used by db-3.0.x
-   and maybe others in the future.  */
-
+/* Open the database stored in FILE.  If succesful, store either a
+   pointer to the mapped file or a file handle for the file in H and
+   return NSS_STATUS_SUCCESS.  On failure, return the appropriate
+   lookup status.  */
 enum nss_status
-load_db (void)
-{
-  static const char *libnames[] = { "libdb.so.3", "libdb-3.0.so" };
-  int x;
-
-  for (x = 0; x < sizeof (libnames) / sizeof (libnames[0]); ++x)
-    {
-      libdb_handle = dlopen (libnames[x], RTLD_LAZY);
-      if (libdb_handle == NULL)
-       continue;
-
-      /* DB 3.0 has db_create instead of db_open.  */
-      libdb_db_create = dlsym (libdb_handle, "db_create");
-
-      if (libdb_db_create == NULL)
-       /* DB 2.x uses db_open.  */
-       libdb_db_open = dlsym (libdb_handle, "db_open");
-
-      if (libdb_db_open != NULL || libdb_db_create != NULL)
-       {
-         /* Alright, we got a library.  Now find out which version it is.  */
-         const char *(*db_version) (int *, int *, int *);
-
-         db_version = dlsym (libdb_handle, "db_version");
-         if (db_version != NULL)
-           {
-             /* Call the function and get the information.  */
-             int major, minor, subminor;
-
-             DL_CALL_FCT (db_version, (&major, &minor, &subminor));
-             switch (major)
-               {
-               case 2:
-                 /* Sanity check: Do we have db_open?  */
-                 if (libdb_db_open != NULL)
-                   {
-                     if (minor < 6 || (minor == 6 && subminor < 4))
-                       {
-                         libdb_version = db24;
-                         db_first = DB24_FIRST;
-                         db_next = DB24_NEXT;
-                         db_nooverwrite = DB24_NOOVERWRITE;
-                         db_truncate = DB24_TRUNCATE;
-                       }
-                     else
-                       {
-                         libdb_version = db27;
-                         db_first = DB27_FIRST;
-                         db_next = DB27_NEXT;
-                         db_nooverwrite = DB27_NOOVERWRITE;
-                         db_truncate = DB27_TRUNCATE;
-                       }
-                     db_keyexist = DB2x_KEYEXIST;
-                     db_notfound = DB2x_NOTFOUND;
-                     db_rdonly = DB2x_RDONLY;
-                   }
-                 break;
-
-               case 3:
-                 /* Sanity check: Do we have db_create?  */
-                 if (libdb_db_create != NULL)
-                   {
-                     libdb_version = db30;
-                     db_first = DB30_FIRST;
-                     db_next = DB30_NEXT;
-                     db_keyexist = DB30_KEYEXIST;
-                     db_notfound = DB30_NOTFOUND;
-                     db_rdonly = DB30_RDONLY;
-                   }
-                 break;
-
-               default:
-                 break;
-               }
-           }
-
-         if (libdb_version != nodb)
-           return NSS_STATUS_SUCCESS;
-
-         /* Clear variables.  */
-         libdb_db_open = NULL;
-         libdb_db_create = NULL;
-       }
-
-      dlclose (libdb_handle);
-    }
-
-  (void) dlerror ();
-  return NSS_STATUS_UNAVAIL;
-}
-
-/* Set the `FD_CLOEXEC' flag of FD.  Return 0 on success, or -1 on
-   error with `errno' set. */
-static int
-set_cloexec_flag (int fd)
+internal_setent (const char *file, struct nss_db_map *mapping)
 {
-  int oldflags = fcntl (fd, F_GETFD, 0);
-
-  if (oldflags < 0)
-    return oldflags;
-
-  oldflags |= FD_CLOEXEC;
-
-  return fcntl (fd, F_SETFD, oldflags);
-}
-
-/* Make sure we don't use the library anymore once we are shutting down.  */
-static void __attribute__ ((destructor))
-unload_db (void)
-{
-  if (libdb_handle != NULL)
+  enum nss_status status = NSS_STATUS_UNAVAIL;
+
+  int mode = O_RDONLY | O_LARGEFILE;
+#ifdef O_CLOEXEC
+  mode |= O_CLOEXEC;
+#endif
+  int fd = open_not_cancel_2 (file, mode);
+  if (fd != -1)
     {
-      libdb_db_open = NULL;
-      libdb_db_create = NULL;
-      libdb_version = nodb;
-      dlclose (libdb_handle);
-    }
-}
-
-/* Open the database stored in FILE.  If succesful, store the database
-   handle in *DBP and return NSS_STATUS_SUCCESS.  On failure, return
-   the appropriate lookup status.  */
-enum nss_status
-internal_setent (const char *file, NSS_DB **dbp)
-{
-  enum nss_status status = NSS_STATUS_SUCCESS;
+      struct nss_db_header header;
 
-  if (*dbp == NULL)
-    {
-      if (libdb_db_open == NULL && libdb_db_create == NULL)
+      if (read (fd, &header, sizeof (header)) == sizeof (header))
        {
-         __libc_lock_lock (lock);
-
-         if (libdb_db_open == NULL && libdb_db_create == NULL)
-           status = load_db ();
-
-         __libc_lock_unlock (lock);
+         mapping->header = mmap (NULL, header.allocate, PROT_READ,
+                                 MAP_PRIVATE, fd, 0);
+         mapping->len = header.allocate;
+         if (mapping->header != MAP_FAILED)
+           status = NSS_STATUS_SUCCESS;
+         else if (errno == ENOMEM)
+           status = NSS_STATUS_TRYAGAIN;
        }
 
-      if (status == NSS_STATUS_SUCCESS)
-       status = dbopen (file, db_rdonly, 0, dbp);
+      close_not_cancel_no_status (fd);
     }
 
   return status;
 }
 
 
-/* Close the database *DBP.  */
+/* Close the database.  */
 void
-internal_endent (NSS_DB **dbp)
-{
-  NSS_DB *db = *dbp;
-
-  if (db != NULL)
-    {
-      DL_CALL_FCT (db->close, (db->db, 0));
-      *dbp = NULL;
-    }
-}
-
-/* Allocate a cursor for database DB and transaction TXN.  On success,
-   store the cursor in *DBCP and return zero.  Otherwise return an
-   error value.  */
-int
-db_cursor (void *db, void *txn, NSS_DBC **dbcp)
-{
-  NSS_DBC *dbc;
-  int ret;
-
-  dbc = (NSS_DBC *) malloc (sizeof (NSS_DBC));
-  if (dbc == NULL)
-    return ENOMEM;
-
-  switch (libdb_version)
-    {
-    case db24:
-      ret = ((struct db24 *) db)->cursor (db, txn, &dbc->cursor);
-
-      if (ret == 0)
-       dbc->c_get = ((struct dbc24 *) dbc->cursor)->c_get;
-      break;
-
-    case db27:
-      ret = ((struct db27 *) db)->cursor (db, txn, &dbc->cursor, 0);
-
-      if (ret == 0)
-       dbc->c_get = ((struct dbc27 *) dbc->cursor)->c_get;
-      break;
-
-    case db30:
-      ret = ((struct db30 *) db)->cursor (db, txn, &dbc->cursor, 0);
-
-      if (ret == 0)
-       dbc->c_get = ((struct dbc30 *) dbc->cursor)->c_get;
-      break;
-
-    default:
-      abort ();
-    }
-
-  if (ret != 0)
-    {
-      free (dbc);
-      return ret;
-    }
-
-  *dbcp = dbc;
-
-  return 0;
-}
-
-
-/* Open the database in FNAME, for access specified by FLAGS.  If
-   opening the database causes the file FNAME to be created, it is
-   created with MODE.  If succesful, store the database handle in *DBP
-   and return NSS_STATUS_SUCCESS.  On failure, return the appropriate
-   lookup status.  */
-int
-dbopen (const char *fname, int oper, int mode, NSS_DB **dbp)
+internal_endent (struct nss_db_map *mapping)
 {
-  int err;
-  int fd;
-  NSS_DB *db;
-
-  /* Construct the object we pass up.  */
-  db = (NSS_DB *) calloc (1, sizeof (NSS_DB));
-  if (db == NULL)
-    return NSS_STATUS_UNAVAIL;
-
-  /* Initialize the object.  */
-  db->cursor = db_cursor;
-
-  /* Actually open the database.  */
-  switch (libdb_version)
-    {
-    case db24:
-    case db27:
-      err = DL_CALL_FCT (libdb_db_open,
-                        (fname, DB_BTREE, oper, mode, NULL, NULL, &db->db));
-      if (err != 0)
-       goto fail;
-
-      if (libdb_version)
-       {
-         db->close = ((struct db24 *) db->db)->close;
-         db->fd = ((struct db24 *) db->db)->fd;
-         db->get = ((struct db24 *) db->db)->get;
-         db->put = ((struct db24 *) db->db)->put;
-       }
-      else
-       {
-         db->close = ((struct db27 *) db->db)->close;
-         db->fd = ((struct db27 *) db->db)->fd;
-         db->get = ((struct db27 *) db->db)->get;
-         db->put = ((struct db27 *) db->db)->put;
-       }
-      break;
-
-    case db30:
-      err = DL_CALL_FCT (libdb_db_create, (db->db, NULL, 0));
-      if (err != 0)
-       goto fail;
-
-      db->close = ((struct db30 *) db->db)->close;
-      db->fd = ((struct db30 *) db->db)->fd;
-      db->get = ((struct db30 *) db->db)->get;
-      db->put = ((struct db30 *) db->db)->put;
-
-      err = ((struct db30 *) db->db)->open (db->db, fname, NULL, DB_BTREE,
-                                           oper, mode);
-      if (err != 0)
-       goto fail;
-      break;
-
-    default:
-      abort ();
-    }
-
-  /* We have to make sure the file is `closed on exec'.  */
-  err = DL_CALL_FCT (db->fd, (db->db, &fd));
-  if (err != 0)
-    goto fail;
-  if (set_cloexec_flag (fd) < 0)
-    goto fail;
-
-  *dbp = db;
-
-  return NSS_STATUS_UNAVAIL;
-
- fail:
-  /* Something went wrong.  Close the database if necessary.  */
-  if (db)
-    {
-      if (db->db && db->close)
-       DL_CALL_FCT (db->close, (db->db, 0));
-      free (db);
-    }
-
-  /* Make sure `errno' is set.  */
-  if (err)
-    __set_errno (err);
-
-  return err == EAGAIN ? NSS_STATUS_TRYAGAIN : NSS_STATUS_UNAVAIL;
+  munmap (mapping->header, mapping->len);
 }
diff --git a/nss/nss_db/dummy-db.h b/nss/nss_db/dummy-db.h
deleted file mode 100644 (file)
index c96bbd9..0000000
+++ /dev/null
@@ -1,333 +0,0 @@
-/* Constants and structures from the various Berkeley DB releases.
-   Copyright (C) 1999, 2000 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-   02111-1307 USA.  */
-
-#include <stdint.h>
-
-#include "nss_db.h"
-
-/* This file contains dummy definitions for various constants and
-   structures from the Berkeley release.  We only provide those
-   definitions that are actually needed.  In case of the structures,
-   we're only interested in the function pointers, since that's the
-   interface to the database.  Unfortunately the structures have been
-   changed several times.  */
-
-/* The value for the btree database type has not been changed (yet?).  */
-#define DB_BTREE       (1)
-
-/* Permission flags for all 2.x releases.  */
-#define DB2x_RDONLY    0x010000
-
-/* The error values for all 2.x releases.  */
-#define DB2x_KEYEXIST  ( -3)
-#define DB2x_NOTFOUND  ( -7)
-
-/* For all 2.x releases up to 2.6.3 we can use the same definitions.
-   We'll refer to them as 2.4 since that's the version distributed
-   with glibc 2.1.  */
-
-/* Access methods from version 2.4.  */
-#define DB24_FIRST             0x000020
-#define DB24_NEXT              0x000800
-#define DB24_NOOVERWRITE       0x001000
-
-/* Permission flags from version 2.4.  */
-#define DB24_TRUNCATE  0x080000
-
-/* The DB structure from version 2.4.  */
-struct db24
-{
-  void *mutexp;
-  enum { dummy24 } type;
-  void *dbenv;
-  void *mp_dbenv;
-  void *master;
-  void *internal;
-  void *mp;
-  void *mpf;
-  struct
-  {
-    void *tqh_first;
-    void **tqh_last;
-  } curs_queue;
-  struct {
-    void *lh_first;
-  } handleq;
-  struct {
-    void *le_next;
-    void **le_prev;
-  } links;
-  uint32_t log_fileid;
-  void *txn;
-  uint32_t locker;
-  struct db24_dbt {
-    void *data;
-    uint32_t size;
-    uint32_t ulen;
-    uint32_t dlen;
-    uint32_t doff;
-    uint32_t flags;
-  } lock_dbt;
-  struct{
-    uint32_t pgno;
-    uint8_t fileid[20];
-  } lock;
-  size_t pgsize;
-  void *db_malloc;
-  /* Functions. */
-  int (*close) (void *, uint32_t);
-  int (*cursor) (void *, void *, void **);
-  int (*del) (void *, void *, DBT *, uint32_t);
-  int (*fd) (void *, int *);
-  int (*get) (void *, void *, DBT *, DBT *, uint32_t);
-  int (*put) (void *, void *, DBT *, DBT *, uint32_t);
-  int (*stat) (void *, void *, void *(*)(size_t), uint32_t);
-  int (*sync) (void *, uint32_t);
-  uint32_t flags;
-};
-
-/* The DBC structure for the 2.4 release.  */
-struct dbc24
-{
-  void *dbp;
-  void *txn;
-  struct
-  {
-    void *tqe_next;
-    void **tqe_prev;
-  } links;
-  void *internal;
-  void *c_close;
-  void *c_del;
-  int (*c_get) (void *, DBT *, DBT *, uint32_t);
-  void *c_put;
-};
-
-/* The 2.7 release is slighty different.  */
-
-/* Access methods from version 2.7.  */
-#define DB27_FIRST             7
-#define DB27_NEXT              15
-#define DB27_NOOVERWRITE       17
-
-/* Permission flags from version 2.7.  */
-#define DB27_TRUNCATE  0x020000
-
-/* The DB structure from version 2.7.  */
-struct db27
-{
-  void *mutexp;
-  enum { dummy27 } type;
-  int byteswapped;
-  int saved_open_fd;
-  void *dbenv;
-  void *mp_dbenv;
-  void *internal;
-  void *mp;
-  void *mpf;
-  struct
-  {
-    void *tqh_first;
-    void **tqh_last;
-  } free_queue;
-  struct
-  {
-    void *tqh_first;
-    void **tqh_last;
-  } active_queue;
-  uint8_t fileid[20];
-  uint32_t log_fileid;
-  size_t pgsize;
-  void *db_malloc;
-  void *dup_compare;
-  void *h_hash;
-  /* Functions. */
-  int (*am_close) (void *);
-  int (*close) (void *, uint32_t);
-  int (*cursor) (void *, void *, void **, uint32_t);
-  int (*del) (void *, void *, DBT *, uint32_t);
-  int (*fd) (void *, int *);
-  int (*get) (void *, void *, DBT *, DBT *, uint32_t);
-  int (*join) (void *, void **, uint32_t, void **);
-  int (*put) (void *, void *, DBT *, DBT *, uint32_t);
-  int (*stat) (void *, void *, void *(*)(size_t), uint32_t);
-  int (*sync) (void *, uint32_t);
-  uint32_t flags;
-};
-
-/* The DBC structure for version 2.7.  */
-struct dbc27
-{
-  void *dbp;
-  void *txn;
-  struct
-  {
-    void *tqe_next;
-    void **tqe_prev;
-  } links;
-  uint32_t lid;
-  uint32_t locker;
-  DBT lock_dbt;
-  struct{
-    uint32_t pgno;
-    uint8_t fileid[20];
-  } lock;
-  size_t mylock;
-  DBT rkey;
-  DBT rdata;
-  void *c_am_close;
-  void *c_am_destroy;
-  void *c_close;
-  void *c_del;
-  int (*c_get) (void *, DBT *, DBT *, uint32_t);
-  void *c_put;
-  void *internal;
-  uint32_t flags;
-};
-
-/* Version 3.0 is mostly incompatible with 2.x.  */
-
-/* Access methods from version 3.0.  */
-#define DB30_FIRST             9
-#define DB30_NEXT              17
-#define DB30_NOOVERWRITE       20
-
-/* Error values from version 3.0.  */
-#define DB30_KEYEXIST  (-30997)
-#define DB30_NOTFOUND  (-30994)
-
-/* Permission flags from version 3.0.  */
-#define DB30_RDONLY    0x000010
-#define DB30_TRUNCATE  0x020000
-
-/* The DB structure from version 3.0.  */
-struct db30
-{
-  size_t pgsize;
-  void (*db_feedback) (void *, int, int);
-  void *(*db_malloc) (size_t);
-  void *(*db_realloc) (void *, size_t);
-  int (*dup_compare) (const DBT *, const DBT *);
-  void *dbenv;
-  enum { dummy30 } type;
-  void *mpf;
-  void *mutexp;
-  u_int8_t fileid[20];
-  int32_t log_fileid;
-  void *open_txn;
-  void *saved_open_fhp;
-  struct
-  {
-    void *tqh_first;
-    void **tqh_last;
-  } free_queue;
-  struct
-  {
-    void *tqh_first;
-    void **tqh_last;
-  } active_queue;
-  void *bt_internal;
-  void *cj_internal;
-  void *h_internal;
-  void *q_internal;
-  void *xa_internal;
-  /* Functions.  */
-  int  (*close) (void *, uint32_t);
-  int  (*cursor) (void *, void *, void **, uint32_t);
-  int  (*del) (void *, void *, DBT *, uint32_t);
-  void (*err) (void *, int, const char *, ...);
-  void (*errx) (void *, const char *, ...);
-  int  (*fd) (void *, int *);
-  int  (*get) (void *, void *, DBT *, DBT *, uint32_t);
-  int  (*get_byteswapped) (void *);
-  int (*get_type) (void *);
-  int  (*join) (void *, void **, void **, uint32_t);
-  int  (*open) (void *,        const char *, const char *, int, uint32_t, int);
-  int  (*put) (void *, void *, DBT *, DBT *, uint32_t);
-  int  (*remove) (void *, const char *, const char *, uint32_t);
-  int  (*set_cachesize) (void *, uint32_t, uint32_t, int);
-  int  (*set_dup_compare) (void *, int (*)(const DBT *, const DBT *));
-  void (*set_errcall) (void *, void (*)(const char *, char *));
-  void (*set_errfile) (void *, void *);
-  void (*set_errpfx) (void *, const char *);
-  void (*set_feedback) (void *, void (*)(void *, int, int));
-  int  (*set_flags) (void *, uint32_t);
-  int  (*set_lorder) (void *, int);
-  int  (*set_malloc) (void *, void *(*)(size_t));
-  int  (*set_pagesize) (void *, uint32_t);
-  void (*set_paniccall) (void *, void (*)(void *, int));
-  int  (*set_realloc) (void *, void *(*)(void *, size_t));
-  int  (*stat) (void *, void *, void *(*)(size_t), uint32_t);
-  int  (*sync) (void *, uint32_t);
-  int  (*upgrade) (void *, const char *, uint32_t);
-
-  int  (*set_bt_compare) (void *, int (*)(const DBT *, const DBT *));
-  int  (*set_bt_maxkey) (void *, uint32_t);
-  int  (*set_bt_minkey) (void *, uint32_t);
-  int  (*set_bt_prefix) (void *, size_t (*)(const DBT *, const DBT *));
-
-  int  (*set_h_ffactor) (void *, uint32_t);
-  int  (*set_h_hash) (void *, uint32_t (*)(const void *, uint32_t));
-  int  (*set_h_nelem) (void *, uint32_t);
-
-  int  (*set_re_delim) (void *, int);
-  int  (*set_re_len) (void *, uint32_t);
-  int  (*set_re_pad) (void *, int);
-  int  (*set_re_source) (void *, const char *);
-
-  uint32_t am_ok;
-  uint32_t flags;
-};
-
-/* The DBC structure from version 3.0.  */
-struct dbc30
-{
-  void *dbp;
-  void *txn;
-  struct
-  {
-    void *tqe_next;
-    void **tqe_prev;
-  } links;
-  uint32_t lid;                        /* Default process' locker id. */
-  uint32_t locker;             /* Locker for this operation. */
-  DBT lock_dbt;                /* DBT referencing lock. */
-  struct
-  {
-    uint32_t pgno;
-    uint8_t fileid[20];
-  } lock;
-  struct
-  {
-    size_t off;
-    uint32_t ndx;
-    uint32_t gen;
-  } mylock;
-  DBT rkey;
-  DBT rdata;
-  int (*c_close) (void *);
-  int (*c_del) (void *, uint32_t);
-  int (*c_dup) (void *, void **, uint32_t);
-  int (*c_get) (void *, DBT *, DBT *, uint32_t);
-  int (*c_put) (void *, DBT *, DBT *, uint32_t);
-  int (*c_am_close) (void *);
-  int (*c_am_destroy) (void *);
-  void *internal;
-  uint32_t flags;
-};
index 0edc9b6bea2adc41b33a3459b6ddee06d1c9cced..a965ae33fe3db8510a06fd61fd7ede4a98823374 100644 (file)
@@ -1,5 +1,5 @@
 /* Common database open/close routines for nss_db.
-   Copyright (C) 1999, 2000 Free Software Foundation, Inc.
+   Copyright (C) 1999, 2000, 2011 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
 
 #include <nss.h>
 #include <stdint.h>
+#include <bits/libc-lock.h>
 
-/* Variables which keep track of the error values.  */
-extern int db_keyexist;
-extern int db_notfound;
 
-/* This flag is the same for all versions of the Berkeley DB library.  */
-#define DB_CREATE      0x000001
+/* String table index type.  */
+typedef uint32_t stridx_t;
 
-/* But constants which vary from version to version are actually
-   variables here.  */
-extern int db_first;
-extern int db_next;
-extern int db_nooverwrite;
-extern int db_truncate;
-extern int db_rdonly;
-
-/* The `DBT' type is the same in all versions we support.  */
-typedef struct
+/* Database file header.  */
+struct nss_db_header
 {
-  void *data;
-  uint32_t size;
-  uint32_t ulen;
-  uint32_t dlen;
-  uint32_t doff;
-  uint32_t flags;
-} DBT;
-
-/* But the cursor object is very different from version to version.  */
-typedef struct
+  uint32_t magic;
+#define NSS_DB_MAGIC 0xdd110601
+  uint32_t ndbs;
+  uint64_t valstroffset;
+  uint64_t valstrlen;
+  uint64_t allocate;
+  struct
+  {
+    char id;
+    char pad[sizeof (uint32_t) - 1];
+    uint32_t hashsize;
+    uint64_t hashoffset;
+    uint64_t keyidxoffset;
+    uint64_t keystroffset;
+  } dbs[0];
+};
+
+
+/* Information about mapped database.  */
+struct nss_db_map
 {
-  void *cursor;
-  int (*c_get) (void *, DBT *, DBT *, uint32_t);
-} NSS_DBC;
+  struct nss_db_header *header;
+  size_t len;
+};
 
-/* We need a helper function for it.  */
-extern int db_cursor (void *db, void *txn, NSS_DBC **dbcp);
-
-/* This is the wrapper we put around the `DB' structures to provide a
-   uniform interface to the higher-level functions.  */
-typedef struct
-{
-  void *db;
-  int (*close) (void *, uint32_t);
-  int (*cursor) (void *, void *, NSS_DBC **);
-  int (*fd) (void *, int *);
-  int (*get) (void *, void *, DBT *, DBT *, uint32_t);
-  int (*put) (void *, void *, DBT *, DBT *, uint32_t);
-} NSS_DB;
 
 /* Open the database stored in FILE.  If succesful, store the database
-   handle in *DBP and return NSS_STATUS_SUCCESS.  On failure, return
-   the appropriate lookup status.  */
-extern enum nss_status internal_setent (const char *file, NSS_DB **dbp);
-
-/* Close the database *DBP.  */
-extern void internal_endent (NSS_DB **dbp);
-
-/* Dynamically load the Berkeley DB library.  Return zero if
-   successful, non-zero if no suitable version of the library could be
-   loaded.  */
-extern enum nss_status load_db (void);
-
-/* Open the database in FNAME, for access specified by FLAGS.  If
-   opening the database causes the file FNAME to be created, it is
-   created with MODE.  If succesful, store the database handle in *DBP
-   and return NSS_STATUS_SUCCESS.  On failure, return the appropriate
+   handle in *MAPPINGP or a file descriptor for the file in *FDP and
+   return NSS_STATUS_SUCCESS.  On failure, return the appropriate
    lookup status.  */
-extern int dbopen (const char *fname, int oper, int mode, NSS_DB **dbp);
+enum nss_status internal_setent (const char *file,
+                                struct nss_db_map *mappingp);
+
+/* Close the database FD.  */
+extern void internal_endent (struct nss_db_map *mapping);
 
 #endif /* nss_db.h */
index 852b58a7e5476941cce1906a7a5fc054202428e8..1a6fa0ddd535ecd6c4bfccdd356ee9d0dfb89df3 100644 (file)
@@ -1,5 +1,5 @@
 /* Common code for file-based databases in nss_files module.
-   Copyright (C) 1996-1999,2001,2002,2004,2007,2008
+   Copyright (C) 1996-1999,2001,2002,2004,2007,2008,2011
    Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -306,15 +306,15 @@ CONCAT(_nss_files_get,ENTNAME_r) (struct STRUCTURE *result, char *buffer,
 
    NAME is the name of the lookup; e.g. `hostbyname'.
 
-   KEYSIZE and KEYPATTERN are ignored here but used by ../nss_db/db-XXX.c.
+   DB_CHAR, KEYPATTERN, KEYSIZE are ignored here but used by db-XXX.c
+   e.g. `1 + sizeof (id) * 4'.
 
-   PROTO describes the arguments for the lookup key;
-   e.g. `const char *hostname'.
+   PROTO is the potentially empty list of other parameters.
 
    BREAK_IF_MATCH is a block of code which compares `struct STRUCTURE *result'
    to the lookup key arguments and does `break;' if they match.  */
 
-#define DB_LOOKUP(name, keysize, keypattern, break_if_match, proto...)       \
+#define DB_LOOKUP(name, db_char, keysize, keypattern, break_if_match, proto...)\
 enum nss_status                                                                      \
 _nss_files_get##name##_r (proto,                                             \
                          struct STRUCTURE *result, char *buffer,             \
index e662c1a4e128f3982dbcd25e270e001ef8b00a87..91363ba17312ff2ed345b8d0d356aabacaeaea9e 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1996, 1997, 2000 Free Software Foundation, Inc.
+/* Copyright (C) 1996, 1997, 2000, 2011 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
@@ -51,13 +51,13 @@ LINE_PARSER
 
 #include GENERIC
 
-DB_LOOKUP (hostton, 1 + strlen (name), (".%s", name),
+DB_LOOKUP (hostton, '.', 0, ("%s", name),
           {
             if (__strcasecmp (result->e_name, name) == 0)
               break;
           }, const char *name)
 
-DB_LOOKUP (ntohost, 18, ("=%x:%x:%x:%x:%x:%x",
+DB_LOOKUP (ntohost, '=', 18, ("%x:%x:%x:%x:%x:%x",
                         addr->ether_addr_octet[0], addr->ether_addr_octet[1],
                         addr->ether_addr_octet[2], addr->ether_addr_octet[3],
                         addr->ether_addr_octet[4], addr->ether_addr_octet[5]),
index 1f205c10932ea3a1b1e286bd130a8b314c30e2dc..30751ab048aaff419b2a5efde9e942ae0571123e 100644 (file)
@@ -1,5 +1,5 @@
 /* Group file parser in nss_files module.
-   Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+   Copyright (C) 1996, 1997, 2011 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
@@ -30,14 +30,14 @@ struct grent_data {};
 #include "files-parse.c"
 #include GENERIC
 
-DB_LOOKUP (grnam, 1 + strlen (name), (".%s", name),
+DB_LOOKUP (grnam, '.', 0, ("%s", name),
           {
             if (name[0] != '-' && name[0] != '+'
                 && ! strcmp (name, result->gr_name))
               break;
           }, const char *name)
 
-DB_LOOKUP (grgid, 20, ("=%lu", (unsigned long int) gid),
+DB_LOOKUP (grgid, '=', 20, ("%lu", (unsigned long int) gid),
           {
             if (result->gr_gid == gid && result->gr_name[0] != '+'
                 && result->gr_name[0] != '-')
index 83de650756355091af3e2c1e6fe2d841c32d3f9f..f6f960ecbe203c3e32c28284364d7a12b1401f71 100644 (file)
@@ -358,7 +358,7 @@ HOST_DB_LOOKUP (hostbyname2, ,,
    gethostbyaddr() function is an IPv6 address.  */
 #define EXTRA_ARGS_VALUE \
   , af, (len == IN6ADDRSZ ? AI_V4MAPPED : 0)
-DB_LOOKUP (hostbyaddr, ,,
+DB_LOOKUP (hostbyaddr, ,,,
           {
             if (result->h_length == (int) len
                 && ! memcmp (addr, result->h_addr_list[0], len))
index 92aea75d9ea994b3819b4f92d4bcf496c5f0ca11..9017c549978d597b11078f19c41f28ab0aa5a120 100644 (file)
@@ -1,5 +1,5 @@
 /* Networks file parser in nss_files module.
-   Copyright (C) 1996-1998, 2000, 2001, 2009 Free Software Foundation, Inc.
+   Copyright (C) 1996-1998, 2000, 2001, 2009, 2011 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
@@ -75,11 +75,11 @@ LINE_PARSER
 
 #include "files-XXX.c"
 
-DB_LOOKUP (netbyname, ,,
+DB_LOOKUP (netbyname, ,,,
           LOOKUP_NAME_CASE (n_name, n_aliases),
           const char *name)
 
-DB_LOOKUP (netbyaddr, ,,
+DB_LOOKUP (netbyaddr, ,,,
           {
             if ((type == AF_UNSPEC || result->n_addrtype == type)
                 && result->n_net == net)
index 0cede6ebd41145ecbcbfb7c8da00e5779760a0d1..5df325b49639abc31650fed1e7680755f3e8b5b1 100644 (file)
@@ -1,5 +1,5 @@
 /* Protocols file parser in nss_files module.
-   Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+   Copyright (C) 1996, 1997, 2011 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
@@ -36,11 +36,11 @@ LINE_PARSER
 
 #include GENERIC
 
-DB_LOOKUP (protobyname, 1 + strlen (name), (".%s", name),
+DB_LOOKUP (protobyname, '.', 0, ("%s", name),
           LOOKUP_NAME (p_name, p_aliases),
           const char *name)
 
-DB_LOOKUP (protobynumber, 20, ("=%d", proto),
+DB_LOOKUP (protobynumber, '=', 20, ("%zd", (ssize_t) proto),
           {
             if (result->p_proto == proto)
               break;
index 4913c3183dc5932c5550e896b31a7fa179ae2d13..4763f0149a034238c7f88f00c92ebc02f82cee2a 100644 (file)
@@ -1,5 +1,5 @@
 /* User file parser in nss_files module.
-   Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+   Copyright (C) 1996, 1997, 2011 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
@@ -30,14 +30,14 @@ struct pwent_data {};
 #include "files-parse.c"
 #include GENERIC
 
-DB_LOOKUP (pwnam, 1 + strlen (name), (".%s", name),
+DB_LOOKUP (pwnam, '.', 0, ("%s", name),
           {
             if (name[0] != '+' && name[0] != '-'
                 && ! strcmp (name, result->pw_name))
               break;
           }, const char *name)
 
-DB_LOOKUP (pwuid, 20, ("=%lu", (unsigned long int) uid),
+DB_LOOKUP (pwuid, '=', 20, ("%lu", (unsigned long int) uid),
           {
             if (result->pw_uid == uid && result->pw_name[0] != '+'
                 && result->pw_name[0] != '-')
index b99ede399b5d8f216d33af3e27617258e88049e1..2b41611d4ccb79eb3c536889eaca741b61aedfdb 100644 (file)
@@ -1,5 +1,5 @@
 /* SunRPC program number file parser in nss_files module.
-   Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+   Copyright (C) 1996, 1997, 2011 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
@@ -36,11 +36,11 @@ LINE_PARSER
 
 #include GENERIC
 
-DB_LOOKUP (rpcbyname, 1 + strlen (name), (".%s", name),
+DB_LOOKUP (rpcbyname, '.', 0, ("%s", name),
           LOOKUP_NAME (r_name, r_aliases),
           const char *name)
 
-DB_LOOKUP (rpcbynumber, 20, ("=%d", number),
+DB_LOOKUP (rpcbynumber, '=', 20, ("%zd", (ssize_t) number),
           {
             if (result->r_number == number)
               break;
index 13532ddc9bab42ed868b494b4b4353e8ed7eea5e..6f2b0e64a67a198888a8b3eb12374ad56355038b 100644 (file)
@@ -1,5 +1,5 @@
 /* Services file parser in nss_files module.
-   Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
+   Copyright (C) 1996, 1997, 1998, 2011 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
@@ -39,8 +39,9 @@ LINE_PARSER
 
 #include GENERIC
 
-DB_LOOKUP (servbyname, 2 + strlen (name) + (proto ? strlen (proto) : 0),
-          (".%s/%s", name, proto ?: ""),
+DB_LOOKUP (servbyname, ':',
+          strlen (name) + 2 + (proto == NULL ? 0 : strlen (proto)),
+          ("%s/%s", name, proto ?: ""),
           {
             /* Must match both protocol (if specified) and name.  */
             if (proto != NULL && strcmp (result->s_proto, proto))
@@ -49,8 +50,8 @@ DB_LOOKUP (servbyname, 2 + strlen (name) + (proto ? strlen (proto) : 0),
           },
           const char *name, const char *proto)
 
-DB_LOOKUP (servbyport, 21 + (proto ? strlen (proto) : 0),
-          ("=%d/%s", ntohs (port), proto ?: ""),
+DB_LOOKUP (servbyport, '=', 21 + (proto ? strlen (proto) : 0),
+          ("%zd/%s", (ssize_t) ntohs (port), proto ?: ""),
           {
             /* Must match both port and protocol.  */
             if (result->s_port == port
index 4e12cd83d4016c7eec856478b4ea2899db485a01..684bacc3d0d40be78d0653843d82fc0039c139fe 100644 (file)
@@ -1,5 +1,5 @@
 /* User file parser in nss_files module.
-   Copyright (C) 2009 Free Software Foundation, Inc.
+   Copyright (C) 2009, 2011 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
@@ -30,7 +30,7 @@ struct sgent_data {};
 #include "files-parse.c"
 #include GENERIC
 
-DB_LOOKUP (sgnam, 1 + strlen (name), (".%s", name),
+DB_LOOKUP (sgnam, '.', 0, ("%s", name),
           {
             if (name[0] != '+' && name[0] != '-'
                 && ! strcmp (name, result->sg_namp))
index 1825d36102e4810238853cf20ff645805db54b98..e227d71275c9e2a5793fa142a879a599d1d1442a 100644 (file)
@@ -1,5 +1,5 @@
 /* User file parser in nss_files module.
-   Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+   Copyright (C) 1996, 1997, 2011 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
@@ -30,7 +30,7 @@ struct spent_data {};
 #include "files-parse.c"
 #include GENERIC
 
-DB_LOOKUP (spnam, 1 + strlen (name), (".%s", name),
+DB_LOOKUP (spnam, '.', 0, ("%s", name),
           {
             if (name[0] != '+' && name[0] != '-'
                 && ! strcmp (name, result->sp_namp))
index d3e840752252235af195fc4be6f351c6e7c6f662..a7839de462d7b16027c47d5aea44109fc3f1f72f 100644 (file)
@@ -113,6 +113,7 @@ alpha.*-.*-linux.*  libresolv=2.1
 .*-.*-.*               libnss_nisplus=2
 .*-.*-.*               libnss_ldap=2
 .*-.*-.*               libnss_hesiod=2
+.*-.*-.*               libnss_db=2
 
 # Tests for NSS.  They must have the same NSS_SHLIB_REVISION number as
 # the rest.