NeoMutt  2018-07-16 +1360-3df4a2
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 "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 "hdrline.h"
#include "hook.h"
#include "mailbox.h"
#include "mutt_attach.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 "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...
 
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 133 of file send.c.

134 {
135  FILE *fp_tmp = NULL;
136  pid_t pid;
137 
138  if (C_Signature && (fp_tmp = mutt_open_read(C_Signature, &pid)))
139  {
140  if (C_SigDashes)
141  fputs("\n-- \n", fp);
142  mutt_file_copy_stream(fp_tmp, fp);
143  mutt_file_fclose(&fp_tmp);
144  if (pid != -1)
145  mutt_wait_filter(pid);
146  }
147 }
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:149
bool C_SigDashes
Config: Insert &#39;– &#39; before the signature.
Definition: send.c:124
int mutt_file_copy_stream(FILE *fp_in, FILE *fp_out)
Copy the contents of one file into another.
Definition: file.c:263
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:1332
char * C_Signature
Config: File containing a signature to append to all mail.
Definition: send.c:125

+ 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 156 of file send.c.

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

204 {
205  struct Address *top = NULL, *ptr = NULL;
206 
207  for (; t || c; t = c, c = NULL)
208  {
209  for (; t; t = t->next)
210  {
211  if (mutt_is_mail_list(t) && !t->group)
212  {
213  if (top)
214  {
215  ptr->next = mutt_addr_copy(t);
216  ptr = ptr->next;
217  }
218  else
219  {
220  top = mutt_addr_copy(t);
221  ptr = top;
222  }
223  }
224  }
225  }
226  return top;
227 }
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:99
struct Address * mutt_addr_copy(struct Address *addr)
Copy the real address.
Definition: address.c:712
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 236 of file send.c.

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

+ 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 268 of file send.c.

269 {
270  char buf[8192];
271 
272 #ifdef USE_NNTP
273  if (OptNewsSend)
274  {
275  if (en->newsgroups)
276  mutt_str_strfcpy(buf, en->newsgroups, sizeof(buf));
277  else
278  buf[0] = '\0';
279  if (mutt_get_field("Newsgroups: ", buf, sizeof(buf), 0) != 0)
280  return -1;
281  FREE(&en->newsgroups);
282  en->newsgroups = mutt_str_strdup(buf);
283 
284  if (en->followup_to)
285  mutt_str_strfcpy(buf, en->followup_to, sizeof(buf));
286  else
287  buf[0] = '\0';
288  if (C_AskFollowUp && (mutt_get_field("Followup-To: ", buf, sizeof(buf), 0) != 0))
289  {
290  return -1;
291  }
292  FREE(&en->followup_to);
293  en->followup_to = mutt_str_strdup(buf);
294 
295  if (en->x_comment_to)
296  mutt_str_strfcpy(buf, en->x_comment_to, sizeof(buf));
297  else
298  buf[0] = '\0';
299  if (C_XCommentTo && C_AskXCommentTo &&
300  (mutt_get_field("X-Comment-To: ", buf, sizeof(buf), 0) != 0))
301  {
302  return -1;
303  }
304  FREE(&en->x_comment_to);
305  en->x_comment_to = mutt_str_strdup(buf);
306  }
307  else
308 #endif
309  {
310  if ((edit_address(&en->to, _("To: ")) == -1) || !en->to)
311  return -1;
312  if (C_Askcc && (edit_address(&en->cc, _("Cc: ")) == -1))
313  return -1;
314  if (C_Askbcc && (edit_address(&en->bcc, _("Bcc: ")) == -1))
315  return -1;
317  (edit_address(&en->from, "From: ") == -1))
318  {
319  return -1;
320  }
321  }
322 
323  if (en->subject)
324  {
325  if (C_FastReply)
326  return 0;
327  else
328  mutt_str_strfcpy(buf, en->subject, sizeof(buf));
329  }
330  else
331  {
332  const char *p = NULL;
333 
334  buf[0] = '\0';
335  struct ListNode *uh = NULL;
336  STAILQ_FOREACH(uh, &UserHeader, entries)
337  {
338  size_t plen = mutt_str_startswith(uh->data, "subject:", CASE_IGNORE);
339  if (plen)
340  {
341  p = mutt_str_skip_email_wsp(uh->data + plen);
342  mutt_str_strfcpy(buf, p, sizeof(buf));
343  }
344  }
345  }
346 
347  if ((mutt_get_field(_("Subject: "), buf, sizeof(buf), 0) != 0) ||
348  (!buf[0] &&
349  (query_quadoption(C_AbortNosubject, _("No subject, abort?")) != MUTT_NO)))
350  {
351  mutt_message(_("No subject, aborting"));
352  return -1;
353  }
354  mutt_str_replace(&en->subject, buf);
355 
356  return 0;
357 }
enum QuadOption query_quadoption(enum QuadOption opt, const char *prompt)
Ask the user a quad-question.
Definition: init.c:3369
#define mutt_message(...)
Definition: logging.h:87
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:77
unsigned char C_AbortNosubject
Config: Abort creating the email if subject is missing.
Definition: send.c:86
#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:99
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:236
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:89
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:741
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:767
#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:459
bool C_AskFollowUp
Config: (nntp) Ask the user for follow-up groups before editing.
Definition: send.c:88
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:165
#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:289
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:383
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:204
WHERE bool C_Askcc
Config: Ask the user for the carbon-copy recipients.
Definition: globals.h:205
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:121

+ 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 367 of file send.c.

368 {
369  SKIPWS(s);
370  return mutt_str_strdup(s);
371 }
#define SKIPWS(ch)
Definition: string2.h:46
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:383

+ 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 378 of file send.c.

379 {
380  struct ListNode *uh = NULL;
381  STAILQ_FOREACH(uh, &UserHeader, entries)
382  {
383  size_t plen;
384  if ((plen = mutt_str_startswith(uh->data, "to:", CASE_IGNORE)))
385  env->to = mutt_addr_parse_list(env->to, uh->data + plen);
386  else if ((plen = mutt_str_startswith(uh->data, "cc:", CASE_IGNORE)))
387  env->cc = mutt_addr_parse_list(env->cc, uh->data + plen);
388  else if ((plen = mutt_str_startswith(uh->data, "bcc:", CASE_IGNORE)))
389  env->bcc = mutt_addr_parse_list(env->bcc, uh->data + plen);
390 #ifdef USE_NNTP
391  else if ((plen = mutt_str_startswith(uh->data, "newsgroups:", CASE_IGNORE)))
392  env->newsgroups = nntp_get_header(uh->data + plen);
393  else if ((plen = mutt_str_startswith(uh->data, "followup-to:", CASE_IGNORE)))
394  env->followup_to = nntp_get_header(uh->data + plen);
395  else if ((plen = mutt_str_startswith(uh->data, "x-comment-to:", CASE_IGNORE)))
396  env->x_comment_to = nntp_get_header(uh->data + plen);
397 #endif
398  }
399 }
struct Address * to
Definition: envelope.h:42
static char * nntp_get_header(const char *s)
Get the trimmed header.
Definition: send.c:367
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
struct Address * mutt_addr_parse_list(struct Address *top, const char *s)
Parse a list of email addresses.
Definition: address.c:465
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:165
char * data
Definition: list.h:35
char * newsgroups
Definition: envelope.h:59
char * followup_to
Definition: envelope.h:61
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 405 of file send.c.

406 {
407  struct ListNode *uh = NULL;
408  STAILQ_FOREACH(uh, &UserHeader, entries)
409  {
410  size_t plen;
411  if ((plen = mutt_str_startswith(uh->data, "from:", CASE_IGNORE)))
412  {
413  /* User has specified a default From: address. Remove default address */
414  mutt_addr_free(&env->from);
415  env->from = mutt_addr_parse_list(env->from, uh->data + plen);
416  }
417  else if ((plen = mutt_str_startswith(uh->data, "reply-to:", CASE_IGNORE)))
418  {
419  mutt_addr_free(&env->reply_to);
420  env->reply_to = mutt_addr_parse_list(env->reply_to, uh->data + plen);
421  }
422  else if ((plen = mutt_str_startswith(uh->data, "message-id:", CASE_IGNORE)))
423  {
424  char *tmp = mutt_extract_message_id(uh->data + plen, NULL);
425  if (mutt_addr_valid_msgid(tmp))
426  {
427  FREE(&env->message_id);
428  env->message_id = tmp;
429  }
430  else
431  FREE(&tmp);
432  }
433  else if (!mutt_str_startswith(uh->data, "to:", CASE_IGNORE) &&
434  !mutt_str_startswith(uh->data, "cc:", CASE_IGNORE) &&
435  !mutt_str_startswith(uh->data, "bcc:", CASE_IGNORE) &&
436 #ifdef USE_NNTP
437  !mutt_str_startswith(uh->data, "newsgroups:", CASE_IGNORE) &&
438  !mutt_str_startswith(uh->data, "followup-to:", CASE_IGNORE) &&
439  !mutt_str_startswith(uh->data, "x-comment-to:", CASE_IGNORE) &&
440 #endif
441  !mutt_str_startswith(uh->data, "supersedes:", CASE_IGNORE) &&
442  !mutt_str_startswith(uh->data, "subject:", CASE_IGNORE) &&
443  !mutt_str_startswith(uh->data, "return-path:", CASE_IGNORE))
444  {
446  }
447  }
448 }
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:58
struct Address * mutt_addr_parse_list(struct Address *top, const char *s)
Parse a list of email addresses.
Definition: address.c:465
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:165
char * data
Definition: list.h:35
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:383
#define FREE(x)
Definition: memory.h:40
void mutt_addr_free(struct Address **p)
Free a list of Addresses.
Definition: address.c:446
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:334
bool mutt_addr_valid_msgid(const char *msgid)
Is this a valid Message ID?
Definition: address.c:790

+ 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 456 of file send.c.

457 {
458  if (!C_ForwardAttributionIntro || !fp)
459  return;
460 
461  char buf[1024];
462  setlocale(LC_TIME, NONULL(C_AttributionLocale));
463  mutt_make_string(buf, sizeof(buf), C_ForwardAttributionIntro, NULL, m, e);
464  setlocale(LC_TIME, "");
465  fputs(buf, fp);
466  fputs("\n\n", fp);
467 }
#define NONULL(x)
Definition: string2.h:36
char * C_ForwardAttributionIntro
Config: Prefix message for forwarded messages.
Definition: send.c:103
WHERE char * C_AttributionLocale
Config: Locale for dates in the attribution message.
Definition: globals.h:105
#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 475 of file send.c.

476 {
477  if (!C_ForwardAttributionTrailer || !fp)
478  return;
479 
480  char buf[1024];
481  setlocale(LC_TIME, NONULL(C_AttributionLocale));
482  mutt_make_string(buf, sizeof(buf), C_ForwardAttributionTrailer, NULL, m, e);
483  setlocale(LC_TIME, "");
484  fputc('\n', fp);
485  fputs(buf, fp);
486  fputc('\n', fp);
487 }
#define NONULL(x)
Definition: string2.h:36
WHERE char * C_AttributionLocale
Config: Locale for dates in the attribution message.
Definition: globals.h:105
char * C_ForwardAttributionTrailer
Config: Suffix message for forwarded messages.
Definition: send.c:104
#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 497 of file send.c.

498 {
499  CopyHeaderFlags chflags = CH_DECODE;
501 
504 
505  if ((WithCrypto != 0) && (e->security & SEC_ENCRYPT) && C_ForwardDecode)
506  {
507  /* make sure we have the user's passphrase before proceeding... */
509  return -1;
510  }
511 
512  mutt_forward_intro(m, e, fp_out);
513 
514  if (C_ForwardDecode)
515  {
516  cmflags |= MUTT_CM_DECODE | MUTT_CM_CHARCONV;
517  if (C_Weed)
518  {
519  chflags |= CH_WEED | CH_REORDER;
520  cmflags |= MUTT_CM_WEED;
521  }
522  }
523  if (C_ForwardQuote)
524  cmflags |= MUTT_CM_PREFIX;
525 
526  /* wrapping headers for forwarding is considered a display
527  * rather than send action */
528  chflags |= CH_DISPLAY;
529 
530  mutt_copy_message_ctx(fp_out, m, e, cmflags, chflags);
531  mutt_forward_trailer(m, e, fp_out);
532  return 0;
533 }
WHERE bool C_ForwardDecode
Config: Decode the message when forwarding it.
Definition: globals.h:218
void mutt_forward_intro(struct Mailbox *m, struct Email *e, FILE *fp)
Add the "start of forwarded message" text.
Definition: send.c:456
#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
int crypt_valid_passphrase(SecurityFlags flags)
Check that we have a usable passphrase, ask if not.
Definition: crypt.c:144
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:799
#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:475
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:219
void mutt_message_hook(struct Mailbox *m, struct Email *e, HookFlags type)
Perform a message hook.
Definition: hook.c:441
#define WithCrypto
Definition: ncrypt.h:155
bool C_Weed
Config: Filter headers when displaying/forwarding/printing/replying.
Definition: email_globals.c:39

