/* 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; }
/* Produce diagnostic output. */ static int diag (mu_sieve_machine_t mach) { if (mu_sieve_get_debug_level (mach) & MU_SIEVE_DEBUG_TRACE) { mu_sieve_debug (mach, "VACATION"); } mu_sieve_log_action (mach, "VACATION", NULL); return mu_sieve_is_dry_run (mach); }
int sieve_run (mu_sieve_machine_t mach) { if (setjmp (mach->errbuf)) return 1; mach->action_count = 0; for (mach->pc = 1; mach->prog[mach->pc].handler; ) (*mach->prog[mach->pc++].instr) (mach); if (mach->action_count == 0) mu_sieve_log_action (mach, "IMPLICIT KEEP", NULL); if (INSTR_DEBUG (mach)) mu_sieve_debug (mach, "%4lu: STOP\n", (unsigned long) mach->pc); return 0; }
static int moderator_action (mu_sieve_machine_t mach, mu_list_t args, mu_list_t tags) { mu_message_t msg, orig; int rc; size_t nparts = 0; int discard = 0; int ismime; if (mu_sieve_get_debug_level (mach) & MU_SIEVE_DEBUG_TRACE) { mu_sieve_debug (mach, "moderator_test %lu", (unsigned long) mu_sieve_get_message_num (mach)); } msg = mu_sieve_get_message (mach); mu_message_is_multipart (msg, &ismime); if (!ismime) { mu_sieve_error (mach, _("message is not multipart")); mu_sieve_abort (mach); } mu_message_get_num_parts (msg, &nparts); if (nparts != 3) /* Mailman moderation requests have three parts */ { mu_sieve_error (mach, _("expected 3 parts, but found %lu"), (unsigned long) nparts); mu_sieve_abort (mach); } if ((rc = moderator_message_get_part (mach, msg, 2, &orig))) mu_sieve_abort (mach); rc = moderator_filter_message (mach, tags, orig, &discard); mu_message_unref (orig); if (rc) mu_sieve_abort (mach); if (discard && !mu_sieve_is_dry_run (mach)) { mu_message_t request; char *from = NULL; mu_sieve_value_t *arg; if ((rc = moderator_message_get_part (mach, msg, 3, &request))) { mu_sieve_error (mach, _("cannot get message part #3: %s"), mu_strerror (rc)); mu_sieve_abort (mach); } if (mu_sieve_tag_lookup (tags, "address", &arg)) from = arg->v.string; if (moderator_discard_message (mach, request, from)) discard = 0; else { if (!mu_sieve_tag_lookup (tags, "keep", NULL)) { mu_attribute_t attr = 0; if (mu_message_get_attribute (msg, &attr) == 0) mu_attribute_set_deleted (attr); } else discard = 0; } mu_message_unref (request); } mu_sieve_log_action (mach, "MODERATOR", discard ? _("discarding message") : _("keeping message")); 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)) { mu_sieve_error (mach, "%lu: %s", (unsigned long) mu_sieve_get_message_num (mach), _("cannot get list item")); mu_sieve_abort (mach); } mu_sieve_log_action (mach, "DELETEHEADER", "%s: (regexp)", field_name); break; case SVT_STRING: field_pattern = val->v.string; mu_sieve_log_action (mach, "DELETEHEADER", "%s: %s", field_name, field_pattern); break; default: mu_sieve_error (mach, "%lu: %s: %d", (unsigned long) mu_sieve_get_message_num (mach), _("unexpected value type"), val->type); mu_sieve_abort (mach); } } 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); } mu_header_get_iterator (hdr, &itr); if (mu_sieve_tag_lookup (tags, "last", NULL)) { int backwards = 1; mu_iterator_ctl (itr, mu_itrctl_set_direction, &backwards); } comp = mu_sieve_get_comparator (mach, tags); if (mu_sieve_tag_lookup (tags, "index", &val)) idx = val->v.number; for (i = 0, mu_iterator_first (itr); !mu_iterator_is_done (itr); mu_iterator_next (itr)) { const char *fn, *fv; mu_iterator_current_kv (itr, (const void **)&fn, (void **)&fv); if (strcmp (field_name, fn)) continue; if (idx && ++i < idx) continue; if (field_pattern) { if (comp (field_pattern, fv)) mu_iterator_ctl (itr, mu_itrctl_delete, NULL); } else mu_iterator_ctl (itr, mu_itrctl_delete, NULL); if (idx) break; } mu_iterator_destroy (&itr); return 0; }