(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.
Showing
1 changed file
with
55 additions
and
40 deletions
... | @@ -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 | ... | ... |
-
Please register or sign in to post a comment