+ 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 541 of file send.c.

542 {
543  if (!C_Attribution || !fp_out)
544  return;
545 
546  char buf[1024];
547  setlocale(LC_TIME, NONULL(C_AttributionLocale));
548  mutt_make_string(buf, sizeof(buf), C_Attribution, NULL, m, e);
549  setlocale(LC_TIME, "");
550  fputs(buf, fp_out);
551  fputc('\n', fp_out);
552 }
#define NONULL(x)
Definition: string2.h:36
WHERE char * C_AttributionLocale
Config: Locale for dates in the attribution message.
Definition: globals.h:105
#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:104

+ 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 560 of file send.c.

561 {
562  if (!C_PostIndentString || !fp_out)
563  return;
564 
565  char buf[256];
566  mutt_make_string(buf, sizeof(buf), C_PostIndentString, NULL, m, e);
567  fputs(buf, fp_out);
568  fputc('\n', fp_out);
569 }
#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:115

+ 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 579 of file send.c.

580 {
581  CopyMessageFlags cmflags =
583  CopyHeaderFlags chflags = CH_DECODE;
584 
585  if ((WithCrypto != 0) && (e->security & SEC_ENCRYPT))
586  {
587  /* make sure we have the user's passphrase before proceeding... */
589  return -1;
590  }
591 
594 
595  mutt_make_attribution(m, e, fp_out);
596 
597  if (!C_Header)
598  cmflags |= MUTT_CM_NOHEADER;
599  if (C_Weed)
600  {
601  chflags |= CH_WEED | CH_REORDER;
602  cmflags |= MUTT_CM_WEED;
603  }
604 
605  mutt_copy_message_ctx(fp_out, m, e, cmflags, chflags);
606 
607  mutt_make_post_indent(m, e, fp_out);
608 
609  return 0;
610 }
#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:560
#define SEC_ENCRYPT
Email is encrypted.
Definition: ncrypt.h:120
#define MUTT_CM_REPLYING
Replying the message.
Definition: copy.h:43
int crypt_valid_passphrase(SecurityFlags flags)
Check that we have a usable passphrase, ask if not.
Definition: crypt.c:144
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:799
#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:225
#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:441
#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:39
void mutt_make_attribution(struct Mailbox *m, struct Email *e, FILE *fp_out)
Add "on DATE, PERSON wrote" header.
Definition: send.c:541

+ 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 621 of file send.c.

622 {
623  char prompt[256];
624 
625  if (flags && env->mail_followup_to && (hmfupto == MUTT_YES))
626  {
627  mutt_addr_append(to, env->mail_followup_to, true);
628  return 0;
629  }
630 
631  /* Exit now if we're setting up the default Cc list for list-reply
632  * (only set if Mail-Followup-To is present and honoured). */
633  if (flags & SEND_LIST_REPLY)
634  return 0;
635 
636  if (!C_ReplySelf && mutt_addr_is_user(env->from))
637  {
638  /* mail is from the user, assume replying to recipients */
639  mutt_addr_append(to, env->to, true);
640  }
641  else if (env->reply_to)
642  {
643  if ((mutt_addr_cmp(env->from, env->reply_to) && !env->reply_to->next &&
644  !env->reply_to->personal) ||
646  (mutt_addr_search(env->reply_to, env->to) ||
647  mutt_addr_search(env->reply_to, env->cc))))
648  {
649  /* If the Reply-To: address is a mailing list, assume that it was
650  * put there by the mailing list, and use the From: address
651  *
652  * We also take the from header if our correspondent has a reply-to
653  * header which is identical to the electronic mail address given
654  * in his From header, and the reply-to has no display-name. */
655  mutt_addr_append(to, env->from, false);
656  }
657  else if (!(mutt_addr_cmp(env->from, env->reply_to) && !env->reply_to->next) &&
658  (C_ReplyTo != MUTT_YES))
659  {
660  /* There are quite a few mailing lists which set the Reply-To:
661  * header field to the list address, which makes it quite impossible
662  * to send a message to only the sender of the message. This
663  * provides a way to do that. */
664  /* L10N: Asks whether the user respects the reply-to header.
665  If she says no, neomutt will reply to the from header's address instead. */
666  snprintf(prompt, sizeof(prompt), _("Reply to %s%s?"),
667  env->reply_to->mailbox, env->reply_to->next ? ",..." : "");
668  switch (query_quadoption(C_ReplyTo, prompt))
669  {
670  case MUTT_YES:
671  mutt_addr_append(to, env->reply_to, false);
672  break;
673 
674  case MUTT_NO:
675  mutt_addr_append(to, env->from, false);
676  break;
677 
678  default:
679  return -1; /* abort */
680  }
681  }
682  else
683  mutt_addr_append(to, env->reply_to, false);
684  }
685  else
686  mutt_addr_append(to, env->from, false);
687 
688  return 0;
689 }
bool C_ReplySelf
Config: Really reply to yourself, when replying to your own email.
Definition: send.c:119
enum QuadOption query_quadoption(enum QuadOption opt, const char *prompt)
Ask the user a quad-question.
Definition: init.c:3369
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:110
struct Address * mutt_addr_append(struct Address **a, struct Address *b, bool prune)
Append one list of addresses onto another.
Definition: address.c:763
bool mutt_is_mail_list(struct Address *addr)
Is this the email address of a mailing list?
Definition: hdrline.c:99
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:120
#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_cmp(struct Address *a, struct Address *b)
Compare two e-mail addresses.
Definition: address.c:883
char * personal
real name of address
Definition: address.h:34
bool mutt_addr_search(struct Address *a, struct Address *lst)
Search for an e-mail address in a list.
Definition: address.c:898
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:678
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 699 of file send.c.

700 {
701  struct Address *tmp = NULL;
702  enum QuadOption hmfupto = MUTT_ABORT;
703 
705  {
706  char prompt[256];
707  snprintf(prompt, sizeof(prompt), _("Follow-up to %s%s?"),
708  in->mail_followup_to->mailbox, in->mail_followup_to->next ? ",..." : "");
709 
710  hmfupto = query_quadoption(C_HonorFollowupTo, prompt);
711  if (hmfupto == MUTT_ABORT)
712  return -1;
713  }
714 
715  if (flags & SEND_LIST_REPLY)
716  {
717  tmp = find_mailing_lists(in->to, in->cc);
718  mutt_addr_append(&out->to, tmp, false);
719  mutt_addr_free(&tmp);
720 
721  if (in->mail_followup_to && (hmfupto == MUTT_YES) &&
722  (default_to(&out->cc, in, flags & SEND_LIST_REPLY, (hmfupto == MUTT_YES)) == MUTT_ABORT))
723  {
724  return -1; /* abort */
725  }
726  }
727  else if (flags & SEND_TO_SENDER)
728  {
729  mutt_addr_append(&out->to, in->from, false);
730  }
731  else
732  {
733  if (default_to(&out->to, in, flags & (SEND_GROUP_REPLY | SEND_GROUP_CHAT_REPLY),
734  (hmfupto == MUTT_YES)) == -1)
735  return -1; /* abort */
736 
737  if ((flags & (SEND_GROUP_REPLY | SEND_GROUP_CHAT_REPLY)) &&
738  (!in->mail_followup_to || (hmfupto != MUTT_YES)))
739  {
740  /* if(!mutt_addr_is_user(in->to)) */
741  if (flags & SEND_GROUP_REPLY)
742  mutt_addr_append(&out->cc, in->to, true);
743  else
744  mutt_addr_append(&out->to, in->to, true);
745  mutt_addr_append(&out->cc, in->cc, true);
746  }
747  }
748  return 0;
749 }
#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:621
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:3369
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
struct Address * mutt_addr_append(struct Address **a, struct Address *b, bool prune)
Append one list of addresses onto another.
Definition: address.c:763
unsigned char C_HonorFollowupTo
Config: Honour the &#39;Mail-Followup-To&#39; header when group replying.
Definition: send.c:109
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
#define SEND_GROUP_CHAT_REPLY
Reply to all recipients preserving To/Cc.
Definition: send.h:99
void mutt_addr_free(struct Address **p)
Free a list of Addresses.
Definition: address.c:446
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:203
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 756 of file send.c.

757 {
758  struct ListNode *np = NULL;
759 
760  struct ListHead *src = !STAILQ_EMPTY(&env->references) ? &env->references : &env->in_reply_to;
761  STAILQ_FOREACH(np, src, entries)
762  {
764  }
765 }
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:58
#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:383
#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 772 of file send.c.

773 {
774  if (env->message_id)
775  {
777  }
778 }
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:383

+ 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 784 of file send.c.

785 {
786  if (!C_Metoo)
787  {
788  /* the order is important here. do the CC: first so that if the
789  * the user is the only recipient, it ends up on the TO: field */
790  env->cc = remove_user(env->cc, (env->to == NULL));
791  env->to = remove_user(env->to, (env->cc == NULL) || C_ReplySelf);
792  }
793 
794  /* the CC field can get cluttered, especially with lists */
795  env->to = mutt_addrlist_dedupe(env->to);
796  env->cc = mutt_addrlist_dedupe(env->cc);
797  env->cc = mutt_addr_remove_xrefs(env->to, env->cc);
798 
799  if (env->cc && !env->to)
800  {
801  env->to = env->cc;
802  env->cc = NULL;
803  }
804 }
static struct Address * remove_user(struct Address *a, bool leave_only)
Remove any address which matches the current user.
Definition: send.c:156
bool C_ReplySelf
Config: Really reply to yourself, when replying to your own email.
Definition: send.c:119
struct Address * to
Definition: envelope.h:42
struct Address * mutt_addrlist_dedupe(struct Address *addr)
Remove duplicate addresses.
Definition: address.c:1281
struct Address * mutt_addr_remove_xrefs(struct Address *a, struct Address *b)
Remove cross-references.
Definition: address.c:1328
bool C_Metoo
Config: Remove the user&#39;s address from the list of recipients.
Definition: send.c:112
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 812 of file send.c.

813 {
814  if (!env)
815  return;
816 
817  char buf[256];
818 
819  /* set the default subject for the message. */
820  mutt_make_string(buf, sizeof(buf), NONULL(C_ForwardFormat), NULL, m, cur);
821  mutt_str_replace(&env->subject, buf);
822 }
#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:106
void mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition: string.c:459
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 829 of file send.c.

830 {
831  if (!env || !curenv)
832  return;
833 
834  /* This takes precedence over a subject that might have
835  * been taken from a List-Post header. Is that correct? */
836  if (curenv->real_subj)
837  {
838  FREE(&env->subject);
839  env->subject = mutt_mem_malloc(mutt_str_strlen(curenv->real_subj) + 5);
840  sprintf(env->subject, "Re: %s", curenv->real_subj);
841  }
842  else if (!env->subject)
844 }
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:662
void * mutt_mem_malloc(size_t size)
Allocate memory on the heap.
Definition: memory.c:99
char * subject
Definition: envelope.h:50
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:383
#define FREE(x)
Definition: memory.h:40
char * C_EmptySubject
Config: Subject to use when replying to an email with none.
Definition: send.c:98

+ 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 851 of file send.c.

