]> git.sur5r.net Git - openldap/blob - libraries/libldbm/ldbm.c
72a212f8ca044c5b610197647da59b1382218437
[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  *   - basic implementation; 1998/02/23, /KSp
6  *   - DB_DBT_MALLOC       ; 1998/03/22, /KSp
7  */
8
9 #include "portable.h"
10
11 #ifdef SLAPD_LDBM
12
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <ac/string.h>
16 #include <ac/errno.h>
17
18 #include "ldbm.h"
19
20 #if defined( LDBM_USE_DBHASH ) || defined( LDBM_USE_DBBTREE )
21
22 /*****************************************************************
23  *                                                               *
24  * use berkeley db hash or btree package                         *
25  *                                                               *
26  *****************************************************************/
27
28 #ifdef HAVE_BERKELEY_DB2
29 /*************************************************
30  *                                               *
31  *  A malloc routine for use with DB_DBT_MALLOC  *
32  *                                               *
33  *************************************************/
34
35 void *
36 ldbm_malloc( size_t size )
37 {
38         return( calloc( 1, size ));
39 }
40
41 #endif
42
43
44 LDBM
45 ldbm_open( char *name, int rw, int mode, int dbcachesize )
46 {
47         LDBM            ret = NULL;
48
49 #ifdef HAVE_BERKELEY_DB2
50         DB_INFO         dbinfo;
51
52         memset( &dbinfo, 0, sizeof( dbinfo ));
53         dbinfo.db_cachesize = dbcachesize;
54         dbinfo.db_pagesize  = DEFAULT_DB_PAGE_SIZE;
55         dbinfo.db_malloc    = ldbm_malloc;
56
57     (void) db_open( name, DB_TYPE, rw, mode, NULL, &dbinfo, &ret );
58
59 #else
60         void            *info;
61         BTREEINFO       binfo;
62         HASHINFO        hinfo;
63
64         if ( DB_TYPE == DB_HASH ) {
65                 memset( (char *) &hinfo, '\0', sizeof(hinfo) );
66                 hinfo.cachesize = dbcachesize;
67                 info = &hinfo;
68         } else if ( DB_TYPE == DB_BTREE ) {
69                 memset( (char *) &binfo, '\0', sizeof(binfo) );
70                 binfo.cachesize = dbcachesize;
71                 info = &binfo;
72         } else {
73                 info = NULL;
74         }
75
76         ret = dbopen( name, rw, mode, DB_TYPE, info );
77
78 #endif
79
80         return( ret );
81 }
82
83 void
84 ldbm_close( LDBM ldbm )
85 {
86 #ifdef HAVE_BERKELEY_DB2
87         (*ldbm->close)( ldbm, 0 );
88 #else
89         (*ldbm->close)( ldbm );
90 #endif
91 }
92
93 void
94 ldbm_sync( LDBM ldbm )
95 {
96         (*ldbm->sync)( ldbm, 0 );
97 }
98
99 void
100 ldbm_datum_free( LDBM ldbm, Datum data )
101 {
102         free( data.dptr );
103 }
104
105 Datum
106 ldbm_datum_dup( LDBM ldbm, Datum data )
107 {
108         Datum   dup;
109
110         ldbm_datum_init( dup );
111
112         if ( data.dsize == 0 ) {
113                 return( dup );
114         }
115         dup.dsize = data.dsize;
116         if ( dup.dptr = (char *) malloc( data.dsize ) )
117                 memcpy( dup.dptr, data.dptr, data.dsize );
118
119         return( dup );
120 }
121
122 Datum
123 ldbm_fetch( LDBM ldbm, Datum key )
124 {
125         Datum   data;
126         int     rc;
127
128 #ifdef HAVE_BERKELEY_DB2
129         ldbm_datum_init( data );
130
131         data.flags = DB_DBT_MALLOC;
132
133         if ( (rc = (*ldbm->get)( ldbm, NULL, &key, &data, 0 )) != 0 ) {
134                 if ( data.dptr ) free( data.dptr );
135 #else
136         if ( (rc = (*ldbm->get)( ldbm, &key, &data, 0 )) == 0 ) {
137                 data = ldbm_datum_dup( ldbm, data );
138         } else {
139 #endif
140                 data.dptr = NULL;
141                 data.dsize = 0;
142         }
143
144         return( data );
145 }
146
147 int
148 ldbm_store( LDBM ldbm, Datum key, Datum data, int flags )
149 {
150         int     rc;
151
152 #ifdef HAVE_BERKELEY_DB2
153         rc = (*ldbm->put)( ldbm, NULL, &key, &data, flags & ~LDBM_SYNC );
154         rc = (-1 ) * rc;
155 #else
156         rc = (*ldbm->put)( ldbm, &key, &data, flags & ~LDBM_SYNC );
157 #endif
158
159         if ( flags & LDBM_SYNC )
160                 (*ldbm->sync)( ldbm, 0 );
161         return( rc );
162 }
163
164 int
165 ldbm_delete( LDBM ldbm, Datum key )
166 {
167         int     rc;
168
169 #ifdef HAVE_BERKELEY_DB2
170         rc = (*ldbm->del)( ldbm, NULL, &key, 0 );
171         rc = (-1 ) * rc;
172 #else
173         rc = (*ldbm->del)( ldbm, &key, 0 );
174 #endif
175         (*ldbm->sync)( ldbm, 0 );
176         return( rc );
177 }
178
179 Datum
180 #ifdef HAVE_BERKELEY_DB2
181 ldbm_firstkey( LDBM ldbm, DBC **dbch )
182 #else
183 ldbm_firstkey( LDBM ldbm )
184 #endif
185 {
186         Datum   key, data;
187         int     rc;
188
189 #ifdef HAVE_BERKELEY_DB2
190         DBC  *dbci;
191
192         ldbm_datum_init( key );
193         ldbm_datum_init( data );
194
195         key.flags = data.flags = DB_DBT_MALLOC;
196
197         /* acquire a cursor for the DB */
198
199 #  if defined( DB_VERSION_MAJOR ) && defined( DB_VERSION_MINOR ) && \
200     DB_VERSION_MAJOR == 2 && DB_VERSION_MINOR < 6
201
202         if ( (*ldbm->cursor)( ldbm, NULL, &dbci )) {
203
204 #  else
205
206         if ( (*ldbm->cursor)( ldbm, NULL, &dbci, 0 )) {
207
208 #  endif
209
210                 return( key );
211         } else {
212                 *dbch = dbci;
213                 if ( (*dbci->c_get)( dbci, &key, &data, DB_NEXT ) == 0 ) {
214                         if ( data.dptr ) free( data.dptr );
215 #else
216         if ( (rc = (*ldbm->seq)( ldbm, &key, &data, R_FIRST )) == 0 ) {
217                 key = ldbm_datum_dup( ldbm, key );
218 #endif
219         } else {
220                 key.dptr = NULL;
221                 key.dsize = 0;
222         }
223
224 #ifdef HAVE_BERKELEY_DB2
225         }
226 #endif
227
228         return( key );
229 }
230
231 Datum
232 #ifdef HAVE_BERKELEY_DB2
233 ldbm_nextkey( LDBM ldbm, Datum key, DBC *dbcp )
234 #else
235 ldbm_nextkey( LDBM ldbm, Datum key )
236 #endif
237 {
238         Datum   data;
239         int     rc;
240
241 #ifdef HAVE_BERKELEY_DB2
242         void *oldKey = key.dptr;
243
244         ldbm_datum_init( data );
245
246         data.flags = DB_DBT_MALLOC;
247
248         if ( (*dbcp->c_get)( dbcp, &key, &data, DB_NEXT ) == 0 ) {
249                 if ( data.dptr ) free( data.dptr );
250 #else
251         if ( (rc = (*ldbm->seq)( ldbm, &key, &data, R_NEXT )) == 0 ) {
252                 key = ldbm_datum_dup( ldbm, key );
253 #endif
254         } else {
255                 key.dptr = NULL;
256                 key.dsize = 0;
257         }
258 #ifdef HAVE_BERKELEY_DB2
259         if ( oldKey ) free( oldKey );
260 #endif
261
262         return( key );
263 }
264
265 int
266 ldbm_errno( LDBM ldbm )
267 {
268         return( errno );
269 }
270
271 #elif defined( HAVE_GDBM )
272
273 #include <sys/stat.h>
274
275 /*****************************************************************
276  *                                                               *
277  * use gdbm                                                      *
278  *                                                               *
279  *****************************************************************/
280
281 LDBM
282 ldbm_open( char *name, int rw, int mode, int dbcachesize )
283 {
284         LDBM            db;
285         struct stat     st;
286
287         if ( (db =  gdbm_open( name, 0, rw | GDBM_FAST, mode, 0 )) == NULL ) {
288                 return( NULL );
289         }
290         if ( dbcachesize > 0 && stat( name, &st ) == 0 ) {
291                 dbcachesize = (dbcachesize / st.st_blksize);
292                 gdbm_setopt( db, GDBM_CACHESIZE, &dbcachesize, sizeof(int) );
293         }
294
295         return( db );
296 }
297
298 void
299 ldbm_close( LDBM ldbm )
300 {
301         gdbm_close( ldbm );
302 }
303
304 void
305 ldbm_sync( LDBM ldbm )
306 {
307         gdbm_sync( ldbm );
308 }
309
310 void
311 ldbm_datum_free( LDBM ldbm, Datum data )
312 {
313         free( data.dptr );
314 }
315
316 Datum
317 ldbm_datum_dup( LDBM ldbm, Datum data )
318 {
319         Datum   dup;
320
321         if ( data.dsize == 0 ) {
322                 dup.dsize = 0;
323                 dup.dptr = NULL;
324
325                 return( dup );
326         }
327         dup.dsize = data.dsize;
328         if ( (dup.dptr = (char *) malloc( data.dsize )) != NULL )
329                 memcpy( dup.dptr, data.dptr, data.dsize );
330
331         return( dup );
332 }
333
334 Datum
335 ldbm_fetch( LDBM ldbm, Datum key )
336 {
337         return( gdbm_fetch( ldbm, key ) );
338 }
339
340 int
341 ldbm_store( LDBM ldbm, Datum key, Datum data, int flags )
342 {
343         int     rc;
344
345         rc = gdbm_store( ldbm, key, data, flags & ~LDBM_SYNC );
346         if ( flags & LDBM_SYNC )
347                 gdbm_sync( ldbm );
348         return( rc );
349 }
350
351 int
352 ldbm_delete( LDBM ldbm, Datum key )
353 {
354         int     rc;
355
356         rc = gdbm_delete( ldbm, key );
357         gdbm_sync( ldbm );
358         return( rc );
359 }
360
361 Datum
362 ldbm_firstkey( LDBM ldbm )
363 {
364         return( gdbm_firstkey( ldbm ) );
365 }
366
367 Datum
368 ldbm_nextkey( LDBM ldbm, Datum key )
369 {
370         return( gdbm_nextkey( ldbm, key ) );
371 }
372
373 int
374 ldbm_errno( LDBM ldbm )
375 {
376         return( (int) gdbm_errno );
377 }
378
379 #elif defined( HAVE_NDBM )
380
381 /*****************************************************************
382  *                                                               *
383  * if no gdbm, fall back to using ndbm, the standard unix thing  *
384  *                                                               *
385  *****************************************************************/
386
387 /* ARGSUSED */
388 LDBM
389 ldbm_open( char *name, int rw, int mode, int dbcachesize )
390 {
391         return( dbm_open( name, rw, mode ) );
392 }
393
394 void
395 ldbm_close( LDBM ldbm )
396 {
397         dbm_close( ldbm );
398 }
399
400 /* ARGSUSED */
401 void
402 ldbm_sync( LDBM ldbm )
403 {
404         return;
405 }
406
407 void
408 ldbm_datum_free( LDBM ldbm, Datum data )
409 {
410         return;
411 }
412
413 Datum
414 ldbm_datum_dup( LDBM ldbm, Datum data )
415 {
416         Datum   dup;
417
418         if ( data.dsize == 0 ) {
419                 dup.dsize = 0;
420                 dup.dptr = NULL;
421
422                 return( dup );
423         }
424         dup.dsize = data.dsize;
425         dup.dptr = (char *) malloc( data.dsize );
426         if ( dup.dptr )
427                 memcpy( dup.dptr, data.dptr, data.dsize );
428
429         return( dup );
430 }
431
432 Datum
433 ldbm_fetch( LDBM ldbm, Datum key )
434 {
435         return( ldbm_datum_dup( ldbm, dbm_fetch( ldbm, key ) ) );
436 }
437
438 int
439 ldbm_store( LDBM ldbm, Datum key, Datum data, int flags )
440 {
441         return( dbm_store( ldbm, key, data, flags ) );
442 }
443
444 int
445 ldbm_delete( LDBM ldbm, Datum key )
446 {
447         return( dbm_delete( ldbm, key ) );
448 }
449
450 Datum
451 ldbm_firstkey( LDBM ldbm )
452 {
453         return( dbm_firstkey( ldbm ) );
454 }
455
456 Datum
457 ldbm_nextkey( LDBM ldbm, Datum key )
458 {
459         return( dbm_nextkey( ldbm ) );
460 }
461
462 int
463 ldbm_errno( LDBM ldbm )
464 {
465         return( dbm_error( ldbm ) );
466 }
467
468 #endif /* ndbm */
469 #endif /* ldbm */