summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2007-11-10 16:18:00 +0000
committerSergey Poznyakoff <gray@gnu.org.ua>2007-11-10 16:18:00 +0000
commit9864f6879fcf04542678301f1f90de84e066073e (patch)
tree12af95de87b5aeadcd9fc0b13ba49a1d5f3b9101
parent55e0fbee9e680aa2572284e0ed265d28b3400558 (diff)
downloadmailutils-9864f6879fcf04542678301f1f90de84e066073e.tar.gz
mailutils-9864f6879fcf04542678301f1f90de84e066073e.tar.bz2
Add new Sieve action : pipe
-rw-r--r--ChangeLog3
-rw-r--r--libsieve/extensions/Makefile.am4
-rw-r--r--libsieve/extensions/pipe.c174
3 files changed, 181 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index 328fd0d82..289cec74b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,8 @@
2007-11-10 Sergey Poznyakoff <gray@gnu.org.ua>
+ * libsieve/extensions/Makefile.am: Add pipe.c
+ * libsieve/extensions/pipe.c: New file
+
* Makefile.am, configure.ac: Add maidag.
* frm/common.c, imap4d/sync.c, libsieve/runtime.c,
mh/scan.c: Update declaration of observable actions.
diff --git a/libsieve/extensions/Makefile.am b/libsieve/extensions/Makefile.am
index 32f2ae5b3..46493eb5b 100644
--- a/libsieve/extensions/Makefile.am
+++ b/libsieve/extensions/Makefile.am
@@ -21,6 +21,7 @@ moddir=@SIEVE_MODDIR@
mod_LTLIBRARIES = \
list.la\
moderator.la\
+ pipe.la\
spamd.la\
timestamp.la\
vacation.la
@@ -49,3 +50,6 @@ vacation_la_SOURCES = vacation.c
vacation_la_LIBADD = ../libsieve.la
vacation_la_LDFLAGS = -module -avoid-version -no-undefined
+pipe_la_SOURCES = pipe.c
+pipe_la_LIBADD = ../libsieve.la
+pipe_la_LDFLAGS = -module -avoid-version -no-undefined
diff --git a/libsieve/extensions/pipe.c b/libsieve/extensions/pipe.c
new file mode 100644
index 000000000..452f9e43f
--- /dev/null
+++ b/libsieve/extensions/pipe.c
@@ -0,0 +1,174 @@
+/* GNU Mailutils -- a suite of utilities for electronic mail
+ Copyright (C) 2007 Free Software Foundation, Inc.
+
+ This library 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 of the License, or (at your option) any later version.
+
+ This library 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 this library; if not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301 USA */
+
+/* Syntax: pipe <program call: string>
+ [:envelope]
+
+ Notes/FIXME: 1. it would be nice to implement meta-variables in
+ <program call> which would expand to various
+ items from the message being handled.
+ 2. :mime tag could be useful too.
+*/
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <string.h>
+#include <signal.h>
+#include <regex.h>
+#include <mu_dbm.h>
+#include <mailutils/libsieve.h>
+
+#define ASSERT(expr, diag, ec) \
+ if (!(expr)) \
+ { \
+ if (ec) \
+ mu_sieve_error (mach, "%d: %s: %s", \
+ mu_sieve_get_message_num (mach), \
+ diag, \
+ mu_strerror (ec)); \
+ else \
+ mu_sieve_error (mach, "%d: %s", \
+ mu_sieve_get_message_num (mach), \
+ diag); \
+ mu_sieve_abort (mach); \
+ }
+
+#define ASSERT2(expr, diag, arg, ec) \
+ if (!(expr)) \
+ { \
+ if (ec) \
+ mu_sieve_error (mach, "%d: `%s': %s: %s", \
+ mu_sieve_get_message_num (mach), \
+ arg, \
+ diag, \
+ mu_strerror (ec)); \
+ else \
+ mu_sieve_error (mach, "%d: `%s': %s", \
+ mu_sieve_get_message_num (mach), \
+ arg, \
+ diag); \
+ mu_sieve_abort (mach); \
+ }
+
+int
+sieve_action_pipe (mu_sieve_machine_t mach, mu_list_t args, mu_list_t tags)
+{
+ int rc;
+ mu_message_t msg;
+ mu_sieve_value_t *val;
+ char *cmd;
+ mu_stream_t mstr, pstr;
+ char buf[512];
+ size_t n;
+ mu_envelope_t env;
+
+ val = mu_sieve_value_get (args, 0);
+ ASSERT (val, _("cannot get command!"), 0);
+ cmd = val->v.string;
+
+ mu_sieve_log_action (mach, "PIPE", NULL);
+ if (mu_sieve_get_debug_level (mach) & MU_SIEVE_DEBUG_TRACE)
+ {
+ mu_sieve_locus_t locus;
+ mu_sieve_get_locus (mach, &locus);
+ mu_sieve_debug (mach, "%s:%lu: PIPE\n",
+ locus.source_file,
+ (unsigned long) locus.source_line);
+ }
+
+ if (mu_sieve_is_dry_run (mach))
+ return 0;
+
+ msg = mu_sieve_get_message (mach);
+ mu_message_get_envelope (msg, &env);
+
+ rc = mu_message_get_stream (msg, &mstr);
+ ASSERT (rc == 0, _("cannot get message stream"), rc);
+
+ rc = mu_prog_stream_create (&pstr, cmd, MU_STREAM_WRITE);
+ ASSERT2 (rc == 0, _("cannot create command stream"), cmd, rc);
+
+ rc = mu_stream_open (pstr);
+ ASSERT2 (rc == 0, _("cannot open command stream"), cmd, rc);
+
+ if (mu_sieve_tag_lookup (tags, "envelope", &val))
+ {
+ char *p;
+
+ rc = mu_envelope_aget_sender (env, &p);
+ ASSERT (rc == 0, _("cannot get envelope sender"), rc);
+ rc = mu_stream_sequential_write (pstr, "From ", 5);
+ ASSERT (rc == 0, _("stream write failed"), rc);
+ mu_stream_sequential_write (pstr, p, strlen (p));
+ free (p);
+ rc = mu_stream_sequential_write (pstr, " ", 1);
+ ASSERT (rc == 0, _("stream write failed"), rc);
+ rc = mu_envelope_aget_date (env, &p);
+ ASSERT (rc == 0, _("cannot get envelope date"), rc);
+ rc = mu_stream_sequential_write (pstr, p, strlen (p));
+ ASSERT (rc == 0, _("stream write failed"), rc);
+ free (p);
+ rc = mu_stream_sequential_write (pstr, "\n", 1);
+ ASSERT (rc == 0, _("stream write failed"), rc);
+ }
+
+ mu_stream_seek (mstr, 0, SEEK_SET);
+ while (rc == 0
+ && mu_stream_sequential_read (mstr, buf, sizeof buf, &n) == 0
+ && n > 0)
+ rc = mu_stream_sequential_write (pstr, buf, n);
+
+ mu_stream_close (pstr);
+ mu_stream_destroy (&pstr, mu_stream_get_owner (pstr));
+
+
+ ASSERT2 (rc == 0, _("command failed"), cmd, rc);
+
+ return 0;
+}
+
+/* Tagged arguments: */
+static mu_sieve_tag_def_t pipe_tags[] = {
+ { "envelope", SVT_VOID },
+ { NULL }
+};
+
+static mu_sieve_tag_group_t pipe_tag_groups[] = {
+ { pipe_tags, NULL },
+ { NULL }
+};
+
+/* Required arguments: */
+static mu_sieve_data_type pipe_args[] = {
+ SVT_STRING, /* program call */
+ SVT_VOID
+};
+
+int
+SIEVE_EXPORT (pipe, init) (mu_sieve_machine_t mach)
+{
+ return mu_sieve_register_action (mach, "pipe", sieve_action_pipe,
+ pipe_args, pipe_tag_groups, 1);
+}
+

Return to:

Send suggestions and report system problems to the System administrator.