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