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