NeoMutt  2018-07-16 +1783-b00bd9
Teaching an old dog new tricks
DOXYGEN
send.c File Reference

Prepare and send an email. More...

#include "config.h"
#include <errno.h>
#include <limits.h>
#include <locale.h>
#include <regex.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <time.h>
#include <unistd.h>
#include "mutt/mutt.h"
#include "address/lib.h"
#include "config/lib.h"
#include "email/lib.h"
#include "mutt.h"
#include "send.h"
#include "alias.h"
#include "compose.h"
#include "context.h"
#include "copy.h"
#include "curs_lib.h"
#include "edit.h"
#include "filter.h"
#include "globals.h"
#include "handler.h"
#include "hdrline.h"
#include "hook.h"
#include "mailbox.h"
#include "mutt_attach.h"
#include "mutt_body.h"
#include "mutt_header.h"
#include "mutt_logging.h"
#include "mutt_parse.h"
#include "muttlib.h"
#include "ncrypt/ncrypt.h"
#include "options.h"
#include "pattern.h"
#include "protos.h"
#include "recvattach.h"
#include "rfc3676.h"
#include "sendlib.h"
#include "smtp.h"
#include "sort.h"
#include "mx.h"
#include "nntp/nntp.h"
#include "notmuch/mutt_notmuch.h"
#include "imap/imap.h"
+ Include dependency graph for send.c:

Go to the source code of this file.

Functions

static void append_signature (FILE *fp)
 Append a signature to an email. More...
 
static struct Addressremove_user (struct Address *a, bool leave_only)
 Remove any address which matches the current user. More...
 
static struct Addressfind_mailing_lists (struct Address *t, struct Address *c)
 Search Address lists for mailing lists. More...
 
static int edit_address (struct Address **a, const char *field)
 Edit an email address. More...
 
static int edit_envelope (struct Envelope *en, SendFlags flags)
 Edit Envelope fields. More...
 
static char * nntp_get_header (const char *s)
 Get the trimmed header. More...
 
static void process_user_recips (struct Envelope *env)
 Process the user headers. More...
 
static void process_user_header (struct Envelope *env)
 Process the user headers. More...
 
void mutt_forward_intro (struct Mailbox *m, struct Email *e, FILE *fp)
 Add the "start of forwarded message" text. More...
 
void mutt_forward_trailer (struct Mailbox *m, struct Email *e, FILE *fp)
 Add a "end of forwarded message" text. More...
 
static int include_forward (struct Mailbox *m, struct Email *e, FILE *fp_out)
 Write out a forwarded message. More...
 
static int inline_forward_attachments (struct Mailbox *m, struct Email *cur, struct Body ***plast, int *forwardq)
 Add attachments to an email, inline. More...
 
int mutt_inline_forward (struct Mailbox *m, struct Email *msg, struct Email *cur, FILE *out)
 Forward attachments, inline. More...
 
void mutt_make_attribution (struct Mailbox *m, struct Email *e, FILE *fp_out)
 Add "on DATE, PERSON wrote" header. More...
 
void mutt_make_post_indent (struct Mailbox *m, struct Email *e, FILE *fp_out)
 Add suffix to replied email text. More...
 
static int include_reply (struct Mailbox *m, struct Email *e, FILE *fp_out)
 Generate the reply text for an email. More...
 
static int default_to (struct Address **to, struct Envelope *env, SendFlags flags, int hmfupto)
 Generate default email addresses. More...
 
int mutt_fetch_recips (struct Envelope *out, struct Envelope *in, SendFlags flags)
 Generate recpients for a reply email. More...
 
static void add_references (struct ListHead *head, struct Envelope *env)
 Add the email's references to a list. More...
 
static void add_message_id (struct ListHead *head, struct Envelope *env)
 Add the email's message ID to a list. More...
 
void mutt_fix_reply_recipients (struct Envelope *env)
 Remove duplicate recipients. More...
 
void mutt_make_forward_subject (struct Envelope *env, struct Mailbox *m, struct Email *cur)
 Create a subject for a forwarded email. More...
 
void mutt_make_misc_reply_headers (struct Envelope *env, struct Envelope *curenv)
 Set subject for a reply. More...
 
void mutt_add_to_reference_headers (struct Envelope *env, struct Envelope *curenv)
 Generate references for a reply email. More...
 
static void make_reference_headers (struct EmailList *el, struct Envelope *env)
 Generate reference headers for an email. More...
 
static int envelope_defaults (struct Envelope *env, struct Mailbox *m, struct EmailList *el, SendFlags flags)
 Fill in some defaults for a new email. More...
 
static int generate_body (FILE *fp_tmp, struct Email *msg, SendFlags flags, struct Mailbox *m, struct EmailList *el)
 Create a new email body. More...
 
void mutt_set_followup_to (struct Envelope *env)
 Set followup-to field. More...
 
static struct Addressset_reverse_name (struct Envelope *env)
 Try to set the 'from' field from the recipients. More...
 
struct Addressmutt_default_from (void)
 Get a default 'from' Address. More...
 
static int send_message (struct Email *msg)
 Send an email. More...
 
void mutt_encode_descriptions (struct Body *b, bool recurse)
 rfc2047 encode the content-descriptions More...
 
static void decode_descriptions (struct Body *b)
 rfc2047 decode them in case of an error More...
 
static void fix_end_of_file (const char *data)
 Ensure a file ends with a linefeed. More...
 
int mutt_resend_message (FILE *fp, struct Context *ctx, struct Email *cur)
 Resend an email. More...
 
static bool is_reply (struct Email *reply, struct Email *orig)
 Is one email a reply to another? More...
 
static bool search_attach_keyword (char *filename)
 Search an email for 'attachment' keywords. More...
 
static int save_fcc (struct Email *msg, char *fcc, size_t fcc_len, struct Body *clear_content, char *pgpkeylist, SendFlags flags, char **finalpath)
 Save an Email to a 'sent mail' folder. More...
 
static int postpone_message (struct Email *msg, struct Email *cur, char *fcc, SendFlags flags)
 Save an Email for another day. More...
 
int ci_send_message (SendFlags flags, struct Email *msg, const char *tempfile, struct Context *ctx, struct EmailList *el)
 Send an email. More...
 

Variables

unsigned char C_AbortNoattach
 Config: Abort sending the email if attachments are missing. More...
 
struct RegexC_AbortNoattachRegex
 Config: Regex to match text indicating attachments are expected. More...
 
unsigned char C_AbortNosubject
 Config: Abort creating the email if subject is missing. More...
 
unsigned char C_AbortUnmodified
 Config: Abort the sending if the message hasn't been edited. More...
 
bool C_AskFollowUp
 Config: (nntp) Ask the user for follow-up groups before editing. More...
 
bool C_AskXCommentTo
 Config: (nntp) Ask the user for the 'X-Comment-To' field before editing. More...
 
char * C_ContentType
 Config: Default "Content-Type" for newly composed messages. More...
 
bool C_CryptAutoencrypt
 Config: Automatically PGP encrypt all outgoing mail. More...
 
bool C_CryptAutopgp
 Config: Allow automatic PGP functions. More...
 
bool C_CryptAutosign
 Config: Automatically PGP sign all outgoing mail. More...
 
bool C_CryptAutosmime
 Config: Allow automatic SMIME functions. More...
 
bool C_CryptReplyencrypt
 Config: Encrypt replies to encrypted messages. More...
 
bool C_CryptReplysign
 Config: Sign replies to signed messages. More...
 
bool C_CryptReplysignencrypted
 Config: Sign replies to encrypted messages. More...
 
char * C_EmptySubject
 Config: Subject to use when replying to an email with none. More...
 
bool C_FastReply
 Config: Don't prompt for the recipients and subject when replying/forwarding. More...
 
unsigned char C_FccAttach
 Config: Save send message with all their attachments. More...
 
bool C_FccClear
 Config: Save sent messages unencrypted and unsigned. More...
 
bool C_FollowupTo
 Config: Add the 'Mail-Followup-To' header is generated when sending mail. More...
 
char * C_ForwardAttributionIntro
 Config: Prefix message for forwarded messages. More...
 
char * C_ForwardAttributionTrailer
 Config: Suffix message for forwarded messages. More...
 
unsigned char C_ForwardEdit
 Config: Automatically start the editor when forwarding a message. More...
 
char * C_ForwardFormat
 Config: printf-like format string to control the subject when forwarding a message. More...
 
bool C_ForwardReferences
 Config: Set the 'In-Reply-To' and 'References' headers when forwarding a message. More...
 
bool C_Hdrs
 Config: Add custom headers to outgoing mail. More...
 
unsigned char C_HonorFollowupTo
 Config: Honour the 'Mail-Followup-To' header when group replying. More...
 
bool C_IgnoreListReplyTo
 Config: Ignore the 'Reply-To' header when using <reply> on a mailing list. More...
 
unsigned char C_Include
 Config: Include a copy of the email that's being replied to. More...
 
bool C_Metoo
 Config: Remove the user's address from the list of recipients. More...
 
bool C_NmRecord
 Config: (notmuch) If the 'record' mailbox (sent mail) should be indexed. More...
 
bool C_PgpReplyinline
 Config: Reply using old-style inline PGP messages (not recommended) More...
 
char * C_PostIndentString
 Config: Suffix message to add after reply text. More...
 
bool C_PostponeEncrypt
 Config: Self-encrypt postponed messages. More...
 
char * C_PostponeEncryptAs
 Config: Fallback encryption key for postponed messages. More...
 
unsigned char C_Recall
 Config: Recall postponed mesaages when asked to compose a message. More...
 
bool C_ReplySelf
 Config: Really reply to yourself, when replying to your own email. More...
 
unsigned char C_ReplyTo
 Config: Address to use as a 'Reply-To' header. More...
 
bool C_ReplyWithXorig
 Config: Create 'From' header from 'X-Original-To' header. More...
 
bool C_ReverseName
 Config: Set the 'From' from the address the email was sent to. More...
 
bool C_ReverseRealname
 Config: Set the 'From' from the full 'To' address the email was sent to. More...
 
bool C_SigDashes
 Config: Insert '– ' before the signature. More...
 
char * C_Signature
 Config: File containing a signature to append to all mail. More...
 
bool C_SigOnTop
 Config: Insert the signature before the quoted text. More...
 
bool C_UseFrom
 Config: Set the 'From' header for outgoing mail. More...
 

Detailed Description

Prepare and send an email.

Authors
  • Michael R. Elkins

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 send.c.

Function Documentation

static void append_signature ( FILE *  fp)
static

Append a signature to an email.

Parameters
fpFile to write to

Definition at line 137 of file send.c.

138 {
139  FILE *fp_tmp = NULL;
140  pid_t pid;
141 
142  if (C_Signature && (fp_tmp = mutt_open_read(C_Signature, &pid)))
143  {
144  if (C_SigDashes)
145  fputs("\n-- \n", fp);
146  mutt_file_copy_stream(fp_tmp, fp);
147  mutt_file_fclose(&fp_tmp);
148  if (pid != -1)
149  mutt_wait_filter(pid);
150  }
151 }
bool C_SigDashes
Config: Insert &#39;– &#39; before the signature.
Definition: send.c:128
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:149
int mutt_file_copy_stream(FILE *fp_in, FILE *fp_out)
Copy the contents of one file into another.
Definition: file.c:264
int mutt_wait_filter(pid_t pid)
Wait for the exit of a process and return its status.
Definition: filter.c:227
FILE * mutt_open_read(const char *path, pid_t *thepid)
Run a command to read from.
Definition: muttlib.c:1359
char * C_Signature
Config: File containing a signature to append to all mail.
Definition: send.c:129

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static struct Address* remove_user ( struct Address a,
bool  leave_only 
)
static

Remove any address which matches the current user.

Parameters
aList of addresses
leave_onlyIf set, don't remove the user's address if it it the only one in the list
Return values
ptrHead of the remaining Address List

Definition at line 160 of file send.c.

161 {
162  struct Address *top = NULL, *last = NULL;
163 
164  while (a)
165  {
166  if (!mutt_addr_is_user(a))
167  {
168  if (top)
169  {
170  last->next = a;
171  last = last->next;
172  }
173  else
174  {
175  last = a;
176  top = a;
177  }
178  a = a->next;
179  last->next = NULL;
180  }
181  else
182  {
183  struct Address *tmp = a;
184 
185  a = a->next;
186  if (!leave_only || a || last)
187  {
188  tmp->next = NULL;
189  mutt_addr_free(&tmp);
190  }
191  else
192  {
193  last = tmp;
194  top = tmp;
195  }
196  }
197  }
198  return top;
199 }
An email address.
Definition: address.h:32
void mutt_addr_free(struct Address **p)
Free a list of Addresses.
Definition: address.c:451
bool mutt_addr_is_user(struct Address *addr)
Does the address belong to the user.
Definition: alias.c:677
struct Address * next
Definition: address.h:39

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static struct Address* find_mailing_lists ( struct Address t,
struct Address c 
)
static

Search Address lists for mailing lists.

Parameters
t'To' Address list
c'Cc' Address list
Return values
ptrNewly allocated Address list of all mailing list matches

Definition at line 207 of file send.c.

208 {
209  struct Address *top = NULL, *ptr = NULL;
210 
211  for (; t || c; t = c, c = NULL)
212  {
213  for (; t; t = t->next)
214  {
215  if (mutt_is_mail_list(t) && !t->group)
216  {
217  if (top)
218  {
219  ptr->next = mutt_addr_copy(t);
220  ptr = ptr->next;
221  }
222  else
223  {
224  top = mutt_addr_copy(t);
225  ptr = top;
226  }
227  }
228  }
229  }
230  return top;
231 }
An email address.
Definition: address.h:32
bool mutt_is_mail_list(struct Address *addr)
Is this the email address of a mailing list?
Definition: hdrline.c:101
struct Address * mutt_addr_copy(struct Address *addr)
Copy the real address.
Definition: address.c:729
bool group
group mailbox?
Definition: address.h:36
struct Address * next
Definition: address.h:39

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static int edit_address ( struct Address **  a,
const char *  field 
)
static

Edit an email address.

Parameters
[out]aAddress to edit
[in]fieldPrompt for user
Return values
0Success
-1Failure

Definition at line 240 of file send.c.

241 {
242  char buf[8192];
243  char *err = NULL;
244  int idna_ok = 0;
245 
246  do
247  {
248  buf[0] = '\0';
250  mutt_addr_write(buf, sizeof(buf), *a, false);
251  if (mutt_get_field(field, buf, sizeof(buf), MUTT_ALIAS) != 0)
252  return -1;
253  mutt_addr_free(a);
255  idna_ok = mutt_addrlist_to_intl(*a, &err);
256  if (idna_ok != 0)
257  {
258  mutt_error(_("Bad IDN: '%s'"), err);
259  FREE(&err);
260  }
261  } while (idna_ok != 0);
262  return 0;
263 }
struct Address * mutt_addr_parse_list2(struct Address *p, const char *s)
Parse a list of email addresses.
Definition: address.c:641
#define MUTT_ALIAS
Do alias "completion" by calling up the alias-menu.
Definition: mutt.h:62
#define _(a)
Definition: message.h:28
#define mutt_get_field(field, buf, buflen, complete)
Definition: curs_lib.h:86
int mutt_addrlist_to_local(struct Address *a)
Convert an Address list from Punycode.
Definition: address.c:1290
size_t mutt_addr_write(char *buf, size_t buflen, struct Address *addr, bool display)
Write an Address to a buffer.
Definition: address.c:1184
int mutt_addrlist_to_intl(struct Address *a, char **err)
Convert an Address list to Punycode.
Definition: address.c:1249
struct Address * mutt_expand_aliases(struct Address *a)
Expand aliases in a List of Addresses.
Definition: alias.c:298
#define mutt_error(...)
Definition: logging.h:83
#define FREE(x)
Definition: memory.h:40
void mutt_addr_free(struct Address **p)
Free a list of Addresses.
Definition: address.c:451

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static int edit_envelope ( struct Envelope en,
SendFlags  flags 
)
static

Edit Envelope fields.

Parameters
enEnvelope to edit
flagsFlags, see SendFlags
Return values
0Success
-1Failure

Definition at line 272 of file send.c.

273 {
274  char buf[8192];
275 
276 #ifdef USE_NNTP
277  if (OptNewsSend)
278  {
279  if (en->newsgroups)
280  mutt_str_strfcpy(buf, en->newsgroups, sizeof(buf));
281  else
282  buf[0] = '\0';
283  if (mutt_get_field("Newsgroups: ", buf, sizeof(buf), 0) != 0)
284  return -1;
285  FREE(&en->newsgroups);
286  en->newsgroups = mutt_str_strdup(buf);
287 
288  if (en->followup_to)
289  mutt_str_strfcpy(buf, en->followup_to, sizeof(buf));
290  else
291  buf[0] = '\0';
292  if (C_AskFollowUp && (mutt_get_field("Followup-To: ", buf, sizeof(buf), 0) != 0))
293  {
294  return -1;
295  }
296  FREE(&en->followup_to);
297  en->followup_to = mutt_str_strdup(buf);
298 
299  if (en->x_comment_to)
300  mutt_str_strfcpy(buf, en->x_comment_to, sizeof(buf));
301  else
302  buf[0] = '\0';
303  if (C_XCommentTo && C_AskXCommentTo &&
304  (mutt_get_field("X-Comment-To: ", buf, sizeof(buf), 0) != 0))
305  {
306  return -1;
307  }
308  FREE(&en->x_comment_to);
309  en->x_comment_to = mutt_str_strdup(buf);
310  }
311  else
312 #endif
313  {
314  if ((edit_address(&en->to, _("To: ")) == -1) || !en->to)
315  return -1;
316  if (C_Askcc && (edit_address(&en->cc, _("Cc: ")) == -1))
317  return -1;
318  if (C_Askbcc && (edit_address(&en->bcc, _("Bcc: ")) == -1))
319  return -1;
321  (edit_address(&en->from, "From: ") == -1))
322  {
323  return -1;
324  }
325  }
326 
327  if (en->subject)
328  {
329  if (C_FastReply)
330  return 0;
331  else
332  mutt_str_strfcpy(buf, en->subject, sizeof(buf));
333  }
334  else
335  {
336  const char *p = NULL;
337 
338  buf[0] = '\0';
339  struct ListNode *uh = NULL;
340  STAILQ_FOREACH(uh, &UserHeader, entries)
341  {
342  size_t plen = mutt_str_startswith(uh->data, "subject:", CASE_IGNORE);
343  if (plen)
344  {
345  p = mutt_str_skip_email_wsp(uh->data + plen);
346  mutt_str_strfcpy(buf, p, sizeof(buf));
347  }
348  }
349  }
350 
351  if ((mutt_get_field(_("Subject: "), buf, sizeof(buf), 0) != 0) ||
352  (!buf[0] &&
353  (query_quadoption(C_AbortNosubject, _("No subject, abort?")) != MUTT_NO)))
354  {
355  mutt_message(_("No subject, aborting"));
356  return -1;
357  }
358  mutt_str_replace(&en->subject, buf);
359 
360  return 0;
361 }
enum QuadOption query_quadoption(enum QuadOption opt, const char *prompt)
Ask the user a quad-question.
Definition: init.c:3367
#define mutt_message(...)
Definition: logging.h:82
struct Address * to
Definition: envelope.h:42
static size_t plen
Length of cached packet.
Definition: pgppacket.c:38
#define _(a)
Definition: message.h:28
#define mutt_get_field(field, buf, buflen, complete)
Definition: curs_lib.h:86
unsigned char C_AbortNosubject
Config: Abort creating the email if subject is missing.
Definition: send.c:90
#define SEND_LIST_REPLY
Reply to mailing list.
Definition: send.h:88
struct Address * from
Definition: envelope.h:41
bool C_FastReply
Config: Don&#39;t prompt for the recipients and subject when replying/forwarding.
Definition: send.c:103
char * x_comment_to
Definition: envelope.h:62
static int edit_address(struct Address **a, const char *field)
Edit an email address.
Definition: send.c:240
struct Address * bcc
Definition: envelope.h:44
bool C_AskXCommentTo
Config: (nntp) Ask the user for the &#39;X-Comment-To&#39; field before editing.
Definition: send.c:93
User answered &#39;No&#39;, or assume &#39;No&#39;.
Definition: quad.h:38
size_t mutt_str_strfcpy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:753
Ignore case when comparing strings.
Definition: string2.h:67
char * mutt_str_skip_email_wsp(const char *s)
Skip over whitespace as defined by RFC5322.
Definition: string.c:779
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:350
#define SEND_REPLY
Reply to sender.
Definition: send.h:86
void mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition: string.c:456
bool C_AskFollowUp
Config: (nntp) Ask the user for follow-up groups before editing.
Definition: send.c:92
size_t mutt_str_startswith(const char *str, const char *prefix, enum CaseSensitivity cs)
Check whether a string starts with a prefix.
Definition: string.c:168
#define SEND_GROUP_REPLY
Reply to all.
Definition: send.h:87
char * data
Definition: list.h:35
char * subject
Definition: envelope.h:50
char * newsgroups
Definition: envelope.h:59
WHERE bool C_XCommentTo
Config: (nntp) Add &#39;X-Comment-To&#39; header that contains article author.
Definition: globals.h:281
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:380
char * followup_to
Definition: envelope.h:61
#define FREE(x)
Definition: memory.h:40
WHERE bool OptNewsSend
(pseudo) used to change behavior when posting
Definition: options.h:43
A List node for strings.
Definition: list.h:33
WHERE bool C_Askbcc
Config: Ask the user for the blind-carbon-copy recipients.
Definition: globals.h:197
WHERE bool C_Askcc
Config: Ask the user for the carbon-copy recipients.
Definition: globals.h:198
struct Address * cc
Definition: envelope.h:43
bool C_ReplyWithXorig
Config: Create &#39;From&#39; header from &#39;X-Original-To&#39; header.
Definition: send.c:125

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static char* nntp_get_header ( const char *  s)
static

