]> git.sur5r.net Git - openldap/blob - servers/slapd/back-ldbm/dn2id.c
separate ID return value form return status in dn2id (back-ldbm/dn2id.c)
[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 ID
117 dn2id(
118     Backend     *be,
119     const char  *dn,
120     int         *rc
121 )
122 {
123         struct ldbminfo *li = (struct ldbminfo *) be->be_private;
124         DBCache *db;
125         ID              id;
126         Datum           key, data;
127
128         *rc = 0;
129         
130 #ifdef NEW_LOGGING
131         LDAP_LOG(( "backend", LDAP_LEVEL_ENTRY,
132                    "dn2id: (%s)\n", dn ));
133 #else
134         Debug( LDAP_DEBUG_TRACE, "=> dn2id( \"%s\" )\n", dn, 0, 0 );
135 #endif
136
137
138         /* first check the cache */
139         if ( (id = cache_find_entry_dn2id( be, &li->li_cache, dn )) != NOID ) {
140 #ifdef NEW_LOGGING
141                 LDAP_LOG(( "backend", LDAP_LEVEL_DETAIL1,
142                            "dn2id: (%s)%ld in cache.\n", dn, id ));
143 #else
144                 Debug( LDAP_DEBUG_TRACE, "<= dn2id %ld (in cache)\n", id,
145                         0, 0 );
146 #endif
147
148                 return( id );
149         }
150
151         if ( (db = ldbm_cache_open( be, "dn2id", LDBM_SUFFIX, LDBM_WRCREAT ))
152                 == NULL ) {
153 #ifdef NEW_LOGGING
154                 LDAP_LOG(( "backend", LDAP_LEVEL_ERR,
155                            "dn2id: couldn't open dn2id%s\n", LDBM_SUFFIX ));
156 #else
157                 Debug( LDAP_DEBUG_ANY, "<= dn2id could not open dn2id%s\n",
158                         LDBM_SUFFIX, 0, 0 );
159 #endif
160                 /*
161                  * return code !0 if ldbm cache open failed;
162                  * callers should handle this
163                  */
164                 *rc = -1;
165                 return( NOID );
166         }
167
168         ldbm_datum_init( key );
169
170         key.dsize = strlen( dn ) + 2;
171         key.dptr = ch_malloc( key.dsize );
172         sprintf( key.dptr, "%c%s", DN_BASE_PREFIX, dn );
173
174         data = ldbm_cache_fetch( db, key );
175
176         ldbm_cache_close( be, db );
177
178         free( key.dptr );
179
180         if ( data.dptr == NULL ) {
181 #ifdef NEW_LOGGING
182                 LDAP_LOG(( "backend", LDAP_LEVEL_INFO,
183                            "dn2id: (%s) NOID\n", dn ));
184 #else
185                 Debug( LDAP_DEBUG_TRACE, "<= dn2id NOID\n", 0, 0, 0 );
186 #endif
187
188                 return( NOID );
189         }
190
191         AC_MEMCPY( (char *) &id, data.dptr, sizeof(ID) );
192
193         assert( id != NOID );
194
195         ldbm_datum_free( db->dbc_db, data );
196
197 #ifdef NEW_LOGGING
198         LDAP_LOG(( "backend", LDAP_LEVEL_ENTRY,
199                    "dn2id: %ld\n", id ));
200 #else
201         Debug( LDAP_DEBUG_TRACE, "<= dn2id %ld\n", id, 0, 0 );
202 #endif
203
204         return( id );
205 }
206
207 ID_BLOCK *
208 dn2idl(
209     Backend     *be,
210     const char  *dn,
211         int             prefix
212 )
213 {
214         DBCache *db;
215         Datum           key;
216         ID_BLOCK        *idl;
217
218 #ifdef NEW_LOGGING
219         LDAP_LOG(( "backend", LDAP_LEVEL_ENTRY,
220                    "dn2idl: \"%c%s\"\n", prefix, dn ));
221 #else
222         Debug( LDAP_DEBUG_TRACE, "=> dn2idl( \"%c%s\" )\n", prefix, dn, 0 );
223 #endif
224
225
226         if ( (db = ldbm_cache_open( be, "dn2id", LDBM_SUFFIX, LDBM_WRCREAT ))
227                 == NULL ) {
228 #ifdef NEW_LOGGING
229                 LDAP_LOG(( "backend", LDAP_LEVEL_ERR,
230                            "dn2idl: could not open dn2id%s\n", LDBM_SUFFIX ));
231 #else
232                 Debug( LDAP_DEBUG_ANY, "<= dn2idl could not open dn2id%s\n",
233                         LDBM_SUFFIX, 0, 0 );
234 #endif
235
236                 return NULL;
237         }
238
239         ldbm_datum_init( key );
240
241         key.dsize = strlen( dn ) + 2;
242         key.dptr = ch_malloc( key.dsize );
243         sprintf( key.dptr, "%c%s", prefix, dn );
244
245         idl = idl_fetch( be, db, key );
246
247         ldbm_cache_close( be, db );
248
249         free( key.dptr );
250
251         return( idl );
252 }
253
254
255 int
256 dn2id_delete(
257     Backend     *be,
258     const char  *dn,
259         ID id
260 )
261 {
262         DBCache *db;
263         Datum           key;
264         int             rc;
265
266 #ifdef NEW_LOGGING
267         LDAP_LOG(( "backend", LDAP_LEVEL_ENTRY,
268                    "dn2id_delete: (%s)%ld\n", dn, id ));
269 #else
270         Debug( LDAP_DEBUG_TRACE, "=> dn2id_delete( \"%s\", %ld )\n", dn, id, 0 );
271 #endif
272
273
274         assert( id != NOID );
275
276         if ( (db = ldbm_cache_open( be, "dn2id", LDBM_SUFFIX, LDBM_WRCREAT ))
277             == NULL ) {
278 #ifdef NEW_LOGGING
279                 LDAP_LOG(( "backend", LDAP_LEVEL_ERR,
280                            "dn2id_delete: couldn't open db2id%s\n", LDBM_SUFFIX ));
281 #else
282                 Debug( LDAP_DEBUG_ANY,
283                     "<= dn2id_delete could not open dn2id%s\n", LDBM_SUFFIX,
284                     0, 0 );
285 #endif
286
287                 return( -1 );
288         }
289
290
291         {
292                 char *pdn = dn_parent( NULL, dn );
293
294                 if( pdn != NULL ) {
295                         ldbm_datum_init( key );
296                         key.dsize = strlen( pdn ) + 2;
297                         key.dptr = ch_malloc( key.dsize );
298                         sprintf( key.dptr, "%c%s", DN_ONE_PREFIX, pdn );
299
300                         (void) idl_delete_key( be, db, key, id );
301
302                         free( key.dptr );
303                         free( pdn );
304                 }
305         }
306
307         {
308                 char **subtree = dn_subtree( NULL, dn );
309
310                 if( subtree != NULL ) {
311                         int i;
312                         for( i=0; subtree[i] != NULL; i++ ) {
313                                 ldbm_datum_init( key );
314                                 key.dsize = strlen( subtree[i] ) + 2;
315                                 key.dptr = ch_malloc( key.dsize );
316                                 sprintf( key.dptr, "%c%s",
317                                         DN_SUBTREE_PREFIX, subtree[i] );
318
319                                 (void) idl_delete_key( be, db, key, id );
320
321                                 free( key.dptr );
322                         }
323
324                         charray_free( subtree );
325                 }
326         }
327
328         ldbm_datum_init( key );
329
330         key.dsize = strlen( dn ) + 2;
331         key.dptr = ch_malloc( key.dsize );
332         sprintf( key.dptr, "%c%s", DN_BASE_PREFIX, dn );
333
334         rc = ldbm_cache_delete( db, key );
335
336         free( key.dptr );
337
338         ldbm_cache_close( be, db );
339
340 #ifdef NEW_LOGGING
341         LDAP_LOG(( "backend", LDAP_LEVEL_ENTRY,
342                    "dn2id_delete: return %d\n", rc ));
343 #else
344         Debug( LDAP_DEBUG_TRACE, "<= dn2id_delete %d\n", rc, 0, 0 );
345 #endif
346
347         return( rc );
348 }
349
350 /*
351  * dn2entry - look up dn in the cache/indexes and return the corresponding
352  * entry.
353  */
354
355 Entry *
356 dn2entry_rw(
357     Backend     *be,
358     const char  *dn,
359     Entry       **matched,
360     int         rw
361 )
362 {
363         ID              id;
364         Entry           *e = NULL;
365         char            *pdn;
366         int             rc_id = 0;
367
368 #ifdef NEW_LOGGING
369         LDAP_LOG(( "backend", LDAP_LEVEL_ENTRY,
370                    "dn2entry_rw: %s entry %s\n", rw ? "w" : "r",
371                    dn ));
372 #else
373         Debug(LDAP_DEBUG_TRACE, "dn2entry_%s: dn: \"%s\"\n",
374                 rw ? "w" : "r", dn, 0);
375 #endif
376
377
378         if( matched != NULL ) {
379                 /* caller cares about match */
380                 *matched = NULL;
381         }
382
383         if ( (id = dn2id( be, dn, &rc_id )) != NOID &&
384                 (e = id2entry_rw( be, id, rw )) != NULL )
385         {
386                 return( e );
387         }
388
389         if ( id != NOID ) {
390 #ifdef NEW_LOGGING
391                 LDAP_LOG(( "backend", LDAP_LEVEL_ERR,
392                            "dn2entry_rw: no entry for valid id (%ld), dn (%s)\n",
393                            id, dn ));
394 #else
395                 Debug(LDAP_DEBUG_ANY,
396                         "dn2entry_%s: no entry for valid id (%ld), dn \"%s\"\n",
397                         rw ? "w" : "r", id, dn);
398 #endif
399
400                 /* must have been deleted from underneath us */
401                 /* treat as if NOID was found */
402         } else if ( rc_id ) {
403                 /* something bad happened to ldbm cache */
404                 return NULL;
405         }
406
407         /* caller doesn't care about match */
408         if( matched == NULL ) return NULL;
409
410         /* entry does not exist - see how much of the dn does exist */
411         /* dn_parent checks returns NULL if dn is suffix */
412         if ( (pdn = dn_parent( be, dn )) != NULL ) {
413                 /* get entry with reader lock */
414                 if ( (e = dn2entry_r( be, pdn, matched )) != NULL ) {
415                         *matched = e;
416                 }
417                 free( pdn );
418         }
419
420         return NULL;
421 }
422