Commit 7cc7c42f 7cc7c42fc2fba3e9113438320ea4d78041ec44d7 by Sergey Poznyakoff

Sieve: "stdin" working mode.

* sieve/sieve.c: New working mode: if `-f -' is given, treat
stdin as an RFC2822 message, apply the script to it and exit with
1 if the message gets deleted, 0 if it is not and EX_SOFTWARE on
software errors.
In traditional mode, exit with standard sysexit codes.
* testsuite/sieve/i-numeric.exp: Reflect changes in sieve.
* NEWS: Update.
1 parent 23160352
2008-10-23 Sergey Poznyakoff <gray@gnu.org.ua>
* sieve/sieve.c: New working mode: if `-f -' is given, treat
stdin as an RFC2822 message, apply the script to it and exit with
1 if the message gets deleted, 0 if it is not and EX_SOFTWARE on
software errors.
In traditional mode, exit with standard sysexit codes.
* testsuite/sieve/i-numeric.exp: Reflect changes in sieve.
* NEWS: Update.
2008-10-19 Sergey Poznyakoff <gray@gnu.org.ua>
* auth/sql.c (decode_tuple): Use new tuple parsing mode, unless
......
GNU mailutils NEWS -- history of user-visible changes. 2008-10-16
GNU mailutils NEWS -- history of user-visible changes. 2008-10-23
Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007,
2008 Free Software Foundation, Inc.
See the end of file for copying conditions.
......@@ -474,6 +474,14 @@ from the available data.
New options `--bulletin-db' and `--bulletin-source' implement bulletin
facility.
* The `sieve' utility.
Exit codes conform to sysexits.h.
New working mode: if `-f -' is given, treat stdin as an RFC2822
message, apply the script to it and exit with 1 if the message gets
deleted, 0 if it is not and EX_SOFTWARE on software errors.
* MH changes
** sortm uses stable sort algorithm.
......
......@@ -30,6 +30,7 @@
#include <string.h>
#include <unistd.h>
#include <syslog.h>
#include <sysexits.h>
#include <mu_asprintf.h>
#include <mailutils/argcv.h>
......@@ -366,6 +367,146 @@ _sieve_action_log (void *unused,
mu_debug_set_locus (debug, NULL, 0);
}
static int
sieve_message (mu_sieve_machine_t mach)
{
int rc;
mu_stream_t instr;
mu_message_t msg;
mu_attribute_t attr;
rc = mu_stdio_stream_create (&instr, stdin, 0);
if (rc)
{
mu_error (_("Cannot create stream: %s"), mu_strerror (rc));
return EX_SOFTWARE;
}
rc = mu_stream_open (instr);
if (rc)
{
mu_error (_("Cannot open stream: %s"), mu_strerror (rc));
return EX_SOFTWARE;
}
rc = mu_stream_to_message (instr, &msg);
if (rc)
{
mu_error (_("Cannot create message from stream: %s"),
mu_strerror (rc));
return EX_SOFTWARE;
}
mu_message_get_attribute (msg, &attr);
mu_attribute_unset_deleted (attr);
rc = mu_sieve_message (mach, msg);
if (rc)
/* FIXME: switch (rc)...*/
return EX_SOFTWARE;
return mu_attribute_is_deleted (attr) ? 1 : EX_OK;
}
static int
sieve_mailbox (mu_sieve_machine_t mach, mu_ticket_t ticket, mu_debug_t debug)
{
int rc;
mu_mailbox_t mbox = NULL;
/* Create, give a ticket to, and open the mailbox. */
if ((rc = mu_mailbox_create_default (&mbox, mbox_url)) != 0)
{
if (mbox)
mu_error (_("Could not create mailbox `%s': %s"),
mbox_url, mu_strerror (rc));
else
mu_error (_("Could not create default mailbox: %s"),
mu_strerror (rc));
goto cleanup;
}
if (debug && (rc = mu_mailbox_set_debug (mbox, debug)))
{
mu_error (_("mu_mailbox_set_debug failed: %s"), mu_strerror (rc));
goto cleanup;
}
if (ticket)
{
mu_folder_t folder = NULL;
mu_authority_t auth = NULL;
if ((rc = mu_mailbox_get_folder (mbox, &folder)))
{
mu_error (_("mu_mailbox_get_folder failed: %s"),
mu_strerror (rc));
goto cleanup;
}
if ((rc = mu_folder_get_authority (folder, &auth)))
{
mu_error (_("mu_folder_get_authority failed: %s"),
mu_strerror (rc));
goto cleanup;
}
/* Authentication-less folders don't have authorities. */
if (auth && (rc = mu_authority_set_ticket (auth, ticket)))
{
mu_error (_("mu_authority_set_ticket failed: %s"),
mu_strerror (rc));
goto cleanup;
}
}
/* Open the mailbox read-only if we aren't going to modify it. */
if (sieve_debug & MU_SIEVE_DRY_RUN)
rc = mu_mailbox_open (mbox, MU_STREAM_READ);
else
rc = mu_mailbox_open (mbox, MU_STREAM_RDWR);
if (rc != 0)
{
if (mbox)
mu_error (_("Opening mailbox `%s' failed: %s"),
mbox_url, mu_strerror (rc));
else
mu_error (_("Opening default mailbox failed: %s"),
mu_strerror (rc));
mu_mailbox_destroy (&mbox);
goto cleanup;
}
/* Process the mailbox */
rc = mu_sieve_mailbox (mach, mbox);
cleanup:
if (mbox && !(sieve_debug & MU_SIEVE_DRY_RUN))
{
int e;
/* A message won't be marked deleted unless the script executed
succesfully on it, so we always do an expunge, it will delete
any messages that were marked DELETED even if execution failed
on a later message. */
if ((e = mu_mailbox_expunge (mbox)) != 0)
{
if (mbox)
mu_error (_("Expunge on mailbox `%s' failed: %s"),
mbox_url, mu_strerror (e));
else
mu_error (_("Expunge on default mailbox failed: %s"),
mu_strerror (e));
}
if (e && !rc)
rc = e;
}
mu_sieve_machine_destroy (&mach);
mu_mailbox_close (mbox);
mu_mailbox_destroy (&mbox);
/* FIXME: switch (rc) ... */
return rc ? EX_SOFTWARE : EX_OK;
}
int
main (int argc, char *argv[])
{
......@@ -373,7 +514,6 @@ main (int argc, char *argv[])
mu_wicket_t wicket = 0;
mu_ticket_t ticket = 0;
mu_debug_t debug = 0;
mu_mailbox_t mbox = 0;
int rc;
/* Native Language Support */
......@@ -394,14 +534,14 @@ main (int argc, char *argv[])
if (mu_app_init (&argp, sieve_argp_capa, sieve_cfg_param,
argc, argv, ARGP_IN_ORDER, NULL, NULL))
exit (1);
exit (EX_USAGE);
/* Sieve interpreter setup. */
rc = mu_sieve_machine_init (&mach, NULL);
if (rc)
{
mu_error (_("Cannot initialize sieve machine: %s"), mu_strerror (rc));
return 1;
return EX_SOFTWARE;
}
if (mu_log_facility)
......@@ -419,14 +559,14 @@ main (int argc, char *argv[])
rc = mu_sieve_compile (mach, script);
if (rc)
return 1;
return EX_CONFIG;
/* We can finish if its only a compilation check. */
if (compile_only)
{
if (compile_only == 2)
mu_sieve_disass (mach);
return 0;
return EX_OK;
}
/* Create a ticket, if we can. */
......@@ -437,14 +577,14 @@ main (int argc, char *argv[])
if ((rc = mu_wicket_get_ticket (wicket, &ticket, 0, 0)) != 0)
{
mu_error (_("ticket_get failed: %s"), mu_strerror (rc));
goto cleanup;
return EX_SOFTWARE; /* FIXME: really? */
}
}
else if (!(tickets_default && errno == ENOENT))
{
mu_error (_("mu_wicket_create `%s' failed: %s"),
tickets, mu_strerror (rc));
goto cleanup;
return EX_SOFTWARE;
}
if (ticket)
mu_sieve_set_ticket (mach, ticket);
......@@ -456,114 +596,25 @@ main (int argc, char *argv[])
if ((rc = mu_debug_create (&debug, mach)))
{
mu_error (_("mu_debug_create failed: %s"), mu_strerror (rc));
goto cleanup;
return EX_SOFTWARE;
}
if ((rc = mu_debug_set_level (debug, debug_level)))
{
mu_error (_("mu_debug_set_level failed: %s"),
mu_strerror (rc));
goto cleanup;
return EX_SOFTWARE;
}
mu_sieve_set_debug_object (mach, debug);
}
mu_sieve_set_debug_level (mach, sieve_debug);
/* Create, give a ticket to, and open the mailbox. */
if ((rc = mu_mailbox_create_default (&mbox, mbox_url)) != 0)
{
if (mbox)
mu_error (_("Could not create mailbox `%s': %s"),
mbox_url, mu_strerror (rc));
else
mu_error (_("Could not create default mailbox: %s"),
mu_strerror (rc));
goto cleanup;
}
if (debug && (rc = mu_mailbox_set_debug (mbox, debug)))
{
mu_error (_("mu_mailbox_set_debug failed: %s"), mu_strerror (rc));
goto cleanup;
}
if (ticket)
{
mu_folder_t folder = NULL;
mu_authority_t auth = NULL;
if ((rc = mu_mailbox_get_folder (mbox, &folder)))
{
mu_error (_("mu_mailbox_get_folder failed: %s"),
mu_strerror (rc));
goto cleanup;
}
if ((rc = mu_folder_get_authority (folder, &auth)))
{
mu_error (_("mu_folder_get_authority failed: %s"),
mu_strerror (rc));
goto cleanup;
}
/* Authentication-less folders don't have authorities. */
if (auth && (rc = mu_authority_set_ticket (auth, ticket)))
{
mu_error (_("mu_authority_set_ticket failed: %s"),
mu_strerror (rc));
goto cleanup;
}
}
/* Open the mailbox read-only if we aren't going to modify it. */
if (sieve_debug & MU_SIEVE_DRY_RUN)
rc = mu_mailbox_open (mbox, MU_STREAM_READ);
if (mbox_url && strcmp (mbox_url, "-") == 0)
rc = sieve_message (mach);
else
rc = mu_mailbox_open (mbox, MU_STREAM_RDWR);
if (rc != 0)
{
if (mbox)
mu_error (_("Opening mailbox `%s' failed: %s"),
mbox_url, mu_strerror (rc));
else
mu_error (_("Opening default mailbox failed: %s"),
mu_strerror (rc));
mu_mailbox_destroy (&mbox);
goto cleanup;
}
/* Process the mailbox */
rc = mu_sieve_mailbox (mach, mbox);
cleanup:
if (mbox && !(sieve_debug & MU_SIEVE_DRY_RUN))
{
int e;
/* A message won't be marked deleted unless the script executed
succesfully on it, so we always do an expunge, it will delete
any messages that were marked DELETED even if execution failed
on a later message. */
if ((e = mu_mailbox_expunge (mbox)) != 0)
{
if (mbox)
mu_error (_("Expunge on mailbox `%s' failed: %s"),
mbox_url, mu_strerror (e));
else
mu_error (_("Expunge on default mailbox failed: %s"),
mu_strerror (e));
}
if (e && !rc)
rc = e;
}
mu_sieve_machine_destroy (&mach);
mu_mailbox_close (mbox);
mu_mailbox_destroy (&mbox);
rc = sieve_mailbox (mach, ticket, debug);
mu_debug_destroy (&debug, mach);
return rc ? 1 : 0;
return rc;
}
......
......@@ -22,7 +22,7 @@ sieve_test i-numeric-is.sv -pattern \
"DISCARD on msg uid 2: marking as deleted"\
"IMPLICIT KEEP on msg uid 3"
sieve_test i-numeric-contains.sv -retcode 1 -pattern \
sieve_test i-numeric-contains.sv -retcode 78 -pattern \
-re ".*i-numeric-contains.sv:9: comparator `i;ascii-numeric' is incompatible with match type `contains' in call to `header'"
# end of i-numeric.exp
......