Get the trimmed header.

Parameters
sHeader line with leading whitespace
Return values
ptrCopy of string
Note
The caller should free the returned string.

Definition at line 371 of file send.c.

372 {
373  SKIPWS(s);
374  return mutt_str_strdup(s);
375 }
#define SKIPWS(ch)
Definition: string2.h:46
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:380

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static void process_user_recips ( struct Envelope env)
static

Process the user headers.

Parameters
envEnvelope to populate

Definition at line 382 of file send.c.

383 {
384  struct ListNode *uh = NULL;
385  STAILQ_FOREACH(uh, &UserHeader, entries)
386  {
387  size_t plen;
388  if ((plen = mutt_str_startswith(uh->data, "to:", CASE_IGNORE)))
389  env->to = mutt_addr_parse_list(env->to, uh->data + plen);
390  else if ((plen = mutt_str_startswith(uh->data, "cc:", CASE_IGNORE)))
391  env->cc = mutt_addr_parse_list(env->cc, uh->data + plen);
392  else if ((plen = mutt_str_startswith(uh->data, "bcc:", CASE_IGNORE)))
393  env->bcc = mutt_addr_parse_list(env->bcc, uh->data + plen);
394 #ifdef USE_NNTP
395  else if ((plen = mutt_str_startswith(uh->data, "newsgroups:", CASE_IGNORE)))
396  env->newsgroups = nntp_get_header(uh->data + plen);
397  else if ((plen = mutt_str_startswith(uh->data, "followup-to:", CASE_IGNORE)))
398  env->followup_to = nntp_get_header(uh->data + plen);
399  else if ((plen = mutt_str_startswith(uh->data, "x-comment-to:", CASE_IGNORE)))
400  env->x_comment_to = nntp_get_header(uh->data + plen);
401 #endif
402  }
403 }
struct Address * to
Definition: envelope.h:42
static char * nntp_get_header(const char *s)
Get the trimmed header.
Definition: send.c:371
static size_t plen
Length of cached packet.
Definition: pgppacket.c:38
char * x_comment_to
Definition: envelope.h:62
struct Address * bcc
Definition: envelope.h:44
Ignore case when comparing strings.
Definition: string2.h:67
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:350
size_t mutt_str_startswith(const char *str, const char *prefix, enum CaseSensitivity cs)
Check whether a string starts with a prefix.
Definition: string.c:168
char * data
Definition: list.h:35
char * newsgroups
Definition: envelope.h:59
char * followup_to
Definition: envelope.h:61
struct Address * mutt_addr_parse_list(struct Address *top, const char *s)
Parse a list of email addresses.
Definition: address.c:473
A List node for strings.
Definition: list.h:33
struct Address * cc
Definition: envelope.h:43

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static void process_user_header ( struct Envelope env)
static

Process the user headers.

Parameters
envEnvelope to populate

Definition at line 409 of file send.c.

410 {
411  struct ListNode *uh = NULL;
412  STAILQ_FOREACH(uh, &UserHeader, entries)
413  {
414  size_t plen;
415  if ((plen = mutt_str_startswith(uh->data, "from:", CASE_IGNORE)))
416  {
417  /* User has specified a default From: address. Remove default address */
418  mutt_addr_free(&env->from);
419  env->from = mutt_addr_parse_list(env->from, uh->data + plen);
420  }
421  else if ((plen = mutt_str_startswith(uh->data, "reply-to:", CASE_IGNORE)))
422  {
423  mutt_addr_free(&env->reply_to);
424  env->reply_to = mutt_addr_parse_list(env->reply_to, uh->data + plen);
425  }
426  else if ((plen = mutt_str_startswith(uh->data, "message-id:", CASE_IGNORE)))
427  {
428  char *tmp = mutt_extract_message_id(uh->data + plen, NULL);
429  if (mutt_addr_valid_msgid(tmp))
430  {
431  FREE(&env->message_id);
432  env->message_id = tmp;
433  }
434  else
435  FREE(&tmp);
436  }
437  else if (!mutt_str_startswith(uh->data, "to:", CASE_IGNORE) &&
438  !mutt_str_startswith(uh->data, "cc:", CASE_IGNORE) &&
439  !mutt_str_startswith(uh->data, "bcc:", CASE_IGNORE) &&
440 #ifdef USE_NNTP
441  !mutt_str_startswith(uh->data, "newsgroups:", CASE_IGNORE) &&
442  !mutt_str_startswith(uh->data, "followup-to:", CASE_IGNORE) &&
443  !mutt_str_startswith(uh->data, "x-comment-to:", CASE_IGNORE) &&
444 #endif
445  !mutt_str_startswith(uh->data, "supersedes:", CASE_IGNORE) &&
446  !mutt_str_startswith(uh->data, "subject:", CASE_IGNORE) &&
447  !mutt_str_startswith(uh->data, "return-path:", CASE_IGNORE))
448  {
450  }
451  }
452 }
static size_t plen
Length of cached packet.
Definition: pgppacket.c:38
struct ListHead userhdrs
user defined headers
Definition: envelope.h:67
struct Address * reply_to
Definition: envelope.h:46
char * message_id
Definition: envelope.h:53
struct Address * from
Definition: envelope.h:41
struct ListNode * mutt_list_insert_tail(struct ListHead *h, char *s)
Append a string to the end of a List.
Definition: list.c:61
Ignore case when comparing strings.
Definition: string2.h:67
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:350
size_t mutt_str_startswith(const char *str, const char *prefix, enum CaseSensitivity cs)
Check whether a string starts with a prefix.
Definition: string.c:168
char * data
Definition: list.h:35
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:380
bool mutt_addr_valid_msgid(const char *msgid)
Is this a valid Message ID?
Definition: address.c:813
#define FREE(x)
Definition: memory.h:40
void mutt_addr_free(struct Address **p)
Free a list of Addresses.
Definition: address.c:451
struct Address * mutt_addr_parse_list(struct Address *top, const char *s)
Parse a list of email addresses.
Definition: address.c:473
A List node for strings.
Definition: list.h:33
char * mutt_extract_message_id(const char *s, const char **saveptr)
Find a message-id.
Definition: parse.c:327

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void mutt_forward_intro ( struct Mailbox m,
struct Email e,
FILE *  fp 
)

Add the "start of forwarded message" text.

Parameters
mMailbox
eEmail
fpFile to write to

Definition at line 460 of file send.c.

461 {
462  if (!C_ForwardAttributionIntro || !fp)
463  return;
464 
465  char buf[1024];
466  setlocale(LC_TIME, NONULL(C_AttributionLocale));
467  mutt_make_string(buf, sizeof(buf), C_ForwardAttributionIntro, NULL, m, e);
468  setlocale(LC_TIME, "");
469  fputs(buf, fp);
470  fputs("\n\n", fp);
471 }
#define NONULL(x)
Definition: string2.h:36
char * C_ForwardAttributionIntro
Config: Prefix message for forwarded messages.
Definition: send.c:107
WHERE char * C_AttributionLocale
Config: Locale for dates in the attribution message.
Definition: globals.h:97
#define mutt_make_string(BUF, BUFLEN, S, CTX, M, E)
Definition: hdrline.h:59

+ Here is the caller graph for this function:

void mutt_forward_trailer ( struct Mailbox m,
struct Email e,
FILE *  fp 
)

Add a "end of forwarded message" text.

Parameters
mMailbox
eEmail
fpFile to write to

Definition at line 479 of file send.c.

480 {
481  if (!C_ForwardAttributionTrailer || !fp)
482  return;
483 
484  char buf[1024];
485  setlocale(LC_TIME, NONULL(C_AttributionLocale));
486  mutt_make_string(buf, sizeof(buf), C_ForwardAttributionTrailer, NULL, m, e);
487  setlocale(LC_TIME, "");
488  fputc('\n', fp);
489  fputs(buf, fp);
490  fputc('\n', fp);
491 }
#define NONULL(x)
Definition: string2.h:36
WHERE char * C_AttributionLocale
Config: Locale for dates in the attribution message.
Definition: globals.h:97
char * C_ForwardAttributionTrailer
Config: Suffix message for forwarded messages.
Definition: send.c:108
#define mutt_make_string(BUF, BUFLEN, S, CTX, M, E)
Definition: hdrline.h:59

+ Here is the caller graph for this function:

static int include_forward ( struct Mailbox m,
struct Email e,
FILE *  fp_out 
)
static

Write out a forwarded message.

Parameters
mMailbox
eEmail
fp_outFile to write to
Return values
0Success
-1Failure

Definition at line 501 of file send.c.

502 {
503  CopyHeaderFlags chflags = CH_DECODE;
505 
508 
509  if ((WithCrypto != 0) && (e->security & SEC_ENCRYPT) && C_ForwardDecode)
510  {
511  /* make sure we have the user's passphrase before proceeding... */
513  return -1;
514  }
515 
516  mutt_forward_intro(m, e, fp_out);
517 
518  if (C_ForwardDecode)
519  {
520  cmflags |= MUTT_CM_DECODE | MUTT_CM_CHARCONV;
521  if (C_Weed)
522  {
523  chflags |= CH_WEED | CH_REORDER;
524  cmflags |= MUTT_CM_WEED;
525  }
526  }
527  if (C_ForwardQuote)
528  cmflags |= MUTT_CM_PREFIX;
529 
530  /* wrapping headers for forwarding is considered a display
531  * rather than send action */
532  chflags |= CH_DISPLAY;
533 
534  mutt_copy_message_ctx(fp_out, m, e, cmflags, chflags);
535  mutt_forward_trailer(m, e, fp_out);
536  return 0;
537 }
WHERE bool C_ForwardDecode
Config: Decode the message when forwarding it.
Definition: globals.h:210
void mutt_forward_intro(struct Mailbox *m, struct Email *e, FILE *fp)
Add the "start of forwarded message" text.
Definition: send.c:460
#define MUTT_CM_WEED
Weed message/rfc822 attachment headers.
Definition: copy.h:40
void mutt_parse_mime_message(struct Mailbox *m, struct Email *e)
Parse a MIME email.
Definition: mutt_parse.c:50
#define MUTT_MESSAGE_HOOK
message-hook: run before displaying a message
Definition: hook.h:51
uint16_t CopyMessageFlags
Flags for mutt_copy_message(), e.g. MUTT_CM_NOHEADER.
Definition: copy.h:31
#define SEC_ENCRYPT
Email is encrypted.
Definition: ncrypt.h:120
#define MUTT_CM_NO_FLAGS
No flags are set.
Definition: copy.h:34
bool crypt_valid_passphrase(SecurityFlags flags)
Check that we have a usable passphrase, ask if not.
Definition: crypt.c:143
int mutt_copy_message_ctx(FILE *fp_out, struct Mailbox *src, struct Email *e, CopyMessageFlags cmflags, CopyHeaderFlags chflags)
Copy a message from a Context.
Definition: copy.c:801
#define CH_WEED
Weed the headers?
Definition: copy.h:52
#define MUTT_CM_PREFIX
Quote the header and body.
Definition: copy.h:36
#define MUTT_CM_DECODE
Decode the message body into text/plain.
Definition: copy.h:37
#define CH_REORDER
Re-order output of headers (specified by &#39;hdr_order&#39;)
Definition: copy.h:58
#define MUTT_CM_CHARCONV
Perform character set conversions.
Definition: copy.h:41
#define CH_DECODE
Do RFC2047 header decoding.
Definition: copy.h:53
#define CH_DISPLAY
Display result to user.
Definition: copy.h:69
SecurityFlags security
bit 0-8: flags, bit 9,10: application.
Definition: email.h:39
void mutt_forward_trailer(struct Mailbox *m, struct Email *e, FILE *fp)
Add a "end of forwarded message" text.
Definition: send.c:479
uint32_t CopyHeaderFlags
Flags for mutt_copy_header(), e.g. CH_UPDATE.
Definition: copy.h:49
WHERE bool C_ForwardQuote
Config: Automatically quote a forwarded message using C_IndentString.
Definition: globals.h:211
void mutt_message_hook(struct Mailbox *m, struct Email *e, HookFlags type)
Perform a message hook.
Definition: hook.c:578
#define WithCrypto
Definition: ncrypt.h:155
bool C_Weed
Config: Filter headers when displaying/forwarding/printing/replying.
Definition: email_globals.c:40

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static int inline_forward_attachments ( struct Mailbox m,
struct Email cur,
struct Body ***  plast,
int *  forwardq 
)
static

Add attachments to an email, inline.

Parameters
[in]mMailbox
[in]curCurrent Email
[out]plastPointer to the last Attachment
[out]forwardqResult of asking the user to forward the attachments, e.g. MUTT_YES
Return values
0Success
-1Error

Definition at line 548 of file send.c.

550 {
551  struct Body **last = *plast, *body = NULL;
552  struct Message *msg = NULL;
553  struct AttachCtx *actx = NULL;
554  int rc = 0, i;
555 
556  mutt_parse_mime_message(m, cur);
558 
559  msg = mx_msg_open(m, cur->msgno);
560  if (!msg)
561  return -1;
562 
563  actx = mutt_mem_calloc(1, sizeof(*actx));
564  actx->email = cur;
565  actx->fp_root = msg->fp;
566 
567  mutt_generate_recvattach_list(actx, actx->email, actx->email->content,
568  actx->fp_root, -1, 0, 0);
569 
570  for (i = 0; i < actx->idxlen; i++)
571  {
572  body = actx->idx[i]->content;
573  if ((body->type != TYPE_MULTIPART) && !mutt_can_decode(body) &&
574  !((body->type == TYPE_APPLICATION) &&
575  ((mutt_str_strcasecmp(body->subtype, "pgp-signature") == 0) ||
576  (mutt_str_strcasecmp(body->subtype, "x-pkcs7-signature") == 0) ||
577  (mutt_str_strcasecmp(body->subtype, "pkcs7-signature") == 0))))
578  {
579  /* Ask the quadoption only once */
580  if (*forwardq == -1)
581  {
583  /* L10N:
584  This is the prompt for $forward_attachments.
585  When inline forwarding ($mime_forward answered "no"), this prompts
586  whether to add non-decodable attachments from the original email.
587  Text/plain parts and the like will already be included in the
588  message contents, but other attachment, such as PDF files, will also
589  be added as attachments to the new mail, if this is answered yes.
590  */
591  _("Forward attachments?"));
592  if (*forwardq != MUTT_YES)
593  {
594  if (*forwardq == -1)
595  rc = -1;
596  goto cleanup;
597  }
598  }
599  if (mutt_body_copy(actx->idx[i]->fp, last, body) == -1)
600  {
601  rc = -1;
602  goto cleanup;
603  }
604  last = &((*last)->next);
605  }
606  }
607 
608 cleanup:
609  *plast = last;
610  mx_msg_close(m, &msg);
611  mutt_actx_free(&actx);
612  return rc;
613 }
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:51
void mutt_generate_recvattach_list(struct AttachCtx *actx, struct Email *e, struct Body *parts, FILE *fp, int parent_type, int level, bool decrypted)
Create a list of attachments.
Definition: recvattach.c:1140
enum QuadOption query_quadoption(enum QuadOption opt, const char *prompt)
Ask the user a quad-question.
Definition: init.c:3367
struct Email * email
used by recvattach for updating
Definition: attach.h:51
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:39
struct Body * content
list of MIME parts
Definition: email.h:93
FILE * fp_root
used by recvattach for updating
Definition: attach.h:52
void mutt_parse_mime_message(struct Mailbox *m, struct Email *e)
Parse a MIME email.
Definition: mutt_parse.c:50
#define _(a)
Definition: message.h:28
short idxlen
Definition: attach.h:55
#define MUTT_MESSAGE_HOOK
message-hook: run before displaying a message
Definition: hook.h:51
The body of an email.
Definition: body.h:34
int mx_msg_close(struct Mailbox *m, struct Message **msg)
Close a message.
Definition: mx.c:1077
int mutt_body_copy(FILE *fp, struct Body **tgt, struct Body *src)
Create a send-mode duplicate from a receive-mode body.
Definition: mutt_body.c:48
void mutt_actx_free(struct AttachCtx **pactx)
Free an Attachment Context.
Definition: attach.c:131
A local copy of an email.
Definition: mx.h:79
bool mutt_can_decode(struct Body *a)
Will decoding the attachment produce any output.
Definition: handler.c:1748
FILE * fp
used in the recvattach menu.
Definition: attach.h:37
Type: &#39;multipart/*&#39;.
Definition: mime.h:37
struct Body * content
Definition: attach.h:36
int mutt_str_strcasecmp(const char *a, const char *b)
Compare two strings ignoring case, safely.
Definition: string.c:631
FILE * fp
pointer to the message data
Definition: mx.h:81
void mutt_message_hook(struct Mailbox *m, struct Email *e, HookFlags type)
Perform a message hook.
Definition: hook.c:578
A set of attachments.
Definition: attach.h:49
struct AttachPtr ** idx
Definition: attach.h:54
struct Message * mx_msg_open(struct Mailbox *m, int msgno)
return a stream pointer for a message
Definition: mx.c:1029
Type: &#39;application/*&#39;.
Definition: mime.h:33
int msgno
number displayed to the user
Definition: email.h:89
WHERE unsigned char C_ForwardAttachments
Config: Forward attachments when forwarding a message.
Definition: globals.h:183

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

int mutt_inline_forward ( struct Mailbox m,
struct Email msg,
struct Email cur,
FILE *  out 
)

Forward attachments, inline.

Parameters
mMailbox
msgEmail to alter
curCurrent Email
outFile
Return values
0Success
-1Error

Definition at line 624 of file send.c.

