* nss/nss_db/db-XXX.c: Move internal_setent and internal_endent
	functions from here...
	* nss/db-alias.c: ...and here...
	* nss/db-netgrp.c: ...and here...
	* nss/nss_db/db-open.c: ...to here.  New file.
	* nss/nss_db/dummy-db.h: New file.
	* nss/nss_db/nss_db.h: New file.
	* nss/Depend: Depend in dlfcn, not db2.
	* nss/Makefile (libnss_db-routines): Add db-open.
	(distribute): Add nss_db.h dummy-db.h.
	(libnss_db.so): Replace libdb dependency by $(libdl).
	Based on a patch by Zack Weinberg.
This commit is contained in:
Ulrich Drepper 2000-01-02 04:20:21 +00:00
parent a673fbcb1f
commit 9a6450d578
9 changed files with 509 additions and 264 deletions

View File

@ -1,5 +1,18 @@
2000-01-01 Ulrich Drepper <drepper@cygnus.com>
* nss/nss_db/db-XXX.c: Move internal_setent and internal_endent
functions from here...
* nss/db-alias.c: ...and here...
* nss/db-netgrp.c: ...and here...
* nss/nss_db/db-open.c: ...to here. New file.
* nss/nss_db/dummy-db.h: New file.
* nss/nss_db/nss_db.h: New file.
* nss/Depend: Depend in dlfcn, not db2.
* nss/Makefile (libnss_db-routines): Add db-open.
(distribute): Add nss_db.h dummy-db.h.
(libnss_db.so): Replace libdb dependency by $(libdl).
Based on a patch by Zack Weinberg.
* locale/programs/ld-ctype.c: Implement rest of transliteration
definition parsing.
* locale/programs/locfile-kw.gperf: New keyword translit_ignore.

View File

@ -1,2 +1,2 @@
db2
dlfcn
resolv

View File

@ -1,4 +1,4 @@
# Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
# Copyright (C) 1996, 1997, 1998, 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
@ -65,10 +65,11 @@ libnss_files-routines := $(addprefix files-,$(databases))
distribute += files-XXX.c files-parse.c
libnss_db-routines := $(addprefix db-,$(filter-out hosts network key,\
$(databases)))
$(databases))) \
db-open
generated += $(filter-out db-alias.c db-netgrp.c, \
$(addsuffix .c,$(libnss_db-routines)))
distribute += db-XXX.c
distribute += db-XXX.c nss_db.h dummy-db.h
# Build static module if requested
@ -80,7 +81,7 @@ libnss_db-inhibit-o = $(filter-out .os,$(object-suffixes))
include ../Rules
$(objpfx)libnss_db.so: $(dbobjdir)/libdb.so $(objpfx)libnss_files.so
$(objpfx)libnss_db.so: $(objpfx)libnss_files.so $(libdl)
$(libnss_db-routines:%=$(objpfx)%.c): $(objpfx)db-%.c: nss_files/files-%.c
@rm -f $@.new

View File

