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