]> git.sur5r.net Git - openldap/blob - servers/slapd/back-meta/cache-substring.c
Changes from HEAD for beta
[openldap] / servers / slapd / back-meta / cache-substring.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 "../back-ldap/back-ldap.h"
29 #include "back-meta.h"
30 #include "ldap_pvt.h"
31 #undef ldap_debug       /* silence a warning in ldap-int.h */
32 #include "ldap_log.h"
33 #include "../../../libraries/libldap/ldap-int.h"
34
35 #include "slap.h"
36 #include "back-meta.h"
37
38 static char* invert_string(char* string);
39 static struct berval* merge_init_final(struct berval*, struct berval*, struct berval*); 
40 static int strings_containment(struct berval* stored, struct berval* incoming); 
41
42 /* find and remove string2 from string1 
43  * from start if position = 1, 
44  * from end if position = 3,
45  * from anywhere if position = 2
46  */
47
48 int 
49 find_and_remove(struct berval* ber1, struct berval* ber2, int position)
50 {
51         char* temp; 
52         int len; 
53         int ret=0;
54
55         char* arg1, *arg2;  
56         char* string1=ber1->bv_val;
57         char* string2=ber2->bv_val;
58         
59         if (string2 == NULL) 
60                 return 1; 
61         if (string1 == NULL) 
62                 return 0; 
63
64         if (position == 3) {
65                 arg1 = invert_string(string1); 
66                 arg2 = invert_string(string2); 
67         } else {
68                 arg1 = string1; 
69                 arg2 = string2; 
70         }
71             
72         temp = strstr(arg1, arg2); 
73         len = strlen(arg2);     
74
75         if (!temp) 
76                 return 0; 
77     
78         switch (position) {
79         case 1: 
80                 if (temp == arg1) {
81                         string1 += len; 
82                         ret = 1; 
83                 } else {
84                         ret = 0; 
85                 }
86                 break; 
87         case 2: 
88                 string1 = temp+len;  
89                 ret = 1; 
90                 break; 
91         case 3: 
92                 temp = strstr(arg1, arg2); 
93                 len = strlen(arg2);     
94                 if (temp == arg1) {
95                         /*arg1 += len;*/ 
96                         string1 = invert_string(arg1+len); 
97                         free(arg1);             
98                         free(arg2);             
99                         ret = 1; 
100                 } else {
101                         free(arg1);             
102                         free(arg2);             
103                         ret = 0; 
104                 }
105                 break; 
106         }
107         temp = (char*) malloc( strlen( string1 ) + 1 );
108         strcpy( temp, string1 );
109         free( ber1->bv_val );
110         ber1->bv_val = temp;
111         return ret;
112 }
113
114 char*
115 invert_string( char* string )
116 {
117         int len = strlen(string); 
118         int i; 
119
120         char* inverted = (char*)(malloc(len+1)); 
121
122         for (i=0; i<len; i++) 
123                 inverted[i] = string[len-i-1];
124
125         inverted[len] ='\0'; 
126
127         return inverted; 
128 }       
129
130 struct berval*  
131 merge_init_final(struct berval* init, struct berval* any, struct berval* final)
132 {
133         struct berval* merged, *temp; 
134         int i, any_count, count; 
135
136         for (any_count=0; any && any[any_count].bv_val; any_count++)
137                 ;
138
139         count = any_count; 
140
141         if (init->bv_val) 
142                 count++; 
143         if (final->bv_val)
144                 count++; 
145
146         merged = (struct berval*)(malloc((count+1)*sizeof(struct berval))); 
147         temp = merged; 
148
149         if (init->bv_val) {
150                 ber_dupbv(temp, init); 
151                 temp++;
152         }
153
154         for (i=0; i<any_count; i++) {
155                 ber_dupbv(temp, any); 
156                 any++;
157                 temp++; 
158         } 
159
160         if (final->bv_val){ 
161                 ber_dupbv(temp, final);
162                 temp++;
163         }        
164         temp->bv_val = NULL; 
165         temp->bv_len = 0; 
166         return merged; 
167 }
168
169 int
170 strings_containment(struct berval* stored, struct berval* incoming)
171 {
172         struct berval* element;
173         int k=0;
174         int j, rc = 0; 
175         
176         for ( element=stored; element->bv_val != NULL; element++ ) {
177                 for (j = k; incoming[j].bv_val != NULL; j++) {
178                         if (find_and_remove(&(incoming[j]), element, 2)) {
179                                 k = j; 
180                                 rc = 1; 
181                                 break; 
182                         }
183                         rc = 0; 
184                 }
185                 if ( rc ) {
186                         continue; 
187                 } else {
188                         return 0;
189                 }
190         }   
191         return 1;
192 }
193
194 int
195 substr_containment_substr(Filter* stored, Filter* incoming) 
196 {
197         int i; 
198         int k=0; 
199         int rc; 
200         int any_count = 0; 
201
202         struct berval* init_incoming = (struct berval*)(malloc(sizeof(struct berval))); 
203         struct berval* final_incoming = (struct berval*)(malloc(sizeof(struct berval)));  
204         struct berval* any_incoming = NULL; 
205         struct berval* remaining_incoming; 
206         struct berval* any_element; 
207
208         if ((!(incoming->f_sub_initial.bv_val) && (stored->f_sub_initial.bv_val)) 
209            || (!(incoming->f_sub_final.bv_val) && (stored->f_sub_final.bv_val))) 
210                 return 0; 
211  
212         
213         ber_dupbv(init_incoming, &(incoming->f_sub_initial)); 
214         ber_dupbv(final_incoming, &(incoming->f_sub_final)); 
215
216         if (incoming->f_sub_any) { 
217                 for ( any_count=0; incoming->f_sub_any[any_count].bv_val != NULL;
218                                 any_count++ )
219                         ;
220             
221                 any_incoming = (struct berval*)malloc((any_count+1) *
222                                                 sizeof(struct berval)); 
223             
224                 for (i=0; i<any_count; i++) {
225                         ber_dupbv(&(any_incoming[i]), &(incoming->f_sub_any[i])); 
226                 }
227                 any_incoming[any_count].bv_val = NULL; 
228                 any_incoming[any_count].bv_len = 0; 
229         }
230   
231         if (find_and_remove(init_incoming, 
232                         &(stored->f_sub_initial), 1) && find_and_remove(final_incoming, 
233                         &(stored->f_sub_final), 3)) 
234         {
235                 if (stored->f_sub_any == NULL) {
236                         rc = 1; 
237                         goto final; 
238                 }
239                 remaining_incoming = merge_init_final(init_incoming,
240                                                 any_incoming, final_incoming); 
241                 rc = strings_containment(stored->f_sub_any, remaining_incoming);
242                 goto final; 
243         }       
244         rc = 0; 
245 final:
246         /*
247         ber_bvfree(init_incoming);
248         ber_bvfree(final_incoming); 
249         if (any_incoming) {
250                 for (i=0; i < any_count; i++) 
251                         free(any_incoming[i].bv_val);
252                 free(any_incoming); 
253         }       
254         */
255                 
256         return rc; 
257 }
258
259 int
260 substr_containment_equality(Filter* stored, Filter* incoming) 
261 {
262                 
263         struct berval* incoming_val = (struct berval*)(malloc(2*sizeof(struct berval)));
264         int rc;
265  
266         ber_dupbv(incoming_val, &(incoming->f_av_value));
267         incoming_val[1].bv_val = NULL;
268         incoming_val[1].bv_len = 0;
269  
270         if (find_and_remove(incoming_val, 
271                         &(stored->f_sub_initial), 1) && find_and_remove(incoming_val, 
272                         &(stored->f_sub_final), 3)) {
273                 if (stored->f_sub_any == NULL){ 
274                         rc = 1;
275                         goto final;
276                 }       
277                 rc = strings_containment(stored->f_sub_any, incoming_val);
278                 goto final;
279         }
280         rc=0;
281 final:
282         /*
283         if(incoming_val[0].bv_val)
284                 free(incoming_val[0].bv_val);
285         free(incoming_val); 
286         */
287         return rc;
288 }