]> git.sur5r.net Git - openldap/blob - servers/slapd/back-meta/cache-merge.c
Drop unused arguments from syncrepl_add_glue
[openldap] / servers / slapd / back-meta / cache-merge.c
1 /* Copyright (c) 2003 by International Business Machines, Inc.
2  *
3  * International Business Machines, Inc. (hereinafter called IBM) grants
4  * permission under its copyrights to use, copy, modify, and distribute this
5  * Software with or without fee, provided that the above copyright notice and
6  * all paragraphs of this notice appear in all copies, and that the name of IBM
7  * not be used in connection with the marketing of any product incorporating
8  * the Software or modifications thereof, without specific, written prior
9  * permission.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
12  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
13  * PARTICULAR PURPOSE.  IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
14  * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
15  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
16  * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
17  */
18
19 #include "portable.h"
20
21 #include <stdio.h>
22
23 #include <ac/socket.h>
24 #include <ac/string.h>
25 #include <ac/time.h>
26
27 #include "slap.h"
28 #include "ldif.h"
29 #include "../back-ldap/back-ldap.h"
30 #include "back-meta.h"
31 #include "ldap_pvt.h"
32 #undef ldap_debug       /* silence a warning in ldap-int.h */
33 #include "ldap_log.h"
34 #include "../../../libraries/libldap/ldap-int.h"
35 #include <sys/time.h>
36
37 static struct berval bv_queryid_any = BER_BVC( "(queryid=*)" );
38
39 static Attribute* 
40 add_attribute(AttributeDescription *ad,
41         Entry* e,
42         BerVarray value_array
43 ); 
44
45 static int
46 null_response (
47         Operation       *op,
48         SlapReply       *rs
49 ); 
50
51 static int 
52 normalize_values( Attribute* attr );    
53
54 struct entry_info {
55         int                     size_init; 
56         int                     size_final; 
57         int                     added; 
58         Entry*                  entry; 
59         struct berval*          uuid; 
60         struct timeval          tv;     /* time */ 
61         enum type_of_result     err; 
62         Backend*                glue_be; 
63 }; 
64
65
66 int 
67 get_entry_size(
68         Entry* e, 
69         int size_init, 
70         struct exception* result )
71 {
72         Attribute       *a;
73         struct berval   bv;
74         int             i; 
75         int             tmplen;
76         int             size=0;
77
78         if ( result )
79                 result->type = SUCCESS; 
80
81         if ( e->e_dn != NULL ) {
82                 tmplen = strlen( e->e_dn );
83                 size = LDIF_SIZE_NEEDED( 2, tmplen );
84         }
85
86         for ( a = e->e_attrs; a != NULL; a = a->a_next ) {
87                 for ( i = 0; a->a_vals[i].bv_val != NULL; i++ ) {
88                         bv = a->a_vals[i];
89                         tmplen = a->a_desc->ad_cname.bv_len;
90                         size += LDIF_SIZE_NEEDED( tmplen, bv.bv_len);
91                 }
92         }
93         if ((size < size_init) && result) {
94                 result->type = SIZE_ERR; 
95         }
96         return size;
97 }
98
99 int
100 merge_entry(
101         Operation               *op,
102         SlapReply               *rs,
103         struct berval*          query_uuid, 
104         struct exception*       result )
105 {
106         struct entry_info info;
107         int             rc;
108         Modifications* modlist = NULL;
109         const char*     text = NULL;
110         BerVarray               value_array; 
111         Attribute               *uuid_attr, *attr;
112         Entry                   *e;
113
114         SlapReply sreply = {REP_RESULT};
115
116         Operation op_tmp = *op;
117         slap_callback cb;
118
119         sreply.sr_entry = NULL; 
120         sreply.sr_nentries = 0; 
121
122         e = ( Entry * ) ch_calloc( 1, sizeof( Entry )); 
123
124         dnPrettyNormal(0, &rs->sr_entry->e_name, &op_tmp.o_req_dn, &op_tmp.o_req_ndn, op->o_tmpmemctx);
125         ber_dupbv( &e->e_name, &op_tmp.o_req_dn );
126         ber_dupbv( &e->e_nname, &op_tmp.o_req_ndn );
127         sl_free( op_tmp.o_req_ndn.bv_val, op->o_tmpmemctx );
128         sl_free( op_tmp.o_req_dn.bv_val, op->o_tmpmemctx );
129         op_tmp.o_req_dn = e->e_name;
130         op_tmp.o_req_ndn = e->e_nname;
131
132         e->e_private = NULL;
133         e->e_attrs = NULL; 
134         e->e_bv.bv_val = NULL; 
135
136         /* add queryid attribute */     
137         value_array = (struct berval *)malloc(2 * sizeof( struct berval) );
138         ber_dupbv(value_array, query_uuid);
139         value_array[1].bv_val = NULL;
140         value_array[1].bv_len = 0;
141
142         uuid_attr = add_attribute(slap_schema.si_ad_queryid, e, value_array); 
143
144         /* append the attribute list from the fetched entry */
145         uuid_attr->a_next = rs->sr_entry->e_attrs;
146         rs->sr_entry->e_attrs = NULL;
147
148         for ( attr = e->e_attrs; attr; attr = attr->a_next ) {
149                 if ( normalize_values( attr ) ) {
150                         info.err = MERGE_ERR; 
151                         result->rc = info.err;
152                         return 0;
153                 }
154         }
155
156         info.entry = e;
157         info.uuid = query_uuid;
158         info.size_init = get_entry_size( rs->sr_entry, 0, 0 );
159         info.size_final = 0;
160         info.added = 0;
161         info.glue_be = op->o_bd;
162         info.err = SUCCESS;
163         cb.sc_private = &info;
164         cb.sc_response = null_response;
165
166         op_tmp.o_tag = LDAP_REQ_ADD;
167         op_tmp.o_protocol = LDAP_VERSION3;
168         op_tmp.o_callback = &cb;
169         op_tmp.o_time = slap_get_time();
170         op_tmp.o_do_not_cache = 1;
171
172         op_tmp.ora_e = e;
173         rc = op->o_bd->be_add( &op_tmp, &sreply );
174
175         if ( rc != LDAP_SUCCESS ) {
176                 if ( rc == LDAP_ALREADY_EXISTS ) {
177                         slap_entry2mods( e, &modlist, &text );
178                         op_tmp.o_tag = LDAP_REQ_MODIFY;
179                         op_tmp.orm_modlist = modlist;
180                         op_tmp.o_req_dn = e->e_name;
181                         op_tmp.o_req_ndn = e->e_nname;
182                         rc = op->o_bd->be_modify( &op_tmp, &sreply );
183                         result->rc = info.added;
184                 } else if ( rc == LDAP_REFERRAL ||
185                                         rc == LDAP_NO_SUCH_OBJECT ) {
186                         syncrepl_add_glue( &op_tmp, e );
187                         result->rc = info.added;
188                 } else {
189                         result->rc = 0;
190                 }
191                 if ( modlist != NULL ) slap_mods_free( modlist );
192         } else {
193                 info.size_init = 0;
194                 result->rc = info.added;
195                 be_entry_release_w( &op_tmp, e );
196         }
197
198         if ( result->rc )
199                 info.size_final = get_entry_size( e, info.size_init, result );
200         else
201                 info.size_final = info.size_init;
202
203         return ( info.size_final - info.size_init );
204 }
205
206 static Attribute* 
207 add_attribute(AttributeDescription *ad,
208         Entry* e, 
209         BerVarray value_array) 
210 {
211         Attribute* new_attr, *last_attr; 
212         const char* text; 
213
214         if (e->e_attrs == NULL) 
215                 last_attr = NULL; 
216         else 
217                 for (last_attr = e->e_attrs; last_attr->a_next;
218                                 last_attr = last_attr->a_next)
219                         ; 
220
221         new_attr = (Attribute*)malloc(sizeof(Attribute));               
222         if (last_attr) 
223                 last_attr->a_next = new_attr;
224         else 
225                 e->e_attrs = new_attr; 
226
227         new_attr->a_next = NULL; 
228         new_attr->a_desc = NULL;
229         new_attr->a_vals = value_array; 
230         new_attr->a_desc = ad;
231
232         return new_attr; 
233 }
234
235 static int
236 null_response (
237         Operation       *op,
238         SlapReply       *rs )
239 {
240         return 0;
241 }
242
243 static int 
244 normalize_values( Attribute* attr ) 
245 {
246         int nvals, rc, i; 
247  
248         if (attr->a_vals == NULL) {
249                 attr->a_nvals = NULL; 
250                 return 0; 
251         } 
252
253         for ( nvals = 0; attr->a_vals[nvals].bv_val; nvals++ ) 
254                 ; 
255
256         attr->a_nvals = (struct berval*)ch_malloc((nvals+1)*sizeof(struct berval));
257
258         if ( attr->a_desc->ad_type->sat_equality &&
259                                 attr->a_desc->ad_type->sat_equality->smr_normalize )
260         {
261                 for ( i = 0; i < nvals; i++ ) {
262                         rc = attr->a_desc->ad_type->sat_equality->smr_normalize(
263                                 SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX,
264                                 attr->a_desc->ad_type->sat_syntax,
265                                 attr->a_desc->ad_type->sat_equality,
266                                 &attr->a_vals[i], &attr->a_nvals[i], NULL );
267                         if ( rc ) {
268 #ifdef NEW_LOGGING
269                                 LDAP_LOG( OPERATION, DETAIL1,
270                                         "Error in normalizing attribute %s value %d (%d)\n",
271                                         attr->a_desc->ad_cname.bv_val, i, rc );
272 #else
273                                 Debug( LDAP_DEBUG_ANY,
274                                         "Error in normalizing attribute %s value %d (%d)\n",
275                                         attr->a_desc->ad_cname.bv_val, i, rc );
276 #endif
277                                 return rc;
278                         }
279                 }
280         } else {
281                 for ( i = 0; i < nvals; i++ ) {
282                         ber_dupbv( &attr->a_nvals[i], &attr->a_vals[i] ); 
283                 }
284         }
285                         
286         attr->a_nvals[i].bv_val = NULL;
287         attr->a_nvals[i].bv_len = 0;
288
289         return LDAP_SUCCESS;
290 }