Commit 9864f687 9864f6879fcf04542678301f1f90de84e066073e by Sergey Poznyakoff

Add new Sieve action : pipe

1 parent 55e0fbee
1 2007-11-10 Sergey Poznyakoff <gray@gnu.org.ua> 1 2007-11-10 Sergey Poznyakoff <gray@gnu.org.ua>
2 2
3 * libsieve/extensions/Makefile.am: Add pipe.c
4 * libsieve/extensions/pipe.c: New file
5
3 * Makefile.am, configure.ac: Add maidag. 6 * Makefile.am, configure.ac: Add maidag.
4 * frm/common.c, imap4d/sync.c, libsieve/runtime.c, 7 * frm/common.c, imap4d/sync.c, libsieve/runtime.c,
5 mh/scan.c: Update declaration of observable actions. 8 mh/scan.c: Update declaration of observable actions.
......
...@@ -21,6 +21,7 @@ moddir=@SIEVE_MODDIR@ ...@@ -21,6 +21,7 @@ moddir=@SIEVE_MODDIR@
21 mod_LTLIBRARIES = \ 21 mod_LTLIBRARIES = \
22 list.la\ 22 list.la\
23 moderator.la\ 23 moderator.la\
24 pipe.la\
24 spamd.la\ 25 spamd.la\
25 timestamp.la\ 26 timestamp.la\
26 vacation.la 27 vacation.la
...@@ -49,3 +50,6 @@ vacation_la_SOURCES = vacation.c ...@@ -49,3 +50,6 @@ vacation_la_SOURCES = vacation.c
49 vacation_la_LIBADD = ../libsieve.la 50 vacation_la_LIBADD = ../libsieve.la
50 vacation_la_LDFLAGS = -module -avoid-version -no-undefined 51 vacation_la_LDFLAGS = -module -avoid-version -no-undefined
51 52
53 pipe_la_SOURCES = pipe.c
54 pipe_la_LIBADD = ../libsieve.la
55 pipe_la_LDFLAGS = -module -avoid-version -no-undefined
......
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2007 Free Software Foundation, Inc.
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 3 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General
15 Public License along with this library; if not, write to the
16 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 Boston, MA 02110-1301 USA */
18
19 /* Syntax: pipe <program call: string>
20 [:envelope]
21
22 Notes/FIXME: 1. it would be nice to implement meta-variables in
23 <program call> which would expand to various
24 items from the message being handled.
25 2. :mime tag could be useful too.
26 */
27
28 #ifdef HAVE_CONFIG_H
29 # include <config.h>
30 #endif
31
32 #include <stdio.h>
33 #include <unistd.h>
34 #include <stdlib.h>
35 #include <sys/types.h>
36 #include <string.h>
37 #include <signal.h>
38 #include <regex.h>
39 #include <mu_dbm.h>
40 #include <mailutils/libsieve.h>
41
42 #define ASSERT(expr, diag, ec) \
43 if (!(expr)) \
44 { \
45 if (ec) \
46 mu_sieve_error (mach, "%d: %s: %s", \
47 mu_sieve_get_message_num (mach), \
48 diag, \
49 mu_strerror (ec)); \
50 else \
51 mu_sieve_error (mach, "%d: %s", \
52 mu_sieve_get_message_num (mach), \
53 diag); \
54 mu_sieve_abort (mach); \
55 }
56
57 #define ASSERT2(expr, diag, arg, ec) \
58 if (!(expr)) \
59 { \
60 if (ec) \
61 mu_sieve_error (mach, "%d: `%s': %s: %s", \
62 mu_sieve_get_message_num (mach), \
63 arg, \
64 diag, \
65 mu_strerror (ec)); \
66 else \
67 mu_sieve_error (mach, "%d: `%s': %s", \
68 mu_sieve_get_message_num (mach), \
69 arg, \
70 diag); \
71 mu_sieve_abort (mach); \
72 }
73
74 int
75 sieve_action_pipe (mu_sieve_machine_t mach, mu_list_t args, mu_list_t tags)
76 {
77 int rc;
78 mu_message_t msg;
79 mu_sieve_value_t *val;
80 char *cmd;
81 mu_stream_t mstr, pstr;
82 char buf[512];
83 size_t n;
84 mu_envelope_t env;
85
86 val = mu_sieve_value_get (args, 0);
87 ASSERT (val, _("cannot get command!"), 0);
88 cmd = val->v.string;
89
90 mu_sieve_log_action (mach, "PIPE", NULL);
91 if (mu_sieve_get_debug_level (mach) & MU_SIEVE_DEBUG_TRACE)
92 {
93 mu_sieve_locus_t locus;
94 mu_sieve_get_locus (mach, &locus);
95 mu_sieve_debug (mach, "%s:%lu: PIPE\n",
96 locus.source_file,
97 (unsigned long) locus.source_line);
98 }
99
100 if (mu_sieve_is_dry_run (mach))
101 return 0;
102
103 msg = mu_sieve_get_message (mach);
104 mu_message_get_envelope (msg, &env);
105
106 rc = mu_message_get_stream (msg, &mstr);
107 ASSERT (rc == 0, _("cannot get message stream"), rc);
108
109 rc = mu_prog_stream_create (&pstr, cmd, MU_STREAM_WRITE);
110 ASSERT2 (rc == 0, _("cannot create command stream"), cmd, rc);
111
112 rc = mu_stream_open (pstr);
113 ASSERT2 (rc == 0, _("cannot open command stream"), cmd, rc);
114
115 if (mu_sieve_tag_lookup (tags, "envelope", &val))
116 {
117 char *p;
118
119 rc = mu_envelope_aget_sender (env, &p);
120 ASSERT (rc == 0, _("cannot get envelope sender"), rc);
121 rc = mu_stream_sequential_write (pstr, "From ", 5);
122 ASSERT (rc == 0, _("stream write failed"), rc);
123 mu_stream_sequential_write (pstr, p, strlen (p));
124 free (p);
125 rc = mu_stream_sequential_write (pstr, " ", 1);
126 ASSERT (rc == 0, _("stream write failed"), rc);
127 rc = mu_envelope_aget_date (env, &p);
128 ASSERT (rc == 0, _("cannot get envelope date"), rc);
129 rc = mu_stream_sequential_write (pstr, p, strlen (p));
130 ASSERT (rc == 0, _("stream write failed"), rc);
131 free (p);
132 rc = mu_stream_sequential_write (pstr, "\n", 1);
133 ASSERT (rc == 0, _("stream write failed"), rc);
134 }
135
136 mu_stream_seek (mstr, 0, SEEK_SET);
137 while (rc == 0
138 && mu_stream_sequential_read (mstr, buf, sizeof buf, &n) == 0
139 && n > 0)
140 rc = mu_stream_sequential_write (pstr, buf, n);
141
142 mu_stream_close (pstr);
143 mu_stream_destroy (&pstr, mu_stream_get_owner (pstr));
144
145
146 ASSERT2 (rc == 0, _("command failed"), cmd, rc);
147
148 return 0;
149 }
150
151 /* Tagged arguments: */
152 static mu_sieve_tag_def_t pipe_tags[] = {
153 { "envelope", SVT_VOID },
154 { NULL }
155 };
156
157 static mu_sieve_tag_group_t pipe_tag_groups[] = {
158 { pipe_tags, NULL },
159 { NULL }
160 };
161
162 /* Required arguments: */
163 static mu_sieve_data_type pipe_args[] = {
164 SVT_STRING, /* program call */
165 SVT_VOID
166 };
167
168 int
169 SIEVE_EXPORT (pipe, init) (mu_sieve_machine_t mach)
170 {
171 return mu_sieve_register_action (mach, "pipe", sieve_action_pipe,
172 pipe_args, pipe_tag_groups, 1);
173 }
174