852 {
853  add_references(&env->references, curenv);
854  add_message_id(&env->references, curenv);
855  add_message_id(&env->in_reply_to, curenv);
856 
857 #ifdef USE_NNTP
858  if (OptNewsSend && C_XCommentTo && curenv->from)
860 #endif
861 }
static void add_references(struct ListHead *head, struct Envelope *env)
Add the email&#39;s references to a list.
Definition: send.c:756
static void add_message_id(struct ListHead *head, struct Envelope *env)
Add the email&#39;s message ID to a list.
Definition: send.c:772
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:153
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:383
WHERE bool C_XCommentTo
Config: (nntp) Add &#39;X-Comment-To&#39; header that contains article author.
Definition: globals.h:289
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 868 of file send.c.

869 {
870  if (!el || !env || STAILQ_EMPTY(el))
871  return;
872 
873  struct EmailNode *en = STAILQ_FIRST(el);
874  bool single = !STAILQ_NEXT(en, entries);
875 
876  if (!single)
877  {
878  STAILQ_FOREACH(en, el, entries)
879  {
881  }
882  }
883  else
885 
886  /* if there's more than entry in In-Reply-To (i.e. message has multiple
887  * parents), don't generate a References: header as it's discouraged by
888  * RFC2822, sect. 3.6.4 */
889  if (!single && !STAILQ_EMPTY(&env->in_reply_to) &&
890  STAILQ_NEXT(STAILQ_FIRST(&env->in_reply_to), entries))
891  {
892  mutt_list_free(&env->references);
893  }
894 }
void mutt_list_free(struct ListHead *h)
Free a List AND its strings.
Definition: list.c:105
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:851

+ 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 905 of file send.c.

907 {
908  if (!el || STAILQ_EMPTY(el))
909  return -1;
910 
911  struct EmailNode *en = STAILQ_FIRST(el);
912  bool single = !STAILQ_NEXT(en, entries);
913 
914  struct Envelope *curenv = en->email->env;
915  if (!curenv)
916  return -1;
917 
918  if (flags & (SEND_REPLY | SEND_TO_SENDER))
919  {
920 #ifdef USE_NNTP
921  if ((flags & SEND_NEWS))
922  {
923  /* in case followup set Newsgroups: with Followup-To: if it present */
924  if (!env->newsgroups &&
925  (mutt_str_strcasecmp(curenv->followup_to, "poster") != 0))
926  {
927  env->newsgroups = mutt_str_strdup(curenv->followup_to);
928  }
929  }
930  else
931 #endif
932  if (!single)
933  {
934  STAILQ_FOREACH(en, el, entries)
935  {
936  if (mutt_fetch_recips(env, en->email->env, flags) == -1)
937  return -1;
938  }
939  }
940  else if (mutt_fetch_recips(env, curenv, flags) == -1)
941  return -1;
942 
943  if ((flags & SEND_LIST_REPLY) && !env->to)
944  {
945  mutt_error(_("No mailing lists found"));
946  return -1;
947  }
948 
949  if (flags & SEND_REPLY)
950  {
951  mutt_make_misc_reply_headers(env, curenv);
952  make_reference_headers(el, env);
953  }
954  }
955  else if (flags & SEND_FORWARD)
956  {
957  mutt_make_forward_subject(env, m, en->email);
959  make_reference_headers(el, env);
960  }
961 
962  return 0;
963 }
static void make_reference_headers(struct EmailList *el, struct Envelope *env)
Generate reference headers for an email.
Definition: send.c:868
#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:699
#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:829
void mutt_make_forward_subject(struct Envelope *env, struct Mailbox *m, struct Email *cur)
Create a subject for a forwarded email.
Definition: send.c:812
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:383
struct Email * email
Definition: email.h:123
#define mutt_error(...)
Definition: logging.h:88
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:624
#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:107
#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 975 of file send.c.

977 {
978  struct Body *tmp = NULL;
979  struct EmailNode *en = NULL;
980  bool single = true;
981 
982  if (el)
983  en = STAILQ_FIRST(el);
984  if (en)
985  single = !STAILQ_NEXT(en, entries);
986 
987  /* An EmailList is required for replying and forwarding */
988  if (!el && (flags & (SEND_REPLY | SEND_FORWARD)))
989  return -1;
990 
991  if (flags & SEND_REPLY)
992  {
993  enum QuadOption ans =
994  query_quadoption(C_Include, _("Include message in reply?"));
995  if (ans == MUTT_ABORT)
996  return -1;
997 
998  if (ans == MUTT_YES)
999  {
1000  mutt_message(_("Including quoted message..."));
1001  if (!single)
1002  {
1003  STAILQ_FOREACH(en, el, entries)
1004  {
1005  if (include_reply(m, en->email, fp_tmp) == -1)
1006  {
1007  mutt_error(_("Could not include all requested messages"));
1008  return -1;
1009  }
1010  fputc('\n', fp_tmp);
1011  }
1012  }
1013  else
1014  include_reply(m, en->email, fp_tmp);
1015  }
1016  }
1017  else if (flags & SEND_FORWARD)
1018  {
1019  enum QuadOption ans =
1020  query_quadoption(C_MimeForward, _("Forward as attachment?"));
1021  if (ans == MUTT_YES)
1022  {
1023  struct Body *last = msg->content;
1024 
1025  mutt_message(_("Preparing forwarded message..."));
1026 
1027  while (last && last->next)
1028  last = last->next;
1029 
1030  if (single)
1031  {
1032  tmp = mutt_make_message_attach(m, en->email, false);
1033  if (last)
1034  last->next = tmp;
1035  else
1036  msg->content = tmp;
1037  }
1038  else
1039  {
1040  STAILQ_FOREACH(en, el, entries)
1041  {
1042  tmp = mutt_make_message_attach(m, en->email, false);
1043  if (last)
1044  {
1045  last->next = tmp;
1046  last = tmp;
1047  }
1048  else
1049  {
1050  last = tmp;
1051  msg->content = tmp;
1052  }
1053  }
1054  }
1055  }
1056  else if (ans != MUTT_ABORT)
1057  {
1058  if (single)
1059  include_forward(m, en->email, fp_tmp);
1060  else
1061  {
1062  STAILQ_FOREACH(en, el, entries)
1063  {
1064  include_forward(m, en->email, fp_tmp);
1065  }
1066  }
1067  }
1068  else
1069  return -1;
1070  }
1071  /* if (WithCrypto && (flags & SEND_KEY)) */
1072  else if (((WithCrypto & APPLICATION_PGP) != 0) && (flags & SEND_KEY))
1073  {
1074  struct Body *b = NULL;
1075 
1076  if (((WithCrypto & APPLICATION_PGP) != 0) && !(b = crypt_pgp_make_key_attachment()))
1077  {
1078  return -1;
1079  }
1080 
1081  b->next = msg->content;
1082  msg->content = b;
1083  }
1084 
1085  mutt_clear_error();
1086 
1087  return 0;
1088 }
struct Body * mutt_make_message_attach(struct Mailbox *m, struct Email *e, bool attach_msg)
Create a message attachment.
Definition: sendlib.c:1459
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:3369
#define mutt_message(...)
Definition: logging.h:87
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
#define _(a)
Definition: message.h:28
struct Body * next
next attachment in the list
Definition: body.h:58
unsigned char C_Include
Config: Include a copy of the email that&#39;s being replied to.
Definition: send.c:111
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:191
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_forward(struct Mailbox *m, struct Email *e, FILE *fp_out)
Write out a forwarded message.
Definition: send.c:497
static int include_reply(struct Mailbox *m, struct Email *e, FILE *fp_out)
Generate the reply text for an email.
Definition: send.c:579
#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:88
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 1094 of file send.c.

1095 {
1096  struct Address *t = NULL;
1097  struct Address *from = NULL;
1098 
1099  /* Only generate the Mail-Followup-To if the user has requested it, and
1100  * it hasn't already been set */
1101 
1102  if (!C_FollowupTo)
1103  return;
1104 #ifdef USE_NNTP
1105  if (OptNewsSend)
1106  {
1107  if (!env->followup_to && env->newsgroups && (strrchr(env->newsgroups, ',')))
1108  env->followup_to = mutt_str_strdup(env->newsgroups);
1109  return;
1110  }
1111 #endif
1112 
1113  if (!env->mail_followup_to)
1114  {
1115  if (mutt_is_list_cc(0, env->to, env->cc))
1116  {
1117  /* this message goes to known mailing lists, so create a proper
1118  * mail-followup-to header */
1119 
1120  t = mutt_addr_append(&env->mail_followup_to, env->to, false);
1121  mutt_addr_append(&t, env->cc, true);
1122  }
1123 
1124  /* remove ourselves from the mail-followup-to header */
1125  env->mail_followup_to = remove_user(env->mail_followup_to, false);
1126 
1127  /* If we are not subscribed to any of the lists in question, re-add
1128  * ourselves to the mail-followup-to header. The mail-followup-to header
1129  * generated is a no-op with group-reply, but makes sure list-reply has the
1130  * desired effect. */
1131 
1132  if (env->mail_followup_to && !mutt_is_list_recipient(false, env->to, env->cc))
1133  {
1134  if (env->reply_to)
1135  from = mutt_addr_copy_list(env->reply_to, false);
1136  else if (env->from)
1137  from = mutt_addr_copy_list(env->from, false);
1138  else
1139  from = mutt_default_from();
1140 
1141  if (from)
1142  {
1143  /* Normally, this loop will not even be entered. */
1144  for (t = from; t && t->next; t = t->next)
1145  ;
1146 
1147  t->next = env->mail_followup_to; /* t cannot be NULL at this point. */
1148  env->mail_followup_to = from;
1149  }
1150  }
1151 
1153  }
1154 }
static struct Address * remove_user(struct Address *a, bool leave_only)
Remove any address which matches the current user.
Definition: send.c:156
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:1708
struct Address * mutt_addrlist_dedupe(struct Address *addr)
Remove duplicate addresses.
Definition: address.c:1281
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:102
struct Address * mutt_addr_append(struct Address **a, struct Address *b, bool prune)
Append one list of addresses onto another.
Definition: address.c:763
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:1200
int mutt_is_list_cc(int alladdr, struct Address *a1, struct Address *a2)
Matches known mailing lists.
Definition: pattern.c:1730
char * newsgroups
Definition: envelope.h:59
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:383
char * followup_to
Definition: envelope.h:61
WHERE bool OptNewsSend
(pseudo) used to change behavior when posting
Definition: options.h:43
struct Address * mutt_addr_copy_list(struct Address *addr, bool prune)
Copy a list of addresses.
Definition: address.c:730
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 1166 of file send.c.

1167 {
1168  struct Address *tmp = NULL;
1169 
1170  for (tmp = env->to; tmp; tmp = tmp->next)
1171  {
1172  if (mutt_addr_is_user(tmp))
1173  break;
1174  }
1175  if (!tmp)
1176  {
1177  for (tmp = env->cc; tmp; tmp = tmp->next)
1178  {
1179  if (mutt_addr_is_user(tmp))
1180  break;
1181  }
1182  }
1183  if (!tmp && mutt_addr_is_user(env->from))
1184  tmp = env->from;
1185  if (tmp)
1186  {
1187  tmp = mutt_addr_copy(tmp);
1188  /* when $reverse_realname is not set, clear the personal name so that it
1189  * may be set via a reply- or send-hook. */
1190  if (!C_ReverseRealname)
1191  FREE(&tmp->personal);
1192  }
1193  return tmp;
1194 }
struct Address * to
Definition: envelope.h:42
An email address.
Definition: address.h:32
struct Address * mutt_addr_copy(struct Address *addr)
Copy the real address.
Definition: address.c:712
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:123
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:678
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 1200 of file send.c.

1201 {
1202  struct Address *addr = NULL;
1203 
1204  /* Note: We let $from override $realname here.
1205  * Is this the right thing to do?
1206  */
1207 
1208  if (C_From)
1209  addr = mutt_addr_copy(C_From);
1210  else
1211  {
1212  addr = mutt_addr_new();
1213  if (C_UseDomain)
1214  {
1215  const char *fqdn = mutt_fqdn(true);
1216  addr->mailbox =
1218  sprintf(addr->mailbox, "%s@%s", NONULL(Username), NONULL(fqdn));
1219  }
1220  else
1221  {
1222  addr->mailbox = mutt_str_strdup(Username);
1223  }
1224  }
1225 
1226  return addr;
1227 }
WHERE char * Username
User&#39;s login name.
Definition: globals.h:51
#define NONULL(x)
Definition: string2.h:36
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:662
WHERE bool C_UseDomain
Config: Qualify local addresses using this domain.
Definition: globals.h:265
struct Address * mutt_addr_copy(struct Address *addr)
Copy the real address.
Definition: address.c:712
WHERE struct Address * C_From
Config: Default &#39;From&#39; address to use, if isn&#39;t otherwise set.
Definition: globals.h:101
void * mutt_mem_malloc(size_t size)
Allocate memory on the heap.
Definition: memory.c:99
const char * mutt_fqdn(bool may_hide_host)
Get the Fully-Qualified Domain Name.
Definition: sendlib.c:2432
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:383
struct Address * mutt_addr_new(void)
Create a new Address.
Definition: address.c:401