625 {
626  int i, forwardq = -1;
627  struct Body **last;
628 
629  if (cur)
630  include_forward(m, cur, out);
631  else
632  for (i = 0; i < m->vcount; i++)
633  if (m->emails[m->v2r[i]]->tagged)
634  include_forward(m, m->emails[m->v2r[i]], out);
635 
637  {
638  last = &msg->content;
639  while (*last)
640  last = &((*last)->next);
641 
642  if (cur)
643  {
644  if (inline_forward_attachments(m, cur, &last, &forwardq) != 0)
645  return -1;
646  }
647  else
648  for (i = 0; i < m->vcount; i++)
649  if (m->emails[m->v2r[i]]->tagged)
650  {
651  if (inline_forward_attachments(m, m->emails[m->v2r[i]], &last, &forwardq) != 0)
652  return -1;
653  if (forwardq == MUTT_NO)
654  break;
655  }
656  }
657 
658  return 0;
659 }
struct Email ** emails
Definition: mailbox.h:99
WHERE bool C_ForwardDecode
Config: Decode the message when forwarding it.
Definition: globals.h:210
struct Body * content
list of MIME parts
Definition: email.h:93
int vcount
the number of virtual messages
Definition: mailbox.h:102
The body of an email.
Definition: body.h:34
bool tagged
Definition: email.h:44
static int include_forward(struct Mailbox *m, struct Email *e, FILE *fp_out)
Write out a forwarded message.
Definition: send.c:501
User answered &#39;No&#39;, or assume &#39;No&#39;.
Definition: quad.h:38
static int inline_forward_attachments(struct Mailbox *m, struct Email *cur, struct Body ***plast, int *forwardq)
Add attachments to an email, inline.
Definition: send.c:548
int * v2r
mapping from virtual to real msgno
Definition: mailbox.h:101
WHERE unsigned char C_ForwardAttachments
Config: Forward attachments when forwarding a message.
Definition: globals.h:183

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void mutt_make_attribution ( struct Mailbox m,
struct Email e,
FILE *  fp_out 
)

Add "on DATE, PERSON wrote" header.

Parameters
mMailbox
eEmail
fp_outFile to write to

Definition at line 667 of file send.c.

668 {
669  if (!C_Attribution || !fp_out)
670  return;
671 
672  char buf[1024];
673  setlocale(LC_TIME, NONULL(C_AttributionLocale));
674  mutt_make_string(buf, sizeof(buf), C_Attribution, NULL, m, e);
675  setlocale(LC_TIME, "");
676  fputs(buf, fp_out);
677  fputc('\n', fp_out);
678 }
#define NONULL(x)
Definition: string2.h:36
WHERE char * C_AttributionLocale
Config: Locale for dates in the attribution message.
Definition: globals.h:97
#define mutt_make_string(BUF, BUFLEN, S, CTX, M, E)
Definition: hdrline.h:59
WHERE char * C_Attribution
Config: Message to start a reply, "On DATE, PERSON wrote:".
Definition: globals.h:96

+ Here is the caller graph for this function:

void mutt_make_post_indent ( struct Mailbox m,
struct Email e,
FILE *  fp_out 
)

Add suffix to replied email text.

Parameters
mMailbox
eEmail
fp_outFile to write to

Definition at line 686 of file send.c.

687 {
688  if (!C_PostIndentString || !fp_out)
689  return;
690 
691  char buf[256];
692  mutt_make_string(buf, sizeof(buf), C_PostIndentString, NULL, m, e);
693  fputs(buf, fp_out);
694  fputc('\n', fp_out);
695 }
#define mutt_make_string(BUF, BUFLEN, S, CTX, M, E)
Definition: hdrline.h:59
char * C_PostIndentString
Config: Suffix message to add after reply text.
Definition: send.c:119

+ Here is the caller graph for this function:

static int include_reply ( struct Mailbox m,
struct Email e,
FILE *  fp_out 
)
static

Generate the reply text for an email.

Parameters
mMailbox
eEmail
fp_outFile to write to
Return values
0Success
-1Failure

Definition at line 705 of file send.c.

706 {
707  CopyMessageFlags cmflags =
709  CopyHeaderFlags chflags = CH_DECODE;
710 
711  if ((WithCrypto != 0) && (e->security & SEC_ENCRYPT))
712  {
713  /* make sure we have the user's passphrase before proceeding... */
715  return -1;
716  }
717 
720 
721  mutt_make_attribution(m, e, fp_out);
722 
723  if (!C_Header)
724  cmflags |= MUTT_CM_NOHEADER;
725  if (C_Weed)
726  {
727  chflags |= CH_WEED | CH_REORDER;
728  cmflags |= MUTT_CM_WEED;
729  }
730 
731  mutt_copy_message_ctx(fp_out, m, e, cmflags, chflags);
732 
733  mutt_make_post_indent(m, e, fp_out);
734 
735  return 0;
736 }
#define MUTT_CM_WEED
Weed message/rfc822 attachment headers.
Definition: copy.h:40
void mutt_parse_mime_message(struct Mailbox *m, struct Email *e)
Parse a MIME email.
Definition: mutt_parse.c:50
#define MUTT_MESSAGE_HOOK
message-hook: run before displaying a message
Definition: hook.h:51
uint16_t CopyMessageFlags
Flags for mutt_copy_message(), e.g. MUTT_CM_NOHEADER.
Definition: copy.h:31
void mutt_make_post_indent(struct Mailbox *m, struct Email *e, FILE *fp_out)
Add suffix to replied email text.
Definition: send.c:686
#define SEC_ENCRYPT
Email is encrypted.
Definition: ncrypt.h:120
#define MUTT_CM_REPLYING
Replying the message.
Definition: copy.h:43
bool crypt_valid_passphrase(SecurityFlags flags)
Check that we have a usable passphrase, ask if not.
Definition: crypt.c:143
int mutt_copy_message_ctx(FILE *fp_out, struct Mailbox *src, struct Email *e, CopyMessageFlags cmflags, CopyHeaderFlags chflags)
Copy a message from a Context.
Definition: copy.c:801
#define CH_WEED
Weed the headers?
Definition: copy.h:52
WHERE bool C_Header
Config: Include the message headers in the reply email (Weed applies)
Definition: globals.h:217
#define MUTT_CM_PREFIX
Quote the header and body.
Definition: copy.h:36
#define MUTT_CM_DECODE
Decode the message body into text/plain.
Definition: copy.h:37
#define CH_REORDER
Re-order output of headers (specified by &#39;hdr_order&#39;)
Definition: copy.h:58
#define MUTT_CM_CHARCONV
Perform character set conversions.
Definition: copy.h:41
#define CH_DECODE
Do RFC2047 header decoding.
Definition: copy.h:53
SecurityFlags security
bit 0-8: flags, bit 9,10: application.
Definition: email.h:39
uint32_t CopyHeaderFlags
Flags for mutt_copy_header(), e.g. CH_UPDATE.
Definition: copy.h:49
void mutt_message_hook(struct Mailbox *m, struct Email *e, HookFlags type)
Perform a message hook.
Definition: hook.c:578
#define MUTT_CM_NOHEADER
Don&#39;t copy the message header.
Definition: copy.h:35
#define WithCrypto
Definition: ncrypt.h:155
bool C_Weed
Config: Filter headers when displaying/forwarding/printing/replying.
Definition: email_globals.c:40
void mutt_make_attribution(struct Mailbox *m, struct Email *e, FILE *fp_out)
Add "on DATE, PERSON wrote" header.
Definition: send.c:667

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static int default_to ( struct Address **  to,
struct Envelope env,
SendFlags  flags,
int  hmfupto 
)
static

Generate default email addresses.

Parameters
[out]to'To' address
[in]envEnvelope to populate
[in]flagsFlags, see SendFlags
[in]hmfuptoIf true, add 'followup-to' address to 'to' address
Return values
0Success
-1Aborted

Definition at line 747 of file send.c.

748 {
749  char prompt[256];
750 
751  if (flags && env->mail_followup_to && (hmfupto == MUTT_YES))
752  {
753  mutt_addr_append(to, env->mail_followup_to, true);
754  return 0;
755  }
756 
757  /* Exit now if we're setting up the default Cc list for list-reply
758  * (only set if Mail-Followup-To is present and honoured). */
759  if (flags & SEND_LIST_REPLY)
760  return 0;
761 
762  if (!C_ReplySelf && mutt_addr_is_user(env->from))
763  {
764  /* mail is from the user, assume replying to recipients */
765  mutt_addr_append(to, env->to, true);
766  }
767  else if (env->reply_to)
768  {
769  if ((mutt_addr_cmp(env->from, env->reply_to) && !env->reply_to->next &&
770  !env->reply_to->personal) ||
772  (mutt_addr_search(env->reply_to, env->to) ||
773  mutt_addr_search(env->reply_to, env->cc))))
774  {
775  /* If the Reply-To: address is a mailing list, assume that it was
776  * put there by the mailing list, and use the From: address
777  *
778  * We also take the from header if our correspondent has a reply-to
779  * header which is identical to the electronic mail address given
780  * in his From header, and the reply-to has no display-name. */
781  mutt_addr_append(to, env->from, false);
782  }
783  else if (!(mutt_addr_cmp(env->from, env->reply_to) && !env->reply_to->next) &&
784  (C_ReplyTo != MUTT_YES))
785  {
786  /* There are quite a few mailing lists which set the Reply-To:
787  * header field to the list address, which makes it quite impossible
788  * to send a message to only the sender of the message. This
789  * provides a way to do that. */
790  /* L10N: Asks whether the user respects the reply-to header.
791  If she says no, neomutt will reply to the from header's address instead. */
792  snprintf(prompt, sizeof(prompt), _("Reply to %s%s?"),
793  env->reply_to->mailbox, env->reply_to->next ? ",..." : "");
794  switch (query_quadoption(C_ReplyTo, prompt))
795  {
796  case MUTT_YES:
797  mutt_addr_append(to, env->reply_to, false);
798  break;
799 
800  case MUTT_NO:
801  mutt_addr_append(to, env->from, false);
802  break;
803 
804  default:
805  return -1; /* abort */
806  }
807  }
808  else
809  mutt_addr_append(to, env->reply_to, false);
810  }
811  else
812  mutt_addr_append(to, env->from, false);
813 
814  return 0;
815 }
bool C_ReplySelf
Config: Really reply to yourself, when replying to your own email.
Definition: send.c:123
enum QuadOption query_quadoption(enum QuadOption opt, const char *prompt)
Ask the user a quad-question.
Definition: init.c:3367
struct Address * to
Definition: envelope.h:42
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:39
#define _(a)
Definition: message.h:28
char * mailbox
mailbox and host address
Definition: address.h:35
bool C_IgnoreListReplyTo
Config: Ignore the &#39;Reply-To&#39; header when using <reply> on a mailing list.
Definition: send.c:114
bool mutt_is_mail_list(struct Address *addr)
Is this the email address of a mailing list?
Definition: hdrline.c:101
struct Address * reply_to
Definition: envelope.h:46
struct Address * mail_followup_to
Definition: envelope.h:47
unsigned char C_ReplyTo
Config: Address to use as a &#39;Reply-To&#39; header.
Definition: send.c:124
#define SEND_LIST_REPLY
Reply to mailing list.
Definition: send.h:88
struct Address * from
Definition: envelope.h:41
User answered &#39;No&#39;, or assume &#39;No&#39;.
Definition: quad.h:38
bool mutt_addr_search(struct Address *a, struct Address *lst)
Search for an e-mail address in a list.
Definition: address.c:923
char * personal
real name of address
Definition: address.h:34
bool mutt_addr_cmp(struct Address *a, struct Address *b)
Compare two e-mail addresses.
Definition: address.c:906
struct Address * mutt_addr_append(struct Address **a, struct Address *b, bool prune)
Append one list of addresses onto another.
Definition: address.c:783
struct Address * cc
Definition: envelope.h:43
bool mutt_addr_is_user(struct Address *addr)
Does the address belong to the user.
Definition: alias.c:677
struct Address * next
Definition: address.h:39

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

int mutt_fetch_recips ( struct Envelope out,
struct Envelope in,
SendFlags  flags 
)

Generate recpients for a reply email.

Parameters
outEnvelope to populate
inEnvelope of source email
flagsFlags, see SendFlags
Return values
0Success
-1Failure

Definition at line 825 of file send.c.

826 {
827  struct Address *tmp = NULL;
828  enum QuadOption hmfupto = MUTT_ABORT;
829 
831  {
832  char prompt[256];
833  snprintf(prompt, sizeof(prompt), _("Follow-up to %s%s?"),
834  in->mail_followup_to->mailbox, in->mail_followup_to->next ? ",..." : "");
835 
836  hmfupto = query_quadoption(C_HonorFollowupTo, prompt);
837  if (hmfupto == MUTT_ABORT)
838  return -1;
839  }
840 
841  if (flags & SEND_LIST_REPLY)
842  {
843  tmp = find_mailing_lists(in->to, in->cc);
844  mutt_addr_append(&out->to, tmp, false);
845  mutt_addr_free(&tmp);
846 
847  if (in->mail_followup_to && (hmfupto == MUTT_YES) &&
848  (default_to(&out->cc, in, flags & SEND_LIST_REPLY, (hmfupto == MUTT_YES)) == MUTT_ABORT))
849  {
850  return -1; /* abort */
851  }
852  }
853  else if (flags & SEND_TO_SENDER)
854  {
855  mutt_addr_append(&out->to, in->from, false);
856  }
857  else
858  {
859  if (default_to(&out->to, in, flags & (SEND_GROUP_REPLY | SEND_GROUP_CHAT_REPLY),
860  (hmfupto == MUTT_YES)) == -1)
861  return -1; /* abort */
862 
863  if ((flags & (SEND_GROUP_REPLY | SEND_GROUP_CHAT_REPLY)) &&
864  (!in->mail_followup_to || (hmfupto != MUTT_YES)))
865  {
866  /* if(!mutt_addr_is_user(in->to)) */
867  if (flags & SEND_GROUP_REPLY)
868  mutt_addr_append(&out->cc, in->to, true);
869  else
870  mutt_addr_append(&out->to, in->to, true);
871  mutt_addr_append(&out->cc, in->cc, true);
872  }
873  }
874  return 0;
875 }
#define SEND_TO_SENDER
Compose new email to sender.
Definition: send.h:98
static int default_to(struct Address **to, struct Envelope *env, SendFlags flags, int hmfupto)
Generate default email addresses.
Definition: send.c:747
User aborted the question (with Ctrl-G)
Definition: quad.h:37
enum QuadOption query_quadoption(enum QuadOption opt, const char *prompt)
Ask the user a quad-question.
Definition: init.c:3367
struct Address * to
Definition: envelope.h:42
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:39
#define _(a)
Definition: message.h:28
An email address.
Definition: address.h:32
char * mailbox
mailbox and host address
Definition: address.h:35
unsigned char C_HonorFollowupTo
Config: Honour the &#39;Mail-Followup-To&#39; header when group replying.
Definition: send.c:113
struct Address * mail_followup_to
Definition: envelope.h:47
#define SEND_LIST_REPLY
Reply to mailing list.
Definition: send.h:88
struct Address * from
Definition: envelope.h:41
#define SEND_GROUP_REPLY
Reply to all.
Definition: send.h:87
void mutt_addr_free(struct Address **p)
Free a list of Addresses.
Definition: address.c:451
#define SEND_GROUP_CHAT_REPLY
Reply to all recipients preserving To/Cc.
Definition: send.h:99
struct Address * mutt_addr_append(struct Address **a, struct Address *b, bool prune)
Append one list of addresses onto another.
Definition: address.c:783
QuadOption
Possible values for a quad-option.
Definition: quad.h:35
static struct Address * find_mailing_lists(struct Address *t, struct Address *c)
Search Address lists for mailing lists.
Definition: send.c:207
struct Address * cc
Definition: envelope.h:43
struct Address * next
Definition: address.h:39

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static void add_references ( struct ListHead *  head,
struct Envelope env 
)
static

Add the email's references to a list.

Parameters
headList of references
envEnvelope of message

Definition at line 882 of file send.c.

883 {
884  struct ListNode *np = NULL;
885 
886  struct ListHead *src = !STAILQ_EMPTY(&env->references) ? &env->references : &env->in_reply_to;
887  STAILQ_FOREACH(np, src, entries)
888  {
890  }
891 }
struct ListHead in_reply_to
in-reply-to header content
Definition: envelope.h:66
struct ListNode * mutt_list_insert_tail(struct ListHead *h, char *s)
Append a string to the end of a List.
Definition: list.c:61
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:350
char * data
Definition: list.h:35
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:380
#define STAILQ_EMPTY(head)
Definition: queue.h:346
struct ListHead references
message references (in reverse order)
Definition: envelope.h:65
A List node for strings.
Definition: list.h:33

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static void add_message_id ( struct ListHead *  head,
struct Envelope env 
)
static

Add the email's message ID to a list.

Parameters
headList of message IDs
envEnvelope of message

Definition at line 898 of file send.c.

899 {
900  if (env->message_id)
901  {
903  }
904 }
char * message_id
Definition: envelope.h:53
struct ListNode * mutt_list_insert_head(struct ListHead *h, char *s)
Insert a string at the beginning of a List.
Definition: list.c:44
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:380

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void mutt_fix_reply_recipients ( struct Envelope env)

Remove duplicate recipients.

Parameters
envEnvelope to fix

Definition at line 910 of file send.c.

911 {
912  if (!C_Metoo)
913  {
914  /* the order is important here. do the CC: first so that if the
915  * the user is the only recipient, it ends up on the TO: field */
916  env->cc = remove_user(env->cc, (env->to == NULL));
917  env->to = remove_user(env->to, (env->cc == NULL) || C_ReplySelf);
918  }
919 
920  /* the CC field can get cluttered, especially with lists */
921  env->to = mutt_addrlist_dedupe(env->to);
922  env->cc = mutt_addrlist_dedupe(env->cc);
923  env->cc = mutt_addr_remove_xrefs(env->to, env->cc);
924 
925  if (env->cc && !env->to)
926  {
927  env->to = env->cc;
928  env->cc = NULL;
929  }
930 }
static struct Address * remove_user(struct Address *a, bool leave_only)
Remove any address which matches the current user.
Definition: send.c:160
bool C_ReplySelf
Config: Really reply to yourself, when replying to your own email.
Definition: send.c:123
struct Address * to
Definition: envelope.h:42
struct Address * mutt_addr_remove_xrefs(struct Address *a, struct Address *b)
Remove cross-references.
Definition: address.c:1369
struct Address * mutt_addrlist_dedupe(struct Address *addr)
Remove duplicate addresses.
Definition: address.c:1322
bool C_Metoo
Config: Remove the user&#39;s address from the list of recipients.
Definition: send.c:116
struct Address * cc
Definition: envelope.h:43

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void mutt_make_forward_subject ( struct Envelope env,
struct Mailbox m,
struct Email cur 
)

Create a subject for a forwarded email.

Parameters
envEnvelope for result
mMailbox
curEmail

Definition at line 938 of file send.c.

939 {
940  if (!env)
941  return;
942 
943  char buf[256];
944 
945  /* set the default subject for the message. */
946  mutt_make_string(buf, sizeof(buf), NONULL(C_ForwardFormat), NULL, m, cur);
947  mutt_str_replace(&env->subject, buf);
948 }
#define NONULL(x)
Definition: string2.h:36
char * C_ForwardFormat
Config: printf-like format string to control the subject when forwarding a message.
Definition: send.c:110
void mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition: string.c:456
char * subject
Definition: envelope.h:50
#define mutt_make_string(BUF, BUFLEN, S, CTX, M, E)
Definition: hdrline.h:59

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void mutt_make_misc_reply_headers ( struct Envelope env,
struct Envelope curenv 
)

Set subject for a reply.

Parameters
envEnvelope for result
curenvEnvelope of source email

Definition at line 955 of file send.c.

956 {
957  if (!env || !curenv)
958  return;
959 
960  /* This takes precedence over a subject that might have
961  * been taken from a List-Post header. Is that correct? */
962  if (curenv->real_subj)
963  {
964  FREE(&env->subject);
965  env->subject = mutt_mem_malloc(mutt_str_strlen(curenv->real_subj) + 5);
966  sprintf(env->subject, "Re: %s", curenv->real_subj);
967  }
968  else if (!env->subject)
970 }
char * real_subj
offset of the real subject
Definition: envelope.h:51
size_t mutt_str_strlen(const char *a)
Calculate the length of a string, safely.
Definition: string.c:669
void * mutt_mem_malloc(size_t size)
Allocate memory on the heap.
Definition: memory.c:97
char * subject
Definition: envelope.h:50
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:380
#define FREE(x)
Definition: memory.h:40
char * C_EmptySubject
Config: Subject to use when replying to an email with none.
Definition: send.c:102

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void mutt_add_to_reference_headers ( struct Envelope env,
struct Envelope curenv 
)

