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