+ 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 1235 of file send.c.

1236 {
1237  char tempfile[PATH_MAX];
1238  int i;
1239 #ifdef USE_SMTP
1240  short old_write_bcc;
1241 #endif
1242 
1243  /* Write out the message in MIME form. */
1244  mutt_mktemp(tempfile, sizeof(tempfile));
1245  FILE *fp_tmp = mutt_file_fopen(tempfile, "w");
1246  if (!fp_tmp)
1247  return -1;
1248 
1249 #ifdef USE_SMTP
1250  old_write_bcc = C_WriteBcc;
1251  if (C_SmtpUrl)
1252  C_WriteBcc = false;
1253 #endif
1254 #ifdef MIXMASTER
1255  mutt_rfc822_write_header(fp_tmp, msg->env, msg->content,
1256  MUTT_WRITE_HEADER_NORMAL, !STAILQ_EMPTY(&msg->chain),
1258 #endif
1259 #ifndef MIXMASTER
1262 #endif
1263 #ifdef USE_SMTP
1264  if (old_write_bcc)
1265  C_WriteBcc = true;
1266 #endif
1267 
1268  fputc('\n', fp_tmp); /* tie off the header. */
1269 
1270  if ((mutt_write_mime_body(msg->content, fp_tmp) == -1))
1271  {
1272  mutt_file_fclose(&fp_tmp);
1273  unlink(tempfile);
1274  return -1;
1275  }
1276 
1277  if (fclose(fp_tmp) != 0)
1278  {
1279  mutt_perror(tempfile);
1280  unlink(tempfile);
1281  return -1;
1282  }
1283 
1284 #ifdef MIXMASTER
1285  if (!STAILQ_EMPTY(&msg->chain))
1286  return mix_send_message(&msg->chain, tempfile);
1287 #endif
1288 
1289 #ifdef USE_SMTP
1290 #ifdef USE_NNTP
1291  if (!OptNewsSend)
1292 #endif
1293  if (C_SmtpUrl)
1294  {
1295  return mutt_smtp_send(msg->env->from, msg->env->to, msg->env->cc, msg->env->bcc,
1296  tempfile, (msg->content->encoding == ENC_8BIT));
1297  }
1298 #endif /* USE_SMTP */
1299 
1300  i = mutt_invoke_sendmail(msg->env->from, msg->env->to, msg->env->cc, msg->env->bcc,
1301  tempfile, (msg->content->encoding == ENC_8BIT));
1302  return i;
1303 }
WHERE char * C_SmtpUrl
Config: (smtp) Url of the SMTP server.
Definition: globals.h:148
WHERE bool C_WriteBcc
Config: Write out the &#39;Bcc&#39; field when preparing to send a mail.
Definition: globals.h:268
#define mutt_perror(...)
Definition: logging.h:89
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:149
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:1037
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:2708
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:2212
struct Envelope * env
envelope information
Definition: email.h:92
unsigned int encoding
content-transfer-encoding
Definition: body.h:71
struct Address * from
Definition: envelope.h:41
struct Address * bcc
Definition: envelope.h:44
#define mutt_mktemp(buf, buflen)
Definition: muttlib.h:72
#define PATH_MAX
Definition: mutt.h:48
int mutt_write_mime_body(struct Body *a, FILE *fp)
Write a MIME part.
Definition: sendlib.c:487
int mix_send_message(struct ListHead *chain, const char *tempfile)
Send an email via Mixmaster.
Definition: remailer.c:821
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:546
#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:741
WHERE bool OptNewsSend
(pseudo) used to change behavior when posting
Definition: options.h:43
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 1310 of file send.c.

1311 {
1312  for (struct Body *t = b; t; t = t->next)
1313  {
1314  if (t->description)
1315  {
1316  rfc2047_encode(&t->description, NULL, sizeof("Content-Description:"), C_SendCharset);
1317  }
1318  if (recurse && t->parts)
1319  mutt_encode_descriptions(t->parts, recurse);
1320  }
1321 }
struct Body * next
next attachment in the list
Definition: body.h:58
The body of an email.
Definition: body.h:34
char * C_SendCharset
Config: Character sets for outgoing mail ///< Config: List of character sets for outgoing messages...
Definition: email_globals.c:37
void rfc2047_encode(char **pd, const char *specials, int col, const char *charsets)
RFC-2047-encode a string.
Definition: rfc2047.c:626
void mutt_encode_descriptions(struct Body *b, bool recurse)
rfc2047 encode the content-descriptions
Definition: send.c:1310

+ 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 1327 of file send.c.

1328 {
1329  for (struct Body *t = b; t; t = t->next)
1330  {
1331  if (t->description)
1332  {
1333  rfc2047_decode(&t->description);
1334  }
1335  if (t->parts)
1336  decode_descriptions(t->parts);
1337  }
1338 }
void rfc2047_decode(char **pd)
Decode any RFC2047-encoded header fields.
Definition: rfc2047.c:650
struct Body * next
next attachment in the list
Definition: body.h:58
The body of an email.
Definition: body.h:34
static void decode_descriptions(struct Body *b)
rfc2047 decode them in case of an error
Definition: send.c:1327

+ 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 1344 of file send.c.

1345 {
1346  FILE *fp = mutt_file_fopen(data, "a+");
1347  if (!fp)
1348  return;
1349  if (fseek(fp, -1, SEEK_END) >= 0)
1350  {
1351  int c = fgetc(fp);
1352  if (c != '\n')
1353  fputc('\n', fp);
1354  }
1355  mutt_file_fclose(&fp);
1356 }
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:546

+ 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 1367 of file send.c.

1368 {
1369  struct Email *msg = mutt_email_new();
1370 
1371  if (mutt_prepare_template(fp, ctx->mailbox, msg, cur, true) < 0)
1372  {
1373  mutt_email_free(&msg);
1374  return -1;
1375  }
1376 
1377  if (WithCrypto)
1378  {
1379  /* mutt_prepare_template doesn't always flip on an application bit.
1380  * so fix that here */
1381  if (!(msg->security & (APPLICATION_SMIME | APPLICATION_PGP)))
1382  {
1383  if (((WithCrypto & APPLICATION_SMIME) != 0) && C_SmimeIsDefault)
1384  msg->security |= APPLICATION_SMIME;
1385  else if (WithCrypto & APPLICATION_PGP)
1386  msg->security |= APPLICATION_PGP;
1387  else
1388  msg->security |= APPLICATION_SMIME;
1389  }
1390 
1392  {
1393  msg->security |= SEC_OPPENCRYPT;
1395  }
1396  }
1397 
1398  struct EmailList el = STAILQ_HEAD_INITIALIZER(el);
1399  el_add_email(&el, cur);
1400  int rc = ci_send_message(SEND_RESEND, msg, NULL, ctx, &el);
1401  el_free(&el);
1402 
1403  return rc;
1404 }
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:322
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:1726
WHERE bool C_SmimeIsDefault
Config: Use SMIME rather than PGP by default.
Definition: globals.h:279
struct Mailbox * mailbox
Definition: context.h:51
int el_add_email(struct EmailList *el, struct Email *e)
Get a list of the selected Emails.
Definition: context.c:386
void crypt_opportunistic_encrypt(struct Email *msg)
Can all recipients be determined.
Definition: crypt.c:985
#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:275
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 1413 of file send.c.

1414 {
1415  if (!reply || !reply->env || !orig || !orig->env)
1416  return false;
1417  return mutt_list_find(&orig->env->references, reply->env->message_id) ||
1418  mutt_list_find(&orig->env->in_reply_to, reply->env->message_id);
1419 }
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:88
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 1431 of file send.c.

1432 {
1433  /* Search for the regex in C_AbortNoattachRegex within a file */
1435  !C_QuoteRegex->regex)
1436  {
1437  return false;
1438  }
1439 
1440  FILE *fp_att = mutt_file_fopen(filename, "r");
1441  if (!fp_att)
1442  return false;
1443 
1444  char *inputline = mutt_mem_malloc(1024);
1445  bool found = false;
1446  while (!feof(fp_att))
1447  {
1448  fgets(inputline, 1024, fp_att);
1449  if (!mutt_is_quote_line(inputline, NULL) &&
1450  (regexec(C_AbortNoattachRegex->regex, inputline, 0, NULL, 0) == 0))
1451  {
1452  found = true;
1453  break;
1454  }
1455  }
1456  FREE(&inputline);
1457  mutt_file_fclose(&fp_att);
1458  return found;
1459 }
struct Regex * C_AbortNoattachRegex
Config: Regex to match text indicating attachments are expected.
Definition: send.c:85
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:149
regex_t * regex
compiled expression
Definition: regex3.h:60
void * mutt_mem_malloc(size_t size)
Allocate memory on the heap.
Definition: memory.c:99
WHERE struct Regex * C_QuoteRegex
Config: Regex to match quoted text in a reply.
Definition: globals.h:185
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:546
#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

+ 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 1473 of file send.c.