Generate references for a reply email.

Parameters
envEnvelope for result
curenvEnvelope of source email

Definition at line 977 of file send.c.

978 {
979  add_references(&env->references, curenv);
980  add_message_id(&env->references, curenv);
981  add_message_id(&env->in_reply_to, curenv);
982 
983 #ifdef USE_NNTP
984  if (OptNewsSend && C_XCommentTo && curenv->from)
986 #endif
987 }
static void add_references(struct ListHead *head, struct Envelope *env)
Add the email&#39;s references to a list.
Definition: send.c:882
static void add_message_id(struct ListHead *head, struct Envelope *env)
Add the email&#39;s message ID to a list.
Definition: send.c:898
struct ListHead in_reply_to
in-reply-to header content
Definition: envelope.h:66
struct Address * from
Definition: envelope.h:41
char * x_comment_to
Definition: envelope.h:62
const char * mutt_get_name(struct Address *a)
Pick the best name to display from an address.
Definition: sort.c:154
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:380
WHERE bool C_XCommentTo
Config: (nntp) Add &#39;X-Comment-To&#39; header that contains article author.
Definition: globals.h:281
WHERE bool OptNewsSend
(pseudo) used to change behavior when posting
Definition: options.h:43
struct ListHead references
message references (in reverse order)
Definition: envelope.h:65

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static void make_reference_headers ( struct EmailList *  el,
struct Envelope env 
)
static

Generate reference headers for an email.

Parameters
elList of source Emails
envEnvelope for result

Definition at line 994 of file send.c.

995 {
996  if (!el || !env || STAILQ_EMPTY(el))
997  return;
998 
999  struct EmailNode *en = STAILQ_FIRST(el);
1000  bool single = !STAILQ_NEXT(en, entries);
1001 
1002  if (!single)
1003  {
1004  STAILQ_FOREACH(en, el, entries)
1005  {
1007  }
1008  }
1009  else
1011 
1012  /* if there's more than entry in In-Reply-To (i.e. message has multiple
1013  * parents), don't generate a References: header as it's discouraged by
1014  * RFC2822, sect. 3.6.4 */
1015  if (!single && !STAILQ_EMPTY(&env->in_reply_to) &&
1016  STAILQ_NEXT(STAILQ_FIRST(&env->in_reply_to), entries))
1017  {
1018  mutt_list_free(&env->references);
1019  }
1020 }
void mutt_list_free(struct ListHead *h)
Free a List AND its strings.
Definition: list.c:117
struct ListHead in_reply_to
in-reply-to header content
Definition: envelope.h:66
struct Envelope * env
envelope information
Definition: email.h:92
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:350
#define STAILQ_NEXT(elm, field)
Definition: queue.h:398
struct Email * email
Definition: email.h:123
#define STAILQ_EMPTY(head)
Definition: queue.h:346
List of Emails.
Definition: email.h:121
struct ListHead references
message references (in reverse order)
Definition: envelope.h:65
#define STAILQ_FIRST(head)
Definition: queue.h:348
void mutt_add_to_reference_headers(struct Envelope *env, struct Envelope *curenv)
Generate references for a reply email.
Definition: send.c:977

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static int envelope_defaults ( struct Envelope env,
struct Mailbox m,
struct EmailList *  el,
SendFlags  flags 
)
static

Fill in some defaults for a new email.

Parameters
envEnvelope for result
mMailbox
elList of Emails to use
flagsFlags, see SendFlags
Return values
0Success
-1Failure

Definition at line 1031 of file send.c.

1033 {
1034  if (!el || STAILQ_EMPTY(el))
1035  return -1;
1036 
1037  struct EmailNode *en = STAILQ_FIRST(el);
1038  bool single = !STAILQ_NEXT(en, entries);
1039 
1040  struct Envelope *curenv = en->email->env;
1041  if (!curenv)
1042  return -1;
1043 
1044  if (flags & (SEND_REPLY | SEND_TO_SENDER))
1045  {
1046 #ifdef USE_NNTP
1047  if ((flags & SEND_NEWS))
1048  {
1049  /* in case followup set Newsgroups: with Followup-To: if it present */
1050  if (!env->newsgroups &&
1051  (mutt_str_strcasecmp(curenv->followup_to, "poster") != 0))
1052  {
1053  env->newsgroups = mutt_str_strdup(curenv->followup_to);
1054  }
1055  }
1056  else
1057 #endif
1058  if (!single)
1059  {
1060  STAILQ_FOREACH(en, el, entries)
1061  {
1062  if (mutt_fetch_recips(env, en->email->env, flags) == -1)
1063  return -1;
1064  }
1065  }
1066  else if (mutt_fetch_recips(env, curenv, flags) == -1)
1067  return -1;
1068 
1069  if ((flags & SEND_LIST_REPLY) && !env->to)
1070  {
1071  mutt_error(_("No mailing lists found"));
1072  return -1;
1073  }
1074 
1075  if (flags & SEND_REPLY)
1076  {
1077  mutt_make_misc_reply_headers(env, curenv);
1078  make_reference_headers(el, env);
1079  }
1080  }
1081  else if (flags & SEND_FORWARD)
1082  {
1083  mutt_make_forward_subject(env, m, en->email);
1084  if (C_ForwardReferences)
1085  make_reference_headers(el, env);
1086  }
1087 
1088  return 0;
1089 }
static void make_reference_headers(struct EmailList *el, struct Envelope *env)
Generate reference headers for an email.
Definition: send.c:994
#define SEND_TO_SENDER
Compose new email to sender.
Definition: send.h:98
struct Address * to
Definition: envelope.h:42
#define SEND_FORWARD
Forward email.
Definition: send.h:89
int mutt_fetch_recips(struct Envelope *out, struct Envelope *in, SendFlags flags)
Generate recpients for a reply email.
Definition: send.c:825
#define _(a)
Definition: message.h:28
void mutt_make_misc_reply_headers(struct Envelope *env, struct Envelope *curenv)
Set subject for a reply.
Definition: send.c:955
void mutt_make_forward_subject(struct Envelope *env, struct Mailbox *m, struct Email *cur)
Create a subject for a forwarded email.
Definition: send.c:938
struct Envelope * env
envelope information
Definition: email.h:92
#define SEND_LIST_REPLY
Reply to mailing list.
Definition: send.h:88
#define SEND_NEWS
Reply to a news article.
Definition: send.h:100
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:350
#define STAILQ_NEXT(elm, field)
Definition: queue.h:398
#define SEND_REPLY
Reply to sender.
Definition: send.h:86
char * newsgroups
Definition: envelope.h:59
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:380
struct Email * email
Definition: email.h:123
#define mutt_error(...)
Definition: logging.h:83
char * followup_to
Definition: envelope.h:61
int mutt_str_strcasecmp(const char *a, const char *b)
Compare two strings ignoring case, safely.
Definition: string.c:631
#define STAILQ_EMPTY(head)
Definition: queue.h:346
List of Emails.
Definition: email.h:121
bool C_ForwardReferences
Config: Set the &#39;In-Reply-To&#39; and &#39;References&#39; headers when forwarding a message. ...
Definition: send.c:111
#define STAILQ_FIRST(head)
Definition: queue.h:348
The header of an email.
Definition: envelope.h:38

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static int generate_body ( FILE *  fp_tmp,
struct Email msg,
SendFlags  flags,
struct Mailbox m,
struct EmailList *  el 
)
static

Create a new email body.

Parameters
fp_tmpStream for outgoing message
msgHeader for outgoing message
flagsCompose mode, see SendFlags
mMailbox
elList of Emails to use
Return values
0Success
-1Error

Definition at line 1101 of file send.c.

1103 {
1104  struct Body *tmp = NULL;
1105  struct EmailNode *en = NULL;
1106  bool single = true;
1107 
1108  if (el)
1109  en = STAILQ_FIRST(el);
1110  if (en)
1111  single = !STAILQ_NEXT(en, entries);
1112 
1113  /* An EmailList is required for replying and forwarding */
1114  if (!el && (flags & (SEND_REPLY | SEND_FORWARD)))
1115  return -1;
1116 
1117  if (flags & SEND_REPLY)
1118  {
1119  enum QuadOption ans =
1120  query_quadoption(C_Include, _("Include message in reply?"));
1121  if (ans == MUTT_ABORT)
1122  return -1;
1123 
1124  if (ans == MUTT_YES)
1125  {
1126  mutt_message(_("Including quoted message..."));
1127  if (!single)
1128  {
1129  STAILQ_FOREACH(en, el, entries)
1130  {
1131  if (include_reply(m, en->email, fp_tmp) == -1)
1132  {
1133  mutt_error(_("Could not include all requested messages"));
1134  return -1;
1135  }
1136  fputc('\n', fp_tmp);
1137  }
1138  }
1139  else
1140  include_reply(m, en->email, fp_tmp);
1141  }
1142  }
1143  else if (flags & SEND_FORWARD)
1144  {
1145  enum QuadOption ans =
1146  query_quadoption(C_MimeForward, _("Forward as attachment?"));
1147  if (ans == MUTT_YES)
1148  {
1149  struct Body *last = msg->content;
1150 
1151  mutt_message(_("Preparing forwarded message..."));
1152 
1153  while (last && last->next)
1154  last = last->next;
1155 
1156  if (single)
1157  {
1158  tmp = mutt_make_message_attach(m, en->email, false);
1159  if (last)
1160  last->next = tmp;
1161  else
1162  msg->content = tmp;
1163  }
1164  else
1165  {
1166  STAILQ_FOREACH(en, el, entries)
1167  {
1168  tmp = mutt_make_message_attach(m, en->email, false);
1169  if (last)
1170  {
1171  last->next = tmp;
1172  last = tmp;
1173  }
1174  else
1175  {
1176  last = tmp;
1177  msg->content = tmp;
1178  }
1179  }
1180  }
1181  }
1182  else if (ans != MUTT_ABORT)
1183  {
1184  if (mutt_inline_forward(m, msg, en->email, fp_tmp) != 0)
1185  return -1;
1186  }
1187  else
1188  return -1;
1189  }
1190  /* if (WithCrypto && (flags & SEND_KEY)) */
1191  else if (((WithCrypto & APPLICATION_PGP) != 0) && (flags & SEND_KEY))
1192  {
1193  struct Body *b = NULL;
1194 
1195  if (((WithCrypto & APPLICATION_PGP) != 0) && !(b = crypt_pgp_make_key_attachment()))
1196  {
1197  return -1;
1198  }
1199 
1200  b->next = msg->content;
1201  msg->content = b;
1202  }
1203 
1204  mutt_clear_error();
1205 
1206  return 0;
1207 }
struct Body * mutt_make_message_attach(struct Mailbox *m, struct Email *e, bool attach_msg)
Create a message attachment.
Definition: sendlib.c:1478
User aborted the question (with Ctrl-G)
Definition: quad.h:37
enum QuadOption query_quadoption(enum QuadOption opt, const char *prompt)
Ask the user a quad-question.
Definition: init.c:3367
#define mutt_message(...)
Definition: logging.h:82
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:39
#define SEND_FORWARD
Forward email.
Definition: send.h:89
struct Body * content
list of MIME parts
Definition: email.h:93
int mutt_inline_forward(struct Mailbox *m, struct Email *msg, struct Email *cur, FILE *out)
Forward attachments, inline.
Definition: send.c:624
#define _(a)
Definition: message.h:28
struct Body * next
next attachment in the list
Definition: body.h:60
unsigned char C_Include
Config: Include a copy of the email that&#39;s being replied to.
Definition: send.c:115
The body of an email.
Definition: body.h:34
WHERE unsigned char C_MimeForward
Config: Forward a message as a &#39;message/RFC822&#39; MIME part.
Definition: globals.h:184
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
Definition: mutt_logging.c:141
#define SEND_KEY
Mail a PGP public key.
Definition: send.h:93
static int include_reply(struct Mailbox *m, struct Email *e, FILE *fp_out)
Generate the reply text for an email.
Definition: send.c:705
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:350
#define STAILQ_NEXT(elm, field)
Definition: queue.h:398
#define SEND_REPLY
Reply to sender.
Definition: send.h:86
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: ncrypt.h:129
struct Body * crypt_pgp_make_key_attachment(void)
Wrapper for CryptModuleSpecs::pgp_make_key_attachment()
Definition: cryptglue.c:259
struct Email * email
Definition: email.h:123
#define mutt_error(...)
Definition: logging.h:83
List of Emails.
Definition: email.h:121
#define STAILQ_FIRST(head)
Definition: queue.h:348
#define WithCrypto
Definition: ncrypt.h:155
QuadOption
Possible values for a quad-option.
Definition: quad.h:35

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void mutt_set_followup_to ( struct Envelope env)

Set followup-to field.

Parameters
envEnvelope to modify

Definition at line 1213 of file send.c.

1214 {
1215  struct Address *t = NULL;
1216  struct Address *from = NULL;
1217 
1218  /* Only generate the Mail-Followup-To if the user has requested it, and
1219  * it hasn't already been set */
1220 
1221  if (!C_FollowupTo)
1222  return;
1223 #ifdef USE_NNTP
1224  if (OptNewsSend)
1225  {
1226  if (!env->followup_to && env->newsgroups && (strrchr(env->newsgroups, ',')))
1227  env->followup_to = mutt_str_strdup(env->newsgroups);
1228  return;
1229  }
1230 #endif
1231 
1232  if (!env->mail_followup_to)
1233  {
1234  if (mutt_is_list_cc(0, env->to, env->cc))
1235  {
1236  /* this message goes to known mailing lists, so create a proper
1237  * mail-followup-to header */
1238 
1239  t = mutt_addr_append(&env->mail_followup_to, env->to, false);
1240  mutt_addr_append(&t, env->cc, true);
1241  }
1242 
1243  /* remove ourselves from the mail-followup-to header */
1244  env->mail_followup_to = remove_user(env->mail_followup_to, false);
1245 
1246  /* If we are not subscribed to any of the lists in question, re-add
1247  * ourselves to the mail-followup-to header. The mail-followup-to header
1248  * generated is a no-op with group-reply, but makes sure list-reply has the
1249  * desired effect. */
1250 
1251  if (env->mail_followup_to && !mutt_is_list_recipient(false, env->to, env->cc))
1252  {
1253  if (env->reply_to)
1254  from = mutt_addr_copy_list(env->reply_to, false);
1255  else if (env->from)
1256  from = mutt_addr_copy_list(env->from, false);
1257  else
1258  from = mutt_default_from();
1259 
1260  if (from)
1261  {
1262  /* Normally, this loop will not even be entered. */
1263  for (t = from; t && t->next; t = t->next)
1264  ;
1265 
1266  t->next = env->mail_followup_to; /* t can't be NULL at this point. */
1267  env->mail_followup_to = from;
1268  }
1269  }
1270 
1272  }
1273 }
static struct Address * remove_user(struct Address *a, bool leave_only)
Remove any address which matches the current user.
Definition: send.c:160
struct Address * to
Definition: envelope.h:42
int mutt_is_list_recipient(bool alladdr, struct Address *a1, struct Address *a2)
Matches subscribed mailing lists.
Definition: pattern.c:1732
struct Address * mutt_addr_copy_list(struct Address *addr, bool prune)
Copy a list of addresses.
Definition: address.c:750
An email address.
Definition: address.h:32
bool C_FollowupTo
Config: Add the &#39;Mail-Followup-To&#39; header is generated when sending mail.
Definition: send.c:106
struct Address * reply_to
Definition: envelope.h:46
struct Address * mail_followup_to
Definition: envelope.h:47
struct Address * from
Definition: envelope.h:41
struct Address * mutt_default_from(void)
Get a default &#39;from&#39; Address.
Definition: send.c:1319
int mutt_is_list_cc(int alladdr, struct Address *a1, struct Address *a2)
Matches known mailing lists.
Definition: pattern.c:1754
struct Address * mutt_addrlist_dedupe(struct Address *addr)
Remove duplicate addresses.
Definition: address.c:1322
char * newsgroups
Definition: envelope.h:59
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:380
char * followup_to
Definition: envelope.h:61
struct Address * mutt_addr_append(struct Address **a, struct Address *b, bool prune)
Append one list of addresses onto another.
Definition: address.c:783
WHERE bool OptNewsSend
(pseudo) used to change behavior when posting
Definition: options.h:43
struct Address * cc
Definition: envelope.h:43
struct Address * next
Definition: address.h:39

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static struct Address* set_reverse_name ( struct Envelope env)
static

Try to set the 'from' field from the recipients.

Parameters
envEnvelope to use
Return values
ptrNewly allocated Address
NULLA suitable Address wasn't found

Look through the recipients of the message we are replying to, and if we find an address that matches $alternates, we use that as the default from field

Definition at line 1285 of file send.c.

1286 {
1287  struct Address *tmp = NULL;
1288 
1289  for (tmp = env->to; tmp; tmp = tmp->next)
1290  {
1291  if (mutt_addr_is_user(tmp))
1292  break;
1293  }
1294  if (!tmp)
1295  {
1296  for (tmp = env->cc; tmp; tmp = tmp->next)
1297  {
1298  if (mutt_addr_is_user(tmp))
1299  break;
1300  }
1301  }
1302  if (!tmp && mutt_addr_is_user(env->from))
1303  tmp = env->from;
1304  if (tmp)
1305  {
1306  tmp = mutt_addr_copy(tmp);
1307  /* when $reverse_realname is not set, clear the personal name so that it
1308  * may be set via a reply- or send-hook. */
1309  if (!C_ReverseRealname)
1310  FREE(&tmp->personal);
1311  }
1312  return tmp;
1313 }
struct Address * to
Definition: envelope.h:42
An email address.
Definition: address.h:32
struct Address * from
Definition: envelope.h:41
bool C_ReverseRealname
Config: Set the &#39;From&#39; from the full &#39;To&#39; address the email was sent to.
Definition: send.c:127
struct Address * mutt_addr_copy(struct Address *addr)
Copy the real address.
Definition: address.c:729
char * personal
real name of address
Definition: address.h:34
#define FREE(x)
Definition: memory.h:40
struct Address * cc
Definition: envelope.h:43
bool mutt_addr_is_user(struct Address *addr)
Does the address belong to the user.
Definition: alias.c:677
struct Address * next
Definition: address.h:39

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

struct Address* mutt_default_from ( void  )

Get a default 'from' Address.

Return values
ptrNewly allocated Address

Definition at line 1319 of file send.c.

1320 {
1321  struct Address *addr = NULL;
1322 
1323  /* Note: We let $from override $realname here.
1324  * Is this the right thing to do?
1325  */
1326 
1327  if (C_From)
1328  addr = mutt_addr_copy(C_From);
1329  else
1330  {
1331  addr = mutt_addr_new();
1332  if (C_UseDomain)
1333  {
1334  const char *fqdn = mutt_fqdn(true);
1335  addr->mailbox =
1337  sprintf(addr->mailbox, "%s@%s", NONULL(Username), NONULL(fqdn));
1338  }
1339  else
1340  {
1341  addr->mailbox = mutt_str_strdup(Username);
1342  }
1343  }
1344 
1345  return addr;
1346 }
WHERE char * Username
User&#39;s login name.
Definition: globals.h:51
#define NONULL(x)
Definition: string2.h:36
struct Address * mutt_addr_new(void)
Create a new Address.
Definition: address.c:401
An email address.
Definition: address.h:32
char * mailbox
mailbox and host address
Definition: address.h:35
size_t mutt_str_strlen(const char *a)
Calculate the length of a string, safely.
Definition: string.c:669
WHERE bool C_UseDomain
Config: Qualify local addresses using this domain.
Definition: globals.h:257
WHERE struct Address * C_From
Config: Default &#39;From&#39; address to use, if isn&#39;t otherwise set.
Definition: globals.h:93
void * mutt_mem_malloc(size_t size)
Allocate memory on the heap.
Definition: memory.c:97
struct Address * mutt_addr_copy(struct Address *addr)
Copy the real address.
Definition: address.c:729
const char * mutt_fqdn(bool may_hide_host)
Get the Fully-Qualified Domain Name.
Definition: sendlib.c:2453
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:380

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static int send_message ( struct Email msg)
static

