summaryrefslogtreecommitdiff
path: root/libsieve/tests.c
diff options
context:
space:
mode:
Diffstat (limited to 'libsieve/tests.c')
-rw-r--r--libsieve/tests.c227
1 files changed, 188 insertions, 39 deletions
diff --git a/libsieve/tests.c b/libsieve/tests.c
index 16b9311c9..455401fe8 100644
--- a/libsieve/tests.c
+++ b/libsieve/tests.c
@@ -25,16 +25,103 @@
#include <string.h>
#include <sieve.h>
+typedef int (*address_aget_t) __PMT ((address_t addr, size_t no, char **buf));
+
+int
+_get_address_part (void *item, void *data)
+{
+ sieve_runtime_tag_t *t = item;
+ address_aget_t ret;
+
+ if (strcmp (t->tag, "all") == 0)
+ ret = address_aget_email;
+ else if (strcmp (t->tag, "domain") == 0)
+ ret = address_aget_domain;
+ else if (strcmp (t->tag, "localpart") == 0)
+ ret = address_aget_local_part;
+ *(address_aget_t*)data = ret;
+ return ret != NULL;
+}
+
+address_aget_t
+sieve_get_address_part (list_t tags)
+{
+ address_aget_t ret = address_aget_email;
+ list_do (tags, _get_address_part, &ret);
+ return ret;
+}
+
+/* Structure shared between address and envelope tests */
+struct address_closure
+{
+ address_aget_t aget; /* appropriate address_aget_ function */
+ void *data; /* Either header_t or envelope_t */
+ address_t addr; /* Obtained address */
+};
+
+int
+retrieve_address (void *item, void *data, int idx, char **pval)
+{
+ struct address_closure *ap = data;
+ char *val;
+ int rc;
+
+ if (!ap->addr)
+ {
+ if (header_aget_value ((header_t)ap->data, (char*)item, &val))
+ return 1;
+ rc = address_create (&ap->addr, val);
+ free (val);
+ if (rc)
+ return rc;
+ }
+
+ rc = ap->aget (ap->addr, idx+1, pval);
+ if (rc)
+ address_destroy (&ap->addr);
+ return rc;
+}
+
int
sieve_test_address (sieve_machine_t mach, list_t args, list_t tags)
{
- return 0;
+ sieve_value_t *h, *v;
+ header_t header = NULL;
+ sieve_comparator_t comp = sieve_get_comparator (tags);
+ struct address_closure clos;
+ int rc;
+
+ if (mach->debug_level & MU_SIEVE_DEBUG_TRACE)
+ sieve_debug (mach, "ADDRESS\n");
+
+ h = sieve_value_get (args, 0);
+ if (!h)
+ {
+ sieve_error (mach, "address: can't get argument 1");
+ sieve_abort (mach);
+ }
+ v = sieve_value_get (args, 1);
+ if (!v)
+ {
+ sieve_error (mach, "address: can't get argument 2");
+ sieve_abort (mach);
+ }
+
+ message_get_header (sieve_get_message (mach), &header);
+ clos.data = header;
+ clos.aget = sieve_get_address_part (tags);
+ clos.addr = NULL;
+ rc = sieve_vlist_compare (h, v, comp, retrieve_address, &clos);
+ address_destroy (&clos.addr);
+ return rc;
}
int
-retrieve_header (void *item, void *data, char **pval)
+retrieve_header (void *item, void *data, int idx, char **pval)
{
- return header_aget_value ((header_t) data, (char*)item, pval);
+ if (idx == 0)
+ return header_aget_value ((header_t) data, (char*)item, pval);
+ return 1;
}
int
@@ -66,9 +153,63 @@ sieve_test_header (sieve_machine_t mach, list_t args, list_t tags)
}
int
+retrieve_envelope (void *item, void *data, int idx, char **pval)
+{
+ struct address_closure *ap = data;
+ int rc;
+
+ if (!ap->addr)
+ {
+ char buf[512];
+ size_t n;
+
+ if (strcasecmp ((char*)item, "from") != 0)
+ return 1;
+
+ if (envelope_sender ((envelope_t)ap->data, buf, sizeof(buf), &n))
+ return 1;
+
+ rc = address_create (&ap->addr, buf);
+ if (rc)
+ return rc;
+ }
+
+ rc = ap->aget (ap->addr, idx+1, pval);
+ if (rc)
+ address_destroy (&ap->addr);
+ return rc;
+}
+
+int
sieve_test_envelope (sieve_machine_t mach, list_t args, list_t tags)
{
- return 0;
+ sieve_value_t *h, *v;
+ sieve_comparator_t comp = sieve_get_comparator (tags);
+ struct address_closure clos;
+ int rc;
+
+ if (mach->debug_level & MU_SIEVE_DEBUG_TRACE)
+ sieve_debug (mach, "HEADER\n");
+
+ h = sieve_value_get (args, 0);
+ if (!h)
+ {
+ sieve_error (mach, "header: can't get argument 1");
+ sieve_abort (mach);
+ }
+ v = sieve_value_get (args, 1);
+ if (!v)
+ {
+ sieve_error (mach, "header: can't get argument 2");
+ sieve_abort (mach);
+ }
+
+ message_get_envelope (sieve_get_message (mach), (envelope_t*)&clos.data);
+ clos.aget = sieve_get_address_part (tags);
+ clos.addr = NULL;
+ rc = sieve_vlist_compare (h, v, comp, retrieve_envelope, &clos);
+ address_destroy (&clos.addr);
+ return rc;
}
int
@@ -89,9 +230,9 @@ sieve_test_size (sieve_machine_t mach, list_t args, list_t tags)
list_get (tags, 0, (void **)&tag);
if (!tag)
rc = size == val->v.number;
- else if (tag->tag == TAG_OVER)
+ else if (strcmp (tag->tag, "over") == 0)
rc = size > val->v.number;
- else if (tag->tag == TAG_UNDER)
+ else if (strcmp (tag->tag, "under") == 0)
rc = size < val->v.number;
return rc;
@@ -142,29 +283,39 @@ sieve_test_exists (sieve_machine_t mach, list_t args, list_t tags)
return sieve_vlist_do (val, _test_exists, header) == 0;
}
-#define ADDRESS_PART \
- { "localpart", TAG_LOCALPART, SVT_VOID },\
- { "domain", TAG_DOMAIN, SVT_VOID },\
- { "all", TAG_ALL, SVT_VOID }
+static sieve_tag_def_t address_part_tags[] = {
+ { "localpart", SVT_VOID },
+ { "domain", SVT_VOID },
+ { "all", SVT_VOID },
+ { NULL }
+};
+
+static sieve_tag_def_t match_part_tags[] = {
+ { "is", SVT_VOID },
+ { "contains", SVT_VOID },
+ { "matches", SVT_VOID },
+ { "regex", SVT_VOID },
+ { "comparator", SVT_STRING },
+ { NULL }
+};
-#define MATCH_PART \
- { "is", TAG_IS, SVT_VOID },\
- { "contains", TAG_CONTAINS, SVT_VOID },\
- { "matches", TAG_MATCHES, SVT_VOID },\
- { "regex", TAG_REGEX, SVT_VOID }
+static sieve_tag_def_t size_tags[] = {
+ { "over", SVT_VOID },
+ { "under", SVT_VOID },
+ { NULL }
+};
+
+#define ADDRESS_PART_GROUP \
+ { address_part_tags, NULL }
-#define COMP_PART \
- { "comparator", TAG_COMPARATOR, SVT_STRING }
+#define MATCH_PART_GROUP \
+ { match_part_tags, sieve_match_part_checker }
-#define SIZE_PART \
- { "under", TAG_UNDER, SVT_VOID },\
- { "over", TAG_OVER, SVT_VOID }
+#define SIZE_GROUP { size_tags, NULL }
-
-sieve_tag_def_t address_tags[] = {
- ADDRESS_PART,
- COMP_PART,
- MATCH_PART,
+sieve_tag_group_t address_tag_groups[] = {
+ ADDRESS_PART_GROUP,
+ MATCH_PART_GROUP,
{ NULL }
};
@@ -174,8 +325,8 @@ sieve_data_type address_req_args[] = {
SVT_VOID
};
-sieve_tag_def_t size_tags[] = {
- SIZE_PART,
+sieve_tag_group_t size_tag_groups[] = {
+ SIZE_GROUP,
{ NULL }
};
@@ -184,10 +335,9 @@ sieve_data_type size_req_args[] = {
SVT_VOID
};
-sieve_tag_def_t envelope_tags[] = {
- COMP_PART,
- ADDRESS_PART,
- MATCH_PART,
+sieve_tag_group_t envelope_tag_groups[] = {
+ ADDRESS_PART_GROUP,
+ MATCH_PART_GROUP,
{ NULL }
};
@@ -196,10 +346,9 @@ sieve_data_type exists_req_args[] = {
SVT_VOID
};
-sieve_tag_def_t header_tags[] = {
- COMP_PART,
- MATCH_PART,
- { NULL },
+sieve_tag_group_t header_tag_groups[] = {
+ MATCH_PART_GROUP,
+ { NULL }
};
void
@@ -208,13 +357,13 @@ sieve_register_standard_tests ()
sieve_register_test ("false", sieve_test_false, NULL, NULL, 1);
sieve_register_test ("true", sieve_test_true, NULL, NULL, 1);
sieve_register_test ("address", sieve_test_address,
- address_req_args, address_tags, 1);
+ address_req_args, address_tag_groups, 1);
sieve_register_test ("size", sieve_test_size,
- size_req_args, size_tags, 1);
+ size_req_args, size_tag_groups, 1);
sieve_register_test ("envelope", sieve_test_envelope,
- address_req_args, envelope_tags, 1);
+ address_req_args, envelope_tag_groups, 1);
sieve_register_test ("exists", sieve_test_exists,
exists_req_args, NULL, 1);
sieve_register_test ("header", sieve_test_header,
- address_req_args, header_tags, 1);
+ address_req_args, header_tag_groups, 1);
}

Return to:

Send suggestions and report system problems to the System administrator.