1475 {
1476  int rc = 0;
1477  struct Body *save_content = NULL;
1478 
1479  mutt_expand_path(fcc, fcc_len);
1480 
1481  /* Don't save a copy when we are in batch-mode, and the FCC
1482  * folder is on an IMAP server: This would involve possibly lots
1483  * of user interaction, which is not available in batch mode.
1484  *
1485  * Note: A patch to fix the problems with the use of IMAP servers
1486  * from non-curses mode is available from Brendan Cully. However,
1487  * I'd like to think a bit more about this before including it. */
1488 
1489 #ifdef USE_IMAP
1490  if ((flags & SEND_BATCH) && (fcc[0] != '\0') && (imap_path_probe(fcc, NULL) == MUTT_IMAP))
1491  {
1492  fcc[0] = '\0';
1493  mutt_error(_("Fcc to an IMAP mailbox is not supported in batch mode"));
1494  return rc;
1495  }
1496 #endif
1497 
1498  if (!(*fcc && mutt_str_strcmp("/dev/null", fcc)))
1499  return rc;
1500 
1501  struct Body *tmpbody = msg->content;
1502  struct Body *save_sig = NULL;
1503  struct Body *save_parts = NULL;
1504 
1505  if ((WithCrypto != 0) && (msg->security & (SEC_ENCRYPT | SEC_SIGN)) && C_FccClear)
1506  {
1507  msg->content = clear_content;
1508  msg->security &= ~(SEC_ENCRYPT | SEC_SIGN);
1510  }
1511 
1512  /* check to see if the user wants copies of all attachments */
1513  if (msg->content->type == TYPE_MULTIPART)
1514  {
1515  if ((WithCrypto != 0) && (msg->security & (SEC_ENCRYPT | SEC_SIGN)) &&
1516  ((mutt_str_strcmp(msg->content->subtype, "encrypted") == 0) ||
1517  (mutt_str_strcmp(msg->content->subtype, "signed") == 0)))
1518  {
1519  if ((clear_content->type == TYPE_MULTIPART) &&
1520  (query_quadoption(C_FccAttach, _("Save attachments in Fcc?")) == MUTT_NO))
1521  {
1522  if (!(msg->security & SEC_ENCRYPT) && (msg->security & SEC_SIGN))
1523  {
1524  /* save initial signature and attachments */
1525  save_sig = msg->content->parts->next;
1526  save_parts = clear_content->parts->next;
1527  }
1528 
1529  /* this means writing only the main part */
1530  msg->content = clear_content->parts;
1531 
1532  if (mutt_protect(msg, pgpkeylist) == -1)
1533  {
1534  /* we can't do much about it at this point, so
1535  * fallback to saving the whole thing to fcc */
1536  msg->content = tmpbody;
1537  save_sig = NULL;
1538  goto full_fcc;
1539  }
1540 
1541  save_content = msg->content;
1542  }
1543  }
1544  else
1545  {
1546  if (query_quadoption(C_FccAttach, _("Save attachments in Fcc?")) == MUTT_NO)
1547  msg->content = msg->content->parts;
1548  }
1549  }
1550 
1551 full_fcc:
1552  if (msg->content)
1553  {
1554  /* update received time so that when storing to a mbox-style folder
1555  * the From_ line contains the current time instead of when the
1556  * message was first postponed. */
1557  msg->received = time(NULL);
1558  rc = mutt_write_multiple_fcc(fcc, msg, NULL, false, NULL, finalpath);
1559  while (rc && !(flags & SEND_BATCH))
1560  {
1561  mutt_clear_error();
1562  int choice = mutt_multi_choice(
1563  /* L10N: Called when saving to $record or Fcc failed after sending.
1564  (r)etry tries the same mailbox again.
1565  alternate (m)ailbox prompts for a different mailbox to try.
1566  (s)kip aborts saving. */
1567  _("Fcc failed. (r)etry, alternate (m)ailbox, or (s)kip? "),
1568  /* L10N: These correspond to the "Fcc failed" multi-choice prompt
1569  (r)etry, alternate (m)ailbox, or (s)kip.
1570  Any similarity to famous leaders of the FSF is coincidental. */
1571  _("rms"));
1572  switch (choice)
1573  {
1574  case 2: /* alternate (m)ailbox */
1575  /* L10N: This is the prompt to enter an "alternate (m)ailbox" when the
1576  initial Fcc fails. */
1577  rc = mutt_enter_fname(_("Fcc mailbox"), fcc, fcc_len, 1);
1578  if ((rc == -1) || (fcc[0] == '\0'))
1579  {
1580  rc = 0;
1581  break;
1582  }
1583  /* fall through */
1584 
1585  case 1: /* (r)etry */
1586  rc = mutt_write_multiple_fcc(fcc, msg, NULL, false, NULL, finalpath);
1587  break;
1588 
1589  case -1: /* abort */
1590  case 3: /* (s)kip */
1591  rc = 0;
1592  break;
1593  }
1594  }
1595  }
1596 
1597  msg->content = tmpbody;
1598 
1599  if ((WithCrypto != 0) && save_sig)
1600  {
1601  /* cleanup the second signature structures */
1602  if (save_content->parts)
1603  {
1604  mutt_body_free(&save_content->parts->next);
1605  save_content->parts = NULL;
1606  }
1607  mutt_body_free(&save_content);
1608 
1609  /* restore old signature and attachments */
1610  msg->content->parts->next = save_sig;
1611  msg->content->parts->parts->next = save_parts;
1612  }
1613  else if ((WithCrypto != 0) && save_content)
1614  {
1615  /* destroy the new encrypted body. */
1616  mutt_body_free(&save_content);
1617  }
1618 
1619  return 0;
1620 }
struct Envelope * mime_headers
memory hole protected headers
Definition: body.h:68
enum MailboxType imap_path_probe(const char *path, const struct stat *st)
Is this an IMAP mailbox? - Implements MxOps::path_probe()
Definition: imap.c:2454
enum QuadOption query_quadoption(enum QuadOption opt, const char *prompt)
Ask the user a quad-question.
Definition: init.c:3369
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:58
&#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:157
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:3085
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:792
#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:168
unsigned char C_FccAttach
Config: Save send message with all their attachments.
Definition: send.c:100
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:59
bool C_FccClear
Config: Save sent messages unencrypted and unsigned.
Definition: send.c:101
SecurityFlags security
bit 0-8: flags, bit 9,10: application.
Definition: email.h:39
unsigned int type
content-type primary type
Definition: body.h:70
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:88
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:76
#define WithCrypto
Definition: ncrypt.h:155
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:611
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 1631 of file send.c.

1632 {
1633  char *pgpkeylist = NULL;
1634  char *encrypt_as = NULL;
1635  struct Body *clear_content = NULL;
1636 
1637  if (!(C_Postponed && *C_Postponed))
1638  {
1639  mutt_error(_("Cannot postpone. $postponed is unset"));
1640  return -1;
1641  }
1642 
1643  if (msg->content->next)
1644  msg->content = mutt_make_multipart(msg->content);
1645 
1646  mutt_encode_descriptions(msg->content, true);
1647 
1648  if ((WithCrypto != 0) && C_PostponeEncrypt && (msg->security & SEC_ENCRYPT))
1649  {
1650  if (((WithCrypto & APPLICATION_PGP) != 0) && (msg->security & APPLICATION_PGP))
1651  encrypt_as = C_PgpDefaultKey;
1652  else if (((WithCrypto & APPLICATION_SMIME) != 0) && (msg->security & APPLICATION_SMIME))
1653  encrypt_as = C_SmimeDefaultKey;
1654  if (!(encrypt_as && *encrypt_as))
1655  encrypt_as = C_PostponeEncryptAs;
1656 
1657  if (encrypt_as && *encrypt_as)
1658  {
1659  bool is_signed = (msg->security & SEC_SIGN);
1660  if (is_signed)
1661  msg->security &= ~SEC_SIGN;
1662 
1663  pgpkeylist = mutt_str_strdup(encrypt_as);
1664  clear_content = msg->content;
1665  if (mutt_protect(msg, pgpkeylist) == -1)
1666  {
1667  if (is_signed)
1668  msg->security |= SEC_SIGN;
1669  FREE(&pgpkeylist);
1670  msg->content = mutt_remove_multipart(msg->content);
1672  return -1;
1673  }
1674 
1675  if (is_signed)
1676  msg->security |= SEC_SIGN;
1677  FREE(&pgpkeylist);
1678 
1679  mutt_encode_descriptions(msg->content, false);
1680  }
1681  }
1682 
1683  /* make sure the message is written to the right part of a maildir
1684  * postponed folder. */
1685  msg->read = false;
1686  msg->old = false;
1687 
1688  mutt_prepare_envelope(msg->env, false);
1689  mutt_env_to_intl(msg->env, NULL, NULL); /* Handle bad IDNAs the next time. */
1690 
1691  if (mutt_write_fcc(NONULL(C_Postponed), msg,
1692  (cur && (flags & SEND_REPLY)) ? cur->env->message_id : NULL,
1693  true, fcc, NULL) < 0)
1694  {
1695  if (clear_content)
1696  {
1697  mutt_body_free(&msg->content);
1698  msg->content = clear_content;
1699  }
1700  mutt_env_free(&msg->content->mime_headers); /* protected headers */
1701  msg->content = mutt_remove_multipart(msg->content);
1704  return -1;
1705  }
1706 
1708 
1709  if (clear_content)
1710  mutt_body_free(&clear_content);
1711 
1712  return 0;
1713 }
char * C_PostponeEncryptAs
Config: Fallback encryption key for postponed messages.
Definition: send.c:117
#define NONULL(x)
Definition: string2.h:36
struct Envelope * mime_headers
memory hole protected headers
Definition: body.h:68
struct Body * mutt_remove_multipart(struct Body *b)
Extract the multipart body if it exists.
Definition: sendlib.c:1713
WHERE char * C_SmimeDefaultKey
Config: Default key for SMIME operations.
Definition: globals.h:174
struct Body * content
list of MIME parts
Definition: email.h:93
bool C_PostponeEncrypt
Config: Self-encrypt postponed messages.
Definition: send.c:116
#define _(a)
Definition: message.h:28
struct Body * next
next attachment in the list
Definition: body.h:58
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:238
#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:2884
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:1327
struct Body * mutt_make_multipart(struct Body *b)
Create a multipart email.
Definition: sendlib.c:1687
void mutt_unprepare_envelope(struct Envelope *env)
Undo the encodings of mutt_prepare_envelope()
Definition: sendlib.c:2922
#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:168
void mutt_encode_descriptions(struct Body *b, bool recurse)
rfc2047 encode the content-descriptions
Definition: send.c:1310
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:383
#define mutt_error(...)
Definition: logging.h:88
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:170
#define FREE(x)
Definition: memory.h:40
WHERE char * C_Postponed
Config: Folder to store postponed messages.
Definition: globals.h:140
#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:3132

+ 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 1726 of file send.c.