Send an email.

Parameters
msgEmail
Return values
0Success
-1Failure

Definition at line 1354 of file send.c.

1355 {
1356  char tempfile[PATH_MAX];
1357  int i;
1358 #ifdef USE_SMTP
1359  short old_write_bcc;
1360 #endif
1361 
1362  /* Write out the message in MIME form. */
1363  mutt_mktemp(tempfile, sizeof(tempfile));
1364  FILE *fp_tmp = mutt_file_fopen(tempfile, "w");
1365  if (!fp_tmp)
1366  return -1;
1367 
1368 #ifdef USE_SMTP
1369  old_write_bcc = C_WriteBcc;
1370  if (C_SmtpUrl)
1371  C_WriteBcc = false;
1372 #endif
1373 #ifdef MIXMASTER
1374  mutt_rfc822_write_header(fp_tmp, msg->env, msg->content,
1375  MUTT_WRITE_HEADER_NORMAL, !STAILQ_EMPTY(&msg->chain),
1377 #endif
1378 #ifndef MIXMASTER
1381 #endif
1382 #ifdef USE_SMTP
1383  if (old_write_bcc)
1384  C_WriteBcc = true;
1385 #endif
1386 
1387  fputc('\n', fp_tmp); /* tie off the header. */
1388 
1389  if ((mutt_write_mime_body(msg->content, fp_tmp) == -1))
1390  {
1391  mutt_file_fclose(&fp_tmp);
1392  unlink(tempfile);
1393  return -1;
1394  }
1395 
1396  if (fclose(fp_tmp) != 0)
1397  {
1398  mutt_perror(tempfile);
1399  unlink(tempfile);
1400  return -1;
1401  }
1402 
1403 #ifdef MIXMASTER
1404  if (!STAILQ_EMPTY(&msg->chain))
1405  return mix_send_message(&msg->chain, tempfile);
1406 #endif
1407 
1408 #ifdef USE_SMTP
1409 #ifdef USE_NNTP
1410  if (!OptNewsSend)
1411 #endif
1412  if (C_SmtpUrl)
1413  {
1414  return mutt_smtp_send(msg->env->from, msg->env->to, msg->env->cc, msg->env->bcc,
1415  tempfile, (msg->content->encoding == ENC_8BIT));
1416  }
1417 #endif /* USE_SMTP */
1418 
1419  i = mutt_invoke_sendmail(msg->env->from, msg->env->to, msg->env->cc, msg->env->bcc,
1420  tempfile, (msg->content->encoding == ENC_8BIT));
1421  return i;
1422 }
WHERE char * C_SmtpUrl
Config: (smtp) Url of the SMTP server.
Definition: globals.h:140
WHERE bool C_WriteBcc
Config: Write out the &#39;Bcc&#39; field when preparing to send a mail.
Definition: globals.h:260
#define mutt_perror(...)
Definition: logging.h:84
struct Address * to
Definition: envelope.h:42
A normal Email, write full header + MIME headers.
Definition: sendlib.h:62
bool mutt_should_hide_protected_subject(struct Email *e)
Should NeoMutt hide the protected subject?
Definition: crypt.c:1032
struct Body * content
list of MIME parts
Definition: email.h:93
8-bit text
Definition: mime.h:50
int mutt_invoke_sendmail(struct Address *from, struct Address *to, struct Address *cc, struct Address *bcc, const char *msg, int eightbit)
Run sendmail.
Definition: sendlib.c:2727
int mutt_rfc822_write_header(FILE *fp, struct Envelope *env, struct Body *attach, enum MuttWriteHeaderMode mode, bool privacy, bool hide_protected_subject)
Write out one RFC822 header line.
Definition: sendlib.c:2233
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:149
struct Envelope * env
envelope information
Definition: email.h:92
unsigned int encoding
content-transfer-encoding
Definition: body.h:73
struct Address * from
Definition: envelope.h:41
struct Address * bcc
Definition: envelope.h:44
#define mutt_mktemp(buf, buflen)
Definition: muttlib.h:74
#define PATH_MAX
Definition: mutt.h:49
int mutt_write_mime_body(struct Body *a, FILE *fp)
Write a MIME part.
Definition: sendlib.c:506
int mix_send_message(struct ListHead *chain, const char *tempfile)
Send an email via Mixmaster.
Definition: remailer.c:825
#define STAILQ_EMPTY(head)
Definition: queue.h:346
int mutt_smtp_send(const struct Address *from, const struct Address *to, const struct Address *cc, const struct Address *bcc, const char *msgfile, bool eightbit)
Send a message using SMTP.
Definition: smtp.c:740
WHERE bool OptNewsSend
(pseudo) used to change behavior when posting
Definition: options.h:43
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:578
struct Address * cc
Definition: envelope.h:43

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void mutt_encode_descriptions ( struct Body b,
bool  recurse 
)

rfc2047 encode the content-descriptions

Parameters
bBody of email
recurseIf true, encode children parts

Definition at line 1429 of file send.c.

1430 {
1431  for (struct Body *t = b; t; t = t->next)
1432  {
1433  if (t->description)
1434  {
1435  rfc2047_encode(&t->description, NULL, sizeof("Content-Description:"), C_SendCharset);
1436  }
1437  if (recurse && t->parts)
1438  mutt_encode_descriptions(t->parts, recurse);
1439  }
1440 }
struct Body * next
next attachment in the list
Definition: body.h:60
The body of an email.
Definition: body.h:34
char * C_SendCharset
Config: Character sets for outgoing mail.
Definition: email_globals.c:38
void mutt_encode_descriptions(struct Body *b, bool recurse)
rfc2047 encode the content-descriptions
Definition: send.c:1429
void rfc2047_encode(char **pd, const char *specials, int col, const char *charsets)
RFC-2047-encode a string.
Definition: rfc2047.c:626

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static void decode_descriptions ( struct Body b)
static

rfc2047 decode them in case of an error

Parameters
bMIME parts to decode

Definition at line 1446 of file send.c.

1447 {
1448  for (struct Body *t = b; t; t = t->next)
1449  {
1450  if (t->description)
1451  {
1452  rfc2047_decode(&t->description);
1453  }
1454  if (t->parts)
1455  decode_descriptions(t->parts);
1456  }
1457 }
struct Body * next
next attachment in the list
Definition: body.h:60
The body of an email.
Definition: body.h:34
void rfc2047_decode(char **pd)
Decode any RFC2047-encoded header fields.
Definition: rfc2047.c:650
static void decode_descriptions(struct Body *b)
rfc2047 decode them in case of an error
Definition: send.c:1446

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static void fix_end_of_file ( const char *  data)
static

Ensure a file ends with a linefeed.

Parameters
dataName of file to fix

Definition at line 1463 of file send.c.

1464 {
1465  FILE *fp = mutt_file_fopen(data, "a+");
1466  if (!fp)
1467  return;
1468  if (fseek(fp, -1, SEEK_END) >= 0)
1469  {
1470  int c = fgetc(fp);
1471  if (c != '\n')
1472  fputc('\n', fp);
1473  }
1474  mutt_file_fclose(&fp);
1475 }
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:149
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:578

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

int mutt_resend_message ( FILE *  fp,
struct Context ctx,
struct Email cur 
)

Resend an email.

Parameters
fpFile containing email
ctxMailbox
curEmail to resend
Return values
0Message was successfully sent
-1Message was aborted or an error occurred
1Message was postponed

Definition at line 1486 of file send.c.

1487 {
1488  struct Email *msg = mutt_email_new();
1489 
1490  if (mutt_prepare_template(fp, ctx->mailbox, msg, cur, true) < 0)
1491  {
1492  mutt_email_free(&msg);
1493  return -1;
1494  }
1495 
1496  if (WithCrypto)
1497  {
1498  /* mutt_prepare_template doesn't always flip on an application bit.
1499  * so fix that here */
1500  if (!(msg->security & (APPLICATION_SMIME | APPLICATION_PGP)))
1501  {
1502  if (((WithCrypto & APPLICATION_SMIME) != 0) && C_SmimeIsDefault)
1503  msg->security |= APPLICATION_SMIME;
1504  else if (WithCrypto & APPLICATION_PGP)
1505  msg->security |= APPLICATION_PGP;
1506  else
1507  msg->security |= APPLICATION_SMIME;
1508  }
1509 
1511  {
1512  msg->security |= SEC_OPPENCRYPT;
1514  }
1515  }
1516 
1517  struct EmailList el = STAILQ_HEAD_INITIALIZER(el);
1518  el_add_email(&el, cur);
1519  int rc = ci_send_message(SEND_RESEND, msg, NULL, ctx, &el);
1520  el_free(&el);
1521 
1522  return rc;
1523 }
The envelope/body of an email.
Definition: email.h:37
void el_free(struct EmailList *el)
Drop a private list of Emails.
Definition: context.c:321
struct Email * mutt_email_new(void)
Create a new Email.
Definition: email.c:63
int ci_send_message(SendFlags flags, struct Email *msg, const char *tempfile, struct Context *ctx, struct EmailList *el)
Send an email.
Definition: send.c:1845
WHERE bool C_SmimeIsDefault
Config: Use SMIME rather than PGP by default.
Definition: globals.h:271
struct Mailbox * mailbox
Definition: context.h:52
int el_add_email(struct EmailList *el, struct Email *e)
Get a list of the selected Emails.
Definition: context.c:385
void crypt_opportunistic_encrypt(struct Email *msg)
Can all recipients be determined.
Definition: crypt.c:980
#define SEND_RESEND
Reply using the current email as a template.
Definition: send.h:94
WHERE bool C_CryptOpportunisticEncrypt
Config: Enable encryption when the recipient&#39;s key is available.
Definition: globals.h:267
int mutt_prepare_template(FILE *fp, struct Mailbox *m, struct Email *newhdr, struct Email *e, bool resend)
Prepare a message template.
Definition: postpone.c:580
SecurityFlags security
bit 0-8: flags, bit 9,10: application.
Definition: email.h:39
void mutt_email_free(struct Email **e)
Free an Email.
Definition: email.c:41
#define SEC_OPPENCRYPT
Opportunistic encrypt mode.
Definition: ncrypt.h:128
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: ncrypt.h:129
#define STAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:322
#define WithCrypto
Definition: ncrypt.h:155
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition: ncrypt.h:130

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static bool is_reply ( struct Email reply,
struct Email orig 
)
static

Is one email a reply to another?

Parameters
replyEmail to test
origOriginal email
Return values
trueIt is a reply
falseIt is not a reply

Definition at line 1532 of file send.c.

1533 {
1534  if (!reply || !reply->env || !orig || !orig->env)
1535  return false;
1536  return mutt_list_find(&orig->env->references, reply->env->message_id) ||
1537  mutt_list_find(&orig->env->in_reply_to, reply->env->message_id);
1538 }
struct ListHead in_reply_to
in-reply-to header content
Definition: envelope.h:66
char * message_id
Definition: envelope.h:53
struct Envelope * env
envelope information
Definition: email.h:92
struct ListNode * mutt_list_find(const struct ListHead *h, const char *data)
Find a string in a List.
Definition: list.c:97
struct ListHead references
message references (in reverse order)
Definition: envelope.h:65

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static bool search_attach_keyword ( char *  filename)
static

Search an email for 'attachment' keywords.

Parameters
filenameFilename
Return values
trueIf the regex matches in the email

Search an email for the regex in $abort_noattach_regex. A match might indicate that the user should have attached something.

Note
Quoted lines (as defined by $quote_regex) are ignored

Definition at line 1550 of file send.c.

1551 {
1552  /* Search for the regex in C_AbortNoattachRegex within a file */
1554  !C_QuoteRegex->regex)
1555  {
1556  return false;
1557  }
1558 
1559  FILE *fp_att = mutt_file_fopen(filename, "r");
1560  if (!fp_att)
1561  return false;
1562 
1563  char *inputline = mutt_mem_malloc(1024);
1564  bool found = false;
1565  while (!feof(fp_att))
1566  {
1567  fgets(inputline, 1024, fp_att);
1568  if (!mutt_is_quote_line(inputline, NULL) &&
1569  (regexec(C_AbortNoattachRegex->regex, inputline, 0, NULL, 0) == 0))
1570  {
1571  found = true;
1572  break;
1573  }
1574  }
1575  FREE(&inputline);
1576  mutt_file_fclose(&fp_att);
1577  return found;
1578 }
struct Regex * C_AbortNoattachRegex
Config: Regex to match text indicating attachments are expected.
Definition: send.c:89
regex_t * regex
compiled expression
Definition: regex3.h:60
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:149
void * mutt_mem_malloc(size_t size)
Allocate memory on the heap.
Definition: memory.c:97
WHERE struct Regex * C_QuoteRegex
Config: Regex to match quoted text in a reply.
Definition: globals.h:177
#define FREE(x)
Definition: memory.h:40
int mutt_is_quote_line(char *line, regmatch_t *pmatch)
Is a line of message text a quote?
Definition: pager.c:873
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:578

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static int save_fcc ( struct Email msg,
char *  fcc,
size_t  fcc_len,
struct Body clear_content,
char *  pgpkeylist,
SendFlags  flags,
char **  finalpath 
)
static

Save an Email to a 'sent mail' folder.

Parameters
[in]msgEmail to save
[in]fccFolder to save to (can be comma-separated list)
[in]fcc_lenLength of fcc buffer
[in]clear_contentCleartext content of Email
[in]pgpkeylistList of pgp keys
[in]flagsSend mode, see SendFlags
[out]finalpathPath of final folder
Return values
0Success
-1Error

Definition at line 1592 of file send.c.

1594 {
1595  int rc = 0;
1596  struct Body *save_content = NULL;
1597 
1598  mutt_expand_path(fcc, fcc_len);
1599 
1600  /* Don't save a copy when we are in batch-mode, and the FCC
1601  * folder is on an IMAP server: This would involve possibly lots
1602  * of user interaction, which is not available in batch mode.
1603  *
1604  * Note: A patch to fix the problems with the use of IMAP servers
1605  * from non-curses mode is available from Brendan Cully. However,
1606  * I'd like to think a bit more about this before including it. */
1607 
1608 #ifdef USE_IMAP
1609  if ((flags & SEND_BATCH) && (fcc[0] != '\0') && (imap_path_probe(fcc, NULL) == MUTT_IMAP))
1610  {
1611  fcc[0] = '\0';
1612  mutt_error(_("Fcc to an IMAP mailbox is not supported in batch mode"));
1613  return rc;
1614  }
1615 #endif
1616 
1617  if (!(*fcc && mutt_str_strcmp("/dev/null", fcc)))
1618  return rc;
1619 
1620  struct Body *tmpbody = msg->content;
1621  struct Body *save_sig = NULL;
1622  struct Body *save_parts = NULL;
1623 
1624  if ((WithCrypto != 0) && (msg->security & (SEC_ENCRYPT | SEC_SIGN)) && C_FccClear)
1625  {
1626  msg->content = clear_content;
1627  msg->security &= ~(SEC_ENCRYPT | SEC_SIGN);
1629  }
1630 
1631  /* check to see if the user wants copies of all attachments */
1632  if (msg->content->type == TYPE_MULTIPART)
1633  {
1634  if ((WithCrypto != 0) && (msg->security & (SEC_ENCRYPT | SEC_SIGN)) &&
1635  ((mutt_str_strcmp(msg->content->subtype, "encrypted") == 0) ||
1636  (mutt_str_strcmp(msg->content->subtype, "signed") == 0)))
1637  {
1638  if ((clear_content->type == TYPE_MULTIPART) &&
1639  (query_quadoption(C_FccAttach, _("Save attachments in Fcc?")) == MUTT_NO))
1640  {
1641  if (!(msg->security & SEC_ENCRYPT) && (msg->security & SEC_SIGN))
1642  {
1643  /* save initial signature and attachments */
1644  save_sig = msg->content->parts->next;
1645  save_parts = clear_content->parts->next;
1646  }
1647 
1648  /* this means writing only the main part */
1649  msg->content = clear_content->parts;
1650 
1651  if (mutt_protect(msg, pgpkeylist) == -1)
1652  {
1653  /* we can't do much about it at this point, so
1654  * fallback to saving the whole thing to fcc */
1655  msg->content = tmpbody;
1656  save_sig = NULL;
1657  goto full_fcc;
1658  }
1659 
1660  save_content = msg->content;
1661  }
1662  }
1663  else
1664  {
1665  if (query_quadoption(C_FccAttach, _("Save attachments in Fcc?")) == MUTT_NO)
1666  msg->content = msg->content->parts;
1667  }
1668  }
1669 
1670 full_fcc:
1671  if (msg->content)
1672  {
1673  /* update received time so that when storing to a mbox-style folder
1674  * the From_ line contains the current time instead of when the
1675  * message was first postponed. */
1676  msg->received = time(NULL);
1677  rc = mutt_write_multiple_fcc(fcc, msg, NULL, false, NULL, finalpath);
1678  while (rc && !(flags & SEND_BATCH))
1679  {
1680  mutt_clear_error();
1681  int choice = mutt_multi_choice(
1682  /* L10N: Called when saving to $record or Fcc failed after sending.
1683  (r)etry tries the same mailbox again.
1684  alternate (m)ailbox prompts for a different mailbox to try.
1685  (s)kip aborts saving. */
1686  _("Fcc failed. (r)etry, alternate (m)ailbox, or (s)kip?"),
1687  /* L10N: These correspond to the "Fcc failed" multi-choice prompt
1688  (r)etry, alternate (m)ailbox, or (s)kip.
1689  Any similarity to famous leaders of the FSF is coincidental. */
1690  _("rms"));
1691  switch (choice)
1692  {
1693  case 2: /* alternate (m)ailbox */
1694  /* L10N: This is the prompt to enter an "alternate (m)ailbox" when the
1695  initial Fcc fails. */
1696  rc = mutt_enter_fname(_("Fcc mailbox"), fcc, fcc_len, true);
1697  if ((rc == -1) || (fcc[0] == '\0'))
1698  {
1699  rc = 0;
1700  break;
1701  }
1702  /* fall through */
1703 
1704  case 1: /* (r)etry */
1705  rc = mutt_write_multiple_fcc(fcc, msg, NULL, false, NULL, finalpath);
1706  break;
1707 
1708  case -1: /* abort */
1709  case 3: /* (s)kip */
1710  rc = 0;
1711  break;
1712  }
1713  }
1714  }
1715 
1716  msg->content = tmpbody;
1717 
1718  if ((WithCrypto != 0) && save_sig)
1719  {
1720  /* cleanup the second signature structures */
1721  if (save_content->parts)
1722  {
1723  mutt_body_free(&save_content->parts->next);
1724  save_content->parts = NULL;
1725  }
1726  mutt_body_free(&save_content);
1727 
1728  /* restore old signature and attachments */
1729  msg->content->parts->next = save_sig;
1730  msg->content->parts->parts->next = save_parts;
1731  }
1732  else if ((WithCrypto != 0) && save_content)
1733  {
1734  /* destroy the new encrypted body. */
1735  mutt_body_free(&save_content);
1736  }
1737 
1738  return 0;
1739 }
struct Envelope * mime_headers
memory hole protected headers
Definition: body.h:70
enum MailboxType imap_path_probe(const char *path, const struct stat *st)
Is this an IMAP mailbox? - Implements MxOps::path_probe()
Definition: imap.c:2440
enum QuadOption query_quadoption(enum QuadOption opt, const char *prompt)
Ask the user a quad-question.
Definition: init.c:3367
struct Body * content
list of MIME parts
Definition: email.h:93
#define _(a)
Definition: message.h:28
struct Body * next
next attachment in the list
Definition: body.h:60
&#39;IMAP&#39; Mailbox type
Definition: magic.h:42
#define SEC_ENCRYPT
Email is encrypted.
Definition: ncrypt.h:120
The body of an email.
Definition: body.h:34
char * mutt_expand_path(char *buf, size_t buflen)
Create the canonical path.
Definition: muttlib.c:127
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
Definition: mutt_logging.c:141
int mutt_write_multiple_fcc(const char *path, struct Email *e, const char *msgid, bool post, char *fcc, char **finalpath)
Handle FCC with multiple, comma separated entries.
Definition: sendlib.c:3105
char * subtype
content-type subtype
Definition: body.h:37
int mutt_multi_choice(const char *prompt, const char *letters)
Offer the user a multiple choice question.
Definition: curs_lib.c:824
#define SEC_SIGN
Email is signed.
Definition: ncrypt.h:121
int mutt_protect(struct Email *msg, char *keylist)
Encrypt and/or sign a message.
Definition: crypt.c:167
unsigned char C_FccAttach
Config: Save send message with all their attachments.
Definition: send.c:104
User answered &#39;No&#39;, or assume &#39;No&#39;.
Definition: quad.h:38
struct Body * parts
parts of a multipart or message/rfc822
Definition: body.h:61
bool C_FccClear
Config: Save sent messages unencrypted and unsigned.
Definition: send.c:105
SecurityFlags security
bit 0-8: flags, bit 9,10: application.
Definition: email.h:39
unsigned int type
content-type primary type
Definition: body.h:72
void mutt_body_free(struct Body **p)
Free a Body.
Definition: body.c:57
Type: &#39;multipart/*&#39;.
Definition: mime.h:37
#define mutt_error(...)
Definition: logging.h:83
void mutt_env_free(struct Envelope **p)
Free an Envelope.
Definition: envelope.c:53
#define mutt_enter_fname(prompt, buf, buflen, mailbox)
Definition: curs_lib.h:85
#define WithCrypto
Definition: ncrypt.h:155
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:618
time_t received
time when the message was placed in the mailbox
Definition: email.h:85
#define SEND_BATCH
Send email in batch mode (without user interaction)
Definition: send.h:91

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static int postpone_message ( struct Email msg,
struct Email cur,
char *  fcc,
SendFlags  flags 
)
static

