Commit c0579714 c0579714b791e5af5f02112488af253e448d5279 by Sergey Poznyakoff

Implemented rest of required sieve tests (address and envelope).

1 parent 516006ad
...@@ -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 {
122 if (idx == 0)
37 return header_aget_value ((header_t) data, (char*)item, pval); 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 };
149 292
150 #define MATCH_PART \ 293 static sieve_tag_def_t match_part_tags[] = {
151 { "is", TAG_IS, SVT_VOID },\ 294 { "is", SVT_VOID },
152 { "contains", TAG_CONTAINS, SVT_VOID },\ 295 { "contains", SVT_VOID },
153 { "matches", TAG_MATCHES, SVT_VOID },\ 296 { "matches", SVT_VOID },
154 { "regex", TAG_REGEX, SVT_VOID } 297 { "regex", SVT_VOID },
298 { "comparator", SVT_STRING },
299 { NULL }
300 };
155 301
156 #define COMP_PART \ 302 static sieve_tag_def_t size_tags[] = {
157 { "comparator", TAG_COMPARATOR, SVT_STRING } 303 { "over", SVT_VOID },
304 { "under", SVT_VOID },
305 { NULL }
306 };
158 307
159 #define SIZE_PART \ 308 #define ADDRESS_PART_GROUP \
160 { "under", TAG_UNDER, SVT_VOID },\ 309 { address_part_tags, NULL }
161 { "over", TAG_OVER, SVT_VOID }
162 310
311 #define MATCH_PART_GROUP \
312 { match_part_tags, sieve_match_part_checker }
163 313
164 sieve_tag_def_t address_tags[] = { 314 #define SIZE_GROUP { size_tags, NULL }
165 ADDRESS_PART, 315
166 COMP_PART, 316 sieve_tag_group_t address_tag_groups[] = {
167 MATCH_PART, 317 ADDRESS_PART_GROUP,
318 MATCH_PART_GROUP,
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 }
......