@ -1,5 +1,5 @@
/* Common code for DB-based databases in nss_db module.
Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
Copyright (C) 1996, 1997, 1998, 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
@ -17,10 +17,11 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include <db.h>
#include <dlfcn.h>
#include <fcntl.h>
#include <bits/libc-lock.h>
#include "nsswitch.h"
#include "nss_db.h"
/* These symbols are defined by the including source file:
@ -51,68 +52,12 @@ __libc_lock_define_initialized (static, lock)
/* Maintenance of the shared handle open on the database. */
static DB *db;
static NSS_DB *db;
static int keep_db;
static unsigned int entidx; /* Index for `getENTNAME'. */
/* Open database file if not already opened. */
static enum nss_status
internal_setent (int stayopen)
{
enum nss_status status = NSS_STATUS_SUCCESS;
int err;
if (db == NULL)
{
err = __nss_db_open (DBFILE, DB_BTREE, DB_RDONLY, 0, NULL, NULL, &db);
if (err != 0)
{
__set_errno (err);
status = err == EAGAIN ? NSS_STATUS_TRYAGAIN : NSS_STATUS_UNAVAIL;
}
else
{
/* We have to make sure the file is `closed on exec'. */
int fd;
int result;
err = db->fd (db, &fd);
if (err != 0)
{
__set_errno (err);
result = -1;
}
else
{
int flags = result = fcntl (fd, F_GETFD, 0);
if (result >= 0)
{
flags |= FD_CLOEXEC;
result = fcntl (fd, F_SETFD, flags);
}
}
if (result < 0)
{
/* Something went wrong. Close the stream and return a
failure. */
db->close (db, 0);
db = NULL;
status = NSS_STATUS_UNAVAIL;
}
}
}
/* Remember STAYOPEN flag. */
if (db != NULL)
keep_db |= stayopen;
return status;
}
static int entidx;
/* Thread-safe, exported version of that. */
/* Open the database. */
enum nss_status
CONCAT(_nss_db_set,ENTNAME) (int stayopen)
{
@ -120,8 +65,11 @@ CONCAT(_nss_db_set,ENTNAME) (int stayopen)
__libc_lock_lock (lock);
status = internal_setent (stayopen);
status = internal_setent (DBFILE, &db);
/* Remember STAYOPEN flag. */
if (db != NULL)
keep_db |= stayopen;
/* Reset the sequential index. */
entidx = 0;
@ -131,25 +79,13 @@ CONCAT(_nss_db_set,ENTNAME) (int stayopen)
}
/* Close the database file. */
static void
internal_endent (void)
{
if (db != NULL)
{
db->close (db, 0);
db = NULL;
}
}
/* Thread-safe, exported version of that. */
/* Close it again. */
enum nss_status
CONCAT(_nss_db_end,ENTNAME) (void)
{
__libc_lock_lock (lock);
internal_endent ();
internal_endent (&db);
/* Reset STAYOPEN flag. */
keep_db = 0;
@ -170,17 +106,20 @@ lookup (DBT *key, struct STRUCTURE *result,
DBT value;
/* Open the database. */
status = internal_setent (keep_db);
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 = db->get (db, NULL, key, &value, 0);
err = DL_CALL_FCT (db->get, (db->db, NULL, key, &value, 0));
if (err != 0)
{
if (err == DB_NOTFOUND)
@ -240,7 +179,7 @@ lookup (DBT *key, struct STRUCTURE *result,
}
if (! keep_db)
internal_endent ();
internal_endent (&db);
return status;
}

View File

@ -1,5 +1,5 @@
/* Mail alias file parser in nss_db module.
Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
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.
@ -21,81 +21,26 @@
#include <aliases.h>
#include <alloca.h>
#include <ctype.h>
#include <db.h>
#include <dlfcn.h>
#include <errno.h>
#include <fcntl.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 DB *db;
static NSS_DB *db;
static int keep_db;
static unsigned int entidx; /* Index for `getaliasent_r'. */
/* Open database file if not already opened. */
static enum nss_status
internal_setent (int stayopen)
{
enum nss_status status = NSS_STATUS_SUCCESS;
int err;
if (db == NULL)
{
err = __nss_db_open (_PATH_VARDB "aliases.db", DB_BTREE, DB_RDONLY, 0,
NULL, NULL, &db);
if (err != 0)
{
__set_errno (err);
status = NSS_STATUS_UNAVAIL;
}
else
{
/* We have to make sure the file is `closed on exec'. */
int fd;
int result;
err = db->fd (db, &fd);
if (err != 0)
{
__set_errno (err);
result = -1;
}
else
{
result = fcntl (fd, F_GETFD, 0);
if (result >= 0)
result = fcntl (fd, F_SETFD, result | FD_CLOEXEC);
}
if (result < 0)
{
/* Something went wrong. Close the stream and return a
failure. */
db->close (db, 0);
db = NULL;
status = NSS_STATUS_UNAVAIL;
}
}
}
/* Remember STAYOPEN flag. */
if (db != NULL)
keep_db |= stayopen;
return status;
}
/* Thread-safe, exported version of that. */
/* Open database. */
enum nss_status
_nss_db_setaliasent (int stayopen)
{
@ -103,7 +48,11 @@ _nss_db_setaliasent (int stayopen)
__libc_lock_lock (lock);
status = internal_setent (stayopen);
status = internal_setent (_PATH_VARDB "aliases.db", &db);
/* Remember STAYOPEN flag. */
if (db != NULL)
keep_db |= stayopen;
/* Reset the sequential index. */
entidx = 0;
@ -114,25 +63,13 @@ _nss_db_setaliasent (int stayopen)
}
/* Close the database file. */
static void
internal_endent (void)
{
if (db != NULL)
{
db->close (db, 0);
db = NULL;
}
}
/* Thread-safe, exported version of that. */
/* Close it again. */
enum nss_status
_nss_db_endaliasent (void)
{
__libc_lock_lock (lock);
internal_endent ();
internal_endent (&db);
/* Reset STAYOPEN flag. */
keep_db = 0;
@ -154,17 +91,22 @@ lookup (DBT *key, struct aliasent *result, char *buffer,
DBT value;
/* Open the database. */
status = internal_setent (keep_db);
if (db == NULL)
{
status = internal_setent (_PATH_VARDB "aliases.db", &db);
if (status != NSS_STATUS_SUCCESS)
{
*errnop = errno;
return status;
}
}
value.flags = 0;
if (db->get (db, NULL, key, &value, 0) == 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;
@ -176,11 +118,6 @@ lookup (DBT *key, struct aliasent *result, char *buffer,
return NSS_STATUS_TRYAGAIN;
}
if (status == NSS_STATUS_SUCCESS)
{
char *cp;
size_t cnt;
buffer = stpncpy (buffer, key->data, key->size) + 1;
buflen -= key->size + 1;
@ -225,12 +162,11 @@ lookup (DBT *key, struct aliasent *result, char *buffer,
status = (result->alias_members_len == 0
? NSS_STATUS_RETURN : NSS_STATUS_SUCCESS);
}
}
else
status = NSS_STATUS_NOTFOUND;
if (! keep_db)
internal_endent ();
internal_endent (&db);
return status;
}

View File

@ -1,5 +1,5 @@
/* Netgroup file parser in nss_db modules.
Copyright (C) 1996, 1997, 1999 Free Software Foundation, Inc.
Copyright (C) 1996, 1997, 1999, 2000 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
@ -18,14 +18,16 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include <db.h>
#include <dlfcn.h>
#include <errno.h>
#include <fcntl.h>
#include <netgroup.h>
#include <string.h>
#include <bits/libc-lock.h>
#include <paths.h>
#include "nsswitch.h"
#include "netgroup.h"
#include "nss_db.h"
#define DBFILE _PATH_VARDB "netgroup.db"
@ -35,58 +37,18 @@
__libc_lock_define_initialized (static, lock)
/* Maintenance of the shared handle open on the database. */
static DB *db;
static NSS_DB *db;
static char *entry;
static char *cursor;
enum nss_status
_nss_db_setnetgrent (const char *group)
{
enum nss_status status = NSS_STATUS_SUCCESS;
int err;
enum nss_status status;
__libc_lock_lock (lock);
/* Make sure the data base file is open. */
if (db == NULL)
{
err = __nss_db_open (DBFILE, DB_BTREE, O_RDONLY, 0, NULL, NULL, &db);
if (err != 0)
{
__set_errno (err);
status = err == EAGAIN ? NSS_STATUS_TRYAGAIN : NSS_STATUS_UNAVAIL;
}
else
{
/* We have to make sure the file is `closed on exec'. */
int fd;
int result;
err = db->fd (db, &fd);
if (err != 0)
{
__set_errno (err);
result = -1;
}
else
{
result = fcntl (fd, F_GETFD, 0);
if (result >= 0)
result = fcntl (fd, F_SETFD, result | FD_CLOEXEC);
}
if (result < 0)
{
/* Something went wrong. Close the stream and return a
failure. */
db->close (db, 0);
db = NULL;
status = NSS_STATUS_UNAVAIL;
}
}
}
status = internal_setent (DBFILE, &db);
if (status == NSS_STATUS_SUCCESS)
{
@ -94,7 +56,7 @@ _nss_db_setnetgrent (const char *group)
DBT value;
value.flags = 0;
if (db->get (db, NULL, &key, &value, 0) != 0)
if (DL_CALL_FCT (db->get, (db->db, NULL, &key, &value, 0)) != 0)
status = NSS_STATUS_NOTFOUND;
else
cursor = entry = value.data;
@ -112,11 +74,7 @@ _nss_db_endnetgrent (void)
{
__libc_lock_lock (lock);
if (db != NULL)
{
db->close (db, 0);
db = NULL;
}
internal_endent (&db);
__libc_lock_unlock (lock);

229
nss/nss_db/db-open.c Normal file
View File

@ -0,0 +1,229 @@
/* Common database open/close routines for nss_db.
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 Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If not,
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include <fcntl.h>
#include <dlfcn.h>
#include <errno.h>
#include <stdlib.h>
#include <bits/libc-lock.h>
#include "dummy-db.h"
#include "nsswitch.h"
#include "nss_db.h"
/* This file contains the functions used to open and close the databases
read by the rest of libnss_db. They are not thread safe; the caller
must handle locking.
We dynamically load the database library, so that it does not have
to be present when glibc is compiled. Once loaded, libdb is never
unloaded again unless this library is unloaded (from the free_mem
routine in nsswitch.c) - we catch the unload by providing a shlib
destructor. (XXX Does it work?) */
static void *libdb_handle;
enum {
nodb,
db24,
db27
} libdb_version;
static int (*libdb_db_open) (const char *, int,
uint32_t, int, void *, void *, void **);
/* Locks the static variables in this file. */
__libc_lock_define_initialized (static, lock)
/* Dynamically load the database library.
We try libdb2.so.3, maybe others in the future. */
static int
load_db (void)
{
static const char *libnames[] = { "libdb.so.3" };
int x;
for(x = 0; x < 1; ++x)
{
libdb_handle = dlopen (libnames[x], RTLD_LAZY);
if (libdb_handle == NULL)
continue;
libdb_db_open = dlsym (libdb_handle, "db_open");
if (libdb_db_open)
{
/* 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));
if (major == 2)
{
/* We currently cannot handle other versions than the
2.x series. */
if (minor < 6 || (minor == 6 && subminor < 4))
libdb_version = db24;
else
libdb_version = db27;
}
}
if (libdb_version != nodb)
return 0;
}
dlclose (libdb_handle);
}
(void) dlerror ();
return 1;
}
/* 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)
{
libdb_db_open = NULL;
libdb_version = nodb;
dlclose (libdb_handle);
}
}
enum nss_status
internal_setent (const char *file, NSS_DB **dbp)
{
enum nss_status status = NSS_STATUS_SUCCESS;
int err;
void *db;
if (*dbp == NULL)
{
if (libdb_db_open == NULL)
{
__libc_lock_lock (lock);
err = load_db ();
__libc_lock_unlock (lock);
if (err != 0)
return NSS_STATUS_UNAVAIL;
}
/* Open the database. Fortunately this interface seems to be the
same for all supported versions. */
err = DL_CALL_FCT (libdb_db_open,
(file, DB_BTREE, DB_RDONLY, 0, NULL, NULL, &db));
/* Construct the object we pass up. */
*dbp = (NSS_DB *) malloc (sizeof (NSS_DB));
if (*dbp != NULL)
{
(*dbp)->db = db;
/* The functions are at different positions for the different
versions. Sigh. */
switch (libdb_version)
{
case db24:
(*dbp)->close =
(int (*) (void *, uint32_t)) ((struct db24 *) db)->close;
(*dbp)->fd =
(int (*) (void *, int *)) ((struct db24 *) db)->fd;
(*dbp)->get =
(int (*) (void *, void *, void *, void *, uint32_t))
((struct db24 *) db)->get;
break;
case db27:
(*dbp)->close =
(int (*) (void *, uint32_t)) ((struct db27 *) db)->close;
(*dbp)->fd =
(int (*) (void *, int *)) ((struct db27 *) db)->fd;
(*dbp)->get =
(int (*) (void *, void *, void *, void *, uint32_t))
((struct db27 *) db)->get;
break;
default:
abort ();
}
}
if (err != 0)
{
__set_errno (err);
*dbp = NULL;
status = err == EAGAIN ? NSS_STATUS_TRYAGAIN : NSS_STATUS_UNAVAIL;
}
else
{
/* We have to make sure the file is `closed on exec'. */
int fd;
int result;
err = DL_CALL_FCT ((*dbp)->fd, (db, &fd));
if (err != 0)
{
__set_errno (err);
result = -1;
}
else
{
int flags = result = fcntl (fd, F_GETFD, 0);
if (result >= 0)
{
flags |= FD_CLOEXEC;
result = fcntl (fd, F_SETFD, flags);
}
}
if (result < 0)
{
/* Something went wrong. Close the stream and return a
failure. */
DL_CALL_FCT ((*dbp)->close, (db, 0));
status = NSS_STATUS_UNAVAIL;
}
if (result < 0)
*dbp = NULL;
}
}
return status;
}
/* Close the database file. */
void
internal_endent (NSS_DB **dbp)
{
NSS_DB *db = *dbp;
if (db != NULL)
{
DL_CALL_FCT (db->close, (db->db, 0));
*dbp = NULL;
}
}

111
nss/nss_db/dummy-db.h Normal file
View File

@ -0,0 +1,111 @@
#include <stdint.h>
#include "nss_db.h"
/* This file contains dummy definitions of the DB structure of the
Berkeley DB. We are only interested in the function pointers since
this is the interface to the database. Unfortunately the structure
changed over time and we have to take this into account. */
/* The values to select the database type are unchanged over the version.
Define only what we really need. */
#define DB_BTREE (1)
/* Permission flags are also not changed. */
#define DB_RDONLY 0x010000
/* This is for the db-2.x version up to 2.x.y. We use the name `db24' since
this is the version which was shipped with glibc 2.1. */
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);
};
/* Version 2.7, slightly incompatible with version 2.4. */
struct db27
{
void *mutexp;
enum { dummy27 } type;
int byteswapped;
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;
struct {
void *lh_first;
} handleq;
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 (*put) (void *, void *, DBT *, DBT *, uint32_t);
int (*stat) (void *, void *, void *(*)(size_t), uint32_t);
int (*sync) (void *, uint32_t);
};

58
nss/nss_db/nss_db.h Normal file
View File

@ -0,0 +1,58 @@
/* Common database open/close routines for nss_db.
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 Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If not,
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#ifndef _NSS_DB_H
#define _NSS_DB_H 1
#include <stdint.h>
/* The error values kept the same values though new values were added.
Define only those which we need. */
#define DB_NOTFOUND ( -7)
/* 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 (*fd) (void *, int *);
int (*get) (void *, void *, void *, void *, uint32_t);
} NSS_DB;
/* The `DBT' type is the same in all versions we support. */
typedef struct {
void *data;
uint32_t size;
uint32_t ulen;
uint32_t dlen;
uint32_t doff;
uint32_t flags;
} DBT;
/* Private routines to nss_db.
You must have included nsswitch.h and db.h before this file. */
extern enum nss_status internal_setent (const char *file, NSS_DB **dbp);
extern void internal_endent (NSS_DB **dbp);
#endif /* nss_db.h */