summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2002-11-14 07:24:31 +0000
committerSergey Poznyakoff <gray@gnu.org.ua>2002-11-14 07:24:31 +0000
commit01b68a33835454728f5361079bb57019c4bca106 (patch)
tree418905a74fd1f9ba1966db0669e0b91e8fc5c5d3
parent4518e810aa0886c561cdaf0bffc9dbd264306c43 (diff)
downloadmailutils-01b68a33835454728f5361079bb57019c4bca106.tar.gz
mailutils-01b68a33835454728f5361079bb57019c4bca106.tar.bz2
Use libsieve calls.
-rw-r--r--sieve/sieve.c265
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;
}

Return to:

Send suggestions and report system problems to the System administrator.