aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@gmail.com>2011-06-14 22:21:51 -0400
committerUlrich Drepper <drepper@gmail.com>2011-06-15 21:06:18 -0400
commit2666d441c2d8107b1987b869714189af64b954c6 (patch)
treec7b8877d691db280202b4c7655907a1165ec84fc /nss/nss_db
parentRewrite makedb to avoid using db library (diff)
downloadglibc-2666d441c2d8107b1987b869714189af64b954c6.tar.gz
glibc-2666d441c2d8107b1987b869714189af64b954c6.tar.bz2
glibc-2666d441c2d8107b1987b869714189af64b954c6.zip
Reenable nss_db with a completely new implementation
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.
Diffstat (limited to 'nss/nss_db')
-rw-r--r--nss/nss_db/db-XXX.c332
-rw-r--r--nss/nss_db/db-alias.c215
-rw-r--r--nss/nss_db/db-netgrp.c94
-rw-r--r--nss/nss_db/db-open.c377
-rw-r--r--nss/nss_db/dummy-db.h333
-rw-r--r--nss/nss_db/nss_db.h96
6 files changed, 309 insertions, 1138 deletions
diff --git a/nss/nss_db/db-XXX.c b/nss/nss_db/db-XXX.c
index aa8cfd0746..30026b1866 100644
--- a/nss/nss_db/db-XXX.c
+++ b/nss/nss_db/db-XXX.c
@@ -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
@@ -19,10 +19,14 @@
#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).
@@ -38,25 +42,25 @@
#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)
-
-/* 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;
+
/* 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;
}
-
-/* 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
@@ -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
index de468cc592..0000000000
--- a/nss/nss_db/db-alias.c
+++ /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)
-
-/* 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;
-}
-
-/* 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;
-}
-
-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;
-}
diff --git a/nss/nss_db/db-netgrp.c b/nss/nss_db/db-netgrp.c
index 47e845a6b9..901d4f50b0 100644
--- a/nss/nss_db/db-netgrp.c
+++ b/nss/nss_db/db-netgrp.c
@@ -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>
@@ -29,55 +30,75 @@
#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"
/* 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;
}
diff --git a/nss/nss_db/db-open.c b/nss/nss_db/db-open.c
index 94dfe5b7da..36ce494d02 100644
--- a/nss/nss_db/db-open.c
+++ b/nss/nss_db/db-open.c
@@ -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
@@ -22,368 +22,51 @@
#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
index c96bbd93b7..0000000000
--- a/nss/nss_db/dummy-db.h
+++ /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;
-};
diff --git a/nss/nss_db/nss_db.h b/nss/nss_db/nss_db.h
index 0edc9b6bea..a965ae33fe 100644
--- a/nss/nss_db/nss_db.h
+++ b/nss/nss_db/nss_db.h
@@ -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
@@ -22,73 +22,49 @@
#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 */