Save an Email for another day.

Parameters
msgEmail to postpone
curCurrent Email in the index
fccFolder for 'sent mail'
flagsSend mode, see SendFlags
Return values
0Success
-1Error

Definition at line 1750 of file send.c.

1751 {
1752  char *pgpkeylist = NULL;
1753  char *encrypt_as = NULL;
1754  struct Body *clear_content = NULL;
1755 
1756  if (!(C_Postponed && *C_Postponed))
1757  {
1758  mutt_error(_("Can't postpone. $postponed is unset"));
1759  return -1;
1760  }
1761 
1762  if (msg->content->next)
1763  msg->content = mutt_make_multipart(msg->content);
1764 
1765  mutt_encode_descriptions(msg->content, true);
1766 
1767  if ((WithCrypto != 0) && C_PostponeEncrypt && (msg->security & SEC_ENCRYPT))
1768  {
1769  if (((WithCrypto & APPLICATION_PGP) != 0) && (msg->security & APPLICATION_PGP))
1770  encrypt_as = C_PgpDefaultKey;
1771  else if (((WithCrypto & APPLICATION_SMIME) != 0) && (msg->security & APPLICATION_SMIME))
1772  encrypt_as = C_SmimeDefaultKey;
1773  if (!(encrypt_as && *encrypt_as))
1774  encrypt_as = C_PostponeEncryptAs;
1775 
1776  if (encrypt_as && *encrypt_as)
1777  {
1778  bool is_signed = (msg->security & SEC_SIGN);
1779  if (is_signed)
1780  msg->security &= ~SEC_SIGN;
1781 
1782  pgpkeylist = mutt_str_strdup(encrypt_as);
1783  clear_content = msg->content;
1784  if (mutt_protect(msg, pgpkeylist) == -1)
1785  {
1786  if (is_signed)
1787  msg->security |= SEC_SIGN;
1788  FREE(&pgpkeylist);
1789  msg->content = mutt_remove_multipart(msg->content);
1791  return -1;
1792  }
1793 
1794  if (is_signed)
1795  msg->security |= SEC_SIGN;
1796  FREE(&pgpkeylist);
1797 
1798  mutt_encode_descriptions(msg->content, false);
1799  }
1800  }
1801 
1802  /* make sure the message is written to the right part of a maildir
1803  * postponed folder. */
1804  msg->read = false;
1805  msg->old = false;
1806 
1807  mutt_prepare_envelope(msg->env, false);
1808  mutt_env_to_intl(msg->env, NULL, NULL); /* Handle bad IDNAs the next time. */
1809 
1810  if (mutt_write_fcc(NONULL(C_Postponed), msg,
1811  (cur && (flags & SEND_REPLY)) ? cur->env->message_id : NULL,
1812  true, fcc, NULL) < 0)
1813  {
1814  if (clear_content)
1815  {
1816  mutt_body_free(&msg->content);
1817  msg->content = clear_content;
1818  }
1819  mutt_env_free(&msg->content->mime_headers); /* protected headers */
1820  msg->content = mutt_remove_multipart(msg->content);
1823  return -1;
1824  }
1825 
1827 
1828  if (clear_content)
1829  mutt_body_free(&clear_content);
1830 
1831  return 0;
1832 }
char * C_PostponeEncryptAs
Config: Fallback encryption key for postponed messages.
Definition: send.c:121
#define NONULL(x)
Definition: string2.h:36
struct Envelope * mime_headers
memory hole protected headers
Definition: body.h:70
struct Body * mutt_remove_multipart(struct Body *b)
Extract the multipart body if it exists.
Definition: sendlib.c:1734
WHERE char * C_SmimeDefaultKey
Config: Default key for SMIME operations.
Definition: globals.h:166
struct Body * content
list of MIME parts
Definition: email.h:93
bool C_PostponeEncrypt
Config: Self-encrypt postponed messages.
Definition: send.c:120
#define _(a)
Definition: message.h:28
struct Body * next
next attachment in the list
Definition: body.h:60
int mutt_env_to_intl(struct Envelope *env, const char **tag, char **err)
Convert an Envelope&#39;s Address fields to Punycode format.
Definition: envelope.c:244
#define SEC_ENCRYPT
Email is encrypted.
Definition: ncrypt.h:120
The body of an email.
Definition: body.h:34
void mutt_prepare_envelope(struct Envelope *env, bool final)
Prepare an email header.
Definition: sendlib.c:2904
bool read
Definition: email.h:51
char * message_id
Definition: envelope.h:53
bool old
Definition: email.h:50
struct Envelope * env
envelope information
Definition: email.h:92
static void decode_descriptions(struct Body *b)
rfc2047 decode them in case of an error
Definition: send.c:1446
struct Body * mutt_make_multipart(struct Body *b)
Create a multipart email.
Definition: sendlib.c:1708
void mutt_unprepare_envelope(struct Envelope *env)
Undo the encodings of mutt_prepare_envelope()
Definition: sendlib.c:2942
#define SEC_SIGN
Email is signed.
Definition: ncrypt.h:121
int mutt_protect(struct Email *msg, char *keylist)
Encrypt and/or sign a message.
Definition: crypt.c:167
void mutt_encode_descriptions(struct Body *b, bool recurse)
rfc2047 encode the content-descriptions
Definition: send.c:1429
void mutt_update_num_postponed(void)
Force the update of the number of postponed messages.
Definition: postpone.c:195
SecurityFlags security
bit 0-8: flags, bit 9,10: application.
Definition: email.h:39
#define SEND_REPLY
Reply to sender.
Definition: send.h:86
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: ncrypt.h:129
void mutt_body_free(struct Body **p)
Free a Body.
Definition: body.c:57
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:380
#define mutt_error(...)
Definition: logging.h:83
void mutt_env_free(struct Envelope **p)
Free an Envelope.
Definition: envelope.c:53
WHERE char * C_PgpDefaultKey
Config: Default key to use for PGP operations.
Definition: globals.h:162
#define FREE(x)
Definition: memory.h:40
WHERE char * C_Postponed
Config: Folder to store postponed messages.
Definition: globals.h:132
#define WithCrypto
Definition: ncrypt.h:155
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition: ncrypt.h:130
int mutt_write_fcc(const char *path, struct Email *e, const char *msgid, bool post, char *fcc, char **finalpath)
Write email to FCC mailbox.
Definition: sendlib.c:3152

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

int ci_send_message ( SendFlags  flags,
struct Email msg,
const char *  tempfile,
struct Context ctx,
struct EmailList *  el 
)

Send an email.

Parameters
flagsSend mode, see SendFlags
msgTemplate to use for new message
tempfileFile specified by -i or -H
ctxCurrent mailbox
elList of Emails to send
Return values
0Message was successfully sent
-1Message was aborted or an error occurred
1Message was postponed

Definition at line 1845 of file send.c.

