X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=libraries%2Flibldbm%2Fldbm.c;h=31c845416f9702ee40d58d901d4b3fc088c5ad82;hb=3b9f4a82ee478c943a66696adf9133dc9f503e16;hp=08c3299520ba9dff61acf4604ca433df29790a4b;hpb=f01a7dad53cd8439b6da4be661c12c7d97f74ffc;p=openldap diff --git a/libraries/libldbm/ldbm.c b/libraries/libldbm/ldbm.c index 08c3299520..31c845416f 100644 --- a/libraries/libldbm/ldbm.c +++ b/libraries/libldbm/ldbm.c @@ -1,7 +1,11 @@ /* ldbm.c - ldap dbm compatibility routines */ +/* $OpenLDAP$ */ +/* + * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved. + * COPYING RESTRICTIONS APPLY, see COPYRIGHT file + */ /* Patched for Berkeley DB version 2.0; /KSp; 98/02/23 - * * - DB version 2.6.4b ; 1998/12/28, /KSp * - DB_DBT_MALLOC ; 1998/03/22, /KSp * - basic implementation; 1998/02/23, /KSp @@ -12,25 +16,24 @@ #ifdef SLAPD_LDBM #include -#include + +#include #include #include #include "ldbm.h" #include "ldap_pvt_thread.h" - void ldbm_datum_free( LDBM ldbm, Datum data ) { if ( data.dptr ) { free( data.dptr ); - memset( &data, 0, sizeof( Datum )); + memset( &data, '\0', sizeof( Datum )); data.dptr = NULL; } } - Datum ldbm_datum_dup( LDBM ldbm, Datum data ) { @@ -45,45 +48,62 @@ ldbm_datum_dup( LDBM ldbm, Datum data ) return( dup ); } dup.dsize = data.dsize; - if ( (dup.dptr = (char *) malloc( data.dsize )) != NULL ) - memcpy( dup.dptr, data.dptr, data.dsize ); + + if ( (dup.dptr = (char *) malloc( data.dsize )) != NULL ) { + AC_MEMCPY( dup.dptr, data.dptr, data.dsize ); + } return( dup ); } static int ldbm_initialized = 0; -#ifndef HAVE_BERKELEY_DB2 -/* Everything but DB2 is non-reentrant */ +#if defined( USE_BERKELEY_CDB ) + /* not currently supported */ +#define LDBM_RWLOCK_INIT ((void) 0) +#define LDBM_RWLOCK_DESTROY ((void) 0) +#define LDBM_WLOCK ((void) 0) +#define LDBM_WUNLOCK ((void) 0) +#define LDBM_RLOCK ((void) 0) +#define LDBM_RUNLOCK ((void) 0) + +#elif defined( HAVE_BERKELEY_DB_THREAD ) +static ldap_pvt_thread_rdwr_t ldbm_big_rdwr; +#define LDBM_RWLOCK_INIT (ldap_pvt_thread_rdwr_init( &ldbm_big_rdwr )) +#define LDBM_RWLOCK_DESTROY (ldap_pvt_thread_rdwr_destroy( &ldbm_big_rdwr )) +#define LDBM_WLOCK (ldap_pvt_thread_rdwr_wlock(&ldbm_big_rdwr)) +#define LDBM_WUNLOCK (ldap_pvt_thread_rdwr_wunlock(&ldbm_big_rdwr)) +#define LDBM_RLOCK (ldap_pvt_thread_rdwr_rlock(&ldbm_big_rdwr)) +#define LDBM_RUNLOCK (ldap_pvt_thread_rdwr_runlock(&ldbm_big_rdwr)) +#else static ldap_pvt_thread_mutex_t ldbm_big_mutex; -#define LDBM_LOCK (ldap_pvt_thread_mutex_lock(&ldbm_big_mutex)) -#define LDBM_UNLOCK (ldap_pvt_thread_mutex_unlock(&ldbm_big_mutex)) - -int ldbm_initialize( void ) -{ - if(ldbm_initialized++) return 1; - - ldap_pvt_thread_mutex_init( &ldbm_big_mutex ); - - return 0; -} - -int ldbm_shutdown( void ) -{ - if( !ldbm_initialized ) return 1; - - ldap_pvt_thread_mutex_destroy( &ldbm_big_mutex ); +#define LDBM_RWLOCK_INIT (ldap_pvt_thread_mutex_init( &ldbm_big_mutex )) +#define LDBM_RWLOCK_DESTROY (ldap_pvt_thread_mutex_destroy( &ldbm_big_mutex )) +#define LDBM_WLOCK (ldap_pvt_thread_mutex_lock(&ldbm_big_mutex)) +#define LDBM_WUNLOCK (ldap_pvt_thread_mutex_unlock(&ldbm_big_mutex)) +#define LDBM_RLOCK LDBM_WLOCK +#define LDBM_RUNLOCK LDBM_WUNLOCK +#endif - return 0; -} +#if !defined( HAVE_BERKELEY_DB ) || (DB_VERSION_MAJOR < 3) + /* a dbEnv for BERKELEYv2 */ +DB_ENV *ldbm_Env = NULL; /* real or fake, depending on db and version */ +#endif -#else +/******************************************************************* + * * + * Create some special functions to initialize Berkeley DB for * + * versions greater than 2. * + * * + *******************************************************************/ +#if defined( HAVE_BERKELEY_DB ) && (DB_VERSION_MAJOR >= 2) void * ldbm_malloc( size_t size ) { - return( calloc( 1, size )); + /* likely should use ber_mem* routines */ + return( calloc( 1, size ) ); } #ifdef LDAP_SYSLOG @@ -94,49 +114,66 @@ static void ldbm_db_errcall( const char *prefix, char *message ) { #ifdef LDAP_SYSLOG - syslog( LOG_INFO, "ldbm_db_errcall(): %s %s", prefix, message ); + syslog( LOG_INFO, "ldbm: %s %s", prefix, message ); #endif } -/* a dbEnv for BERKELEYv2 */ -static DB_ENV ldbm_Env_internal; -DB_ENV *ldbm_Env = NULL; - -/* Berkeley DB 2.x is reentrant */ -#define LDBM_LOCK ((void)0) -#define LDBM_UNLOCK ((void)0) - -int ldbm_initialize( void ) +int ldbm_initialize( const char* home ) { - int err; - int envFlags; +#if DB_VERSION_MAJOR < 3 + int err; + u_int32_t envFlags; +#endif if(ldbm_initialized++) return 1; - memset( &ldbm_Env_internal, 0, sizeof( DB_ENV )); - ldbm_Env = &ldbm_Env_internal; + { + char *version; + int major, minor, patch; + version = db_version( &major, &minor, &patch ); - ldbm_Env->db_errcall = ldbm_db_errcall; - ldbm_Env->db_errpfx = "==>"; + if( major != DB_VERSION_MAJOR || + minor < DB_VERSION_MINOR ) + { +#ifdef LDAP_SYSLOG + syslog( LOG_INFO, + "ldbm_initialize(): version mismatch\nexpected: %s\ngot: %s\n", + DB_VERSION_STRING, version ); +#endif + return 1; + } + } - envFlags = DB_CREATE | DB_THREAD; +#if DB_VERSION_MAJOR < 3 + ldbm_Env = calloc( 1, sizeof( DB_ENV )); - if ( ( err = db_appinit( NULL, NULL, ldbm_Env, envFlags )) ) { - char error[BUFSIZ]; + if( ldbm_Env == NULL ) return 1; - if ( err < 0 ) { - sprintf( error, "%ld\n", (long) err ); - } else { - sprintf( error, "%s\n", strerror( err )); - } + ldbm_Env->db_errcall = ldbm_db_errcall; + ldbm_Env->db_errpfx = "==>"; + + envFlags = DB_CREATE | DB_USE_ENVIRON; + + /* add optional flags */ +#ifdef DB_PRIVATE + envFlags |= DB_PRIVATE; +#endif +#ifdef HAVE_BERKELEY_DB_THREAD + envFlags |= DB_THREAD; +#endif + err = db_appinit( home, NULL, ldbm_Env, envFlags ); + + if ( err ) { #ifdef LDAP_SYSLOG - syslog( LOG_INFO, - "ldbm_initialize(): FATAL error in db_appinit() : %s\n", - error ); + syslog( LOG_INFO, "ldbm_initialize(): " + "FATAL error (%d) in db_appinit()\n", err ); #endif return( 1 ); } +#endif + + LDBM_RWLOCK_INIT; return 0; } @@ -145,11 +182,114 @@ int ldbm_shutdown( void ) { if( !ldbm_initialized ) return 1; +#if DB_VERSION_MAJOR < 3 db_appexit( ldbm_Env ); +#endif + + LDBM_RWLOCK_DESTROY; + return 0; +} + +#else /* some DB other than Berkeley V2 or greater */ + +int ldbm_initialize( const char * home ) +{ + if(ldbm_initialized++) return 1; + + LDBM_RWLOCK_INIT; return 0; } +int ldbm_shutdown( void ) +{ + if( !ldbm_initialized ) return 1; + + LDBM_RWLOCK_DESTROY; + + return 0; +} + +#endif /* HAVE_BERKELEY_DB */ + +#if defined( HAVE_BERKELEY_DB ) && (DB_VERSION_MAJOR >= 3) + +DB_ENV *ldbm_initialize_env(const char *home, int dbcachesize, int *envdirok) +{ + DB_ENV *env = NULL; + int err; + u_int32_t envFlags; + + err = db_env_create( &env, 0 ); + + if ( err ) { +#ifdef LDAP_SYSLOG + syslog( LOG_INFO, "ldbm_initialize_env(): " + "FATAL error in db_env_create() : %s (%d)\n", + db_strerror( err ), err ); +#endif + return NULL; + } + +#if DB_VERSION_MAJOR > 3 || DB_VERSION_MINOR >= 3 + /* This interface appeared in 3.3 */ + env->set_alloc( env, ldbm_malloc, NULL, NULL ); +#endif + + env->set_errcall( env, ldbm_db_errcall ); + env->set_errpfx( env, "==>" ); + if (dbcachesize) { + env->set_cachesize( env, 0, dbcachesize, 0 ); + } + + envFlags = DB_CREATE | DB_INIT_MPOOL | DB_USE_ENVIRON; +#ifdef DB_PRIVATE + envFlags |= DB_PRIVATE; +#endif +#ifdef DB_MPOOL_PRIVATE + envFlags |= DB_MPOOL_PRIVATE; +#endif +#ifdef HAVE_BERKELEY_DB_THREAD + envFlags |= DB_THREAD; +#endif + +#if DB_VERSION_MAJOR > 3 || DB_VERSION_MINOR > 0 + err = env->open( env, home, envFlags, 0 ); +#else + /* 3.0.x requires an extra argument */ + err = env->open( env, home, NULL, envFlags, 0 ); +#endif + + if ( err != 0 ) { +#ifdef LDAP_SYSLOG + syslog( LOG_INFO, "ldbm_initialize_env(): " + "FATAL error in dbEnv->open() : %s (%d)\n", + db_strerror( err ), err ); +#endif + env->close( env, 0 ); + return NULL; + } + + *envdirok = 1; + return env; +} + +void ldbm_shutdown_env(DB_ENV *env) +{ + env->close( env, 0 ); +} + +#else + +DB_ENV *ldbm_initialize_env(const char *home, int dbcachesize, int *envdirok) +{ + return ldbm_Env; +} + +void ldbm_shutdown_env(DB_ENV *env) +{ +} + #endif #if defined( LDBM_USE_DBHASH ) || defined( LDBM_USE_DBBTREE ) @@ -161,22 +301,80 @@ int ldbm_shutdown( void ) *****************************************************************/ LDBM -ldbm_open( char *name, int rw, int mode, int dbcachesize ) +ldbm_open( DB_ENV *env, char *name, int rw, int mode, int dbcachesize ) { LDBM ret = NULL; +#ifdef HAVE_EBCDIC + char n2[2048]; +#endif + +#if DB_VERSION_MAJOR >= 3 + int err; + + LDBM_WLOCK; + + err = db_create( &ret, env, 0 ); + if ( err != 0 ) { + (void)ret->close(ret, 0); + LDBM_WUNLOCK; + + return NULL; + } + +#if DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR < 3 + ret->set_malloc( ret, ldbm_malloc ); +#endif -#ifdef HAVE_BERKELEY_DB2 + ret->set_pagesize( ret, DEFAULT_DB_PAGE_SIZE ); + + /* likely should use ber_mem* routines */ + +#ifdef HAVE_EBCDIC + strncpy(n2, name, sizeof(n2)-1); + n2[sizeof(n2)-1] = '\0'; + __atoe(n2); + name = n2; +#endif +#if DB_VERSION_MAJOR >= 4 && DB_VERSION_MINOR > 0 && DB_VERSION_PATCH >= 17 + err = ret->open( ret, NULL, name, NULL, DB_TYPE, rw, mode); +#else + err = ret->open( ret, name, NULL, DB_TYPE, rw, mode); +#endif + + if ( err != 0 ) { + int tmp = errno; + (void)ret->close(ret, 0); + errno = tmp; + + LDBM_WUNLOCK; + return NULL; + } + + LDBM_WUNLOCK; + +#elif DB_VERSION_MAJOR >= 2 DB_INFO dbinfo; - memset( &dbinfo, 0, sizeof( dbinfo )); - if (( ldbm_Env == NULL ) || ( ldbm_Env->mp_info == NULL )) + memset( &dbinfo, '\0', sizeof( dbinfo )); + +#if DB_VERSION_MAJOR == 2 && DB_VERSION_MINOR == 4 + /* + * BerkeleyDB 2.4 do not allow db_cachesize + * to be specified if an DB_ENV is. + */ +#else + /* set db_cachesize of MPOOL is NOT being used. */ + if (( ldbm_Env == NULL ) || ( ldbm_Env->mp_info == NULL )) { dbinfo.db_cachesize = dbcachesize; - dbinfo.db_pagesize = DEFAULT_DB_PAGE_SIZE; - dbinfo.db_malloc = ldbm_malloc; + } +#endif + + dbinfo.db_pagesize = DEFAULT_DB_PAGE_SIZE; + dbinfo.db_malloc = ldbm_malloc; - LDBM_LOCK; - (void) db_open( name, DB_TYPE, rw, mode, ldbm_Env, &dbinfo, &ret ); - LDBM_UNLOCK; + LDBM_WLOCK; + (void) db_open( name, DB_TYPE, rw, mode, ldbm_Env, &dbinfo, &ret ); + LDBM_WUNLOCK; #else void *info; @@ -195,33 +393,32 @@ ldbm_open( char *name, int rw, int mode, int dbcachesize ) info = NULL; } - LDBM_LOCK; + LDBM_WLOCK; ret = dbopen( name, rw, mode, DB_TYPE, info ); - LDBM_UNLOCK; - + LDBM_WUNLOCK; #endif - return( ret ); + return ret; } void ldbm_close( LDBM ldbm ) { - LDBM_LOCK; -#ifdef HAVE_BERKELEY_DB2 - (*ldbm->close)( ldbm, 0 ); + LDBM_WLOCK; +#if DB_VERSION_MAJOR >= 2 + ldbm->close( ldbm, 0 ); #else - (*ldbm->close)( ldbm ); + ldbm->close( ldbm ); #endif - LDBM_UNLOCK; + LDBM_WUNLOCK; } void ldbm_sync( LDBM ldbm ) { - LDBM_LOCK; + LDBM_WLOCK; (*ldbm->sync)( ldbm, 0 ); - LDBM_UNLOCK; + LDBM_WUNLOCK; } Datum @@ -230,27 +427,30 @@ ldbm_fetch( LDBM ldbm, Datum key ) Datum data; int rc; - LDBM_LOCK; + LDBM_RLOCK; -#ifdef HAVE_BERKELEY_DB2 +#if DB_VERSION_MAJOR >= 2 ldbm_datum_init( data ); data.flags = DB_DBT_MALLOC; - if ( (rc = (*ldbm->get)( ldbm, NULL, &key, &data, 0 )) != 0 ) { + if ( (rc = ldbm->get( ldbm, NULL, &key, &data, 0 )) != 0 ) { ldbm_datum_free( ldbm, data ); + data.dptr = NULL; + data.dsize = 0; + } #else - if ( (rc = (*ldbm->get)( ldbm, &key, &data, 0 )) == 0 ) { + if ( (rc = ldbm->get( ldbm, &key, &data, 0 )) == 0 ) { /* Berkeley DB 1.85 don't malloc the data for us */ /* duplicate it for to ensure reentrancy */ data = ldbm_datum_dup( ldbm, data ); } else { -#endif data.dptr = NULL; data.dsize = 0; } +#endif - LDBM_UNLOCK; + LDBM_RUNLOCK; return( data ); } @@ -260,19 +460,19 @@ ldbm_store( LDBM ldbm, Datum key, Datum data, int flags ) { int rc; - LDBM_LOCK; + LDBM_WLOCK; -#ifdef HAVE_BERKELEY_DB2 - rc = (*ldbm->put)( ldbm, NULL, &key, &data, flags & ~LDBM_SYNC ); - rc = (-1 ) * rc; +#if DB_VERSION_MAJOR >= 2 + rc = ldbm->put( ldbm, NULL, &key, &data, flags & ~LDBM_SYNC ); + rc = (-1) * rc; #else - rc = (*ldbm->put)( ldbm, &key, &data, flags & ~LDBM_SYNC ); + rc = ldbm->put( ldbm, &key, &data, flags & ~LDBM_SYNC ); #endif if ( flags & LDBM_SYNC ) - (*ldbm->sync)( ldbm, 0 ); + ldbm->sync( ldbm, 0 ); - LDBM_UNLOCK; + LDBM_WUNLOCK; return( rc ); } @@ -282,119 +482,107 @@ ldbm_delete( LDBM ldbm, Datum key ) { int rc; - LDBM_LOCK; + LDBM_WLOCK; -#ifdef HAVE_BERKELEY_DB2 - rc = (*ldbm->del)( ldbm, NULL, &key, 0 ); - rc = (-1 ) * rc; +#if DB_VERSION_MAJOR >= 2 + rc = ldbm->del( ldbm, NULL, &key, 0 ); + rc = (-1) * rc; #else - rc = (*ldbm->del)( ldbm, &key, 0 ); + rc = ldbm->del( ldbm, &key, 0 ); #endif - (*ldbm->sync)( ldbm, 0 ); + ldbm->sync( ldbm, 0 ); - LDBM_UNLOCK; + LDBM_WUNLOCK; return( rc ); } Datum -#ifdef HAVE_BERKELEY_DB2 -ldbm_firstkey( LDBM ldbm, DBC **dbch ) -#else -ldbm_firstkey( LDBM ldbm ) -#endif +ldbm_firstkey( LDBM ldbm, LDBMCursor **dbch ) { Datum key, data; + int rc; -#ifdef HAVE_BERKELEY_DB2 - DBC *dbci; +#if DB_VERSION_MAJOR >= 2 + LDBMCursor *dbci; ldbm_datum_init( key ); ldbm_datum_init( data ); key.flags = data.flags = DB_DBT_MALLOC; - LDBM_LOCK; + LDBM_RLOCK; /* acquire a cursor for the DB */ +# if DB_VERSION_MAJOR >= 3 || (DB_VERSION_MAJOR == 2 && DB_VERSION_MINOR > 5) + rc = ldbm->cursor( ldbm, NULL, &dbci, 0 ); +# else + rc = ldbm->cursor( ldbm, NULL, &dbci ); +# endif -# if defined( DB_VERSION_MAJOR ) && defined( DB_VERSION_MINOR ) && \ - DB_VERSION_MAJOR == 2 && DB_VERSION_MINOR < 6 - - if ( (*ldbm->cursor)( ldbm, NULL, &dbci )) - -# else - if ( (*ldbm->cursor)( ldbm, NULL, &dbci, 0 )) -# endif - { + if( rc ) { key.dptr = NULL; - return( key ); } else { *dbch = dbci; - if ( (*dbci->c_get)( dbci, &key, &data, DB_NEXT ) == 0 ) { + if ( dbci->c_get( dbci, &key, &data, DB_NEXT ) == 0 ) { ldbm_datum_free( ldbm, data ); + } else { + key.dptr = NULL; + key.dsize = 0; } - else { + } + + LDBM_RUNLOCK; + #else - int rc; + LDBM_RLOCK; - LDBM_LOCK; + rc = ldbm->seq( ldbm, &key, &data, R_FIRST ); - if ( (rc = (*ldbm->seq)( ldbm, &key, &data, R_FIRST )) == 0 ) { + if ( rc == 0 ) { key = ldbm_datum_dup( ldbm, key ); - } - else { -#endif + } else { key.dptr = NULL; key.dsize = 0; } -#ifdef HAVE_BERKELEY_DB2 - } + LDBM_RUNLOCK; #endif - LDBM_UNLOCK; - return( key ); } Datum -#ifdef HAVE_BERKELEY_DB2 -ldbm_nextkey( LDBM ldbm, Datum key, DBC *dbcp ) -#else -ldbm_nextkey( LDBM ldbm, Datum key ) -#endif +ldbm_nextkey( LDBM ldbm, Datum key, LDBMCursor *dbcp ) { + int rc; Datum data; -#ifdef HAVE_BERKELEY_DB2 + LDBM_RLOCK; + +#if DB_VERSION_MAJOR >= 2 ldbm_datum_init( data ); ldbm_datum_free( ldbm, key ); key.flags = data.flags = DB_DBT_MALLOC; - LDBM_LOCK; - - if ( (*dbcp->c_get)( dbcp, &key, &data, DB_NEXT ) == 0 ) { + rc = dbcp->c_get( dbcp, &key, &data, DB_NEXT ); + if ( rc == 0 ) { ldbm_datum_free( ldbm, data ); - } - else { + } else #else - int rc; + rc = ldbm->seq( ldbm, &key, &data, R_NEXT ); - LDBM_LOCK; - - if ( (rc = (*ldbm->seq)( ldbm, &key, &data, R_NEXT )) == 0 ) { + if ( rc == 0 ) { key = ldbm_datum_dup( ldbm, key ); - } - else { + } else #endif + { key.dptr = NULL; key.dsize = 0; } - LDBM_UNLOCK; - + LDBM_RUNLOCK; return( key ); } @@ -404,6 +592,12 @@ ldbm_errno( LDBM ldbm ) return( errno ); } +/****************************************************************** + * * + * END Berkeley section * + * * + ******************************************************************/ + #elif defined( HAVE_GDBM ) #ifdef HAVE_ST_BLKSIZE @@ -417,31 +611,43 @@ ldbm_errno( LDBM ldbm ) *****************************************************************/ LDBM -ldbm_open( char *name, int rw, int mode, int dbcachesize ) +ldbm_open( DB_ENV *env, char *name, int rw, int mode, int dbcachesize ) { LDBM db; #ifdef HAVE_ST_BLKSIZE struct stat st; #endif +#ifdef HAVE_EBCDIC + char n2[2048]; + + strncpy(n2, name, sizeof(n2)-1); + n2[sizeof(n2)-1] = '\0'; + __atoe(n2); + name = n2; +#endif - LDBM_LOCK; + LDBM_WLOCK; - if ( (db = gdbm_open( name, 0, rw | GDBM_FAST, mode, 0 )) == NULL ) { - LDBM_UNLOCK; + if ( (db = gdbm_open( name, 0, rw | GDBM_FAST, mode, 0 )) == NULL ) { + LDBM_WUNLOCK; return( NULL ); } #ifdef HAVE_ST_BLKSIZE if ( dbcachesize > 0 && stat( name, &st ) == 0 ) { - dbcachesize = (dbcachesize / st.st_blksize); + dbcachesize /= st.st_blksize; + if( dbcachesize == 0 ) dbcachesize = 1; gdbm_setopt( db, GDBM_CACHESIZE, &dbcachesize, sizeof(int) ); } #else - dbcachesize = (dbcachesize / 4096); - gdbm_setopt( db, GDBM_CACHESIZE, &dbcachesize, sizeof(int) ); + if ( dbcachesize > 0 ) { + dbcachesize /= 4096; + if( dbcachesize == 0 ) dbcachesize = 1; + gdbm_setopt( db, GDBM_CACHESIZE, &dbcachesize, sizeof(int) ); + } #endif - LDBM_UNLOCK; + LDBM_WUNLOCK; return( db ); } @@ -449,17 +655,17 @@ ldbm_open( char *name, int rw, int mode, int dbcachesize ) void ldbm_close( LDBM ldbm ) { - LDBM_LOCK; + LDBM_WLOCK; gdbm_close( ldbm ); - LDBM_UNLOCK; + LDBM_WUNLOCK; } void ldbm_sync( LDBM ldbm ) { - LDBM_LOCK; + LDBM_WLOCK; gdbm_sync( ldbm ); - LDBM_UNLOCK; + LDBM_WUNLOCK; } Datum @@ -467,9 +673,9 @@ ldbm_fetch( LDBM ldbm, Datum key ) { Datum d; - LDBM_LOCK; + LDBM_RLOCK; d = gdbm_fetch( ldbm, key ); - LDBM_UNLOCK; + LDBM_RUNLOCK; return d; } @@ -479,11 +685,11 @@ ldbm_store( LDBM ldbm, Datum key, Datum data, int flags ) { int rc; - LDBM_LOCK; + LDBM_WLOCK; rc = gdbm_store( ldbm, key, data, flags & ~LDBM_SYNC ); if ( flags & LDBM_SYNC ) gdbm_sync( ldbm ); - LDBM_UNLOCK; + LDBM_WUNLOCK; return( rc ); } @@ -493,34 +699,47 @@ ldbm_delete( LDBM ldbm, Datum key ) { int rc; - LDBM_LOCK; + LDBM_WLOCK; rc = gdbm_delete( ldbm, key ); gdbm_sync( ldbm ); - LDBM_UNLOCK; + LDBM_WUNLOCK; return( rc ); } Datum -ldbm_firstkey( LDBM ldbm ) +ldbm_firstkey( LDBM ldbm, LDBMCursor **dbcp ) { Datum d; - LDBM_LOCK; + LDBM_RLOCK; d = gdbm_firstkey( ldbm ); - LDBM_UNLOCK; + LDBM_RUNLOCK; + + if ( d.dptr != NULL ) { + *dbcp = (Datum *) malloc( sizeof( Datum ) ); + **dbcp = ldbm_datum_dup( ldbm, d ); + } return d; } Datum -ldbm_nextkey( LDBM ldbm, Datum key ) +ldbm_nextkey( LDBM ldbm, Datum key, LDBMCursor *dbcp ) { Datum d; - LDBM_LOCK; - d = gdbm_nextkey( ldbm, key ); - LDBM_UNLOCK; + LDBM_RLOCK; + d = gdbm_nextkey( ldbm, *dbcp ); + LDBM_RUNLOCK; + + ldbm_datum_free( ldbm, *dbcp ); + + if ( d.dptr != NULL ) { + *dbcp = ldbm_datum_dup( ldbm, d ); + } else { + free( dbcp ); + } return d; } @@ -530,9 +749,9 @@ ldbm_errno( LDBM ldbm ) { int err; - LDBM_LOCK; + LDBM_WLOCK; err = gdbm_errno; - LDBM_UNLOCK; + LDBM_WUNLOCK; return( err ); } @@ -541,8 +760,7 @@ ldbm_errno( LDBM ldbm ) /* MMAPED DBM HASHING DATABASE */ -#include -#include +#include /* #define MDBM_DEBUG */ @@ -557,7 +775,6 @@ ldbm_errno( LDBM ldbm ) /* Use chaining */ - #define mdbm_store mdbm_chain_store #define mdbm_fetch mdbm_chain_fetch #define mdbm_delete mdbm_chain_delete @@ -575,7 +792,7 @@ ldbm_errno( LDBM ldbm ) *****************************************************************/ LDBM -ldbm_open( char *name, int rw, int mode, int dbcachesize ) +ldbm_open( DB_ENV *env, char *name, int rw, int mode, int dbcachesize ) { LDBM db; @@ -586,26 +803,23 @@ ldbm_open( char *name, int rw, int mode, int dbcachesize ) fflush( stdout ); #endif - LDBM_LOCK; /* We need locking here, this is the only non-thread - * safe function we have. - */ + LDBM_WLOCK; /* We need locking here, this is the only non-thread + * safe function we have. */ if ( (db = mdbm_open( name, rw, mode, MDBM_PG_SZ )) == NULL ) { - - LDBM_UNLOCK; + LDBM_WUNLOCK; #ifdef MDBM_DEBUG fprintf( stdout, "<==(mdbm)ldbm_open(db=NULL)\n" ); fflush( stdout ); #endif return( NULL ); - } #ifdef MDBM_CHAIN (void)mdbm_set_chain(db); #endif - LDBM_UNLOCK; + LDBM_WUNLOCK; #ifdef MDBM_DEBUG fprintf( stdout, "<==(mdbm)ldbm_open(db=%p)\n", db ); @@ -613,16 +827,11 @@ ldbm_open( char *name, int rw, int mode, int dbcachesize ) #endif return( db ); - -}/* LDBM ldbm_open() */ - - - +} void ldbm_close( LDBM ldbm ) { - /* Open and close are not reentrant so we need to use locks here */ #ifdef MDBM_DEBUG @@ -631,34 +840,27 @@ ldbm_close( LDBM ldbm ) fflush( stdout ); #endif - LDBM_LOCK; + LDBM_WLOCK; mdbm_close( ldbm ); - LDBM_UNLOCK; + LDBM_WUNLOCK; #ifdef MDBM_DEBUG fprintf( stdout, "<==(mdbm)ldbm_close()\n" ); fflush( stdout ); #endif - -}/* void ldbm_close() */ - - - +} void ldbm_sync( LDBM ldbm ) { - /* XXX: Not sure if this is re-entrant need to check code, if so * you can leave LOCKS out. */ - LDBM_LOCK; + LDBM_WLOCK; mdbm_sync( ldbm ); - LDBM_UNLOCK; - -}/* void ldbm_sync() */ - + LDBM_WUNLOCK; +} #define MAX_MDBM_RETRY 5 @@ -674,13 +876,11 @@ ldbm_fetch( LDBM ldbm, Datum key ) * mode. */ - /* LDBM_LOCK; */ - #ifdef NO_NULL_KEY k.key.dsize = key.dsize + 1; - k.key.dptr = alloca(k.key.dsize); + k.key.dptr = malloc(k.key.dsize); *(k.key.dptr) = 'l'; - memcpy( (void *)(k.key.dptr + 1), key.dptr, key.dsize ); + AC_MEMCPY( (void *)(k.key.dptr + 1), key.dptr, key.dsize ); #else k.key = key; #endif @@ -688,42 +888,33 @@ ldbm_fetch( LDBM ldbm, Datum key ) k.val.dptr = NULL; k.val.dsize = 0; + /* LDBM_RLOCK; */ do { - d = mdbm_fetch( ldbm, k ); if ( d.dsize > 0 ) { - if ( k.val.dptr != NULL ) { - - free( k.val.dptr ); - + free( k.val.dptr ); } if ( (k.val.dptr = malloc( d.dsize )) != NULL ) { - k.val.dsize = d.dsize; d = mdbm_fetch( ldbm, k ); } else { - d.dsize = 0; break; - } - }/* if ( d.dsize > 0 ) */ - } while ((d.dsize > k.val.dsize) && (++retry < MAX_MDBM_RETRY)); + /* LDBM_RUNLOCK; */ - /* LDBM_UNLOCK; */ +#ifdef NO_NULL_KEY + free(k.key.dptr); +#endif return d; - -}/* Datum ldbm_fetch() */ - - - +} int ldbm_store( LDBM ldbm, Datum key, Datum data, int flags ) @@ -738,13 +929,13 @@ ldbm_store( LDBM ldbm, Datum key, Datum data, int flags ) fflush( stdout ); #endif - /* LDBM_LOCK; */ + /* LDBM_WLOCK; */ #ifdef NO_NULL_KEY int_key.dsize = key.dsize + 1; - int_key.dptr = alloca( int_key.dsize ); + int_key.dptr = malloc( int_key.dsize ); *(int_key.dptr) = 'l'; /* Must not be NULL !*/ - memcpy( (void *)(int_key.dptr + 1), key.dptr, key.dsize ); + AC_MEMCPY( (void *)(int_key.dptr + 1), key.dptr, key.dsize ); #else int_key = key; #endif @@ -754,19 +945,19 @@ ldbm_store( LDBM ldbm, Datum key, Datum data, int flags ) mdbm_sync( ldbm ); } - /* LDBM_UNLOCK; */ + /* LDBM_WUNLOCK; */ #ifdef MDBM_DEBUG fprintf( stdout, "<==(mdbm)ldbm_store(rc=%d)\n", rc ); fflush( stdout ); #endif - return( rc ); - -}/* int ldbm_store() */ - - +#ifdef NO_NULL_KEY + free(int_key.dptr); +#endif + return( rc ); +} int ldbm_delete( LDBM ldbm, Datum key ) @@ -774,32 +965,30 @@ ldbm_delete( LDBM ldbm, Datum key ) int rc; Datum int_key; - /* LDBM_LOCK; */ + /* LDBM_WLOCK; */ #ifdef NO_NULL_KEY int_key.dsize = key.dsize + 1; - int_key.dptr = alloca(int_key.dsize); + int_key.dptr = malloc(int_key.dsize); *(int_key.dptr) = 'l'; - memcpy( (void *)(int_key.dptr + 1), key.dptr, key.dsize ); + AC_MEMCPY( (void *)(int_key.dptr + 1), key.dptr, key.dsize ); #else int_key = key; #endif rc = mdbm_delete( ldbm, int_key ); - /* LDBM_UNLOCK; */ + /* LDBM_WUNLOCK; */ +#ifdef NO_NULL_KEY + free(int_key.dptr); +#endif return( rc ); - -}/* int ldbm_delete() */ - - - +} static Datum ldbm_get_next( LDBM ldbm, kvpair (*fptr)(MDBM *, kvpair) ) { - kvpair out; kvpair in; Datum ret; @@ -810,10 +999,10 @@ ldbm_get_next( LDBM ldbm, kvpair (*fptr)(MDBM *, kvpair) ) int delta = 0; #endif - /* LDBM_LOCK; */ + /* LDBM_RLOCK; */ in.key.dsize = sz; /* Assume first key in one pg */ - in.key.dptr = alloca(sz); + in.key.dptr = malloc(sz); in.val.dptr = NULL; /* Don't need data just key */ in.val.dsize = 0; @@ -824,65 +1013,47 @@ ldbm_get_next( LDBM ldbm, kvpair (*fptr)(MDBM *, kvpair) ) out = fptr( ldbm, in ); if (out.key.dsize > 0) { + ret.dsize = out.key.dsize - delta; - ret.dsize = out.key.dsize - delta; - if ((ret.dptr = (char *)malloc(ret.dsize)) == NULL) { - - ret.dsize = 0; - ret.dptr = NULL; - - } else { - - memcpy(ret.dptr, (void *)(out.key.dptr + delta), - ret.dsize ); + if ((ret.dptr = (char *)malloc(ret.dsize)) == NULL) { + ret.dsize = 0; + ret.dptr = NULL; + } else { + AC_MEMCPY(ret.dptr, (void *)(out.key.dptr + delta), + ret.dsize ); } - } - /* LDBM_UNLOCK; */ - + /* LDBM_RUNLOCK; */ + + free(in.key.dptr); return ret; - -}/* static Datum ldbm_get_next() */ - - - +} Datum -ldbm_firstkey( LDBM ldbm ) +ldbm_firstkey( LDBM ldbm, LDBMCursor **dbcp ) { - return ldbm_get_next( ldbm, mdbm_first ); - -}/* Datum ldbm_firstkey() */ - - - +} Datum -ldbm_nextkey( LDBM ldbm, Datum key ) +ldbm_nextkey( LDBM ldbm, Datum key, LDBMCursor *dbcp ) { - /* XXX: - * don't know if this will affect the LDAP server opertaion + * don't know if this will affect the LDAP server operation * but mdbm cannot take and input key. */ return ldbm_get_next( ldbm, mdbm_next ); - -}/* Datum ldbm_nextkey() */ +} int ldbm_errno( LDBM ldbm ) { /* XXX: best we can do with current mdbm interface */ return( errno ); - -}/* int ldbm_errno() */ - - - +} #elif defined( HAVE_NDBM ) @@ -894,13 +1065,13 @@ ldbm_errno( LDBM ldbm ) /* ARGSUSED */ LDBM -ldbm_open( char *name, int rw, int mode, int dbcachesize ) +ldbm_open( DB_ENV *env, char *name, int rw, int mode, int dbcachesize ) { LDBM ldbm; - LDBM_LOCK; + LDBM_WLOCK; ldbm = dbm_open( name, rw, mode ); - LDBM_UNLOCK; + LDBM_WUNLOCK; return( ldbm ); } @@ -908,9 +1079,9 @@ ldbm_open( char *name, int rw, int mode, int dbcachesize ) void ldbm_close( LDBM ldbm ) { - LDBM_LOCK; + LDBM_WLOCK; dbm_close( ldbm ); - LDBM_UNLOCK; + LDBM_WUNLOCK; } /* ARGSUSED */ @@ -925,9 +1096,9 @@ ldbm_fetch( LDBM ldbm, Datum key ) { Datum d; - LDBM_LOCK; + LDBM_RLOCK; d = ldbm_datum_dup( ldbm, dbm_fetch( ldbm, key ) ); - LDBM_UNLOCK; + LDBM_RUNLOCK; return d; } @@ -937,9 +1108,9 @@ ldbm_store( LDBM ldbm, Datum key, Datum data, int flags ) { int rc; - LDBM_LOCK; + LDBM_WLOCK; rc = dbm_store( ldbm, key, data, flags ); - LDBM_UNLOCK; + LDBM_WUNLOCK; return rc; } @@ -949,33 +1120,33 @@ ldbm_delete( LDBM ldbm, Datum key ) { int rc; - LDBM_LOCK; + LDBM_WLOCK; rc = dbm_delete( ldbm, key ); - LDBM_UNLOCK; + LDBM_WUNLOCK; return rc; } Datum -ldbm_firstkey( LDBM ldbm ) +ldbm_firstkey( LDBM ldbm, LDBMCursor **dbcp ) { Datum d; - LDBM_LOCK; + LDBM_RLOCK; d = dbm_firstkey( ldbm ); - LDBM_UNLOCK; + LDBM_RUNLOCK; return d; } Datum -ldbm_nextkey( LDBM ldbm, Datum key ) +ldbm_nextkey( LDBM ldbm, Datum key, LDBMCursor *dbcp ) { Datum d; - LDBM_LOCK; + LDBM_RLOCK; d = dbm_nextkey( ldbm ); - LDBM_UNLOCK; + LDBM_RUNLOCK; return d; } @@ -985,9 +1156,9 @@ ldbm_errno( LDBM ldbm ) { int err; - LDBM_LOCK; + LDBM_WLOCK; err = dbm_error( ldbm ); - LDBM_UNLOCK; + LDBM_WUNLOCK; return err; }