Commit 7b5902b4 7b5902b4ffd7acf44934dcdd1d09e70abe26efc3 by Sergey Poznyakoff

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.
1 parent c382e9d0
...@@ -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,30 +47,47 @@ _smtp_data_send (mu_smtp_t smtp, mu_stream_t stream) ...@@ -47,30 +47,47 @@ _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;
...@@ -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;
94 return status; 109 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 if (smtp->state == MU_SMTP_EHLO)
97 smtp->state = MU_SMTP_MAIL; 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
......
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 ()
...@@ -46,11 +48,39 @@ send_rcpt_command (void *item, void *data) ...@@ -46,11 +48,39 @@ send_rcpt_command (void *item, void *data)
46 return 0; 48 return 0;
47 } 49 }
48 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;
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)
119 {
120 char *arg = argv[i] + 6;
121
122 if (mu_isdigit (arg[0]))
88 mu_smtp_trace (smtp, atoi (argv[i] + 6) ? 123 mu_smtp_trace (smtp, atoi (argv[i] + 6) ?
89 MU_SMTP_TRACE_SET : MU_SMTP_TRACE_CLR); 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);
224 } 285 }
286 mu_iterator_destroy (&itr);
287 MU_ASSERT (mu_stream_write (ostr, "\n", 1, NULL));
225 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);
295 }
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);
......