]> git.sur5r.net Git - openldap/blob - servers/slapd/back-ldbm/dn2id.c
Used API signature from back-bdb; compiles and passes make test
[openldap] / servers / slapd / back-ldbm / dn2id.c
1 /* dn2id.c - routines to deal with the dn2id index */
2 /* $OpenLDAP$ */
3 /*
4  * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
5  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
6  */
7
8 #include "portable.h"
9
10 #include <stdio.h>
11
12 #include <ac/string.h>
13 #include <ac/socket.h>
14
15 #include "slap.h"
16 #include "back-ldbm.h"
17 #include "proto-back-ldbm.h"
18
19 int
20 dn2id_add(
21     Backend     *be,
22     const char  *dn,
23     ID          id
24 )
25 {
26         int             rc, flags;
27         DBCache *db;
28         Datum           key, data;
29         struct ldbminfo *li = (struct ldbminfo *) be->be_private;
30
31 #ifdef NEW_LOGGING
32         LDAP_LOG(( "backend", LDAP_LEVEL_ENTRY,
33                    "dn2id_add: (%s):%ld\n", dn, id ));
34 #else
35         Debug( LDAP_DEBUG_TRACE, "=> dn2id_add( \"%s\", %ld )\n", dn, id, 0 );
36 #endif
37
38         assert( id != NOID );
39
40         if ( (db = ldbm_cache_open( be, "dn2id", LDBM_SUFFIX, LDBM_WRCREAT ))
41             == NULL ) {
42 #ifdef NEW_LOGGING
43                 LDAP_LOG(( "backend", LDAP_LEVEL_ERR,
44                            "dn2id_add: couldn't open/create dn2id%s\n", LDBM_SUFFIX ));
45 #else
46                 Debug( LDAP_DEBUG_ANY, "Could not open/create dn2id%s\n",
47                     LDBM_SUFFIX, 0, 0 );
48 #endif
49
50                 return( -1 );
51         }
52
53         ldbm_datum_init( key );
54         key.dsize = strlen( dn ) + 2;
55         key.dptr = ch_malloc( key.dsize );
56         sprintf( key.dptr, "%c%s", DN_BASE_PREFIX, dn );
57
58         ldbm_datum_init( data );
59         data.dptr = (char *) &id;
60         data.dsize = sizeof(ID);
61
62         flags = LDBM_INSERT;
63         rc = ldbm_cache_store( db, key, data, flags );
64
65         free( key.dptr );
66
67         if ( rc != -1 ) {
68                 char *pdn = dn_parent( NULL, dn );
69
70                 if( pdn != NULL ) {
71                         ldbm_datum_init( key );
72                         key.dsize = strlen( pdn ) + 2;
73                         key.dptr = ch_malloc( key.dsize );
74                         sprintf( key.dptr, "%c%s", DN_ONE_PREFIX, pdn );
75                         rc = idl_insert_key( be, db, key, id );
76                         free( key.dptr );
77                         free( pdn );
78                 }
79         }
80
81         if ( rc != -1 ) {
82                 char **subtree = dn_subtree( NULL, dn );
83
84                 if( subtree != NULL ) {
85                         int i;
86                         for( i=0; subtree[i] != NULL; i++ ) {
87                                 ldbm_datum_init( key );
88                                 key.dsize = strlen( subtree[i] ) + 2;
89                                 key.dptr = ch_malloc( key.dsize );
90                                 sprintf( key.dptr, "%c%s",
91                                         DN_SUBTREE_PREFIX, subtree[i] );
92
93                                 rc = idl_insert_key( be, db, key, id );
94
95                                 free( key.dptr );
96
97                                 if(rc == -1) break;
98                         }
99
100                         charray_free( subtree );
101                 }
102         }
103
104         ldbm_cache_close( be, db );
105
106 #ifdef NEW_LOGGING
107         LDAP_LOG(( "backend", LDAP_LEVEL_ENTRY,
108                    "dn2id_add: return %d\n", rc ));
109 #else
110         Debug( LDAP_DEBUG_TRACE, "<= dn2id_add %d\n", rc, 0, 0 );
111 #endif
112
113         return( rc );
114 }
115
116 int
117 dn2id(
118     Backend     *be,
119     const char  *dn,
120     ID          *idp
121 )
122 {
123         struct ldbminfo *li = (struct ldbminfo *) be->be_private;
124         DBCache *db;
125         Datum           key, data;
126
127 #ifdef NEW_LOGGING
128         LDAP_LOG(( "backend", LDAP_LEVEL_ENTRY,
129                    "dn2id: (%s)\n", dn ));
130 #else
131         Debug( LDAP_DEBUG_TRACE, "=> dn2id( \"%s\" )\n", dn, 0, 0 );
132 #endif
133
134         assert( idp );
135
136         /* first check the cache */
137         if ( (*idp = cache_find_entry_dn2id( be, &li->li_cache, dn )) != NOID ) {
138 #ifdef NEW_LOGGING
139                 LDAP_LOG(( "backend", LDAP_LEVEL_DETAIL1,
140                            "dn2id: (%s)%ld in cache.\n", dn, *idp ));
141 #else
142                 Debug( LDAP_DEBUG_TRACE, "<= dn2id %ld (in cache)\n", *idp,
143                         0, 0 );
144 #endif
145
146                 return( 0 );
147         }
148
149         if ( (db = ldbm_cache_open( be, "dn2id", LDBM_SUFFIX, LDBM_WRCREAT ))
150                 == NULL ) {
151 #ifdef NEW_LOGGING
152                 LDAP_LOG(( "backend", LDAP_LEVEL_ERR,
153                            "dn2id: couldn't open dn2id%s\n", LDBM_SUFFIX ));
154 #else
155                 Debug( LDAP_DEBUG_ANY, "<= dn2id could not open dn2id%s\n",
156                         LDBM_SUFFIX, 0, 0 );
157 #endif
158                 /*
159                  * return code !0 if ldbm cache open failed;
160                  * callers should handle this
161                  */
162                 *idp = NOID;
163                 return( -1 );
164         }
165
166         ldbm_datum_init( key );
167
168         key.dsize = strlen( dn ) + 2;
169         key.dptr = ch_malloc( key.dsize );
170         sprintf( key.dptr, "%c%s", DN_BASE_PREFIX, dn );
171
172         data = ldbm_cache_fetch( db, key );
173
174         ldbm_cache_close( be, db );
175
176         free( key.dptr );
177
178         if ( data.dptr == NULL ) {
179 #ifdef NEW_LOGGING
180                 LDAP_LOG(( "backend", LDAP_LEVEL_INFO,
181                            "dn2id: (%s) NOID\n", dn ));
182 #else
183                 Debug( LDAP_DEBUG_TRACE, "<= dn2id NOID\n", 0, 0, 0 );
184 #endif
185
186                 *idp = NOID;
187                 return( 0 );
188         }
189
190         AC_MEMCPY( (char *) idp, data.dptr, sizeof(ID) );
191
192         assert( *idp != NOID );
193
194         ldbm_datum_free( db->dbc_db, data );
195
196 #ifdef NEW_LOGGING
197         LDAP_LOG(( "backend", LDAP_LEVEL_ENTRY,
198                    "dn2id: %ld\n", *idp ));
199 #else
200         Debug( LDAP_DEBUG_TRACE, "<= dn2id %ld\n", *idp, 0, 0 );
201 #endif
202
203         return( 0 );
204 }
205
206 ID_BLOCK *
207 dn2idl(
208     Backend     *be,
209     const char  *dn,
210         int             prefix
211 )
212 {
213         DBCache *db;
214         Datum           key;
215         ID_BLOCK        *idl;
216
217 #ifdef NEW_LOGGING
218         LDAP_LOG(( "backend", LDAP_LEVEL_ENTRY,
219                    "dn2idl: \"%c%s\"\n", prefix, dn ));
220 #else
221         Debug( LDAP_DEBUG_TRACE, "=> dn2idl( \"%c%s\" )\n", prefix, dn, 0 );
222 #endif
223
224
225         if ( (db = ldbm_cache_open( be, "dn2id", LDBM_SUFFIX, LDBM_WRCREAT ))
226                 == NULL ) {
227 #ifdef NEW_LOGGING
228                 LDAP_LOG(( "backend", LDAP_LEVEL_ERR,
229                            "dn2idl: could not open dn2id%s\n", LDBM_SUFFIX ));
230 #else
231                 Debug( LDAP_DEBUG_ANY, "<= dn2idl could not open dn2id%s\n",
232                         LDBM_SUFFIX, 0, 0 );
233 #endif
234
235                 return NULL;
236         }
237
238         ldbm_datum_init( key );
239
240         key.dsize = strlen( dn ) + 2;
241         key.dptr = ch_malloc( key.dsize );
242         sprintf( key.dptr, "%c%s", prefix, dn );
243
244         idl = idl_fetch( be, db, key );
245
246         ldbm_cache_close( be, db );
247
248         free( key.dptr );
249
250         return( idl );
251 }
252
253
254 int
255 dn2id_delete(
256     Backend     *be,
257     const char  *dn,
258         ID id
259 )
260 {
261         DBCache *db;
262         Datum           key;
263         int             rc;
264
265 #ifdef NEW_LOGGING
266         LDAP_LOG(( "backend", LDAP_LEVEL_ENTRY,
267                    "dn2id_delete: (%s)%ld\n", dn, id ));
268 #else
269         Debug( LDAP_DEBUG_TRACE, "=> dn2id_delete( \"%s\", %ld )\n", dn, id, 0 );
270 #endif
271
272
273         assert( id != NOID );
274
275         if ( (db = ldbm_cache_open( be, "dn2id", LDBM_SUFFIX, LDBM_WRCREAT ))
276             == NULL ) {
277 #ifdef NEW_LOGGING
278                 LDAP_LOG(( "backend", LDAP_LEVEL_ERR,
279                            "dn2id_delete: couldn't open db2id%s\n", LDBM_SUFFIX ));
280 #else
281                 Debug( LDAP_DEBUG_ANY,
282                     "<= dn2id_delete could not open dn2id%s\n", LDBM_SUFFIX,
283                     0, 0 );
284 #endif
285
286                 return( -1 );
287         }
288
289
290         {
291                 char *pdn = dn_parent( NULL, dn );
292
293                 if( pdn != NULL ) {
294                         ldbm_datum_init( key );
295                         key.dsize = strlen( pdn ) + 2;
296                         key.dptr = ch_malloc( key.dsize );
297                         sprintf( key.dptr, "%c%s", DN_ONE_PREFIX, pdn );
298
299                         (void) idl_delete_key( be, db, key, id );
300
301                         free( key.dptr );
302                         free( pdn );
303                 }
304         }
305
306         {
307                 char **subtree = dn_subtree( NULL, dn );
308
309                 if( subtree != NULL ) {
310                         int i;
311                         for( i=0; subtree[i] != NULL; i++ ) {
312                                 ldbm_datum_init( key );
313                                 key.dsize = strlen( subtree[i] ) + 2;
314                                 key.dptr = ch_malloc( key.dsize );
315                                 sprintf( key.dptr, "%c%s",
316                                         DN_SUBTREE_PREFIX, subtree[i] );
317
318                                 (void) idl_delete_key( be, db, key, id );
319
320                                 free( key.dptr );
321                         }
322
323                         charray_free( subtree );
324                 }
325         }
326
327         ldbm_datum_init( key );
328
329         key.dsize = strlen( dn ) + 2;
330         key.dptr = ch_malloc( key.dsize );
331         sprintf( key.dptr, "%c%s", DN_BASE_PREFIX, dn );
332
333         rc = ldbm_cache_delete( db, key );
334
335         free( key.dptr );
336
337         ldbm_cache_close( be, db );
338
339 #ifdef NEW_LOGGING
340         LDAP_LOG(( "backend", LDAP_LEVEL_ENTRY,
341                    "dn2id_delete: return %d\n", rc ));
342 #else
343         Debug( LDAP_DEBUG_TRACE, "<= dn2id_delete %d\n", rc, 0, 0 );
344 #endif
345
346         return( rc );
347 }
348
349 /*
350  * dn2entry - look up dn in the cache/indexes and return the corresponding
351  * entry.
352  */
353
354 Entry *
355 dn2entry_rw(
356     Backend     *be,
357     const char  *dn,
358     Entry       **matched,
359     int         rw
360 )
361 {
362         ID              id;
363         Entry           *e = NULL;
364         char            *pdn;
365
366 #ifdef NEW_LOGGING
367         LDAP_LOG(( "backend", LDAP_LEVEL_ENTRY,
368                    "dn2entry_rw: %s entry %s\n", rw ? "w" : "r",
369                    dn ));
370 #else
371         Debug(LDAP_DEBUG_TRACE, "dn2entry_%s: dn: \"%s\"\n",
372                 rw ? "w" : "r", dn, 0);
373 #endif
374
375
376         if( matched != NULL ) {
377                 /* caller cares about match */
378                 *matched = NULL;
379         }
380
381         if ( dn2id( be, dn, &id ) ) {
382                 /* something bad happened to ldbm cache */
383                 return( NULL );
384
385         } else if ( id != NOID ) {
386                 /* try to return the entry */
387                 if ((e = id2entry_rw( be, id, rw )) != NULL ) {
388                         return( e );
389                 }
390
391 #ifdef NEW_LOGGING
392                 LDAP_LOG(( "backend", LDAP_LEVEL_ERR,
393                            "dn2entry_rw: no entry for valid id (%ld), dn (%s)\n",
394                            id, dn ));
395 #else
396                 Debug(LDAP_DEBUG_ANY,
397                         "dn2entry_%s: no entry for valid id (%ld), dn \"%s\"\n",
398                         rw ? "w" : "r", id, dn);
399 #endif
400
401                 /* must have been deleted from underneath us */
402                 /* treat as if NOID was found */
403         }
404
405         /* caller doesn't care about match */
406         if( matched == NULL ) return NULL;
407
408         /* entry does not exist - see how much of the dn does exist */
409         /* dn_parent checks returns NULL if dn is suffix */
410         if ( (pdn = dn_parent( be, dn )) != NULL ) {
411                 /* get entry with reader lock */
412                 if ( (e = dn2entry_r( be, pdn, matched )) != NULL ) {
413                         *matched = e;
414                 }
415                 free( pdn );
416         }
417
418         return NULL;
419 }
420