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