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