1728 {
1729  char buf[1024];
1730  char fcc[PATH_MAX] = ""; /* where to copy this message */
1731  FILE *fp_tmp = NULL;
1732  struct Body *pbody = NULL;
1733  int i;
1734  bool killfrom = false;
1735  bool free_clear_content = false;
1736 
1737  struct Body *clear_content = NULL;
1738  char *pgpkeylist = NULL;
1739  /* save current value of "pgp_sign_as" and "smime_default_key" */
1740  char *pgp_signas = NULL;
1741  char *smime_signas = NULL;
1742  const char *tag = NULL;
1743  char *err = NULL;
1744  char *ctype = NULL;
1745  char *finalpath = NULL;
1746  struct EmailNode *en = NULL;
1747  struct Email *cur = NULL;
1748 
1749  if (el)
1750  en = STAILQ_FIRST(el);
1751  if (en)
1752  cur = STAILQ_NEXT(en, entries) ? en->email : NULL;
1753 
1754  int rc = -1;
1755 
1756 #ifdef USE_NNTP
1757  if (flags & SEND_NEWS)
1758  OptNewsSend = true;
1759  else
1760  OptNewsSend = false;
1761 #endif
1762 
1763  if (!flags && !msg && (C_Recall != MUTT_NO) &&
1764  mutt_num_postponed(ctx ? ctx->mailbox : NULL, true))
1765  {
1766  /* If the user is composing a new message, check to see if there
1767  * are any postponed messages first. */
1768  enum QuadOption ans =
1769  query_quadoption(C_Recall, _("Recall postponed message?"));
1770  if (ans == MUTT_ABORT)
1771  return rc;
1772 
1773  if (ans == MUTT_YES)
1774  flags |= SEND_POSTPONED;
1775  }
1776 
1777  if (flags & SEND_POSTPONED)
1778  {
1780  pgp_signas = mutt_str_strdup(C_PgpSignAs);
1782  smime_signas = mutt_str_strdup(C_SmimeSignAs);
1783  }
1784 
1785  /* Delay expansion of aliases until absolutely necessary--shouldn't
1786  * be necessary unless we are prompting the user or about to execute a
1787  * send-hook. */
1788 
1789  if (!msg)
1790  {
1791  msg = mutt_email_new();
1792 
1793  if (flags == SEND_POSTPONED)
1794  {
1795  rc = mutt_get_postponed(ctx, msg, &cur, fcc, sizeof(fcc));
1796  if (rc < 0)
1797  {
1798  flags = SEND_POSTPONED;
1799  goto cleanup;
1800  }
1801  flags = rc;
1802 #ifdef USE_NNTP
1803  /* If postponed message is a news article, it have
1804  * a "Newsgroups:" header line, then set appropriate flag. */
1805  if (msg->env->newsgroups)
1806  {
1807  flags |= SEND_NEWS;
1808  OptNewsSend = true;
1809  }
1810  else
1811  {
1812  flags &= ~SEND_NEWS;
1813  OptNewsSend = false;
1814  }
1815 #endif
1816  }
1817 
1818  if (flags & (SEND_POSTPONED | SEND_RESEND))
1819  {
1820  fp_tmp = mutt_file_fopen(msg->content->filename, "a+");
1821  if (!fp_tmp)
1822  {
1823  mutt_perror(msg->content->filename);
1824  goto cleanup;
1825  }
1826  }
1827 
1828  if (!msg->env)
1829  msg->env = mutt_env_new();
1830  }
1831 
1832  /* Parse and use an eventual list-post header */
1833  if ((flags & SEND_LIST_REPLY) && cur && cur->env && cur->env->list_post)
1834  {
1835  /* Use any list-post header as a template */
1836  url_parse_mailto(msg->env, NULL, cur->env->list_post);
1837  /* We don't let them set the sender's address. */
1838  mutt_addr_free(&msg->env->from);
1839  }
1840 
1841  if (!(flags & (SEND_KEY | SEND_POSTPONED | SEND_RESEND)))
1842  {
1843  /* When SEND_DRAFT_FILE is set, the caller has already
1844  * created the "parent" body structure. */
1845  if (!(flags & SEND_DRAFT_FILE))
1846  {
1847  pbody = mutt_body_new();
1848  pbody->next = msg->content; /* don't kill command-line attachments */
1849  msg->content = pbody;
1850 
1851  ctype = mutt_str_strdup(C_ContentType);
1852  if (!ctype)
1853  ctype = mutt_str_strdup("text/plain");
1854  mutt_parse_content_type(ctype, msg->content);
1855  FREE(&ctype);
1856  msg->content->unlink = true;
1857  msg->content->use_disp = false;
1859 
1860  if (!tempfile)
1861  {
1862  mutt_mktemp(buf, sizeof(buf));
1863  fp_tmp = mutt_file_fopen(buf, "w+");
1864  msg->content->filename = mutt_str_strdup(buf);
1865  }
1866  else
1867  {
1868  fp_tmp = mutt_file_fopen(tempfile, "a+");
1869  msg->content->filename = mutt_str_strdup(tempfile);
1870  }
1871  }
1872  else
1873  fp_tmp = mutt_file_fopen(msg->content->filename, "a+");
1874 
1875  if (!fp_tmp)
1876  {
1877  mutt_debug(LL_DEBUG1, "can't create tempfile %s (errno=%d)\n",
1878  msg->content->filename, errno);
1879  mutt_perror(msg->content->filename);
1880  goto cleanup;
1881  }
1882  }
1883 
1884  /* this is handled here so that the user can match ~f in send-hook */
1885  if (cur && C_ReverseName && !(flags & (SEND_POSTPONED | SEND_RESEND)))
1886  {
1887  /* we shouldn't have to worry about freeing 'msg->env->from' before
1888  * setting it here since this code will only execute when doing some
1889  * sort of reply. the pointer will only be set when using the -H command
1890  * line option.
1891  *
1892  * We shouldn't have to worry about alias expansion here since we are
1893  * either replying to a real or postponed message, therefore no aliases
1894  * should exist since the user has not had the opportunity to add
1895  * addresses to the list. We just have to ensure the postponed messages
1896  * have their aliases expanded. */
1897 
1898  if (msg->env->from)
1899  {
1900  mutt_debug(5, "msg->env->from before set_reverse_name: %s\n",
1901  msg->env->from->mailbox);
1902  }
1903  msg->env->from = set_reverse_name(cur->env);
1904  }
1905  if (cur && C_ReplyWithXorig && !(flags & (SEND_POSTPONED | SEND_RESEND | SEND_FORWARD)))
1906  {
1907  /* We shouldn't have to worry about freeing 'msg->env->from' before
1908  * setting it here since this code will only execute when doing some
1909  * sort of reply. The pointer will only be set when using the -H command
1910  * line option.
1911  *
1912  * If there is already a from address recorded in 'msg->env->from',
1913  * then it theoretically comes from C_ReverseName handling, and we don't use
1914  * the 'X-Orig-To header'. */
1915  if (cur->env->x_original_to && !msg->env->from)
1916  {
1917  msg->env->from = mutt_addr_copy(cur->env->x_original_to);
1918  mutt_debug(5, "msg->env->from extracted from X-Original-To: header: %s\n",
1919  msg->env->from->mailbox);
1920  }
1921  }
1922 
1923  if (!(flags & (SEND_POSTPONED | SEND_RESEND)) &&
1924  !((flags & SEND_DRAFT_FILE) && C_ResumeDraftFiles))
1925  {
1926  if ((flags & (SEND_REPLY | SEND_FORWARD | SEND_TO_SENDER)) && ctx &&
1927  (envelope_defaults(msg->env, ctx->mailbox, el, flags) == -1))
1928  {
1929  goto cleanup;
1930  }
1931 
1932  if (C_Hdrs)
1933  process_user_recips(msg->env);
1934 
1935  /* Expand aliases and remove duplicates/crossrefs */
1937 
1938  if (flags & SEND_REPLY)
1940 
1941 #ifdef USE_NNTP
1942  if ((flags & SEND_NEWS) && ctx && (ctx->mailbox->magic == MUTT_NNTP) &&
1943  !msg->env->newsgroups)
1944  {
1945  msg->env->newsgroups =
1946  mutt_str_strdup(((struct NntpMboxData *) ctx->mailbox->mdata)->group);
1947  }
1948 #endif
1949 
1950  if (!(flags & (SEND_MAILX | SEND_BATCH)) &&
1951  !(C_Autoedit && C_EditHeaders) && !((flags & SEND_REPLY) && C_FastReply))
1952  {
1953  if (edit_envelope(msg->env, flags) == -1)
1954  goto cleanup;
1955  }
1956 
1957  /* the from address must be set here regardless of whether or not
1958  * $use_from is set so that the '~P' (from you) operator in send-hook
1959  * patterns will work. if $use_from is unset, the from address is killed
1960  * after send-hooks are evaluated */
1961 
1962  if (!msg->env->from)
1963  {
1964  msg->env->from = mutt_default_from();
1965  killfrom = true;
1966  }
1967 
1968  if ((flags & SEND_REPLY) && cur)
1969  {
1970  /* change setting based upon message we are replying to */
1971  mutt_message_hook(ctx ? ctx->mailbox : NULL, cur, MUTT_REPLY_HOOK);
1972 
1973  /* set the replied flag for the message we are generating so that the
1974  * user can use ~Q in a send-hook to know when reply-hook's are also
1975  * being used. */
1976  msg->replied = true;
1977  }
1978 
1979  /* change settings based upon recipients */
1980 
1981  mutt_message_hook(NULL, msg, MUTT_SEND_HOOK);
1982 
1983  /* Unset the replied flag from the message we are composing since it is
1984  * no longer required. This is done here because the FCC'd copy of
1985  * this message was erroneously get the 'R'eplied flag when stored in
1986  * a maildir-style mailbox. */
1987  msg->replied = false;
1988 
1989  if (!(flags & SEND_KEY))
1990  {
1991  if (C_TextFlowed && (msg->content->type == TYPE_TEXT) &&
1992  (mutt_str_strcasecmp(msg->content->subtype, "plain") == 0))
1993  {
1994  mutt_param_set(&msg->content->parameter, "format", "flowed");
1995  }
1996  }
1997 
1998  /* $use_from and/or $from might have changed in a send-hook */
1999  if (killfrom)
2000  {
2001  mutt_addr_free(&msg->env->from);
2002  if (C_UseFrom && !(flags & (SEND_POSTPONED | SEND_RESEND)))
2003  msg->env->from = mutt_default_from();
2004  killfrom = false;
2005  }
2006 
2007  if (C_Hdrs)
2008  process_user_header(msg->env);
2009 
2010  if (flags & SEND_BATCH)
2011  mutt_file_copy_stream(stdin, fp_tmp);
2012 
2013  if (C_SigOnTop && !(flags & (SEND_MAILX | SEND_KEY | SEND_BATCH)) &&
2014  C_Editor && (mutt_str_strcmp(C_Editor, "builtin") != 0))
2015  {
2016  append_signature(fp_tmp);
2017  }
2018 
2019  /* include replies/forwarded messages, unless we are given a template */
2020  if (!tempfile && (ctx || !(flags & (SEND_REPLY | SEND_FORWARD))) &&
2021  (generate_body(fp_tmp, msg, flags, ctx->mailbox, el) == -1))
2022  {
2023  goto cleanup;
2024  }
2025 
2026  if (!C_SigOnTop && !(flags & (SEND_MAILX | SEND_KEY | SEND_BATCH)) &&
2027  C_Editor && (mutt_str_strcmp(C_Editor, "builtin") != 0))
2028  {
2029  append_signature(fp_tmp);
2030  }
2031  }
2032 
2033  /* This hook is even called for postponed messages, and can, e.g., be
2034  * used for setting the editor, the sendmail path, or the
2035  * envelope sender. */
2036  mutt_message_hook(NULL, msg, MUTT_SEND2_HOOK);
2037 
2038  /* wait until now to set the real name portion of our return address so
2039  * that $realname can be set in a send-hook */
2040  if (msg->env->from && !msg->env->from->personal && !(flags & (SEND_RESEND | SEND_POSTPONED)))
2042 
2043  if (!(((WithCrypto & APPLICATION_PGP) != 0) && (flags & SEND_KEY)))
2044  mutt_file_fclose(&fp_tmp);
2045 
2046  if (flags & SEND_MAILX)
2047  {
2048  if (mutt_builtin_editor(msg->content->filename, msg, cur) == -1)
2049  goto cleanup;
2050  }
2051  else if (!(flags & SEND_BATCH))
2052  {
2053  struct stat st;
2054  time_t mtime = mutt_file_decrease_mtime(msg->content->filename, NULL);
2055 
2057 
2058  /* Select whether or not the user's editor should be called now. We
2059  * don't want to do this when:
2060  * 1) we are sending a key/cert
2061  * 2) we are forwarding a message and the user doesn't want to edit it.
2062  * This is controlled by the quadoption $forward_edit. However, if
2063  * both $edit_headers and $autoedit are set, we want to ignore the
2064  * setting of $forward_edit because the user probably needs to add the
2065  * recipients. */
2066  if (!(flags & SEND_KEY) &&
2067  (((flags & SEND_FORWARD) == 0) || (C_EditHeaders && C_Autoedit) ||
2068  (query_quadoption(C_ForwardEdit, _("Edit forwarded message?")) == MUTT_YES)))
2069  {
2070  /* If the this isn't a text message, look for a mailcap edit command */
2071  if (mutt_needs_mailcap(msg->content))
2072  {
2073  if (!mutt_edit_attachment(msg->content))
2074  goto cleanup;
2075  }
2076  else if (!C_Editor || (mutt_str_strcmp("builtin", C_Editor) == 0))
2077  mutt_builtin_editor(msg->content->filename, msg, cur);
2078  else if (C_EditHeaders)
2079  {
2080  mutt_env_to_local(msg->env);
2081  mutt_edit_headers(C_Editor, msg->content->filename, msg, fcc, sizeof(fcc));
2082  mutt_env_to_intl(msg->env, NULL, NULL);
2083  }
2084  else
2085  {
2087  if (stat(msg->content->filename, &st) == 0)
2088  {
2089  if (mtime != st.st_mtime)
2091  }
2092  else
2093  mutt_perror(msg->content->filename);
2094  }
2095 
2096  /* If using format=flowed, perform space stuffing. Avoid stuffing when
2097  * recalling a postponed message where the stuffing was already
2098  * performed. If it has already been performed, the format=flowed
2099  * parameter will be present. */
2100  if (C_TextFlowed && (msg->content->type == TYPE_TEXT) &&
2101  (mutt_str_strcasecmp("plain", msg->content->subtype) == 0))
2102  {
2103  char *p = mutt_param_get(&msg->content->parameter, "format");
2104  if (mutt_str_strcasecmp("flowed", p) != 0)
2105  rfc3676_space_stuff(msg);
2106  }
2107 
2108  mutt_message_hook(NULL, msg, MUTT_SEND2_HOOK);
2109  }
2110 
2111  if (!(flags & (SEND_POSTPONED | SEND_FORWARD | SEND_KEY | SEND_RESEND | SEND_DRAFT_FILE)))
2112  {
2113  if (stat(msg->content->filename, &st) == 0)
2114  {
2115  /* if the file was not modified, bail out now */
2116  if ((mtime == st.st_mtime) && !msg->content->next &&
2118  _("Abort unmodified message?")) == MUTT_YES))
2119  {
2120  mutt_message(_("Aborted unmodified message"));
2121  goto cleanup;
2122  }
2123  }
2124  else
2125  mutt_perror(msg->content->filename);
2126  }
2127  }
2128 
2129  /* Set the message security unless:
2130  * 1) crypto support is not enabled (WithCrypto==0)
2131  * 2) pgp: header field was present during message editing with $edit_headers (msg->security != 0)
2132  * 3) we are resending a message
2133  * 4) we are recalling a postponed message (don't override the user's saved settings)
2134  * 5) we are in mailx mode
2135  * 6) we are in batch mode
2136  *
2137  * This is done after allowing the user to edit the message so that security
2138  * settings can be configured with send2-hook and $edit_headers. */
2139  if ((WithCrypto != 0) && (msg->security == 0) &&
2140  !(flags & (SEND_BATCH | SEND_MAILX | SEND_POSTPONED | SEND_RESEND)))
2141  {
2142  if (C_CryptAutosign)
2143  msg->security |= SEC_SIGN;
2144  if (C_CryptAutoencrypt)
2145  msg->security |= SEC_ENCRYPT;
2146  if (C_CryptReplyencrypt && cur && (cur->security & SEC_ENCRYPT))
2147  msg->security |= SEC_ENCRYPT;
2148  if (C_CryptReplysign && cur && (cur->security & SEC_SIGN))
2149  msg->security |= SEC_SIGN;
2150  if (C_CryptReplysignencrypted && cur && (cur->security & SEC_ENCRYPT))
2151  msg->security |= SEC_SIGN;
2152  if (((WithCrypto & APPLICATION_PGP) != 0) &&
2154  {
2155  if (C_PgpAutoinline)
2156  msg->security |= SEC_INLINE;
2157  if (C_PgpReplyinline && cur && (cur->security & SEC_INLINE))
2158  msg->security |= SEC_INLINE;
2159  }
2160 
2162  {
2163  /* When replying / forwarding, use the original message's
2164  * crypto system. According to the documentation,
2165  * smime_is_default should be disregarded here.
2166  *
2167  * Problem: At least with forwarding, this doesn't really
2168  * make much sense. Should we have an option to completely
2169  * disable individual mechanisms at run-time? */
2170  if (cur)
2171  {
2172  if (((WithCrypto & APPLICATION_PGP) != 0) && C_CryptAutopgp &&
2173  (cur->security & APPLICATION_PGP))
2174  {
2175  msg->security |= APPLICATION_PGP;
2176  }
2177  else if (((WithCrypto & APPLICATION_SMIME) != 0) && C_CryptAutosmime &&
2178  (cur->security & APPLICATION_SMIME))
2179  {
2180  msg->security |= APPLICATION_SMIME;
2181  }
2182  }
2183 
2184  /* No crypto mechanism selected? Use availability + smime_is_default
2185  * for the decision. */
2186  if (!(msg->security & (APPLICATION_SMIME | APPLICATION_PGP)))
2187  {
2188  if (((WithCrypto & APPLICATION_SMIME) != 0) && C_CryptAutosmime && C_SmimeIsDefault)
2189  {
2190  msg->security |= APPLICATION_SMIME;
2191  }
2192  else if (((WithCrypto & APPLICATION_PGP) != 0) && C_CryptAutopgp)
2193  {
2194  msg->security |= APPLICATION_PGP;
2195  }
2196  else if (((WithCrypto & APPLICATION_SMIME) != 0) && C_CryptAutosmime)
2197  {
2198  msg->security |= APPLICATION_SMIME;
2199  }
2200  }
2201  }
2202 
2203  /* opportunistic encrypt relies on SMIME or PGP already being selected */
2205  {
2206  /* If something has already enabled encryption, e.g. C_CryptAutoencrypt
2207  * or C_CryptReplyencrypt, then don't enable opportunistic encrypt for
2208  * the message. */
2209  if (!(msg->security & SEC_ENCRYPT))
2210  {
2211  msg->security |= SEC_OPPENCRYPT;
2213  }
2214  }
2215 
2216  /* No permissible mechanisms found. Don't sign or encrypt. */
2217  if (!(msg->security & (APPLICATION_SMIME | APPLICATION_PGP)))
2218  msg->security = SEC_NO_FLAGS;
2219  }
2220 
2221  /* Deal with the corner case where the crypto module backend is not available.
2222  * This can happen if configured without pgp/smime and with gpgme, but
2223  * $crypt_use_gpgme is unset. */
2224  if (msg->security && !crypt_has_module_backend(msg->security))
2225  {
2226  mutt_error(_(
2227  "No crypto backend configured. Disabling message security setting."));
2228  msg->security = SEC_NO_FLAGS;
2229  }
2230 
2231  /* specify a default fcc. if we are in batchmode, only save a copy of
2232  * the message if the value of $copy is yes or ask-yes */
2233 
2234  if (!fcc[0] && !(flags & SEND_POSTPONED_FCC) && (!(flags & SEND_BATCH) || (C_Copy & 0x1)))
2235  {
2236  /* set the default FCC */
2237  if (!msg->env->from)
2238  {
2239  msg->env->from = mutt_default_from();
2240  killfrom = true; /* no need to check $use_from because if the user specified
2241  a from address it would have already been set by now */
2242  }
2243  mutt_select_fcc(fcc, sizeof(fcc), msg);
2244  if (killfrom)
2245  {
2246  mutt_addr_free(&msg->env->from);
2247  }
2248  }
2249 
2251 
2252  if (!(flags & (SEND_MAILX | SEND_BATCH)))
2253  {
2254  main_loop:
2255 
2256  mutt_pretty_mailbox(fcc, sizeof(fcc));
2257  i = mutt_compose_menu(msg, fcc, sizeof(fcc), cur,
2259  if (i == -1)
2260  {
2261 /* abort */
2262 #ifdef USE_NNTP
2263  if (flags & SEND_NEWS)
2264  mutt_message(_("Article not posted"));
2265  else
2266 #endif
2267  mutt_message(_("Mail not sent"));
2268  goto cleanup;
2269  }
2270  else if (i == 1)
2271  {
2272  if (postpone_message(msg, cur, fcc, flags) != 0)
2273  goto main_loop;
2274  mutt_message(_("Message postponed"));
2275  rc = 1;
2276  goto cleanup;
2277  }
2278  }
2279 
2280 #ifdef USE_NNTP
2281  if (!(flags & SEND_NEWS))
2282 #endif
2283  if ((mutt_addr_has_recips(msg->env->to) == 0) &&
2284  (mutt_addr_has_recips(msg->env->cc) == 0) &&
2285  (mutt_addr_has_recips(msg->env->bcc) == 0))
2286  {
2287  if (!(flags & SEND_BATCH))
2288  {
2289  mutt_error(_("No recipients specified"));
2290  goto main_loop;
2291  }
2292  else
2293  {
2294  puts(_("No recipients specified"));
2295  goto cleanup;
2296  }
2297  }
2298 
2299  if (mutt_env_to_intl(msg->env, &tag, &err))
2300  {
2301  mutt_error(_("Bad IDN in '%s': '%s'"), tag, err);
2302  FREE(&err);
2303  if (!(flags & SEND_BATCH))
2304  goto main_loop;
2305  else
2306  goto cleanup;
2307  }
2308 
2309  if (!msg->env->subject && !(flags & SEND_BATCH) &&
2310  (query_quadoption(C_AbortNosubject, _("No subject, abort sending?")) != MUTT_NO))
2311  {
2312  /* if the abort is automatic, print an error message */
2313  if (C_AbortNosubject == MUTT_YES)
2314  mutt_error(_("No subject specified"));
2315  goto main_loop;
2316  }
2317 #ifdef USE_NNTP
2318  if ((flags & SEND_NEWS) && !msg->env->subject)
2319  {
2320  mutt_error(_("No subject specified"));
2321  goto main_loop;
2322  }
2323 
2324  if ((flags & SEND_NEWS) && !msg->env->newsgroups)
2325  {
2326  mutt_error(_("No newsgroup specified"));
2327  goto main_loop;
2328  }
2329 #endif
2330 
2331  if (!(flags & SEND_BATCH) && (C_AbortNoattach != MUTT_NO) &&
2332  !msg->content->next && (msg->content->type == TYPE_TEXT) &&
2333  (mutt_str_strcasecmp(msg->content->subtype, "plain") == 0) &&
2336  _("No attachments, cancel sending?")) != MUTT_NO))
2337  {
2338  /* if the abort is automatic, print an error message */
2339  if (C_AbortNoattach == MUTT_YES)
2340  {
2341  mutt_error(_("Message contains text matching "
2342  "\"$abort_noattach_regex\". Not sending."));
2343  }
2344  goto main_loop;
2345  }
2346 
2347  if (msg->content->next)
2348  msg->content = mutt_make_multipart(msg->content);
2349 
2350  /* Ok, we need to do it this way instead of handling all fcc stuff in
2351  * one place in order to avoid going to main_loop with encoded "env"
2352  * in case of error. Ugh. */
2353 
2354  mutt_encode_descriptions(msg->content, true);
2355 
2356  /* Make sure that clear_content and free_clear_content are
2357  * properly initialized -- we may visit this particular place in
2358  * the code multiple times, including after a failed call to
2359  * mutt_protect(). */
2360 
2361  clear_content = NULL;
2362  free_clear_content = false;
2363 
2364  if (WithCrypto)
2365  {
2366  if (msg->security & (SEC_ENCRYPT | SEC_SIGN))
2367  {
2368  /* save the decrypted attachments */
2369  clear_content = msg->content;
2370 
2371  if ((crypt_get_keys(msg, &pgpkeylist, 0) == -1) ||
2372  (mutt_protect(msg, pgpkeylist) == -1))
2373  {
2374  msg->content = mutt_remove_multipart(msg->content);
2375 
2376  FREE(&pgpkeylist);
2377 
2379  goto main_loop;
2380  }
2381  mutt_encode_descriptions(msg->content, false);
2382  }
2383 
2384  /* at this point, msg->content is one of the following three things:
2385  * - multipart/signed. In this case, clear_content is a child
2386  * - multipart/encrypted. In this case, clear_content exists independently
2387  * - application/pgp. In this case, clear_content exists independently
2388  * - something else. In this case, it's the same as clear_content
2389  */
2390 
2391  /* This is ugly -- lack of "reporting back" from mutt_protect(). */
2392 
2393  if (clear_content && (msg->content != clear_content) && (msg->content->parts != clear_content))
2394  free_clear_content = true;
2395  }
2396 
2397  if (!OptNoCurses && !(flags & SEND_MAILX))
2398  mutt_message(_("Sending message..."));
2399 
2400  mutt_prepare_envelope(msg->env, true);
2401 
2402  i = send_message(msg);
2403  if (i < 0)
2404  {
2405  if (!(flags & SEND_BATCH))
2406  {
2407  if (!WithCrypto)
2408  ;
2409  else if ((msg->security & SEC_ENCRYPT) ||
2410  ((msg->security & SEC_SIGN) && (msg->content->type == TYPE_APPLICATION)))
2411  {
2412  mutt_body_free(&msg->content); /* destroy PGP data */
2413  msg->content = clear_content; /* restore clear text. */
2414  }
2415  else if ((msg->security & SEC_SIGN) && (msg->content->type == TYPE_MULTIPART))
2416  {
2417  mutt_body_free(&msg->content->parts->next); /* destroy sig */
2418  msg->content = mutt_remove_multipart(msg->content);
2419  }
2420 
2421  FREE(&pgpkeylist);
2422  mutt_env_free(&msg->content->mime_headers); /* protected headers */
2423  msg->content = mutt_remove_multipart(msg->content);
2426  FREE(&finalpath);
2427  goto main_loop;
2428  }
2429  else
2430  {
2431  puts(_("Could not send the message"));
2432  goto cleanup;
2433  }
2434  }
2435 
2436  save_fcc(msg, fcc, sizeof(fcc), clear_content, pgpkeylist, flags, &finalpath);
2437 
2438  if (!OptNoCurses && !(flags & SEND_MAILX))
2439  {
2440  mutt_message(i != 0 ? _("Sending in background") :
2441  (flags & SEND_NEWS) ? _("Article posted") : /* USE_NNTP */
2442  _("Mail sent"));
2443 #ifdef USE_NOTMUCH
2444  if (C_NmRecord)
2445  nm_record_message(ctx ? ctx->mailbox : NULL, finalpath, cur);
2446 #endif
2447  mutt_sleep(0);
2448  }
2449 
2450  if (WithCrypto)
2451  FREE(&pgpkeylist);
2452 
2453  if ((WithCrypto != 0) && free_clear_content)
2454  mutt_body_free(&clear_content);
2455 
2456  /* set 'replied' flag only if the user didn't change/remove
2457  * In-Reply-To: and References: headers during edit */
2458  if (flags & SEND_REPLY)
2459  {
2460  if (cur && ctx)
2461  mutt_set_flag(ctx->mailbox, cur, MUTT_REPLIED, is_reply(cur, msg));
2462  else if (!(flags & SEND_POSTPONED) && ctx && ctx->mailbox &&
2463  (ctx->mailbox->msg_tagged != 0))
2464  {
2465  STAILQ_FOREACH(en, el, entries)
2466  {
2467  mutt_set_flag(ctx->mailbox, en->email, MUTT_REPLIED, is_reply(en->email, msg));
2468  }
2469  }
2470  }
2471 
2472  rc = 0;
2473 
2474 cleanup:
2475 
2476  if (flags & SEND_POSTPONED)
2477  {
2478  if (WithCrypto & APPLICATION_PGP)
2479  {
2480  FREE(&C_PgpSignAs);
2481  C_PgpSignAs = pgp_signas;
2482  }
2483  if (WithCrypto & APPLICATION_SMIME)
2484  {
2485  FREE(&C_SmimeSignAs);
2486  C_SmimeSignAs = smime_signas;
2487  }
2488  }
2489 
2490  mutt_file_fclose(&fp_tmp);
2491  if (!(flags & SEND_NO_FREE_HEADER))
2492  mutt_email_free(&msg);
2493 
2494  FREE(&finalpath);
2495  return rc;
2496 }
#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:784
bool C_Hdrs
Config: Add custom headers to outgoing mail.
Definition: send.c:108
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:68
struct Body * mutt_remove_multipart(struct Body *b)
Extract the multipart body if it exists.
Definition: sendlib.c:1713
#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:89
static void fix_end_of_file(const char *data)
Ensure a file ends with a linefeed.
Definition: send.c:1344
unsigned char C_AbortNoattach
Config: Abort sending the email if attachments are missing.
Definition: send.c:84
int mutt_builtin_editor(const char *path, struct Email *msg, struct Email *cur)
Show the user the built-in editor.
Definition: edit.c:399
static bool search_attach_keyword(char *filename)
Search an email for &#39;attachment&#39; keywords.
Definition: send.c:1431
&#39;NNTP&#39; (Usenet) Mailbox type
Definition: magic.h:41
void mutt_pretty_mailbox(char *s, size_t buflen)
Shorten a mailbox path using &#39;~&#39; or &#39;=&#39;.
Definition: muttlib.c:605
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:149
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:3369
static int send_message(struct Email *msg)
Send an email.
Definition: send.c:1235
#define mutt_message(...)
Definition: logging.h:87
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:1631
void mutt_expand_aliases_env(struct Envelope *env)
Expand aliases in all the fields of an Envelope.
Definition: alias.c:312
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:905
#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:405
#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:248
#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:87
WHERE bool C_PgpAutoinline
Config: Use old-style inline PGP messages (not recommended)
Definition: globals.h:283
struct Body * next
next attachment in the list
Definition: body.h:58
WHERE unsigned char C_Copy
Config: Save outgoing emails to $record.
Definition: globals.h:189
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:93
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:238
#define SEC_ENCRYPT
Email is encrypted.
Definition: ncrypt.h:120
#define SEND_POSTPONED
Recall a postponed email.
Definition: send.h:90
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:882
bool C_CryptReplysign
Config: Sign replies to signed messages.
Definition: send.c:96
void mutt_select_fcc(char *path, size_t pathlen, struct Email *e)
Select the FCC path for an email.
Definition: hook.c:559
int url_parse_mailto(struct Envelope *e, char **body, const char *src)
Parse a mailto:// url.
Definition: mutt_url.c:47
Messages that have been replied to.
Definition: mutt.h:97
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:2884
unsigned int disposition
content-disposition
Definition: body.h:72
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:279
bool C_CryptAutosmime
Config: Allow automatic SMIME functions.
Definition: send.c:94
#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:1166
void mutt_sleep(short s)
Sleep for a while.
Definition: muttlib.c:1471
WHERE bool C_EditHeaders
Config: Let the user edit the email headers whilst editing an email.
Definition: globals.h:216
struct Mailbox * mailbox
Definition: context.h:51
unsigned char C_Recall
Config: Recall postponed mesaages when asked to compose a message.
Definition: send.c:118
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:86
enum MailboxType magic
mailbox type
Definition: mailbox.h:106
struct Address * mutt_addr_copy(struct Address *addr)
Copy the real address.
Definition: address.c:712
void mutt_update_encoding(struct Body *a)
Update the encoding type.
Definition: sendlib.c:1428
static void process_user_recips(struct Envelope *env)
Process the user headers.
Definition: send.c:378
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:1327
int crypt_get_keys(struct Email *msg, char **keylist, bool oppenc_mode)
Check we have all the keys we need.
Definition: crypt.c:914
WHERE bool C_Autoedit
Config: Skip the initial compose menu and edit the email.
Definition: globals.h:206
#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:1413
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:1473
void * mdata
driver specific data
Definition: mailbox.h:137
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:1687
#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:985
bool C_FastReply
Config: Don&#39;t prompt for the recipients and subject when replying/forwarding.
Definition: send.c:99
#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:2922
#define mutt_mktemp(buf, buflen)
Definition: muttlib.h:72
#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:1200
int mutt_protect(struct Email *msg, char *keylist)
Encrypt and/or sign a message.
Definition: crypt.c:168
WHERE bool C_CryptOpportunisticEncrypt
Config: Enable encryption when the recipient&#39;s key is available.
Definition: globals.h:275
bool C_ReverseName
Config: Set the &#39;From&#39; from the address the email was sent to.
Definition: send.c:122
#define PATH_MAX
Definition: mutt.h:48
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:883
void mutt_encode_descriptions(struct Body *b, bool recurse)
rfc2047 encode the content-descriptions
Definition: send.c:1310
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:107
struct Body * parts
parts of a multipart or message/rfc822
Definition: body.h:59
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:975
int msg_tagged
how many messages are tagged?
Definition: mailbox.h:98
#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
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:114
#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:126
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:105
unsigned int type
content-type primary type
Definition: body.h:70
#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:95
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:546
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:263
void mutt_parse_content_type(const char *s, struct Body *ct)
Parse a content type.
Definition: parse.c:432
void mutt_env_to_local(struct Envelope *env)
Convert an Envelope&#39;s Address fields to local format.
Definition: envelope.c:203
WHERE bool C_ResumeDraftFiles
Config: Process draft files like postponed messages.
Definition: globals.h:253
char * mutt_param_get(const struct ParameterList *p, const char *s)
Find a matching Parameter.
Definition: parameter.c:81
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:73
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:383
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:88
bool mutt_needs_mailcap(struct Body *m)
Does this type need a mailcap entry do display.
Definition: muttlib.c:399
bool unlink
flag to indicate the file named by "filename" should be unlink()ed before free()ing this structure ...
Definition: body.h:74
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:268
int mutt_str_strcasecmp(const char *a, const char *b)
Compare two strings ignoring case, safely.
Definition: string.c:624
WHERE char * C_Editor
Config: External command to use as an email editor.
Definition: globals.h:112
bool C_UseFrom
Config: Set the &#39;From&#39; header for outgoing mail.
Definition: send.c:127
#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_file_copy_stream(FILE *fp_in, FILE *fp_out)
Copy the contents of one file into another.
Definition: file.c:263
List of Emails.
Definition: email.h:121
WHERE char * C_Realname
Config: Real name of the user.
Definition: globals.h:144
#define mutt_debug(LEVEL,...)
Definition: logging.h:85
void mutt_message_hook(struct Mailbox *m, struct Email *e, HookFlags type)
Perform a message hook.
Definition: hook.c:441
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:171
void mutt_addr_free(struct Address **p)
Free a list of Addresses.
Definition: address.c:446
WHERE char * C_SmimeSignAs
Config: Use this alternative key for signing messages.
Definition: globals.h:175
static void append_signature(FILE *fp)
Append a signature to an email.
Definition: send.c:133
char * C_ContentType
Config: Default "Content-Type" for newly composed messages.
Definition: send.c:90
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:611
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_addr_has_recips(struct Address *a)
Count the number of Addresses with valid recipients.
Definition: address.c:864
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:97
bool C_NmRecord
Config: (notmuch) If the &#39;record&#39; mailbox (sent mail) should be indexed.
Definition: send.c:113
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition: ncrypt.h:130
bool C_CryptAutopgp
Config: Allow automatic PGP functions.
Definition: send.c:92
bool C_CryptAutoencrypt
Config: Automatically PGP encrypt all outgoing mail.
Definition: send.c:91
bool C_ReplyWithXorig
Config: Create &#39;From&#39; header from &#39;X-Original-To&#39; header.
Definition: send.c:121

