diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2012-11-12 19:59:26 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2012-11-12 20:17:19 +0200 |
commit | 6fad8e1734a83c273f6283436775a6548f9c941f (patch) | |
tree | 1816552b9058bda515d6e521fd16ef2cbd95332d | |
parent | a7a174d51ca7845f9eda854709258d64e5d0077e (diff) | |
download | mailutils-6fad8e1734a83c273f6283436775a6548f9c941f.tar.gz mailutils-6fad8e1734a83c273f6283436775a6548f9c941f.tar.bz2 |
Implement editheader sieve extension (RFC 5293).
Also fix iterator synchronization after removing an element and
improve Sieve API.
* include/mailutils/header.h (mu_header_get_itemptr): New proto.
* include/mailutils/iterator.h (mu_iterator_advance): Remove.
(mu_iterator_delitem): New proto.
(mu_iterator_set_delitem): New proto.
* include/mailutils/sieve.h (mu_sieve_register_t) <opt_args>: New member.
(mu_sieve_register_test_ext)
(mu_sieve_register_action_ext): New protos.
* include/mailutils/sys/iterator.h (_mu_iterator) <curitem_p>: Remove.
<delitem>: New member. All uses updated.
* libmailutils/base/iterator.c (mu_iterator_set_delitem): New function.
* libmailutils/mailbox/hdritr.c: Implement bidirectional iteration.
Implement itrctl method.
* libmailutils/mailbox/header.c: Likewise.
* libmailutils/base/assoc.c: Use delitem method instead of curitem_p.
(mu_iterator_delitem): New function.
* libmailutils/base/opool.c
* libmailutils/diag/debug.c
* libmailutils/list/iterator.c
* libmailutils/list/pop.c
* libmailutils/list/remove.c
* libmailutils/list/removenth.c
* libmailutils/mailbox/imapenv.c
* libmailutils/mailbox/mbxitr.c
* libproto/pop/pop3_iterator.c
* libmu_sieve/extensions/Makefile.am: Add editheader.c
* libmu_sieve/extensions/editheader.c: New file.
* libmu_sieve/prog.c (mu_sv_code_command): Allow for optional positional
arguments.
* libmu_sieve/register.c (mu_sieve_test_lookup)
(mu_sieve_action_lookup): Return NULL if a record with
empty (NULL) handler is found.
(mu_sieve_register_test_ext)
(mu_sieve_register_action_ext): New functions.
(mu_sieve_register_test)
(mu_sieve_register_action): Rewrite as wrappers to the above.
* libmu_sieve/util.c (mu_sieve_vlist_do): Allow for SVT_STRING
argument.
* sieve/tests/Makefile.am: Add new testcases.
* sieve/tests/testsuite.at: Include new testcases.
* sieve/tests/addheader.at: New testcase.
* sieve/tests/delheader.at: New testcase.
* NEWS: Update.
* doc/rfc/README: Update.
28 files changed, 870 insertions, 80 deletions
@@ -1,4 +1,4 @@ -GNU mailutils NEWS -- history of user-visible changes. 2012-08-07 +GNU mailutils NEWS -- history of user-visible changes. 2012-11-12 Copyright (C) 2002-2012 Free Software Foundation, Inc. See the end of file for copying conditions. @@ -114,6 +114,10 @@ header field with the given date. See <http://mailutils.org/wiki/Timestamp_(Sieve_test)>. +Implemented the Editheader extension: `addheader' and `delheader' actions. + +See <http://tools.ietf.org/html/rfc5293>. + ** mail: sending attachments The mail[x] utility now allows for sending attachments. Any number of diff --git a/doc/rfc/README b/doc/rfc/README index 38d0abbef..593ec69b0 100644 --- a/doc/rfc/README +++ b/doc/rfc/README @@ -53,3 +53,4 @@ the actual RFC number. 3501 INTERNET MESSAGE ACCESS PROTOCOL - VERSION 4rev1 3691 Internet Message Access Protocol (IMAP) UNSELECT command 4314 IMAP4 Access Control List (ACL) Extension +5293 Sieve Email Filtering: Editheader Extension diff --git a/include/mailutils/header.h b/include/mailutils/header.h index 8e50cb601..079f679d9 100644 --- a/include/mailutils/header.h +++ b/include/mailutils/header.h @@ -169,6 +169,8 @@ extern int mu_header_set_fill (mu_header_t, int (*_fill) (void *data, char **, size_t *), void *data); +extern int mu_header_get_itemptr (mu_header_t header, size_t num, + const void **sptr); #ifdef __cplusplus } diff --git a/include/mailutils/iterator.h b/include/mailutils/iterator.h index 84d469f96..867f77537 100644 --- a/include/mailutils/iterator.h +++ b/include/mailutils/iterator.h @@ -37,7 +37,7 @@ enum mu_itrctl_req mu_itrctl_qry_direction, /* Query iteration direction */ mu_itrctl_set_direction /* Set iteration direction */ }; - + extern int mu_iterator_create (mu_iterator_t *, void *); extern int mu_iterator_dup (mu_iterator_t *piterator, mu_iterator_t orig); extern void mu_iterator_destroy (mu_iterator_t *); @@ -53,7 +53,7 @@ extern int mu_iterator_ctl (mu_iterator_t, enum mu_itrctl_req, void *); extern int mu_iterator_attach (mu_iterator_t *root, mu_iterator_t iterator); extern int mu_iterator_detach (mu_iterator_t *root, mu_iterator_t iterator); -extern void mu_iterator_advance (mu_iterator_t iterator, void *e); +extern void mu_iterator_delitem (mu_iterator_t iterator, void *e); extern int mu_iterator_set_first (mu_iterator_t, int (*first) (void *)); extern int mu_iterator_set_next (mu_iterator_t, int (*next) (void *)); @@ -66,8 +66,13 @@ extern int mu_iterator_set_dup (mu_iterator_t itr, int (*dup) (void **ptr, void *data)); extern int mu_iterator_set_destroy (mu_iterator_t itr, int (*destroy) (mu_iterator_t, void *data)); -extern int mu_iterator_set_curitem_p (mu_iterator_t itr, - int (*curitem_p) (void *, void *)); + +#define MU_ITR_DELITEM_NOTHING 0 +#define MU_ITR_DELITEM_NEXT 1 +#define MU_ITR_DELITEM_ADVANCE 2 + +extern int mu_iterator_set_delitem (mu_iterator_t itr, + int (*delitem) (void *, void *)); extern int mu_iterator_set_itrctl (mu_iterator_t itr, int (*itrctl) (void *, enum mu_itrctl_req, diff --git a/include/mailutils/sieve.h b/include/mailutils/sieve.h index f9ef9dbf6..ffe5db347 100644 --- a/include/mailutils/sieve.h +++ b/include/mailutils/sieve.h @@ -100,6 +100,7 @@ typedef struct int required; mu_sieve_handler_t handler; mu_sieve_data_type *req_args; + mu_sieve_data_type *opt_args; mu_sieve_tag_group_t *tags; } mu_sieve_register_t; @@ -146,10 +147,21 @@ mu_sieve_register_t *mu_sieve_test_lookup (mu_sieve_machine_t mach, const char *name); mu_sieve_register_t *mu_sieve_action_lookup (mu_sieve_machine_t mach, const char *name); +int mu_sieve_register_test_ext (mu_sieve_machine_t mach, + const char *name, mu_sieve_handler_t handler, + mu_sieve_data_type *req_args, + mu_sieve_data_type *opt_args, + mu_sieve_tag_group_t *tags, int required); int mu_sieve_register_test (mu_sieve_machine_t mach, const char *name, mu_sieve_handler_t handler, mu_sieve_data_type * arg_types, mu_sieve_tag_group_t * tags, int required); + +int mu_sieve_register_action_ext (mu_sieve_machine_t mach, + const char *name, mu_sieve_handler_t handler, + mu_sieve_data_type *req_args, + mu_sieve_data_type *opt_args, + mu_sieve_tag_group_t *tags, int required); int mu_sieve_register_action (mu_sieve_machine_t mach, const char *name, mu_sieve_handler_t handler, mu_sieve_data_type * arg_types, diff --git a/include/mailutils/sys/iterator.h b/include/mailutils/sys/iterator.h index 73a4926f5..7f007afe3 100644 --- a/include/mailutils/sys/iterator.h +++ b/include/mailutils/sys/iterator.h @@ -36,7 +36,7 @@ struct _mu_iterator int (*first) (void *owner); int (*next) (void *owner); int (*getitem) (void *owner, void **pret, const void **pkey); - int (*curitem_p) (void *owner, void *item); + int (*delitem) (void *owner, void *item); int (*finished_p) (void *owner); int (*itrctl) (void *owner, enum mu_itrctl_req req, void *arg); void *(*dataptr) (void *); diff --git a/libmailutils/base/assoc.c b/libmailutils/base/assoc.c index c34b6af0f..ecef8a320 100644 --- a/libmailutils/base/assoc.c +++ b/libmailutils/base/assoc.c @@ -452,13 +452,13 @@ destroy (mu_iterator_t iterator, void *data) } static int -curitem_p (void *owner, void *item) +delitem (void *owner, void *item) { struct assoc_iterator *itr = owner; mu_assoc_t assoc = itr->assoc; struct _mu_assoc_elem *elem = ASSOC_ELEM (assoc, itr->index); - return elem == item; + return elem == item ? MU_ITR_DELITEM_NEXT : MU_ITR_DELITEM_NOTHING; } static int @@ -498,7 +498,7 @@ mu_assoc_get_iterator (mu_assoc_t assoc, mu_iterator_t *piterator) mu_iterator_set_next (iterator, next); mu_iterator_set_getitem (iterator, getitem); mu_iterator_set_finished_p (iterator, finished_p); - mu_iterator_set_curitem_p (iterator, curitem_p); + mu_iterator_set_delitem (iterator, delitem); mu_iterator_set_destroy (iterator, destroy); mu_iterator_set_dup (iterator, assoc_data_dup); diff --git a/libmailutils/base/iterator.c b/libmailutils/base/iterator.c index 8e88c68ca..118de726b 100644 --- a/libmailutils/base/iterator.c +++ b/libmailutils/base/iterator.c @@ -81,12 +81,12 @@ mu_iterator_set_finished_p (mu_iterator_t itr, int (*finished_p) (void *)) } int -mu_iterator_set_curitem_p (mu_iterator_t itr, - int (*curitem_p) (void *, void *)) +mu_iterator_set_delitem (mu_iterator_t itr, + int (*delitem) (void *, void *)) { if (!itr) return EINVAL; - itr->curitem_p = curitem_p; + itr->delitem = delitem; return 0; } @@ -158,7 +158,7 @@ mu_iterator_dup (mu_iterator_t *piterator, mu_iterator_t orig) iterator->first = orig->first; iterator->next = orig->next; iterator->getitem = orig->getitem; - iterator->curitem_p = orig->curitem_p; + iterator->delitem = orig->delitem; iterator->finished_p = orig->finished_p; iterator->itrctl = orig->itrctl; @@ -250,14 +250,19 @@ iterator_get_owner (mu_iterator_t iterator, void **powner) } void -mu_iterator_advance (mu_iterator_t iterator, void *e) +mu_iterator_delitem (mu_iterator_t iterator, void *itm) { for (; iterator; iterator = iterator->next_itr) { - if (iterator->curitem_p (iterator->owner, e)) + if (iterator->delitem) { - iterator->next (iterator->owner); - iterator->is_advanced++; + switch (iterator->delitem (iterator->owner, itm)) + { + case MU_ITR_DELITEM_NEXT: + iterator->next (iterator->owner); + case MU_ITR_DELITEM_ADVANCE: + iterator->is_advanced++; + } } } } diff --git a/libmailutils/base/opool.c b/libmailutils/base/opool.c index 51c8e91e0..00a65824b 100644 --- a/libmailutils/base/opool.c +++ b/libmailutils/base/opool.c @@ -384,10 +384,11 @@ opitr_finished_p (void *owner) } static int -opitr_curitem_p (void *owner, void *item) +opitr_delitem (void *owner, void *item) { struct opool_iterator *itr = owner; - return itr->cur && itr->cur->buf == item; + return (itr->cur && itr->cur->buf == item) ? + MU_ITR_DELITEM_NEXT : MU_ITR_DELITEM_NOTHING; } static int @@ -446,7 +447,7 @@ mu_opool_get_iterator (mu_opool_t opool, mu_iterator_t *piterator) mu_iterator_set_next (iterator, opitr_next); mu_iterator_set_getitem (iterator, opitr_getitem); mu_iterator_set_finished_p (iterator, opitr_finished_p); - mu_iterator_set_curitem_p (iterator, opitr_curitem_p); + mu_iterator_set_delitem (iterator, opitr_delitem); mu_iterator_set_destroy (iterator, opitr_destroy); mu_iterator_set_dup (iterator, opitr_data_dup); diff --git a/libmailutils/diag/debug.c b/libmailutils/diag/debug.c index 897062cfe..d9b5178b8 100644 --- a/libmailutils/diag/debug.c +++ b/libmailutils/diag/debug.c @@ -572,10 +572,11 @@ finished_p (void *owner) } static int -curitem_p (void *owner, void *item) +delitem (void *owner, void *item) { struct debug_iterator *itr = owner; - return mu_c_strcasecmp (cattab[itr->pos].name, (char *) item) == 0; + return mu_c_strcasecmp (cattab[itr->pos].name, (char *) item) == 0 ? + MU_ITR_DELITEM_NEXT : MU_ITR_DELITEM_NOTHING; } static int @@ -659,7 +660,7 @@ mu_debug_get_iterator (mu_iterator_t *piterator, int skipunset) mu_iterator_set_next (iterator, next); mu_iterator_set_getitem (iterator, getitem); mu_iterator_set_finished_p (iterator, finished_p); - mu_iterator_set_curitem_p (iterator, curitem_p); + mu_iterator_set_delitem (iterator, delitem); mu_iterator_set_dup (iterator, list_data_dup); mu_iterator_set_itrctl (iterator, list_itrctl); diff --git a/libmailutils/list/iterator.c b/libmailutils/list/iterator.c index 26cc364e0..f517a8093 100644 --- a/libmailutils/list/iterator.c +++ b/libmailutils/list/iterator.c @@ -84,10 +84,10 @@ destroy (mu_iterator_t iterator, void *data) } static int -curitem_p (void *owner, void *item) +delitem (void *owner, void *item) { struct list_iterator *itr = owner; - return itr->cur == item; + return itr->cur == item ? MU_ITR_DELITEM_NEXT : MU_ITR_DELITEM_NOTHING; } static int @@ -142,7 +142,7 @@ list_itrctl (void *owner, enum mu_itrctl_req req, void *arg) ptr = itr->cur; prev = ptr->prev; - mu_iterator_advance (list->itr, ptr); + mu_iterator_delitem (list->itr, ptr); prev->next = ptr->next; ptr->next->prev = prev; if (req == mu_itrctl_delete) @@ -238,7 +238,7 @@ mu_list_get_iterator (mu_list_t list, mu_iterator_t *piterator) mu_iterator_set_next (iterator, next); mu_iterator_set_getitem (iterator, getitem); mu_iterator_set_finished_p (iterator, finished_p); - mu_iterator_set_curitem_p (iterator, curitem_p); + mu_iterator_set_delitem (iterator, delitem); mu_iterator_set_destroy (iterator, destroy); mu_iterator_set_dup (iterator, list_data_dup); mu_iterator_set_itrctl (iterator, list_itrctl); diff --git a/libmailutils/list/pop.c b/libmailutils/list/pop.c index c25c2aed8..6a504eb73 100644 --- a/libmailutils/list/pop.c +++ b/libmailutils/list/pop.c @@ -35,7 +35,7 @@ mu_list_pop (mu_list_t list, void **item) last = list->head.prev; prev = last->prev; - mu_iterator_advance (list->itr, last); + mu_iterator_delitem (list->itr, last); prev->next = last->next; prev->next->prev = prev; if (item) diff --git a/libmailutils/list/remove.c b/libmailutils/list/remove.c index 5ebd31235..f56340390 100644 --- a/libmailutils/list/remove.c +++ b/libmailutils/list/remove.c @@ -41,7 +41,7 @@ mu_list_remove (mu_list_t list, void *item) { struct list_data *previous = current->prev; - mu_iterator_advance (list->itr, current); + mu_iterator_delitem (list->itr, current); previous->next = current->next; current->next->prev = previous; DESTROY_ITEM (list, current); diff --git a/libmailutils/list/removenth.c b/libmailutils/list/removenth.c index 80550eeb7..f589b51e1 100644 --- a/libmailutils/list/removenth.c +++ b/libmailutils/list/removenth.c @@ -26,7 +26,6 @@ int mu_list_remove_nth (mu_list_t list, size_t n) { struct list_data *current; - mu_list_comparator_t comp; int status = MU_ERR_NOENT; size_t i; @@ -42,7 +41,7 @@ mu_list_remove_nth (mu_list_t list, size_t n) { struct list_data *previous = current->prev; - mu_iterator_advance (list->itr, current); + mu_iterator_delitem (list->itr, current); previous->next = current->next; current->next->prev = previous; DESTROY_ITEM (list, current); diff --git a/libmailutils/mailbox/hdritr.c b/libmailutils/mailbox/hdritr.c index a2504d5fb..d516b7259 100644 --- a/libmailutils/mailbox/hdritr.c +++ b/libmailutils/mailbox/hdritr.c @@ -30,13 +30,20 @@ struct header_iterator { mu_header_t header; size_t index; + int backwards; }; static int hdr_first (void *owner) { struct header_iterator *itr = owner; - itr->index = 1; + if (itr->backwards) + { + if (mu_header_get_field_count (itr->header, &itr->index)) + return 1; + } + else + itr->index = 1; return 0; } @@ -44,7 +51,13 @@ static int hdr_next (void *owner) { struct header_iterator *itr = owner; - itr->index++; + if (itr->backwards) + { + if (itr->index != 0) + itr->index--; + } + else + itr->index++; return 0; } @@ -58,16 +71,16 @@ hdr_getitem (void *owner, void **pret, const void **pkey) rc = mu_header_get_field_count (itr->header, &count); if (rc) return rc; - if (itr->index > count) + if (itr->index < 1 || itr->index > count) return MU_ERR_NOENT; - rc = mu_header_sget_field_name (itr->header, itr->index, - (const char**) pkey); + rc = mu_header_sget_field_value (itr->header, itr->index, + (const char**) pret); if (rc == 0) { if (pkey) - rc = mu_header_sget_field_value (itr->header, itr->index, - (const char**) pret); + rc = mu_header_sget_field_name (itr->header, itr->index, + (const char**) pkey); } return rc; } @@ -78,6 +91,9 @@ hdr_finished_p (void *owner) struct header_iterator *itr = owner; size_t count; + if (itr->backwards) + return itr->index < 1; + if (mu_header_get_field_count (itr->header, &count)) return 1; return itr->index > count; @@ -93,13 +109,16 @@ hdr_destroy (mu_iterator_t iterator, void *data) } static int -hdr_curitem_p (void *owner, void *item) +hdr_delitem (void *owner, void *item) { - void *ptr; + struct header_iterator *itr = owner; + const void *ptr; - if (hdr_getitem (owner, &ptr, NULL)) - return 0; - return ptr == item; + if (mu_header_get_itemptr (itr->header, itr->index, &ptr)) + return MU_ITR_DELITEM_NOTHING; + if (ptr == item && !itr->backwards) + return MU_ITR_DELITEM_ADVANCE; + return MU_ITR_DELITEM_NOTHING; } static int @@ -115,6 +134,51 @@ hdr_data_dup (void **ptr, void *owner) return 0; } +static int +hdr_itrctl (void *owner, enum mu_itrctl_req req, void *arg) +{ + struct header_iterator *itr = owner; + + switch (req) + { + case mu_itrctl_tell: + /* Return current position in the object */ + if (hdr_finished_p (owner)) + return MU_ERR_NOENT; + else + *(size_t*)arg = itr->index; + return 0; + break; + + case mu_itrctl_delete: + /* Delete current element */ + if (hdr_finished_p (owner)) + return MU_ERR_NOENT; + else + return mu_header_remove (itr->header, NULL, itr->index); + break; + + case mu_itrctl_qry_direction: + if (!arg) + return EINVAL; + else + *(int*)arg = itr->backwards; + break; + + case mu_itrctl_set_direction: + if (!arg) + return EINVAL; + else + itr->backwards = !!*(int*)arg; + break; + + default: + return ENOSYS; + } + return 0; +} + + int mu_header_get_iterator (mu_header_t hdr, mu_iterator_t *piterator) { @@ -142,9 +206,10 @@ mu_header_get_iterator (mu_header_t hdr, mu_iterator_t *piterator) mu_iterator_set_next (iterator, hdr_next); mu_iterator_set_getitem (iterator, hdr_getitem); mu_iterator_set_finished_p (iterator, hdr_finished_p); - mu_iterator_set_curitem_p (iterator, hdr_curitem_p); + mu_iterator_set_delitem (iterator, hdr_delitem); mu_iterator_set_destroy (iterator, hdr_destroy); mu_iterator_set_dup (iterator, hdr_data_dup); + mu_iterator_set_itrctl (iterator, hdr_itrctl); mu_iterator_attach (&hdr->itr, iterator); diff --git a/libmailutils/mailbox/header.c b/libmailutils/mailbox/header.c index 1c7642183..2745963b9 100644 --- a/libmailutils/mailbox/header.c +++ b/libmailutils/mailbox/header.c @@ -80,13 +80,15 @@ mu_hdrent_find (struct _mu_header *hdr, const char *name, int pos) if (pos > 0) { for (p = hdr->head; p; p = p->next) - if (mu_c_strcasecmp (MU_HDRENT_NAME (hdr,p), name) == 0 && pos-- == 1) + if ((!name || mu_c_strcasecmp (MU_HDRENT_NAME (hdr,p), name) == 0) && + pos-- == 1) break; } else if (pos < 0) { for (p = hdr->tail; p; p = p->prev) - if (mu_c_strcasecmp (MU_HDRENT_NAME (hdr,p), name) == 0 && ++pos == 0) + if ((!name || mu_c_strcasecmp (MU_HDRENT_NAME (hdr,p), name) == 0) && + ++pos == 0) break; } else @@ -544,7 +546,7 @@ mu_header_remove (mu_header_t header, const char *fn, int n) int status; struct mu_hdrent *ent; - if (header == NULL || fn == NULL) + if (header == NULL) return EINVAL; status = mu_header_fill (header); @@ -555,6 +557,7 @@ mu_header_remove (mu_header_t header, const char *fn, int n) if (!ent) return MU_ERR_NOENT; + mu_iterator_delitem (header->itr, ent); mu_hdrent_remove (header, ent); HEADER_SET_MODIFIED (header); free (ent); @@ -782,6 +785,26 @@ mu_header_get_field_count (mu_header_t header, size_t *pcount) } int +mu_header_get_itemptr (mu_header_t header, size_t num, const void **sptr) +{ + int status; + + if (header == NULL) + return EINVAL; + + status = mu_header_fill (header); + if (status == 0) + { + struct mu_hdrent *ent = mu_hdrent_nth (header, num); + if (ent) + *sptr = ent; + else + status = MU_ERR_NOENT; + } + return status; +} + +int mu_header_sget_field_name (mu_header_t header, size_t num, const char **sptr) { int status; diff --git a/libmailutils/mailbox/imapenv.c b/libmailutils/mailbox/imapenv.c index 847a6f762..aa8a865af 100644 --- a/libmailutils/mailbox/imapenv.c +++ b/libmailutils/mailbox/imapenv.c @@ -52,7 +52,7 @@ mu_message_get_imapenvelope (mu_message_t msg, struct mu_imapenvelope **pimapenv if (msg == NULL) return EINVAL; - if (imapenvelope == NULL) + if (pimapenvelope == NULL) return MU_ERR_OUT_PTR_NULL; if (msg->_imapenvelope) return msg->_imapenvelope (msg, pimapenvelope); diff --git a/libmailutils/mailbox/mbxitr.c b/libmailutils/mailbox/mbxitr.c index 72c7a7dfb..0ea8856aa 100644 --- a/libmailutils/mailbox/mbxitr.c +++ b/libmailutils/mailbox/mbxitr.c @@ -111,13 +111,14 @@ mbx_destroy (mu_iterator_t iterator, void *data) } static int -mbx_curitem_p (void *owner, void *item) +mbx_delitem (void *owner, void *item) { void *ptr; if (mbx_getitem (owner, &ptr, NULL)) return 0; - return ptr == item;/* FIXME: Is it ok? */ + return ptr == item ? MU_ITR_DELITEM_NEXT : MU_ITR_DELITEM_NOTHING; + /* FIXME: is it ok? */ } static int @@ -210,7 +211,7 @@ mu_mailbox_get_iterator (mu_mailbox_t mbx, mu_iterator_t *piterator) mu_iterator_set_next (iterator, mbx_next); mu_iterator_set_getitem (iterator, mbx_getitem); mu_iterator_set_finished_p (iterator, mbx_finished_p); - mu_iterator_set_curitem_p (iterator, mbx_curitem_p); + mu_iterator_set_delitem (iterator, mbx_delitem); mu_iterator_set_destroy (iterator, mbx_destroy); mu_iterator_set_dup (iterator, mbx_data_dup); mu_iterator_set_itrctl (iterator, mbx_itrctl); diff --git a/libmu_sieve/extensions/Makefile.am b/libmu_sieve/extensions/Makefile.am index 9ac82b175..d538ca6b1 100644 --- a/libmu_sieve/extensions/Makefile.am +++ b/libmu_sieve/extensions/Makefile.am @@ -16,6 +16,7 @@ moddir=@MU_SIEVE_MODDIR@ mod_LTLIBRARIES = \ + editheader.la\ list.la\ moderator.la\ pipe.la\ diff --git a/libmu_sieve/extensions/editheader.c b/libmu_sieve/extensions/editheader.c new file mode 100644 index 000000000..89ae6ea43 --- /dev/null +++ b/libmu_sieve/extensions/editheader.c @@ -0,0 +1,339 @@ +/* GNU Mailutils -- a suite of utilities for electronic mail + Copyright (C) 2012 Free Software Foundation, Inc. + + GNU Mailutils is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + GNU Mailutils is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with GNU Mailutils. If not, see + <http://www.gnu.org/licenses/>. */ + +/* This module implements the Editheader Extension (RFC 5293) */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <mailutils/types.h> +#include <mailutils/message.h> +#include <mailutils/header.h> +#include <mailutils/error.h> +#include <mailutils/errno.h> +#include <mailutils/sieve.h> + +/* Syntax: addheader [:last] <field-name: string> <value: string> + */ +int +sieve_addheader (mu_sieve_machine_t mach, mu_list_t args, mu_list_t tags) +{ + mu_sieve_value_t *val; + const char *field_name; + const char *field_value; + mu_message_t msg; + mu_header_t hdr; + int rc; + + val = mu_sieve_value_get (args, 0); + if (!val) + { + mu_sieve_error (mach, "%lu: %s", + (unsigned long) mu_sieve_get_message_num (mach), + _("cannot get field name")); + mu_sieve_abort (mach); + } + field_name = val->v.string; + + val = mu_sieve_value_get (args, 1); + if (!val) + { + mu_sieve_error (mach, "%lu: %s", + (unsigned long) mu_sieve_get_message_num (mach), + _("cannot get field value")); + mu_sieve_abort (mach); + } + field_value = val->v.string; + + mu_sieve_log_action (mach, "ADDHEADER", "%s: %s", field_name, field_value); + + if (mu_sieve_is_dry_run (mach)) + return 0; + + msg = mu_sieve_get_message (mach); + rc = mu_message_get_header (msg, &hdr); + if (rc) + { + mu_sieve_error (mach, "%lu: %s: %s", + (unsigned long) mu_sieve_get_message_num (mach), + _("cannot get message header"), + mu_strerror (rc)); + mu_sieve_abort (mach); + } + + rc = (mu_sieve_tag_lookup (tags, "last", NULL) ? + mu_header_append : mu_header_prepend) (hdr, field_name, field_value); + if (rc) + { + mu_sieve_error (mach, "%lu: %s: %s", + (unsigned long) mu_sieve_get_message_num (mach), + _("cannot append message header"), + mu_strerror (rc)); + mu_sieve_abort (mach); + } + return 0; +} + +/* Syntax: deleteheader [:index <fieldno: number> [:last]] + [COMPARATOR] [MATCH-TYPE] + <field-name: string> + [<value-patterns: string-list>] + */ +int +sieve_deleteheader (mu_sieve_machine_t mach, mu_list_t args, mu_list_t tags) +{ + mu_sieve_value_t *val; + const char *field_name; + const char *field_pattern; + mu_message_t msg; + mu_header_t hdr; + int rc; + mu_sieve_comparator_t comp; + mu_iterator_t itr; + unsigned long i, idx = 0; + + val = mu_sieve_value_get (args, 0); + if (!val) + { + mu_sieve_error (mach, "%lu: %s", + (unsigned long) mu_sieve_get_message_num (mach), + _("cannot get field name")); + mu_sieve_abort (mach); + } + field_name = val->v.string; + + val = mu_sieve_value_get (args, 1); + if (!val) + { + field_pattern = NULL; + mu_sieve_log_action (mach, "DELETEHEADER", "%s", field_name); + } + else + { + switch (val->type) + { + case SVT_STRING_LIST: + if (mu_list_get (val->v.list, 0, (void**)&field_pattern)) |