]> git.sur5r.net Git - openldap/blob - servers/slapd/back-ldbm/dn2id.c
s/SAFEMEMCPY/AC_MEMCPY/
[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         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         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         AC_MEMCPY( (char *) &id, data.dptr, sizeof(ID) );
143
144         assert( id != NOID );
145
146         ldbm_datum_free( db->dbc_db, data );
147
148         Debug( LDAP_DEBUG_TRACE, "<= dn2id %ld\n", id, 0, 0 );
149         return( id );
150 }
151
152 ID_BLOCK *
153 dn2idl(
154     Backend     *be,
155     const char  *dn,
156         int             prefix
157 )
158 {
159         DBCache *db;
160         Datum           key;
161         ID_BLOCK        *idl;
162
163         Debug( LDAP_DEBUG_TRACE, "=> dn2idl( \"%c%s\" )\n", prefix, dn, 0 );
164
165         if ( (db = ldbm_cache_open( be, "dn2id", LDBM_SUFFIX, LDBM_WRCREAT ))
166                 == NULL ) {
167                 Debug( LDAP_DEBUG_ANY, "<= dn2idl could not open dn2id%s\n",
168                         LDBM_SUFFIX, 0, 0 );
169                 return NULL;
170         }
171
172         ldbm_datum_init( key );
173
174         key.dsize = strlen( dn ) + 2;
175         key.dptr = ch_malloc( key.dsize );
176         sprintf( key.dptr, "%c%s", prefix, dn );
177
178         idl = idl_fetch( be, db, key );
179
180         ldbm_cache_close( be, db );
181
182         free( key.dptr );
183
184         return( idl );
185 }
186
187
188 int
189 dn2id_delete(
190     Backend     *be,
191     const char  *dn,
192         ID id
193 )
194 {
195         DBCache *db;
196         Datum           key;
197         int             rc;
198
199         Debug( LDAP_DEBUG_TRACE, "=> dn2id_delete( \"%s\", %ld )\n", dn, id, 0 );
200
201         assert( id != NOID );
202
203         if ( (db = ldbm_cache_open( be, "dn2id", LDBM_SUFFIX, LDBM_WRCREAT ))
204             == NULL ) {
205                 Debug( LDAP_DEBUG_ANY,
206                     "<= dn2id_delete could not open dn2id%s\n", LDBM_SUFFIX,
207                     0, 0 );
208                 return( -1 );
209         }
210
211
212         {
213                 char *pdn = dn_parent( NULL, dn );
214
215                 if( pdn != NULL ) {
216                         ldbm_datum_init( key );
217                         key.dsize = strlen( pdn ) + 2;
218                         key.dptr = ch_malloc( key.dsize );
219                         sprintf( key.dptr, "%c%s", DN_ONE_PREFIX, pdn );
220
221                         (void) idl_delete_key( be, db, key, id );
222
223                         free( key.dptr );
224                         free( pdn );
225                 }
226         }
227
228         {
229                 char **subtree = dn_subtree( NULL, dn );
230
231                 if( subtree != NULL ) {
232                         int i;
233                         for( i=0; subtree[i] != NULL; i++ ) {
234                                 ldbm_datum_init( key );
235                                 key.dsize = strlen( subtree[i] ) + 2;
236                                 key.dptr = ch_malloc( key.dsize );
237                                 sprintf( key.dptr, "%c%s",
238                                         DN_SUBTREE_PREFIX, subtree[i] );
239
240                                 (void) idl_delete_key( be, db, key, id );
241
242                                 free( key.dptr );
243                         }
244
245                         charray_free( subtree );
246                 }
247         }
248
249         ldbm_datum_init( key );
250
251         key.dsize = strlen( dn ) + 2;
252         key.dptr = ch_malloc( key.dsize );
253         sprintf( key.dptr, "%c%s", DN_BASE_PREFIX, dn );
254
255         rc = ldbm_cache_delete( db, key );
256
257         free( key.dptr );
258
259         ldbm_cache_close( be, db );
260
261         Debug( LDAP_DEBUG_TRACE, "<= dn2id_delete %d\n", rc, 0, 0 );
262         return( rc );
263 }
264
265 /*
266  * dn2entry - look up dn in the cache/indexes and return the corresponding
267  * entry.
268  */
269
270 Entry *
271 dn2entry_rw(
272     Backend     *be,
273     const char  *dn,
274     Entry       **matched,
275     int         rw
276 )
277 {
278         ID              id;
279         Entry           *e = NULL;
280         char            *pdn;
281
282         Debug(LDAP_DEBUG_TRACE, "dn2entry_%s: dn: \"%s\"\n",
283                 rw ? "w" : "r", dn, 0);
284
285         if( matched != NULL ) {
286                 /* caller cares about match */
287                 *matched = NULL;
288         }
289
290         if ( (id = dn2id( be, dn )) != NOID &&
291                 (e = id2entry_rw( be, id, rw )) != NULL )
292         {
293                 return( e );
294         }
295
296         if ( id != NOID ) {
297                 Debug(LDAP_DEBUG_ANY,
298                         "dn2entry_%s: no entry for valid id (%ld), dn \"%s\"\n",
299                         rw ? "w" : "r", id, dn);
300                 /* must have been deleted from underneath us */
301                 /* treat as if NOID was found */
302         }
303
304         /* caller doesn't care about match */
305         if( matched == NULL ) return NULL;
306
307         /* entry does not exist - see how much of the dn does exist */
308         /* dn_parent checks returns NULL if dn is suffix */
309         if ( (pdn = dn_parent( be, dn )) != NULL ) {
310                 /* get entry with reader lock */
311                 if ( (e = dn2entry_r( be, pdn, matched )) != NULL ) {
312                         *matched = e;
313                 }
314                 free( pdn );
315         }
316
317         return NULL;
318 }
319