Commit 2e6b4a7f 2e6b4a7f2251ef9149e9f11216640a129114caa9 by Sergey Poznyakoff

sieve: improve "pipe" action, implement "pipe" test.

* libmu_sieve/extensions/pipe.c: Allow to specify which parts of the
message should be piped.
Implement "pipe" test.
* sieve/tests/pipeact.at: New file.
* sieve/tests/pipetest.at: New file.
* sieve/tests/Makefile.am (TESTSUITE_AT): Add pipeact.at
and pipetest.at
* sieve/tests/testsuite.at: Include pipeact.at
and pipetest.at
(MUT_SIEVE_EXT_TEST): Redefine MUT_SIEVE_OPTIONS.
Set envar "cwd".
Use cat and heredoc to create prog, instead of using AT_DATA.
* sieve/tests/moderator.at: Update to these changes.
1 parent 9bc59f54
...@@ -41,17 +41,6 @@ ...@@ -41,17 +41,6 @@
41 #include <mailutils/sieve.h> 41 #include <mailutils/sieve.h>
42 #include <mailutils/prog.h> 42 #include <mailutils/prog.h>
43 43
44 int
45 sieve_action_pipe (mu_sieve_machine_t mach, mu_list_t args, mu_list_t tags)
46 {
47 int rc;
48 mu_message_t msg;
49 mu_sieve_value_t *val;
50 char *cmd;
51 mu_stream_t mstr, pstr;
52 mu_envelope_t env;
53 const char *error_diag = NULL;
54 const char *error_arg = NULL;
55 #define ONERR(rc, diag, arg) \ 44 #define ONERR(rc, diag, arg) \
56 if (rc) \ 45 if (rc) \
57 { \ 46 { \
...@@ -60,6 +49,25 @@ sieve_action_pipe (mu_sieve_machine_t mach, mu_list_t args, mu_list_t tags) ...@@ -60,6 +49,25 @@ sieve_action_pipe (mu_sieve_machine_t mach, mu_list_t args, mu_list_t tags)
60 break; \ 49 break; \
61 } 50 }
62 51
52 #define PIPE_ENVELOPE 0x01
53 #define PIPE_HEADERS 0x02
54 #define PIPE_BODY 0x04
55 #define PIPE_ALL (PIPE_ENVELOPE | PIPE_HEADERS | PIPE_BODY)
56
57 int
58 sieve_pipe (mu_sieve_machine_t mach, mu_list_t args, mu_list_t tags, int test)
59 {
60 int retval = 0;
61 int rc, result;
62 mu_message_t msg;
63 mu_sieve_value_t *val;
64 char *cmd;
65 mu_stream_t pstr;
66 mu_envelope_t env;
67 const char *error_diag = NULL;
68 const char *error_arg = NULL;
69 int pipe_mask = 0;
70
63 val = mu_sieve_value_get (args, 0); 71 val = mu_sieve_value_get (args, 0);
64 if (!val) 72 if (!val)
65 { 73 {
...@@ -70,10 +78,9 @@ sieve_action_pipe (mu_sieve_machine_t mach, mu_list_t args, mu_list_t tags) ...@@ -70,10 +78,9 @@ sieve_action_pipe (mu_sieve_machine_t mach, mu_list_t args, mu_list_t tags)
70 } 78 }
71 cmd = val->v.string; 79 cmd = val->v.string;
72 80
73 mu_sieve_log_action (mach, "PIPE", NULL);
74 if (mu_sieve_get_debug_level (mach) & MU_SIEVE_DEBUG_TRACE) 81 if (mu_sieve_get_debug_level (mach) & MU_SIEVE_DEBUG_TRACE)
75 { 82 {
76 mu_sieve_debug (mach, "PIPE"); 83 mu_sieve_debug (mach, test ? "PIPE (test)" : "PIPE (action)");
77 } 84 }
78 85
79 if (mu_sieve_is_dry_run (mach)) 86 if (mu_sieve_is_dry_run (mach))
...@@ -82,15 +89,22 @@ sieve_action_pipe (mu_sieve_machine_t mach, mu_list_t args, mu_list_t tags) ...@@ -82,15 +89,22 @@ sieve_action_pipe (mu_sieve_machine_t mach, mu_list_t args, mu_list_t tags)
82 msg = mu_sieve_get_message (mach); 89 msg = mu_sieve_get_message (mach);
83 mu_message_get_envelope (msg, &env); 90 mu_message_get_envelope (msg, &env);
84 91
92 if (mu_sieve_tag_lookup (tags, "envelope", NULL))
93 pipe_mask |= PIPE_ENVELOPE;
94 if (mu_sieve_tag_lookup (tags, "header", NULL))
95 pipe_mask |= PIPE_HEADERS;
96 if (mu_sieve_tag_lookup (tags, "body", NULL))
97 pipe_mask |= PIPE_BODY;
98 if (pipe_mask == 0)
99 pipe_mask = PIPE_ALL;
85 do 100 do
86 { 101 {
87 rc = mu_message_get_streamref (msg, &mstr); 102 mu_stream_t mstr = NULL;
88 ONERR (rc, _("cannot get message stream"), NULL); 103
89
90 rc = mu_command_stream_create (&pstr, cmd, MU_STREAM_WRITE); 104 rc = mu_command_stream_create (&pstr, cmd, MU_STREAM_WRITE);
91 ONERR (rc, _("cannot create command stream"), cmd); 105 ONERR (rc, _("cannot create command stream"), cmd);
92 106
93 if (mu_sieve_tag_lookup (tags, "envelope", &val)) 107 if (pipe_mask & PIPE_ENVELOPE)
94 { 108 {
95 char *p; 109 char *p;
96 110
...@@ -111,14 +125,30 @@ sieve_action_pipe (mu_sieve_machine_t mach, mu_list_t args, mu_list_t tags) ...@@ -111,14 +125,30 @@ sieve_action_pipe (mu_sieve_machine_t mach, mu_list_t args, mu_list_t tags)
111 ONERR (rc, _("stream write failed"), NULL); 125 ONERR (rc, _("stream write failed"), NULL);
112 } 126 }
113 127
114 rc = mu_stream_copy (pstr, mstr, 0, NULL); 128 if (pipe_mask & PIPE_HEADERS)
115 ONERR (rc, _("command failed"), cmd); 129 {
130 mu_header_t hdr;
131
132 mu_message_get_header (msg, &hdr);
133 mu_header_get_streamref (hdr, &mstr);
134 rc = mu_stream_copy (pstr, mstr, 0, NULL);
135 ONERR (rc, _("copying headers failed"), cmd);
136 mu_stream_destroy (&mstr);
137 }
138 if (pipe_mask & PIPE_BODY)
139 {
140 mu_body_t body;
141
142 mu_message_get_body (msg, &body);
143 mu_body_get_streamref (body, &mstr);
144 rc = mu_stream_copy (pstr, mstr, 0, NULL);
145 ONERR (rc, _("copying body failed"), cmd);
146 mu_stream_destroy (&mstr);
147 }
116 } 148 }
117 while (0); 149 while (0);
118 150
119 mu_stream_destroy (&mstr); 151 result = mu_stream_close (pstr);
120 mu_stream_close (pstr);
121 mu_stream_destroy (&pstr);
122 152
123 if (rc) 153 if (rc)
124 { 154 {
...@@ -133,20 +163,91 @@ sieve_action_pipe (mu_sieve_machine_t mach, mu_list_t args, mu_list_t tags) ...@@ -133,20 +163,91 @@ sieve_action_pipe (mu_sieve_machine_t mach, mu_list_t args, mu_list_t tags)
133 (unsigned long) mu_sieve_get_message_num (mach), 163 (unsigned long) mu_sieve_get_message_num (mach),
134 error_diag, 164 error_diag,
135 mu_strerror (rc)); 165 mu_strerror (rc));
166 mu_stream_destroy (&pstr);
136 mu_sieve_abort (mach); 167 mu_sieve_abort (mach);
137 } 168 }
138 169
139 return 0; 170 if (test)
171 {
172 int code = 0;
173 int status;
174
175 rc = mu_stream_ioctl (pstr, MU_IOCTL_PROGSTREAM,
176 MU_IOCTL_PROG_STATUS, &status);
177 if (rc)
178 {
179 mu_stream_destroy (&pstr);
180 mu_sieve_abort (mach);
181 }
182
183 if (mu_sieve_tag_lookup (tags, "exit", &val))
184 code = val->v.number;
185 if (result == 0)
186 retval = code == 0;
187 else if (result == MU_ERR_PROCESS_EXITED)
188 retval = code == WEXITSTATUS (status);
189 else if (result == MU_ERR_PROCESS_SIGNALED)
190 {
191 int signo = WTERMSIG (status);
192 if (mu_sieve_tag_lookup (tags, "signal", &val))
193 retval = signo == val->v.number;
194 else
195 {
196 mu_stream_destroy (&pstr);
197 mu_sieve_abort (mach);
198 }
199 }
200 else
201 {
202 mu_sieve_error (mach, "%lu: %s",
203 (unsigned long) mu_sieve_get_message_num (mach),
204 mu_strerror (result));
205 mu_stream_destroy (&pstr);
206 mu_sieve_abort (mach);
207 }
208 }
209
210 mu_stream_destroy (&pstr);
211
212 return retval;
213 }
214
215 int
216 sieve_action_pipe (mu_sieve_machine_t mach, mu_list_t args, mu_list_t tags)
217 {
218 mu_sieve_log_action (mach, "PIPE", NULL);
219 return sieve_pipe (mach, args, tags, 0);
140 } 220 }
141 221
222 int
223 sieve_test_pipe (mu_sieve_machine_t mach, mu_list_t args, mu_list_t tags)
224 {
225 return sieve_pipe (mach, args, tags, 1);
226 }
227
228
142 /* Tagged arguments: */ 229 /* Tagged arguments: */
143 static mu_sieve_tag_def_t pipe_tags[] = { 230 static mu_sieve_tag_def_t pipe_tags[] = {
144 { "envelope", SVT_VOID }, 231 { "envelope", SVT_VOID },
232 { "body", SVT_VOID },
233 { "header", SVT_VOID },
234 { NULL }
235 };
236
237 static mu_sieve_tag_group_t pipe_action_tag_groups[] = {
238 { pipe_tags, NULL },
145 { NULL } 239 { NULL }
146 }; 240 };
147 241
148 static mu_sieve_tag_group_t pipe_tag_groups[] = { 242 static mu_sieve_tag_def_t pipe_test_tags[] = {
243 { "exit", SVT_NUMBER },
244 { "signal", SVT_NUMBER },
245 { NULL }
246 };
247
248 static mu_sieve_tag_group_t pipe_test_tag_groups[] = {
149 { pipe_tags, NULL }, 249 { pipe_tags, NULL },
250 { pipe_test_tags, NULL },
150 { NULL } 251 { NULL }
151 }; 252 };
152 253
...@@ -159,6 +260,11 @@ static mu_sieve_data_type pipe_args[] = { ...@@ -159,6 +260,11 @@ static mu_sieve_data_type pipe_args[] = {
159 int 260 int
160 SIEVE_EXPORT (pipe, init) (mu_sieve_machine_t mach) 261 SIEVE_EXPORT (pipe, init) (mu_sieve_machine_t mach)
161 { 262 {
162 return mu_sieve_register_action (mach, "pipe", sieve_action_pipe, 263 int rc;
163 pipe_args, pipe_tag_groups, 1); 264 rc = mu_sieve_register_action (mach, "pipe", sieve_action_pipe,
265 pipe_args, pipe_action_tag_groups, 1);
266 if (rc)
267 return rc;
268 return mu_sieve_register_test (mach, "pipe", sieve_test_pipe,
269 pipe_args, pipe_test_tag_groups, 1);
164 } 270 }
......
...@@ -56,6 +56,8 @@ TESTSUITE_AT = \ ...@@ -56,6 +56,8 @@ TESTSUITE_AT = \
56 moderator.at\ 56 moderator.at\
57 mul-addr.at\ 57 mul-addr.at\
58 not.at\ 58 not.at\
59 pipeact.at\
60 pipetest.at\
59 redirect.at\ 61 redirect.at\
60 reject.at\ 62 reject.at\
61 relational.at\ 63 relational.at\
......
...@@ -26,8 +26,7 @@ chmod +w mailbox ...@@ -26,8 +26,7 @@ chmod +w mailbox
26 26
27 MTA_DIAG=`pwd`/mta.diag 27 MTA_DIAG=`pwd`/mta.diag
28 export MTA_DIAG 28 export MTA_DIAG
29 sieve MUT_SIEVE_CMDLINE dnl 29 sieve MUT_SIEVE_CMDLINE MUT_SIEVE_OPTIONS -f ./mailbox prog || exit 1
30 --clearpath -L "${abs_top_builddir}/libmu_sieve/extensions" -f ./mailbox prog || exit 1
31 sed 's/ENVELOPE FROM:.*/ENVELOPE FROM/' ./mta.diag 30 sed 's/ENVELOPE FROM:.*/ENVELOPE FROM/' ./mta.diag
32 ], 31 ],
33 [ENVELOPE FROM 32 [ENVELOPE FROM
......
1 # This file is part of GNU Mailutils. -*- Autotest -*-
2 # Copyright (C) 2010 Free Software Foundation, Inc.
3 #
4 # GNU Mailutils is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License as
6 # published by the Free Software Foundation; either version 3, or (at
7 # your option) any later version.
8 #
9 # GNU Mailutils is distributed in the hope that it will be useful, but
10 # WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 # General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public License
15 # along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>.
16
17 m4_pushdef([MUT_SIEVE_EXT_NAME],[pipe action])
18
19 m4_pushdef([make_savemsg],[
20 AT_DATA([savemsg],[#! /bin/sh
21 echo "Message begin" >> $[]1
22 cat - >> $[]1
23 echo "Message end" >> $[]1
24 ])
25 chmod +x savemsg
26 ])
27
28 MUT_SIEVE_EXT_TEST([pipe entire message],[pipe00],
29 [require "pipe";
30 if header :is "Subject" "Coffee"
31 {
32 pipe "$cwd/savemsg $cwd/sieve.out";
33 }
34 ],
35 [MUT_MBCOPY($abs_top_srcdir/testsuite/spool/sieve.mbox,mailbox)
36 make_savemsg
37 sieve MUT_SIEVE_CMDLINE MUT_SIEVE_OPTIONS -f ./mailbox prog
38 cat sieve.out
39 ],
40 [Message begin
41 From bar@dontmailme.org Fri Dec 28 23:28:09 2001
42 Received: (from bar@dontmailme.org)
43 by dontmailme.org id fERKR9N16790
44 for foobar@nonexistent.net; Fri, 28 Dec 2001 22:18:08 +0200
45 Date: Fri, 28 Dec 2001 23:28:08 +0200
46 From: Bar <bar@dontmailme.org>
47 To: Foo Bar <foobar@nonexistent.net>
48 Message-Id: <200112232808.fERKR9N16790@dontmailme.org>
49 Subject: Coffee
50
51 How about some coffee?
52 Message end
53 ],
54 [IMPLICIT KEEP on msg uid 1
55 IMPLICIT KEEP on msg uid 2
56 PIPE on msg uid 3
57 ])
58
59 MUT_SIEVE_EXT_TEST([pipe envelope],[pipe01],
60 [require "pipe";
61 if header :is "Subject" "Coffee"
62 {
63 pipe :envelope "$cwd/savemsg $cwd/sieve.out";
64 }
65 ],
66 [MUT_MBCOPY($abs_top_srcdir/testsuite/spool/sieve.mbox,mailbox)
67 make_savemsg
68 sieve MUT_SIEVE_CMDLINE MUT_SIEVE_OPTIONS -f ./mailbox prog
69 cat sieve.out
70 ],
71 [Message begin
72 From bar@dontmailme.org Fri Dec 28 23:28:09 2001
73 Message end
74 ],
75 [IMPLICIT KEEP on msg uid 1
76 IMPLICIT KEEP on msg uid 2
77 PIPE on msg uid 3
78 ])
79
80 MUT_SIEVE_EXT_TEST([pipe header],[pipe02],
81 [require "pipe";
82 if header :is "Subject" "Coffee"
83 {
84 pipe :header "$cwd/savemsg $cwd/sieve.out";
85 }
86 ],
87 [MUT_MBCOPY($abs_top_srcdir/testsuite/spool/sieve.mbox,mailbox)
88 make_savemsg
89 sieve MUT_SIEVE_CMDLINE MUT_SIEVE_OPTIONS -f ./mailbox prog
90 cat sieve.out
91 ],
92 [Message begin
93 Received: (from bar@dontmailme.org)
94 by dontmailme.org id fERKR9N16790
95 for foobar@nonexistent.net; Fri, 28 Dec 2001 22:18:08 +0200
96 Date: Fri, 28 Dec 2001 23:28:08 +0200
97 From: Bar <bar@dontmailme.org>
98 To: Foo Bar <foobar@nonexistent.net>
99 Message-Id: <200112232808.fERKR9N16790@dontmailme.org>
100 Subject: Coffee
101
102 Message end
103 ],
104 [IMPLICIT KEEP on msg uid 1
105 IMPLICIT KEEP on msg uid 2
106 PIPE on msg uid 3
107 ])
108
109 MUT_SIEVE_EXT_TEST([pipe body],[pipe03],
110 [require "pipe";
111 if header :is "Subject" "Coffee"
112 {
113 pipe :body "$cwd/savemsg $cwd/sieve.out";
114 }
115 ],
116 [MUT_MBCOPY($abs_top_srcdir/testsuite/spool/sieve.mbox,mailbox)
117 make_savemsg
118 sieve MUT_SIEVE_CMDLINE MUT_SIEVE_OPTIONS -f ./mailbox prog
119 cat sieve.out
120 ],
121 [Message begin
122 How about some coffee?
123 Message end
124 ],
125 [IMPLICIT KEEP on msg uid 1
126 IMPLICIT KEEP on msg uid 2
127 PIPE on msg uid 3
128 ])
129
130 MUT_SIEVE_EXT_TEST([pipe combined],[pipe04],
131 [require "pipe";
132 if header :is "Subject" "Coffee"
133 {
134 pipe :envelope :body "$cwd/savemsg $cwd/sieve.out";
135 }
136 ],
137 [MUT_MBCOPY($abs_top_srcdir/testsuite/spool/sieve.mbox,mailbox)
138 make_savemsg
139 sieve MUT_SIEVE_CMDLINE MUT_SIEVE_OPTIONS -f ./mailbox prog
140 cat sieve.out
141 ],
142 [Message begin
143 From bar@dontmailme.org Fri Dec 28 23:28:09 2001
144 How about some coffee?
145 Message end
146 ],
147 [IMPLICIT KEEP on msg uid 1
148 IMPLICIT KEEP on msg uid 2
149 PIPE on msg uid 3
150 ])
151
152 m4_popdef([make_savemsg])
153 m4_popdef([MUT_SIEVE_EXT_NAME])
1 # This file is part of GNU Mailutils. -*- Autotest -*-
2 # Copyright (C) 2010 Free Software Foundation, Inc.
3 #
4 # GNU Mailutils is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License as
6 # published by the Free Software Foundation; either version 3, or (at
7 # your option) any later version.
8 #
9 # GNU Mailutils is distributed in the hope that it will be useful, but
10 # WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 # General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public License
15 # along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>.
16
17 m4_pushdef([MUT_SIEVE_EXT_NAME],[pipe test])
18
19 MUT_SIEVE_EXT_TEST([],[pipetest00],
20 [require "test-pipe";
21 if pipe :header "$cwd/ckmsg"
22 {
23 discard;
24 }
25 ],
26 [MUT_MBCOPY($abs_top_srcdir/testsuite/spool/sieve.mbox,mailbox)
27 AT_DATA([ckmsg],[#! /bin/sh
28 grep "^From:.*example\.org" >/dev/null
29 ])
30 chmod +x ckmsg
31
32 sieve MUT_SIEVE_CMDLINE MUT_SIEVE_OPTIONS -f ./mailbox prog
33 ],
34 [],
35 [DISCARD on msg uid 1: marking as deleted
36 IMPLICIT KEEP on msg uid 2
37 IMPLICIT KEEP on msg uid 3
38 ])
39
40 m4_popdef([MUT_SIEVE_EXT_NAME])
...@@ -87,15 +87,19 @@ dnl [STDOUT = `'],[STDERR = `']) ...@@ -87,15 +87,19 @@ dnl [STDOUT = `'],[STDERR = `'])
87 m4_define([MUT_SIEVE_EXT_TEST],[ 87 m4_define([MUT_SIEVE_EXT_TEST],[
88 AT_SETUP(MUT_SIEVE_EXT_NAME[: $1]) 88 AT_SETUP(MUT_SIEVE_EXT_NAME[: $1])
89 AT_KEYWORDS([MUT_SIEVE_EXT_NAME $2]) 89 AT_KEYWORDS([MUT_SIEVE_EXT_NAME $2])
90 90 m4_pushdef([MUT_SIEVE_OPTIONS],
91 [--clearpath -L "${abs_top_builddir}/libmu_sieve/extensions"])
91 AT_CHECK([ 92 AT_CHECK([
92 MUT_PREREQ_CAPA([HAVE_LIBLTDL]) 93 MUT_PREREQ_CAPA([HAVE_LIBLTDL])
93 94 cwd=`pwd`
94 AT_DATA([prog],[$3]) 95 cat >>prog<<EOT
96 $3
97 EOT
95 $4 98 $4
96 ], 99 ],
97 [0], 100 [0],
98 [$5],[$6]) 101 [$5],[$6])
102 m4_popdef([MUT_SIEVE_OPTIONS])
99 AT_CLEANUP]) 103 AT_CLEANUP])
100 104
101 105
...@@ -125,6 +129,8 @@ m4_include([redirect.at]) ...@@ -125,6 +129,8 @@ m4_include([redirect.at])
125 m4_include([reject.at]) 129 m4_include([reject.at])
126 m4_include([ext.at]) 130 m4_include([ext.at])
127 m4_include([moderator.at]) 131 m4_include([moderator.at])
132 m4_include([pipeact.at])
133 m4_include([pipetest.at])
128 134
129 135
130 136
......