]> git.sur5r.net Git - openldap/blob - servers/slapd/back-meta/cache-template.c
unifdef LDAP_CACHING
[openldap] / servers / slapd / back-meta / cache-template.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 #undef ldap_debug       /* silence a warning in ldap-int.h */
31 #include "../../../libraries/libldap/ldap-int.h"
32
33 void 
34 filter2template(
35         Filter                  *f,
36         struct                  berval *fstr,
37         AttributeName**         filter_attrs, 
38         int*                    filter_cnt,
39         struct exception*       result  )
40 {
41         int     i;
42         Filter  *p;
43         struct berval tmp;
44         ber_len_t len;
45         const char* text; 
46
47         /*
48          * FIXME: should we use an assert here?
49          */
50         if ( f == NULL ) {
51                 ber_str2bv( "No filter!", sizeof("No filter!")-1, 1, fstr );
52                 result->type = FILTER_ERR; 
53                 return; 
54         }
55
56         switch ( f->f_choice ) {
57         case LDAP_FILTER_EQUALITY:
58                 fstr->bv_len = f->f_av_desc->ad_cname.bv_len +
59                                 ( sizeof("(=)") - 1 );
60                 fstr->bv_val = ch_malloc( fstr->bv_len + 1 );
61
62                 snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s=)",
63                                 f->f_av_desc->ad_cname.bv_val );
64
65                 *filter_attrs = (AttributeName *)ch_realloc(*filter_attrs,
66                                 (*filter_cnt + 2)*sizeof(AttributeName)); 
67                 
68 #if 0   /* ? */
69                 ber_dupbv(&(*filter_attrs)[*filter_cnt].an_name,
70                                 &f->f_av_desc->ad_cname); 
71 #endif
72                 
73                 (*filter_attrs)[*filter_cnt].an_name = f->f_av_desc->ad_cname; 
74                 (*filter_attrs)[*filter_cnt].an_desc = NULL; 
75                 slap_bv2ad(&f->f_av_desc->ad_cname,
76                                 &(*filter_attrs)[*filter_cnt].an_desc, &text); 
77                 (*filter_attrs)[*filter_cnt+1].an_name.bv_val = NULL; 
78                 (*filter_attrs)[*filter_cnt+1].an_name.bv_len = 0; 
79                 (*filter_cnt)++; 
80                 break;
81         case LDAP_FILTER_GE:
82                 fstr->bv_len = f->f_av_desc->ad_cname.bv_len +
83                                 + ( sizeof("(>=)") - 1 );
84                 fstr->bv_val = ch_malloc( fstr->bv_len + 1 );
85
86                 snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s>=)",
87                         f->f_av_desc->ad_cname.bv_val);
88
89                 *filter_attrs = (AttributeName *)ch_realloc(*filter_attrs, 
90                                 (*filter_cnt + 2)*sizeof(AttributeName)); 
91 #if 0   /* ? */
92                 ber_dupbv(&(*filter_attrs)[filter_cnt].an_name,
93                                 &f->f_av_desc->ad_cname);
94 #endif
95
96                 (*filter_attrs)[*filter_cnt].an_name = f->f_av_desc->ad_cname; 
97                 (*filter_attrs)[*filter_cnt].an_desc = NULL; 
98                 slap_bv2ad(&f->f_av_desc->ad_cname,
99                                 &(*filter_attrs)[*filter_cnt].an_desc, &text); 
100                 (*filter_attrs)[*filter_cnt+1].an_name.bv_val = NULL; 
101                 (*filter_attrs)[*filter_cnt+1].an_name.bv_len = 0; 
102                 (*filter_cnt)++; 
103
104                 break;
105
106         case LDAP_FILTER_LE:
107                 fstr->bv_len = f->f_av_desc->ad_cname.bv_len +
108                         + ( sizeof("(<=)") - 1 );
109                 fstr->bv_val = ch_malloc( fstr->bv_len + 1 );
110
111                 snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s<=)",
112                         f->f_av_desc->ad_cname.bv_val);
113
114                 *filter_attrs = (AttributeName *)ch_realloc(*filter_attrs, 
115                                 (*filter_cnt + 2)*sizeof(AttributeName)); 
116 #if 0   /* ? */
117                 ber_dupbv(&(*filter_attrs)[filter_cnt].an_name,
118                                 &f->f_av_desc->ad_cname);
119 #endif
120                 
121                 (*filter_attrs)[*filter_cnt].an_name = f->f_av_desc->ad_cname; 
122                 (*filter_attrs)[*filter_cnt].an_desc = NULL; 
123                 slap_bv2ad(&f->f_av_desc->ad_cname,
124                                 &(*filter_attrs)[*filter_cnt].an_desc, &text); 
125                 (*filter_attrs)[*filter_cnt+1].an_name.bv_val = NULL; 
126                 (*filter_attrs)[*filter_cnt+1].an_name.bv_len = 0; 
127                 (*filter_cnt++); 
128
129                 break;
130
131         case LDAP_FILTER_APPROX:
132                 fstr->bv_len = f->f_av_desc->ad_cname.bv_len +
133                         + ( sizeof("(~=)") - 1 );
134                 fstr->bv_val = ch_malloc( fstr->bv_len + 1 );
135
136                 snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s~=)",
137                         f->f_av_desc->ad_cname.bv_val);
138                 
139                 *filter_attrs = (AttributeName *)ch_realloc(*filter_attrs,
140                                 (*filter_cnt + 2)*sizeof(AttributeName));
141
142 #if 0   /* ? */
143                 ber_dupbv(&(*filter_attrs)[filter_cnt].an_name,
144                                 &f->f_av_desc->ad_cname);
145 #endif
146                 
147                 (*filter_attrs)[*filter_cnt].an_name = f->f_av_desc->ad_cname; 
148                 (*filter_attrs)[*filter_cnt].an_desc = NULL; 
149                 slap_bv2ad(&f->f_av_desc->ad_cname,
150                                 &(*filter_attrs)[*filter_cnt].an_desc, &text); 
151                 (*filter_attrs)[*filter_cnt+1].an_name.bv_val = NULL; 
152                 (*filter_attrs)[*filter_cnt+1].an_name.bv_len = 0; 
153                 (*filter_cnt)++; 
154
155                 break;
156
157         case LDAP_FILTER_SUBSTRINGS:
158                 fstr->bv_len = f->f_sub_desc->ad_cname.bv_len +
159                         ( sizeof("(=)") - 1 );
160                 fstr->bv_val = ch_malloc( fstr->bv_len + 1 );
161
162                 snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s=)",
163                         f->f_sub_desc->ad_cname.bv_val );
164
165                 *filter_attrs = (AttributeName *)ch_realloc(*filter_attrs,
166                                 (*filter_cnt + 2)*sizeof(AttributeName));
167
168 #if 0   /* ? */
169                 ber_dupbv(&(*filter_attrs)[filter_cnt].an_name,
170                                 &f->f_av_desc->ad_cname);
171 #endif
172                 
173                 (*filter_attrs)[*filter_cnt].an_name = f->f_av_desc->ad_cname; 
174                 (*filter_attrs)[*filter_cnt].an_desc = NULL; 
175                 slap_bv2ad(&f->f_av_desc->ad_cname,
176                                 &(*filter_attrs)[*filter_cnt].an_desc, &text);
177                 (*filter_attrs)[*filter_cnt+1].an_name.bv_val = NULL; 
178                 (*filter_attrs)[*filter_cnt+1].an_name.bv_len = 0; 
179                 (*filter_cnt)++; 
180
181                 break;
182
183         case LDAP_FILTER_PRESENT:
184                 fstr->bv_len = f->f_desc->ad_cname.bv_len +
185                         ( sizeof("(=*)") - 1 );
186                 fstr->bv_val = ch_malloc( fstr->bv_len + 1 );
187
188                 snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s=*)",
189                         f->f_desc->ad_cname.bv_val );
190
191                 *filter_attrs = (AttributeName *)ch_realloc(*filter_attrs,
192                                 (*filter_cnt+2)*sizeof(AttributeName)); 
193
194 #if 0   /* ? */
195                 ber_dupbv(&(*filter_attrs)[filter_cnt].an_name,
196                                 &f->f_av_desc->ad_cname);
197 #endif
198                 
199                 (*filter_attrs)[*filter_cnt].an_name = f->f_desc->ad_cname; 
200                 (*filter_attrs)[*filter_cnt].an_desc = NULL; 
201                 slap_bv2ad(&f->f_desc->ad_cname,
202                                 &(*filter_attrs)[*filter_cnt].an_desc, &text);
203                 (*filter_attrs)[*filter_cnt+1].an_name.bv_val = NULL; 
204                 (*filter_attrs)[*filter_cnt+1].an_name.bv_len = 0; 
205                 (*filter_cnt)++; 
206
207                 break;
208
209         case LDAP_FILTER_AND:
210         case LDAP_FILTER_OR:
211         case LDAP_FILTER_NOT:
212                 fstr->bv_len = sizeof("(%)") - 1;
213                 fstr->bv_val = ch_malloc( fstr->bv_len + 128 );
214
215                 snprintf( fstr->bv_val, fstr->bv_len + 1, "(%c)",
216                         f->f_choice == LDAP_FILTER_AND ? '&' :
217                         f->f_choice == LDAP_FILTER_OR ? '|' : '!' );
218
219                 for ( p = f->f_list; p != NULL; p = p->f_next ) {
220                         len = fstr->bv_len;
221
222                         filter2template( p, &tmp, filter_attrs, filter_cnt,
223                                         result); 
224                         if (result->type != SUCCESS) {
225                                 return; 
226                         }
227                         
228                         fstr->bv_len += tmp.bv_len;
229                         fstr->bv_val = ch_realloc( fstr->bv_val,
230                                         fstr->bv_len + 1 );
231
232                         snprintf( &fstr->bv_val[len-1], tmp.bv_len + 2, 
233                                 /*"("*/ "%s)", tmp.bv_val );
234
235                         ch_free( tmp.bv_val );
236                 }
237
238                 break;
239
240         default:
241                 ber_str2bv( "(?=unknown)", sizeof("(?=unknown)")-1, 1, fstr );
242                 result->type = FILTER_ERR; 
243                 return;
244         }
245 }