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