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