NeoMutt  2022-04-29-323-g5fcc6c
Teaching an old dog new tricks
DOXYGEN
sendmail.h File Reference

Send email using sendmail. More...

#include <stdbool.h>
+ Include dependency graph for sendmail.h:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

int mutt_invoke_sendmail (struct Mailbox *m, struct AddressList *from, struct AddressList *to, struct AddressList *cc, struct AddressList *bcc, const char *msg, bool eightbit, struct ConfigSubset *sub)
 Run sendmail. More...
 

Detailed Description

Send email using sendmail.

Authors
  • Richard Russon

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.

Definition in file sendmail.h.

Function Documentation

◆ mutt_invoke_sendmail()

int mutt_invoke_sendmail ( struct Mailbox m,
struct AddressList *  from,
struct AddressList *  to,
struct AddressList *  cc,
struct AddressList *  bcc,
const char *  msg,
bool  eightbit,
struct ConfigSubset sub 
)

Run sendmail.

Parameters
mMailbox
fromThe sender
toRecipients
ccRecipients
bccRecipients
msgFile containing message
eightbitMessage contains 8bit chars
subConfig Subset
Return values
0Success
-1Failure
See also
$inews, nntp_format_str()

Definition at line 292 of file sendmail.c.

296{
297 char *ps = NULL, *path = NULL, *s = NULL, *childout = NULL;
298 struct SendmailArgs args = ARRAY_HEAD_INITIALIZER;
299 struct SendmailArgs extra_args = ARRAY_HEAD_INITIALIZER;
300 int i;
301
302#ifdef USE_NNTP
303 if (OptNewsSend)
304 {
305 char cmd[1024] = { 0 };
306
307 const char *const c_inews = cs_subset_string(sub, "inews");
308 mutt_expando_format(cmd, sizeof(cmd), 0, sizeof(cmd), NONULL(c_inews),
310 if (*cmd == '\0')
311 {
312 i = nntp_post(m, msg);
313 unlink(msg);
314 return i;
315 }
316
317 s = mutt_str_dup(cmd);
318 }
319 else
320#endif
321 {
322 const char *const c_sendmail = cs_subset_string(sub, "sendmail");
323 s = mutt_str_dup(c_sendmail);
324 }
325
326 /* ensure that $sendmail is set to avoid a crash. http://dev.mutt.org/trac/ticket/3548 */
327 if (!s)
328 {
329 mutt_error(_("$sendmail must be set in order to send mail"));
330 return -1;
331 }
332
333 ps = s;
334 i = 0;
335 while ((ps = strtok(ps, " ")))
336 {
337 if (i)
338 {
339 if (mutt_str_equal(ps, "--"))
340 break;
341 ARRAY_ADD(&args, ps);
342 }
343 else
344 {
345 path = mutt_str_dup(ps);
346 ps = strrchr(ps, '/');
347 if (ps)
348 ps++;
349 else
350 ps = path;
351 ARRAY_ADD(&args, ps);
352 }
353 ps = NULL;
354 i++;
355 }
356
357#ifdef USE_NNTP
358 if (!OptNewsSend)
359 {
360#endif
361 /* If $sendmail contained a "--", we save the recipients to append to
362 * args after other possible options added below. */
363 if (ps)
364 {
365 ps = NULL;
366 while ((ps = strtok(ps, " ")))
367 {
368 ARRAY_ADD(&extra_args, ps);
369 ps = NULL;
370 }
371 }
372
373 const bool c_use_8bit_mime = cs_subset_bool(sub, "use_8bit_mime");
374 if (eightbit && c_use_8bit_mime)
375 ARRAY_ADD(&args, "-B8BITMIME");
376
377 const bool c_use_envelope_from = cs_subset_bool(sub, "use_envelope_from");
378 if (c_use_envelope_from)
379 {
380 const struct Address *c_envelope_from_address = cs_subset_address(sub, "envelope_from_address");
381 if (c_envelope_from_address)
382 {
383 ARRAY_ADD(&args, "-f");
384 add_args_one(&args, c_envelope_from_address);
385 }
386 else if (!TAILQ_EMPTY(from) && !TAILQ_NEXT(TAILQ_FIRST(from), entries))
387 {
388 ARRAY_ADD(&args, "-f");
389 add_args(&args, from);
390 }
391 }
392
393 const char *const c_dsn_notify = cs_subset_string(sub, "dsn_notify");
394 if (c_dsn_notify)
395 {
396 ARRAY_ADD(&args, "-N");
397 ARRAY_ADD(&args, c_dsn_notify);
398 }
399
400 const char *const c_dsn_return = cs_subset_string(sub, "dsn_return");
401 if (c_dsn_return)
402 {
403 ARRAY_ADD(&args, "-R");
404 ARRAY_ADD(&args, c_dsn_return);
405 }
406 ARRAY_ADD(&args, "--");
407 const char **e = NULL;
408 ARRAY_FOREACH(e, &extra_args)
409 {
410 ARRAY_ADD(&args, *e);
411 }
412 add_args(&args, to);
413 add_args(&args, cc);
414 add_args(&args, bcc);
415#ifdef USE_NNTP
416 }
417#endif
418
419 ARRAY_ADD(&args, NULL);
420
421 const short c_sendmail_wait = cs_subset_number(sub, "sendmail_wait");
422 i = send_msg(path, &args, msg, OptNoCurses ? NULL : &childout, c_sendmail_wait);
423
424 /* Some user's $sendmail command uses gpg for password decryption,
425 * and is set up to prompt using ncurses pinentry. If we
426 * mutt_endwin() it leaves other users staring at a blank screen.
427 * So instead, just force a hard redraw on the next refresh. */
428 if (!OptNoCurses)
429 {
431 }
432
433 if (i != (EX_OK & 0xff))
434 {
435 if (i != S_BKG)
436 {
437 const char *e = mutt_str_sysexit(i);
438 mutt_error(_("Error sending message, child exited %d (%s)"), i, NONULL(e));
439 if (childout)
440 {
441 struct stat st = { 0 };
442
443 if ((stat(childout, &st) == 0) && (st.st_size > 0))
444 {
445 struct PagerData pdata = { 0 };
446 struct PagerView pview = { &pdata };
447
448 pdata.fname = childout;
449
450 pview.banner = _("Output of the delivery process");
452 pview.mode = PAGER_MODE_OTHER;
453
454 mutt_do_pager(&pview, NULL);
455 }
456 }
457 }
458 }
459 else if (childout)
460 unlink(childout);
461
462 FREE(&childout);
463 FREE(&path);
464 FREE(&s);
465 ARRAY_FREE(&args);
466 ARRAY_FREE(&extra_args);
467
468 if (i == (EX_OK & 0xff))
469 i = 0;
470 else if (i == S_BKG)
471 i = 1;
472 else
473 i = -1;
474 return i;
475}
#define ARRAY_ADD(head, elem)
Add an element at the end of the array.
Definition: array.h:155
#define ARRAY_FOREACH(elem, head)
Iterate over all elements of the array.
Definition: array.h:211
#define ARRAY_FREE(head)
Release all memory.
Definition: array.h:203
#define ARRAY_HEAD_INITIALIZER
Static initializer for arrays.
Definition: array.h:57
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:317
short cs_subset_number(const struct ConfigSubset *sub, const char *name)
Get a number config item by name.
Definition: helpers.c:169
const struct Address * cs_subset_address(const struct ConfigSubset *sub, const char *name)
Get an Address config item by name.
Definition: helpers.c:49
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:73
void mutt_need_hard_redraw(void)
Force a hard refresh.
Definition: curs_lib.c:162
int mutt_do_pager(struct PagerView *pview, struct Email *e)
Display some page-able text to the user (help or attachment)
Definition: do_pager.c:123
#define MUTT_FORMAT_NO_FLAGS
No flags are set.
Definition: format_flags.h:30
const char * nntp_format_str(char *buf, size_t buflen, size_t col, int cols, char op, const char *src, const char *prec, const char *if_str, const char *else_str, intptr_t data, MuttFormatFlags flags)
Expand the newsrc filename - Implements format_t -.
Definition: newsrc.c:925
void mutt_expando_format(char *buf, size_t buflen, size_t col, int cols, const char *src, format_t callback, intptr_t data, MuttFormatFlags flags)
Expand expandos (x) in a string -.
Definition: muttlib.c:777
#define mutt_error(...)
Definition: logging.h:87
#define FREE(x)
Definition: memory.h:43
#define _(a)
Definition: message.h:28
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:250
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:807
const char * mutt_str_sysexit(int err_num)
Return a string matching an error code.
Definition: string.c:166
int nntp_post(struct Mailbox *m, const char *msg)
Post article.
Definition: nntp.c:1874
bool OptNoCurses
(pseudo) when sending in batch mode
Definition: options.h:53
bool OptNewsSend
(pseudo) used to change behavior when posting
Definition: options.h:51
#define MUTT_PAGER_NO_FLAGS
No flags are set.
Definition: lib.h:58
@ PAGER_MODE_OTHER
Pager is invoked via 3rd path. Non-email content is likely to be shown.
Definition: lib.h:139
#define TAILQ_FIRST(head)
Definition: queue.h:723
#define TAILQ_NEXT(elm, field)
Definition: queue.h:832
#define TAILQ_EMPTY(head)
Definition: queue.h:721
static void add_args_one(struct SendmailArgs *args, const struct Address *addr)
Add an Address to a dynamic array.
Definition: sendmail.c:251
static int send_msg(const char *path, struct SendmailArgs *args, const char *msg, char **tempfile, int wait_time)
Invoke sendmail in a subshell.
Definition: sendmail.c:88
static void add_args(struct SendmailArgs *args, struct AddressList *al)
Add a list of Addresses to a dynamic array.
Definition: sendmail.c:265
#define EX_OK
Definition: sendmail.c:54
#define NONULL(x)
Definition: string2.h:37
#define S_BKG
Definition: string2.h:42
An email address.
Definition: address.h:36
Data to be displayed by PagerView.
Definition: lib.h:158
const char * fname
Name of the file to read.
Definition: lib.h:162
Paged view into some data.
Definition: lib.h:169
struct PagerData * pdata
Data that pager displays. NOTNULL.
Definition: lib.h:170
enum PagerMode mode
Pager mode.
Definition: lib.h:171
PagerFlags flags
Additional settings to tweak pager's function.
Definition: lib.h:172
const char * banner
Title to display in status bar.
Definition: lib.h:173
+ Here is the call graph for this function:
+ Here is the caller graph for this function: