Implemented rest of required sieve tests (address and envelope).
Showing
1 changed file
with
188 additions
and
39 deletions
... | @@ -25,16 +25,103 @@ | ... | @@ -25,16 +25,103 @@ |
25 | #include <string.h> | 25 | #include <string.h> |
26 | #include <sieve.h> | 26 | #include <sieve.h> |
27 | 27 | ||
28 | typedef int (*address_aget_t) __PMT ((address_t addr, size_t no, char **buf)); | ||
29 | |||
30 | int | ||
31 | _get_address_part (void *item, void *data) | ||
32 | { | ||
33 | sieve_runtime_tag_t *t = item; | ||
34 | address_aget_t ret; | ||
35 | |||
36 | if (strcmp (t->tag, "all") == 0) | ||
37 | ret = address_aget_email; | ||
38 | else if (strcmp (t->tag, "domain") == 0) | ||
39 | ret = address_aget_domain; | ||
40 | else if (strcmp (t->tag, "localpart") == 0) | ||
41 | ret = address_aget_local_part; | ||
42 | *(address_aget_t*)data = ret; | ||
43 | return ret != NULL; | ||
44 | } | ||
45 | |||
46 | address_aget_t | ||
47 | sieve_get_address_part (list_t tags) | ||
48 | { | ||
49 | address_aget_t ret = address_aget_email; | ||
50 | list_do (tags, _get_address_part, &ret); | ||
51 | return ret; | ||
52 | } | ||
53 | |||
54 | /* Structure shared between address and envelope tests */ | ||
55 | struct address_closure | ||
56 | { | ||
57 | address_aget_t aget; /* appropriate address_aget_ function */ | ||
58 | void *data; /* Either header_t or envelope_t */ | ||
59 | address_t addr; /* Obtained address */ | ||
60 | }; | ||
61 | |||
62 | int | ||
63 | retrieve_address (void *item, void *data, int idx, char **pval) | ||
64 | { | ||
65 | struct address_closure *ap = data; | ||
66 | char *val; | ||
67 | int rc; | ||
68 | |||
69 | if (!ap->addr) | ||
70 | { | ||
71 | if (header_aget_value ((header_t)ap->data, (char*)item, &val)) | ||
72 | return 1; | ||
73 | rc = address_create (&ap->addr, val); | ||
74 | free (val); | ||
75 | if (rc) | ||
76 | return rc; | ||
77 | } | ||
78 | |||
79 | rc = ap->aget (ap->addr, idx+1, pval); | ||
80 | if (rc) | ||
81 | address_destroy (&ap->addr); | ||
82 | return rc; | ||
83 | } | ||
84 | |||
28 | int | 85 | int |
29 | sieve_test_address (sieve_machine_t mach, list_t args, list_t tags) | 86 | sieve_test_address (sieve_machine_t mach, list_t args, list_t tags) |
30 | { | 87 | { |
31 | return 0; | 88 | sieve_value_t *h, *v; |
89 | header_t header = NULL; | ||
90 | sieve_comparator_t comp = sieve_get_comparator (tags); | ||
91 | struct address_closure clos; | ||
92 | int rc; | ||
93 | |||
94 | if (mach->debug_level & MU_SIEVE_DEBUG_TRACE) | ||
95 | sieve_debug (mach, "ADDRESS\n"); | ||
96 | |||
97 | h = sieve_value_get (args, 0); | ||
98 | if (!h) | ||
99 | { | ||
100 | sieve_error (mach, "address: can't get argument 1"); | ||
101 | sieve_abort (mach); | ||
102 | } | ||
103 | v = sieve_value_get (args, 1); | ||
104 | if (!v) | ||
105 | { | ||
106 | sieve_error (mach, "address: can't get argument 2"); | ||
107 | sieve_abort (mach); | ||
108 | } | ||
109 | |||
110 | message_get_header (sieve_get_message (mach), &header); | ||
111 | clos.data = header; | ||
112 | clos.aget = sieve_get_address_part (tags); | ||
113 | clos.addr = NULL; | ||
114 | rc = sieve_vlist_compare (h, v, comp, retrieve_address, &clos); | ||
115 | address_destroy (&clos.addr); | ||
116 | return rc; | ||
32 | } | 117 | } |
33 | 118 | ||
34 | int | 119 | int |
35 | retrieve_header (void *item, void *data, char **pval) | 120 | retrieve_header (void *item, void *data, int idx, char **pval) |
36 | { | 121 | { |
37 | return header_aget_value ((header_t) data, (char*)item, pval); | 122 | if (idx == 0) |
123 | return header_aget_value ((header_t) data, (char*)item, pval); | ||
124 | return 1; | ||
38 | } | 125 | } |
39 | 126 | ||
40 | int | 127 | int |
... | @@ -66,9 +153,63 @@ sieve_test_header (sieve_machine_t mach, list_t args, list_t tags) | ... | @@ -66,9 +153,63 @@ sieve_test_header (sieve_machine_t mach, list_t args, list_t tags) |
66 | } | 153 | } |
67 | 154 | ||
68 | int | 155 | int |
156 | retrieve_envelope (void *item, void *data, int idx, char **pval) | ||
157 | { | ||
158 | struct address_closure *ap = data; | ||
159 | int rc; | ||
160 | |||
161 | if (!ap->addr) | ||
162 | { | ||
163 | char buf[512]; | ||
164 | size_t n; | ||
165 | |||
166 | if (strcasecmp ((char*)item, "from") != 0) | ||
167 | return 1; | ||
168 | |||
169 | if (envelope_sender ((envelope_t)ap->data, buf, sizeof(buf), &n)) | ||
170 | return 1; | ||
171 | |||
172 | rc = address_create (&ap->addr, buf); | ||
173 | if (rc) | ||
174 | return rc; | ||
175 | } | ||
176 | |||
177 | rc = ap->aget (ap->addr, idx+1, pval); | ||
178 | if (rc) | ||
179 | address_destroy (&ap->addr); | ||
180 | return rc; | ||
181 | } | ||
182 | |||
183 | int | ||
69 | sieve_test_envelope (sieve_machine_t mach, list_t args, list_t tags) | 184 | sieve_test_envelope (sieve_machine_t mach, list_t args, list_t tags) |
70 | { | 185 | { |
71 | return 0; | 186 | sieve_value_t *h, *v; |
187 | sieve_comparator_t comp = sieve_get_comparator (tags); | ||
188 | struct address_closure clos; | ||
189 | int rc; | ||
190 | |||
191 | if (mach->debug_level & MU_SIEVE_DEBUG_TRACE) | ||
192 | sieve_debug (mach, "HEADER\n"); | ||
193 | |||
194 | h = sieve_value_get (args, 0); | ||
195 | if (!h) | ||
196 | { | ||
197 | sieve_error (mach, "header: can't get argument 1"); | ||
198 | sieve_abort (mach); | ||
199 | } | ||
200 | v = sieve_value_get (args, 1); | ||
201 | if (!v) | ||
202 | { | ||
203 | sieve_error (mach, "header: can't get argument 2"); | ||
204 | sieve_abort (mach); | ||
205 | } | ||
206 | |||
207 | message_get_envelope (sieve_get_message (mach), (envelope_t*)&clos.data); | ||
208 | clos.aget = sieve_get_address_part (tags); | ||
209 | clos.addr = NULL; | ||
210 | rc = sieve_vlist_compare (h, v, comp, retrieve_envelope, &clos); | ||
211 | address_destroy (&clos.addr); | ||
212 | return rc; | ||
72 | } | 213 | } |
73 | 214 | ||
74 | int | 215 | int |
... | @@ -89,9 +230,9 @@ sieve_test_size (sieve_machine_t mach, list_t args, list_t tags) | ... | @@ -89,9 +230,9 @@ sieve_test_size (sieve_machine_t mach, list_t args, list_t tags) |
89 | list_get (tags, 0, (void **)&tag); | 230 | list_get (tags, 0, (void **)&tag); |
90 | if (!tag) | 231 | if (!tag) |
91 | rc = size == val->v.number; | 232 | rc = size == val->v.number; |
92 | else if (tag->tag == TAG_OVER) | 233 | else if (strcmp (tag->tag, "over") == 0) |
93 | rc = size > val->v.number; | 234 | rc = size > val->v.number; |
94 | else if (tag->tag == TAG_UNDER) | 235 | else if (strcmp (tag->tag, "under") == 0) |
95 | rc = size < val->v.number; | 236 | rc = size < val->v.number; |
96 | 237 | ||
97 | return rc; | 238 | return rc; |
... | @@ -142,29 +283,39 @@ sieve_test_exists (sieve_machine_t mach, list_t args, list_t tags) | ... | @@ -142,29 +283,39 @@ sieve_test_exists (sieve_machine_t mach, list_t args, list_t tags) |
142 | return sieve_vlist_do (val, _test_exists, header) == 0; | 283 | return sieve_vlist_do (val, _test_exists, header) == 0; |
143 | } | 284 | } |
144 | 285 | ||
145 | #define ADDRESS_PART \ | 286 | static sieve_tag_def_t address_part_tags[] = { |
146 | { "localpart", TAG_LOCALPART, SVT_VOID },\ | 287 | { "localpart", SVT_VOID }, |
147 | { "domain", TAG_DOMAIN, SVT_VOID },\ | 288 | { "domain", SVT_VOID }, |
148 | { "all", TAG_ALL, SVT_VOID } | 289 | { "all", SVT_VOID }, |
290 | { NULL } | ||
291 | }; | ||
292 | |||
293 | static sieve_tag_def_t match_part_tags[] = { | ||
294 | { "is", SVT_VOID }, | ||
295 | { "contains", SVT_VOID }, | ||
296 | { "matches", SVT_VOID }, | ||
297 | { "regex", SVT_VOID }, | ||
298 | { "comparator", SVT_STRING }, | ||
299 | { NULL } | ||
300 | }; | ||
149 | 301 | ||
150 | #define MATCH_PART \ | 302 | static sieve_tag_def_t size_tags[] = { |
151 | { "is", TAG_IS, SVT_VOID },\ | 303 | { "over", SVT_VOID }, |
152 | { "contains", TAG_CONTAINS, SVT_VOID },\ | 304 | { "under", SVT_VOID }, |
153 | { "matches", TAG_MATCHES, SVT_VOID },\ | 305 | { NULL } |
154 | { "regex", TAG_REGEX, SVT_VOID } | 306 | }; |
307 | |||
308 | #define ADDRESS_PART_GROUP \ | ||
309 | { address_part_tags, NULL } | ||
155 | 310 | ||
156 | #define COMP_PART \ | 311 | #define MATCH_PART_GROUP \ |
157 | { "comparator", TAG_COMPARATOR, SVT_STRING } | 312 | { match_part_tags, sieve_match_part_checker } |
158 | 313 | ||
159 | #define SIZE_PART \ | 314 | #define SIZE_GROUP { size_tags, NULL } |
160 | { "under", TAG_UNDER, SVT_VOID },\ | ||
161 | { "over", TAG_OVER, SVT_VOID } | ||
162 | 315 | ||
163 | 316 | sieve_tag_group_t address_tag_groups[] = { | |
164 | sieve_tag_def_t address_tags[] = { | 317 | ADDRESS_PART_GROUP, |
165 | ADDRESS_PART, | 318 | MATCH_PART_GROUP, |
166 | COMP_PART, | ||
167 | MATCH_PART, | ||
168 | { NULL } | 319 | { NULL } |
169 | }; | 320 | }; |
170 | 321 | ||
... | @@ -174,8 +325,8 @@ sieve_data_type address_req_args[] = { | ... | @@ -174,8 +325,8 @@ sieve_data_type address_req_args[] = { |
174 | SVT_VOID | 325 | SVT_VOID |
175 | }; | 326 | }; |
176 | 327 | ||
177 | sieve_tag_def_t size_tags[] = { | 328 | sieve_tag_group_t size_tag_groups[] = { |
178 | SIZE_PART, | 329 | SIZE_GROUP, |
179 | { NULL } | 330 | { NULL } |
180 | }; | 331 | }; |
181 | 332 | ||
... | @@ -184,10 +335,9 @@ sieve_data_type size_req_args[] = { | ... | @@ -184,10 +335,9 @@ sieve_data_type size_req_args[] = { |
184 | SVT_VOID | 335 | SVT_VOID |
185 | }; | 336 | }; |
186 | 337 | ||
187 | sieve_tag_def_t envelope_tags[] = { | 338 | sieve_tag_group_t envelope_tag_groups[] = { |
188 | COMP_PART, | 339 | ADDRESS_PART_GROUP, |
189 | ADDRESS_PART, | 340 | MATCH_PART_GROUP, |
190 | MATCH_PART, | ||
191 | { NULL } | 341 | { NULL } |
192 | }; | 342 | }; |
193 | 343 | ||
... | @@ -196,10 +346,9 @@ sieve_data_type exists_req_args[] = { | ... | @@ -196,10 +346,9 @@ sieve_data_type exists_req_args[] = { |
196 | SVT_VOID | 346 | SVT_VOID |
197 | }; | 347 | }; |
198 | 348 | ||
199 | sieve_tag_def_t header_tags[] = { | 349 | sieve_tag_group_t header_tag_groups[] = { |
200 | COMP_PART, | 350 | MATCH_PART_GROUP, |
201 | MATCH_PART, | 351 | { NULL } |
202 | { NULL }, | ||
203 | }; | 352 | }; |
204 | 353 | ||
205 | void | 354 | void |
... | @@ -208,13 +357,13 @@ sieve_register_standard_tests () | ... | @@ -208,13 +357,13 @@ sieve_register_standard_tests () |
208 | sieve_register_test ("false", sieve_test_false, NULL, NULL, 1); | 357 | sieve_register_test ("false", sieve_test_false, NULL, NULL, 1); |
209 | sieve_register_test ("true", sieve_test_true, NULL, NULL, 1); | 358 | sieve_register_test ("true", sieve_test_true, NULL, NULL, 1); |
210 | sieve_register_test ("address", sieve_test_address, | 359 | sieve_register_test ("address", sieve_test_address, |
211 | address_req_args, address_tags, 1); | 360 | address_req_args, address_tag_groups, 1); |
212 | sieve_register_test ("size", sieve_test_size, | 361 | sieve_register_test ("size", sieve_test_size, |
213 | size_req_args, size_tags, 1); | 362 | size_req_args, size_tag_groups, 1); |
214 | sieve_register_test ("envelope", sieve_test_envelope, | 363 | sieve_register_test ("envelope", sieve_test_envelope, |
215 | address_req_args, envelope_tags, 1); | 364 | address_req_args, envelope_tag_groups, 1); |
216 | sieve_register_test ("exists", sieve_test_exists, | 365 | sieve_register_test ("exists", sieve_test_exists, |
217 | exists_req_args, NULL, 1); | 366 | exists_req_args, NULL, 1); |
218 | sieve_register_test ("header", sieve_test_header, | 367 | sieve_register_test ("header", sieve_test_header, |
219 | address_req_args, header_tags, 1); | 368 | address_req_args, header_tag_groups, 1); |
220 | } | 369 | } | ... | ... |
-
Please register or sign in to post a comment