]> git.sur5r.net Git - openldap/blob - servers/slapd/back-bdb/tools.c
Plug memory leak
[openldap] / servers / slapd / back-bdb / tools.c
1 /* tools.c - tools for slap tools */
2 /* $OpenLDAP$ */
3 /*
4  * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
5  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
6  */
7
8 #include "portable.h"
9
10 #include <stdio.h>
11 #include <ac/string.h>
12
13 #include "back-bdb.h"
14
15 static DBC *cursor = NULL;
16 static DBT key, data;
17
18 int bdb_tool_entry_open(
19         BackendDB *be, int mode )
20 {
21         /* initialize key and data thangs */
22         DBTzero( &key );
23         DBTzero( &data );
24         key.flags = DB_DBT_REALLOC;
25         data.flags = DB_DBT_REALLOC;
26
27         return 0;
28 }
29
30 int bdb_tool_entry_close(
31         BackendDB *be )
32 {
33         assert( be != NULL );
34
35         if( key.data ) {
36                 ch_free( key.data );
37                 key.data = NULL;
38         }
39         if( data.data ) {
40                 ch_free( data.data );
41                 data.data = NULL;
42         }
43
44         if( cursor ) {
45                 cursor->c_close( cursor );
46                 cursor = NULL;
47         }
48
49         return 0;
50 }
51
52 ID bdb_tool_entry_next(
53         BackendDB *be )
54 {
55         int rc;
56         ID id;
57         struct bdb_info *bdb = (struct bdb_info *) be->be_private;
58
59         assert( be != NULL );
60         assert( slapMode & SLAP_TOOL_MODE );
61         assert( bdb != NULL );
62         
63         if (cursor == NULL) {
64                 rc = bdb->bi_id2entry->bdi_db->cursor(
65                         bdb->bi_id2entry->bdi_db, NULL, &cursor,
66                         bdb->bi_db_opflags );
67                 if( rc != 0 ) {
68                         return NOID;
69                 }
70         }
71
72         rc = cursor->c_get( cursor, &key, &data, DB_NEXT );
73
74         if( rc != 0 ) {
75                 return NOID;
76         }
77
78         if( data.data == NULL ) {
79                 return NOID;
80         }
81
82         AC_MEMCPY( &id, key.data, key.size );
83         return id;
84 }
85
86 Entry* bdb_tool_entry_get( BackendDB *be, ID id )
87 {
88         int rc;
89         Entry *e;
90         struct berval bv;
91
92         assert( be != NULL );
93         assert( slapMode & SLAP_TOOL_MODE );
94         assert( data.data != NULL );
95
96         DBT2bv( &data, &bv );
97
98         rc = entry_decode( &bv, &e );
99
100         if( rc == LDAP_SUCCESS ) {
101                 e->e_id = id;
102         }
103
104 #ifdef BDB_HIER
105         bdb_fix_dn(be, id, e);
106 #endif
107
108         return e;
109 }
110
111 ID bdb_tool_entry_put(
112         BackendDB *be,
113         Entry *e,
114         struct berval *text )
115 {
116         int rc;
117         struct bdb_info *bdb = (struct bdb_info *) be->be_private;
118         DB_TXN *tid = NULL;
119         struct berval pdn;
120
121         assert( be != NULL );
122         assert( slapMode & SLAP_TOOL_MODE );
123
124         assert( text );
125         assert( text->bv_val );
126         assert( text->bv_val[0] == '\0' );      /* overconservative? */
127
128 #ifdef NEW_LOGGING
129         LDAP_LOG ( TOOLS, ARGS, "=> bdb_tool_entry_put( %ld, \"%s\" )\n",
130                 (long) e->e_id, e->e_dn, 0 );
131 #else
132         Debug( LDAP_DEBUG_TRACE, "=> bdb_tool_entry_put( %ld, \"%s\" )\n",
133                 (long) e->e_id, e->e_dn, 0 );
134 #endif
135
136         rc = TXN_BEGIN( bdb->bi_dbenv, NULL, &tid, 
137                 bdb->bi_db_opflags );
138         if( rc != 0 ) {
139                 snprintf( text->bv_val, text->bv_len,
140                         "txn_begin failed: %s (%d)",
141                         db_strerror(rc), rc );
142 #ifdef NEW_LOGGING
143         LDAP_LOG ( TOOLS, ERR, "=> bdb_tool_entry_put: %s\n", text->bv_val, 0, 0 );
144 #else
145                 Debug( LDAP_DEBUG_ANY,
146                         "=> bdb_tool_entry_put: %s\n",
147                          text->bv_val, 0, 0 );
148 #endif
149                 return NOID;
150         }
151
152         rc = bdb_next_id( be, tid, &e->e_id );
153         if( rc != 0 ) {
154                 snprintf( text->bv_val, text->bv_len,
155                                 "next_id failed: %s (%d)",
156                                 db_strerror(rc), rc );
157 #ifdef NEW_LOGGING
158                 LDAP_LOG ( TOOLS, ERR, 
159                         "=> bdb_tool_entry_put: %s\n", text->bv_val, 0, 0 );
160 #else
161                 Debug( LDAP_DEBUG_ANY,
162                         "=> bdb_tool_entry_put: %s\n", text->bv_val, 0, 0 );
163 #endif
164                 goto done;
165         }
166
167         /* add dn2id indices */
168         if ( be_issuffix( be, &e->e_nname ) ) {
169                 pdn = slap_empty_bv;
170         } else {
171                 dnParent( &e->e_nname, &pdn );
172         }
173         rc = bdb_dn2id_add( be, tid, &pdn, e );
174         if( rc != 0 ) {
175                 snprintf( text->bv_val, text->bv_len, 
176                                 "dn2id_add failed: %s (%d)",
177                                 db_strerror(rc), rc );
178 #ifdef NEW_LOGGING
179                 LDAP_LOG ( TOOLS, ERR, 
180                         "=> bdb_tool_entry_put: %s\n", text->bv_val, 0, 0 );
181 #else
182                 Debug( LDAP_DEBUG_ANY,
183                         "=> bdb_tool_entry_put: %s\n", text->bv_val, 0, 0 );
184 #endif
185                 goto done;
186         }
187
188         /* id2entry index */
189         rc = bdb_id2entry_add( be, tid, e );
190         if( rc != 0 ) {
191                 snprintf( text->bv_val, text->bv_len,
192                                 "id2entry_add failed: %s (%d)",
193                                 db_strerror(rc), rc );
194 #ifdef NEW_LOGGING
195                 LDAP_LOG ( TOOLS, ERR, 
196                         "=> bdb_tool_entry_put: %s\n", text->bv_val, 0, 0 );
197 #else
198                 Debug( LDAP_DEBUG_ANY,
199                         "=> bdb_tool_entry_put: %s\n", text->bv_val, 0, 0 );
200 #endif
201                 goto done;
202         }
203
204         rc = bdb_index_entry_add( be, tid, e, e->e_attrs );
205         if( rc != 0 ) {
206                 snprintf( text->bv_val, text->bv_len,
207                                 "index_entry_add failed: %s (%d)",
208                                 db_strerror(rc), rc );
209 #ifdef NEW_LOGGING
210                 LDAP_LOG ( TOOLS, ERR, 
211                         "=> bdb_tool_entry_put: %s\n", text->bv_val, 0, 0 );
212 #else
213                 Debug( LDAP_DEBUG_ANY,
214                         "=> bdb_tool_entry_put: %s\n", text->bv_val, 0, 0 );
215 #endif
216                 goto done;
217         }
218
219 done:
220         if( rc == 0 ) {
221                 rc = TXN_COMMIT( tid, 0 );
222                 if( rc != 0 ) {
223                         snprintf( text->bv_val, text->bv_len,
224                                         "txn_commit failed: %s (%d)",
225                                         db_strerror(rc), rc );
226 #ifdef NEW_LOGGING
227                         LDAP_LOG ( TOOLS, ERR, 
228                                 "=> bdb_tool_entry_put: %s\n", text->bv_val, 0, 0 );
229 #else
230                         Debug( LDAP_DEBUG_ANY,
231                                 "=> bdb_tool_entry_put: %s\n",
232                                 text->bv_val, 0, 0 );
233 #endif
234                         e->e_id = NOID;
235                 }
236
237         } else {
238                 TXN_ABORT( tid );
239                 snprintf( text->bv_val, text->bv_len,
240                         "txn_aborted! %s (%d)",
241                         db_strerror(rc), rc );
242 #ifdef NEW_LOGGING
243                 LDAP_LOG ( TOOLS, ERR, 
244                         "=> bdb_tool_entry_put: %s\n", text->bv_val, 0, 0 );
245 #else
246                 Debug( LDAP_DEBUG_ANY,
247                         "=> bdb_tool_entry_put: %s\n",
248                         text->bv_val, 0, 0 );
249 #endif
250                 e->e_id = NOID;
251         }
252
253         return e->e_id;
254 }
255
256 int bdb_tool_entry_reindex(
257         BackendDB *be,
258         ID id )
259 {
260         struct bdb_info *bi = (struct bdb_info *) be->be_private;
261         int rc;
262         Entry *e;
263         DB_TXN *tid = NULL;
264         struct berval pdn;
265
266 #ifdef NEW_LOGGING
267         LDAP_LOG ( TOOLS, ARGS, 
268                 "=> bdb_tool_entry_reindex( %ld )\n", (long) id, 0, 0 );
269 #else
270         Debug( LDAP_DEBUG_ARGS, "=> bdb_tool_entry_reindex( %ld )\n",
271                 (long) id, 0, 0 );
272 #endif
273
274         e = bdb_tool_entry_get( be, id );
275
276         if( e == NULL ) {
277 #ifdef NEW_LOGGING
278                 LDAP_LOG ( TOOLS, DETAIL1, 
279                         "bdb_tool_entry_reindex:: could not locate id=%ld\n", 
280                         (long) id, 0, 0 );
281 #else
282                 Debug( LDAP_DEBUG_ANY,
283                         "bdb_tool_entry_reindex:: could not locate id=%ld\n",
284                         (long) id, 0, 0 );
285 #endif
286                 return -1;
287         }
288
289         rc = TXN_BEGIN( bi->bi_dbenv, NULL, &tid, bi->bi_db_opflags );
290         if( rc != 0 ) {
291 #ifdef NEW_LOGGING
292                 LDAP_LOG ( TOOLS, ERR, 
293                         "=> bdb_tool_entry_reindex: txn_begin failed: %s (%d)\n", 
294                         db_strerror(rc), rc, 0 );
295 #else
296                 Debug( LDAP_DEBUG_ANY,
297                         "=> bdb_tool_entry_reindex: txn_begin failed: %s (%d)\n",
298                         db_strerror(rc), rc, 0 );
299 #endif
300                 goto done;
301         }
302         
303         /*
304          * just (re)add them for now
305          * assume that some other routine (not yet implemented)
306          * will zap index databases
307          *
308          */
309
310 #ifdef NEW_LOGGING
311         LDAP_LOG ( TOOLS, ERR, 
312                 "=> bdb_tool_entry_reindex( %ld, \"%s\" )\n", (long) id, e->e_dn, 0 );
313 #else
314         Debug( LDAP_DEBUG_TRACE, "=> bdb_tool_entry_reindex( %ld, \"%s\" )\n",
315                 (long) id, e->e_dn, 0 );
316 #endif
317
318         /* add dn2id indices */
319         if ( be_issuffix( be, &e->e_nname ) ) {
320                 pdn = slap_empty_bv;
321         } else {
322                 dnParent( &e->e_nname, &pdn );
323         }
324         rc = bdb_dn2id_add( be, tid, &pdn, e );
325         if( rc != 0 && rc != DB_KEYEXIST ) {
326 #ifdef NEW_LOGGING
327                 LDAP_LOG ( TOOLS, ERR, 
328                         "=> bdb_tool_entry_reindex: dn2id_add failed: %s (%d)\n", 
329                         db_strerror(rc), rc, 0 );
330 #else
331                 Debug( LDAP_DEBUG_ANY,
332                         "=> bdb_tool_entry_reindex: dn2id_add failed: %s (%d)\n",
333                         db_strerror(rc), rc, 0 );
334 #endif
335                 goto done;
336         }
337
338         rc = bdb_index_entry_add( be, tid, e, e->e_attrs );
339
340 done:
341         if( rc == 0 ) {
342                 rc = TXN_COMMIT( tid, 0 );
343                 if( rc != 0 ) {
344 #ifdef NEW_LOGGING
345                         LDAP_LOG ( TOOLS, ERR, 
346                                 "=> bdb_tool_entry_reindex: txn_commit failed: %s (%d)\n", 
347                                 db_strerror(rc), rc, 0 );
348 #else
349                         Debug( LDAP_DEBUG_ANY,
350                                 "=> bdb_tool_entry_reindex: txn_commit failed: %s (%d)\n",
351                                 db_strerror(rc), rc, 0 );
352 #endif
353                         e->e_id = NOID;
354                 }
355
356         } else {
357                 TXN_ABORT( tid );
358 #ifdef NEW_LOGGING
359                 LDAP_LOG ( TOOLS, DETAIL1, 
360                         "=> bdb_tool_entry_reindex: txn_aborted! %s (%d)\n", 
361                         db_strerror(rc), rc, 0 );
362 #else
363                 Debug( LDAP_DEBUG_ANY,
364                         "=> bdb_tool_entry_reindex: txn_aborted! %s (%d)\n",
365                         db_strerror(rc), rc, 0 );
366 #endif
367                 e->e_id = NOID;
368         }
369
370         return rc;
371 }