+ 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 84 of file send.c.

struct Regex* C_AbortNoattachRegex

Config: Regex to match text indicating attachments are expected.

Definition at line 85 of file send.c.

unsigned char C_AbortNosubject

Config: Abort creating the email if subject is missing.

Definition at line 86 of file send.c.

unsigned char C_AbortUnmodified

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

Definition at line 87 of file send.c.

bool C_AskFollowUp

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

Definition at line 88 of file send.c.

bool C_AskXCommentTo

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

Definition at line 89 of file send.c.

char* C_ContentType

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

Definition at line 90 of file send.c.

bool C_CryptAutoencrypt

Config: Automatically PGP encrypt all outgoing mail.

Definition at line 91 of file send.c.

bool C_CryptAutopgp

Config: Allow automatic PGP functions.

Definition at line 92 of file send.c.

bool C_CryptAutosign

Config: Automatically PGP sign all outgoing mail.

Definition at line 93 of file send.c.

bool C_CryptAutosmime

Config: Allow automatic SMIME functions.

Definition at line 94 of file send.c.

bool C_CryptReplyencrypt

Config: Encrypt replies to encrypted messages.

Definition at line 95 of file send.c.

bool C_CryptReplysign

Config: Sign replies to signed messages.

Definition at line 96 of file send.c.

