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