]> git.sur5r.net Git - openldap/blob - servers/slapd/back-meta/cache-substring.c
Notices and acknowledgements
[openldap] / servers / slapd / back-meta / cache-substring.c
1 /* $OpenLDAP$ */
2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
3  *
4  * Copyright 1999-2003 The OpenLDAP Foundation.
5  * Portions Copyright 2003 IBM Corporation.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted only as authorized by the OpenLDAP
10  * Public License.
11  *
12  * A copy of this license is available in the file LICENSE in the
13  * top-level directory of the distribution or, alternatively, at
14  * <http://www.OpenLDAP.org/license.html>.
15  */
16 /* ACKNOWLEDGEMENTS:
17  * This work was initially developed by the Apurva Kumar for inclusion
18  * in OpenLDAP Software.
19  */
20
21 #include "portable.h"
22
23 #include <stdio.h>
24
25 #include <ac/socket.h>
26 #include <ac/string.h>
27 #include <ac/time.h>
28
29 #include "slap.h"
30 #include "../back-ldap/back-ldap.h"
31 #include "back-meta.h"
32 #include "ldap_pvt.h"
33 #undef ldap_debug       /* silence a warning in ldap-int.h */
34 #include "ldap_log.h"
35 #include "../../../libraries/libldap/ldap-int.h"
36
37 #include "slap.h"
38 #include "back-meta.h"
39
40 static char* invert_string(char* string);
41 static struct berval* merge_init_final(struct berval*, struct berval*, struct berval*); 
42 static int strings_containment(struct berval* stored, struct berval* incoming); 
43
44 /* find and remove string2 from string1 
45  * from start if position = 1, 
46  * from end if position = 3,
47  * from anywhere if position = 2
48  */
49
50 int 
51 find_and_remove(struct berval* ber1, struct berval* ber2, int position)
52 {
53         char* temp; 
54         int len; 
55         int ret=0;
56
57         char* arg1, *arg2;  
58         char* string1=ber1->bv_val;
59         char* string2=ber2->bv_val;
60         
61         if (string2 == NULL) 
62                 return 1; 
63         if (string1 == NULL) 
64                 return 0; 
65
66         if (position == 3) {
67                 arg1 = invert_string(string1); 
68                 arg2 = invert_string(string2); 
69         } else {
70                 arg1 = string1; 
71                 arg2 = string2; 
72         }
73             
74         temp = strstr(arg1, arg2); 
75         len = strlen(arg2);     
76
77         if (!temp) 
78                 return 0; 
79     
80         switch (position) {
81         case 1: 
82                 if (temp == arg1) {
83                         string1 += len; 
84                         ret = 1; 
85                 } else {
86                         ret = 0; 
87                 }
88                 break; 
89         case 2: 
90                 string1 = temp+len;  
91                 ret = 1; 
92                 break; 
93         case 3: 
94                 temp = strstr(arg1, arg2); 
95                 len = strlen(arg2);     
96                 if (temp == arg1) {
97                         /*arg1 += len;*/ 
98                         string1 = invert_string(arg1+len); 
99                         free(arg1);             
100                         free(arg2);             
101                         ret = 1; 
102                 } else {
103                         free(arg1);             
104                         free(arg2);             
105                         ret = 0; 
106                 }
107                 break; 
108         }
109         temp = (char*) malloc( strlen( string1 ) + 1 );
110         strcpy( temp, string1 );
111         free( ber1->bv_val );
112         ber1->bv_val = temp;
113         return ret;
114 }
115
116 char*
117 invert_string( char* string )
118 {
119         int len = strlen(string); 
120         int i; 
121
122         char* inverted = (char*)(malloc(len+1)); 
123
124         for (i=0; i<len; i++) 
125                 inverted[i] = string[len-i-1];
126
127         inverted[len] ='\0'; 
128
129         return inverted; 
130 }       
131
132 struct berval*  
133 merge_init_final(struct berval* init, struct berval* any, struct berval* final)
134 {
135         struct berval* merged, *temp; 
136         int i, any_count, count; 
137
138         for (any_count=0; any && any[any_count].bv_val; any_count++)
139                 ;
140
141         count = any_count; 
142
143         if (init->bv_val) 
144                 count++; 
145         if (final->bv_val)
146                 count++; 
147
148         merged = (struct berval*)(malloc((count+1)*sizeof(struct berval))); 
149         temp = merged; 
150
151         if (init->bv_val) {
152                 ber_dupbv(temp, init); 
153                 temp++;
154         }
155
156         for (i=0; i<any_count; i++) {
157                 ber_dupbv(temp, any); 
158                 any++;
159                 temp++; 
160         } 
161
162         if (final->bv_val){ 
163                 ber_dupbv(temp, final);
164                 temp++;
165         }        
166         temp->bv_val = NULL; 
167         temp->bv_len = 0; 
168         return merged; 
169 }
170
171 int
172 strings_containment(struct berval* stored, struct berval* incoming)
173 {
174         struct berval* element;
175         int k=0;
176         int j, rc = 0; 
177         
178         for ( element=stored; element->bv_val != NULL; element++ ) {
179                 for (j = k; incoming[j].bv_val != NULL; j++) {
180                         if (find_and_remove(&(incoming[j]), element, 2)) {
181                                 k = j; 
182                                 rc = 1; 
183                                 break; 
184                         }
185                         rc = 0; 
186                 }
187                 if ( rc ) {
188                         continue; 
189                 } else {
190                         return 0;
191                 }
192         }   
193         return 1;
194 }
195
196 int
197 substr_containment_substr(Filter* stored, Filter* incoming) 
198 {
199         int i; 
200         int k=0; 
201         int rc; 
202         int any_count = 0; 
203
204         struct berval* init_incoming = (struct berval*)(malloc(sizeof(struct berval))); 
205         struct berval* final_incoming = (struct berval*)(malloc(sizeof(struct berval)));  
206         struct berval* any_incoming = NULL; 
207         struct berval* remaining_incoming; 
208         struct berval* any_element; 
209
210         if ((!(incoming->f_sub_initial.bv_val) && (stored->f_sub_initial.bv_val)) 
211            || (!(incoming->f_sub_final.bv_val) && (stored->f_sub_final.bv_val))) 
212                 return 0; 
213  
214         
215         ber_dupbv(init_incoming, &(incoming->f_sub_initial)); 
216         ber_dupbv(final_incoming, &(incoming->f_sub_final)); 
217
218         if (incoming->f_sub_any) { 
219                 for ( any_count=0; incoming->f_sub_any[any_count].bv_val != NULL;
220                                 any_count++ )
221                         ;
222             
223                 any_incoming = (struct berval*)malloc((any_count+1) *
224                                                 sizeof(struct berval)); 
225             
226                 for (i=0; i<any_count; i++) {
227                         ber_dupbv(&(any_incoming[i]), &(incoming->f_sub_any[i])); 
228                 }
229                 any_incoming[any_count].bv_val = NULL; 
230                 any_incoming[any_count].bv_len = 0; 
231         }
232   
233         if (find_and_remove(init_incoming, 
234                         &(stored->f_sub_initial), 1) && find_and_remove(final_incoming, 
235                         &(stored->f_sub_final), 3)) 
236         {
237                 if (stored->f_sub_any == NULL) {
238                         rc = 1; 
239                         goto final; 
240                 }
241                 remaining_incoming = merge_init_final(init_incoming,
242                                                 any_incoming, final_incoming); 
243                 rc = strings_containment(stored->f_sub_any, remaining_incoming);
244                 goto final; 
245         }       
246         rc = 0; 
247 final:
248         /*
249         ber_bvfree(init_incoming);
250         ber_bvfree(final_incoming); 
251         if (any_incoming) {
252                 for (i=0; i < any_count; i++) 
253                         free(any_incoming[i].bv_val);
254                 free(any_incoming); 
255         }       
256         */
257                 
258         return rc; 
259 }
260
261 int
262 substr_containment_equality(Filter* stored, Filter* incoming) 
263 {
264                 
265         struct berval* incoming_val = (struct berval*)(malloc(2*sizeof(struct berval)));
266         int rc;
267  
268         ber_dupbv(incoming_val, &(incoming->f_av_value));
269         incoming_val[1].bv_val = NULL;
270         incoming_val[1].bv_len = 0;
271  
272         if (find_and_remove(incoming_val, 
273                         &(stored->f_sub_initial), 1) && find_and_remove(incoming_val, 
274                         &(stored->f_sub_final), 3)) {
275                 if (stored->f_sub_any == NULL){ 
276                         rc = 1;
277                         goto final;
278                 }       
279                 rc = strings_containment(stored->f_sub_any, incoming_val);
280                 goto final;
281         }
282         rc=0;
283 final:
284         /*
285         if(incoming_val[0].bv_val)
286                 free(incoming_val[0].bv_val);
287         free(incoming_val); 
288         */
289         return rc;
290 }