]> git.sur5r.net Git - openldap/blob - servers/slapd/back-ldbm/dn2id.c
Import strdup() -> ch_strdup() change from -devel.
[openldap] / servers / slapd / back-ldbm / dn2id.c
1 /* dn2id.c - routines to deal with the dn2id index */
2
3 #include "portable.h"
4
5 #include <stdio.h>
6
7 #include <ac/string.h>
8 #include <ac/socket.h>
9
10 #include "slap.h"
11 #include "back-ldbm.h"
12 #include "proto-back-ldbm.h"
13
14 int
15 dn2id_add(
16     Backend     *be,
17     char        *dn,
18     ID          id
19 )
20 {
21         int             rc, flags;
22         struct dbcache  *db;
23         Datum           key, data;
24         struct ldbminfo *li = (struct ldbminfo *) be->be_private;
25
26 #ifdef HAVE_BERKELEY_DB2
27         memset( &key, 0, sizeof( key ) );
28         memset( &data, 0, sizeof( data ) );
29 #endif
30
31         Debug( LDAP_DEBUG_TRACE, "=> dn2id_add( \"%s\", %ld )\n", dn, id, 0 );
32
33         if ( (db = ldbm_cache_open( be, "dn2id", LDBM_SUFFIX, LDBM_WRCREAT ))
34             == NULL ) {
35                 Debug( LDAP_DEBUG_ANY, "Could not open/create dn2id%s\n",
36                     LDBM_SUFFIX, 0, 0 );
37                 return( -1 );
38         }
39
40         dn = ch_strdup( dn );
41         dn_normalize_case( dn );
42
43         key.dptr = dn;
44         key.dsize = strlen( dn ) + 1;
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( dn );
54         ldbm_cache_close( be, db );
55
56         Debug( LDAP_DEBUG_TRACE, "<= dn2id_add %d\n", rc, 0, 0 );
57         return( rc );
58 }
59
60 ID
61 dn2id(
62     Backend     *be,
63     char        *dn
64 )
65 {
66         struct ldbminfo *li = (struct ldbminfo *) be->be_private;
67         struct dbcache  *db;
68         ID              id;
69         Datum           key, data;
70
71 #ifdef HAVE_BERKELEY_DB2
72         memset( &key, 0, sizeof( key ) );
73         memset( &data, 0, sizeof( data ) );
74 #endif
75
76         dn = ch_strdup( dn );
77         Debug( LDAP_DEBUG_TRACE, "=> dn2id( \"%s\" )\n", dn, 0, 0 );
78         dn_normalize_case( dn );
79
80         /* first check the cache */
81         if ( (id = cache_find_entry_dn2id( be, &li->li_cache, dn )) != NOID ) {
82                 free( dn );
83                 Debug( LDAP_DEBUG_TRACE, "<= dn2id %lu (in cache)\n", id,
84                         0, 0 );
85                 return( id );
86         }
87
88         if ( (db = ldbm_cache_open( be, "dn2id", LDBM_SUFFIX, LDBM_WRCREAT ))
89                 == NULL ) {
90                 free( dn );
91                 Debug( LDAP_DEBUG_ANY, "<= dn2id could not open dn2id%s\n",
92                         LDBM_SUFFIX, 0, 0 );
93                 return( NOID );
94         }
95
96         key.dptr = dn;
97         key.dsize = strlen( dn ) + 1;
98
99         data = ldbm_cache_fetch( db, key );
100
101         ldbm_cache_close( be, db );
102         free( dn );
103
104         if ( data.dptr == NULL ) {
105                 Debug( LDAP_DEBUG_TRACE, "<= dn2id NOID\n", 0, 0, 0 );
106                 return( NOID );
107         }
108
109         (void) memcpy( (char *) &id, data.dptr, sizeof(ID) );
110
111         ldbm_datum_free( db->dbc_db, data );
112
113         Debug( LDAP_DEBUG_TRACE, "<= dn2id %lu\n", id, 0, 0 );
114         return( id );
115 }
116
117 int
118 dn2id_delete(
119     Backend     *be,
120     char        *dn
121 )
122 {
123         struct ldbminfo *li = (struct ldbminfo *) be->be_private;
124         struct dbcache  *db;
125         Datum           key;
126         int             rc;
127
128 #ifdef HAVE_BERKELEY_DB2
129         memset( &key, 0, sizeof( key ) );
130 #endif
131
132         Debug( LDAP_DEBUG_TRACE, "=> dn2id_delete( \"%s\" )\n", dn, 0, 0 );
133
134         if ( (db = ldbm_cache_open( be, "dn2id", LDBM_SUFFIX, LDBM_WRCREAT ))
135             == NULL ) {
136                 Debug( LDAP_DEBUG_ANY,
137                     "<= dn2id_delete could not open dn2id%s\n", LDBM_SUFFIX,
138                     0, 0 );
139                 return( -1 );
140         }
141
142         dn_normalize_case( dn );
143         key.dptr = dn;
144         key.dsize = strlen( dn ) + 1;
145
146         rc = ldbm_cache_delete( db, key );
147
148         ldbm_cache_close( be, db );
149
150         Debug( LDAP_DEBUG_TRACE, "<= dn2id_delete %d\n", rc, 0, 0 );
151         return( rc );
152 }
153
154 /*
155  * dn2entry - look up dn in the cache/indexes and return the corresponding
156  * entry.
157  */
158
159 static Entry *
160 dn2entry(
161     Backend     *be,
162     char        *dn,
163     char        **matched,
164     int         rw
165 )
166 {
167         struct ldbminfo *li = (struct ldbminfo *) be->be_private;
168         ID              id;
169         Entry           *e = NULL;
170         char            *pdn;
171
172         Debug(LDAP_DEBUG_TRACE, "dn2entry_%s: dn: %s\n",
173                 rw ? "w" : "r", dn, 0);
174
175         *matched = NULL;
176
177         if ( (id = dn2id( be, dn )) != NOID &&
178                 (e = id2entry( be, id, rw )) != NULL )
179         {
180                 return( e );
181         }
182
183         /* stop when we get to the suffix */
184         if ( be_issuffix( be, dn ) ) {
185                 return( NULL );
186         }
187
188         /* entry does not exist - see how much of the dn does exist */
189         if ( (pdn = dn_parent( be, dn )) != NULL ) {
190                 /* get entry with reader lock */
191                 if ( (e = dn2entry_r( be, pdn, matched )) != NULL ) {
192                         *matched = pdn;
193                         /* free entry with reader lock */
194                         cache_return_entry_r( &li->li_cache, e );
195                 } else {
196                         free( pdn );
197                 }
198         }
199
200         return( NULL );
201 }
202
203 Entry *
204 dn2entry_r(
205         Backend *be,
206         char    *dn,
207         char    **matched
208 )
209 {
210         return( dn2entry( be, dn, matched, 0 ) );
211 }
212
213 Entry *
214 dn2entry_w(
215         Backend *be,
216         char    *dn,
217         char    **matched
218 )
219 {
220         return( dn2entry( be, dn, matched, 1 ) );
221 }
222
223
224