]> git.sur5r.net Git - openldap/blob - servers/slapd/back-ldbm/dn2id.c
c361418e3c7f12cd6ae55a444e1cbb6d5578fcef
[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         ldbm_datum_init( key );
27         ldbm_datum_init( data );
28
29         Debug( LDAP_DEBUG_TRACE, "=> dn2id_add( \"%s\", %ld )\n", dn, id, 0 );
30
31         if ( (db = ldbm_cache_open( be, "dn2id", LDBM_SUFFIX, LDBM_WRCREAT ))
32             == NULL ) {
33                 Debug( LDAP_DEBUG_ANY, "Could not open/create dn2id%s\n",
34                     LDBM_SUFFIX, 0, 0 );
35                 return( -1 );
36         }
37
38         dn = ch_strdup( dn );
39         dn_normalize_case( dn );
40
41         key.dptr = dn;
42         key.dsize = strlen( dn ) + 1;
43         data.dptr = (char *) &id;
44         data.dsize = sizeof(ID);
45
46         flags = LDBM_INSERT;
47         if ( li->li_dbcachewsync ) flags |= LDBM_SYNC;
48
49         rc = ldbm_cache_store( db, key, data, flags );
50
51         free( dn );
52         ldbm_cache_close( be, db );
53
54         Debug( LDAP_DEBUG_TRACE, "<= dn2id_add %d\n", rc, 0, 0 );
55         return( rc );
56 }
57
58 ID
59 dn2id(
60     Backend     *be,
61     char        *dn
62 )
63 {
64         struct ldbminfo *li = (struct ldbminfo *) be->be_private;
65         struct dbcache  *db;
66         ID              id;
67         Datum           key, data;
68
69         ldbm_datum_init( key );
70         ldbm_datum_init( data );
71
72         dn = ch_strdup( dn );
73         Debug( LDAP_DEBUG_TRACE, "=> dn2id( \"%s\" )\n", dn, 0, 0 );
74         dn_normalize_case( dn );
75
76         /* first check the cache */
77         if ( (id = cache_find_entry_dn2id( be, &li->li_cache, dn )) != NOID ) {
78                 free( dn );
79                 Debug( LDAP_DEBUG_TRACE, "<= dn2id %ld (in cache)\n", id,
80                         0, 0 );
81                 return( id );
82         }
83
84         if ( (db = ldbm_cache_open( be, "dn2id", LDBM_SUFFIX, LDBM_WRCREAT ))
85                 == NULL ) {
86                 free( dn );
87                 Debug( LDAP_DEBUG_ANY, "<= dn2id could not open dn2id%s\n",
88                         LDBM_SUFFIX, 0, 0 );
89                 return( NOID );
90         }
91
92         key.dptr = dn;
93         key.dsize = strlen( dn ) + 1;
94
95         data = ldbm_cache_fetch( db, key );
96
97         ldbm_cache_close( be, db );
98         free( dn );
99
100         if ( data.dptr == NULL ) {
101                 Debug( LDAP_DEBUG_TRACE, "<= dn2id NOID\n", 0, 0, 0 );
102                 return( NOID );
103         }
104
105         (void) memcpy( (char *) &id, data.dptr, sizeof(ID) );
106
107         ldbm_datum_free( db->dbc_db, data );
108
109         Debug( LDAP_DEBUG_TRACE, "<= dn2id %ld\n", id, 0, 0 );
110         return( id );
111 }
112
113 int
114 dn2id_delete(
115     Backend     *be,
116     char        *dn
117 )
118 {
119         struct dbcache  *db;
120         Datum           key;
121         int             rc;
122
123         ldbm_datum_init( key );
124
125         Debug( LDAP_DEBUG_TRACE, "=> dn2id_delete( \"%s\" )\n", dn, 0, 0 );
126
127         if ( (db = ldbm_cache_open( be, "dn2id", LDBM_SUFFIX, LDBM_WRCREAT ))
128             == NULL ) {
129                 Debug( LDAP_DEBUG_ANY,
130                     "<= dn2id_delete could not open dn2id%s\n", LDBM_SUFFIX,
131                     0, 0 );
132                 return( -1 );
133         }
134
135         dn = ch_strdup( dn );
136         dn_normalize_case( dn );
137         key.dptr = dn;
138         key.dsize = strlen( dn ) + 1;
139
140         rc = ldbm_cache_delete( db, key );
141
142         free( dn );
143
144         ldbm_cache_close( be, db );
145
146         Debug( LDAP_DEBUG_TRACE, "<= dn2id_delete %d\n", rc, 0, 0 );
147         return( rc );
148 }
149
150 /*
151  * dn2entry - look up dn in the cache/indexes and return the corresponding
152  * entry.
153  */
154
155 Entry *
156 dn2entry_rw(
157     Backend     *be,
158     char        *dn,
159     Entry       **matched,
160     int         rw
161 )
162 {
163         struct ldbminfo *li = (struct ldbminfo *) be->be_private;
164         ID              id;
165         Entry           *e = NULL;
166         char            *pdn;
167
168         Debug(LDAP_DEBUG_TRACE, "dn2entry_%s: dn: \"%s\"\n",
169                 rw ? "w" : "r", dn, 0);
170
171         if( matched != NULL ) {
172                 /* caller cares about match */
173                 *matched = NULL;
174         }
175
176         if ( (id = dn2id( be, dn )) != NOID &&
177                 (e = id2entry_rw( be, id, rw )) != NULL )
178         {
179                 return( e );
180         }
181
182         if ( id != NOID ) {
183                 Debug(LDAP_DEBUG_ANY,
184                         "dn2entry_%s: no entry for valid id (%ld), dn \"%s\"\n",
185                         rw ? "w" : "r", id, dn);
186                 /* must have been deleted from underneath us */
187                 /* treat as if NOID was found */
188         }
189
190         /* caller doesn't care about match */
191         if( matched == NULL ) return NULL;
192
193         /* entry does not exist - see how much of the dn does exist */
194         /* dn_parent checks returns NULL if dn is suffix */
195         if ( (pdn = dn_parent( be, dn )) != NULL ) {
196                 /* get entry with reader lock */
197                 if ( (e = dn2entry_r( be, pdn, matched )) != NULL ) {
198                         *matched = e;
199                 }
200                 free( pdn );
201         }
202
203         return NULL;
204 }
205