bool C_CryptReplysignencrypted

Config: Sign replies to encrypted messages.

Definition at line 97 of file send.c.

char* C_EmptySubject

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

Definition at line 98 of file send.c.

bool C_FastReply

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

Definition at line 99 of file send.c.

unsigned char C_FccAttach

Config: Save send message with all their attachments.

Definition at line 100 of file send.c.

bool C_FccClear

Config: Save sent messages unencrypted and unsigned.

Definition at line 101 of file send.c.

bool C_FollowupTo

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

Definition at line 102 of file send.c.

char* C_ForwardAttributionIntro

Config: Prefix message for forwarded messages.

Definition at line 103 of file send.c.

char* C_ForwardAttributionTrailer

Config: Suffix message for forwarded messages.

Definition at line 104 of file send.c.

unsigned char C_ForwardEdit

Config: Automatically start the editor when forwarding a message.

Definition at line 105 of file send.c.

char* C_ForwardFormat

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

Definition at line 106 of file send.c.

bool C_ForwardReferences

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

Definition at line 107 of file send.c.

bool C_Hdrs

Config: Add custom headers to outgoing mail.

Definition at line 108 of file send.c.

unsigned char C_HonorFollowupTo

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

Definition at line 109 of file send.c.

bool C_IgnoreListReplyTo

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

Definition at line 110 of file send.c.

unsigned char C_Include

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

Definition at line 111 of file send.c.

bool C_Metoo

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

Definition at line 112 of file send.c.

bool C_NmRecord

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

Definition at line 113 of file send.c.

bool C_PgpReplyinline

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

Definition at line 114 of file send.c.

char* C_PostIndentString

Config: Suffix message to add after reply text.

Definition at line 115 of file send.c.

bool C_PostponeEncrypt

Config: Self-encrypt postponed messages.

Definition at line 116 of file send.c.

char* C_PostponeEncryptAs

Config: Fallback encryption key for postponed messages.

Definition at line 117 of file send.c.

unsigned char C_Recall

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

Definition at line 118 of file send.c.

bool C_ReplySelf

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

Definition at line 119 of file send.c.

unsigned char C_ReplyTo

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

Definition at line 120 of file send.c.

bool C_ReplyWithXorig

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

Definition at line 121 of file send.c.

bool C_ReverseName

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

Definition at line 122 of file send.c.

bool C_ReverseRealname

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

Definition at line 123 of file send.c.

bool C_SigDashes

Config: Insert '– ' before the signature.

Definition at line 124 of file send.c.

char* C_Signature

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

Definition at line 125 of file send.c.

bool C_SigOnTop

Config: Insert the signature before the quoted text.

Definition at line 126 of file send.c.

bool C_UseFrom

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

Definition at line 127 of file send.c.