Improve smtp sending functions.
* include/mailutils/smtp.h (mu_smtp_write): Mark as printf-like. (mu_smtp_mail_basic, mu_smtp_rcpt_basic): Take variable number of arguments. Mark as printf-like. (mu_smtp_data): New prototype. * include/mailutils/sys/smtp.h (_MU_SMTP_SAVEBUF): New flag. (_mu_smtp) <savebuf>: New member. (_mu_smtp_data_begin, _mu_smtp_data_end): New protos. * libproto/mailer/smtp_send.c: New file. * libproto/mailer/smtp_data.c (_mu_smtp_data_begin) (_mu_smtp_data_end, mu_smtp_data): New functions. * libproto/mailer/Makefile.am (libmu_mailer_la_SOURCES): Add smtp_send.c. * libproto/mailer/smtp_ehlo.c (mu_smtp_ehlo): Switch to MU_SMTP_EHLO only if in MU_SMTP_MAIL state. * libproto/mailer/smtp_mail.c (mu_smtp_mail_basic): Take variable number of arguments. * libproto/mailer/smtp_param.c (mu_smtp_get_param): Add missing typecast. * libproto/mailer/smtp_rcpt.c (mu_smtp_rcpt_basic): Take variable number of arguments. * libproto/mailer/smtp_send.c (_smtp_data_send): Use _mu_smtp_data_begin and _mu_smtp_data_end. * testsuite/smtpsend.c: Emulate sending from a MU message.
Showing
10 changed files
with
243 additions
and
60 deletions
... | @@ -43,7 +43,7 @@ int mu_smtp_get_carrier (mu_smtp_t smtp, mu_stream_t *pcarrier); | ... | @@ -43,7 +43,7 @@ int mu_smtp_get_carrier (mu_smtp_t smtp, mu_stream_t *pcarrier); |
43 | 43 | ||
44 | int mu_smtp_open (mu_smtp_t); | 44 | int mu_smtp_open (mu_smtp_t); |
45 | int mu_smtp_response (mu_smtp_t smtp); | 45 | int mu_smtp_response (mu_smtp_t smtp); |
46 | int mu_smtp_write (mu_smtp_t smtp, const char *fmt, ...); | 46 | int mu_smtp_write (mu_smtp_t smtp, const char *fmt, ...) MU_PRINTFLIKE(2,3); |
47 | 47 | ||
48 | #define MU_SMTP_TRACE_CLR 0 | 48 | #define MU_SMTP_TRACE_CLR 0 |
49 | #define MU_SMTP_TRACE_SET 1 | 49 | #define MU_SMTP_TRACE_SET 1 |
... | @@ -58,8 +58,12 @@ int mu_smtp_get_param (mu_smtp_t smtp, int code, const char **param); | ... | @@ -58,8 +58,12 @@ int mu_smtp_get_param (mu_smtp_t smtp, int code, const char **param); |
58 | int mu_smtp_capa_test (mu_smtp_t smtp, const char *capa, const char **pret); | 58 | int mu_smtp_capa_test (mu_smtp_t smtp, const char *capa, const char **pret); |
59 | int mu_smtp_starttls (mu_smtp_t smtp); | 59 | int mu_smtp_starttls (mu_smtp_t smtp); |
60 | 60 | ||
61 | int mu_smtp_mail_basic (mu_smtp_t smtp, const char *email, const char *args); | 61 | int mu_smtp_mail_basic (mu_smtp_t smtp, const char *email, |
62 | int mu_smtp_rcpt_basic (mu_smtp_t smtp, const char *email, const char *args); | 62 | const char *fmt, ...) MU_PRINTFLIKE(3,4); |
63 | int mu_smtp_rcpt_basic (mu_smtp_t smtp, const char *email, | ||
64 | const char *fmt, ...) MU_PRINTFLIKE(3,4); | ||
65 | |||
66 | int mu_smtp_data (mu_smtp_t smtp, mu_stream_t *pstream); | ||
63 | int mu_smtp_send_stream (mu_smtp_t smtp, mu_stream_t str); | 67 | int mu_smtp_send_stream (mu_smtp_t smtp, mu_stream_t str); |
64 | int mu_smtp_rset (mu_smtp_t smtp); | 68 | int mu_smtp_rset (mu_smtp_t smtp); |
65 | int mu_smtp_quit (mu_smtp_t smtp); | 69 | int mu_smtp_quit (mu_smtp_t smtp); | ... | ... |
... | @@ -21,6 +21,7 @@ | ... | @@ -21,6 +21,7 @@ |
21 | # include <sys/socket.h> | 21 | # include <sys/socket.h> |
22 | # include <mailutils/types.h> | 22 | # include <mailutils/types.h> |
23 | # include <mailutils/smtp.h> | 23 | # include <mailutils/smtp.h> |
24 | # include <mailutils/stream.h> | ||
24 | 25 | ||
25 | # define _MU_SMTP_ESMTP 0x01 /* Connection supports ESMTP */ | 26 | # define _MU_SMTP_ESMTP 0x01 /* Connection supports ESMTP */ |
26 | # define _MU_SMTP_TRACE 0x02 /* Session trace required/enabled */ | 27 | # define _MU_SMTP_TRACE 0x02 /* Session trace required/enabled */ |
... | @@ -29,6 +30,7 @@ | ... | @@ -29,6 +30,7 @@ |
29 | # define _MU_SMTP_TLS 0x10 /* TLS initiated */ | 30 | # define _MU_SMTP_TLS 0x10 /* TLS initiated */ |
30 | # define _MU_SMTP_AUTH 0x20 /* Authorization passed */ | 31 | # define _MU_SMTP_AUTH 0x20 /* Authorization passed */ |
31 | # define _MU_SMTP_CLNPASS 0x40 /* Password has been de-obfuscated */ | 32 | # define _MU_SMTP_CLNPASS 0x40 /* Password has been de-obfuscated */ |
33 | # define _MU_SMTP_SAVEBUF 0x80 /* Buffering state saved */ | ||
32 | 34 | ||
33 | #define MU_SMTP_XSCRIPT_MASK(n) (0x100<<(n)) | 35 | #define MU_SMTP_XSCRIPT_MASK(n) (0x100<<(n)) |
34 | 36 | ||
... | @@ -69,6 +71,7 @@ struct _mu_smtp | ... | @@ -69,6 +71,7 @@ struct _mu_smtp |
69 | size_t flsize; | 71 | size_t flsize; |
70 | 72 | ||
71 | mu_list_t mlrepl; | 73 | mu_list_t mlrepl; |
74 | struct mu_buffer_query savebuf; | ||
72 | }; | 75 | }; |
73 | 76 | ||
74 | #define MU_SMTP_FSET(p,f) ((p)->flags |= (f)) | 77 | #define MU_SMTP_FSET(p,f) ((p)->flags |= (f)) |
... | @@ -91,5 +94,7 @@ int _mu_smtp_trace_disable (mu_smtp_t smtp); | ... | @@ -91,5 +94,7 @@ int _mu_smtp_trace_disable (mu_smtp_t smtp); |
91 | int _mu_smtp_xscript_level (mu_smtp_t smtp, int xlev); | 94 | int _mu_smtp_xscript_level (mu_smtp_t smtp, int xlev); |
92 | int _mu_smtp_gsasl_auth (mu_smtp_t smtp); | 95 | int _mu_smtp_gsasl_auth (mu_smtp_t smtp); |
93 | int _mu_smtp_mech_impl (mu_smtp_t smtp, mu_list_t list); | 96 | int _mu_smtp_mech_impl (mu_smtp_t smtp, mu_list_t list); |
97 | int _mu_smtp_data_begin (mu_smtp_t smtp); | ||
98 | int _mu_smtp_data_end (mu_smtp_t smtp); | ||
94 | 99 | ||
95 | #endif | 100 | #endif | ... | ... |
... | @@ -48,6 +48,7 @@ libmu_mailer_la_SOURCES = \ | ... | @@ -48,6 +48,7 @@ libmu_mailer_la_SOURCES = \ |
48 | smtp_param.c\ | 48 | smtp_param.c\ |
49 | smtp_rcpt.c\ | 49 | smtp_rcpt.c\ |
50 | smtp_rset.c\ | 50 | smtp_rset.c\ |
51 | smtp_send.c\ | ||
51 | smtp_starttls.c\ | 52 | smtp_starttls.c\ |
52 | smtp_trace.c\ | 53 | smtp_trace.c\ |
53 | smtp_quit.c\ | 54 | smtp_quit.c\ | ... | ... |
... | @@ -22,18 +22,18 @@ | ... | @@ -22,18 +22,18 @@ |
22 | #include <stdlib.h> | 22 | #include <stdlib.h> |
23 | #include <string.h> | 23 | #include <string.h> |
24 | #include <mailutils/errno.h> | 24 | #include <mailutils/errno.h> |
25 | #include <mailutils/diag.h> | ||
25 | #include <mailutils/filter.h> | 26 | #include <mailutils/filter.h> |
26 | #include <mailutils/list.h> | 27 | #include <mailutils/list.h> |
27 | #include <mailutils/smtp.h> | 28 | #include <mailutils/smtp.h> |
28 | #include <mailutils/stream.h> | 29 | #include <mailutils/stream.h> |
30 | #include <mailutils/sys/stream.h> | ||
29 | #include <mailutils/sys/smtp.h> | 31 | #include <mailutils/sys/smtp.h> |
30 | 32 | ||
31 | static int | 33 | int |
32 | _smtp_data_send (mu_smtp_t smtp, mu_stream_t stream) | 34 | _mu_smtp_data_begin (mu_smtp_t smtp) |
33 | { | 35 | { |
34 | int status; | 36 | int status; |
35 | struct mu_buffer_query oldbuf; | ||
36 | int buffer_changed = 0; | ||
37 | 37 | ||
38 | status = mu_smtp_write (smtp, "DATA\r\n"); | 38 | status = mu_smtp_write (smtp, "DATA\r\n"); |
39 | MU_SMTP_CHECK_ERROR (smtp, status); | 39 | MU_SMTP_CHECK_ERROR (smtp, status); |
... | @@ -47,34 +47,51 @@ _smtp_data_send (mu_smtp_t smtp, mu_stream_t stream) | ... | @@ -47,34 +47,51 @@ _smtp_data_send (mu_smtp_t smtp, mu_stream_t stream) |
47 | _mu_smtp_xscript_level (smtp, MU_XSCRIPT_PAYLOAD); | 47 | _mu_smtp_xscript_level (smtp, MU_XSCRIPT_PAYLOAD); |
48 | 48 | ||
49 | if (mu_stream_ioctl (smtp->carrier, MU_IOCTL_GET_TRANSPORT_BUFFER, | 49 | if (mu_stream_ioctl (smtp->carrier, MU_IOCTL_GET_TRANSPORT_BUFFER, |
50 | &oldbuf) == 0) | 50 | &smtp->savebuf) == 0) |
51 | { | 51 | { |
52 | struct mu_buffer_query newbuf; | 52 | struct mu_buffer_query newbuf; |
53 | newbuf.type = MU_TRANSPORT_OUTPUT; | 53 | newbuf.type = MU_TRANSPORT_OUTPUT; |
54 | newbuf.buftype = mu_buffer_full; | 54 | newbuf.buftype = mu_buffer_full; |
55 | newbuf.bufsize = 64*1024; | 55 | newbuf.bufsize = 64*1024; |
56 | buffer_changed = mu_stream_ioctl (smtp->carrier, | 56 | if (mu_stream_ioctl (smtp->carrier, MU_IOCTL_SET_TRANSPORT_BUFFER, |
57 | MU_IOCTL_SET_TRANSPORT_BUFFER, | 57 | &newbuf) == 0) |
58 | &newbuf) == 0; | 58 | MU_SMTP_FSET (smtp, _MU_SMTP_SAVEBUF); |
59 | } | 59 | } |
60 | return 0; | ||
61 | } | ||
60 | 62 | ||
61 | status = mu_stream_copy (smtp->carrier, stream, 0, NULL); | 63 | int |
64 | _mu_smtp_data_end (mu_smtp_t smtp) | ||
65 | { | ||
66 | int status = 0; | ||
67 | /* code is always _MU_STR_EVENT_CLOSE */ | ||
68 | if (MU_SMTP_FISSET (smtp, _MU_SMTP_SAVEBUF)) | ||
69 | { | ||
70 | status = mu_stream_ioctl (smtp->carrier, MU_IOCTL_SET_TRANSPORT_BUFFER, | ||
71 | &smtp->savebuf); | ||
72 | if (status) | ||
73 | mu_diag_output (MU_DIAG_NOTICE, | ||
74 | "failed to restore buffer state on SMTP carrier: %s", | ||
75 | mu_strerror (status)); | ||
76 | } | ||
62 | _mu_smtp_xscript_level (smtp, MU_XSCRIPT_NORMAL); | 77 | _mu_smtp_xscript_level (smtp, MU_XSCRIPT_NORMAL); |
63 | mu_stream_flush (smtp->carrier); | ||
64 | if (buffer_changed) | ||
65 | mu_stream_ioctl (smtp->carrier, MU_IOCTL_SET_TRANSPORT_BUFFER, | ||
66 | &oldbuf); | ||
67 | |||
68 | return status; | 78 | return status; |
69 | } | 79 | } |
70 | 80 | ||
81 | static void | ||
82 | _smtp_event_cb (struct _mu_stream *str, int code, | ||
83 | unsigned long lval, void *pval) | ||
84 | { | ||
85 | mu_smtp_t smtp = str->event_cb_data; | ||
86 | _mu_smtp_data_end (smtp); | ||
87 | } | ||
71 | 88 | ||
72 | int | 89 | int |
73 | mu_smtp_send_stream (mu_smtp_t smtp, mu_stream_t stream) | 90 | mu_smtp_data (mu_smtp_t smtp, mu_stream_t *pstream) |
74 | { | 91 | { |
75 | int status; | 92 | int status; |
76 | mu_stream_t input; | 93 | mu_stream_t input; |
77 | 94 | ||
78 | if (!smtp) | 95 | if (!smtp) |
79 | return EINVAL; | 96 | return EINVAL; |
80 | if (MU_SMTP_FISSET (smtp, _MU_SMTP_ERR)) | 97 | if (MU_SMTP_FISSET (smtp, _MU_SMTP_ERR)) |
... | @@ -82,14 +99,17 @@ mu_smtp_send_stream (mu_smtp_t smtp, mu_stream_t stream) | ... | @@ -82,14 +99,17 @@ mu_smtp_send_stream (mu_smtp_t smtp, mu_stream_t stream) |
82 | if (smtp->state != MU_SMTP_MORE) | 99 | if (smtp->state != MU_SMTP_MORE) |
83 | return MU_ERR_SEQ; | 100 | return MU_ERR_SEQ; |
84 | 101 | ||
85 | status = mu_filter_create (&input, stream, "CRLFDOT", MU_FILTER_ENCODE, | 102 | status = _mu_smtp_data_begin (smtp); |
86 | MU_STREAM_READ); | ||
87 | if (status) | 103 | if (status) |
88 | return status; | 104 | return status; |
89 | 105 | ||
90 | status = _smtp_data_send (smtp, input); | 106 | status = mu_filter_create (&input, smtp->carrier, "CRLFDOT", |
91 | mu_stream_destroy (&input); | 107 | MU_FILTER_ENCODE, MU_STREAM_WRITE); |
92 | if (status == 0) | 108 | if (status) |
93 | smtp->state = MU_SMTP_DOT; | 109 | return status; |
94 | return status; | 110 | input->event_cb = _smtp_event_cb; |
111 | input->event_cb_data = smtp; | ||
112 | input->event_mask = _MU_STR_EVMASK (_MU_STR_EVENT_CLOSE); | ||
113 | *pstream = input; | ||
114 | return 0; | ||
95 | } | 115 | } | ... | ... |
... | @@ -94,6 +94,7 @@ mu_smtp_ehlo (mu_smtp_t smtp) | ... | @@ -94,6 +94,7 @@ mu_smtp_ehlo (mu_smtp_t smtp) |
94 | if (smtp->replcode[0] != '2') | 94 | if (smtp->replcode[0] != '2') |
95 | return MU_ERR_REPLY; | 95 | return MU_ERR_REPLY; |
96 | } | 96 | } |
97 | smtp->state = MU_SMTP_MAIL; | 97 | if (smtp->state == MU_SMTP_EHLO) |
98 | smtp->state = MU_SMTP_MAIL; | ||
98 | return 0; | 99 | return 0; |
99 | } | 100 | } | ... | ... |
... | @@ -19,6 +19,7 @@ | ... | @@ -19,6 +19,7 @@ |
19 | #endif | 19 | #endif |
20 | 20 | ||
21 | #include <errno.h> | 21 | #include <errno.h> |
22 | #include <stdarg.h> | ||
22 | #include <stdlib.h> | 23 | #include <stdlib.h> |
23 | #include <string.h> | 24 | #include <string.h> |
24 | #include <mailutils/errno.h> | 25 | #include <mailutils/errno.h> |
... | @@ -26,10 +27,11 @@ | ... | @@ -26,10 +27,11 @@ |
26 | #include <mailutils/list.h> | 27 | #include <mailutils/list.h> |
27 | #include <mailutils/mutil.h> | 28 | #include <mailutils/mutil.h> |
28 | #include <mailutils/smtp.h> | 29 | #include <mailutils/smtp.h> |
30 | #include <mailutils/stream.h> | ||
29 | #include <mailutils/sys/smtp.h> | 31 | #include <mailutils/sys/smtp.h> |
30 | 32 | ||
31 | int | 33 | int |
32 | mu_smtp_mail_basic (mu_smtp_t smtp, const char *email, const char *args) | 34 | mu_smtp_mail_basic (mu_smtp_t smtp, const char *email, const char *fmt, ...) |
33 | { | 35 | { |
34 | int status; | 36 | int status; |
35 | 37 | ||
... | @@ -41,9 +43,14 @@ mu_smtp_mail_basic (mu_smtp_t smtp, const char *email, const char *args) | ... | @@ -41,9 +43,14 @@ mu_smtp_mail_basic (mu_smtp_t smtp, const char *email, const char *args) |
41 | return MU_ERR_SEQ; | 43 | return MU_ERR_SEQ; |
42 | status = mu_smtp_write (smtp, "MAIL FROM:<%s>", email); | 44 | status = mu_smtp_write (smtp, "MAIL FROM:<%s>", email); |
43 | MU_SMTP_CHECK_ERROR (smtp, status); | 45 | MU_SMTP_CHECK_ERROR (smtp, status); |
44 | if (args) | 46 | if (fmt) |
45 | { | 47 | { |
46 | status = mu_smtp_write (smtp, " %s", args); | 48 | va_list ap; |
49 | |||
50 | status = mu_smtp_write (smtp, " "); | ||
51 | va_start (ap, fmt); | ||
52 | status = mu_stream_vprintf (smtp->carrier, fmt, ap); | ||
53 | va_end (ap); | ||
47 | MU_SMTP_CHECK_ERROR (smtp, status); | 54 | MU_SMTP_CHECK_ERROR (smtp, status); |
48 | } | 55 | } |
49 | status = mu_smtp_write (smtp, "\r\n"); | 56 | status = mu_smtp_write (smtp, "\r\n"); | ... | ... |
... | @@ -24,6 +24,7 @@ | ... | @@ -24,6 +24,7 @@ |
24 | #include <mailutils/errno.h> | 24 | #include <mailutils/errno.h> |
25 | #include <mailutils/cctype.h> | 25 | #include <mailutils/cctype.h> |
26 | #include <mailutils/list.h> | 26 | #include <mailutils/list.h> |
27 | #include <mailutils/secret.h> | ||
27 | #include <mailutils/smtp.h> | 28 | #include <mailutils/smtp.h> |
28 | #include <mailutils/sys/smtp.h> | 29 | #include <mailutils/sys/smtp.h> |
29 | 30 | ||
... | @@ -69,7 +70,7 @@ mu_smtp_get_param (mu_smtp_t smtp, int pcode, const char **pparam) | ... | @@ -69,7 +70,7 @@ mu_smtp_get_param (mu_smtp_t smtp, int pcode, const char **pparam) |
69 | if (pcode == MU_SMTP_PARAM_PASSWORD && smtp->secret && | 70 | if (pcode == MU_SMTP_PARAM_PASSWORD && smtp->secret && |
70 | !MU_SMTP_FISSET (smtp, _MU_SMTP_CLNPASS)) | 71 | !MU_SMTP_FISSET (smtp, _MU_SMTP_CLNPASS)) |
71 | { | 72 | { |
72 | smtp->param[pcode] = mu_secret_password (smtp->secret); | 73 | smtp->param[pcode] = (char*) mu_secret_password (smtp->secret); |
73 | MU_SMTP_FSET (smtp, _MU_SMTP_CLNPASS); | 74 | MU_SMTP_FSET (smtp, _MU_SMTP_CLNPASS); |
74 | } | 75 | } |
75 | 76 | ... | ... |
... | @@ -26,10 +26,11 @@ | ... | @@ -26,10 +26,11 @@ |
26 | #include <mailutils/list.h> | 26 | #include <mailutils/list.h> |
27 | #include <mailutils/mutil.h> | 27 | #include <mailutils/mutil.h> |
28 | #include <mailutils/smtp.h> | 28 | #include <mailutils/smtp.h> |
29 | #include <mailutils/stream.h> | ||
29 | #include <mailutils/sys/smtp.h> | 30 | #include <mailutils/sys/smtp.h> |
30 | 31 | ||
31 | int | 32 | int |
32 | mu_smtp_rcpt_basic (mu_smtp_t smtp, const char *email, const char *args) | 33 | mu_smtp_rcpt_basic (mu_smtp_t smtp, const char *email, const char *fmt, ...) |
33 | { | 34 | { |
34 | int status; | 35 | int status; |
35 | 36 | ||
... | @@ -41,9 +42,14 @@ mu_smtp_rcpt_basic (mu_smtp_t smtp, const char *email, const char *args) | ... | @@ -41,9 +42,14 @@ mu_smtp_rcpt_basic (mu_smtp_t smtp, const char *email, const char *args) |
41 | return MU_ERR_SEQ; | 42 | return MU_ERR_SEQ; |
42 | status = mu_smtp_write (smtp, "RCPT TO:<%s>", email); | 43 | status = mu_smtp_write (smtp, "RCPT TO:<%s>", email); |
43 | MU_SMTP_CHECK_ERROR (smtp, status); | 44 | MU_SMTP_CHECK_ERROR (smtp, status); |
44 | if (args) | 45 | if (fmt) |
45 | { | 46 | { |
46 | status = mu_smtp_write (smtp, " %s", args); | 47 | va_list ap; |
48 | |||
49 | status = mu_smtp_write (smtp, " "); | ||
50 | va_start (ap, fmt); | ||
51 | status = mu_stream_vprintf (smtp->carrier, fmt, ap); | ||
52 | va_end (ap); | ||
47 | MU_SMTP_CHECK_ERROR (smtp, status); | 53 | MU_SMTP_CHECK_ERROR (smtp, status); |
48 | } | 54 | } |
49 | status = mu_smtp_write (smtp, "\r\n"); | 55 | status = mu_smtp_write (smtp, "\r\n"); |
... | @@ -56,5 +62,3 @@ mu_smtp_rcpt_basic (mu_smtp_t smtp, const char *email, const char *args) | ... | @@ -56,5 +62,3 @@ mu_smtp_rcpt_basic (mu_smtp_t smtp, const char *email, const char *args) |
56 | smtp->state = MU_SMTP_MORE; | 62 | smtp->state = MU_SMTP_MORE; |
57 | return 0; | 63 | return 0; |
58 | } | 64 | } |
59 | |||
60 | ... | ... |
libproto/mailer/smtp_send.c
0 → 100644
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | ||
2 | Copyright (C) 2010 Free Software Foundation, Inc. | ||
3 | |||
4 | This library is free software; you can redistribute it and/or modify | ||
5 | it under the terms of the GNU Lesser General Public License as published by | ||
6 | the Free Software Foundation; either version 3, or (at your option) | ||
7 | 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 | ||
12 | GNU Lesser General Public License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU Lesser General Public License | ||
15 | along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */ | ||
16 | |||
17 | #ifdef HAVE_CONFIG_H | ||
18 | # include <config.h> | ||
19 | #endif | ||
20 | |||
21 | #include <errno.h> | ||
22 | #include <stdlib.h> | ||
23 | #include <string.h> | ||
24 | #include <mailutils/errno.h> | ||
25 | #include <mailutils/filter.h> | ||
26 | #include <mailutils/list.h> | ||
27 | #include <mailutils/smtp.h> | ||
28 | #include <mailutils/stream.h> | ||
29 | #include <mailutils/sys/smtp.h> | ||
30 | |||
31 | static int | ||
32 | _smtp_data_send (mu_smtp_t smtp, mu_stream_t stream) | ||
33 | { | ||
34 | int status = _mu_smtp_data_begin (smtp); | ||
35 | |||
36 | if (status) | ||
37 | return status; | ||
38 | |||
39 | status = mu_stream_copy (smtp->carrier, stream, 0, NULL); | ||
40 | _mu_smtp_data_end (smtp); | ||
41 | return status; | ||
42 | } | ||
43 | |||
44 | |||
45 | int | ||
46 | mu_smtp_send_stream (mu_smtp_t smtp, mu_stream_t stream) | ||
47 | { | ||
48 | int status; | ||
49 | mu_stream_t input; | ||
50 | |||
51 | if (!smtp) | ||
52 | return EINVAL; | ||
53 | if (MU_SMTP_FISSET (smtp, _MU_SMTP_ERR)) | ||
54 | return MU_ERR_FAILURE; | ||
55 | if (smtp->state != MU_SMTP_MORE) | ||
56 | return MU_ERR_SEQ; | ||
57 | |||
58 | status = mu_filter_create (&input, stream, "CRLFDOT", MU_FILTER_ENCODE, | ||
59 | MU_STREAM_READ); | ||
60 | if (status) | ||
61 | return status; | ||
62 | |||
63 | status = _smtp_data_send (smtp, input); | ||
64 | mu_stream_destroy (&input); | ||
65 | if (status == 0) | ||
66 | smtp->state = MU_SMTP_DOT; | ||
67 | return status; | ||
68 | } |
... | @@ -20,6 +20,7 @@ | ... | @@ -20,6 +20,7 @@ |
20 | #include <unistd.h> | 20 | #include <unistd.h> |
21 | #include <stdio.h> | 21 | #include <stdio.h> |
22 | #include <stdlib.h> | 22 | #include <stdlib.h> |
23 | #include <mailutils/cctype.h> | ||
23 | #include <mailutils/mailutils.h> | 24 | #include <mailutils/mailutils.h> |
24 | #include <mailutils/smtp.h> | 25 | #include <mailutils/smtp.h> |
25 | 26 | ||
... | @@ -27,7 +28,8 @@ static char usage_text[] = | ... | @@ -27,7 +28,8 @@ static char usage_text[] = |
27 | "usage: %s hostname [port=N] [trace=N] [tls=N] [from=STRING] [rcpt=STRING]\n" | 28 | "usage: %s hostname [port=N] [trace=N] [tls=N] [from=STRING] [rcpt=STRING]\n" |
28 | " [domain=STRING] [user=STRING] [pass=STRING]\n" | 29 | " [domain=STRING] [user=STRING] [pass=STRING]\n" |
29 | " [service=STRING] [realm=STRING] [host=STRING]\n" | 30 | " [service=STRING] [realm=STRING] [host=STRING]\n" |
30 | " [auth=method[,...]] [url=STRING] [input=FILE] [raw=N]\n"; | 31 | " [auth=method[,...]] [url=STRING] [input=FILE] [raw=N]\n" |
32 | " [skiphdr=name[,...]]\n"; | ||
31 | 33 | ||
32 | static void | 34 | static void |
33 | usage () | 35 | usage () |
... | @@ -45,12 +47,40 @@ send_rcpt_command (void *item, void *data) | ... | @@ -45,12 +47,40 @@ send_rcpt_command (void *item, void *data) |
45 | MU_ASSERT (mu_smtp_rcpt_basic (smtp, email, NULL)); | 47 | MU_ASSERT (mu_smtp_rcpt_basic (smtp, email, NULL)); |
46 | return 0; | 48 | return 0; |
47 | } | 49 | } |
50 | |||
51 | static void | ||
52 | update_list (mu_list_t *plist, const char *arg) | ||
53 | { | ||
54 | int mc, j; | ||
55 | char **mv; | ||
56 | mu_list_t list = *plist; | ||
48 | 57 | ||
58 | if (!list) | ||
59 | { | ||
60 | MU_ASSERT (mu_list_create (&list)); | ||
61 | *plist = list; | ||
62 | } | ||
63 | |||
64 | MU_ASSERT (mu_argcv_get_np (arg, strlen (arg), | ||
65 | ",", NULL, | ||
66 | 0, | ||
67 | &mc, &mv, NULL)); | ||
68 | for (j = 0; j < mc; j++) | ||
69 | MU_ASSERT (mu_list_append (list, mv[j])); | ||
70 | free (mv); | ||
71 | } | ||
72 | |||
73 | static int | ||
74 | headercmp (const void *item, const void *data) | ||
75 | { | ||
76 | return mu_c_strcasecmp (item, data); | ||
77 | } | ||
78 | |||
49 | int | 79 | int |
50 | main (int argc, char **argv) | 80 | main (int argc, char **argv) |
51 | { | 81 | { |
52 | int i; | 82 | int i; |
53 | char *host; | 83 | char *host = NULL; |
54 | char *infile = NULL; | 84 | char *infile = NULL; |
55 | int port = 25; | 85 | int port = 25; |
56 | int tls = 0; | 86 | int tls = 0; |
... | @@ -62,6 +92,7 @@ main (int argc, char **argv) | ... | @@ -62,6 +92,7 @@ main (int argc, char **argv) |
62 | char *from = NULL; | 92 | char *from = NULL; |
63 | mu_list_t rcpt_list = NULL; | 93 | mu_list_t rcpt_list = NULL; |
64 | mu_list_t meth_list = NULL; | 94 | mu_list_t meth_list = NULL; |
95 | mu_list_t skiphdr_list = NULL; | ||
65 | 96 | ||
66 | mu_set_program_name (argv[0]); | 97 | mu_set_program_name (argv[0]); |
67 | #ifdef WITH_TLS | 98 | #ifdef WITH_TLS |
... | @@ -85,8 +116,17 @@ main (int argc, char **argv) | ... | @@ -85,8 +116,17 @@ main (int argc, char **argv) |
85 | } | 116 | } |
86 | } | 117 | } |
87 | else if (strncmp (argv[i], "trace=", 6) == 0) | 118 | else if (strncmp (argv[i], "trace=", 6) == 0) |
88 | mu_smtp_trace (smtp, atoi (argv[i] + 6) ? | 119 | { |
89 | MU_SMTP_TRACE_SET : MU_SMTP_TRACE_CLR); | 120 | char *arg = argv[i] + 6; |
121 | |||
122 | if (mu_isdigit (arg[0])) | ||
123 | mu_smtp_trace (smtp, atoi (argv[i] + 6) ? | ||
124 | MU_SMTP_TRACE_SET : MU_SMTP_TRACE_CLR); | ||
125 | else if (strcmp (arg, "secure") == 0) | ||
126 | mu_smtp_trace_mask (smtp, MU_SMTP_TRACE_SET, MU_XSCRIPT_SECURE); | ||
127 | else if (strcmp (arg, "payload") == 0) | ||
128 | mu_smtp_trace_mask (smtp, MU_SMTP_TRACE_SET, MU_XSCRIPT_PAYLOAD); | ||
129 | } | ||
90 | else if (strncmp (argv[i], "tls=", 4) == 0) | 130 | else if (strncmp (argv[i], "tls=", 4) == 0) |
91 | tls = atoi (argv[i] + 4); | 131 | tls = atoi (argv[i] + 4); |
92 | else if (strncmp (argv[i], "domain=", 7) == 0) | 132 | else if (strncmp (argv[i], "domain=", 7) == 0) |
... | @@ -110,8 +150,8 @@ main (int argc, char **argv) | ... | @@ -110,8 +150,8 @@ main (int argc, char **argv) |
110 | else if (strncmp (argv[i], "url=", 4) == 0) | 150 | else if (strncmp (argv[i], "url=", 4) == 0) |
111 | MU_ASSERT (mu_smtp_set_param (smtp, MU_SMTP_PARAM_URL, | 151 | MU_ASSERT (mu_smtp_set_param (smtp, MU_SMTP_PARAM_URL, |
112 | argv[i] + 4)); | 152 | argv[i] + 4)); |
113 | else if (strncmp (argv[i], "infile=", 7) == 0) | 153 | else if (strncmp (argv[i], "input=", 6) == 0) |
114 | infile = argv[i] + 7; | 154 | infile = argv[i] + 6; |
115 | else if (strncmp (argv[i], "raw=", 4) == 0) | 155 | else if (strncmp (argv[i], "raw=", 4) == 0) |
116 | raw = atoi (argv[i] + 4); | 156 | raw = atoi (argv[i] + 4); |
117 | else if (strncmp (argv[i], "rcpt=", 5) == 0) | 157 | else if (strncmp (argv[i], "rcpt=", 5) == 0) |
... | @@ -123,20 +163,17 @@ main (int argc, char **argv) | ... | @@ -123,20 +163,17 @@ main (int argc, char **argv) |
123 | else if (strncmp (argv[i], "from=", 5) == 0) | 163 | else if (strncmp (argv[i], "from=", 5) == 0) |
124 | from = argv[i] + 5; | 164 | from = argv[i] + 5; |
125 | else if (strncmp (argv[i], "auth=", 5) == 0) | 165 | else if (strncmp (argv[i], "auth=", 5) == 0) |
166 | update_list (&meth_list, argv[i] + 5); | ||
167 | else if (strncmp (argv[i], "skiphdr=", 8) == 0) | ||
126 | { | 168 | { |
127 | int mc, j; | 169 | update_list (&skiphdr_list, argv[i] + 8); |
128 | char **mv; | 170 | raw = 0; |
129 | 171 | } | |
130 | if (!meth_list) | 172 | else if (host) |
131 | MU_ASSERT (mu_list_create (&meth_list)); | 173 | { |
132 | 174 | mu_error ("server name already given: %s, new name %s?", | |
133 | MU_ASSERT (mu_argcv_get_np (argv[i] + 5, strlen (argv[i] + 5), | 175 | host, argv[i]); |
134 | ",", NULL, | 176 | exit (1); |
135 | 0, | ||
136 | &mc, &mv, NULL)); | ||
137 | for (j = 0; j < mc; j++) | ||
138 | MU_ASSERT (mu_list_append (meth_list, mv[j])); | ||
139 | free (mv); | ||
140 | } | 177 | } |
141 | else | 178 | else |
142 | host = argv[i]; | 179 | host = argv[i]; |
... | @@ -209,20 +246,55 @@ main (int argc, char **argv) | ... | @@ -209,20 +246,55 @@ main (int argc, char **argv) |
209 | } | 246 | } |
210 | } | 247 | } |
211 | 248 | ||
249 | MU_ASSERT (mu_smtp_mail_basic (smtp, from, NULL)); | ||
250 | mu_list_do (rcpt_list, send_rcpt_command, smtp); | ||
251 | |||
212 | if (raw) | 252 | if (raw) |
213 | { | 253 | { |
214 | /* Raw sending mode: send from the stream directly */ | 254 | /* Raw sending mode: send from the stream directly */ |
215 | MU_ASSERT (mu_smtp_mail_basic (smtp, from, NULL)); | ||
216 | mu_list_do (rcpt_list, send_rcpt_command, smtp); | ||
217 | MU_ASSERT (mu_smtp_send_stream (smtp, instr)); | 255 | MU_ASSERT (mu_smtp_send_stream (smtp, instr)); |
218 | MU_ASSERT (mu_smtp_quit (smtp)); | ||
219 | } | 256 | } |
220 | else | 257 | else |
221 | { | 258 | { |
222 | /* Message (standard) sending mode: send a MU message. */ | 259 | /* Message (standard) sending mode: send a MU message. */ |
223 | //FIXME; | 260 | |
261 | mu_message_t msg; | ||
262 | mu_stream_t ostr, bstr; | ||
263 | mu_header_t hdr; | ||
264 | mu_iterator_t itr; | ||
265 | mu_body_t body; | ||
266 | |||
267 | if (skiphdr_list) | ||
268 | mu_list_set_comparator (skiphdr_list, headercmp); | ||
269 | |||
270 | MU_ASSERT (mu_stream_to_message (instr, &msg)); | ||
271 | MU_ASSERT (mu_smtp_data (smtp, &ostr)); | ||
272 | MU_ASSERT (mu_message_get_header (msg, &hdr)); | ||
273 | MU_ASSERT (mu_header_get_iterator (hdr, &itr)); | ||
274 | for (mu_iterator_first (itr); !mu_iterator_is_done (itr); | ||
275 | mu_iterator_next (itr)) | ||
276 | { | ||
277 | const char *name; | ||
278 | void *value; | ||
279 | |||
280 | mu_iterator_current_kv (itr, (void*) &name, &value); | ||
281 | if (mu_list_locate (skiphdr_list, (void*) name, NULL) == 0) | ||
282 | continue; | ||
283 | |||
284 | mu_stream_printf (ostr, "%s: %s\n", name, (char*)value); | ||
285 | } | ||
286 | mu_iterator_destroy (&itr); | ||
287 | MU_ASSERT (mu_stream_write (ostr, "\n", 1, NULL)); | ||
288 | |||
289 | MU_ASSERT (mu_message_get_body (msg, &body)); | ||
290 | MU_ASSERT (mu_body_get_streamref (body, &bstr)); | ||
291 | MU_ASSERT (mu_stream_copy (ostr, bstr, 0, NULL)); | ||
292 | mu_stream_destroy (&bstr); | ||
293 | mu_stream_close (ostr); | ||
294 | mu_stream_destroy (&ostr); | ||
224 | } | 295 | } |
225 | 296 | ||
297 | MU_ASSERT (mu_smtp_quit (smtp)); | ||
226 | 298 | ||
227 | mu_smtp_destroy (&smtp); | 299 | mu_smtp_destroy (&smtp); |
228 | mu_stream_close (instr); | 300 | mu_stream_close (instr); | ... | ... |
-
Please register or sign in to post a comment