25 |
#include <string.h> |
#include <string.h> |
26 |
#include <sieve.h> |
#include <sieve.h> |
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 |
|
|
85 |
int |
int |
86 |
sieve_test_address (sieve_machine_t mach, list_t args, list_t tags) |
sieve_test_address (sieve_machine_t mach, list_t args, list_t tags) |
87 |
{ |
{ |
88 |
return 0; |
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; |
117 |
} |
} |
118 |
|
|
119 |
int |
int |
120 |
retrieve_header (void *item, void *data, char **pval) |
retrieve_header (void *item, void *data, int idx, char **pval) |
121 |
{ |
{ |
122 |
return header_aget_value ((header_t) data, (char*)item, pval); |
if (idx == 0) |
123 |
|
return header_aget_value ((header_t) data, (char*)item, pval); |
124 |
|
return 1; |
125 |
} |
} |
126 |
|
|
127 |
int |
int |
153 |
} |
} |
154 |
|
|
155 |
int |
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 |
184 |
sieve_test_envelope (sieve_machine_t mach, list_t args, list_t tags) |
sieve_test_envelope (sieve_machine_t mach, list_t args, list_t tags) |
185 |
{ |
{ |
186 |
return 0; |
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; |
213 |
} |
} |
214 |
|
|
215 |
int |
int |
230 |
list_get (tags, 0, (void **)&tag); |
list_get (tags, 0, (void **)&tag); |
231 |
if (!tag) |
if (!tag) |
232 |
rc = size == val->v.number; |
rc = size == val->v.number; |
233 |
else if (tag->tag == TAG_OVER) |
else if (strcmp (tag->tag, "over") == 0) |
234 |
rc = size > val->v.number; |
rc = size > val->v.number; |
235 |
else if (tag->tag == TAG_UNDER) |
else if (strcmp (tag->tag, "under") == 0) |
236 |
rc = size < val->v.number; |
rc = size < val->v.number; |
237 |
|
|
238 |
return rc; |
return rc; |
283 |
return sieve_vlist_do (val, _test_exists, header) == 0; |
return sieve_vlist_do (val, _test_exists, header) == 0; |
284 |
} |
} |
285 |
|
|
286 |
#define ADDRESS_PART \ |
static sieve_tag_def_t address_part_tags[] = { |
287 |
{ "localpart", TAG_LOCALPART, SVT_VOID },\ |
{ "localpart", SVT_VOID }, |
288 |
{ "domain", TAG_DOMAIN, SVT_VOID },\ |
{ "domain", SVT_VOID }, |
289 |
{ "all", TAG_ALL, SVT_VOID } |
{ "all", SVT_VOID }, |
290 |
|
{ NULL } |
291 |
#define MATCH_PART \ |
}; |
292 |
{ "is", TAG_IS, SVT_VOID },\ |
|
293 |
{ "contains", TAG_CONTAINS, SVT_VOID },\ |
static sieve_tag_def_t match_part_tags[] = { |
294 |
{ "matches", TAG_MATCHES, SVT_VOID },\ |
{ "is", SVT_VOID }, |
295 |
{ "regex", TAG_REGEX, SVT_VOID } |
{ "contains", SVT_VOID }, |
296 |
|
{ "matches", SVT_VOID }, |
297 |
#define COMP_PART \ |
{ "regex", SVT_VOID }, |
298 |
{ "comparator", TAG_COMPARATOR, SVT_STRING } |
{ "comparator", SVT_STRING }, |
299 |
|
{ NULL } |
300 |
#define SIZE_PART \ |
}; |
301 |
{ "under", TAG_UNDER, SVT_VOID },\ |
|
302 |
{ "over", TAG_OVER, SVT_VOID } |
static sieve_tag_def_t size_tags[] = { |
303 |
|
{ "over", SVT_VOID }, |
304 |
|
{ "under", SVT_VOID }, |
305 |
|
{ NULL } |
306 |
|
}; |
307 |
|
|
308 |
|
#define ADDRESS_PART_GROUP \ |
309 |
|
{ address_part_tags, NULL } |
310 |
|
|
311 |
|
#define MATCH_PART_GROUP \ |
312 |
|
{ match_part_tags, sieve_match_part_checker } |
313 |
|
|
314 |
|
#define SIZE_GROUP { size_tags, NULL } |
315 |
|
|
316 |
|
sieve_tag_group_t address_tag_groups[] = { |
317 |
sieve_tag_def_t address_tags[] = { |
ADDRESS_PART_GROUP, |
318 |
ADDRESS_PART, |
MATCH_PART_GROUP, |
|
COMP_PART, |
|
|
MATCH_PART, |
|
319 |
{ NULL } |
{ NULL } |
320 |
}; |
}; |
321 |
|
|
325 |
SVT_VOID |
SVT_VOID |
326 |
}; |
}; |
327 |
|
|
328 |
sieve_tag_def_t size_tags[] = { |
sieve_tag_group_t size_tag_groups[] = { |
329 |
SIZE_PART, |
SIZE_GROUP, |
330 |
{ NULL } |
{ NULL } |
331 |
}; |
}; |
332 |
|
|
335 |
SVT_VOID |
SVT_VOID |
336 |
}; |
}; |
337 |
|
|
338 |
sieve_tag_def_t envelope_tags[] = { |
sieve_tag_group_t envelope_tag_groups[] = { |
339 |
COMP_PART, |
ADDRESS_PART_GROUP, |
340 |
ADDRESS_PART, |
MATCH_PART_GROUP, |
|
MATCH_PART, |
|
341 |
{ NULL } |
{ NULL } |
342 |
}; |
}; |
343 |
|
|
346 |
SVT_VOID |
SVT_VOID |
347 |
}; |
}; |
348 |
|
|
349 |
sieve_tag_def_t header_tags[] = { |
sieve_tag_group_t header_tag_groups[] = { |
350 |
COMP_PART, |
MATCH_PART_GROUP, |
351 |
MATCH_PART, |
{ NULL } |
|
{ NULL }, |
|
352 |
}; |
}; |
353 |
|
|
354 |
void |
void |
357 |
sieve_register_test ("false", sieve_test_false, NULL, NULL, 1); |
sieve_register_test ("false", sieve_test_false, NULL, NULL, 1); |
358 |
sieve_register_test ("true", sieve_test_true, NULL, NULL, 1); |
sieve_register_test ("true", sieve_test_true, NULL, NULL, 1); |
359 |
sieve_register_test ("address", sieve_test_address, |
sieve_register_test ("address", sieve_test_address, |
360 |
address_req_args, address_tags, 1); |
address_req_args, address_tag_groups, 1); |
361 |
sieve_register_test ("size", sieve_test_size, |
sieve_register_test ("size", sieve_test_size, |
362 |
size_req_args, size_tags, 1); |
size_req_args, size_tag_groups, 1); |
363 |
sieve_register_test ("envelope", sieve_test_envelope, |
sieve_register_test ("envelope", sieve_test_envelope, |
364 |
address_req_args, envelope_tags, 1); |
address_req_args, envelope_tag_groups, 1); |
365 |
sieve_register_test ("exists", sieve_test_exists, |
sieve_register_test ("exists", sieve_test_exists, |
366 |
exists_req_args, NULL, 1); |
exists_req_args, NULL, 1); |
367 |
sieve_register_test ("header", sieve_test_header, |
sieve_register_test ("header", sieve_test_header, |
368 |
address_req_args, header_tags, 1); |
address_req_args, header_tag_groups, 1); |
369 |
} |
} |