]> git.sur5r.net Git - openldap/blob - libraries/libldbm/ldbm.c
s/int/u_int32_t/ for db_appinit flags
[openldap] / libraries / libldbm / ldbm.c
1 /* ldbm.c - ldap dbm compatibility routines */
2 /*
3  * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
4  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
5  */
6
7 /* Patched for Berkeley DB version 2.0; /KSp; 98/02/23
8  *
9  *   - DB version 2.6.4b   ; 1998/12/28, /KSp
10  *   - DB_DBT_MALLOC       ; 1998/03/22, /KSp
11  *   - basic implementation; 1998/02/23, /KSp
12  */
13
14 #include "portable.h"
15
16 #ifdef SLAPD_LDBM
17
18 #include <stdio.h>
19
20 #include <ac/stdlib.h>
21 #include <ac/string.h>
22 #include <ac/errno.h>
23
24 #include "ldbm.h"
25 #include "ldap_pvt_thread.h"
26
27
28 void
29 ldbm_datum_free( LDBM ldbm, Datum data )
30 {
31         if ( data.dptr ) {
32                 free( data.dptr );
33                 memset( &data, 0, sizeof( Datum ));
34                 data.dptr = NULL;
35         }
36 }
37
38
39 Datum
40 ldbm_datum_dup( LDBM ldbm, Datum data )
41 {
42         Datum   dup;
43
44         ldbm_datum_init( dup );
45
46         if ( data.dsize == 0 ) {
47                 dup.dsize = 0;
48                 dup.dptr = NULL;
49
50                 return( dup );
51         }
52         dup.dsize = data.dsize;
53         if ( (dup.dptr = (char *) malloc( data.dsize )) != NULL )
54                 memcpy( dup.dptr, data.dptr, data.dsize );
55
56         return( dup );
57 }
58
59 static int ldbm_initialized = 0;
60
61 #ifndef HAVE_BERKELEY_DB2
62 /* Everything but DB2 is non-reentrant */
63
64 static ldap_pvt_thread_mutex_t ldbm_big_mutex;
65 #define LDBM_LOCK       (ldap_pvt_thread_mutex_lock(&ldbm_big_mutex))
66 #define LDBM_UNLOCK     (ldap_pvt_thread_mutex_unlock(&ldbm_big_mutex))
67
68 int ldbm_initialize( void )
69 {
70         if(ldbm_initialized++) return 1;
71
72         ldap_pvt_thread_mutex_init( &ldbm_big_mutex );
73
74         return 0;
75 }
76
77 int ldbm_shutdown( void )
78 {
79         if( !ldbm_initialized ) return 1;
80
81         ldap_pvt_thread_mutex_destroy( &ldbm_big_mutex );
82
83         return 0;
84 }
85
86 #else
87
88 void *
89 ldbm_malloc( size_t size )
90 {
91         return( calloc( 1, size ));
92 }
93
94 #ifdef LDAP_SYSLOG
95 #include <ac/syslog.h>
96 #endif
97
98 static void
99 ldbm_db_errcall( const char *prefix, char *message )
100 {
101 #ifdef LDAP_SYSLOG
102         syslog( LOG_INFO, "ldbm_db_errcall(): %s %s", prefix, message );
103 #endif
104 }
105
106 /*  a dbEnv for BERKELEYv2  */
107 static DB_ENV    ldbm_Env_internal;
108 DB_ENV           *ldbm_Env = NULL;
109
110 /* Berkeley DB 2.x is reentrant */
111 #define LDBM_LOCK       ((void)0)
112 #define LDBM_UNLOCK     ((void)0)
113
114 int ldbm_initialize( void )
115 {
116         int     err;
117         u_int32_t       envFlags;
118
119         if(ldbm_initialized++) return 1;
120
121         memset( &ldbm_Env_internal, 0, sizeof( DB_ENV ));
122         ldbm_Env = &ldbm_Env_internal;
123
124         ldbm_Env->db_errcall   = ldbm_db_errcall;
125         ldbm_Env->db_errpfx    = "==>";
126
127         envFlags = DB_CREATE | DB_THREAD;
128
129         if ( ( err = db_appinit( NULL, NULL, ldbm_Env, envFlags )) ) {
130                 char  error[BUFSIZ];
131
132                 if ( err < 0 ) {
133                         sprintf( error, "%ld\n", (long) err );
134                 } else {
135                         sprintf( error, "%s\n", strerror( err ));
136                 }
137
138 #ifdef LDAP_SYSLOG
139                 syslog( LOG_INFO,
140                         "ldbm_initialize(): FATAL error in db_appinit() : %s\n",
141                         error );
142 #endif
143                 return( 1 );
144         }
145
146         return 0;
147 }
148
149 int ldbm_shutdown( void )
150 {
151         if( !ldbm_initialized ) return 1;
152
153         db_appexit( ldbm_Env );
154
155         return 0;
156 }
157
158 #endif
159
160 #if defined( LDBM_USE_DBHASH ) || defined( LDBM_USE_DBBTREE )
161
162 /*****************************************************************
163  *                                                               *
164  * use berkeley db hash or btree package                         *
165  *                                                               *
166  *****************************************************************/
167
168 LDBM
169 ldbm_open( char *name, int rw, int mode, int dbcachesize )
170 {
171         LDBM            ret = NULL;
172
173 #ifdef HAVE_BERKELEY_DB2
174         DB_INFO dbinfo;
175
176         memset( &dbinfo, 0, sizeof( dbinfo ));
177
178 #if defined( DB_VERSION_MAJOR ) && defined( DB_VERSION_MINOR ) && \
179     DB_VERSION_MAJOR == 2 && DB_VERSION_MINOR == 4
180         /*
181          * BerkeleyDB 2.4 do not allow db_cachesize
182          * to be specified if an DB_ENV is.
183          */
184 #else
185         /* set db_cachesize of MPOOL is NOT being used. */
186         if (( ldbm_Env == NULL ) || ( ldbm_Env->mp_info == NULL ))
187                 dbinfo.db_cachesize = dbcachesize;
188 #endif
189
190         dbinfo.db_pagesize  = DEFAULT_DB_PAGE_SIZE;
191         dbinfo.db_malloc    = ldbm_malloc;
192
193         LDBM_LOCK;
194     (void) db_open( name, DB_TYPE, rw, mode, ldbm_Env, &dbinfo, &ret );
195         LDBM_UNLOCK;
196
197 #else
198         void            *info;
199         BTREEINFO       binfo;
200         HASHINFO        hinfo;
201
202         if ( DB_TYPE == DB_HASH ) {
203                 memset( (char *) &hinfo, '\0', sizeof(hinfo) );
204                 hinfo.cachesize = dbcachesize;
205                 info = &hinfo;
206         } else if ( DB_TYPE == DB_BTREE ) {
207                 memset( (char *) &binfo, '\0', sizeof(binfo) );
208                 binfo.cachesize = dbcachesize;
209                 info = &binfo;
210         } else {
211                 info = NULL;
212         }
213
214         LDBM_LOCK;
215         ret = dbopen( name, rw, mode, DB_TYPE, info );
216         LDBM_UNLOCK;
217
218 #endif
219
220         return( ret );
221 }
222
223 void
224 ldbm_close( LDBM ldbm )
225 {
226         LDBM_LOCK;
227 #ifdef HAVE_BERKELEY_DB2
228         (*ldbm->close)( ldbm, 0 );
229 #else
230         (*ldbm->close)( ldbm );
231 #endif
232         LDBM_UNLOCK;
233 }
234
235 void
236 ldbm_sync( LDBM ldbm )
237 {
238         LDBM_LOCK;
239         (*ldbm->sync)( ldbm, 0 );
240         LDBM_UNLOCK;
241 }
242
243 Datum
244 ldbm_fetch( LDBM ldbm, Datum key )
245 {
246         Datum   data;
247         int     rc;
248
249         LDBM_LOCK;
250
251 #ifdef HAVE_BERKELEY_DB2
252         ldbm_datum_init( data );
253
254         data.flags = DB_DBT_MALLOC;
255
256         if ( (rc = (*ldbm->get)( ldbm, NULL, &key, &data, 0 )) != 0 ) {
257                 ldbm_datum_free( ldbm, data );
258 #else
259         if ( (rc = (*ldbm->get)( ldbm, &key, &data, 0 )) == 0 ) {
260                 /* Berkeley DB 1.85 don't malloc the data for us */
261                 /* duplicate it for to ensure reentrancy */
262                 data = ldbm_datum_dup( ldbm, data );
263         } else {
264 #endif
265                 data.dptr = NULL;
266                 data.dsize = 0;
267         }
268
269         LDBM_UNLOCK;
270
271         return( data );
272 }
273
274 int
275 ldbm_store( LDBM ldbm, Datum key, Datum data, int flags )
276 {
277         int     rc;
278
279         LDBM_LOCK;
280
281 #ifdef HAVE_BERKELEY_DB2
282         rc = (*ldbm->put)( ldbm, NULL, &key, &data, flags & ~LDBM_SYNC );
283         rc = (-1 ) * rc;
284 #else
285         rc = (*ldbm->put)( ldbm, &key, &data, flags & ~LDBM_SYNC );
286 #endif
287
288         if ( flags & LDBM_SYNC )
289                 (*ldbm->sync)( ldbm, 0 );
290
291         LDBM_UNLOCK;
292
293         return( rc );
294 }
295
296 int
297 ldbm_delete( LDBM ldbm, Datum key )
298 {
299         int     rc;
300
301         LDBM_LOCK;
302
303 #ifdef HAVE_BERKELEY_DB2
304         rc = (*ldbm->del)( ldbm, NULL, &key, 0 );
305         rc = (-1 ) * rc;
306 #else
307         rc = (*ldbm->del)( ldbm, &key, 0 );
308 #endif
309         (*ldbm->sync)( ldbm, 0 );
310
311         LDBM_UNLOCK;
312
313         return( rc );
314 }
315
316 Datum
317 ldbm_firstkey( LDBM ldbm, LDBMCursor **dbch )
318 {
319         Datum   key, data;
320
321 #ifdef HAVE_BERKELEY_DB2
322         LDBMCursor  *dbci;
323
324         ldbm_datum_init( key );
325         ldbm_datum_init( data );
326
327         key.flags = data.flags = DB_DBT_MALLOC;
328
329         LDBM_LOCK;
330
331         /* acquire a cursor for the DB */
332
333 #  if defined( DB_VERSION_MAJOR ) && defined( DB_VERSION_MINOR ) && \
334     DB_VERSION_MAJOR == 2 && DB_VERSION_MINOR < 6
335
336         if ( (*ldbm->cursor)( ldbm, NULL, &dbci )) 
337
338 #  else
339         if ( (*ldbm->cursor)( ldbm, NULL, &dbci, 0 ))
340 #  endif
341         {
342                 key.dptr = NULL;
343                 return( key );
344         } else {
345                 *dbch = dbci;
346                 if ( (*dbci->c_get)( dbci, &key, &data, DB_NEXT ) == 0 ) {
347                         ldbm_datum_free( ldbm, data );
348                 }
349         else {
350 #else
351         int     rc;
352
353         LDBM_LOCK;
354
355         if ( (rc = (*ldbm->seq)( ldbm, &key, &data, R_FIRST )) == 0 ) {
356                 key = ldbm_datum_dup( ldbm, key );
357         }
358         else {
359 #endif
360                 key.dptr = NULL;
361                 key.dsize = 0;
362         }
363
364 #ifdef HAVE_BERKELEY_DB2
365         }
366 #endif
367
368         LDBM_UNLOCK;
369
370         return( key );
371 }
372
373 Datum
374 ldbm_nextkey( LDBM ldbm, Datum key, LDBMCursor *dbcp )
375 {
376         Datum   data;
377
378 #ifdef HAVE_BERKELEY_DB2
379         ldbm_datum_init( data );
380
381         ldbm_datum_free( ldbm, key );
382         key.flags = data.flags = DB_DBT_MALLOC;
383
384         LDBM_LOCK;
385
386         if ( (*dbcp->c_get)( dbcp, &key, &data, DB_NEXT ) == 0 ) {
387                 ldbm_datum_free( ldbm, data );
388         }
389         else {
390 #else
391         int     rc;
392
393         LDBM_LOCK;
394
395         if ( (rc = (*ldbm->seq)( ldbm, &key, &data, R_NEXT )) == 0 ) {
396                 key = ldbm_datum_dup( ldbm, key );
397         }
398         else {
399 #endif
400                 key.dptr = NULL;
401                 key.dsize = 0;
402         }
403
404         LDBM_UNLOCK;
405
406         return( key );
407 }
408
409 int
410 ldbm_errno( LDBM ldbm )
411 {
412         return( errno );
413 }
414
415 #elif defined( HAVE_GDBM )
416
417 #ifdef HAVE_ST_BLKSIZE
418 #include <sys/stat.h>
419 #endif
420
421 /*****************************************************************
422  *                                                               *
423  * use gdbm                                                      *
424  *                                                               *
425  *****************************************************************/
426
427 LDBM
428 ldbm_open( char *name, int rw, int mode, int dbcachesize )
429 {
430         LDBM            db;
431 #ifdef HAVE_ST_BLKSIZE
432                 struct stat     st;
433 #endif
434
435         LDBM_LOCK;
436
437         if ( (db =  gdbm_open( name, 0, rw | GDBM_FAST, mode, 0 )) == NULL ) {
438                 LDBM_UNLOCK;
439                 return( NULL );
440         }
441
442 #ifdef HAVE_ST_BLKSIZE
443         if ( dbcachesize > 0 && stat( name, &st ) == 0 ) {
444                 dbcachesize /= st.st_blksize;
445                 if( dbcachesize == 0 ) dbcachesize = 1;
446                 gdbm_setopt( db, GDBM_CACHESIZE, &dbcachesize, sizeof(int) );
447         }
448 #else
449         if ( dbcachesize > 0 ) {
450                 dbcachesize /= 4096;
451                 if( dbcachesize == 0 ) dbcachesize = 1;
452                 gdbm_setopt( db, GDBM_CACHESIZE, &dbcachesize, sizeof(int) );
453         }
454 #endif
455
456         LDBM_UNLOCK;
457
458         return( db );
459 }
460
461 void
462 ldbm_close( LDBM ldbm )
463 {
464         LDBM_LOCK;
465         gdbm_close( ldbm );
466         LDBM_UNLOCK;
467 }
468
469 void
470 ldbm_sync( LDBM ldbm )
471 {
472         LDBM_LOCK;
473         gdbm_sync( ldbm );
474         LDBM_UNLOCK;
475 }
476
477 Datum
478 ldbm_fetch( LDBM ldbm, Datum key )
479 {
480         Datum d;
481
482         LDBM_LOCK;
483         d = gdbm_fetch( ldbm, key );
484         LDBM_UNLOCK;
485
486         return d;
487 }
488
489 int
490 ldbm_store( LDBM ldbm, Datum key, Datum data, int flags )
491 {
492         int     rc;
493
494         LDBM_LOCK;
495         rc = gdbm_store( ldbm, key, data, flags & ~LDBM_SYNC );
496         if ( flags & LDBM_SYNC )
497                 gdbm_sync( ldbm );
498         LDBM_UNLOCK;
499
500         return( rc );
501 }
502
503 int
504 ldbm_delete( LDBM ldbm, Datum key )
505 {
506         int     rc;
507
508         LDBM_LOCK;
509         rc = gdbm_delete( ldbm, key );
510         gdbm_sync( ldbm );
511         LDBM_UNLOCK;
512
513         return( rc );
514 }
515
516 Datum
517 ldbm_firstkey( LDBM ldbm, LDBMCursor **dbcp )
518 {
519         Datum d;
520
521         LDBM_LOCK;
522         d = gdbm_firstkey( ldbm );
523         LDBM_UNLOCK;
524
525         return d;
526 }
527
528 Datum
529 ldbm_nextkey( LDBM ldbm, Datum key, LDBMCursor *dbcp )
530 {
531         Datum d;
532
533         LDBM_LOCK;
534         d = gdbm_nextkey( ldbm, key );
535         LDBM_UNLOCK;
536
537         return d;
538 }
539
540 int
541 ldbm_errno( LDBM ldbm )
542 {
543         int err;
544
545         LDBM_LOCK;
546         err = gdbm_errno;
547         LDBM_UNLOCK;
548
549         return( err );
550 }
551
552 #elif HAVE_MDBM
553
554 /* MMAPED DBM HASHING DATABASE */
555
556 #include <ac/string.h>
557
558 /* #define MDBM_DEBUG */
559
560 #ifdef MDBM_DEBUG
561 #include <stdio.h>
562 #endif
563
564 #define NO_NULL_KEY
565 /* #define MDBM_CHAIN */
566
567 #ifdef MDBM_CHAIN
568
569 /* Use chaining */
570
571
572 #define mdbm_store      mdbm_chain_store
573 #define mdbm_fetch      mdbm_chain_fetch
574 #define mdbm_delete     mdbm_chain_delete
575 #define mdbm_first      mdbm_chain_first
576 #define mdbm_next       mdbm_chain_next
577
578 #endif
579
580 #define MDBM_PG_SZ      (4*1024)
581
582 /*****************************************************************
583  *                                                               *
584  * use mdbm                                                      *
585  *                                                               *
586  *****************************************************************/
587
588 LDBM
589 ldbm_open( char *name, int rw, int mode, int dbcachesize )
590 {
591         LDBM            db;
592
593 #ifdef MDBM_DEBUG
594         fprintf( stdout,
595                  "==>(mdbm)ldbm_open(name=%s,rw=%x,mode=%x,cachesize=%d)\n",
596                  name ? name : "NULL", rw, mode, dbcachesize );
597         fflush( stdout );
598 #endif
599
600         LDBM_LOCK;      /* We need locking here, this is the only non-thread
601                          * safe function we have.
602                          */
603
604         if ( (db =  mdbm_open( name, rw, mode, MDBM_PG_SZ )) == NULL ) {
605
606                 LDBM_UNLOCK;
607 #ifdef MDBM_DEBUG
608                 fprintf( stdout, "<==(mdbm)ldbm_open(db=NULL)\n" );
609                 fflush( stdout );
610 #endif
611                 return( NULL );
612
613         }
614
615 #ifdef MDBM_CHAIN
616         (void)mdbm_set_chain(db);
617 #endif
618
619         LDBM_UNLOCK;
620
621 #ifdef MDBM_DEBUG
622         fprintf( stdout, "<==(mdbm)ldbm_open(db=%p)\n", db );
623         fflush( stdout );
624 #endif
625
626         return( db );
627
628 }
629
630
631
632
633 void
634 ldbm_close( LDBM ldbm )
635 {
636
637         /* Open and close are not reentrant so we need to use locks here */
638
639 #ifdef MDBM_DEBUG
640         fprintf( stdout,
641                  "==>(mdbm)ldbm_close(db=%p)\n", ldbm );
642         fflush( stdout );
643 #endif
644
645         LDBM_LOCK;
646         mdbm_close( ldbm );
647         LDBM_UNLOCK;
648
649 #ifdef MDBM_DEBUG
650         fprintf( stdout, "<==(mdbm)ldbm_close()\n" );
651         fflush( stdout );
652 #endif
653
654 }
655
656
657
658
659 void
660 ldbm_sync( LDBM ldbm )
661 {
662
663         /* XXX: Not sure if this is re-entrant need to check code, if so
664          * you can leave LOCKS out.
665          */
666
667         LDBM_LOCK;
668         mdbm_sync( ldbm );
669         LDBM_UNLOCK;
670
671 }
672
673
674 #define MAX_MDBM_RETRY  5
675
676 Datum
677 ldbm_fetch( LDBM ldbm, Datum key )
678 {
679         Datum   d;
680         kvpair  k;
681         int     retry = 0;
682
683         /* This hack is needed because MDBM does not take keys
684          * which begin with NULL when working in the chaining
685          * mode.
686          */
687
688         /* LDBM_LOCK; */
689
690 #ifdef NO_NULL_KEY
691         k.key.dsize = key.dsize + 1;                    
692         k.key.dptr = malloc(k.key.dsize);
693         *(k.key.dptr) = 'l';
694         memcpy( (void *)(k.key.dptr + 1), key.dptr, key.dsize );        
695 #else
696         k.key = key;
697 #endif  
698
699         k.val.dptr = NULL;
700         k.val.dsize = 0;
701
702         do {
703
704                 d = mdbm_fetch( ldbm, k );
705
706                 if ( d.dsize > 0 ) {
707
708                         if ( k.val.dptr != NULL ) {
709                             
710                             free( k.val.dptr );
711
712                         }
713
714                         if ( (k.val.dptr = malloc( d.dsize )) != NULL ) {
715                 
716                                 k.val.dsize = d.dsize;
717                                 d = mdbm_fetch( ldbm, k );
718
719                         } else { 
720
721                                 d.dsize = 0;
722                                 break;
723                         
724                         }
725
726                 }/* if ( d.dsize > 0 ) */
727
728         } while ((d.dsize > k.val.dsize) && (++retry < MAX_MDBM_RETRY));
729
730         /* LDBM_UNLOCK; */
731
732 #ifdef NO_NULL_KEY
733         free(k.key.dptr);
734 #endif
735
736         return d;
737
738 }
739
740
741
742
743 int
744 ldbm_store( LDBM ldbm, Datum key, Datum data, int flags )
745 {
746         int     rc;
747         Datum   int_key;        /* Internal key */
748
749 #ifdef MDBM_DEBUG
750         fprintf( stdout,
751                  "==>(mdbm)ldbm_store(db=%p, key(dptr=%p,sz=%d), data(dptr=%p,sz=%d), flags=%x)\n",
752                  ldbm, key.dptr, key.dsize, data.dptr, data.dsize, flags );
753         fflush( stdout );
754 #endif
755
756         /* LDBM_LOCK; */
757
758 #ifdef NO_NULL_KEY
759         int_key.dsize = key.dsize + 1;
760         int_key.dptr = malloc( int_key.dsize );
761         *(int_key.dptr) = 'l';  /* Must not be NULL !*/
762         memcpy( (void *)(int_key.dptr + 1), key.dptr, key.dsize );
763 #else
764         int_key = key;
765 #endif
766
767         rc = mdbm_store( ldbm, int_key, data, flags );
768         if ( flags & LDBM_SYNC ) {
769                 mdbm_sync( ldbm );
770         }
771
772         /* LDBM_UNLOCK; */
773
774 #ifdef MDBM_DEBUG
775         fprintf( stdout, "<==(mdbm)ldbm_store(rc=%d)\n", rc );
776         fflush( stdout );
777 #endif
778
779 #ifdef NO_NULL_KEY
780         free(int_key.dptr);
781 #endif
782
783         return( rc );
784
785 }
786
787
788
789 int
790 ldbm_delete( LDBM ldbm, Datum key )
791 {
792         int     rc;
793         Datum   int_key;
794
795         /* LDBM_LOCK; */
796
797 #ifdef NO_NULL_KEY
798         int_key.dsize = key.dsize + 1;
799         int_key.dptr = malloc(int_key.dsize);
800         *(int_key.dptr) = 'l';
801         memcpy( (void *)(int_key.dptr + 1), key.dptr, key.dsize );      
802 #else
803         int_key = key;
804 #endif
805         
806         rc = mdbm_delete( ldbm, int_key );
807
808         /* LDBM_UNLOCK; */
809 #ifdef NO_NULL_KEY
810         free(int_key.dptr);
811 #endif
812
813         return( rc );
814
815 }
816
817
818
819
820 static Datum
821 ldbm_get_next( LDBM ldbm, kvpair (*fptr)(MDBM *, kvpair) ) 
822 {
823
824         kvpair  out;
825         kvpair  in;
826         Datum   ret;
827         size_t  sz = MDBM_PAGE_SIZE(ldbm);
828 #ifdef NO_NULL_KEY
829         int     delta = 1;
830 #else
831         int     delta = 0;
832 #endif
833
834         /* LDBM_LOCK; */
835
836         in.key.dsize = sz;      /* Assume first key in one pg */
837         in.key.dptr = malloc(sz);
838         
839         in.val.dptr = NULL;     /* Don't need data just key */ 
840         in.val.dsize = 0;
841
842         ret.dptr = NULL;
843         ret.dsize = NULL;
844
845         out = fptr( ldbm, in );
846
847         if (out.key.dsize > 0) {
848
849             ret.dsize = out.key.dsize - delta;
850             if ((ret.dptr = (char *)malloc(ret.dsize)) == NULL) { 
851
852                 ret.dsize = 0;
853                 ret.dptr = NULL;
854
855             } else {
856
857                 memcpy(ret.dptr, (void *)(out.key.dptr + delta),
858                        ret.dsize );
859
860             }
861
862         }
863
864         /* LDBM_UNLOCK; */
865         
866         free(in.key.dptr);
867
868         return ret;
869
870 }
871
872
873
874
875 Datum
876 ldbm_firstkey( LDBM ldbm, LDBMCursor **dbcp )
877 {
878
879         return ldbm_get_next( ldbm, mdbm_first );
880
881 }
882
883
884
885
886 Datum
887 ldbm_nextkey( LDBM ldbm, Datum key, LDBMCursor *dbcp )
888 {
889
890         /* XXX:
891          * don't know if this will affect the LDAP server opertaion 
892          * but mdbm cannot take and input key.
893          */
894
895         return ldbm_get_next( ldbm, mdbm_next );
896
897 }
898
899 int
900 ldbm_errno( LDBM ldbm )
901 {
902         /* XXX: best we can do with current  mdbm interface */
903         return( errno );
904
905 }
906
907
908
909
910 #elif defined( HAVE_NDBM )
911
912 /*****************************************************************
913  *                                                               *
914  * if no gdbm or mdbm, fall back to using ndbm, the standard unix thing  *
915  *                                                               *
916  *****************************************************************/
917
918 /* ARGSUSED */
919 LDBM
920 ldbm_open( char *name, int rw, int mode, int dbcachesize )
921 {
922         LDBM ldbm;
923
924         LDBM_LOCK;
925         ldbm = dbm_open( name, rw, mode );
926         LDBM_UNLOCK;
927
928         return( ldbm );
929 }
930
931 void
932 ldbm_close( LDBM ldbm )
933 {
934         LDBM_LOCK;
935         dbm_close( ldbm );
936         LDBM_UNLOCK;
937 }
938
939 /* ARGSUSED */
940 void
941 ldbm_sync( LDBM ldbm )
942 {
943         return;
944 }
945
946 Datum
947 ldbm_fetch( LDBM ldbm, Datum key )
948 {
949         Datum d;
950
951         LDBM_LOCK;
952         d = ldbm_datum_dup( ldbm, dbm_fetch( ldbm, key ) );
953         LDBM_UNLOCK;
954
955         return d;
956 }
957
958 int
959 ldbm_store( LDBM ldbm, Datum key, Datum data, int flags )
960 {
961         int rc;
962
963         LDBM_LOCK;
964         rc = dbm_store( ldbm, key, data, flags );
965         LDBM_UNLOCK;
966
967         return rc;
968 }
969
970 int
971 ldbm_delete( LDBM ldbm, Datum key )
972 {
973         int rc;
974
975         LDBM_LOCK;
976         rc = dbm_delete( ldbm, key );
977         LDBM_UNLOCK;
978
979         return rc;
980 }
981
982 Datum
983 ldbm_firstkey( LDBM ldbm, LDBMCursor **dbcp )
984 {
985         Datum d;
986
987         LDBM_LOCK;
988         d = dbm_firstkey( ldbm );
989         LDBM_UNLOCK;
990
991         return d;
992 }
993
994 Datum
995 ldbm_nextkey( LDBM ldbm, Datum key, LDBMCursor *dbcp )
996 {
997         Datum d;
998
999         LDBM_LOCK;
1000         d = dbm_nextkey( ldbm );
1001         LDBM_UNLOCK;
1002
1003         return d;
1004 }
1005
1006 int
1007 ldbm_errno( LDBM ldbm )
1008 {
1009         int err;
1010
1011         LDBM_LOCK;
1012         err = dbm_error( ldbm );
1013         LDBM_UNLOCK;
1014
1015         return err;
1016 }
1017
1018 #endif /* ndbm */
1019 #endif /* ldbm */