2 * Copyright notice from original mutt:
5 * This file is part of mutt-ng, see http://www.muttng.org/.
6 * It's licensed under the GNU General Public License,
7 * please see the file GPL in the top level source directory.
20 #include <auth-client.h>
23 static char authpass[STRING] = "";
30 #define MSGFAIL(msg) \
32 mutt_error("%s", msg); \
35 #define LIBCFAIL(msg) \
37 mutt_error("%s: %s", msg, strerror(errno)); \
40 #define SMTPFAIL(msg) \
42 _mutt_libesmtp_perror(msg); \
47 * _mutt_libesmtp_ensure_init
48 * Make sure the libESMTP support in mutt is initialized at some time.
50 static void _mutt_libesmtp_ensure_init ()
52 static int libesmtp_init = 0;
62 * _mutt_libesmtp_perror
63 * Prints 'msg', a colon, and then a string representation of the
64 * libesmtp errno as a mutt error.
66 static void _mutt_libesmtp_perror (const char *msg)
70 mutt_error ("%s: %s", msg,
71 smtp_strerror (smtp_errno (), buf, sizeof (buf)));
75 * _mutt_libesmtp_add_recipients
76 * Adds every address in 'addr' as a recipient to the smtp message
77 * 'message'. Note that this does not mean that they will necessarily
78 * show up in the mail headers (e.g., when bcc'ing). Returns 0 upon
79 * success, -1 upon failure (and prints an error message).
81 * Very similar to sendlib.c::add_args
84 _mutt_libesmtp_add_recipients (smtp_message_t message, ADDRESS * addr)
88 for (; addr; addr = addr->next) {
89 /* weed out group mailboxes, since those are for display only */
90 if (addr->mailbox && !addr->group) {
91 if (!smtp_add_recipient (message, addr->mailbox))
92 SMTPFAIL ("smtp_add_recipient");
101 _mutt_libesmtp_auth_interact (auth_client_request_t request,
102 char **result, int fields, void *arg)
106 for (i = 0; i < fields; i++) {
107 if (request[i].flags & AUTH_USER) {
108 result[i] = SmtpAuthUser;
110 else if (request[i].flags & AUTH_PASS) {
112 result[i] = SmtpAuthPass;
115 if (authpass[0] == '\0') {
118 snprintf (prompt, sizeof (prompt), "%s%s: ", request[i].prompt,
120 flags & AUTH_CLEARTEXT) ? " (not encrypted)" : "");
121 mutt_get_password (prompt, authpass, sizeof (authpass));
123 result[i] = authpass;
133 static const char *_mutt_libesmtp_messagefp_cb (void **buf, int *len,
139 *buf = malloc (BUFLEN);
142 rewind ((FILE *) arg);
146 if (fgets (*buf, BUFLEN - 2, (FILE *) arg) == NULL) {
150 char *p = strchr (*buf, '\0');
152 if (p[-1] == '\n' && p[-2] != '\r') {
153 strcpy (p - 1, "\r\n");
156 octets = p - (char *) *buf;
164 * mutt_invoke_libesmtp
165 * Sends a mail message to the provided recipients using libesmtp.
166 * Returns 0 upon success, -1 upon failure (and prints an error
169 int mutt_invoke_libesmtp (ADDRESS * from, /* the sender */
170 ADDRESS * to, ADDRESS * cc, ADDRESS * bcc, /* recips */
171 const char *msg, /* file containing message */
173 { /* message contains 8bit chars */
174 int ret = 0; /* return value, default = success */
175 smtp_session_t session;
176 smtp_message_t message;
177 char *hostportstr = NULL;
180 auth_context_t authctx = NULL;
181 const smtp_status_t *status;
183 _mutt_libesmtp_ensure_init ();
185 if ((session = smtp_create_session ()) == NULL)
186 SMTPFAIL ("smtp_create_session");
188 /* Create hostname:port string and tell libesmtp */
189 /* len = SmtpHost len + colon + max port (65536 => 5 chars) + terminator */
190 hostportlen = safe_strlen (SmtpHost) + 7;
191 hostportstr = safe_malloc (hostportlen);
192 snprintf (hostportstr, hostportlen, "%s:%d", SmtpHost, SmtpPort);
193 if (!smtp_set_server (session, hostportstr))
194 SMTPFAIL ("smtp_set_server");
197 if ((authctx = auth_create_context ()) == NULL)
198 MSGFAIL ("auth_create_context failed");
199 auth_set_mechanism_flags (authctx, AUTH_PLUGIN_PLAIN, 0);
200 auth_set_interact_cb (authctx, _mutt_libesmtp_auth_interact, NULL);
202 if (!smtp_auth_set_context (session, authctx))
203 SMTPFAIL ("smtp_auth_set_context");
206 if ((message = smtp_add_message (session)) == NULL)
207 SMTPFAIL ("smtp_add_message");
208 /* Initialize envelope sender */
209 if (!smtp_set_reverse_path (message, from->mailbox))
210 SMTPFAIL ("smtp_set_reverse_path");
212 if ((fp = fopen (msg, "r")) == NULL)
214 if (!smtp_set_messagecb (message, _mutt_libesmtp_messagefp_cb, fp))
215 SMTPFAIL ("smtp_set_messagecb");
216 if (_mutt_libesmtp_add_recipients (message, to))
218 if (_mutt_libesmtp_add_recipients (message, cc))
220 if (_mutt_libesmtp_add_recipients (message, bcc))
222 if (!smtp_start_session (session))
223 SMTPFAIL ("smtp_start_session");
225 status = smtp_message_transfer_status (message);
226 if (status->code < 200 || status->code > 299) {
229 snprintf (buf, sizeof (buf), "SMTP error while sending: %d %s",
230 status->code, status->text);
237 if (hostportstr != NULL)
240 smtp_destroy_session (session);
242 auth_destroy_context (authctx);
244 /* Forget user-entered SMTP AUTH password if send fails */