diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2002-11-14 07:24:31 +0000 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2002-11-14 07:24:31 +0000 |
commit | 01b68a33835454728f5361079bb57019c4bca106 (patch) | |
tree | 418905a74fd1f9ba1966db0669e0b91e8fc5c5d3 | |
parent | 4518e810aa0886c561cdaf0bffc9dbd264306c43 (diff) | |
download | mailutils-01b68a33835454728f5361079bb57019c4bca106.tar.gz mailutils-01b68a33835454728f5361079bb57019c4bca106.tar.bz2 |
Use libsieve calls.
-rw-r--r-- | sieve/sieve.c | 265 |
1 files changed, 97 insertions, 168 deletions
diff --git a/sieve/sieve.c b/sieve/sieve.c index b453d0aa1..fb1331d83 100644 --- a/sieve/sieve.c +++ b/sieve/sieve.c @@ -15,12 +15,8 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* -sieve script interpreter. -*/ - #ifdef HAVE_CONFIG_H -#include <config.h> +# include <config.h> #endif #include <assert.h> @@ -35,10 +31,7 @@ sieve script interpreter. #include <sys/stat.h> #include <mailutils/argcv.h> - -#include "sieve.h" -#include "sieve_interface.h" - +#include <mailutils/libsieve.h> #include <mailutils/argp.h> #include <mailutils/auth.h> #include <mailutils/errno.h> @@ -54,20 +47,19 @@ void mutil_register_all_mbox_formats (void); const char *argp_program_version = "sieve (" PACKAGE_STRING ")"; static char doc[] = - "GNU sieve -- a mail filtering tool\n" - "\v" - "Debug flags:\n" - " a - address parser traces\n" - " g - main parser traces\n" - " T - mailutil traces (MU_DEBUG_TRACE)\n" - " P - network protocols (MU_DEBUG_PROT)\n" - " t - sieve trace (SV_DEBUG_TRACE)\n" - " h - sieve header filling (SV_DEBUG_HDR_FILL)\n" - " q - sieve message queries (SV_DEBUG_MSG_QUERY)\n"; +"GNU sieve -- a mail filtering tool\n" +"\v" +"Debug flags:\n" +" g - main parser traces\n" +" T - mailutil traces (MU_DEBUG_TRACE)\n" +" P - network protocols (MU_DEBUG_PROT)\n" +" t - sieve trace (MU_SIEVE_DEBUG_TRACE)\n" +" i - sieve instructions trace (MU_SIEVE_DEBUG_INSTR)\n"; #define D_DEFAULT "TPt" -static struct argp_option options[] = { +static struct argp_option options[] = +{ {"no-actions", 'n', 0, 0, "No actions executed, just print what would be done", 0}, @@ -77,6 +69,9 @@ static struct argp_option options[] = { {"compile-only", 'c', 0, 0, "Compile script and exit", 0}, + {"dump", 'D', 0, 0, + "Compile script, dump disasembled sieve code on terminal and exit", 0 }, + {"mbox-url", 'f', "MBOX", 0, "Mailbox to sieve (defaults to user's mail spool)", 0}, @@ -92,14 +87,13 @@ static struct argp_option options[] = { {0} }; -struct options -{ - int no_actions; +struct options { int keep_going; int compile_only; char *mbox; char *tickets; int debug_level; + int sieve_debug; char *mailer; char *script; }; @@ -119,28 +113,39 @@ parser (int key, char *arg, struct argp_state *state) if (!opts->debug_level) opts->debug_level = MU_DEBUG_ERROR; break; + case 'n': - opts->no_actions = SV_FLAG_NO_ACTIONS; + opts->sieve_debug |= MU_SIEVE_DRY_RUN; break; + case 'k': opts->keep_going = 1; break; + case 'c': opts->compile_only = 1; break; + + case 'D': + opts->compile_only = 2; + break; + case 'f': if (opts->mbox) argp_error (state, "only one MBOX can be specified"); opts->mbox = strdup (arg); break; + case 't': free (opts->tickets); opts->tickets = mu_tilde_expansion (arg, "/", NULL); break; + case 'M': free (opts->mailer); opts->mailer = strdup (arg); break; + case 'd': if (!arg) arg = D_DEFAULT; @@ -156,26 +161,18 @@ parser (int key, char *arg, struct argp_state *state) opts->debug_level |= MU_DEBUG_PROT; break; - case 't': - opts->debug_level |= SV_DEBUG_TRACE; - break; - - case 'h': - opts->debug_level |= SV_DEBUG_HDR_FILL; - break; - - case 'q': - opts->debug_level |= SV_DEBUG_MSG_QUERY; - break; - case 'g': - yydebug = 1; + sieve_yydebug = 1; break; - case 'a': - addrdebug = 1; + case 't': + opts->sieve_debug |= MU_SIEVE_DEBUG_TRACE; break; - + + case 'i': + opts->sieve_debug |= MU_SIEVE_DEBUG_INSTR; + break; + default: argp_error (state, "%c is not a valid debug flag", *arg); break; @@ -199,63 +196,47 @@ parser (int key, char *arg, struct argp_state *state) return 0; } -static struct argp argp = { +static struct argp argp = +{ options, parser, "SCRIPT", doc }; -static const char *sieve_argp_capa[] = { +static const char *sieve_argp_capa[] = +{ "common", "mailbox", "license", NULL }; -char *sieve_license_text = - " Copyright 1999 by Carnegie Mellon University\n" - " Copyright 1999,2001,2002 by Free Software Foundation\n" - "\n" - " Permission to use, copy, modify, and distribute this software and its\n" - " documentation for any purpose and without fee is hereby granted,\n" - " provided that the above copyright notice appear in all copies and that\n" - " both that copyright notice and this permission notice appear in\n" - " supporting documentation, and that the name of Carnegie Mellon\n" - " University not be used in advertising or publicity pertaining to\n" - " distribution of the software without specific, written prior\n" - " permission.\n"; - - -static void -parse_error (const char *script, int lineno, const char *errmsg) +int +sieve_debug_printer (void *unused, const char *fmt, va_list ap) { - fprintf (stderr, "%s:%d: %s\n", script, lineno, errmsg); + vfprintf (stderr, fmt, ap); + return 0; } -static void -execute_error (const char *script, message_t msg, int rc, const char *errmsg) +static int +debug_print (mu_debug_t unused, size_t level, const char *fmt, va_list ap) { - size_t uid = 0; - message_get_uid (msg, &uid); - - if (rc) - fprintf (stderr, "%s on msg uid %d failed: %s (%s)\n", script, uid, - errmsg, mu_errstring (rc)); - else - fprintf (stderr, "%s on msg uid %d failed: %s\n", script, uid, errmsg); + vfprintf ((level == MU_DEBUG_ERROR) ? stderr : stdout, fmt, ap); + return 0; } static void -action_log (const char *script, message_t msg, const char *action, - const char *fmt, va_list ap) +action_log (void *unused, + const char *script, size_t msgno, message_t msg, + const char *action, const char *fmt, va_list ap) { size_t uid = 0; message_get_uid (msg, &uid); fprintf (stdout, "%s on msg uid %d", action, uid); - if (strlen (fmt)) + if (fmt && strlen (fmt)) { fprintf (stdout, ": "); vfprintf (stdout, fmt, ap); @@ -263,120 +244,101 @@ action_log (const char *script, message_t msg, const char *action, fprintf (stdout, "\n"); } -static int -debug_print (mu_debug_t debug, size_t level, const char *fmt, va_list ap) -{ - (void) debug; - vfprintf ((level == MU_DEBUG_ERROR) ? stderr : stdout, fmt, ap); - return 0; -} - int main (int argc, char *argv[]) { - sv_interp_t interp = 0; - sv_script_t script = 0; + sieve_machine_t mach; wicket_t wicket = 0; ticket_t ticket = 0; mu_debug_t debug = 0; mailer_t mailer = 0; mailbox_t mbox = 0; + int rc; + struct options opts = {0}; - struct options opts = { 0 }; - - size_t count = 0; - int msgno = 0; - - int rc = 0; - - /* Override license text: */ - mu_license_text = sieve_license_text; rc = mu_argp_parse (&argp, &argc, &argv, ARGP_IN_ORDER, sieve_argp_capa, 0, &opts); if (rc) - { - fprintf (stderr, "arg parsing failed: %s\n", sv_strerror (rc)); - return 1; - } + return 1; mutil_register_all_mbox_formats (); /* Sieve interpreter setup. */ - rc = sv_interp_alloc (&interp, parse_error, execute_error, action_log); - + rc = sieve_machine_init (&mach, NULL); if (rc) { - fprintf (stderr, "sv_interp_alloc() failed: %s\n", sv_strerror (rc)); - goto cleanup; + mu_error ("can't initialize sieve machine: %s", mu_errstring (rc)); + return 1; } - - rc = sv_script_parse (&script, interp, opts.script); - + sieve_machine_set_debug (mach, sieve_debug_printer); + sieve_machine_set_logger (mach, action_log); + + rc = sieve_compile (mach, opts.script); if (rc) - { - /* Don't print this if there was a parse failure, because - parse_error() was already called to report it. */ - if (rc != SV_EPARSE) - fprintf (stderr, "parsing %s failed: %s\n", - opts.script, sv_strerror (rc)); - goto cleanup; - } + return 1; /* We can finish if its only a compilation check. */ if (opts.compile_only) - goto cleanup; + { + if (opts.compile_only == 2) + sieve_disass (mach); + return 0; + } /* Create a ticket, if we can. */ if (opts.tickets) { if ((rc = wicket_create (&wicket, opts.tickets)) != 0) { - fprintf (stderr, "wicket create <%s> failed: %s\n", + mu_error ("wicket create <%s> failed: %s\n", opts.tickets, mu_errstring (rc)); goto cleanup; } if ((rc = wicket_get_ticket (wicket, &ticket, 0, 0)) != 0) { - fprintf (stderr, "ticket get failed: %s\n", mu_errstring (rc)); + mu_error ("ticket get failed: %s\n", mu_errstring (rc)); goto cleanup; } + sieve_machine_set_ticket (mach, ticket); } /* Create a debug object, if needed. */ if (opts.debug_level) { - if ((rc = mu_debug_create (&debug, interp))) + if ((rc = mu_debug_create (&debug, mach))) { - fprintf (stderr, "mu_debug_create failed: %s\n", mu_errstring (rc)); + mu_error ("mu_debug_create failed: %s\n", mu_errstring (rc)); goto cleanup; } if ((rc = mu_debug_set_level (debug, opts.debug_level))) { - fprintf (stderr, "mu_debug_set_level failed: %s\n", + mu_error ("mu_debug_set_level failed: %s\n", mu_errstring (rc)); goto cleanup; } - if ((rc = mu_debug_set_print (debug, debug_print, interp))) + if ((rc = mu_debug_set_print (debug, debug_print, mach))) { - fprintf (stderr, "mu_debug_set_print failed: %s\n", + mu_error ("mu_debug_set_print failed: %s\n", mu_errstring (rc)); goto cleanup; } } - + + sieve_machine_set_debug_level (mach, debug, opts.sieve_debug); + /* Create a mailer. */ if (strcmp (opts.mailer, "none")) { if ((rc = mailer_create (&mailer, opts.mailer))) { - fprintf (stderr, "mailer create <%s> failed: %s\n", + mu_error ("mailer create <%s> failed: %s\n", opts.mailer, mu_errstring (rc)); goto cleanup; } if (debug && (rc = mailer_set_debug (mailer, debug))) { - fprintf (stderr, "mailer_set_debug failed: %s\n", + mu_error ("mailer_set_debug failed: %s\n", mu_errstring (rc)); goto cleanup; } @@ -384,14 +346,14 @@ main (int argc, char *argv[]) /* Create, give a ticket to, and open the mailbox. */ if ((rc = mailbox_create_default (&mbox, opts.mbox)) != 0) { - fprintf (stderr, "mailbox create <%s> failed: %s\n", + mu_error ("mailbox create <%s> failed: %s\n", opts.mbox ? opts.mbox : "default", mu_errstring (rc)); goto cleanup; } if (debug && (rc = mailbox_set_debug (mbox, debug))) { - fprintf (stderr, "mailbox_set_debug failed: %s\n", mu_errstring (rc)); + mu_error ("mailbox_set_debug failed: %s\n", mu_errstring (rc)); goto cleanup; } @@ -402,14 +364,14 @@ main (int argc, char *argv[]) if ((rc = mailbox_get_folder (mbox, &folder))) { - fprintf (stderr, "mailbox_get_folder failed: %s", + mu_error ("mailbox_get_folder failed: %s", mu_errstring (rc)); goto cleanup; } if ((rc = folder_get_authority (folder, &auth))) { - fprintf (stderr, "folder_get_authority failed: %s", + mu_error ("folder_get_authority failed: %s", mu_errstring (rc)); goto cleanup; } @@ -417,65 +379,34 @@ main (int argc, char *argv[]) /* Authentication-less folders don't have authorities. */ if (auth && (rc = authority_set_ticket (auth, ticket))) { - fprintf (stderr, "authority_set_ticket failed: %s", + mu_error ("authority_set_ticket failed: %s", mu_errstring (rc)); goto cleanup; } } /* Open the mailbox read-only if we aren't going to modify it. */ - if (opts.no_actions) + if (opts.sieve_debug & MU_SIEVE_DRY_RUN) rc = mailbox_open (mbox, MU_STREAM_READ); else rc = mailbox_open (mbox, MU_STREAM_RDWR); if (rc != 0) { - fprintf (stderr, "open on %s failed: %s\n", + mu_error ("open on %s failed: %s\n", opts.mbox ? opts.mbox : "default", mu_errstring (rc)); goto cleanup; } - /* Iterate over all the messages in the mailbox. */ - rc = mailbox_messages_count (mbox, &count); - - if (rc != 0) + /* Process the mailbox */ + rc = sieve_mailbox (mach, mbox); + if (rc) { - fprintf (stderr, "message count on %s failed: %s\n", - opts.mbox ? opts.mbox : "default", mu_errstring (rc)); goto cleanup; } - for (msgno = 1; msgno <= count; ++msgno) - { - message_t msg = 0; - - if ((rc = mailbox_get_message (mbox, msgno, &msg)) != 0) - { - fprintf (stderr, "get message on %s (msg %d) failed: %s\n", - opts.mbox ? opts.mbox : "default", msgno, - mu_errstring (rc)); - goto cleanup; - } - - rc = - sv_script_execute (script, msg, ticket, debug, mailer, - opts.no_actions); - - if (rc) - { - fprintf (stderr, "execution of %s on %s (msg %d) failed: %s\n", - opts.script, opts.mbox ? opts.mbox : "default", msgno, - sv_strerror (rc)); - if (opts.keep_going) - rc = 0; - else - goto cleanup; - } - } - cleanup: - if (mbox && !opts.no_actions && !opts.compile_only) + if (mbox && !(opts.sieve_debug & MU_SIEVE_DRY_RUN)) { int e; @@ -484,8 +415,8 @@ cleanup: any messages that were marked DELETED even if execution failed on a later message. */ if ((e = mailbox_expunge (mbox)) != 0) - fprintf (stderr, "expunge on %s failed: %s\n", - opts.mbox ? opts.mbox : "default", mu_errstring (e)); + mu_error ("expunge on %s failed: %s\n", + opts.mbox ? opts.mbox : "default", mu_errstring (e)); if (e && !rc) rc = e; @@ -493,9 +424,7 @@ cleanup: mailbox_close (mbox); mailbox_destroy (&mbox); - mu_debug_destroy (&debug, interp); - sv_script_free (&script); - sv_interp_free (&interp); + mu_debug_destroy (&debug, mach); return rc ? 1 : 0; } |