]> git.sur5r.net Git - openldap/blob - servers/slapd/back-ldbm/dn2id.c
7bfb1078e22ab7e45fd1c87f4a17cc5b97f671cd
[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_EQ_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         ldbm_cache_close( be, db );
60
61 #ifdef DN_INDICES
62         free( key.dptr );
63 #endif
64
65         Debug( LDAP_DEBUG_TRACE, "<= dn2id_add %d\n", rc, 0, 0 );
66         return( rc );
67 }
68
69 ID
70 dn2id(
71     Backend     *be,
72     char        *dn
73 )
74 {
75         struct ldbminfo *li = (struct ldbminfo *) be->be_private;
76         DBCache *db;
77         ID              id;
78         Datum           key, data;
79
80         ldbm_datum_init( key );
81         ldbm_datum_init( data );
82
83         Debug( LDAP_DEBUG_TRACE, "=> dn2id( \"%s\" )\n", dn, 0, 0 );
84
85         /* first check the cache */
86         if ( (id = cache_find_entry_dn2id( be, &li->li_cache, dn )) != NOID ) {
87                 Debug( LDAP_DEBUG_TRACE, "<= dn2id %ld (in cache)\n", id,
88                         0, 0 );
89                 return( id );
90         }
91
92         if ( (db = ldbm_cache_open( be, "dn2id", LDBM_SUFFIX, LDBM_WRCREAT ))
93                 == NULL ) {
94                 Debug( LDAP_DEBUG_ANY, "<= dn2id could not open dn2id%s\n",
95                         LDBM_SUFFIX, 0, 0 );
96                 return( NOID );
97         }
98
99 #ifndef DN_INDICES
100         key.dptr = dn;
101         key.dsize = strlen( key.dptr ) + 1;
102 #else
103         key.dsize = strlen( dn ) + 2;
104         key.dptr = ch_malloc( key.dsize );
105         sprintf( key.dptr, "%c%s", DN_EQ_PREFIX, dn );
106 #endif
107
108         data = ldbm_cache_fetch( db, key );
109
110         ldbm_cache_close( be, db );
111
112 #ifdef DN_INDICES
113         free( key.dptr );
114 #endif
115
116         if ( data.dptr == NULL ) {
117                 Debug( LDAP_DEBUG_TRACE, "<= dn2id NOID\n", 0, 0, 0 );
118                 return( NOID );
119         }
120
121         (void) memcpy( (char *) &id, data.dptr, sizeof(ID) );
122
123         ldbm_datum_free( db->dbc_db, data );
124
125         Debug( LDAP_DEBUG_TRACE, "<= dn2id %ld\n", id, 0, 0 );
126         return( id );
127 }
128
129 int
130 dn2id_delete(
131     Backend     *be,
132     char        *dn
133 )
134 {
135         DBCache *db;
136         Datum           key;
137         int             rc;
138
139         ldbm_datum_init( key );
140
141         Debug( LDAP_DEBUG_TRACE, "=> dn2id_delete( \"%s\" )\n", dn, 0, 0 );
142
143         if ( (db = ldbm_cache_open( be, "dn2id", LDBM_SUFFIX, LDBM_WRCREAT ))
144             == NULL ) {
145                 Debug( LDAP_DEBUG_ANY,
146                     "<= dn2id_delete could not open dn2id%s\n", LDBM_SUFFIX,
147                     0, 0 );
148                 return( -1 );
149         }
150
151 #ifndef DN_INDICES
152         key.dptr = dn;
153         key.dsize = strlen( key.dptr ) + 1;
154 #else
155         key.dsize = strlen( dn ) + 2;
156         key.dptr = ch_malloc( key.dsize );
157         sprintf( key.dptr, "%c%s", DN_EQ_PREFIX, dn );
158 #endif
159
160         rc = ldbm_cache_delete( db, key );
161
162 #ifdef DN_INDICES
163         free( key.dptr );
164 #endif
165
166         ldbm_cache_close( be, db );
167
168         Debug( LDAP_DEBUG_TRACE, "<= dn2id_delete %d\n", rc, 0, 0 );
169         return( rc );
170 }
171
172 /*
173  * dn2entry - look up dn in the cache/indexes and return the corresponding
174  * entry.
175  */
176
177 Entry *
178 dn2entry_rw(
179     Backend     *be,
180     char        *dn,
181     Entry       **matched,
182     int         rw
183 )
184 {
185         struct ldbminfo *li = (struct ldbminfo *) be->be_private;
186         ID              id;
187         Entry           *e = NULL;
188         char            *pdn;
189
190         Debug(LDAP_DEBUG_TRACE, "dn2entry_%s: dn: \"%s\"\n",
191                 rw ? "w" : "r", dn, 0);
192
193         if( matched != NULL ) {
194                 /* caller cares about match */
195                 *matched = NULL;
196         }
197
198         if ( (id = dn2id( be, dn )) != NOID &&
199                 (e = id2entry_rw( be, id, rw )) != NULL )
200         {
201                 return( e );
202         }
203
204         if ( id != NOID ) {
205                 Debug(LDAP_DEBUG_ANY,
206                         "dn2entry_%s: no entry for valid id (%ld), dn \"%s\"\n",
207                         rw ? "w" : "r", id, dn);
208                 /* must have been deleted from underneath us */
209                 /* treat as if NOID was found */
210         }
211
212         /* caller doesn't care about match */
213         if( matched == NULL ) return NULL;
214
215         /* entry does not exist - see how much of the dn does exist */
216         /* dn_parent checks returns NULL if dn is suffix */
217         if ( (pdn = dn_parent( be, dn )) != NULL ) {
218                 /* get entry with reader lock */
219                 if ( (e = dn2entry_r( be, pdn, matched )) != NULL ) {
220                         *matched = e;
221                 }
222                 free( pdn );
223         }
224
225         return NULL;
226 }
227