1847 {
1848  char buf[1024];
1849  char fcc[PATH_MAX] = ""; /* where to copy this message */
1850  FILE *fp_tmp = NULL;
1851  struct Body *pbody = NULL;
1852  int i;
1853  bool killfrom = false;
1854  bool free_clear_content = false;
1855 
1856  struct Body *clear_content = NULL;
1857  char *pgpkeylist = NULL;
1858  /* save current value of "pgp_sign_as" and "smime_default_key" */
1859  char *pgp_signas = NULL;
1860  char *smime_signas = NULL;
1861  const char *tag = NULL;
1862  char *err = NULL;
1863  char *ctype = NULL;
1864  char *finalpath = NULL;
1865  struct EmailNode *en = NULL;
1866  struct Email *cur = NULL;
1867 
1868  if (el)
1869  en = STAILQ_FIRST(el);
1870  if (en)
1871  cur = STAILQ_NEXT(en, entries) ? en->email : NULL;
1872 
1873  int rc = -1;
1874 
1875 #ifdef USE_NNTP
1876  if (flags & SEND_NEWS)
1877  OptNewsSend = true;
1878  else
1879  OptNewsSend = false;
1880 #endif
1881 
1882  if (!flags && !msg && (C_Recall != MUTT_NO) &&
1883  mutt_num_postponed(ctx ? ctx->mailbox : NULL, true))
1884  {
1885  /* If the user is composing a new message, check to see if there
1886  * are any postponed messages first. */
1887  enum QuadOption ans =
1888  query_quadoption(C_Recall, _("Recall postponed message?"));
1889  if (ans == MUTT_ABORT)
1890  return rc;
1891 
1892  if (ans == MUTT_YES)
1893  flags |= SEND_POSTPONED;
1894  }
1895 
1896  if (flags & SEND_POSTPONED)
1897  {
1899  pgp_signas = mutt_str_strdup(C_PgpSignAs);
1901  smime_signas = mutt_str_strdup(C_SmimeSignAs);
1902  }
1903 
1904  /* Delay expansion of aliases until absolutely necessary--shouldn't
1905  * be necessary unless we are prompting the user or about to execute a
1906  * send-hook. */
1907 
1908  if (!msg)
1909  {
1910  msg = mutt_email_new();
1911 
1912  if (flags == SEND_POSTPONED)
1913  {
1914  rc = mutt_get_postponed(ctx, msg, &cur, fcc, sizeof(fcc));
1915  if (rc < 0)
1916  {
1917  flags = SEND_POSTPONED;
1918  goto cleanup;
1919  }
1920  flags = rc;
1921 #ifdef USE_NNTP
1922  /* If postponed message is a news article, it have
1923  * a "Newsgroups:" header line, then set appropriate flag. */
1924  if (msg->env->newsgroups)
1925  {
1926  flags |= SEND_NEWS;
1927  OptNewsSend = true;
1928  }
1929  else
1930  {
1931  flags &= ~SEND_NEWS;
1932  OptNewsSend = false;
1933  }
1934 #endif
1935  }
1936 
1937  if (flags & (SEND_POSTPONED | SEND_RESEND))
1938  {
1939  fp_tmp = mutt_file_fopen(msg->content->filename, "a+");
1940  if (!fp_tmp)
1941  {
1942  mutt_perror(msg->content->filename);
1943  goto cleanup;
1944  }
1945  }
1946 
1947  if (!msg->env)
1948  msg->env = mutt_env_new();
1949  }
1950 
1951  /* Parse and use an eventual list-post header */
1952  if ((flags & SEND_LIST_REPLY) && cur && cur->env && cur->env->list_post)
1953  {
1954  /* Use any list-post header as a template */
1955  mutt_parse_mailto(msg->env, NULL, cur->env->list_post);
1956  /* We don't let them set the sender's address. */
1957  mutt_addr_free(&msg->env->from);
1958  }
1959 
1960  if (!(flags & (SEND_KEY | SEND_POSTPONED | SEND_RESEND)))
1961  {
1962  /* When SEND_DRAFT_FILE is set, the caller has already
1963  * created the "parent" body structure. */
1964  if (!(flags & SEND_DRAFT_FILE))
1965  {
1966  pbody = mutt_body_new();
1967  pbody->next = msg->content; /* don't kill command-line attachments */
1968  msg->content = pbody;
1969 
1970  ctype = mutt_str_strdup(C_ContentType);
1971  if (!ctype)
1972  ctype = mutt_str_strdup("text/plain");
1973  mutt_parse_content_type(ctype, msg->content);
1974  FREE(&ctype);
1975  msg->content->unlink = true;
1976  msg->content->use_disp = false;
1978 
1979  if (!tempfile)
1980  {
1981  mutt_mktemp(buf, sizeof(buf));
1982  fp_tmp = mutt_file_fopen(buf, "w+");
1983  msg->content->filename = mutt_str_strdup(buf);
1984  }
1985  else
1986  {
1987  fp_tmp = mutt_file_fopen(tempfile, "a+");
1988  msg->content->filename = mutt_str_strdup(tempfile);
1989  }
1990  }
1991  else
1992  fp_tmp = mutt_file_fopen(msg->content->filename, "a+");
1993 
1994  if (!fp_tmp)
1995  {
1996  mutt_debug(LL_DEBUG1, "can't create tempfile %s (errno=%d)\n",
1997  msg->content->filename, errno);
1998  mutt_perror(msg->content->filename);
1999  goto cleanup;
2000  }
2001  }
2002 
2003  /* this is handled here so that the user can match ~f in send-hook */
2004  if (cur && C_ReverseName && !(flags & (SEND_POSTPONED | SEND_RESEND)))
2005  {
2006  /* we shouldn't have to worry about freeing 'msg->env->from' before
2007  * setting it here since this code will only execute when doing some
2008  * sort of reply. the pointer will only be set when using the -H command
2009  * line option.
2010  *
2011  * We shouldn't have to worry about alias expansion here since we are
2012  * either replying to a real or postponed message, therefore no aliases
2013  * should exist since the user has not had the opportunity to add
2014  * addresses to the list. We just have to ensure the postponed messages
2015  * have their aliases expanded. */
2016 
2017  if (msg->env->from)
2018  {
2019  mutt_debug(5, "msg->env->from before set_reverse_name: %s\n",
2020  msg->env->from->mailbox);
2021  }
2022  msg->env->from = set_reverse_name(cur->env);
2023  }
2024  if (cur && C_ReplyWithXorig && !(flags & (SEND_POSTPONED | SEND_RESEND | SEND_FORWARD)))
2025  {
2026  /* We shouldn't have to worry about freeing 'msg->env->from' before
2027  * setting it here since this code will only execute when doing some
2028  * sort of reply. The pointer will only be set when using the -H command
2029  * line option.
2030  *
2031  * If there is already a from address recorded in 'msg->env->from',
2032  * then it theoretically comes from C_ReverseName handling, and we don't use
2033  * the 'X-Orig-To header'. */
2034  if (cur->env->x_original_to && !msg->env->from)
2035  {
2036  msg->env->from = mutt_addr_copy(cur->env->x_original_to);
2037  mutt_debug(5, "msg->env->from extracted from X-Original-To: header: %s\n",
2038  msg->env->from->mailbox);
2039  }
2040  }
2041 
2042  if (!(flags & (SEND_POSTPONED | SEND_RESEND)) &&
2043  !((flags & SEND_DRAFT_FILE) && C_ResumeDraftFiles))
2044  {
2045  if ((flags & (SEND_REPLY | SEND_FORWARD | SEND_TO_SENDER)) && ctx &&
2046  (envelope_defaults(msg->env, ctx->mailbox, el, flags) == -1))
2047  {
2048  goto cleanup;
2049  }
2050 
2051  if (C_Hdrs)
2052  process_user_recips(msg->env);
2053 
2054  /* Expand aliases and remove duplicates/crossrefs */
2056 
2057  if (flags & SEND_REPLY)
2059 
2060 #ifdef USE_NNTP
2061  if ((flags & SEND_NEWS) && ctx && (ctx->mailbox->magic == MUTT_NNTP) &&
2062  !msg->env->newsgroups)
2063  {
2064  msg->env->newsgroups =
2065  mutt_str_strdup(((struct NntpMboxData *) ctx->mailbox->mdata)->group);
2066  }
2067 #endif
2068 
2069  if (!(flags & (SEND_MAILX | SEND_BATCH)) &&
2070  !(C_Autoedit && C_EditHeaders) && !((flags & SEND_REPLY) && C_FastReply))
2071  {
2072  if (edit_envelope(msg->env, flags) == -1)
2073  goto cleanup;
2074  }
2075 
2076  /* the from address must be set here regardless of whether or not
2077  * $use_from is set so that the '~P' (from you) operator in send-hook
2078  * patterns will work. if $use_from is unset, the from address is killed
2079  * after send-hooks are evaluated */
2080 
2081  if (!msg->env->from)
2082  {
2083  msg->env->from = mutt_default_from();
2084  killfrom = true;
2085  }
2086 
2087  if ((flags & SEND_REPLY) && cur)
2088  {
2089  /* change setting based upon message we are replying to */
2090  mutt_message_hook(ctx ? ctx->mailbox : NULL, cur, MUTT_REPLY_HOOK);
2091 
2092  /* set the replied flag for the message we are generating so that the
2093  * user can use ~Q in a send-hook to know when reply-hook's are also
2094  * being used. */
2095  msg->replied = true;
2096  }
2097 
2098  /* change settings based upon recipients */
2099 
2100  mutt_message_hook(NULL, msg, MUTT_SEND_HOOK);
2101 
2102  /* Unset the replied flag from the message we are composing since it is
2103  * no longer required. This is done here because the FCC'd copy of
2104  * this message was erroneously get the 'R'eplied flag when stored in
2105  * a maildir-style mailbox. */
2106  msg->replied = false;
2107 
2108  if (!(flags & SEND_KEY))
2109  {
2110  if (C_TextFlowed && (msg->content->type == TYPE_TEXT) &&
2111  (mutt_str_strcasecmp(msg->content->subtype, "plain") == 0))
2112  {
2113  mutt_param_set(&msg->content->parameter, "format", "flowed");
2114  }
2115  }
2116 
2117  /* $use_from and/or $from might have changed in a send-hook */
2118  if (killfrom)
2119  {
2120  mutt_addr_free(&msg->env->from);
2121  if (C_UseFrom && !(flags & (SEND_POSTPONED | SEND_RESEND)))
2122  msg->env->from = mutt_default_from();
2123  killfrom = false;
2124  }
2125 
2126  if (C_Hdrs)
2127  process_user_header(msg->env);
2128 
2129  if (flags & SEND_BATCH)
2130  mutt_file_copy_stream(stdin, fp_tmp);
2131 
2132  if (C_SigOnTop && !(flags & (SEND_MAILX | SEND_KEY | SEND_BATCH)) &&
2133  C_Editor && (mutt_str_strcmp(C_Editor, "builtin") != 0))
2134  {
2135  append_signature(fp_tmp);
2136  }
2137 
2138  /* include replies/forwarded messages, unless we are given a template */
2139  if (!tempfile && (ctx || !(flags & (SEND_REPLY | SEND_FORWARD))) &&
2140  (generate_body(fp_tmp, msg, flags, ctx ? ctx->mailbox : NULL, el) == -1))
2141  {
2142  goto cleanup;
2143  }
2144 
2145  if (!C_SigOnTop && !(flags & (SEND_MAILX | SEND_KEY | SEND_BATCH)) &&
2146  C_Editor && (mutt_str_strcmp(C_Editor, "builtin") != 0))
2147  {
2148  append_signature(fp_tmp);
2149  }
2150  }
2151 
2152  /* This hook is even called for postponed messages, and can, e.g., be
2153  * used for setting the editor, the sendmail path, or the
2154  * envelope sender. */
2155  mutt_message_hook(NULL, msg, MUTT_SEND2_HOOK);
2156 
2157  /* wait until now to set the real name portion of our return address so
2158  * that $realname can be set in a send-hook */
2159  if (msg->env->from && !msg->env->from->personal && !(flags & (SEND_RESEND | SEND_POSTPONED)))
2161 
2162  if (!(((WithCrypto & APPLICATION_PGP) != 0) && (flags & SEND_KEY)))
2163  mutt_file_fclose(&fp_tmp);
2164 
2165  if (flags & SEND_MAILX)
2166  {
2167  if (mutt_builtin_editor(msg->content->filename, msg, cur) == -1)
2168  goto cleanup;
2169  }
2170  else if (!(flags & SEND_BATCH))
2171  {
2172  struct stat st;
2173  time_t mtime = mutt_file_decrease_mtime(msg->content->filename, NULL);
2174 
2176 
2177  /* Select whether or not the user's editor should be called now. We
2178  * don't want to do this when:
2179  * 1) we are sending a key/cert
2180  * 2) we are forwarding a message and the user doesn't want to edit it.
2181  * This is controlled by the quadoption $forward_edit. However, if
2182  * both $edit_headers and $autoedit are set, we want to ignore the
2183  * setting of $forward_edit because the user probably needs to add the
2184  * recipients. */
2185  if (!(flags & SEND_KEY) &&
2186  (((flags & SEND_FORWARD) == 0) || (C_EditHeaders && C_Autoedit) ||
2187  (query_quadoption(C_ForwardEdit, _("Edit forwarded message?")) == MUTT_YES)))
2188  {
2189  /* If the this isn't a text message, look for a mailcap edit command */
2190  if (mutt_needs_mailcap(msg->content))
2191  {
2192  if (!mutt_edit_attachment(msg->content))
2193  goto cleanup;
2194  }
2195  else if (!C_Editor || (mutt_str_strcmp("builtin", C_Editor) == 0))
2196  mutt_builtin_editor(msg->content->filename, msg, cur);
2197  else if (C_EditHeaders)
2198  {
2199  mutt_env_to_local(msg->env);
2200  mutt_edit_headers(C_Editor, msg->content->filename, msg, fcc, sizeof(fcc));
2201  mutt_env_to_intl(msg->env, NULL, NULL);
2202  }
2203  else
2204  {
2206  if (stat(msg->content->filename, &st) == 0)
2207  {
2208  if (mtime != st.st_mtime)
2210  }
2211  else
2212  mutt_perror(msg->content->filename);
2213  }
2214 
2215  /* If using format=flowed, perform space stuffing. Avoid stuffing when
2216  * recalling a postponed message where the stuffing was already
2217  * performed. If it has already been performed, the format=flowed
2218  * parameter will be present. */
2219  if (C_TextFlowed && (msg->content->type == TYPE_TEXT) &&
2220  (mutt_str_strcasecmp("plain", msg->content->subtype) == 0))
2221  {
2222  char *p = mutt_param_get(&msg->content->parameter, "format");
2223  if (mutt_str_strcasecmp("flowed", p) != 0)
2224  rfc3676_space_stuff(msg);
2225  }
2226 
2227  mutt_message_hook(NULL, msg, MUTT_SEND2_HOOK);
2228  }
2229 
2230  if (!(flags & (SEND_POSTPONED | SEND_FORWARD | SEND_KEY | SEND_RESEND | SEND_DRAFT_FILE)))
2231  {
2232  if (stat(msg->content->filename, &st) == 0)
2233  {
2234  /* if the file was not modified, bail out now */
2235  if ((mtime == st.st_mtime) && !msg->content->next &&
2237  _("Abort unmodified message?")) == MUTT_YES))
2238  {
2239  mutt_message(_("Aborted unmodified message"));
2240  goto cleanup;
2241  }
2242  }
2243  else
2244  mutt_perror(msg->content->filename);
2245  }
2246  }
2247 
2248  /* Set the message security unless:
2249  * 1) crypto support is not enabled (WithCrypto==0)
2250  * 2) pgp: header field was present during message editing with $edit_headers (msg->security != 0)
2251  * 3) we are resending a message
2252  * 4) we are recalling a postponed message (don't override the user's saved settings)
2253  * 5) we are in mailx mode
2254  * 6) we are in batch mode
2255  *
2256  * This is done after allowing the user to edit the message so that security
2257  * settings can be configured with send2-hook and $edit_headers. */
2258  if ((WithCrypto != 0) && (msg->security == 0) &&
2259  !(flags & (SEND_BATCH | SEND_MAILX | SEND_POSTPONED | SEND_RESEND)))
2260  {
2261  if (C_CryptAutosign)
2262  msg->security |= SEC_SIGN;
2263  if (C_CryptAutoencrypt)
2264  msg->security |= SEC_ENCRYPT;
2265  if (C_CryptReplyencrypt && cur && (cur->security & SEC_ENCRYPT))
2266  msg->security |= SEC_ENCRYPT;
2267  if (C_CryptReplysign && cur && (cur->security & SEC_SIGN))
2268  msg->security |= SEC_SIGN;
2269  if (C_CryptReplysignencrypted && cur && (cur->security & SEC_ENCRYPT))
2270  msg->security |= SEC_SIGN;
2271  if (((WithCrypto & APPLICATION_PGP) != 0) &&
2273  {
2274  if (C_PgpAutoinline)
2275  msg->security |= SEC_INLINE;
2276  if (C_PgpReplyinline && cur && (cur->security & SEC_INLINE))
2277  msg->security |= SEC_INLINE;
2278  }
2279 
2281  {
2282  /* When replying / forwarding, use the original message's
2283  * crypto system. According to the documentation,
2284  * smime_is_default should be disregarded here.
2285  *
2286  * Problem: At least with forwarding, this doesn't really
2287  * make much sense. Should we have an option to completely
2288  * disable individual mechanisms at run-time? */
2289  if (cur)
2290  {
2291  if (((WithCrypto & APPLICATION_PGP) != 0) && C_CryptAutopgp &&
2292  (cur->security & APPLICATION_PGP))
2293  {
2294  msg->security |= APPLICATION_PGP;
2295  }
2296  else if (((WithCrypto & APPLICATION_SMIME) != 0) && C_CryptAutosmime &&
2297  (cur->security & APPLICATION_SMIME))
2298  {
2299  msg->security |= APPLICATION_SMIME;
2300  }
2301  }
2302 
2303  /* No crypto mechanism selected? Use availability + smime_is_default
2304  * for the decision. */
2305  if (!(msg->security & (APPLICATION_SMIME | APPLICATION_PGP)))
2306  {
2307  if (((WithCrypto & APPLICATION_SMIME) != 0) && C_CryptAutosmime && C_SmimeIsDefault)
2308  {
2309  msg->security |= APPLICATION_SMIME;
2310  }
2311  else if (((WithCrypto & APPLICATION_PGP) != 0) && C_CryptAutopgp)
2312  {
2313  msg->security |= APPLICATION_PGP;
2314  }
2315  else if (((WithCrypto & APPLICATION_SMIME) != 0) && C_CryptAutosmime)
2316  {
2317  msg->security |= APPLICATION_SMIME;
2318  }
2319  }
2320  }
2321 
2322  /* opportunistic encrypt relies on SMIME or PGP already being selected */
2324  {
2325  /* If something has already enabled encryption, e.g. C_CryptAutoencrypt
2326  * or C_CryptReplyencrypt, then don't enable opportunistic encrypt for
2327  * the message. */
2328  if (!(msg->security & SEC_ENCRYPT))
2329  {
2330  msg->security |= SEC_OPPENCRYPT;
2332  }
2333  }
2334 
2335  /* No permissible mechanisms found. Don't sign or encrypt. */
2336  if (!(msg->security & (APPLICATION_SMIME | APPLICATION_PGP)))
2337  msg->security = SEC_NO_FLAGS;
2338  }
2339 
2340  /* Deal with the corner case where the crypto module backend is not available.
2341  * This can happen if configured without pgp/smime and with gpgme, but
2342  * $crypt_use_gpgme is unset. */
2343  if (msg->security && !crypt_has_module_backend(msg->security))
2344  {
2345  mutt_error(_(
2346  "No crypto backend configured. Disabling message security setting."));
2347  msg->security = SEC_NO_FLAGS;
2348  }
2349 
2350  /* specify a default fcc. if we are in batchmode, only save a copy of
2351  * the message if the value of $copy is yes or ask-yes */
2352 
2353  if (!fcc[0] && !(flags & SEND_POSTPONED_FCC) && (!(flags & SEND_BATCH) || (C_Copy & 0x1)))
2354  {
2355  /* set the default FCC */
2356  if (!msg->env->from)
2357  {
2358  msg->env->from = mutt_default_from();
2359  killfrom = true; /* no need to check $use_from because if the user specified
2360  a from address it would have already been set by now */
2361  }
2362  mutt_select_fcc(fcc, sizeof(fcc), msg);
2363  if (killfrom)
2364  {
2365  mutt_addr_free(&msg->env->from);
2366  }
2367  }
2368 
2370 
2371  if (!(flags & (SEND_MAILX | SEND_BATCH)))
2372  {
2373  main_loop:
2374 
2375  mutt_pretty_mailbox(fcc, sizeof(fcc));
2376  i = mutt_compose_menu(msg, fcc, sizeof(fcc), cur,
2378  if (i == -1)
2379  {
2380 /* abort */
2381 #ifdef USE_NNTP
2382  if (flags & SEND_NEWS)
2383  mutt_message(_("Article not posted"));
2384  else
2385 #endif
2386  mutt_message(_("Mail not sent"));
2387  goto cleanup;
2388  }
2389  else if (i == 1)
2390  {
2391  if (postpone_message(msg, cur, fcc, flags) != 0)
2392  goto main_loop;
2393  mutt_message(_("Message postponed"));
2394  rc = 1;
2395  goto cleanup;
2396  }
2397  }
2398 
2399 #ifdef USE_NNTP
2400  if (!(flags & SEND_NEWS))
2401 #endif
2402  if ((mutt_addr_has_recips(msg->env->to) == 0) &&
2403  (mutt_addr_has_recips(msg->env->cc) == 0) &&
2404  (mutt_addr_has_recips(msg->env->bcc) == 0))
2405  {
2406  if (!(flags & SEND_BATCH))
2407  {
2408  mutt_error(_("No recipients specified"));
2409  goto main_loop;
2410  }
2411  else
2412  {
2413  puts(_("No recipients specified"));
2414  goto cleanup;
2415  }
2416  }
2417 
2418  if (mutt_env_to_intl(msg->env, &tag, &err))
2419  {
2420  mutt_error(_("Bad IDN in '%s': '%s'"), tag, err);
2421  FREE(&err);
2422  if (!(flags & SEND_BATCH))
2423  goto main_loop;
2424  else
2425  goto cleanup;
2426  }
2427 
2428  if (!msg->env->subject && !(flags & SEND_BATCH) &&
2429  (query_quadoption(C_AbortNosubject, _("No subject, abort sending?")) != MUTT_NO))
2430  {
2431  /* if the abort is automatic, print an error message */
2432  if (C_AbortNosubject == MUTT_YES)
2433  mutt_error(_("No subject specified"));
2434  goto main_loop;
2435  }
2436 #ifdef USE_NNTP
2437  if ((flags & SEND_NEWS) && !msg->env->subject)
2438  {
2439  mutt_error(_("No subject specified"));
2440  goto main_loop;
2441  }
2442 
2443  if ((flags & SEND_NEWS) && !msg->env->newsgroups)
2444  {
2445  mutt_error(_("No newsgroup specified"));
2446  goto main_loop;
2447  }
2448 #endif
2449 
2450  if (!(flags & SEND_BATCH) && (C_AbortNoattach != MUTT_NO) &&
2451  !msg->content->next && (msg->content->type == TYPE_TEXT) &&
2452  (mutt_str_strcasecmp(msg->content->subtype, "plain") == 0) &&
2455  _("No attachments, cancel sending?")) != MUTT_NO))
2456  {
2457  /* if the abort is automatic, print an error message */
2458  if (C_AbortNoattach == MUTT_YES)
2459  {
2460  mutt_error(_("Message contains text matching "
2461  "\"$abort_noattach_regex\". Not sending."));
2462  }
2463  goto main_loop;
2464  }
2465 
2466  if (msg->content->next)
2467  msg->content = mutt_make_multipart(msg->content);
2468 
2469  /* Ok, we need to do it this way instead of handling all fcc stuff in
2470  * one place in order to avoid going to main_loop with encoded "env"
2471  * in case of error. Ugh. */
2472 
2473  mutt_encode_descriptions(msg->content, true);
2474 
2475  /* Make sure that clear_content and free_clear_content are
2476  * properly initialized -- we may visit this particular place in
2477  * the code multiple times, including after a failed call to
2478  * mutt_protect(). */
2479 
2480  clear_content = NULL;
2481  free_clear_content = false;
2482 
2483  if (WithCrypto)
2484  {
2485  if (msg->security & (SEC_ENCRYPT | SEC_SIGN))
2486  {
2487  /* save the decrypted attachments */
2488  clear_content = msg->content;
2489 
2490  if ((crypt_get_keys(msg, &pgpkeylist, 0) == -1) ||
2491  (mutt_protect(msg, pgpkeylist) == -1))
2492  {
2493  msg->content = mutt_remove_multipart(msg->content);
2494 
2495  FREE(&pgpkeylist);
2496 
2498  goto main_loop;
2499  }
2500  mutt_encode_descriptions(msg->content, false);
2501  }
2502 
2503  /* at this point, msg->content is one of the following three things:
2504  * - multipart/signed. In this case, clear_content is a child
2505  * - multipart/encrypted. In this case, clear_content exists independently
2506  * - application/pgp. In this case, clear_content exists independently
2507  * - something else. In this case, it's the same as clear_content
2508  */
2509 
2510  /* This is ugly -- lack of "reporting back" from mutt_protect(). */
2511 
2512  if (clear_content && (msg->content != clear_content) && (msg->content->parts != clear_content))
2513  free_clear_content = true;
2514  }
2515 
2516  if (!OptNoCurses && !(flags & SEND_MAILX))
2517  mutt_message(_("Sending message..."));
2518 
2519  mutt_prepare_envelope(msg->env, true);
2520 
2521  i = send_message(msg);
2522  if (i < 0)
2523  {
2524  if (!(flags & SEND_BATCH))
2525  {
2526  if (!WithCrypto)
2527  ;
2528  else if ((msg->security & SEC_ENCRYPT) ||
2529  ((msg->security & SEC_SIGN) && (msg->content->type == TYPE_APPLICATION)))
2530  {
2531  mutt_body_free(&msg->content); /* destroy PGP data */
2532  msg->content = clear_content; /* restore clear text. */
2533  }
2534  else if ((msg->security & SEC_SIGN) && (msg->content->type == TYPE_MULTIPART))
2535  {
2536  mutt_body_free(&msg->content->parts->next); /* destroy sig */
2537  msg->content = mutt_remove_multipart(msg->content);
2538  }
2539 
2540  FREE(&pgpkeylist);
2541  mutt_env_free(&msg->content->mime_headers); /* protected headers */
2542  msg->content = mutt_remove_multipart(msg->content);
2545  FREE(&finalpath);
2546  goto main_loop;
2547  }
2548  else
2549  {
2550  puts(_("Could not send the message"));
2551  goto cleanup;
2552  }
2553  }
2554 
2555  save_fcc(msg, fcc, sizeof(fcc), clear_content, pgpkeylist, flags, &finalpath);
2556 
2557  if (!OptNoCurses && !(flags & SEND_MAILX))
2558  {
2559  mutt_message((i != 0) ? _("Sending in background") :
2560  (flags & SEND_NEWS) ? _("Article posted") : /* USE_NNTP */
2561  _("Mail sent"));
2562 #ifdef USE_NOTMUCH
2563  if (C_NmRecord)
2564  nm_record_message(ctx ? ctx->mailbox : NULL, finalpath, cur);
2565 #endif
2566  mutt_sleep(0);
2567  }
2568 
2569  if (WithCrypto)
2570  FREE(&pgpkeylist);
2571 
2572  if ((WithCrypto != 0) && free_clear_content)
2573  mutt_body_free(&clear_content);
2574 
2575  /* set 'replied' flag only if the user didn't change/remove
2576  * In-Reply-To: and References: headers during edit */
2577  if (flags & SEND_REPLY)
2578  {
2579  if (!(flags & SEND_POSTPONED) && ctx && ctx->mailbox)
2580  {
2581  STAILQ_FOREACH(en, el, entries)
2582  {
2583  mutt_set_flag(ctx->mailbox, en->email, MUTT_REPLIED, is_reply(en->email, msg));
2584  }
2585  }
2586  }
2587 
2588  rc = 0;
2589 
2590 cleanup:
2591 
2592  if (flags & SEND_POSTPONED)
2593  {
2594  if (WithCrypto & APPLICATION_PGP)
2595  {
2596  FREE(&C_PgpSignAs);
2597  C_PgpSignAs = pgp_signas;
2598  }
2599  if (WithCrypto & APPLICATION_SMIME)
2600  {
2601  FREE(&C_SmimeSignAs);
2602  C_SmimeSignAs = smime_signas;
2603  }
2604  }
2605 
2606  mutt_file_fclose(&fp_tmp);
2607  if (!(flags & SEND_NO_FREE_HEADER))
2608  mutt_email_free(&msg);
2609 
2610  FREE(&finalpath);
2611  return rc;
2612 }
#define MUTT_SEND_HOOK
send-hook: when composing a new email
Definition: hook.h:46
void mutt_fix_reply_recipients(struct Envelope *env)
Remove duplicate recipients.
Definition: send.c:910
bool C_Hdrs
Config: Add custom headers to outgoing mail.
Definition: send.c:112
char * filename
when sending a message, this is the file to which this structure refers
Definition: body.h:48
struct Envelope * mime_headers
memory hole protected headers
Definition: body.h:70
struct Body * mutt_remove_multipart(struct Body *b)
Extract the multipart body if it exists.
Definition: sendlib.c:1734
#define mutt_set_flag(m, e, flag, bf)
Definition: protos.h:68
#define SEND_POSTPONED_FCC
Used by mutt_get_postponed() to signal that the x-mutt-fcc header field was present.
Definition: send.h:95
#define SEND_TO_SENDER
Compose new email to sender.
Definition: send.h:98
The envelope/body of an email.
Definition: email.h:37
#define mutt_perror(...)
Definition: logging.h:84
static void fix_end_of_file(const char *data)
Ensure a file ends with a linefeed.
Definition: send.c:1463
unsigned char C_AbortNoattach
Config: Abort sending the email if attachments are missing.
Definition: send.c:88
int mutt_builtin_editor(const char *path, struct Email *msg, struct Email *cur)
Show the user the built-in editor.
Definition: edit.c:400
static bool search_attach_keyword(char *filename)
Search an email for &#39;attachment&#39; keywords.
Definition: send.c:1550
&#39;NNTP&#39; (Usenet) Mailbox type
Definition: magic.h:41
User aborted the question (with Ctrl-G)
Definition: quad.h:37
enum QuadOption query_quadoption(enum QuadOption opt, const char *prompt)
Ask the user a quad-question.
Definition: init.c:3367
static int send_message(struct Email *msg)
Send an email.
Definition: send.c:1354
#define mutt_message(...)
Definition: logging.h:82
int mutt_parse_mailto(struct Envelope *e, char **body, const char *src)
Parse a mailto:// url.
Definition: parse.c:1463
struct Address * to
Definition: envelope.h:42
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:39
#define SEND_DRAFT_FILE
Used by the -H flag.
Definition: send.h:97
static int postpone_message(struct Email *msg, struct Email *cur, char *fcc, SendFlags flags)
Save an Email for another day.
Definition: send.c:1750
void mutt_expand_aliases_env(struct Envelope *env)
Expand aliases in all the fields of an Envelope.
Definition: alias.c:313
static int envelope_defaults(struct Envelope *env, struct Mailbox *m, struct EmailList *el, SendFlags flags)
Fill in some defaults for a new email.
Definition: send.c:1031
#define SEC_NO_FLAGS
No flags are set.
Definition: ncrypt.h:119
static void process_user_header(struct Envelope *env)
Process the user headers.
Definition: send.c:409
#define SEND_FORWARD
Forward email.
Definition: send.h:89
struct Body * content
list of MIME parts
Definition: email.h:93
int mutt_edit_attachment(struct Body *a)
Edit an attachment.
Definition: mutt_attach.c:259
#define _(a)
Definition: message.h:28
unsigned char C_AbortUnmodified
Config: Abort the sending if the message hasn&#39;t been edited.
Definition: send.c:91
WHERE bool C_PgpAutoinline
Config: Use old-style inline PGP messages (not recommended)
Definition: globals.h:275
struct Body * next
next attachment in the list
Definition: body.h:60
WHERE unsigned char C_Copy
Config: Save outgoing emails to $record.
Definition: globals.h:181
WHERE bool OptNoCurses
(pseudo) when sending in batch mode
Definition: options.h:45
char * mailbox
mailbox and host address
Definition: address.h:35
#define SEC_INLINE
Email has an inline signature.
Definition: ncrypt.h:127
bool C_CryptAutosign
Config: Automatically PGP sign all outgoing mail.
Definition: send.c:97
struct Email * mutt_email_new(void)
Create a new Email.
Definition: email.c:63
int mutt_env_to_intl(struct Envelope *env, const char **tag, char **err)
Convert an Envelope&#39;s Address fields to Punycode format.
Definition: envelope.c:244
#define SEC_ENCRYPT
Email is encrypted.
Definition: ncrypt.h:120
#define SEND_POSTPONED
Recall a postponed email.
Definition: send.h:90
bool C_CryptReplysign
Config: Sign replies to signed messages.
Definition: send.c:100
void mutt_select_fcc(char *path, size_t pathlen, struct Email *e)
Select the FCC path for an email.
Definition: hook.c:695
Messages that have been replied to.
Definition: mutt.h:98
The body of an email.
Definition: body.h:34
void mutt_prepare_envelope(struct Envelope *env, bool final)
Prepare an email header.
Definition: sendlib.c:2904
unsigned int disposition
content-disposition
Definition: body.h:74
int nm_record_message(struct Mailbox *m, char *path, struct Email *e)
Add a message to the Notmuch database.
WHERE bool C_SmimeIsDefault
Config: Use SMIME rather than PGP by default.
Definition: globals.h:271
bool C_CryptAutosmime
Config: Allow automatic SMIME functions.
Definition: send.c:98
#define SEND_MAILX
Send email in Mailx compatibility mode.
Definition: send.h:92
static struct Address * set_reverse_name(struct Envelope *env)
Try to set the &#39;from&#39; field from the recipients.
Definition: send.c:1285
void mutt_sleep(short s)
Sleep for a while.
Definition: muttlib.c:1498
WHERE bool C_EditHeaders
Config: Let the user edit the email headers whilst editing an email.
Definition: globals.h:208
struct Mailbox * mailbox
Definition: context.h:52
unsigned char C_Recall
Config: Recall postponed mesaages when asked to compose a message.
Definition: send.c:122
struct Body * mutt_body_new(void)
Create a new Body.
Definition: body.c:43
unsigned char C_AbortNosubject
Config: Abort creating the email if subject is missing.
Definition: send.c:90
enum MailboxType magic
mailbox type
Definition: mailbox.h:105
void mutt_update_encoding(struct Body *a)
Update the encoding type.
Definition: sendlib.c:1447
static void process_user_recips(struct Envelope *env)
Process the user headers.
Definition: send.c:382
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:149
struct Envelope * env
envelope information
Definition: email.h:92
static void decode_descriptions(struct Body *b)
rfc2047 decode them in case of an error
Definition: send.c:1446
int crypt_get_keys(struct Email *msg, char **keylist, bool oppenc_mode)
Check we have all the keys we need.
Definition: crypt.c:909
WHERE bool C_Autoedit
Config: Skip the initial compose menu and edit the email.
Definition: globals.h:199
#define SEND_LIST_REPLY
Reply to mailing list.
Definition: send.h:88
static bool is_reply(struct Email *reply, struct Email *orig)
Is one email a reply to another?
Definition: send.c:1532
struct Address * from
Definition: envelope.h:41
static int save_fcc(struct Email *msg, char *fcc, size_t fcc_len, struct Body *clear_content, char *pgpkeylist, SendFlags flags, char **finalpath)
Save an Email to a &#39;sent mail&#39; folder.
Definition: send.c:1592
void * mdata
driver specific data
Definition: mailbox.h:136
struct Envelope * mutt_env_new(void)
Create a new Envelope.
Definition: envelope.c:40
struct Body * mutt_make_multipart(struct Body *b)
Create a multipart email.
Definition: sendlib.c:1708
#define SEND_KEY
Mail a PGP public key.
Definition: send.h:93
struct Address * x_original_to
Definition: envelope.h:48
char * subtype
content-type subtype
Definition: body.h:37
void crypt_opportunistic_encrypt(struct Email *msg)
Can all recipients be determined.
Definition: crypt.c:980
bool C_FastReply
Config: Don&#39;t prompt for the recipients and subject when replying/forwarding.
Definition: send.c:103
#define SEND_RESEND
Reply using the current email as a template.
Definition: send.h:94
struct Address * bcc
Definition: envelope.h:44
void mutt_unprepare_envelope(struct Envelope *env)
Undo the encodings of mutt_prepare_envelope()
Definition: sendlib.c:2942
#define mutt_mktemp(buf, buflen)
Definition: muttlib.h:74
#define SEC_SIGN
Email is signed.
Definition: ncrypt.h:121
struct Address * mutt_default_from(void)
Get a default &#39;from&#39; Address.
Definition: send.c:1319
int mutt_protect(struct Email *msg, char *keylist)
Encrypt and/or sign a message.
Definition: crypt.c:167
WHERE bool C_CryptOpportunisticEncrypt
Config: Enable encryption when the recipient&#39;s key is available.
Definition: globals.h:267
bool C_ReverseName
Config: Set the &#39;From&#39; from the address the email was sent to.
Definition: send.c:126
#define PATH_MAX
Definition: mutt.h:49
User answered &#39;No&#39;, or assume &#39;No&#39;.
Definition: quad.h:38
int mutt_compose_menu(struct Email *msg, char *fcc, size_t fcclen, struct Email *cur, int flags)
Allow the user to edit the message envelope.
Definition: compose.c:884
void mutt_encode_descriptions(struct Body *b, bool recurse)
rfc2047 encode the content-descriptions
Definition: send.c:1429
Type: &#39;text/*&#39;.
Definition: mime.h:38
void mutt_param_set(struct ParameterList *p, const char *attribute, const char *value)
Set a Parameter.
Definition: parameter.c:109
struct Body * parts
parts of a multipart or message/rfc822
Definition: body.h:61
static int generate_body(FILE *fp_tmp, struct Email *msg, SendFlags flags, struct Mailbox *m, struct EmailList *el)
Create a new email body.
Definition: send.c:1101
struct Address * mutt_addr_copy(struct Address *addr)
Copy the real address.
Definition: address.c:729
#define SEND_NEWS
Reply to a news article.
Definition: send.h:100
void mutt_pretty_mailbox(char *buf, size_t buflen)
Shorten a mailbox path using &#39;~&#39; or &#39;=&#39;.
Definition: muttlib.c:615
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:350
#define STAILQ_NEXT(elm, field)
Definition: queue.h:398
SecurityFlags security
bit 0-8: flags, bit 9,10: application.
Definition: email.h:39
bool C_PgpReplyinline
Config: Reply using old-style inline PGP messages (not recommended)
Definition: send.c:118
#define SEND_REPLY
Reply to sender.
Definition: send.h:86
NNTP-specific Mailbox data -.
Definition: nntp.h:139
bool C_SigOnTop
Config: Insert the signature before the quoted text.
Definition: send.c:130
void mutt_email_free(struct Email **e)
Free an Email.
Definition: email.c:41
#define SEND_NO_FREE_HEADER
Used by the -E flag.
Definition: send.h:96
void rfc3676_space_stuff(struct Email *e)
Perform required RFC3676 space stuffing.
Definition: rfc3676.c:397
unsigned char C_ForwardEdit
Config: Automatically start the editor when forwarding a message.
Definition: send.c:109
unsigned int type
content-type primary type
Definition: body.h:72
#define SEC_OPPENCRYPT
Opportunistic encrypt mode.
Definition: ncrypt.h:128
char * list_post
this stores a mailto URL, or nothing
Definition: envelope.h:49
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: ncrypt.h:129
bool C_CryptReplyencrypt
Config: Encrypt replies to encrypted messages.
Definition: send.c:99
bool crypt_has_module_backend(SecurityFlags type)
Is there a crypto backend for a given type?
Definition: cryptglue.c:151
char * personal
real name of address
Definition: address.h:34
int mutt_num_postponed(struct Mailbox *m, bool force)
Return the number of postponed messages.
Definition: postpone.c:85
WHERE bool C_TextFlowed
Config: Generate &#39;format=flowed&#39; messages.
Definition: globals.h:255
void mutt_parse_content_type(const char *s, struct Body *ct)
Parse a content type.
Definition: parse.c:425
void mutt_env_to_local(struct Envelope *env)
Convert an Envelope&#39;s Address fields to local format.
Definition: envelope.c:206
WHERE bool C_ResumeDraftFiles
Config: Process draft files like postponed messages.
Definition: globals.h:245
char * mutt_param_get(const struct ParameterList *p, const char *s)
Find a matching Parameter.
Definition: parameter.c:83
void mutt_body_free(struct Body **p)
Free a Body.
Definition: body.c:57
char * subject
Definition: envelope.h:50
Type: &#39;multipart/*&#39;.
Definition: mime.h:37
Log at debug level 1.
Definition: logging.h:56
char * newsgroups
Definition: envelope.h:59
#define MUTT_SEND2_HOOK
send2-hook: when changing fields in the compose menu
Definition: hook.h:55
bool use_disp
Content-Disposition uses filename= ?
Definition: body.h:75
int mutt_file_copy_stream(FILE *fp_in, FILE *fp_out)
Copy the contents of one file into another.
Definition: file.c:264
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:380
void mutt_edit_headers(const char *editor, const char *body, struct Email *msg, char *fcc, size_t fcclen)
Let the user edit the message header and body.
Definition: mutt_header.c:171
struct Email * email
Definition: email.h:123
#define mutt_error(...)
Definition: logging.h:83
bool mutt_needs_mailcap(struct Body *m)
Does this type need a mailcap entry do display.
Definition: muttlib.c:409
bool unlink
flag to indicate the file named by "filename" should be unlink()ed before free()ing this structure ...
Definition: body.h:76
bool replied
Definition: email.h:54
void mutt_env_free(struct Envelope **p)
Free an Envelope.
Definition: envelope.c:53
static int edit_envelope(struct Envelope *en, SendFlags flags)
Edit Envelope fields.
Definition: send.c:272
int mutt_str_strcasecmp(const char *a, const char *b)
Compare two strings ignoring case, safely.
Definition: string.c:631
WHERE char * C_Editor
Config: External command to use as an email editor.
Definition: globals.h:104
bool C_UseFrom
Config: Set the &#39;From&#39; header for outgoing mail.
Definition: send.c:131
time_t mutt_file_decrease_mtime(const char *fp, struct stat *st)
Decrease a file&#39;s modification time by 1 second.
Definition: file.c:954
#define MUTT_REPLY_HOOK
reply-hook: when replying to an email
Definition: hook.h:54
#define FREE(x)
Definition: memory.h:40
#define MUTT_COMPOSE_NOFREEHEADER
Definition: compose.h:36
int mutt_addr_has_recips(struct Address *a)
Count the number of Addresses with valid recipients.
Definition: address.c:887
void mutt_addr_free(struct Address **p)
Free a list of Addresses.
Definition: address.c:451
List of Emails.
Definition: email.h:121
WHERE char * C_Realname
Config: Real name of the user.
Definition: globals.h:136
#define mutt_debug(LEVEL,...)
Definition: logging.h:80
void mutt_message_hook(struct Mailbox *m, struct Email *e, HookFlags type)
Perform a message hook.
Definition: hook.c:578
WHERE bool OptNewsSend
(pseudo) used to change behavior when posting
Definition: options.h:43
WHERE char * C_PgpSignAs
Config: Use this alternative key for signing messages.
Definition: globals.h:163
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:578
WHERE char * C_SmimeSignAs
Config: Use this alternative key for signing messages.
Definition: globals.h:167
static void append_signature(FILE *fp)
Append a signature to an email.
Definition: send.c:137
char * C_ContentType
Config: Default "Content-Type" for newly composed messages.
Definition: send.c:94
Content is inline.
Definition: mime.h:62
struct ParameterList parameter
parameters of the content-type
Definition: body.h:39
#define STAILQ_FIRST(head)
Definition: queue.h:348
#define WithCrypto
Definition: ncrypt.h:155
void mutt_edit_file(const char *editor, const char *file)
Let the user edit a file.
Definition: curs_lib.c:308
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:618
Type: &#39;application/*&#39;.
Definition: mime.h:33
QuadOption
Possible values for a quad-option.
Definition: quad.h:35
#define SEND_BATCH
Send email in batch mode (without user interaction)
Definition: send.h:91
struct Address * cc
Definition: envelope.h:43
int mutt_get_postponed(struct Context *ctx, struct Email *hdr, struct Email **cur, char *fcc, size_t fcclen)
Recall a postponed message.
Definition: postpone.c:290
bool C_CryptReplysignencrypted
Config: Sign replies to encrypted messages.
Definition: send.c:101
bool C_NmRecord
Config: (notmuch) If the &#39;record&#39; mailbox (sent mail) should be indexed.
Definition: send.c:117
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition: ncrypt.h:130
bool C_CryptAutopgp
Config: Allow automatic PGP functions.
Definition: send.c:96
bool C_CryptAutoencrypt
Config: Automatically PGP encrypt all outgoing mail.
Definition: send.c:95
bool C_ReplyWithXorig
Config: Create &#39;From&#39; header from &#39;X-Original-To&#39; header.
Definition: send.c:125

