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