]> git.sur5r.net Git - openldap/blob - libraries/libldbm/ldbm.c
Merge in all -devel changes made since branch was created.
[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         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 #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 = (dbcachesize / st.st_blksize);
445                 gdbm_setopt( db, GDBM_CACHESIZE, &dbcachesize, sizeof(int) );
446         }
447 #else
448         dbcachesize = (dbcachesize / 4096);
449         gdbm_setopt( db, GDBM_CACHESIZE, &dbcachesize, sizeof(int) );
450 #endif
451
452         LDBM_UNLOCK;
453
454         return( db );
455 }
456
457 void
458 ldbm_close( LDBM ldbm )
459 {
460         LDBM_LOCK;
461         gdbm_close( ldbm );
462         LDBM_UNLOCK;
463 }
464
465 void
466 ldbm_sync( LDBM ldbm )
467 {
468         LDBM_LOCK;
469         gdbm_sync( ldbm );
470         LDBM_UNLOCK;
471 }
472
473 Datum
474 ldbm_fetch( LDBM ldbm, Datum key )
475 {
476         Datum d;
477
478         LDBM_LOCK;
479         d = gdbm_fetch( ldbm, key );
480         LDBM_UNLOCK;
481
482         return d;
483 }
484
485 int
486 ldbm_store( LDBM ldbm, Datum key, Datum data, int flags )
487 {
488         int     rc;
489
490         LDBM_LOCK;
491         rc = gdbm_store( ldbm, key, data, flags & ~LDBM_SYNC );
492         if ( flags & LDBM_SYNC )
493                 gdbm_sync( ldbm );
494         LDBM_UNLOCK;
495
496         return( rc );
497 }
498
499 int
500 ldbm_delete( LDBM ldbm, Datum key )
501 {
502         int     rc;
503
504         LDBM_LOCK;
505         rc = gdbm_delete( ldbm, key );
506         gdbm_sync( ldbm );
507         LDBM_UNLOCK;
508
509         return( rc );
510 }
511
512 Datum
513 ldbm_firstkey( LDBM ldbm, LDBMCursor **dbcp )
514 {
515         Datum d;
516
517         LDBM_LOCK;
518         d = gdbm_firstkey( ldbm );
519         LDBM_UNLOCK;
520
521         return d;
522 }
523
524 Datum
525 ldbm_nextkey( LDBM ldbm, Datum key, LDBMCursor *dbcp )
526 {
527         Datum d;
528
529         LDBM_LOCK;
530         d = gdbm_nextkey( ldbm, key );
531         LDBM_UNLOCK;
532
533         return d;
534 }
535
536 int
537 ldbm_errno( LDBM ldbm )
538 {
539         int err;
540
541         LDBM_LOCK;
542         err = gdbm_errno;
543         LDBM_UNLOCK;
544
545         return( err );
546 }
547
548 #elif HAVE_MDBM
549
550 /* MMAPED DBM HASHING DATABASE */
551
552 #include <ac/string.h>
553
554 /* #define MDBM_DEBUG */
555
556 #ifdef MDBM_DEBUG
557 #include <stdio.h>
558 #endif
559
560 #define NO_NULL_KEY
561 /* #define MDBM_CHAIN */
562
563 #ifdef MDBM_CHAIN
564
565 /* Use chaining */
566
567
568 #define mdbm_store      mdbm_chain_store
569 #define mdbm_fetch      mdbm_chain_fetch
570 #define mdbm_delete     mdbm_chain_delete
571 #define mdbm_first      mdbm_chain_first
572 #define mdbm_next       mdbm_chain_next
573
574 #endif
575
576 #define MDBM_PG_SZ      (4*1024)
577
578 /*****************************************************************
579  *                                                               *
580  * use mdbm                                                      *
581  *                                                               *
582  *****************************************************************/
583
584 LDBM
585 ldbm_open( char *name, int rw, int mode, int dbcachesize )
586 {
587         LDBM            db;
588
589 #ifdef MDBM_DEBUG
590         fprintf( stdout,
591                  "==>(mdbm)ldbm_open(name=%s,rw=%x,mode=%x,cachesize=%d)\n",
592                  name ? name : "NULL", rw, mode, dbcachesize );
593         fflush( stdout );
594 #endif
595
596         LDBM_LOCK;      /* We need locking here, this is the only non-thread
597                          * safe function we have.
598                          */
599
600         if ( (db =  mdbm_open( name, rw, mode, MDBM_PG_SZ )) == NULL ) {
601
602                 LDBM_UNLOCK;
603 #ifdef MDBM_DEBUG
604                 fprintf( stdout, "<==(mdbm)ldbm_open(db=NULL)\n" );
605                 fflush( stdout );
606 #endif
607                 return( NULL );
608
609         }
610
611 #ifdef MDBM_CHAIN
612         (void)mdbm_set_chain(db);
613 #endif
614
615         LDBM_UNLOCK;
616
617 #ifdef MDBM_DEBUG
618         fprintf( stdout, "<==(mdbm)ldbm_open(db=%p)\n", db );
619         fflush( stdout );
620 #endif
621
622         return( db );
623
624 }
625
626
627
628
629 void
630 ldbm_close( LDBM ldbm )
631 {
632
633         /* Open and close are not reentrant so we need to use locks here */
634
635 #ifdef MDBM_DEBUG
636         fprintf( stdout,
637                  "==>(mdbm)ldbm_close(db=%p)\n", ldbm );
638         fflush( stdout );
639 #endif
640
641         LDBM_LOCK;
642         mdbm_close( ldbm );
643         LDBM_UNLOCK;
644
645 #ifdef MDBM_DEBUG
646         fprintf( stdout, "<==(mdbm)ldbm_close()\n" );
647         fflush( stdout );
648 #endif
649
650 }
651
652
653
654
655 void
656 ldbm_sync( LDBM ldbm )
657 {
658
659         /* XXX: Not sure if this is re-entrant need to check code, if so
660          * you can leave LOCKS out.
661          */
662
663         LDBM_LOCK;
664         mdbm_sync( ldbm );
665         LDBM_UNLOCK;
666
667 }
668
669
670 #define MAX_MDBM_RETRY  5
671
672 Datum
673 ldbm_fetch( LDBM ldbm, Datum key )
674 {
675         Datum   d;
676         kvpair  k;
677         int     retry = 0;
678
679         /* This hack is needed because MDBM does not take keys
680          * which begin with NULL when working in the chaining
681          * mode.
682          */
683
684         /* LDBM_LOCK; */
685
686 #ifdef NO_NULL_KEY
687         k.key.dsize = key.dsize + 1;                    
688         k.key.dptr = malloc(k.key.dsize);
689         *(k.key.dptr) = 'l';
690         memcpy( (void *)(k.key.dptr + 1), key.dptr, key.dsize );        
691 #else
692         k.key = key;
693 #endif  
694
695         k.val.dptr = NULL;
696         k.val.dsize = 0;
697
698         do {
699
700                 d = mdbm_fetch( ldbm, k );
701
702                 if ( d.dsize > 0 ) {
703
704                         if ( k.val.dptr != NULL ) {
705                             
706                             free( k.val.dptr );
707
708                         }
709
710                         if ( (k.val.dptr = malloc( d.dsize )) != NULL ) {
711                 
712                                 k.val.dsize = d.dsize;
713                                 d = mdbm_fetch( ldbm, k );
714
715                         } else { 
716
717                                 d.dsize = 0;
718                                 break;
719                         
720                         }
721
722                 }/* if ( d.dsize > 0 ) */
723
724         } while ((d.dsize > k.val.dsize) && (++retry < MAX_MDBM_RETRY));
725
726         /* LDBM_UNLOCK; */
727
728 #ifdef NO_NULL_KEY
729         free(k.key.dptr);
730 #endif
731
732         return d;
733
734 }
735
736
737
738
739 int
740 ldbm_store( LDBM ldbm, Datum key, Datum data, int flags )
741 {
742         int     rc;
743         Datum   int_key;        /* Internal key */
744
745 #ifdef MDBM_DEBUG
746         fprintf( stdout,
747                  "==>(mdbm)ldbm_store(db=%p, key(dptr=%p,sz=%d), data(dptr=%p,sz=%d), flags=%x)\n",
748                  ldbm, key.dptr, key.dsize, data.dptr, data.dsize, flags );
749         fflush( stdout );
750 #endif
751
752         /* LDBM_LOCK; */
753
754 #ifdef NO_NULL_KEY
755         int_key.dsize = key.dsize + 1;
756         int_key.dptr = malloc( int_key.dsize );
757         *(int_key.dptr) = 'l';  /* Must not be NULL !*/
758         memcpy( (void *)(int_key.dptr + 1), key.dptr, key.dsize );
759 #else
760         int_key = key;
761 #endif
762
763         rc = mdbm_store( ldbm, int_key, data, flags );
764         if ( flags & LDBM_SYNC ) {
765                 mdbm_sync( ldbm );
766         }
767
768         /* LDBM_UNLOCK; */
769
770 #ifdef MDBM_DEBUG
771         fprintf( stdout, "<==(mdbm)ldbm_store(rc=%d)\n", rc );
772         fflush( stdout );
773 #endif
774
775 #ifdef NO_NULL_KEY
776         free(int_key.dptr);
777 #endif
778
779         return( rc );
780
781 }
782
783
784
785 int
786 ldbm_delete( LDBM ldbm, Datum key )
787 {
788         int     rc;
789         Datum   int_key;
790
791         /* LDBM_LOCK; */
792
793 #ifdef NO_NULL_KEY
794         int_key.dsize = key.dsize + 1;
795         int_key.dptr = malloc(int_key.dsize);
796         *(int_key.dptr) = 'l';
797         memcpy( (void *)(int_key.dptr + 1), key.dptr, key.dsize );      
798 #else
799         int_key = key;
800 #endif
801         
802         rc = mdbm_delete( ldbm, int_key );
803
804         /* LDBM_UNLOCK; */
805 #ifdef NO_NULL_KEY
806         free(int_key.dptr);
807 #endif
808
809         return( rc );
810
811 }
812
813
814
815
816 static Datum
817 ldbm_get_next( LDBM ldbm, kvpair (*fptr)(MDBM *, kvpair) ) 
818 {
819
820         kvpair  out;
821         kvpair  in;
822         Datum   ret;
823         size_t  sz = MDBM_PAGE_SIZE(ldbm);
824 #ifdef NO_NULL_KEY
825         int     delta = 1;
826 #else
827         int     delta = 0;
828 #endif
829
830         /* LDBM_LOCK; */
831
832         in.key.dsize = sz;      /* Assume first key in one pg */
833         in.key.dptr = malloc(sz);
834         
835         in.val.dptr = NULL;     /* Don't need data just key */ 
836         in.val.dsize = 0;
837
838         ret.dptr = NULL;
839         ret.dsize = NULL;
840
841         out = fptr( ldbm, in );
842
843         if (out.key.dsize > 0) {
844
845             ret.dsize = out.key.dsize - delta;
846             if ((ret.dptr = (char *)malloc(ret.dsize)) == NULL) { 
847
848                 ret.dsize = 0;
849                 ret.dptr = NULL;
850
851             } else {
852
853                 memcpy(ret.dptr, (void *)(out.key.dptr + delta),
854                        ret.dsize );
855
856             }
857
858         }
859
860         /* LDBM_UNLOCK; */
861         
862         free(in.key.dptr);
863
864         return ret;
865
866 }
867
868
869
870
871 Datum
872 ldbm_firstkey( LDBM ldbm, LDBMCursor **dbcp )
873 {
874
875         return ldbm_get_next( ldbm, mdbm_first );
876
877 }
878
879
880
881
882 Datum
883 ldbm_nextkey( LDBM ldbm, Datum key, LDBMCursor *dbcp )
884 {
885
886         /* XXX:
887          * don't know if this will affect the LDAP server opertaion 
888          * but mdbm cannot take and input key.
889          */
890
891         return ldbm_get_next( ldbm, mdbm_next );
892
893 }
894
895 int
896 ldbm_errno( LDBM ldbm )
897 {
898         /* XXX: best we can do with current  mdbm interface */
899         return( errno );
900
901 }
902
903
904
905
906 #elif defined( HAVE_NDBM )
907
908 /*****************************************************************
909  *                                                               *
910  * if no gdbm or mdbm, fall back to using ndbm, the standard unix thing  *
911  *                                                               *
912  *****************************************************************/
913
914 /* ARGSUSED */
915 LDBM
916 ldbm_open( char *name, int rw, int mode, int dbcachesize )
917 {
918         LDBM ldbm;
919
920         LDBM_LOCK;
921         ldbm = dbm_open( name, rw, mode );
922         LDBM_UNLOCK;
923
924         return( ldbm );
925 }
926
927 void
928 ldbm_close( LDBM ldbm )
929 {
930         LDBM_LOCK;
931         dbm_close( ldbm );
932         LDBM_UNLOCK;
933 }
934
935 /* ARGSUSED */
936 void
937 ldbm_sync( LDBM ldbm )
938 {
939         return;
940 }
941
942 Datum
943 ldbm_fetch( LDBM ldbm, Datum key )
944 {
945         Datum d;
946
947         LDBM_LOCK;
948         d = ldbm_datum_dup( ldbm, dbm_fetch( ldbm, key ) );
949         LDBM_UNLOCK;
950
951         return d;
952 }
953
954 int
955 ldbm_store( LDBM ldbm, Datum key, Datum data, int flags )
956 {
957         int rc;
958
959         LDBM_LOCK;
960         rc = dbm_store( ldbm, key, data, flags );
961         LDBM_UNLOCK;
962
963         return rc;
964 }
965
966 int
967 ldbm_delete( LDBM ldbm, Datum key )
968 {
969         int rc;
970
971         LDBM_LOCK;
972         rc = dbm_delete( ldbm, key );
973         LDBM_UNLOCK;
974
975         return rc;
976 }
977
978 Datum
979 ldbm_firstkey( LDBM ldbm, LDBMCursor **dbcp )
980 {
981         Datum d;
982
983         LDBM_LOCK;
984         d = dbm_firstkey( ldbm );
985         LDBM_UNLOCK;
986
987         return d;
988 }
989
990 Datum
991 ldbm_nextkey( LDBM ldbm, Datum key, LDBMCursor *dbcp )
992 {
993         Datum d;
994
995         LDBM_LOCK;
996         d = dbm_nextkey( ldbm );
997         LDBM_UNLOCK;
998
999         return d;
1000 }
1001
1002 int
1003 ldbm_errno( LDBM ldbm )
1004 {
1005         int err;
1006
1007         LDBM_LOCK;
1008         err = dbm_error( ldbm );
1009         LDBM_UNLOCK;
1010
1011         return err;
1012 }
1013
1014 #endif /* ndbm */
1015 #endif /* ldbm */