Commit aaa399e1 aaa399e10f2ad7160653a2519372cbe18cce6b20 by Sergey Poznyakoff

(do_count): New function. A common handler for :count tag.

(retrieve_header): Use header_get_field_{name|value}, since
header_aget_value cannot return multiple header values.

(sieve_test_address,sieve_test_header,sieve_test_envelope): Use do_count.
1 parent 95a3f648
...@@ -63,6 +63,28 @@ struct address_closure ...@@ -63,6 +63,28 @@ struct address_closure
63 address_t addr; /* Obtained address */ 63 address_t addr; /* Obtained address */
64 }; 64 };
65 65
66 static int
67 do_count (list_t args, list_t tags, size_t count, int retval)
68 {
69 sieve_value_t *arg;
70
71 if (sieve_tag_lookup (tags, "count", &arg))
72 {
73 size_t limit;
74 char *str;
75 sieve_value_t *val;
76 sieve_relcmpn_t stest;
77
78 val = sieve_value_get (args, 1);
79 list_get (val->v.list, 0, (void **) &str);
80 limit = strtoul (str, &str, 10);
81
82 sieve_str_to_relcmp (arg->v.string, NULL, &stest);
83 return stest (count, limit);
84 }
85 return retval;
86 }
87
66 int 88 int
67 retrieve_address (void *item, void *data, int idx, char **pval) 89 retrieve_address (void *item, void *data, int idx, char **pval)
68 { 90 {
...@@ -120,29 +142,35 @@ sieve_test_address (sieve_machine_t mach, list_t args, list_t tags) ...@@ -120,29 +142,35 @@ sieve_test_address (sieve_machine_t mach, list_t args, list_t tags)
120 rc = sieve_vlist_compare (h, v, comp, test, retrieve_address, &clos, &count); 142 rc = sieve_vlist_compare (h, v, comp, test, retrieve_address, &clos, &count);
121 address_destroy (&clos.addr); 143 address_destroy (&clos.addr);
122 144
123 if (sieve_tag_lookup (tags, "count", &arg)) 145 return do_count (args, tags, count, rc);
124 {
125 size_t limit;
126 char *str;
127 sieve_value_t *val;
128 sieve_relcmpn_t stest;
129
130 val = sieve_value_get (args, 1);
131 list_get (val->v.list, 0, (void **) &str);
132 limit = strtoul (str, &str, 10);
133
134 sieve_str_to_relcmp (arg->v.string, NULL, &stest);
135 return stest (count, limit);
136 }
137
138 return rc;
139 } 146 }
140 147
148 struct header_closure {
149 header_t header;
150 int index;
151 };
152
141 int 153 int
142 retrieve_header (void *item, void *data, int idx, char **pval) 154 retrieve_header (void *item, void *data, int idx, char **pval)
143 { 155 {
156 struct header_closure *hc = data;
157 char buf[512];
158 size_t n;
159
144 if (idx == 0) 160 if (idx == 0)
145 return header_aget_value ((header_t) data, (char*)item, pval); 161 hc->index = 1;
162
163 while (!header_get_field_name (hc->header, hc->index, buf, sizeof(buf), &n))
164 {
165 int i = hc->index++;
166 if (strcasecmp (buf, (char*)item) == 0)
167 {
168 if (header_aget_field_value (hc->header, i, pval))
169 return 1;
170 return 0;
171 }
172 }
173
146 return 1; 174 return 1;
147 } 175 }
148 176
...@@ -150,10 +178,10 @@ int ...@@ -150,10 +178,10 @@ int
150 sieve_test_header (sieve_machine_t mach, list_t args, list_t tags) 178 sieve_test_header (sieve_machine_t mach, list_t args, list_t tags)
151 { 179 {
152 sieve_value_t *h, *v, *arg; 180 sieve_value_t *h, *v, *arg;
153 header_t header = NULL;
154 sieve_comparator_t comp = sieve_get_comparator (mach, tags); 181 sieve_comparator_t comp = sieve_get_comparator (mach, tags);
155 sieve_relcmp_t test = sieve_get_relcmp (mach, tags); 182 sieve_relcmp_t test = sieve_get_relcmp (mach, tags);
156 size_t count, mcount = 0; 183 size_t count, mcount = 0;
184 struct header_closure clos;
157 185
158 if (mach->debug_level & MU_SIEVE_DEBUG_TRACE) 186 if (mach->debug_level & MU_SIEVE_DEBUG_TRACE)
159 sieve_debug (mach, "HEADER\n"); 187 sieve_debug (mach, "HEADER\n");
...@@ -187,34 +215,19 @@ sieve_test_header (sieve_machine_t mach, list_t args, list_t tags) ...@@ -187,34 +215,19 @@ sieve_test_header (sieve_machine_t mach, list_t args, list_t tags)
187 215
188 if (message_get_part (mach->msg, i, &message) == 0) 216 if (message_get_part (mach->msg, i, &message) == 0)
189 { 217 {
190 message_get_header (message, &header); 218 message_get_header (message, &clos.header);
191 if (sieve_vlist_compare (h, v, comp, test, 219 if (sieve_vlist_compare (h, v, comp, test,
192 retrieve_header, header, &mcount)) 220 retrieve_header, &clos, &mcount))
193 return 1; 221 return 1;
194 } 222 }
195 } 223 }
196 } 224 }
197 } 225 }
198 message_get_header (mach->msg, &header); 226 message_get_header (mach->msg, &clos.header);
199 if (sieve_vlist_compare (h, v, comp, test, retrieve_header, header, &count)) 227 if (sieve_vlist_compare (h, v, comp, test, retrieve_header, &clos, &count))
200 return 1; 228 return 1;
201 229
202 if (sieve_tag_lookup (tags, "count", &arg)) 230 return do_count (args, tags, count + mcount, 0);
203 {
204 size_t limit;
205 char *str;
206 sieve_value_t *val;
207 sieve_relcmpn_t stest;
208
209 val = sieve_value_get (args, 1);
210 list_get (val->v.list, 0, (void **) &str);
211 limit = strtoul (str, &str, 10);
212
213 sieve_str_to_relcmp (arg->v.string, NULL, &stest);
214 return stest (count + mcount, limit);
215 }
216
217 return 0;
218 } 231 }
219 232
220 int 233 int
...@@ -253,6 +266,7 @@ sieve_test_envelope (sieve_machine_t mach, list_t args, list_t tags) ...@@ -253,6 +266,7 @@ sieve_test_envelope (sieve_machine_t mach, list_t args, list_t tags)
253 sieve_relcmp_t test = sieve_get_relcmp (mach, tags); 266 sieve_relcmp_t test = sieve_get_relcmp (mach, tags);
254 struct address_closure clos; 267 struct address_closure clos;
255 int rc; 268 int rc;
269 size_t count;
256 270
257 if (mach->debug_level & MU_SIEVE_DEBUG_TRACE) 271 if (mach->debug_level & MU_SIEVE_DEBUG_TRACE)
258 sieve_debug (mach, "HEADER\n"); 272 sieve_debug (mach, "HEADER\n");
...@@ -273,9 +287,10 @@ sieve_test_envelope (sieve_machine_t mach, list_t args, list_t tags) ...@@ -273,9 +287,10 @@ sieve_test_envelope (sieve_machine_t mach, list_t args, list_t tags)
273 message_get_envelope (sieve_get_message (mach), (envelope_t*)&clos.data); 287 message_get_envelope (sieve_get_message (mach), (envelope_t*)&clos.data);
274 clos.aget = sieve_get_address_part (tags); 288 clos.aget = sieve_get_address_part (tags);
275 clos.addr = NULL; 289 clos.addr = NULL;
276 rc = sieve_vlist_compare (h, v, comp, test, retrieve_envelope, &clos, NULL); 290 rc = sieve_vlist_compare (h, v, comp, test, retrieve_envelope, &clos,
291 &count);
277 address_destroy (&clos.addr); 292 address_destroy (&clos.addr);
278 return rc; 293 return do_count (args, tags, count, rc);
279 } 294 }
280 295
281 int 296 int
......