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