]> git.sur5r.net Git - openldap/blob - servers/slapd/back-bdb2/dn2id.c
43707b77d9f08ce8c0b3070869aaafb29f83122e
[openldap] / servers / slapd / back-bdb2 / dn2id.c
1 /* dn2id.c - routines to deal with the dn2id index */
2
3 #include "portable.h"
4
5 #include <stdio.h>
6
7 #include <ac/string.h>
8 #include <ac/socket.h>
9
10 #include "slap.h"
11 #include "back-bdb2.h"
12 #include "proto-back-bdb2.h"
13
14 int
15 bdb2i_dn2id_add(
16     BackendDB   *be,
17     char        *dn,
18     ID          id
19 )
20 {
21         int             rc, flags;
22         struct dbcache  *db;
23         Datum           key, data;
24         struct ldbminfo *li = (struct ldbminfo *) be->be_private;
25
26         Debug( LDAP_DEBUG_TRACE, "=> bdb2i_dn2id_add( \"%s\", %ld )\n", dn, id, 0 );
27
28         if ( (db = bdb2i_cache_open( be, "dn2id", BDB2_SUFFIX, LDBM_WRCREAT ))
29             == NULL ) {
30                 Debug( LDAP_DEBUG_ANY, "Could not open/create dn2id%s\n",
31                     BDB2_SUFFIX, 0, 0 );
32                 return( -1 );
33         }
34
35         ldbm_datum_init( key );
36         key.dsize = strlen( dn ) + 2;
37         key.dptr = ch_malloc( key.dsize );
38         sprintf( key.dptr, "%c%s", DN_BASE_PREFIX, dn );
39
40         ldbm_datum_init( data );
41         data.dptr = (char *) &id;
42         data.dsize = sizeof(ID);
43
44         flags = LDBM_INSERT;
45         if ( li->li_dbcachewsync ) flags |= LDBM_SYNC;
46
47         rc = bdb2i_cache_store( db, key, data, flags );
48
49         free( key.dptr );
50
51         if ( rc != -1 ) {
52                 char *pdn = dn_parent( NULL, dn );
53
54                 if( pdn != NULL ) {
55                         ldbm_datum_init( key );
56                         key.dsize = strlen( pdn ) + 2;
57                         key.dptr = ch_malloc( key.dsize );
58                         sprintf( key.dptr, "%c%s", DN_ONE_PREFIX, pdn );
59                         rc = bdb2i_idl_insert_key( be, db, key, id );
60                         free( key.dptr );
61                         free( pdn );
62                 }
63         }
64
65         if ( rc != -1 ) {
66                 char **subtree = dn_subtree( NULL, dn );
67
68                 if( subtree != NULL ) {
69                         int i;
70                         for( i=0; subtree[i] != NULL; i++ ) {
71                                 ldbm_datum_init( key );
72                                 key.dsize = strlen( subtree[i] ) + 2;
73                                 key.dptr = ch_malloc( key.dsize );
74                                 sprintf( key.dptr, "%c%s", DN_SUBTREE_PREFIX, subtree[i] );
75
76                                 rc = bdb2i_idl_insert_key( be, db, key, id );
77
78                                 free( key.dptr );
79                         }
80
81                         charray_free( subtree );
82                 }
83         }
84
85         bdb2i_cache_close( be, db );
86
87         Debug( LDAP_DEBUG_TRACE, "<= bdb2i_dn2id_add %d\n", rc, 0, 0 );
88         return( rc );
89 }
90
91 ID
92 bdb2i_dn2id(
93     BackendDB   *be,
94     char        *dn
95 )
96 {
97         struct ldbminfo *li = (struct ldbminfo *) be->be_private;
98         struct dbcache  *db;
99         ID              id;
100         Datum           key, data;
101
102         Debug( LDAP_DEBUG_TRACE, "=> bdb2i_dn2id( \"%s\" )\n", dn, 0, 0 );
103
104         /* first check the cache */
105         if ( (id = bdb2i_cache_find_entry_dn2id( be, &li->li_cache, dn )) != NOID ) {
106                 Debug( LDAP_DEBUG_TRACE, "<= bdb2i_dn2id %ld (in cache)\n", id,
107                         0, 0 );
108                 return( id );
109         }
110
111         if ( (db = bdb2i_cache_open( be, "dn2id", BDB2_SUFFIX, LDBM_WRCREAT ))
112                 == NULL ) {
113                 Debug( LDAP_DEBUG_ANY, "<= bdb2i_dn2id could not open dn2id%s\n",
114                         BDB2_SUFFIX, 0, 0 );
115                 return( NOID );
116         }
117
118         ldbm_datum_init( key );
119
120         key.dsize = strlen( dn ) + 2;
121         key.dptr = ch_malloc( key.dsize );
122         sprintf( key.dptr, "%c%s", DN_BASE_PREFIX, dn );
123
124         data = bdb2i_cache_fetch( db, key );
125
126         bdb2i_cache_close( be, db );
127
128         free( key.dptr );
129
130         if ( data.dptr == NULL ) {
131                 Debug( LDAP_DEBUG_TRACE, "<= bdb2i_dn2id NOID\n", 0, 0, 0 );
132                 return( NOID );
133         }
134
135         (void) memcpy( (char *) &id, data.dptr, sizeof(ID) );
136
137         ldbm_datum_free( db->dbc_db, data );
138
139         Debug( LDAP_DEBUG_TRACE, "<= bdb2i_dn2id %ld\n", id, 0, 0 );
140         return( id );
141 }
142
143 ID_BLOCK *
144 bdb2i_dn2idl(
145     BackendDB   *be,
146     char        *dn,
147         int     prefix )
148 {
149         struct dbcache  *db;
150         Datum key;
151         ID_BLOCK *idl;
152
153         Debug( LDAP_DEBUG_TRACE, "=> bdb2i_dn2idl( \"%c%s\" )\n", prefix, dn, 0 );
154
155         if ( (db = bdb2i_cache_open( be, "dn2id", BDB2_SUFFIX, LDBM_WRCREAT ))
156             == NULL ) {
157                 Debug( LDAP_DEBUG_ANY,
158                     "<= bdb2i_dn2idl could not open dn2id%s\n", BDB2_SUFFIX,
159                     0, 0 );
160                 return( NULL );
161         }
162
163         ldbm_datum_init( key );
164
165         key.dsize = strlen( dn ) + 2;
166         key.dptr = ch_malloc( key.dsize );
167         sprintf( key.dptr, "%c%s", prefix, dn );
168
169         idl = bdb2i_idl_fetch( be, db, key );
170
171         free( key.dptr );
172
173         bdb2i_cache_close( be, db );
174
175         return( idl );
176 }
177
178 int
179 bdb2i_dn2id_delete(
180     BackendDB   *be,
181     char        *dn
182 )
183 {
184         struct dbcache  *db;
185         Datum           key;
186         int             rc;
187
188         Debug( LDAP_DEBUG_TRACE, "=> bdb2i_dn2id_delete( \"%s\" )\n", dn, 0, 0 );
189
190         if ( (db = bdb2i_cache_open( be, "dn2id", BDB2_SUFFIX, LDBM_WRCREAT ))
191             == NULL ) {
192                 Debug( LDAP_DEBUG_ANY,
193                     "<= bdb2i_dn2id_delete could not open dn2id%s\n", BDB2_SUFFIX,
194                     0, 0 );
195                 return( -1 );
196         }
197
198         ldbm_datum_init( key );
199
200         key.dsize = strlen( dn ) + 2;
201         key.dptr = ch_malloc( key.dsize );
202         sprintf( key.dptr, "%c%s", DN_BASE_PREFIX, dn );
203
204         rc = bdb2i_cache_delete( db, key );
205
206         free( key.dptr );
207
208         bdb2i_cache_close( be, db );
209
210         Debug( LDAP_DEBUG_TRACE, "<= bdb2i_dn2id_delete %d\n", rc, 0, 0 );
211         return( rc );
212 }
213
214 /*
215  * dn2entry - look up dn in the cache/indexes and return the corresponding
216  * entry.
217  */
218
219 Entry *
220 bdb2i_dn2entry_rw(
221     BackendDB   *be,
222     char        *dn,
223     Entry       **matched,
224     int         rw
225 )
226 {
227         struct ldbminfo *li = (struct ldbminfo *) be->be_private;
228         ID              id;
229         Entry           *e = NULL;
230         char            *pdn;
231
232         Debug(LDAP_DEBUG_TRACE, "dn2entry_%s: dn: \"%s\"\n",
233                 rw ? "w" : "r", dn, 0);
234
235         if( matched != NULL ) {
236                 /* caller cares about match */
237                 *matched = NULL;
238         }
239
240         if ( (id = bdb2i_dn2id( be, dn )) != NOID &&
241                 (e = bdb2i_id2entry_rw( be, id, rw )) != NULL )
242         {
243                 return( e );
244         }
245
246         if ( id != NOID ) {
247                 Debug(LDAP_DEBUG_ANY,
248                         "dn2entry_%s: no entry for valid id (%ld), dn \"%s\"\n",
249                         rw ? "w" : "r", id, dn);
250                 /* must have been deleted from underneath us */
251                 /* treat as if NOID was found */
252         }
253
254         /* caller doesn't care about match */
255         if( matched == NULL ) return NULL;
256
257         /* entry does not exist - see how much of the dn does exist */
258         /* dn_parent checks returns NULL if dn is suffix */
259         if ( (pdn = dn_parent( be, dn )) != NULL ) {
260                 /* get entry with reader lock */
261                 if ( (e = bdb2i_dn2entry_r( be, pdn, matched )) != NULL ) {
262                         *matched = e;
263                 }
264                 free( pdn );
265         }
266
267         return( NULL );
268 }
269
270