1 /* ldbm.c - ldap dbm compatibility routines */
3 /* Patched for Berkeley DB version 2.0; /KSp; 98/02/23
5 * - DB version 2.6.4b ; 1998/12/28, /KSp
6 * - DB_DBT_MALLOC ; 1998/03/22, /KSp
7 * - basic implementation; 1998/02/23, /KSp
18 #include <ac/string.h>
24 #if defined( LDBM_USE_DBHASH ) || defined( LDBM_USE_DBBTREE )
26 /*****************************************************************
28 * use berkeley db hash or btree package *
30 *****************************************************************/
32 #ifdef HAVE_BERKELEY_DB2
35 ldbm_malloc( size_t size )
37 return( calloc( 1, size ));
41 ldbm_db_errcall( const char *prefix, char *message )
44 syslog( LOG_INFO, "ldbm_db_errcall(): %s %s", prefix, message );
48 /* a dbEnv for BERKELEYv2 */
49 static DB_ENV ldbm_Env;
51 /* Berkeley DB 2.x is reentrant */
52 #define LDBM_LOCK ((void)0)
53 #define LDBM_UNLOCK ((void)0)
55 void ldbm_initialize( void )
57 static int initialized = 0;
62 if(initialized++) return;
64 memset( &ldbm_Env, 0, sizeof( ldbm_Env ));
66 ldbm_Env.db_errcall = ldbm_db_errcall;
67 ldbm_Env.db_errpfx = "==>";
69 envFlags = DB_CREATE | DB_THREAD;
71 if ( ( err = db_appinit( NULL, NULL, &ldbm_Env, envFlags )) ) {
75 sprintf( error, "%ld\n", (long) err );
77 sprintf( error, "%s\n", strerror( err ));
81 "ldbm_initialize(): FATAL error in db_appinit() : %s\n",
89 /* DB 1.85 is non-reentrant */
90 static pthread_mutex_t ldbm_big_mutex;
91 #define LDBM_LOCK (pthread_mutex_lock(&ldbm_big_mutex))
92 #define LDBM_UNLOCK (pthread_mutex_unlock(&ldbm_big_mutex))
94 void ldbm_initialize( void )
96 static int initialized = 0;
98 if(initialized++) return;
100 pthread_mutex_init( &ldbm_big_mutex, pthread_mutexattr_default );
108 ldbm_open( char *name, int rw, int mode, int dbcachesize )
112 #ifdef HAVE_BERKELEY_DB2
115 memset( &dbinfo, 0, sizeof( dbinfo ));
116 dbinfo.db_cachesize = dbcachesize;
117 dbinfo.db_pagesize = DEFAULT_DB_PAGE_SIZE;
118 dbinfo.db_malloc = ldbm_malloc;
121 (void) db_open( name, DB_TYPE, rw, mode, &ldbm_Env, &dbinfo, &ret );
129 if ( DB_TYPE == DB_HASH ) {
130 memset( (char *) &hinfo, '\0', sizeof(hinfo) );
131 hinfo.cachesize = dbcachesize;
133 } else if ( DB_TYPE == DB_BTREE ) {
134 memset( (char *) &binfo, '\0', sizeof(binfo) );
135 binfo.cachesize = dbcachesize;
142 ret = dbopen( name, rw, mode, DB_TYPE, info );
151 ldbm_close( LDBM ldbm )
154 #ifdef HAVE_BERKELEY_DB2
155 (*ldbm->close)( ldbm, 0 );
157 (*ldbm->close)( ldbm );
163 ldbm_sync( LDBM ldbm )
166 (*ldbm->sync)( ldbm, 0 );
171 ldbm_datum_free( LDBM ldbm, Datum data )
177 ldbm_datum_dup( LDBM ldbm, Datum data )
181 ldbm_datum_init( dup );
183 if ( data.dsize == 0 ) {
186 dup.dsize = data.dsize;
187 if ( dup.dptr = (char *) malloc( data.dsize ) )
188 memcpy( dup.dptr, data.dptr, data.dsize );
194 ldbm_fetch( LDBM ldbm, Datum key )
201 #ifdef HAVE_BERKELEY_DB2
202 ldbm_datum_init( data );
204 data.flags = DB_DBT_MALLOC;
206 if ( (rc = (*ldbm->get)( ldbm, NULL, &key, &data, 0 )) != 0 ) {
207 if ( data.dptr ) free( data.dptr );
209 if ( (rc = (*ldbm->get)( ldbm, &key, &data, 0 )) == 0 ) {
210 data = ldbm_datum_dup( ldbm, data );
223 ldbm_store( LDBM ldbm, Datum key, Datum data, int flags )
229 #ifdef HAVE_BERKELEY_DB2
230 rc = (*ldbm->put)( ldbm, NULL, &key, &data, flags & ~LDBM_SYNC );
233 rc = (*ldbm->put)( ldbm, &key, &data, flags & ~LDBM_SYNC );
236 if ( flags & LDBM_SYNC )
237 (*ldbm->sync)( ldbm, 0 );
245 ldbm_delete( LDBM ldbm, Datum key )
251 #ifdef HAVE_BERKELEY_DB2
252 rc = (*ldbm->del)( ldbm, NULL, &key, 0 );
255 rc = (*ldbm->del)( ldbm, &key, 0 );
257 (*ldbm->sync)( ldbm, 0 );
265 #ifdef HAVE_BERKELEY_DB2
266 ldbm_firstkey( LDBM ldbm, DBC **dbch )
268 ldbm_firstkey( LDBM ldbm )
274 #ifdef HAVE_BERKELEY_DB2
277 ldbm_datum_init( key );
278 ldbm_datum_init( data );
280 key.flags = data.flags = DB_DBT_MALLOC;
284 /* acquire a cursor for the DB */
286 # if defined( DB_VERSION_MAJOR ) && defined( DB_VERSION_MINOR ) && \
287 DB_VERSION_MAJOR == 2 && DB_VERSION_MINOR < 6
289 if ( (*ldbm->cursor)( ldbm, NULL, &dbci )) {
293 if ( (*ldbm->cursor)( ldbm, NULL, &dbci, 0 )) {
300 if ( (*dbci->c_get)( dbci, &key, &data, DB_NEXT ) == 0 ) {
301 if ( data.dptr ) free( data.dptr );
306 if ( (rc = (*ldbm->seq)( ldbm, &key, &data, R_FIRST )) == 0 ) {
307 key = ldbm_datum_dup( ldbm, key );
314 #ifdef HAVE_BERKELEY_DB2
324 #ifdef HAVE_BERKELEY_DB2
325 ldbm_nextkey( LDBM ldbm, Datum key, DBC *dbcp )
327 ldbm_nextkey( LDBM ldbm, Datum key )
333 #ifdef HAVE_BERKELEY_DB2
334 void *oldKey = key.dptr;
336 ldbm_datum_init( data );
338 data.flags = DB_DBT_MALLOC;
342 if ( (*dbcp->c_get)( dbcp, &key, &data, DB_NEXT ) == 0 ) {
343 if ( data.dptr ) free( data.dptr );
348 if ( (rc = (*ldbm->seq)( ldbm, &key, &data, R_NEXT )) == 0 ) {
349 key = ldbm_datum_dup( ldbm, key );
358 #ifdef HAVE_BERKELEY_DB2
359 if ( oldKey ) free( oldKey );
366 ldbm_errno( LDBM ldbm )
371 #elif defined( HAVE_GDBM )
373 #include <sys/stat.h>
375 /* GDBM is non-reentrant */
376 static pthread_mutex_t ldbm_big_mutex;
377 #define LDBM_LOCK (pthread_mutex_lock(&ldbm_big_mutex))
378 #define LDBM_UNLOCK (pthread_mutex_unlock(&ldbm_big_mutex))
380 void ldbm_initialize( void )
382 static int initialized = 0;
384 if(initialized++) return;
386 pthread_mutex_init( &ldbm_big_mutex, pthread_mutexattr_default );
389 /*****************************************************************
393 *****************************************************************/
396 ldbm_open( char *name, int rw, int mode, int dbcachesize )
403 if ( (db = gdbm_open( name, 0, rw | GDBM_FAST, mode, 0 )) == NULL ) {
407 if ( dbcachesize > 0 && stat( name, &st ) == 0 ) {
408 dbcachesize = (dbcachesize / st.st_blksize);
409 gdbm_setopt( db, GDBM_CACHESIZE, &dbcachesize, sizeof(int) );
417 ldbm_close( LDBM ldbm )
425 ldbm_sync( LDBM ldbm )
433 ldbm_datum_free( LDBM ldbm, Datum data )
439 ldbm_datum_dup( LDBM ldbm, Datum data )
443 if ( data.dsize == 0 ) {
449 dup.dsize = data.dsize;
450 if ( (dup.dptr = (char *) malloc( data.dsize )) != NULL )
451 memcpy( dup.dptr, data.dptr, data.dsize );
457 ldbm_fetch( LDBM ldbm, Datum key )
461 d = gdbm_fetch( ldbm, key );
467 ldbm_store( LDBM ldbm, Datum key, Datum data, int flags )
472 rc = gdbm_store( ldbm, key, data, flags & ~LDBM_SYNC );
473 if ( flags & LDBM_SYNC )
480 ldbm_delete( LDBM ldbm, Datum key )
485 rc = gdbm_delete( ldbm, key );
492 ldbm_firstkey( LDBM ldbm )
496 d = gdbm_firstkey( ldbm );
502 ldbm_nextkey( LDBM ldbm, Datum key )
506 d = gdbm_nextkey( ldbm, key );
512 ldbm_errno( LDBM ldbm )
521 #elif defined( HAVE_NDBM )
523 /* GDBM is non-reentrant */
524 static pthread_mutex_t ldbm_big_mutex;
525 #define LDBM_LOCK (pthread_mutex_lock(&ldbm_big_mutex))
526 #define LDBM_UNLOCK (pthread_mutex_unlock(&ldbm_big_mutex))
528 void ldbm_initialize( void )
530 static int initialized = 0;
532 if(initialized++) return;
534 pthread_mutex_init( &ldbm_big_mutex, pthread_mutexattr_default );
537 /*****************************************************************
539 * if no gdbm, fall back to using ndbm, the standard unix thing *
541 *****************************************************************/
545 ldbm_open( char *name, int rw, int mode, int dbcachesize )
550 ldbm = dbm_open( name, rw, mode );
557 ldbm_close( LDBM ldbm )
566 ldbm_sync( LDBM ldbm )
572 ldbm_datum_free( LDBM ldbm, Datum data )
578 ldbm_datum_dup( LDBM ldbm, Datum data )
582 if ( data.dsize == 0 ) {
588 dup.dsize = data.dsize;
589 dup.dptr = (char *) malloc( data.dsize );
591 memcpy( dup.dptr, data.dptr, data.dsize );
597 ldbm_fetch( LDBM ldbm, Datum key )
601 d = ldbm_datum_dup( ldbm, dbm_fetch( ldbm, key ) );
607 ldbm_store( LDBM ldbm, Datum key, Datum data, int flags )
611 rc = dbm_store( ldbm, key, data, flags );
617 ldbm_delete( LDBM ldbm, Datum key )
621 rc = dbm_delete( ldbm, key );
627 ldbm_firstkey( LDBM ldbm )
631 d = dbm_firstkey( ldbm );
637 ldbm_nextkey( LDBM ldbm, Datum key )
641 d = dbm_nextkey( ldbm );
647 ldbm_errno( LDBM ldbm )
651 err = dbm_error( ldbm );