+ Here is the caller graph for this function:

Variable Documentation

unsigned char C_AbortNoattach

Config: Abort sending the email if attachments are missing.

Definition at line 88 of file send.c.

struct Regex* C_AbortNoattachRegex

Config: Regex to match text indicating attachments are expected.

Definition at line 89 of file send.c.

unsigned char C_AbortNosubject

Config: Abort creating the email if subject is missing.

Definition at line 90 of file send.c.

unsigned char C_AbortUnmodified

Config: Abort the sending if the message hasn't been edited.

Definition at line 91 of file send.c.

bool C_AskFollowUp

Config: (nntp) Ask the user for follow-up groups before editing.

Definition at line 92 of file send.c.

bool C_AskXCommentTo

Config: (nntp) Ask the user for the 'X-Comment-To' field before editing.

Definition at line 93 of file send.c.

char* C_ContentType

Config: Default "Content-Type" for newly composed messages.

Definition at line 94 of file send.c.

bool C_CryptAutoencrypt

Config: Automatically PGP encrypt all outgoing mail.

Definition at line 95 of file send.c.

bool C_CryptAutopgp

Config: Allow automatic PGP functions.

Definition at line 96 of file send.c.

bool C_CryptAutosign

Config: Automatically PGP sign all outgoing mail.

Definition at line 97 of file send.c.

bool C_CryptAutosmime

Config: Allow automatic SMIME functions.

Definition at line 98 of file send.c.

bool C_CryptReplyencrypt

Config: Encrypt replies to encrypted messages.

Definition at line 99 of file send.c.

bool C_CryptReplysign

Config: Sign replies to signed messages.

Definition at line 100 of file send.c.

bool C_CryptReplysignencrypted

Config: Sign replies to encrypted messages.

Definition at line 101 of file send.c.

char* C_EmptySubject

Config: Subject to use when replying to an email with none.

Definition at line 102 of file send.c.

bool C_FastReply

Config: Don't prompt for the recipients and subject when replying/forwarding.

Definition at line 103 of file send.c.

unsigned char C_FccAttach

Config: Save send message with all their attachments.

Definition at line 104 of file send.c.

bool C_FccClear

Config: Save sent messages unencrypted and unsigned.

Definition at line 105 of file send.c.

bool C_FollowupTo

Config: Add the 'Mail-Followup-To' header is generated when sending mail.

Definition at line 106 of file send.c.

char* C_ForwardAttributionIntro

Config: Prefix message for forwarded messages.

Definition at line 107 of file send.c.

char* C_ForwardAttributionTrailer

Config: Suffix message for forwarded messages.

Definition at line 108 of file send.c.

unsigned char C_ForwardEdit

Config: Automatically start the editor when forwarding a message.

Definition at line 109 of file send.c.

char* C_ForwardFormat

Config: printf-like format string to control the subject when forwarding a message.

Definition at line 110 of file send.c.

bool C_ForwardReferences

Config: Set the 'In-Reply-To' and 'References' headers when forwarding a message.

Definition at line 111 of file send.c.

bool C_Hdrs

Config: Add custom headers to outgoing mail.

Definition at line 112 of file send.c.

unsigned char C_HonorFollowupTo

Config: Honour the 'Mail-Followup-To' header when group replying.

Definition at line 113 of file send.c.

bool C_IgnoreListReplyTo

Config: Ignore the 'Reply-To' header when using <reply> on a mailing list.

Definition at line 114 of file send.c.

unsigned char C_Include

Config: Include a copy of the email that's being replied to.

Definition at line 115 of file send.c.

bool C_Metoo

Config: Remove the user's address from the list of recipients.

Definition at line 116 of file send.c.

bool C_NmRecord

Config: (notmuch) If the 'record' mailbox (sent mail) should be indexed.

Definition at line 117 of file send.c.

bool C_PgpReplyinline

Config: Reply using old-style inline PGP messages (not recommended)

Definition at line 118 of file send.c.

char* C_PostIndentString

Config: Suffix message to add after reply text.

Definition at line 119 of file send.c.

bool C_PostponeEncrypt

Config: Self-encrypt postponed messages.

Definition at line 120 of file send.c.

char* C_PostponeEncryptAs

Config: Fallback encryption key for postponed messages.

Definition at line 121 of file send.c.

unsigned char C_Recall

Config: Recall postponed mesaages when asked to compose a message.

Definition at line 122 of file send.c.

bool C_ReplySelf

Config: Really reply to yourself, when replying to your own email.

Definition at line 123 of file send.c.

unsigned char C_ReplyTo

Config: Address to use as a 'Reply-To' header.

Definition at line 124 of file send.c.

bool C_ReplyWithXorig

Config: Create 'From' header from 'X-Original-To' header.

Definition at line 125 of file send.c.

bool C_ReverseName

Config: Set the 'From' from the address the email was sent to.

Definition at line 126 of file send.c.

bool C_ReverseRealname

Config: Set the 'From' from the full 'To' address the email was sent to.

Definition at line 127 of file send.c.

bool C_SigDashes

Config: Insert '– ' before the signature.

Definition at line 128 of file send.c.

char* C_Signature

Config: File containing a signature to append to all mail.

Definition at line 129 of file send.c.

bool C_SigOnTop

Config: Insert the signature before the quoted text.

Definition at line 130 of file send.c.

bool C_UseFrom

Config: Set the 'From' header for outgoing mail.

Definition at line 131 of file send.c.