89static int send_msg(
const char *path,
struct StringArray *args,
const char *msg,
90 char **tempfile,
int wait_time)
99 sigaddset(&set, SIGTSTP);
100 sigprocmask(SIG_BLOCK, &set, NULL);
102 if ((wait_time >= 0) && tempfile)
113 struct sigaction act = { 0 };
114 struct sigaction oldalrm = { 0 };
117 pid_t ppid = getppid();
126 for (
int fd = tempfile ? 1 : 3; fd < OPEN_MAX; fd++)
128#elif defined(_POSIX_OPEN_MAX)
129 for (
int fd = tempfile ? 1 : 3; fd < _POSIX_OPEN_MAX; fd++)
144 if (open(msg, O_RDONLY, 0) < 0)
151 if ((wait_time >= 0) && tempfile && *tempfile)
154 if (open(*tempfile, O_WRONLY | O_APPEND | O_CREAT | O_EXCL, 0600) < 0)
162 if (open(
"/dev/null", O_WRONLY | O_APPEND) < 0)
164 if (open(
"/dev/null", O_RDWR | O_APPEND) < 0)
172 execvp(path, (
char **) args->entries);
191 act.sa_flags = SA_INTERRUPT;
195 sigemptyset(&act.sa_mask);
196 sigaction(SIGALRM, &act, &oldalrm);
199 else if (wait_time < 0)
204 if (waitpid(pid, &st, 0) > 0)
206 st = WIFEXITED(st) ? WEXITSTATUS(st) :
S_ERR;
207 if (wait_time && (st == (0xff &
EX_OK)) && tempfile && *tempfile)
216 if ((wait_time > 0) && tempfile && *tempfile)
227 sigaction(SIGALRM, &oldalrm, NULL);
230 if ((kill(ppid, 0) == -1) && (errno == ESRCH) && tempfile && *tempfile)
240 sigprocmask(SIG_UNBLOCK, &set, NULL);
242 if ((pid != -1) && (waitpid(pid, &st, 0) > 0))
243 st = WIFEXITED(st) ? WEXITSTATUS(st) :
S_ERR;
271static void add_args(
struct StringArray *args,
struct AddressList *al)
299 struct AddressList *to,
struct AddressList *cc,
300 struct AddressList *bcc,
const char *msg,
303 char *ps = NULL, *path = NULL, *s = NULL, *childout = NULL;
334 mutt_error(
_(
"$sendmail must be set in order to send mail"));
340 while ((ps = strtok(ps,
" ")))
351 ps = strrchr(ps,
'/');
369 while ((ps = strtok(ps,
" ")))
376 const bool c_use_8bit_mime =
cs_subset_bool(sub,
"use_8bit_mime");
377 if (eightbit && c_use_8bit_mime)
380 const bool c_use_envelope_from =
cs_subset_bool(sub,
"use_envelope_from");
381 if (c_use_envelope_from)
384 if (c_envelope_from_address)
410 const char **e = NULL;
423 i =
send_msg(path, &args, msg,
OptGui ? &childout : NULL, c_sendmail_wait);
434 if (i != (
EX_OK & 0xff))
442 struct stat st = { 0 };
444 if ((stat(childout, &st) == 0) && (st.st_size > 0))
451 pview.
banner =
_(
"Output of the delivery process");
471 if (i == (
EX_OK & 0xff))
const struct Address * cs_subset_address(const struct ConfigSubset *sub, const char *name)
Get an Address config item by name.
#define ARRAY_ADD(head, elem)
Add an element at the end of the array.
#define ARRAY_FOREACH(elem, head)
Iterate over all elements of the array.
#define ARRAY_FREE(head)
Release all memory.
#define ARRAY_HEAD_INITIALIZER
Static initializer for arrays.
bool buf_is_empty(const struct Buffer *buf)
Is the Buffer empty?
char * buf_strdup(const struct Buffer *buf)
Copy a Buffer's string.
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
short cs_subset_number(const struct ConfigSubset *sub, const char *name)
Get a number config item by name.
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
const struct Expando * cs_subset_expando(const struct ConfigSubset *sub, const char *name)
Get an Expando config item by name.
Convenience wrapper for the config headers.
Convenience wrapper for the core headers.
void mutt_need_hard_redraw(void)
Force a hard refresh.
int expando_filter(const struct Expando *exp, const struct ExpandoRenderCallback *erc, void *data, MuttFormatFlags flags, int max_cols, char **env_list, struct Buffer *buf)
Render an Expando and run the result through a filter.
const struct ExpandoRenderCallback NntpRenderCallbacks[]
Callbacks for Newsrc Expandos.
bool OptGui
(pseudo) when the gui (and curses) are started
bool OptNewsSend
(pseudo) used to change behavior when posting
Convenience wrapper for the gui headers.
Convenience wrapper for the library headers.
char * mutt_str_dup(const char *str)
Copy a string, safely.
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
const char * mutt_str_sysexit(int err_num)
Return a string matching an error code.
Usenet network mailbox type; talk to an NNTP server.
int nntp_post(struct Mailbox *m, const char *msg)
Post article.
struct Buffer * buf_pool_get(void)
Get a Buffer from the pool.
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
#define TAILQ_FOREACH(var, head, field)
#define TAILQ_FIRST(head)
#define TAILQ_NEXT(elm, field)
#define TAILQ_EMPTY(head)
#define MUTT_FORMAT_NO_FLAGS
No flags are set.
static void alarm_handler(int sig)
Async notification of an alarm signal.
static int send_msg(const char *path, struct StringArray *args, const char *msg, char **tempfile, int wait_time)
Invoke sendmail in a subshell.
static void add_args(struct StringArray *args, struct AddressList *al)
Add a list of Addresses to a dynamic array.
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.
static void add_args_one(struct StringArray *args, const struct Address *addr)
Add an Address to a dynamic array.
static volatile sig_atomic_t SigAlrm
true after SIGALRM is received
Send email using sendmail.
void mutt_sig_reset_child_signals(void)
Reset ignored signals back to the default.
void mutt_sig_block_system(void)
Block signals before calling exec()
void mutt_sig_unblock_system(bool restore)
Restore previously blocked signals.
struct Buffer * mailbox
Mailbox and host address.
String manipulation buffer.
size_t dsize
Length of data.
A set of inherited config items.
Container for Accounts, Notifications.
char ** env
Private copy of the environment variables.