Add new Sieve action : pipe
Showing
3 changed files
with
181 additions
and
0 deletions
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 | ... | ... |
libsieve/extensions/pipe.c
0 → 100644
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 |
-
Please register or sign in to post a comment