Initial implementation of a `prog' mailer.
* configure.ac: Enable/disable prog mailer support. * include/mailutils/progmailer.h: New file. * include/mailutils/Makefile.am (pkginclude_HEADERS): Add progmailer.h * include/mailutils/mailutils.h: Include progmailer.h * include/mailutils/registrar.h (MU_PROG_PRIO): New define. (mu_prog_record): New extern. (mu_register_all_mailer_formats): Register mu_prog_record. * include/mailutils/types.hin (mu_progmailer_t): New typedef. * libproto/include/registrar0.h (MU_PROG_SCHEME) (MU_PROG_SCHEME_LEN): New defines. * libproto/mailer/prog.c: New file. * libproto/mailer/Makefile.am (libmu_mailer_la_SOURCES): Add prog.c * libproto/mailer/sendmail.c: Rewrite using mu_progmailer_t * libproto/remote/folder.c (_remote_is_scheme): Remove unused variable. * mailbox/progmailer.c: New file * mailbox/Makefile.am (libmailutils_la_SOURCES): Add progmailer.c * mailbox/acl.c (_expand_aclno): Add a fixme. * mail/send.c (msg_to_pipe): Bugfix: use pclose, instead of fclose. * examples/config/mailutils.schema: Update.
Showing
17 changed files
with
756 additions
and
12 deletions
1 | 2008-10-25 Sergey Poznyakoff <gray@gnu.org.ua> | ||
2 | |||
3 | Initial implementation of a `prog' mailer. | ||
4 | |||
5 | * configure.ac: Enable/disable prog mailer support. | ||
6 | * include/mailutils/progmailer.h: New file. | ||
7 | * include/mailutils/Makefile.am (pkginclude_HEADERS): Add | ||
8 | progmailer.h | ||
9 | * include/mailutils/mailutils.h: Include progmailer.h | ||
10 | * include/mailutils/registrar.h (MU_PROG_PRIO): New define. | ||
11 | (mu_prog_record): New extern. | ||
12 | (mu_register_all_mailer_formats): Register mu_prog_record. | ||
13 | * include/mailutils/types.hin (mu_progmailer_t): New typedef. | ||
14 | * libproto/include/registrar0.h (MU_PROG_SCHEME) | ||
15 | (MU_PROG_SCHEME_LEN): New defines. | ||
16 | * libproto/mailer/prog.c: New file. | ||
17 | * libproto/mailer/Makefile.am (libmu_mailer_la_SOURCES): Add | ||
18 | prog.c | ||
19 | * libproto/mailer/sendmail.c: Rewrite using mu_progmailer_t | ||
20 | * libproto/remote/folder.c (_remote_is_scheme): Remove unused | ||
21 | variable. | ||
22 | * mailbox/progmailer.c: New file | ||
23 | * mailbox/Makefile.am (libmailutils_la_SOURCES): Add progmailer.c | ||
24 | |||
25 | * mailbox/acl.c (_expand_aclno): Add a fixme. | ||
26 | * mail/send.c (msg_to_pipe): Bugfix: use pclose, instead of fclose. | ||
27 | * examples/config/mailutils.schema: Update. | ||
28 | |||
1 | 2008-10-24 Sergey Poznyakoff <gray@gnu.org.ua> | 29 | 2008-10-24 Sergey Poznyakoff <gray@gnu.org.ua> |
2 | 30 | ||
3 | * examples/config/mailutils.dict: Use GNU OID number. | 31 | * examples/config/mailutils.dict: Use GNU OID number. | ... | ... |
... | @@ -767,10 +767,13 @@ MU_ENABLE_SUPPORT(nntp) | ... | @@ -767,10 +767,13 @@ MU_ENABLE_SUPPORT(nntp) |
767 | 767 | ||
768 | AC_SUBST(BUILD_SMTP_PROGRAMS) | 768 | AC_SUBST(BUILD_SMTP_PROGRAMS) |
769 | AC_SUBST(RUN_SMTP_DEJATOOL) | 769 | AC_SUBST(RUN_SMTP_DEJATOOL) |
770 | |||
770 | MU_ENABLE_SUPPORT(smtp, [BUILD_SMTP_PROGRAMS='$(PROGRAMS_SMTP)' | 771 | MU_ENABLE_SUPPORT(smtp, [BUILD_SMTP_PROGRAMS='$(PROGRAMS_SMTP)' |
771 | RUN_SMTP_DEJATOOL='$(SMTP_DEJATOOL)']) | 772 | RUN_SMTP_DEJATOOL='$(SMTP_DEJATOOL)']) |
772 | MU_ENABLE_SUPPORT(sendmail) | 773 | MU_ENABLE_SUPPORT(sendmail) |
773 | 774 | ||
775 | MU_ENABLE_SUPPORT(prog) | ||
776 | |||
774 | AC_SUBST(BUILD_MH_PROGRAMS) | 777 | AC_SUBST(BUILD_MH_PROGRAMS) |
775 | AC_SUBST(BUILD_MH_LIBRARIES) | 778 | AC_SUBST(BUILD_MH_LIBRARIES) |
776 | AC_SUBST(BUILD_MH_EXEC_HOOK) | 779 | AC_SUBST(BUILD_MH_EXEC_HOOK) | ... | ... |
1 | # This file is part of GNU Mailutils -- a suite of utilities for electronic | 1 | # This file is part of GNU Mailutils -- a suite of utilities for electronic |
2 | 2 | ||
3 | # Copyright (C) 2008 Free Software Foundation, Inc. | 3 | # Copyright (C) 2007, 2008 Free Software Foundation, Inc. |
4 | # | 4 | # |
5 | # GNU Mailutils is free software; you can redistribute it and/or | 5 | # GNU Mailutils is free software; you can redistribute it and/or |
6 | # modify it under the terms of the GNU General Public License as | 6 | # modify it under the terms of the GNU General Public License as |
... | @@ -13,7 +13,7 @@ | ... | @@ -13,7 +13,7 @@ |
13 | # GNU General Public License for more details. | 13 | # GNU General Public License for more details. |
14 | # | 14 | # |
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 this program. If not, see <http://www.gnu.org/licenses/>. | 16 | # along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. |
17 | 17 | ||
18 | # Mailutuls LDAP schema items | 18 | # Mailutuls LDAP schema items |
19 | # | 19 | # | ... | ... |
... | @@ -50,6 +50,7 @@ | ... | @@ -50,6 +50,7 @@ |
50 | #include <mailutils/opool.h> | 50 | #include <mailutils/opool.h> |
51 | #include <mailutils/parse822.h> | 51 | #include <mailutils/parse822.h> |
52 | #include <mailutils/pop3.h> | 52 | #include <mailutils/pop3.h> |
53 | #include <mailutils/progmailer.h> | ||
53 | #include <mailutils/property.h> | 54 | #include <mailutils/property.h> |
54 | #include <mailutils/refcount.h> | 55 | #include <mailutils/refcount.h> |
55 | #include <mailutils/registrar.h> | 56 | #include <mailutils/registrar.h> | ... | ... |
include/mailutils/progmailer.h
0 → 100644
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | ||
2 | Copyright (C) 2008 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 | #ifndef _MAILUTILS_PROGMAILER_H | ||
20 | #define _MAILUTILS_PROGMAILER_H | ||
21 | |||
22 | #include <mailutils/types.h> | ||
23 | |||
24 | #ifdef __cplusplus | ||
25 | extern "C" { | ||
26 | #endif | ||
27 | |||
28 | int mu_progmailer_create (mu_progmailer_t *pm); | ||
29 | int mu_progmailer_set_command (mu_progmailer_t pm, const char *command); | ||
30 | int mu_progmailer_sget_command (mu_progmailer_t pm, const char **command); | ||
31 | /* FIXME: missing _aget_ and _get_ */ | ||
32 | int mu_progmailer_set_debug (mu_progmailer_t pm, mu_debug_t debug); | ||
33 | int mu_progmailer_open (mu_progmailer_t pm, char **argv); | ||
34 | int mu_progmailer_send (mu_progmailer_t pm, mu_message_t msg); | ||
35 | int mu_progmailer_close (mu_progmailer_t pm); | ||
36 | void mu_progmailer_destroy (mu_progmailer_t *pm); | ||
37 | |||
38 | #ifdef __cplusplus | ||
39 | } | ||
40 | #endif | ||
41 | |||
42 | #endif /* _MAILUTILS_PROGMAILER_H */ | ||
43 |
... | @@ -121,11 +121,14 @@ extern mu_record_t mu_remote_mbox_record; | ... | @@ -121,11 +121,14 @@ extern mu_record_t mu_remote_mbox_record; |
121 | #define MU_REMOTE_MBOX_PRIO 10000 | 121 | #define MU_REMOTE_MBOX_PRIO 10000 |
122 | #define MU_SMTP_PRIO 10000 | 122 | #define MU_SMTP_PRIO 10000 |
123 | #define MU_SENDMAIL_PRIO 10000 | 123 | #define MU_SENDMAIL_PRIO 10000 |
124 | #define MU_PROG_PRIO 10000 | ||
124 | 125 | ||
125 | /* SMTP mailer, "smtp://" */ | 126 | /* SMTP mailer, "smtp://" */ |
126 | extern mu_record_t mu_smtp_record; | 127 | extern mu_record_t mu_smtp_record; |
127 | /* Sendmail, "sendmail:" */ | 128 | /* Sendmail, "sendmail:" */ |
128 | extern mu_record_t mu_sendmail_record; | 129 | extern mu_record_t mu_sendmail_record; |
130 | /* Program mailer, "prog://", "|" */ | ||
131 | extern mu_record_t mu_prog_record; | ||
129 | 132 | ||
130 | #define mu_register_all_mbox_formats() do {\ | 133 | #define mu_register_all_mbox_formats() do {\ |
131 | mu_registrar_record (mu_path_record);\ | 134 | mu_registrar_record (mu_path_record);\ |
... | @@ -156,6 +159,7 @@ extern mu_record_t mu_sendmail_record; | ... | @@ -156,6 +159,7 @@ extern mu_record_t mu_sendmail_record; |
156 | #define mu_register_all_mailer_formats() do {\ | 159 | #define mu_register_all_mailer_formats() do {\ |
157 | mu_registrar_record (mu_sendmail_record);\ | 160 | mu_registrar_record (mu_sendmail_record);\ |
158 | mu_registrar_record (mu_smtp_record);\ | 161 | mu_registrar_record (mu_smtp_record);\ |
162 | mu_registrar_record (mu_prog_record);\ | ||
159 | } while (0) | 163 | } while (0) |
160 | 164 | ||
161 | #define mu_register_extra_formats() do {\ | 165 | #define mu_register_extra_formats() do {\ | ... | ... |
... | @@ -111,6 +111,7 @@ typedef struct _mu_server *mu_server_t; | ... | @@ -111,6 +111,7 @@ typedef struct _mu_server *mu_server_t; |
111 | typedef struct _mu_ip_server *mu_ip_server_t; | 111 | typedef struct _mu_ip_server *mu_ip_server_t; |
112 | typedef struct _mu_m_server *mu_m_server_t; | 112 | typedef struct _mu_m_server *mu_m_server_t; |
113 | typedef struct _mu_opool *mu_opool_t; | 113 | typedef struct _mu_opool *mu_opool_t; |
114 | typedef struct _mu_progmailer *mu_progmailer_t; | ||
114 | 115 | ||
115 | #define MU_FOLDER_ATTRIBUTE_DIRECTORY 0x001 | 116 | #define MU_FOLDER_ATTRIBUTE_DIRECTORY 0x001 |
116 | #define MU_FOLDER_ATTRIBUTE_FILE 0x002 | 117 | #define MU_FOLDER_ATTRIBUTE_FILE 0x002 | ... | ... |
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | 1 | /* GNU Mailutils -- a suite of utilities for electronic mail |
2 | Copyright (C) 1999, 2000, 2004, 2005, 2007 Free Software Foundation, Inc. | 2 | Copyright (C) 1999, 2000, 2004, 2005, 2007, 2008 Free Software Foundation, Inc. |
3 | 3 | ||
4 | This library is free software; you can redistribute it and/or | 4 | This library is free software; you can redistribute it and/or |
5 | modify it under the terms of the GNU Lesser General Public | 5 | modify it under the terms of the GNU Lesser General Public |
... | @@ -19,10 +19,6 @@ | ... | @@ -19,10 +19,6 @@ |
19 | #ifndef _REGISTRAR0_H | 19 | #ifndef _REGISTRAR0_H |
20 | #define _REGISTRAR0_H | 20 | #define _REGISTRAR0_H |
21 | 21 | ||
22 | #ifdef DMALLOC | ||
23 | # include <dmalloc.h> | ||
24 | #endif | ||
25 | |||
26 | #include <mailutils/registrar.h> | 22 | #include <mailutils/registrar.h> |
27 | 23 | ||
28 | #ifdef __cplusplus | 24 | #ifdef __cplusplus |
... | @@ -85,6 +81,9 @@ extern int _mailer_smtp_init (mu_mailer_t); | ... | @@ -85,6 +81,9 @@ extern int _mailer_smtp_init (mu_mailer_t); |
85 | extern int _url_sendmail_init (mu_url_t); | 81 | extern int _url_sendmail_init (mu_url_t); |
86 | extern int _mailer_sendmail_init (mu_mailer_t); | 82 | extern int _mailer_sendmail_init (mu_mailer_t); |
87 | 83 | ||
84 | #define MU_PROG_SCHEME "prog" | ||
85 | #define MU_PROG_SCHEME_LEN (sizeof (MU_PROG_SCHEME) - 1) | ||
86 | |||
88 | #define MU_MH_SCHEME "mh" | 87 | #define MU_MH_SCHEME "mh" |
89 | #define MU_MH_SCHEME_LEN (sizeof (MU_MH_SCHEME) - 1) | 88 | #define MU_MH_SCHEME_LEN (sizeof (MU_MH_SCHEME) - 1) |
90 | extern int _mailbox_mh_init (mu_mailbox_t mailbox); | 89 | extern int _mailbox_mh_init (mu_mailbox_t mailbox); | ... | ... |
1 | ## Process this file with GNU Automake to create Makefile.in | 1 | ## Process this file with GNU Automake to create Makefile.in |
2 | 2 | ||
3 | ## Copyright (C) 2007 Free Software Foundation, Inc. | 3 | ## Copyright (C) 2007, 2008 Free Software Foundation, Inc. |
4 | ## | 4 | ## |
5 | ## GNU Mailutils is free software; you can redistribute it and/or | 5 | ## GNU Mailutils is free software; you can redistribute it and/or |
6 | ## modify it under the terms of the GNU General Public License as | 6 | ## modify it under the terms of the GNU General Public License as |
... | @@ -24,6 +24,7 @@ libmu_mailer_la_LDFLAGS=-version-info @VI_CURRENT@:@VI_REVISION@:@VI_AGE@ | ... | @@ -24,6 +24,7 @@ libmu_mailer_la_LDFLAGS=-version-info @VI_CURRENT@:@VI_REVISION@:@VI_AGE@ |
24 | libmu_mailer_la_LIBADD = ${MU_LIB_AUTH} ${MU_LIB_MAILUTILS} @INTLLIBS@ | 24 | libmu_mailer_la_LIBADD = ${MU_LIB_AUTH} ${MU_LIB_MAILUTILS} @INTLLIBS@ |
25 | 25 | ||
26 | libmu_mailer_la_SOURCES = \ | 26 | libmu_mailer_la_SOURCES = \ |
27 | prog.c\ | ||
27 | sendmail.c\ | 28 | sendmail.c\ |
28 | smtp.c\ | 29 | smtp.c\ |
29 | url_sendmail.c\ | 30 | url_sendmail.c\ | ... | ... |
libproto/mailer/prog.c
0 → 100644
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | ||
2 | Copyright (C) 2008 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, | ||
16 | see <http://www.gnu.org/licenses/>. */ | ||
17 | |||
18 | #ifdef HAVE_CONFIG_H | ||
19 | # include <config.h> | ||
20 | #endif | ||
21 | |||
22 | #ifdef ENABLE_PROG | ||
23 | #include <stdlib.h> | ||
24 | #include <errno.h> | ||
25 | #include <unistd.h> | ||
26 | |||
27 | #include <mailutils/address.h> | ||
28 | #include <mailutils/argcv.h> | ||
29 | #include <mailutils/debug.h> | ||
30 | #include <mailutils/errno.h> | ||
31 | #include <mailutils/header.h> | ||
32 | #include <mailutils/message.h> | ||
33 | #include <mailutils/observer.h> | ||
34 | #include <mailutils/progmailer.h> | ||
35 | #include <mailutils/vartab.h> | ||
36 | |||
37 | #include <url0.h> | ||
38 | #include <mailer0.h> | ||
39 | #include <registrar0.h> | ||
40 | |||
41 | static int _url_prog_init (mu_url_t); | ||
42 | static int _url_pipe_init (mu_url_t); | ||
43 | static int _mailer_prog_init (mu_mailer_t); | ||
44 | |||
45 | static struct _mu_record _prog_record = | ||
46 | { | ||
47 | MU_PROG_PRIO, | ||
48 | MU_PROG_SCHEME, | ||
49 | _url_prog_init, /* url init. */ | ||
50 | NULL, /* Mailbox entry. */ | ||
51 | _mailer_prog_init, /* Mailer entry. */ | ||
52 | NULL, /* Folder entry. */ | ||
53 | NULL, /* No need for a back pointer. */ | ||
54 | NULL, /* _is_scheme method. */ | ||
55 | NULL, /* _get_url method. */ | ||
56 | NULL, /* _get_mailbox method. */ | ||
57 | NULL, /* _get_mailer method. */ | ||
58 | NULL /* _get_folder method. */ | ||
59 | }; | ||
60 | |||
61 | mu_record_t mu_prog_record = &_prog_record; | ||
62 | |||
63 | |||
64 | static int | ||
65 | _url_prog_init (mu_url_t url) | ||
66 | { | ||
67 | int status = mu_url_init (url, 0, "prog"); | ||
68 | if (status) | ||
69 | return status; | ||
70 | /* not valid in a sendmail url */ | ||
71 | if (url->user || url->passwd || url->auth || url->host || url->port) | ||
72 | return EINVAL; | ||
73 | if (!url->path) | ||
74 | return EINVAL; | ||
75 | return 0; | ||
76 | } | ||
77 | |||
78 | |||
79 | static void prog_destroy (mu_mailer_t); | ||
80 | static int prog_open (mu_mailer_t, int); | ||
81 | static int prog_close (mu_mailer_t); | ||
82 | static int prog_send_message (mu_mailer_t, mu_message_t, mu_address_t, | ||
83 | mu_address_t); | ||
84 | |||
85 | static int | ||
86 | _mailer_prog_init (mu_mailer_t mailer) | ||
87 | { | ||
88 | int status; | ||
89 | mu_progmailer_t pm; | ||
90 | |||
91 | status = mu_progmailer_create (&pm); | ||
92 | if (status) | ||
93 | return status; | ||
94 | |||
95 | mailer->data = pm; | ||
96 | mailer->_destroy = prog_destroy; | ||
97 | mailer->_open = prog_open; | ||
98 | mailer->_close = prog_close; | ||
99 | mailer->_send_message = prog_send_message; | ||
100 | |||
101 | return 0; | ||
102 | } | ||
103 | |||
104 | static void | ||
105 | prog_destroy (mu_mailer_t mailer) | ||
106 | { | ||
107 | mu_progmailer_destroy ((mu_progmailer_t*)&mailer->data); | ||
108 | } | ||
109 | |||
110 | static int | ||
111 | prog_open (mu_mailer_t mailer, int flags) | ||
112 | { | ||
113 | mu_progmailer_t pm = mailer->data; | ||
114 | int status; | ||
115 | const char *path; | ||
116 | |||
117 | /* Sanity checks. */ | ||
118 | if (pm == NULL) | ||
119 | return EINVAL; | ||
120 | |||
121 | mailer->flags = flags; | ||
122 | |||
123 | if ((status = mu_url_sget_path (mailer->url, &path))) | ||
124 | return status; | ||
125 | |||
126 | if (access (path, X_OK) == -1) | ||
127 | return errno; | ||
128 | |||
129 | mu_progmailer_set_debug (pm, mailer->debug); | ||
130 | status = mu_progmailer_set_command (pm, path); | ||
131 | MU_DEBUG1 (mailer->debug, MU_DEBUG_TRACE, "prog (%s)\n", path); | ||
132 | return status; | ||
133 | } | ||
134 | |||
135 | static int | ||
136 | prog_close (mu_mailer_t mailer) | ||
137 | { | ||
138 | return mu_progmailer_close (mailer->data); | ||
139 | } | ||
140 | |||
141 | static int | ||
142 | _expand_sender (const char *name, void *data, char **p) | ||
143 | { | ||
144 | mu_address_t addr = data; | ||
145 | const char *email; | ||
146 | int status = mu_address_sget_email (addr, 1, &email); | ||
147 | |||
148 | if (status != 0) | ||
149 | return status; | ||
150 | *(const char**)p = email; | ||
151 | return 0; | ||
152 | } | ||
153 | |||
154 | struct ex_rcpt | ||
155 | { | ||
156 | mu_message_t msg; | ||
157 | mu_address_t addr; | ||
158 | char *string; | ||
159 | }; | ||
160 | |||
161 | static int | ||
162 | address_add (mu_address_t *paddr, const char *value) | ||
163 | { | ||
164 | mu_address_t addr = NULL; | ||
165 | int status; | ||
166 | |||
167 | status = mu_address_create (&addr, value); | ||
168 | if (status) | ||
169 | return status; | ||
170 | status = mu_address_union (paddr, addr); | ||
171 | mu_address_destroy (&addr); | ||
172 | return status; | ||
173 | } | ||
174 | |||
175 | static int | ||
176 | message_read_rcpt (mu_message_t msg, mu_address_t *paddr) | ||
177 | { | ||
178 | mu_header_t header = NULL; | ||
179 | const char *value; | ||
180 | int status; | ||
181 | |||
182 | status = mu_message_get_header (msg, &header); | ||
183 | if (status) | ||
184 | return status; | ||
185 | |||
186 | status = mu_header_sget_value (header, MU_HEADER_TO, &value); | ||
187 | |||
188 | if (status == 0) | ||
189 | address_add (paddr, value); | ||
190 | else if (status != MU_ERR_NOENT) | ||
191 | return status; | ||
192 | |||
193 | status = mu_header_sget_value (header, MU_HEADER_CC, &value); | ||
194 | if (status == 0) | ||
195 | address_add (paddr, value); | ||
196 | else if (status != MU_ERR_NOENT) | ||
197 | return status; | ||
198 | |||
199 | status = mu_header_sget_value (header, MU_HEADER_BCC, &value); | ||
200 | if (status == 0) | ||
201 | address_add (paddr, value); | ||
202 | else if (status != MU_ERR_NOENT) | ||
203 | return status; | ||
204 | return 0; | ||
205 | } | ||
206 | |||
207 | static int | ||
208 | _expand_rcpt (const char *name, void *data, char **p) | ||
209 | { | ||
210 | struct ex_rcpt *exrcpt = data; | ||
211 | int status; | ||
212 | |||
213 | if (!exrcpt->string) | ||
214 | { | ||
215 | size_t i, count = 0; | ||
216 | size_t len = 0; | ||
217 | char *str; | ||
218 | mu_address_t tmp_addr = NULL, addr; | ||
219 | |||
220 | if (exrcpt->addr) | ||
221 | addr = exrcpt->addr; | ||
222 | else | ||
223 | { | ||
224 | status = message_read_rcpt (exrcpt->msg, &tmp_addr); | ||
225 | if (status) | ||
226 | { | ||
227 | mu_address_destroy (&tmp_addr); | ||
228 | return status; | ||
229 | } | ||
230 | addr = tmp_addr; | ||
231 | } | ||
232 | |||
233 | mu_address_get_count (addr, &count); | ||
234 | for (i = 1; i <= count; i++) | ||
235 | { | ||
236 | const char *email; | ||
237 | if (i > 1) | ||
238 | len++; | ||
239 | if ((status = mu_address_sget_email (addr, i, &email)) != 0) | ||
240 | { | ||
241 | mu_address_destroy (&tmp_addr); | ||
242 | return status; | ||
243 | } | ||
244 | len += strlen (email); | ||
245 | } | ||
246 | |||
247 | str = malloc (len + 1); | ||
248 | if (!str) | ||
249 | { | ||
250 | mu_address_destroy (&tmp_addr); | ||
251 | return ENOMEM; | ||
252 | } | ||
253 | exrcpt->string = str; | ||
254 | |||
255 | for (i = 1; i <= count; i++) | ||
256 | { | ||
257 | const char *email; | ||
258 | if (i > 1) | ||
259 | *str++ = ' '; | ||
260 | if (mu_address_sget_email (addr, i, &email)) | ||
261 | continue; | ||
262 | strcpy (str, email); | ||
263 | str += strlen (email); | ||
264 | } | ||
265 | *str = 0; | ||
266 | mu_address_destroy (&tmp_addr); | ||
267 | } | ||
268 | *p = exrcpt->string; | ||
269 | return 0; | ||
270 | } | ||
271 | |||
272 | void | ||
273 | _free_rcpt (void *data, char *value) | ||
274 | { | ||
275 | free (value); | ||
276 | } | ||
277 | |||
278 | static int | ||
279 | url_to_argv (mu_url_t url, mu_message_t msg, | ||
280 | mu_address_t from, mu_address_t to, | ||
281 | int *pargc, char ***pargv) | ||
282 | { | ||
283 | int rc; | ||
284 | mu_vartab_t vtab; | ||
285 | struct ex_rcpt ex_rcpt; | ||
286 | const char *query; | ||
287 | char *cmdargs; | ||
288 | int argc; | ||
289 | char **argv; | ||
290 | |||
291 | ex_rcpt.msg = msg; | ||
292 | ex_rcpt.addr = to; | ||
293 | ex_rcpt.string = NULL; | ||
294 | mu_vartab_create (&vtab); | ||
295 | mu_vartab_define_exp (vtab, "sender", _expand_sender, NULL, from); | ||
296 | mu_vartab_define_exp (vtab, "rcpt", _expand_rcpt, _free_rcpt, &ex_rcpt); | ||
297 | |||
298 | rc = mu_url_sget_query (url, &query); | ||
299 | if (rc) | ||
300 | return rc; | ||
301 | |||
302 | rc = mu_vartab_expand (vtab, query, &cmdargs); | ||
303 | mu_vartab_destroy (&vtab); | ||
304 | if (rc) | ||
305 | return rc; | ||
306 | |||
307 | rc = mu_argcv_get_np (cmdargs, strlen (cmdargs), | ||
308 | "&", NULL, | ||
309 | 0, &argc, &argv, NULL); | ||
310 | free (cmdargs); | ||
311 | if (rc) | ||
312 | return rc; | ||
313 | argv = realloc (argv, (argc + 2) * sizeof (argv[0])); | ||
314 | memmove (argv + 1, argv, (argc + 1) * sizeof (argv[0])); | ||
315 | mu_url_aget_path (url, &argv[0]); | ||
316 | |||
317 | *pargc = argc + 1; | ||
318 | *pargv = argv; | ||
319 | return 0; | ||
320 | } | ||
321 | |||
322 | static int | ||
323 | prog_send_message (mu_mailer_t mailer, mu_message_t msg, mu_address_t from, | ||
324 | mu_address_t to) | ||
325 | { | ||
326 | mu_progmailer_t pm = mailer->data; | ||
327 | int argc; | ||
328 | char **argv; | ||
329 | int status; | ||
330 | |||
331 | status = url_to_argv(mailer->url, msg, from, to, &argc, &argv); | ||
332 | if (status) | ||
333 | { | ||
334 | MU_DEBUG1 (mailer->debug, MU_DEBUG_ERROR, | ||
335 | "cannot convert URL to command line: %s\n", | ||
336 | mu_strerror (status)); | ||
337 | return status; | ||
338 | } | ||
339 | |||
340 | mu_progmailer_set_debug (pm, mailer->debug); | ||
341 | status = mu_progmailer_open (pm, argv); | ||
342 | if (status == 0) | ||
343 | { | ||
344 | status = mu_progmailer_send (pm, msg); | ||
345 | if (status == 0) | ||
346 | mu_observable_notify (mailer->observable, MU_EVT_MAILER_MESSAGE_SENT, | ||
347 | msg); | ||
348 | else | ||
349 | MU_DEBUG1 (mailer->debug, MU_DEBUG_ERROR, | ||
350 | "progmailer error: %s\n", | ||
351 | mu_strerror (status)); | ||
352 | } | ||
353 | |||
354 | mu_argcv_free (argc, argv); | ||
355 | return status; | ||
356 | } | ||
357 | |||
358 | #else | ||
359 | #include <stdio.h> | ||
360 | #include <registrar0.h> | ||
361 | mu_record_t mu_prog_record = NULL; | ||
362 | #endif |
This diff is collapsed.
Click to expand it.
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | 1 | /* GNU Mailutils -- a suite of utilities for electronic mail |
2 | Copyright (C) 2007 Free Software Foundation, Inc. | 2 | Copyright (C) 2007, 2008 Free Software Foundation, Inc. |
3 | 3 | ||
4 | This library is free software; you can redistribute it and/or | 4 | This library is free software; you can redistribute it and/or |
5 | modify it under the terms of the GNU Lesser General Public | 5 | modify it under the terms of the GNU Lesser General Public |
... | @@ -46,7 +46,6 @@ _remote_is_scheme (mu_record_t record, mu_url_t url, int flags) | ... | @@ -46,7 +46,6 @@ _remote_is_scheme (mu_record_t record, mu_url_t url, int flags) |
46 | { | 46 | { |
47 | char *scheme = url->scheme; | 47 | char *scheme = url->scheme; |
48 | size_t scheme_len = scheme ? strlen (scheme) : 0; | 48 | size_t scheme_len = scheme ? strlen (scheme) : 0; |
49 | int rc; | ||
50 | struct _mu_url s_url; | 49 | struct _mu_url s_url; |
51 | 50 | ||
52 | if (!scheme | 51 | if (!scheme | ... | ... |
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | 1 | /* GNU Mailutils -- a suite of utilities for electronic mail |
2 | Copyright (C) 1999, 2001, 2002, 2003, 2004, | 2 | Copyright (C) 1999, 2001, 2002, 2003, 2004, |
3 | 2005, 2006, 2007 Free Software Foundation, Inc. | 3 | 2005, 2006, 2007, 2008 Free Software Foundation, Inc. |
4 | 4 | ||
5 | GNU Mailutils is free software; you can redistribute it and/or modify | 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 | 6 | it under the terms of the GNU General Public License as published by |
... | @@ -666,7 +666,7 @@ msg_to_pipe (const char *cmd, mu_message_t msg) | ... | @@ -666,7 +666,7 @@ msg_to_pipe (const char *cmd, mu_message_t msg) |
666 | fprintf (fp, "%s", buffer); | 666 | fprintf (fp, "%s", buffer); |
667 | off += n; | 667 | off += n; |
668 | } | 668 | } |
669 | fclose (fp); | 669 | pclose (fp); |
670 | } | 670 | } |
671 | else | 671 | else |
672 | util_error (_("Piping %s failed"), cmd); | 672 | util_error (_("Piping %s failed"), cmd); | ... | ... |
... | @@ -108,6 +108,7 @@ libmailutils_la_SOURCES = \ | ... | @@ -108,6 +108,7 @@ libmailutils_la_SOURCES = \ |
108 | opool.c\ | 108 | opool.c\ |
109 | parse822.c\ | 109 | parse822.c\ |
110 | parsedate.c\ | 110 | parsedate.c\ |
111 | progmailer.c\ | ||
111 | property.c\ | 112 | property.c\ |
112 | registrar.c\ | 113 | registrar.c\ |
113 | refcount.c\ | 114 | refcount.c\ | ... | ... |
... | @@ -501,6 +501,7 @@ _expand_aclno (const char *name, void *data, char **p) | ... | @@ -501,6 +501,7 @@ _expand_aclno (const char *name, void *data, char **p) |
501 | { | 501 | { |
502 | struct run_closure *rp = data; | 502 | struct run_closure *rp = data; |
503 | char buf[UINTMAX_STRSIZE_BOUND]; | 503 | char buf[UINTMAX_STRSIZE_BOUND]; |
504 | /*FIXME: memory leak*/ | ||
504 | *p = strdup (umaxtostr (rp->idx, buf)); | 505 | *p = strdup (umaxtostr (rp->idx, buf)); |
505 | return 0; | 506 | return 0; |
506 | } | 507 | } | ... | ... |
mailbox/progmailer.c
0 → 100644
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | ||
2 | Copyright (C) 1999, 2000, 2001, 2004, 2005, | ||
3 | 2006, 2007, 2008 Free Software Foundation, Inc. | ||
4 | |||
5 | This library is free software; you can redistribute it and/or | ||
6 | modify it under the terms of the GNU Lesser General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 3 of the License, or (at your option) any later version. | ||
9 | |||
10 | This library 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 GNU | ||
13 | Lesser General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Lesser General | ||
16 | Public License along with this library; if not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301 USA */ | ||
19 | |||
20 | #ifdef HAVE_CONFIG_H | ||
21 | # include <config.h> | ||
22 | #endif | ||
23 | |||
24 | #include <errno.h> | ||
25 | #include <stdio.h> | ||
26 | #include <stdlib.h> | ||
27 | #include <string.h> | ||
28 | #include <unistd.h> | ||
29 | #include <sysexits.h> | ||
30 | |||
31 | #include <sys/types.h> | ||
32 | #include <sys/wait.h> | ||
33 | |||
34 | #include <mailutils/debug.h> | ||
35 | #include <mailutils/error.h> | ||
36 | #include <mailutils/errno.h> | ||
37 | #include <mailutils/stream.h> | ||
38 | #include <mailutils/header.h> | ||
39 | #include <mailutils/body.h> | ||
40 | #include <mailutils/message.h> | ||
41 | #include <mailutils/progmailer.h> | ||
42 | |||
43 | struct _mu_progmailer | ||
44 | { | ||
45 | int fd; | ||
46 | pid_t pid; | ||
47 | RETSIGTYPE (*sighandler)(); | ||
48 | mu_debug_t debug; | ||
49 | char *command; | ||
50 | }; | ||
51 | |||
52 | /* Close FD unless it is part of pipe P */ | ||
53 | #define SCLOSE(fd,p) if (p[0]!=fd&&p[1]!=fd) close(fd) | ||
54 | |||
55 | int | ||
56 | mu_progmailer_create (struct _mu_progmailer **ppm) | ||
57 | { | ||
58 | struct _mu_progmailer *pm = malloc (sizeof (*pm)); | ||
59 | if (!pm) | ||
60 | return ENOMEM; | ||
61 | pm->fd = -1; | ||
62 | pm->pid = -1; | ||
63 | pm->sighandler = SIG_ERR; | ||
64 | pm->debug = NULL; | ||
65 | pm->command = NULL; | ||
66 | *ppm = pm; | ||
67 | return 0; | ||
68 | } | ||
69 | |||
70 | int | ||
71 | mu_progmailer_set_command (mu_progmailer_t pm, const char *command) | ||
72 | { | ||
73 | if (!pm) | ||
74 | return EINVAL; | ||
75 | free (pm->command); | ||
76 | if (command) | ||
77 | { | ||
78 | pm->command = strdup (command); | ||
79 | if (!pm->command) | ||
80 | return EINVAL; | ||
81 | } | ||
82 | else | ||
83 | pm->command = NULL; | ||
84 | return 0; | ||
85 | } | ||
86 | |||
87 | int | ||
88 | mu_progmailer_sget_command (mu_progmailer_t pm, const char **command) | ||
89 | { | ||
90 | if (!pm) | ||
91 | return EINVAL; | ||
92 | *command = pm->command; | ||
93 | return 0; | ||
94 | } | ||
95 | |||
96 | int | ||
97 | mu_progmailer_set_debug (mu_progmailer_t pm, mu_debug_t debug) | ||
98 | { | ||
99 | if (!pm) | ||
100 | return EINVAL; | ||
101 | pm->debug = debug; | ||
102 | } | ||
103 | |||
104 | void | ||
105 | mu_progmailer_destroy (struct _mu_progmailer **ppm) | ||
106 | { | ||
107 | if (*ppm) | ||
108 | { | ||
109 | free ((*ppm)->command); | ||
110 | free (*ppm); | ||
111 | *ppm = NULL; | ||
112 | } | ||
113 | } | ||
114 | |||
115 | int | ||
116 | mu_progmailer_open (struct _mu_progmailer *pm, char **argv) | ||
117 | { | ||
118 | int tunnel[2]; | ||
119 | int status = 0; | ||
120 | int i; | ||
121 | |||
122 | if (!pm || !argv) | ||
123 | return EINVAL; | ||
124 | |||
125 | if ((pm->sighandler = signal (SIGCHLD, SIG_DFL)) == SIG_ERR) | ||
126 | { | ||
127 | status = errno; | ||
128 | MU_DEBUG1 (pm->debug, MU_DEBUG_ERROR, | ||
129 | "setting SIGCHLD failed: %s\n", mu_strerror (status)); | ||
130 | return status; | ||
131 | } | ||
132 | |||
133 | if (pipe (tunnel) == 0) | ||
134 | { | ||
135 | pm->fd = tunnel[1]; | ||
136 | pm->pid = fork (); | ||
137 | if (pm->pid == 0) /* Child. */ | ||
138 | { | ||
139 | SCLOSE (STDIN_FILENO, tunnel); | ||
140 | SCLOSE (STDOUT_FILENO, tunnel); | ||
141 | SCLOSE (STDERR_FILENO, tunnel); | ||
142 | close (tunnel[1]); | ||
143 | dup2 (tunnel[0], STDIN_FILENO); | ||
144 | execv (pm->command ? pm->command : argv[0], argv); | ||
145 | exit (errno ? EX_CANTCREAT : 0); | ||
146 | } | ||
147 | else if (pm->pid == -1) | ||
148 | { | ||
149 | status = errno; | ||
150 | MU_DEBUG1 (pm->debug, MU_DEBUG_ERROR, | ||
151 | "fork failed: %s\n", mu_strerror (status)); | ||
152 | } | ||
153 | } | ||
154 | else | ||
155 | { | ||
156 | status = errno; | ||
157 | MU_DEBUG1 (pm->debug, MU_DEBUG_ERROR, | ||
158 | "pipe() failed: %s\n", mu_strerror (status)); | ||
159 | } | ||
160 | MU_DEBUG1 (pm->debug, MU_DEBUG_TRACE, "exec %s argv:", pm->command); | ||
161 | for (i = 0; argv[i]; i++) | ||
162 | MU_DEBUG1 (pm->debug, MU_DEBUG_TRACE, " %s", argv[i]); | ||
163 | MU_DEBUG (pm->debug, MU_DEBUG_TRACE, "\n"); | ||
164 | close (tunnel[0]); | ||
165 | |||
166 | if (status != 0) | ||
167 | close (pm->fd); | ||
168 | return status; | ||
169 | } | ||
170 | |||
171 | int | ||
172 | mu_progmailer_send (struct _mu_progmailer *pm, mu_message_t msg) | ||
173 | { | ||
174 | int status; | ||
175 | mu_stream_t stream = NULL; | ||
176 | char buffer[512]; | ||
177 | size_t len = 0; | ||
178 | int rc; | ||
179 | size_t offset = 0; | ||
180 | mu_header_t hdr; | ||
181 | mu_body_t body; | ||
182 | int found_nl = 0; | ||
183 | int exit_status; | ||
184 | |||
185 | if (!pm || !msg) | ||
186 | return EINVAL; | ||
187 | mu_message_get_header (msg, &hdr); | ||
188 | mu_header_get_stream (hdr, &stream); | ||
189 | |||
190 | MU_DEBUG (pm->debug, MU_DEBUG_TRACE, "Sending headers...\n"); | ||
191 | while ((status = mu_stream_readline (stream, buffer, sizeof (buffer), | ||
192 | offset, &len)) == 0 | ||
193 | && len != 0) | ||
194 | { | ||
195 | if (strncasecmp (buffer, MU_HEADER_FCC, sizeof (MU_HEADER_FCC) - 1)) | ||
196 | { | ||
197 | MU_DEBUG1 (pm->debug, MU_DEBUG_PROT, "Header: %s", buffer); | ||
198 | if (write (pm->fd, buffer, len) == -1) | ||
199 | { | ||
200 | status = errno; | ||
201 | |||
202 | MU_DEBUG1 (pm->debug, MU_DEBUG_TRACE, | ||
203 | "write failed: %s\n", strerror (status)); | ||
204 | break; | ||
205 | } | ||
206 | } | ||
207 | found_nl = (len == 1 && buffer[0] == '\n'); | ||
208 | |||
209 | offset += len; | ||
210 | } | ||
211 | |||
212 | if (!found_nl) | ||
213 | { | ||
214 | if (write (pm->fd, "\n", 1) == -1) | ||
215 | { | ||
216 | status = errno; | ||
217 | |||
218 | MU_DEBUG1 (pm->debug, MU_DEBUG_TRACE, | ||
219 | "write failed: %s\n", strerror (status)); | ||
220 | } | ||
221 | } | ||
222 | |||
223 | mu_message_get_body (msg, &body); | ||
224 | mu_body_get_stream (body, &stream); | ||
225 | |||
226 | MU_DEBUG (pm->debug, MU_DEBUG_TRACE, "Sending body...\n"); | ||
227 | offset = 0; | ||
228 | while ((status = mu_stream_read (stream, buffer, sizeof (buffer), | ||
229 | offset, &len)) == 0 | ||
230 | && len != 0) | ||
231 | { | ||
232 | if (write (pm->fd, buffer, len) == -1) | ||
233 | { | ||
234 | status = errno; | ||
235 | |||
236 | MU_DEBUG1 (pm->debug, MU_DEBUG_TRACE, | ||
237 | "write failed: %s\n", strerror (status)); | ||
238 | break; | ||
239 | } | ||
240 | offset += len; | ||
241 | } | ||
242 | |||
243 | close (pm->fd); | ||
244 | |||
245 | rc = waitpid (pm->pid, &exit_status, 0); | ||
246 | if (status == 0) | ||
247 | { | ||
248 | if (rc < 0) | ||
249 | { | ||
250 | if (errno == ECHILD) | ||
251 | status = 0; | ||
252 | else | ||
253 | { | ||
254 | status = errno; | ||
255 | MU_DEBUG2 (pm->debug, MU_DEBUG_TRACE, | ||
256 | "waitpid(%lu) failed: %s\n", | ||
257 | (unsigned long) pm->pid, strerror (status)); | ||
258 | } | ||
259 | } | ||
260 | else if (WIFEXITED (exit_status)) | ||
261 | { | ||
262 | exit_status = WEXITSTATUS (exit_status); | ||
263 | MU_DEBUG2 (pm->debug, MU_DEBUG_TRACE, | ||
264 | "%s exited with: %d\n", | ||
265 | pm->command, exit_status); | ||
266 | status = (exit_status == 0) ? 0 : MU_ERR_PROCESS_EXITED; | ||
267 | } | ||
268 | else if (WIFSIGNALED (exit_status)) | ||
269 | status = MU_ERR_PROCESS_SIGNALED; | ||
270 | else | ||
271 | status = MU_ERR_PROCESS_UNKNOWN_FAILURE; | ||
272 | } | ||
273 | pm->pid = -1; | ||
274 | return status; | ||
275 | } | ||
276 | |||
277 | int | ||
278 | mu_progmailer_close (struct _mu_progmailer *pm) | ||
279 | { | ||
280 | int status = 0; | ||
281 | |||
282 | if (!pm) | ||
283 | return EINVAL; | ||
284 | |||
285 | if (pm->pid > 0) | ||
286 | { | ||
287 | kill (SIGTERM, pm->pid); | ||
288 | pm->pid = -1; | ||
289 | } | ||
290 | |||
291 | if (pm->sighandler != SIG_ERR | ||
292 | && signal (SIGCHLD, pm->sighandler) == SIG_ERR) | ||
293 | { | ||
294 | status = errno; | ||
295 | MU_DEBUG1 (pm->debug, MU_DEBUG_ERROR, | ||
296 | "resetting SIGCHLD failed: %s\n", mu_strerror (status)); | ||
297 | } | ||
298 | pm->sighandler = SIG_ERR; | ||
299 | return status; | ||
300 | } |
-
Please register or sign in to post a comment