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