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