Add scripting capability to mh/inc.
This patch adds a convenience library libmuscript that provides scripting capability easy to use in MU applications. Currently used by maidag and inc. * include/mailutils/util.h (mu_stpcpy): 2nd arg is const. * libmailutils/string/stpcpy.c: Likewise. * lib/.gitignore: Update. * lib/Makefile.am: New library libmuscript.a * lib/muscript.h: New file. * lib/muscript_priv.h: New file. * lib/script.c: New file. * maidag/guile.c: Rename to ... * lib/guile.c: ... this * maidag/python.c: Rename to ... * lib/python.c: ... this * maidag/sieve.c: Rename to ... * lib/sieve.c: ... this * maidag/Makefile.am (maidag_LDADD): Add libmuscript.a (maidag_SOURCES): Update. * maidag/maidag.c (script_handler): Change type to mu_script_t. * maidag/maidag.h: Include muscript.h * maidag/script.c: Rewrite via libmuscript * mh/Makefile.am (inc_LDADD): New variable. * mh/inc.c (options): New options --language and --script. (mh_option): New options -language and -script. (incdat) <handler,descr>: New members. (incmbx): Optionally process each message through a script. If it is marked as deleted upon return, don't incorporate it. (main): Set mh as the default mailbox scheme. Initialize scripting subsystem and deallocate it when finished. * mh/mh_getopt.h (ARG_LANG, ARG_SCRIPT): New constants.
Showing
17 changed files
with
515 additions
and
165 deletions
... | @@ -34,7 +34,7 @@ extern "C" { | ... | @@ -34,7 +34,7 @@ extern "C" { |
34 | unsigned long mu_hex2ul (char hex); | 34 | unsigned long mu_hex2ul (char hex); |
35 | size_t mu_hexstr2ul (unsigned long* ul, const char* hex, size_t len); | 35 | size_t mu_hexstr2ul (unsigned long* ul, const char* hex, size_t len); |
36 | size_t mu_cpystr (char *dst, const char *src, size_t size); | 36 | size_t mu_cpystr (char *dst, const char *src, size_t size); |
37 | char *mu_stpcpy (char *p, char *q); | 37 | char *mu_stpcpy (char *p, const char *q); |
38 | int mu_string_unfold (char *text, size_t *plen); | 38 | int mu_string_unfold (char *text, size_t *plen); |
39 | int mu_true_answer_p (const char *p); | 39 | int mu_true_answer_p (const char *p); |
40 | int mu_unre_set_regex (const char *str, int caseflag, char **errp); | 40 | int mu_unre_set_regex (const char *str, int caseflag, char **errp); | ... | ... |
lib/.gitignore
0 → 100644
1 | gnu |
... | @@ -17,8 +17,14 @@ | ... | @@ -17,8 +17,14 @@ |
17 | 17 | ||
18 | SUBDIRS = gnu . | 18 | SUBDIRS = gnu . |
19 | 19 | ||
20 | AM_CPPFLAGS = @MU_LIB_COMMON_INCLUDES@ -I${top_srcdir}/lib/gnu -I${top_builddir}/lib/gnu | 20 | AM_CPPFLAGS = \ |
21 | noinst_LIBRARIES = libmuaux.a | 21 | @MU_LIB_COMMON_INCLUDES@\ |
22 | -I${top_srcdir}/lib/gnu\ | ||
23 | -I${top_builddir}/lib/gnu\ | ||
24 | @GUILE_INCLUDES@\ | ||
25 | @PYTHON_INCLUDES@ | ||
26 | |||
27 | noinst_LIBRARIES = libmuaux.a libmuscript.a | ||
22 | libmuaux_a_SOURCES = \ | 28 | libmuaux_a_SOURCES = \ |
23 | argp_base.c\ | 29 | argp_base.c\ |
24 | daemon.c\ | 30 | daemon.c\ |
... | @@ -35,8 +41,21 @@ libmuaux_a_LIBADD=gnu/*.o | ... | @@ -35,8 +41,21 @@ libmuaux_a_LIBADD=gnu/*.o |
35 | noinst_HEADERS =\ | 41 | noinst_HEADERS =\ |
36 | mailcap.h\ | 42 | mailcap.h\ |
37 | muaux.h\ | 43 | muaux.h\ |
44 | muscript.h\ | ||
45 | muscript_priv.h\ | ||
38 | tcpwrap.h | 46 | tcpwrap.h |
39 | 47 | ||
40 | EXTRA_DIST = utmp.c | 48 | EXTRA_DIST = utmp.c |
41 | 49 | ||
50 | libmuscript_a_SOURCES = \ | ||
51 | script.c\ | ||
52 | sieve.c | ||
53 | |||
54 | if MU_COND_LIBMU_SCM | ||
55 | libmuscript_a_SOURCES += guile.c | ||
56 | endif | ||
57 | |||
58 | if MU_COND_PYTHON | ||
59 | libmuscript_a_SOURCES += python.c | ||
60 | endif | ||
42 | 61 | ... | ... |
... | @@ -15,21 +15,18 @@ | ... | @@ -15,21 +15,18 @@ |
15 | You should have received a copy of the GNU General Public License | 15 | You should have received a copy of the GNU General Public License |
16 | along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */ | 16 | along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */ |
17 | 17 | ||
18 | #include "maidag.h" | 18 | #include "muscript.h" |
19 | 19 | #include "muscript_priv.h" | |
20 | #ifdef WITH_GUILE | ||
21 | #include <mailutils/guile.h> | 20 | #include <mailutils/guile.h> |
22 | 21 | ||
23 | int debug_guile; | ||
24 | static int initialized; | 22 | static int initialized; |
25 | 23 | ||
26 | int | 24 | static int |
27 | scheme_check_msg (mu_message_t msg, struct mu_auth_data *auth, | 25 | scheme_init (const char *prog, mu_script_descr_t *pdescr) |
28 | const char *prog) | ||
29 | { | 26 | { |
30 | if (!initialized) | 27 | if (!initialized) |
31 | { | 28 | { |
32 | mu_guile_init (debug_guile); | 29 | mu_guile_init (mu_script_debug_guile); |
33 | if (mu_log_syslog) | 30 | if (mu_log_syslog) |
34 | { | 31 | { |
35 | SCM port; | 32 | SCM port; |
... | @@ -42,9 +39,21 @@ scheme_check_msg (mu_message_t msg, struct mu_auth_data *auth, | ... | @@ -42,9 +39,21 @@ scheme_check_msg (mu_message_t msg, struct mu_auth_data *auth, |
42 | initialized = 1; | 39 | initialized = 1; |
43 | } | 40 | } |
44 | mu_guile_load (prog, 0, NULL); | 41 | mu_guile_load (prog, 0, NULL); |
45 | mu_guile_message_apply (msg, "mailutils-check-message"); | ||
46 | return 0; | 42 | return 0; |
47 | } | 43 | } |
48 | 44 | ||
49 | #endif | 45 | static int |
46 | scheme_proc (mu_script_descr_t descr, mu_message_t msg) | ||
47 | { | ||
48 | mu_guile_message_apply (msg, "mailutils-check-message"); | ||
49 | return 0; | ||
50 | } | ||
50 | 51 | ||
52 | struct mu_script_fun mu_script_scheme = { | ||
53 | "scheme", | ||
54 | "scm\0", | ||
55 | scheme_init, | ||
56 | NULL, | ||
57 | scheme_proc, | ||
58 | NULL | ||
59 | }; | ... | ... |
lib/muscript.h
0 → 100644
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | ||
2 | Copyright (C) 1999-2002, 2005, 2007, 2009-2012, 2014 Free Software | ||
3 | Foundation, Inc. | ||
4 | |||
5 | GNU Mailutils is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published by | ||
7 | the Free Software Foundation; either version 3, or (at your option) | ||
8 | any later version. | ||
9 | |||
10 | GNU Mailutils is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | GNU General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */ | ||
17 | |||
18 | #if defined(HAVE_CONFIG_H) | ||
19 | # include <config.h> | ||
20 | #endif | ||
21 | #include <mailutils/sieve.h> | ||
22 | #include <mailutils/diag.h> | ||
23 | #include <mailutils/errno.h> | ||
24 | #include <mailutils/error.h> | ||
25 | |||
26 | |||
27 | typedef struct mu_script_fun *mu_script_t; | ||
28 | typedef struct mu_script_descr *mu_script_descr_t; | ||
29 | |||
30 | mu_script_t mu_script_lang_handler (const char *lang); | ||
31 | mu_script_t mu_script_suffix_handler (const char *name); | ||
32 | |||
33 | int mu_script_init (mu_script_t scr, const char *name, mu_script_descr_t *); | ||
34 | int mu_script_done (mu_script_t, mu_script_descr_t); | ||
35 | int mu_script_process_msg (mu_script_t, mu_script_descr_t, mu_message_t msg); | ||
36 | void mu_script_log_enable (mu_script_t scr, mu_script_descr_t descr, | ||
37 | const char *name, const char *hdr); | ||
38 | |||
39 | int mu_script_debug_flags (const char *arg, char **endp); | ||
40 | |||
41 | extern int mu_script_debug_guile; | ||
42 | extern int mu_script_debug_sieve; | ||
43 | extern int mu_script_sieve_log; | ||
44 | |||
45 |
lib/muscript_priv.h
0 → 100644
1 | struct mu_script_fun | ||
2 | { | ||
3 | char *lang; | ||
4 | char *suf; | ||
5 | int (*script_init) (const char *, mu_script_descr_t *); | ||
6 | int (*script_done) (mu_script_descr_t); | ||
7 | int (*script_process) (mu_script_descr_t, mu_message_t); | ||
8 | int (*script_log_enable) (mu_script_descr_t descr, const char *name, | ||
9 | const char *hdr); | ||
10 | }; | ||
11 | |||
12 | extern struct mu_script_fun mu_script_python; | ||
13 | extern struct mu_script_fun mu_script_sieve; | ||
14 | extern struct mu_script_fun mu_script_scheme; |
... | @@ -14,41 +14,59 @@ | ... | @@ -14,41 +14,59 @@ |
14 | You should have received a copy of the GNU General Public License | 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/>. */ | 15 | along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */ |
16 | 16 | ||
17 | #include "maidag.h" | 17 | #include "muscript.h" |
18 | 18 | #include "muscript_priv.h" | |
19 | #ifdef WITH_PYTHON | ||
20 | #include <mailutils/python.h> | 19 | #include <mailutils/python.h> |
20 | #include <string.h> | ||
21 | |||
22 | static int | ||
23 | python_init (const char *prog, mu_script_descr_t *pdescr) | ||
24 | { | ||
25 | *pdescr = (mu_script_descr_t) strdup (prog); | ||
26 | if (!*pdescr) | ||
27 | return errno; | ||
28 | return 0; | ||
29 | } | ||
21 | 30 | ||
22 | int | 31 | static int |
23 | python_check_msg (mu_message_t msg, struct mu_auth_data *auth, | 32 | python_done (mu_script_descr_t descr) |
24 | const char *prog) | 33 | { |
34 | free (descr); | ||
35 | } | ||
36 | |||
37 | static int | ||
38 | python_proc (mu_script_descr_t descr, mu_message_t msg) | ||
25 | { | 39 | { |
26 | PyMessage *py_msg; | 40 | PyMessage *py_msg; |
27 | mu_py_dict dict[2]; | 41 | mu_py_dict dict[2]; |
28 | mu_py_script_data data[1]; | 42 | mu_py_script_data data[1]; |
29 | char *argv[] = { "maidag", NULL }; | 43 | char *argv[] = { NULL, NULL }; |
30 | 44 | ||
45 | argv[0] = mu_program_name; | ||
46 | |||
31 | mu_py_script_init (1, argv); | 47 | mu_py_script_init (1, argv); |
32 | 48 | ||
33 | if (!log_to_stderr) | ||
34 | { | ||
35 | /* FIXME */ | ||
36 | } | ||
37 | |||
38 | py_msg = PyMessage_NEW (); | 49 | py_msg = PyMessage_NEW (); |
39 | py_msg->msg = msg; | 50 | py_msg->msg = msg; |
40 | Py_INCREF (py_msg); | 51 | Py_INCREF (py_msg); |
41 | 52 | ||
42 | dict[0].name = "message"; | 53 | dict[0].name = "message"; |
43 | dict[0].obj = (PyObject *)py_msg; | 54 | dict[0].obj = (PyObject *)py_msg; |
44 | dict[1].name = NULL; | 55 | data[0].module_name = mu_program_name; |
45 | data[0].module_name = "maidag"; | ||
46 | data[0].attrs = dict; | 56 | data[0].attrs = dict; |
57 | dict[1].name = NULL; | ||
47 | 58 | ||
48 | mu_py_script_run (prog, data); | 59 | mu_py_script_run ((char*)descr, data); |
49 | mu_py_script_finish (); | 60 | mu_py_script_finish (); |
50 | return 0; | 61 | return 0; |
51 | } | 62 | } |
52 | 63 | ||
53 | #endif /* WITH_PYTHON */ | 64 | struct mu_script_fun mu_script_python = { |
65 | "python", | ||
66 | "py\0pyc\0", | ||
67 | python_init, | ||
68 | python_done, | ||
69 | python_proc, | ||
70 | NULL | ||
71 | }; | ||
54 | 72 | ... | ... |
lib/script.c
0 → 100644
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | ||
2 | Copyright (C) 1999-2002, 2005, 2007, 2009-2012, 2014 Free Software | ||
3 | Foundation, Inc. | ||
4 | |||
5 | GNU Mailutils is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published by | ||
7 | the Free Software Foundation; either version 3, or (at your option) | ||
8 | any later version. | ||
9 | |||
10 | GNU Mailutils is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | GNU General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */ | ||
17 | |||
18 | #include "muscript.h" | ||
19 | #include "muscript_priv.h" | ||
20 | |||
21 | int mu_script_debug_sieve; | ||
22 | int mu_script_debug_guile; | ||
23 | int mu_script_sieve_log; | ||
24 | |||
25 | struct mu_script_fun *script_tab[] = { | ||
26 | &mu_script_sieve, | ||
27 | #ifdef WITH_PYTHON | ||
28 | &mu_script_python, | ||
29 | #endif | ||
30 | #ifdef WITH_GUILE | ||
31 | &mu_script_scheme, | ||
32 | #endif | ||
33 | NULL | ||
34 | }; | ||
35 | |||
36 | int | ||
37 | mu_script_debug_flags (const char *arg, char **endp) | ||
38 | { | ||
39 | for (; *arg; arg++) | ||
40 | { | ||
41 | switch (*arg) | ||
42 | { | ||
43 | case 'g': | ||
44 | mu_script_debug_guile = 1; | ||
45 | break; | ||
46 | |||
47 | case 't': | ||
48 | mu_script_debug_sieve |= MU_SIEVE_DEBUG_TRACE; | ||
49 | break; | ||
50 | |||
51 | case 'i': | ||
52 | mu_script_debug_sieve |= MU_SIEVE_DEBUG_INSTR; | ||
53 | break; | ||
54 | |||
55 | case 'l': | ||
56 | mu_script_sieve_log = 1; | ||
57 | break; | ||
58 | |||
59 | default: | ||
60 | if (endp) | ||
61 | *endp = (char*) arg; | ||
62 | return 1; | ||
63 | } | ||
64 | } | ||
65 | return 0; | ||
66 | } | ||
67 | |||
68 | mu_script_t | ||
69 | mu_script_lang_handler (const char *lang) | ||
70 | { | ||
71 | int i; | ||
72 | |||
73 | for (i = 0; script_tab[i]; i++) | ||
74 | if (strcmp (script_tab[i]->lang, lang) == 0) | ||
75 | return script_tab[i]; | ||
76 | return NULL; | ||
77 | } | ||
78 | |||
79 | mu_script_t | ||
80 | mu_script_suffix_handler (const char *name) | ||
81 | { | ||
82 | int i; | ||
83 | char *suf; | ||
84 | |||
85 | suf = strrchr (name, '.'); | ||
86 | if (!suf) | ||
87 | return NULL; | ||
88 | suf++; | ||
89 | |||
90 | for (i = 0; script_tab[i]; i++) | ||
91 | { | ||
92 | char *s; | ||
93 | |||
94 | for (s = script_tab[i]->suf; *s; s += strlen (s) + 1) | ||
95 | if (strcmp (s, suf) == 0) | ||
96 | return script_tab[i]; | ||
97 | } | ||
98 | return NULL; | ||
99 | } | ||
100 | |||
101 | int | ||
102 | mu_script_init (mu_script_t scr, const char *name, mu_script_descr_t *pdescr) | ||
103 | { | ||
104 | return scr->script_init ? scr->script_init (name, pdescr) : 0; | ||
105 | } | ||
106 | |||
107 | int | ||
108 | mu_script_done (mu_script_t scr, mu_script_descr_t descr) | ||
109 | { | ||
110 | return scr->script_done ? scr->script_done (descr) : 0; | ||
111 | } | ||
112 | |||
113 | void | ||
114 | mu_script_log_enable (mu_script_t scr, mu_script_descr_t descr, | ||
115 | const char *name, const char *hdr) | ||
116 | { | ||
117 | if (scr->script_log_enable) | ||
118 | scr->script_log_enable (descr, name, hdr); | ||
119 | } | ||
120 | |||
121 | int | ||
122 | mu_script_process_msg (mu_script_t scr, mu_script_descr_t descr, | ||
123 | mu_message_t msg) | ||
124 | { | ||
125 | return scr->script_process (descr, msg); | ||
126 | } | ||
127 |
... | @@ -15,29 +15,41 @@ | ... | @@ -15,29 +15,41 @@ |
15 | You should have received a copy of the GNU General Public License | 15 | You should have received a copy of the GNU General Public License |
16 | along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */ | 16 | along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */ |
17 | 17 | ||
18 | #include "maidag.h" | 18 | #include "muscript.h" |
19 | #include "muscript_priv.h" | ||
20 | |||
21 | struct sieve_log_data | ||
22 | { | ||
23 | char *user; | ||
24 | char *hdr; | ||
25 | }; | ||
19 | 26 | ||
20 | static void | 27 | static void |
21 | _sieve_action_log (void *user_name, | 28 | _sieve_action_log (void *data, |
22 | mu_stream_t stream, size_t msgno, | 29 | mu_stream_t stream, size_t msgno, |
23 | mu_message_t msg, | 30 | mu_message_t msg, |
24 | const char *action, const char *fmt, va_list ap) | 31 | const char *action, const char *fmt, va_list ap) |
25 | { | 32 | { |
33 | struct sieve_log_data *ldat = data; | ||
26 | int pfx = 0; | 34 | int pfx = 0; |
27 | 35 | ||
28 | mu_stream_printf (stream, "\033s<%d>", MU_LOG_NOTICE); | 36 | mu_stream_printf (stream, "\033s<%d>", MU_LOG_NOTICE); |
29 | mu_stream_printf (stream, _("(user %s) "), (char*) user_name); | 37 | if (ldat) |
30 | if (message_id_header) | ||
31 | { | 38 | { |
32 | mu_header_t hdr = NULL; | 39 | if (ldat->user) |
33 | char *val = NULL; | 40 | mu_stream_printf (stream, _("(user %s) "), ldat->user); |
34 | mu_message_get_header (msg, &hdr); | 41 | if (ldat->hdr) |
35 | if (mu_header_aget_value (hdr, message_id_header, &val) == 0 | ||
36 | || mu_header_aget_value (hdr, MU_HEADER_MESSAGE_ID, &val) == 0) | ||
37 | { | 42 | { |
38 | pfx = 1; | 43 | mu_header_t hdr = NULL; |
39 | mu_stream_printf (stream, _("%s on msg %s"), action, val); | 44 | char *val = NULL; |
40 | free (val); | 45 | mu_message_get_header (msg, &hdr); |
46 | if (mu_header_aget_value (hdr, ldat->hdr, &val) == 0 | ||
47 | || mu_header_aget_value (hdr, MU_HEADER_MESSAGE_ID, &val) == 0) | ||
48 | { | ||
49 | pfx = 1; | ||
50 | mu_stream_printf (stream, _("%s on msg %s"), action, val); | ||
51 | free (val); | ||
52 | } | ||
41 | } | 53 | } |
42 | } | 54 | } |
43 | 55 | ||
... | @@ -57,29 +69,82 @@ _sieve_action_log (void *user_name, | ... | @@ -57,29 +69,82 @@ _sieve_action_log (void *user_name, |
57 | mu_stream_printf (stream, "\n"); | 69 | mu_stream_printf (stream, "\n"); |
58 | } | 70 | } |
59 | 71 | ||
60 | int | 72 | static int |
61 | sieve_check_msg (mu_message_t msg, struct mu_auth_data *auth, const char *prog) | 73 | sieve_init (const char *prog, mu_script_descr_t *pdescr) |
62 | { | 74 | { |
63 | int rc; | 75 | int rc; |
64 | mu_sieve_machine_t mach; | 76 | mu_sieve_machine_t mach; |
65 | 77 | ||
66 | rc = mu_sieve_machine_init (&mach); | 78 | rc = mu_sieve_machine_init (&mach); |
67 | if (rc) | 79 | if (rc == 0) |
68 | { | ||
69 | mu_error (_("Cannot initialize sieve machine: %s"), | ||
70 | mu_strerror (rc)); | ||
71 | } | ||
72 | else | ||
73 | { | 80 | { |
74 | mu_sieve_set_data (mach, auth->name); | 81 | mu_sieve_set_debug_level (mach, mu_script_debug_sieve); |
75 | if (sieve_enable_log) | 82 | if (mu_script_sieve_log) |
76 | mu_sieve_set_logger (mach, _sieve_action_log); | 83 | mu_sieve_set_logger (mach, _sieve_action_log); |
77 | |||
78 | rc = mu_sieve_compile (mach, prog); | 84 | rc = mu_sieve_compile (mach, prog); |
79 | if (rc == 0) | ||
80 | mu_sieve_message (mach, msg); | ||
81 | mu_sieve_machine_destroy (&mach); | ||
82 | } | 85 | } |
86 | *pdescr = (mu_script_descr_t) mach; | ||
87 | return rc; | ||
88 | } | ||
89 | |||
90 | static int | ||
91 | sieve_log_enable (mu_script_descr_t descr, const char *name, const char *hdr) | ||
92 | { | ||
93 | mu_sieve_machine_t mach = (mu_sieve_machine_t) descr; | ||
94 | struct sieve_log_data *ldat; | ||
95 | size_t size = 0; | ||
96 | char *p; | ||
97 | |||
98 | if (name) | ||
99 | size += strlen (name) + 1; | ||
100 | if (hdr) | ||
101 | size += strlen (hdr) + 1; | ||
102 | |||
103 | if (size) | ||
104 | { | ||
105 | ldat = calloc (1, sizeof (*ldat) + size); | ||
106 | if (!ldat) | ||
107 | return ENOMEM; | ||
108 | p = (char *) (ldat + 1); | ||
109 | if (name) | ||
110 | { | ||
111 | ldat->user = p; | ||
112 | p = mu_stpcpy (p, name) + 1; | ||
113 | } | ||
114 | if (hdr) | ||
115 | { | ||
116 | ldat->hdr = p; | ||
117 | strcpy (p, hdr); | ||
118 | } | ||
119 | |||
120 | mu_sieve_set_data (mach, ldat); | ||
121 | } | ||
122 | mu_sieve_set_logger (mach, _sieve_action_log); | ||
83 | return 0; | 123 | return 0; |
84 | } | 124 | } |
85 | 125 | ||
126 | static int | ||
127 | sieve_done (mu_script_descr_t descr) | ||
128 | { | ||
129 | mu_sieve_machine_t mach = (mu_sieve_machine_t) descr; | ||
130 | void *p = mu_sieve_get_data (mach); | ||
131 | free (p); | ||
132 | mu_sieve_machine_destroy (&mach); | ||
133 | return 0; | ||
134 | } | ||
135 | |||
136 | static int | ||
137 | sieve_proc (mu_script_descr_t descr, mu_message_t msg) | ||
138 | { | ||
139 | return mu_sieve_message ((mu_sieve_machine_t) descr, msg); | ||
140 | } | ||
141 | |||
142 | struct mu_script_fun mu_script_sieve = { | ||
143 | "sieve", | ||
144 | "sv\0siv\0sieve\0", | ||
145 | sieve_init, | ||
146 | sieve_done, | ||
147 | sieve_proc, | ||
148 | sieve_log_enable | ||
149 | }; | ||
150 | ... | ... |
... | @@ -19,13 +19,10 @@ sbin_PROGRAMS=maidag | ... | @@ -19,13 +19,10 @@ sbin_PROGRAMS=maidag |
19 | maidag_SOURCES=\ | 19 | maidag_SOURCES=\ |
20 | deliver.c\ | 20 | deliver.c\ |
21 | forward.c\ | 21 | forward.c\ |
22 | guile.c\ | ||
23 | lmtp.c\ | 22 | lmtp.c\ |
24 | maidag.c\ | 23 | maidag.c\ |
25 | maidag.h\ | 24 | maidag.h\ |
26 | mailquota.c\ | 25 | mailquota.c\ |
27 | python.c\ | ||
28 | sieve.c\ | ||
29 | script.c\ | 26 | script.c\ |
30 | util.c | 27 | util.c |
31 | 28 | ||
... | @@ -34,6 +31,7 @@ if MU_COND_DBM | ... | @@ -34,6 +31,7 @@ if MU_COND_DBM |
34 | endif | 31 | endif |
35 | 32 | ||
36 | maidag_LDADD = \ | 33 | maidag_LDADD = \ |
34 | ../lib/libmuscript.a\ | ||
37 | @LIBMU_SCM@ @GUILE_LIBS@\ | 35 | @LIBMU_SCM@ @GUILE_LIBS@\ |
38 | @LIBMU_SCM_DEPS@\ | 36 | @LIBMU_SCM_DEPS@\ |
39 | @MU_LIB_PY@ @PYTHON_LIBS@\ | 37 | @MU_LIB_PY@ @PYTHON_LIBS@\ | ... | ... |
... | @@ -30,7 +30,7 @@ char *quota_query = NULL; /* SQL query to retrieve mailbox quota */ | ... | @@ -30,7 +30,7 @@ char *quota_query = NULL; /* SQL query to retrieve mailbox quota */ |
30 | 30 | ||
31 | char *sender_address = NULL; | 31 | char *sender_address = NULL; |
32 | 32 | ||
33 | maidag_script_fun script_handler; | 33 | mu_script_t script_handler; |
34 | 34 | ||
35 | mu_list_t script_list; | 35 | mu_list_t script_list; |
36 | 36 | ||
... | @@ -62,7 +62,7 @@ static char doc[] = | ... | @@ -62,7 +62,7 @@ static char doc[] = |
62 | N_("GNU maidag -- the mail delivery agent.") | 62 | N_("GNU maidag -- the mail delivery agent.") |
63 | "\v" | 63 | "\v" |
64 | N_("Debug flags are:\n\ | 64 | N_("Debug flags are:\n\ |
65 | g - guimb stack traces\n\ | 65 | g - guile stack traces\n\ |
66 | t - sieve trace (MU_SIEVE_DEBUG_TRACE)\n\ | 66 | t - sieve trace (MU_SIEVE_DEBUG_TRACE)\n\ |
67 | i - sieve instructions trace (MU_SIEVE_DEBUG_INSTR)\n\ | 67 | i - sieve instructions trace (MU_SIEVE_DEBUG_INSTR)\n\ |
68 | l - sieve action logs\n\ | 68 | l - sieve action logs\n\ |
... | @@ -143,47 +143,28 @@ static const char *maidag_argp_capa[] = { | ... | @@ -143,47 +143,28 @@ static const char *maidag_argp_capa[] = { |
143 | NULL | 143 | NULL |
144 | }; | 144 | }; |
145 | 145 | ||
146 | #define D_DEFAULT "9,s" | ||
147 | |||
148 | static void | 146 | static void |
149 | set_debug_flags (const char *arg) | 147 | set_debug_flags (const char *arg) |
150 | { | 148 | { |
151 | while (*arg) | 149 | while (*arg) |
152 | { | 150 | { |
153 | if (mu_isdigit (*arg)) | 151 | if (mu_script_debug_flags (arg, (char**)&arg) == 0) |
152 | break; | ||
153 | else if (mu_isdigit (*arg)) | ||
154 | debug_level = strtoul (arg, (char**)&arg, 10); | 154 | debug_level = strtoul (arg, (char**)&arg, 10); |
155 | else | 155 | else |
156 | for (; *arg && *arg != ','; arg++) | 156 | { |
157 | { | 157 | mu_error (_("%c is not a valid debug flag"), *arg); |
158 | switch (*arg) | 158 | break; |
159 | { | 159 | } |
160 | case 'g': | 160 | |
161 | #ifdef WITH_GUILE | ||
162 | debug_guile = 1; | ||
163 | #endif | ||
164 | break; | ||
165 | |||
166 | case 't': | ||
167 | sieve_debug_flags |= MU_SIEVE_DEBUG_TRACE; | ||
168 | break; | ||
169 | |||
170 | case 'i': | ||
171 | sieve_debug_flags |= MU_SIEVE_DEBUG_INSTR; | ||
172 | break; | ||
173 | |||
174 | case 'l': | ||
175 | sieve_enable_log = 1; | ||
176 | break; | ||
177 | |||
178 | default: | ||
179 | mu_error (_("%c is not a valid debug flag"), *arg); | ||
180 | break; | ||
181 | } | ||
182 | } | ||
183 | if (*arg == ',') | 161 | if (*arg == ',') |
184 | arg++; | 162 | arg++; |
185 | else if (*arg) | 163 | else if (*arg) |
186 | mu_error (_("expected comma, but found %c"), *arg); | 164 | { |
165 | mu_error (_("expected comma, but found %c"), *arg); | ||
166 | exit (1); | ||
167 | } | ||
187 | } | 168 | } |
188 | } | 169 | } |
189 | 170 | ||
... | @@ -234,7 +215,7 @@ parse_opt (int key, char *arg, struct argp_state *state) | ... | @@ -234,7 +215,7 @@ parse_opt (int key, char *arg, struct argp_state *state) |
234 | break; | 215 | break; |
235 | 216 | ||
236 | case 'l': | 217 | case 'l': |
237 | script_handler = script_lang_handler (arg); | 218 | script_handler = mu_script_lang_handler (arg); |
238 | if (!script_handler) | 219 | if (!script_handler) |
239 | argp_error (state, _("unknown or unsupported language: %s"), | 220 | argp_error (state, _("unknown or unsupported language: %s"), |
240 | arg); | 221 | arg); |
... | @@ -256,7 +237,7 @@ parse_opt (int key, char *arg, struct argp_state *state) | ... | @@ -256,7 +237,7 @@ parse_opt (int key, char *arg, struct argp_state *state) |
256 | break; | 237 | break; |
257 | 238 | ||
258 | case 'x': | 239 | case 'x': |
259 | mu_argp_node_list_new (lst, "debug", arg ? arg : D_DEFAULT); | 240 | mu_argp_node_list_new (lst, "debug", arg); |
260 | break; | 241 | break; |
261 | 242 | ||
262 | case STDERR_OPTION: | 243 | case STDERR_OPTION: |
... | @@ -353,7 +334,7 @@ cb_script_language (void *data, mu_config_value_t *val) | ... | @@ -353,7 +334,7 @@ cb_script_language (void *data, mu_config_value_t *val) |
353 | { | 334 | { |
354 | if (mu_cfg_assert_value_type (val, MU_CFG_STRING)) | 335 | if (mu_cfg_assert_value_type (val, MU_CFG_STRING)) |
355 | return 1; | 336 | return 1; |
356 | script_handler = script_lang_handler (val->v.string); | 337 | script_handler = mu_script_lang_handler (val->v.string); |
357 | if (!script_handler) | 338 | if (!script_handler) |
358 | { | 339 | { |
359 | mu_error (_("unsupported language: %s"), val->v.string); | 340 | mu_error (_("unsupported language: %s"), val->v.string); |
... | @@ -457,7 +438,7 @@ struct mu_cfg_param maidag_cfg_param[] = { | ... | @@ -457,7 +438,7 @@ struct mu_cfg_param maidag_cfg_param[] = { |
457 | { "debug", mu_cfg_callback, NULL, 0, cb_debug, | 438 | { "debug", mu_cfg_callback, NULL, 0, cb_debug, |
458 | N_("Set maidag debug level. Debug level consists of one or more " | 439 | N_("Set maidag debug level. Debug level consists of one or more " |
459 | "of the following letters:\n" | 440 | "of the following letters:\n" |
460 | " g - guimb stack traces\n" | 441 | " g - guile stack traces\n" |
461 | " t - sieve trace (MU_SIEVE_DEBUG_TRACE)\n" | 442 | " t - sieve trace (MU_SIEVE_DEBUG_TRACE)\n" |
462 | " i - sieve instructions trace (MU_SIEVE_DEBUG_INSTR)\n" | 443 | " i - sieve instructions trace (MU_SIEVE_DEBUG_INSTR)\n" |
463 | " l - sieve action logs\n") }, | 444 | " l - sieve action logs\n") }, | ... | ... |
... | @@ -94,6 +94,7 @@ | ... | @@ -94,6 +94,7 @@ |
94 | #include "mailutils/libargp.h" | 94 | #include "mailutils/libargp.h" |
95 | 95 | ||
96 | #include "tcpwrap.h" | 96 | #include "tcpwrap.h" |
97 | #include "muscript.h" | ||
97 | 98 | ||
98 | /* Debug */ | 99 | /* Debug */ |
99 | extern int debug_level; | 100 | extern int debug_level; |
... | @@ -177,12 +178,12 @@ typedef int (*maidag_script_fun) (mu_message_t msg, | ... | @@ -177,12 +178,12 @@ typedef int (*maidag_script_fun) (mu_message_t msg, |
177 | struct mu_auth_data *auth, | 178 | struct mu_auth_data *auth, |
178 | const char *prog); | 179 | const char *prog); |
179 | 180 | ||
180 | extern maidag_script_fun script_handler; | 181 | extern mu_script_t script_handler; |
181 | 182 | ||
182 | struct maidag_script | 183 | struct maidag_script |
183 | { | 184 | { |
184 | maidag_script_fun fun; /* Handler function */ | 185 | mu_script_t scr; /* Handler script */ |
185 | const char *pat; /* Script name pattern */ | 186 | const char *pat; /* Script name pattern */ |
186 | }; | 187 | }; |
187 | 188 | ||
188 | maidag_script_fun script_lang_handler (const char *lang); | 189 | maidag_script_fun script_lang_handler (const char *lang); | ... | ... |
... | @@ -17,80 +17,27 @@ | ... | @@ -17,80 +17,27 @@ |
17 | 17 | ||
18 | #include "maidag.h" | 18 | #include "maidag.h" |
19 | 19 | ||
20 | struct script_tab | ||
21 | { | ||
22 | char *lang; | ||
23 | char *suf; | ||
24 | maidag_script_fun fun; | ||
25 | }; | ||
26 | |||
27 | struct script_tab script_tab[] = { | ||
28 | #ifdef WITH_PYTHON | ||
29 | { "python", "py\0pyc\0", python_check_msg }, | ||
30 | #endif | ||
31 | { "sieve", "sv\0siv\0sieve\0", sieve_check_msg }, | ||
32 | #ifdef WITH_GUILE | ||
33 | { "scheme", "scm\0", scheme_check_msg }, | ||
34 | #endif | ||
35 | { NULL } | ||
36 | }; | ||
37 | |||
38 | maidag_script_fun | ||
39 | script_lang_handler (const char *lang) | ||
40 | { | ||
41 | struct script_tab *p; | ||
42 | |||
43 | for (p = script_tab; p->lang; p++) | ||
44 | if (strcmp (p->lang, lang) == 0) | ||
45 | return p->fun; | ||
46 | return NULL; | ||
47 | } | ||
48 | |||
49 | maidag_script_fun | ||
50 | script_suffix_handler (const char *name) | ||
51 | { | ||
52 | struct script_tab *p; | ||
53 | char *suf; | ||
54 | |||
55 | suf = strrchr (name, '.'); | ||
56 | if (!suf) | ||
57 | return NULL; | ||
58 | suf++; | ||
59 | |||
60 | for (p = script_tab; p->lang; p++) | ||
61 | { | ||
62 | char *s; | ||
63 | |||
64 | for (s = p->suf; *s; s += strlen (s) + 1) | ||
65 | if (strcmp (s, suf) == 0) | ||
66 | return p->fun; | ||
67 | } | ||
68 | return NULL; | ||
69 | } | ||
70 | |||
71 | |||
72 | |||
73 | int | 20 | int |
74 | script_register (const char *pattern) | 21 | script_register (const char *pattern) |
75 | { | 22 | { |
76 | maidag_script_fun fun; | 23 | mu_script_t scr; |
77 | struct maidag_script *scr; | 24 | struct maidag_script *p; |
78 | 25 | ||
79 | if (script_handler) | 26 | if (script_handler) |
80 | fun = script_handler; | 27 | scr = script_handler; |
81 | else | 28 | else |
82 | { | 29 | { |
83 | fun = script_suffix_handler (pattern); | 30 | scr = mu_script_suffix_handler (pattern); |
84 | if (!fun) | 31 | if (!scr) |
85 | return EINVAL; | 32 | return EINVAL; |
86 | } | 33 | } |
87 | 34 | ||
88 | scr = malloc (sizeof (*scr)); | 35 | p = malloc (sizeof (*p)); |
89 | if (!scr) | 36 | if (!p) |
90 | return MU_ERR_FAILURE; | 37 | return MU_ERR_FAILURE; |
91 | 38 | ||
92 | scr->fun = fun; | 39 | p->scr = scr; |
93 | scr->pat = pattern; | 40 | p->pat = pattern; |
94 | 41 | ||
95 | if (!script_list) | 42 | if (!script_list) |
96 | { | 43 | { |
... | @@ -98,7 +45,7 @@ script_register (const char *pattern) | ... | @@ -98,7 +45,7 @@ script_register (const char *pattern) |
98 | return MU_ERR_FAILURE; | 45 | return MU_ERR_FAILURE; |
99 | } | 46 | } |
100 | 47 | ||
101 | if (mu_list_append (script_list, scr)) | 48 | if (mu_list_append (script_list, p)) |
102 | return MU_ERR_FAILURE; | 49 | return MU_ERR_FAILURE; |
103 | 50 | ||
104 | return 0; | 51 | return 0; |
... | @@ -119,6 +66,7 @@ apply_script (void *item, void *data) | ... | @@ -119,6 +66,7 @@ apply_script (void *item, void *data) |
119 | char *progfile; | 66 | char *progfile; |
120 | int rc; | 67 | int rc; |
121 | struct stat st; | 68 | struct stat st; |
69 | mu_script_descr_t sd; | ||
122 | 70 | ||
123 | progfile = mu_expand_path_pattern (scr->pat, clos->auth->name); | 71 | progfile = mu_expand_path_pattern (scr->pat, clos->auth->name); |
124 | if (stat (progfile, &st)) | 72 | if (stat (progfile, &st)) |
... | @@ -131,7 +79,21 @@ apply_script (void *item, void *data) | ... | @@ -131,7 +79,21 @@ apply_script (void *item, void *data) |
131 | return 0; | 79 | return 0; |
132 | } | 80 | } |
133 | 81 | ||
134 | rc = scr->fun (clos->msg, clos->auth, progfile); | 82 | rc = mu_script_init (scr->scr, progfile, &sd); |
83 | if (rc) | ||
84 | mu_error (_("initialization of script %s failed: %s"), | ||
85 | progfile, mu_strerror (rc)); | ||
86 | else | ||
87 | { | ||
88 | if (sieve_enable_log) | ||
89 | mu_script_log_enable (scr->scr, sd, clos->auth->name, | ||
90 | message_id_header); | ||
91 | rc = mu_script_process_msg (scr->scr, sd, clos->msg); | ||
92 | if (rc) | ||
93 | mu_error (_("script %s failed: %s"), progfile, mu_strerror (rc)); | ||
94 | mu_script_done (scr->scr, sd); | ||
95 | } | ||
96 | |||
135 | free (progfile); | 97 | free (progfile); |
136 | 98 | ||
137 | if (rc == 0) | 99 | if (rc == 0) | ... | ... |
... | @@ -125,6 +125,27 @@ pick_SOURCES = pick.c pick.h pick-gram.c pick-gram.h | ... | @@ -125,6 +125,27 @@ pick_SOURCES = pick.c pick.h pick-gram.c pick-gram.h |
125 | YLWRAP = $(SHELL) $(mu_aux_dir)/gylwrap | 125 | YLWRAP = $(SHELL) $(mu_aux_dir)/gylwrap |
126 | AM_YFLAGS=-vt | 126 | AM_YFLAGS=-vt |
127 | 127 | ||
128 | inc_LDADD = \ | ||
129 | ./libmh.a\ | ||
130 | ../lib/libmuaux.a\ | ||
131 | ../lib/libmuscript.a\ | ||
132 | @LIBMU_SCM@ @GUILE_LIBS@\ | ||
133 | @LIBMU_SCM_DEPS@\ | ||
134 | @MU_LIB_PY@ @PYTHON_LIBS@\ | ||
135 | ${MU_LIB_SIEVE}\ | ||
136 | ${MU_LIB_MBOX}\ | ||
137 | ${MU_LIB_IMAP}\ | ||
138 | ${MU_LIB_POP}\ | ||
139 | ${MU_LIB_MH}\ | ||
140 | ${MU_LIB_NNTP}\ | ||
141 | ${MU_LIB_MAILDIR}\ | ||
142 | ${MU_LIB_MAILER}\ | ||
143 | ${MU_LIB_AUTH}\ | ||
144 | @MU_AUTHLIBS@\ | ||
145 | ${MU_LIB_MAILUTILS}\ | ||
146 | @MU_COMMON_LIBRARIES@ | ||
147 | |||
148 | |||
128 | pick-gram.c pick-gram.h: $(srcdir)/pick.y | 149 | pick-gram.c pick-gram.h: $(srcdir)/pick.y |
129 | $(YLWRAP) "$(YACC) $(AM_YFLAGS) -d" $< \ | 150 | $(YLWRAP) "$(YACC) $(AM_YFLAGS) -d" $< \ |
130 | y.tab.c pick-gram.c y.tab.h pick-gram.h \ | 151 | y.tab.c pick-gram.c y.tab.h pick-gram.h \ | ... | ... |
... | @@ -18,9 +18,15 @@ | ... | @@ -18,9 +18,15 @@ |
18 | /* MH inc command */ | 18 | /* MH inc command */ |
19 | 19 | ||
20 | #include <mh.h> | 20 | #include <mh.h> |
21 | #include "muscript.h" | ||
21 | 22 | ||
22 | static char doc[] = N_("GNU MH inc")"\v" | 23 | static char doc[] = N_("GNU MH inc")"\v" |
23 | N_("Use -help to obtain the list of traditional MH options."); | 24 | N_("Debug flags are:\n\ |
25 | g - guile stack traces\n\ | ||
26 | t - sieve trace (MU_SIEVE_DEBUG_TRACE)\n\ | ||
27 | i - sieve instructions trace (MU_SIEVE_DEBUG_INSTR)\n\ | ||
28 | l - sieve action logs\n\n\ | ||
29 | Use -help to obtain the list of traditional MH options."); | ||
24 | static char args_doc[] = N_("[+FOLDER]"); | 30 | static char args_doc[] = N_("[+FOLDER]"); |
25 | 31 | ||
26 | /* GNU options */ | 32 | /* GNU options */ |
... | @@ -51,6 +57,12 @@ static struct argp_option options[] = { | ... | @@ -51,6 +57,12 @@ static struct argp_option options[] = { |
51 | N_("be quiet")}, | 57 | N_("be quiet")}, |
52 | {"notify", ARG_NOTIFY,N_("BOOL"), OPTION_ARG_OPTIONAL, | 58 | {"notify", ARG_NOTIFY,N_("BOOL"), OPTION_ARG_OPTIONAL, |
53 | N_("enable biff notification"), }, | 59 | N_("enable biff notification"), }, |
60 | {"language",ARG_LANG, N_("LANG"), 0, | ||
61 | N_("set language for the --script option") }, | ||
62 | {"script", ARG_SCRIPT,N_("FILE"), 0, | ||
63 | N_("filter incoming messages using script FILE") }, | ||
64 | {"debug", ARG_DEBUG, N_("FLAGS"), 0, | ||
65 | N_("enable debugging") }, | ||
54 | { 0 } | 66 | { 0 } |
55 | }; | 67 | }; |
56 | 68 | ||
... | @@ -67,6 +79,9 @@ struct mh_option mh_option[] = { | ... | @@ -67,6 +79,9 @@ struct mh_option mh_option[] = { |
67 | { "width", MH_OPT_ARG, "number" }, | 79 | { "width", MH_OPT_ARG, "number" }, |
68 | { "notify", MH_OPT_BOOL }, | 80 | { "notify", MH_OPT_BOOL }, |
69 | { "quiet" }, | 81 | { "quiet" }, |
82 | { "language", MH_OPT_ARG, "lang" }, | ||
83 | { "script", MH_OPT_ARG, "file" }, | ||
84 | { "debug", MH_OPT_ARG, "flags" }, | ||
70 | { NULL } | 85 | { NULL } |
71 | }; | 86 | }; |
72 | 87 | ||
... | @@ -81,11 +96,14 @@ static int quiet = 0; | ... | @@ -81,11 +96,14 @@ static int quiet = 0; |
81 | static int notify = 0; | 96 | static int notify = 0; |
82 | static const char *append_folder; | 97 | static const char *append_folder; |
83 | static const char *move_to_mailbox; | 98 | static const char *move_to_mailbox; |
99 | static const char *script_file; | ||
100 | static const char *script_lang; | ||
84 | 101 | ||
85 | static error_t | 102 | static error_t |
86 | opt_handler (int key, char *arg, struct argp_state *state) | 103 | opt_handler (int key, char *arg, struct argp_state *state) |
87 | { | 104 | { |
88 | int rc; | 105 | int rc; |
106 | char *p; | ||
89 | 107 | ||
90 | switch (key) | 108 | switch (key) |
91 | { | 109 | { |
... | @@ -106,6 +124,11 @@ opt_handler (int key, char *arg, struct argp_state *state) | ... | @@ -106,6 +124,11 @@ opt_handler (int key, char *arg, struct argp_state *state) |
106 | changecur = is_true (arg); | 124 | changecur = is_true (arg); |
107 | break; | 125 | break; |
108 | 126 | ||
127 | case ARG_DEBUG: | ||
128 | if (mu_script_debug_flags (arg, &p)) | ||
129 | argp_error (state, _("invalid debug flag near %s"), p); | ||
130 | break; | ||
131 | |||
109 | case ARG_NOCHANGECUR: | 132 | case ARG_NOCHANGECUR: |
110 | changecur = 0; | 133 | changecur = 0; |
111 | break; | 134 | break; |
... | @@ -169,6 +192,14 @@ opt_handler (int key, char *arg, struct argp_state *state) | ... | @@ -169,6 +192,14 @@ opt_handler (int key, char *arg, struct argp_state *state) |
169 | case ARG_NOTIFY: | 192 | case ARG_NOTIFY: |
170 | notify = is_true (arg);; | 193 | notify = is_true (arg);; |
171 | break; | 194 | break; |
195 | |||
196 | case ARG_LANG: | ||
197 | script_lang = arg; | ||
198 | break; | ||
199 | |||
200 | case ARG_SCRIPT: | ||
201 | script_file = arg; | ||
202 | break; | ||
172 | 203 | ||
173 | default: | 204 | default: |
174 | return ARGP_ERR_UNKNOWN; | 205 | return ARGP_ERR_UNKNOWN; |
... | @@ -196,6 +227,8 @@ struct incdat | ... | @@ -196,6 +227,8 @@ struct incdat |
196 | mu_mailbox_t output; | 227 | mu_mailbox_t output; |
197 | size_t lastmsg; | 228 | size_t lastmsg; |
198 | mh_format_t format; | 229 | mh_format_t format; |
230 | mu_script_t handler; | ||
231 | mu_script_descr_t descr; | ||
199 | }; | 232 | }; |
200 | 233 | ||
201 | static int | 234 | static int |
... | @@ -294,6 +327,23 @@ incmbx (void *item, void *data) | ... | @@ -294,6 +327,23 @@ incmbx (void *item, void *data) |
294 | continue; | 327 | continue; |
295 | } | 328 | } |
296 | 329 | ||
330 | if (dp->handler) | ||
331 | { | ||
332 | mu_attribute_t attr; | ||
333 | |||
334 | if (mu_script_process_msg (dp->handler, dp->descr, imsg)) | ||
335 | { | ||
336 | mu_error (_("%lu: filter failed: %s"), | ||
337 | (unsigned long) n, mu_strerror (rc)); | ||
338 | continue; | ||
339 | } | ||
340 | |||
341 | mu_message_get_attribute (imsg, &attr); | ||
342 | if (mu_attribute_is_deleted (attr)) | ||
343 | continue; | ||
344 | } | ||
345 | |||
346 | |||
297 | if ((rc = mu_mailbox_append_message (dp->output, imsg)) != 0) | 347 | if ((rc = mu_mailbox_append_message (dp->output, imsg)) != 0) |
298 | { | 348 | { |
299 | mu_error (_("%lu: error appending message: %s"), | 349 | mu_error (_("%lu: error appending message: %s"), |
... | @@ -379,10 +429,12 @@ main (int argc, char **argv) | ... | @@ -379,10 +429,12 @@ main (int argc, char **argv) |
379 | 429 | ||
380 | /* Native Language Support */ | 430 | /* Native Language Support */ |
381 | MU_APP_INIT_NLS (); | 431 | MU_APP_INIT_NLS (); |
382 | 432 | ||
383 | mh_argp_init (); | 433 | mh_argp_init (); |
384 | mh_argp_parse (&argc, &argv, 0, options, mh_option, args_doc, doc, | 434 | mh_argp_parse (&argc, &argv, 0, options, mh_option, args_doc, doc, |
385 | opt_handler, NULL, NULL); | 435 | opt_handler, NULL, NULL); |
436 | mu_registrar_set_default_scheme ("mh"); | ||
437 | |||
386 | /* Inc sets missing cur to 1 */ | 438 | /* Inc sets missing cur to 1 */ |
387 | mh_mailbox_cur_default = 1; | 439 | mh_mailbox_cur_default = 1; |
388 | 440 | ||
... | @@ -395,6 +447,38 @@ main (int argc, char **argv) | ... | @@ -395,6 +447,38 @@ main (int argc, char **argv) |
395 | 447 | ||
396 | incdat.output = mh_open_folder (append_folder, | 448 | incdat.output = mh_open_folder (append_folder, |
397 | MU_STREAM_READ|MU_STREAM_APPEND|MU_STREAM_CREAT); | 449 | MU_STREAM_READ|MU_STREAM_APPEND|MU_STREAM_CREAT); |
450 | |||
451 | if (script_file) | ||
452 | { | ||
453 | if (script_lang) | ||
454 | { | ||
455 | incdat.handler = mu_script_lang_handler (script_lang); | ||
456 | if (!incdat.handler) | ||
457 | { | ||
458 | mu_error (_("unknown or unsupported language: %s"), | ||
459 | script_lang); | ||
460 | exit (1); | ||
461 | } | ||
462 | } | ||
463 | else | ||
464 | { | ||
465 | incdat.handler = mu_script_suffix_handler (script_file); | ||
466 | if (!incdat.handler) | ||
467 | { | ||
468 | mu_error (_("unknown or unsupported language: %s"), | ||
469 | script_file); | ||
470 | exit (1); | ||
471 | } | ||
472 | } | ||
473 | rc = mu_script_init (incdat.handler, script_file, &incdat.descr); | ||
474 | if (rc) | ||
475 | { | ||
476 | mu_error (_("script initialization failed: %s"), | ||
477 | mu_strerror (rc)); | ||
478 | exit (1); | ||
479 | } | ||
480 | } | ||
481 | |||
398 | if (notify) | 482 | if (notify) |
399 | { | 483 | { |
400 | rc = mu_mailbox_set_notify (incdat.output, NULL); | 484 | rc = mu_mailbox_set_notify (incdat.output, NULL); |
... | @@ -424,6 +508,9 @@ main (int argc, char **argv) | ... | @@ -424,6 +508,9 @@ main (int argc, char **argv) |
424 | else | 508 | else |
425 | mu_list_foreach (input_file_list, incmbx, &incdat); | 509 | mu_list_foreach (input_file_list, incmbx, &incdat); |
426 | 510 | ||
511 | if (script_file) | ||
512 | mu_script_done (incdat.handler, incdat.descr); | ||
513 | |||
427 | unseen_seq = mh_global_profile_get ("Unseen-Sequence", NULL); | 514 | unseen_seq = mh_global_profile_get ("Unseen-Sequence", NULL); |
428 | if (unseen_seq && lastseen < incdat.lastmsg) | 515 | if (unseen_seq && lastseen < incdat.lastmsg) |
429 | { | 516 | { | ... | ... |
... | @@ -87,6 +87,7 @@ enum mh_arg { | ... | @@ -87,6 +87,7 @@ enum mh_arg { |
87 | ARG_HOST, | 87 | ARG_HOST, |
88 | ARG_INPLACE, | 88 | ARG_INPLACE, |
89 | ARG_INTERACTIVE, | 89 | ARG_INTERACTIVE, |
90 | ARG_LANG, | ||
90 | ARG_LBRACE, | 91 | ARG_LBRACE, |
91 | ARG_LENGTH, | 92 | ARG_LENGTH, |
92 | ARG_LIMIT, | 93 | ARG_LIMIT, |
... | @@ -166,6 +167,7 @@ enum mh_arg { | ... | @@ -166,6 +167,7 @@ enum mh_arg { |
166 | ARG_RECURSIVE, | 167 | ARG_RECURSIVE, |
167 | ARG_REORDER, | 168 | ARG_REORDER, |
168 | ARG_REVERSE, | 169 | ARG_REVERSE, |
170 | ARG_SCRIPT, | ||
169 | ARG_SEQUENCE, | 171 | ARG_SEQUENCE, |
170 | ARG_SERIALONLY, | 172 | ARG_SERIALONLY, |
171 | ARG_SHOW, | 173 | ARG_SHOW, | ... | ... |
-
Please register or sign in to post a comment