]> git.sur5r.net Git - openldap/blob - servers/slapd/back-ldbm/dn2id.c
39ba6d4ee08e61bae91d9485c684a0bf784054e8
[openldap] / servers / slapd / back-ldbm / dn2id.c
1 /* dn2id.c - routines to deal with the dn2id index */
2 /*
3  * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
4  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
5  */
6
7 #include "portable.h"
8
9 #include <stdio.h>
10
11 #include <ac/string.h>
12 #include <ac/socket.h>
13
14 #include "slap.h"
15 #include "back-ldbm.h"
16 #include "proto-back-ldbm.h"
17
18 int
19 dn2id_add(
20     Backend     *be,
21     const char  *dn,
22     ID          id
23 )
24 {
25         int             rc, flags;
26         DBCache *db;
27         Datum           key, data;
28         struct ldbminfo *li = (struct ldbminfo *) be->be_private;
29
30         Debug( LDAP_DEBUG_TRACE, "=> dn2id_add( \"%s\", %ld )\n", dn, id, 0 );
31         assert( id != NOID );
32
33         if ( (db = ldbm_cache_open( be, "dn2id", LDBM_SUFFIX, LDBM_WRCREAT ))
34             == NULL ) {
35                 Debug( LDAP_DEBUG_ANY, "Could not open/create dn2id%s\n",
36                     LDBM_SUFFIX, 0, 0 );
37                 return( -1 );
38         }
39
40         ldbm_datum_init( key );
41         key.dsize = strlen( dn ) + 2;
42         key.dptr = ch_malloc( key.dsize );
43         sprintf( key.dptr, "%c%s", DN_BASE_PREFIX, dn );
44
45         ldbm_datum_init( data );
46         data.dptr = (char *) &id;
47         data.dsize = sizeof(ID);
48
49         flags = LDBM_INSERT;
50         if ( li->li_dbcachewsync ) flags |= LDBM_SYNC;
51
52         rc = ldbm_cache_store( db, key, data, flags );
53
54         free( key.dptr );
55
56         if ( rc != -1 ) {
57                 char *pdn = dn_parent( NULL, dn );
58
59                 if( pdn != NULL ) {
60                         ldbm_datum_init( key );
61                         key.dsize = strlen( pdn ) + 2;
62                         key.dptr = ch_malloc( key.dsize );
63                         sprintf( key.dptr, "%c%s", DN_ONE_PREFIX, pdn );
64                         rc = idl_insert_key( be, db, key, id );
65                         free( key.dptr );
66                         free( pdn );
67                 }
68         }
69
70         if ( rc != -1 ) {
71                 char **subtree = dn_subtree( NULL, dn );
72
73                 if( subtree != NULL ) {
74                         int i;
75                         for( i=0; subtree[i] != NULL; i++ ) {
76                                 ldbm_datum_init( key );
77                                 key.dsize = strlen( subtree[i] ) + 2;
78                                 key.dptr = ch_malloc( key.dsize );
79                                 sprintf( key.dptr, "%c%s",
80                                         DN_SUBTREE_PREFIX, subtree[i] );
81
82                                 rc = idl_insert_key( be, db, key, id );
83
84                                 free( key.dptr );
85
86                                 if(rc == -1) break;
87                         }
88
89                         charray_free( subtree );
90                 }
91         }
92
93         ldbm_cache_close( be, db );
94
95         Debug( LDAP_DEBUG_TRACE, "<= dn2id_add %d\n", rc, 0, 0 );
96         return( rc );
97 }
98
99 ID
100 dn2id(
101     Backend     *be,
102     const char  *dn
103 )
104 {
105         struct ldbminfo *li = (struct ldbminfo *) be->be_private;
106         DBCache *db;
107         ID              id;
108         Datum           key, data;
109
110         Debug( LDAP_DEBUG_TRACE, "=> dn2id( \"%s\" )\n", dn, 0, 0 );
111
112         /* first check the cache */
113         if ( (id = cache_find_entry_dn2id( be, &li->li_cache, dn )) != NOID ) {
114                 Debug( LDAP_DEBUG_TRACE, "<= dn2id %ld (in cache)\n", id,
115                         0, 0 );
116                 return( id );
117         }
118
119         if ( (db = ldbm_cache_open( be, "dn2id", LDBM_SUFFIX, LDBM_WRCREAT ))
120                 == NULL ) {
121                 Debug( LDAP_DEBUG_ANY, "<= dn2id could not open dn2id%s\n",
122                         LDBM_SUFFIX, 0, 0 );
123                 return( NOID );
124         }
125
126         ldbm_datum_init( key );
127
128         key.dsize = strlen( dn ) + 2;
129         key.dptr = ch_malloc( key.dsize );
130         sprintf( key.dptr, "%c%s", DN_BASE_PREFIX, dn );
131
132         data = ldbm_cache_fetch( db, key );
133
134         ldbm_cache_close( be, db );
135
136         free( key.dptr );
137
138         if ( data.dptr == NULL ) {
139                 Debug( LDAP_DEBUG_TRACE, "<= dn2id NOID\n", 0, 0, 0 );
140                 return( NOID );
141         }
142
143         (void) memcpy( (char *) &id, data.dptr, sizeof(ID) );
144
145         assert( id != NOID );
146
147         ldbm_datum_free( db->dbc_db, data );
148
149         Debug( LDAP_DEBUG_TRACE, "<= dn2id %ld\n", id, 0, 0 );
150         return( id );
151 }
152
153 ID_BLOCK *
154 dn2idl(
155     Backend     *be,
156     const char  *dn,
157         int             prefix
158 )
159 {
160         DBCache *db;
161         Datum           key;
162         ID_BLOCK        *idl;
163
164         Debug( LDAP_DEBUG_TRACE, "=> dn2idl( \"%c%s\" )\n", prefix, dn, 0 );
165
166         if ( (db = ldbm_cache_open( be, "dn2id", LDBM_SUFFIX, LDBM_WRCREAT ))
167                 == NULL ) {
168                 Debug( LDAP_DEBUG_ANY, "<= dn2idl could not open dn2id%s\n",
169                         LDBM_SUFFIX, 0, 0 );
170                 return NULL;
171         }
172
173         ldbm_datum_init( key );
174
175         key.dsize = strlen( dn ) + 2;
176         key.dptr = ch_malloc( key.dsize );
177         sprintf( key.dptr, "%c%s", prefix, dn );
178
179         idl = idl_fetch( be, db, key );
180
181         ldbm_cache_close( be, db );
182
183         free( key.dptr );
184
185         return( idl );
186 }
187
188
189 int
190 dn2id_delete(
191     Backend     *be,
192     const char  *dn,
193         ID id
194 )
195 {
196         DBCache *db;
197         Datum           key;
198         int             rc;
199
200         Debug( LDAP_DEBUG_TRACE, "=> dn2id_delete( \"%s\", %ld )\n", dn, id, 0 );
201
202         assert( id != NOID );
203
204         if ( (db = ldbm_cache_open( be, "dn2id", LDBM_SUFFIX, LDBM_WRCREAT ))
205             == NULL ) {
206                 Debug( LDAP_DEBUG_ANY,
207                     "<= dn2id_delete could not open dn2id%s\n", LDBM_SUFFIX,
208                     0, 0 );
209                 return( -1 );
210         }
211
212
213         {
214                 char *pdn = dn_parent( NULL, dn );
215
216                 if( pdn != NULL ) {
217                         ldbm_datum_init( key );
218                         key.dsize = strlen( pdn ) + 2;
219                         key.dptr = ch_malloc( key.dsize );
220                         sprintf( key.dptr, "%c%s", DN_ONE_PREFIX, pdn );
221
222                         (void) idl_delete_key( be, db, key, id );
223
224                         free( key.dptr );
225                         free( pdn );
226                 }
227         }
228
229 #if 1
230         {
231                 char **subtree = dn_subtree( NULL, dn );
232
233                 if( subtree != NULL ) {
234                         int i;
235                         for( i=0; subtree[i] != NULL; i++ ) {
236                                 ldbm_datum_init( key );
237                                 key.dsize = strlen( subtree[i] ) + 2;
238                                 key.dptr = ch_malloc( key.dsize );
239                                 sprintf( key.dptr, "%c%s",
240                                         DN_SUBTREE_PREFIX, subtree[i] );
241
242                                 (void) idl_delete_key( be, db, key, id );
243
244                                 free( key.dptr );
245                         }
246
247                         charray_free( subtree );
248                 }
249         }
250 #endif
251
252         ldbm_datum_init( key );
253
254         key.dsize = strlen( dn ) + 2;
255         key.dptr = ch_malloc( key.dsize );
256         sprintf( key.dptr, "%c%s", DN_BASE_PREFIX, dn );
257
258         rc = ldbm_cache_delete( db, key );
259
260         free( key.dptr );
261
262         ldbm_cache_close( be, db );
263
264         Debug( LDAP_DEBUG_TRACE, "<= dn2id_delete %d\n", rc, 0, 0 );
265         return( rc );
266 }
267
268 /*
269  * dn2entry - look up dn in the cache/indexes and return the corresponding
270  * entry.
271  */
272
273 Entry *
274 dn2entry_rw(
275     Backend     *be,
276     const char  *dn,
277     Entry       **matched,
278     int         rw
279 )
280 {
281         ID              id;
282         Entry           *e = NULL;
283         char            *pdn;
284
285         Debug(LDAP_DEBUG_TRACE, "dn2entry_%s: dn: \"%s\"\n",
286                 rw ? "w" : "r", dn, 0);
287
288         if( matched != NULL ) {
289                 /* caller cares about match */
290                 *matched = NULL;
291         }
292
293         if ( (id = dn2id( be, dn )) != NOID &&
294                 (e = id2entry_rw( be, id, rw )) != NULL )
295         {
296                 return( e );
297         }
298
299         if ( id != NOID ) {
300                 Debug(LDAP_DEBUG_ANY,
301                         "dn2entry_%s: no entry for valid id (%ld), dn \"%s\"\n",
302                         rw ? "w" : "r", id, dn);
303                 /* must have been deleted from underneath us */
304                 /* treat as if NOID was found */
305         }
306
307         /* caller doesn't care about match */
308         if( matched == NULL ) return NULL;
309
310         /* entry does not exist - see how much of the dn does exist */
311         /* dn_parent checks returns NULL if dn is suffix */
312         if ( (pdn = dn_parent( be, dn )) != NULL ) {
313                 /* get entry with reader lock */
314                 if ( (e = dn2entry_r( be, pdn, matched )) != NULL ) {
315                         *matched = e;
316                 }
317                 free( pdn );
318         }
319
320         return NULL;
321 }
322