NeoMutt  2020-03-20-65-g141838
Teaching an old dog new tricks
DOXYGEN
send.c File Reference

Prepare and send an email. More...

#include "config.h"
#include <errno.h>
#include <locale.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <time.h>
#include <unistd.h>
#include "mutt/lib.h"
#include "address/lib.h"
#include "config/lib.h"
#include "email/lib.h"
#include "core/lib.h"
#include "gui/lib.h"
#include "mutt.h"
#include "send.h"
#include "alias.h"
#include "compose.h"
#include "context.h"
#include "copy.h"
#include "edit.h"
#include "globals.h"
#include "handler.h"
#include "hdrline.h"
#include "hook.h"
#include "init.h"
#include "mutt_attach.h"
#include "mutt_body.h"
#include "mutt_header.h"
#include "mutt_logging.h"
#include "mutt_parse.h"
#include "muttlib.h"
#include "options.h"
#include "pattern.h"
#include "protos.h"
#include "recvattach.h"
#include "rfc3676.h"
#include "sendlib.h"
#include "smtp.h"
#include "sort.h"
#include "ncrypt/lib.h"
#include "mx.h"
#include "nntp/lib.h"
#include "remailer.h"
#include "notmuch/lib.h"
#include "imap/lib.h"
#include "autocrypt/lib.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 void remove_user (struct AddressList *al, bool leave_only)
 Remove any address which matches the current user. More...
 
static void add_mailing_lists (struct AddressList *out, const struct AddressList *t, const struct AddressList *c)
 Search Address lists for mailing lists. More...
 
int mutt_edit_address (struct AddressList *al, const char *field, bool expand_aliases)
 Edit an email address. More...
 
static int edit_envelope (struct Envelope *en, SendFlags flags)
 Edit Envelope fields. More...
 
static char * nntp_get_header (const char *s)
 Get the trimmed header. More...
 
static void process_user_recips (struct Envelope *env)
 Process the user headers. More...
 
static void process_user_header (struct Envelope *env)
 Process the user headers. More...
 
void mutt_forward_intro (struct Mailbox *m, struct Email *e, FILE *fp)
 Add the "start of forwarded message" text. More...
 
void mutt_forward_trailer (struct Mailbox *m, struct Email *e, FILE *fp)
 Add a "end of forwarded message" text. More...
 
static int include_forward (struct Mailbox *m, struct Email *e, FILE *fp_out)
 Write out a forwarded message. More...
 
static int inline_forward_attachments (struct Mailbox *m, struct Email *e, struct Body ***plast, int *forwardq)
 Add attachments to an email, inline. More...
 
static int mutt_inline_forward (struct Mailbox *m, struct Email *e_edit, struct Email *e_cur, FILE *out)
 Forward attachments, inline. More...
 
void mutt_make_attribution (struct Mailbox *m, struct Email *e, FILE *fp_out)
 Add "on DATE, PERSON wrote" header. More...
 
void mutt_make_post_indent (struct Mailbox *m, struct Email *e, FILE *fp_out)
 Add suffix to replied email text. More...
 
static int include_reply (struct Mailbox *m, struct Email *e, FILE *fp_out)
 Generate the reply text for an email. More...
 
static const struct AddressList * choose_default_to (const struct Address *from, const struct Envelope *env)
 Pick the best 'to:' value. More...
 
static int default_to (struct AddressList *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 *e)
 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 *e, 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 void set_reverse_name (struct AddressList *al, 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 *e)
 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 *e_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 *e, struct Buffer *fcc, 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 *e_post, struct Email *e_cur, const char *fcc, SendFlags flags)
 Save an Email for another day. More...
 
int ci_send_message (SendFlags flags, struct Email *e_templ, 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_FccBeforeSend
 Config: Save FCCs before sending the message. 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
  • Pietro Cerutti

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

◆ append_signature()

static void append_signature ( FILE *  fp)
static

Append a signature to an email.

Parameters
fpFile to write to

Definition at line 140 of file send.c.

141 {
142  FILE *fp_tmp = NULL;
143  pid_t pid;
144 
145  if (C_Signature && (fp_tmp = mutt_open_read(C_Signature, &pid)))
146  {
147  if (C_SigDashes)
148  fputs("\n-- \n", fp);
149  mutt_file_copy_stream(fp_tmp, fp);
150  mutt_file_fclose(&fp_tmp);
151  if (pid != -1)
152  filter_wait(pid);
153  }
154 }
bool C_SigDashes
Config: Insert &#39;– &#39; before the signature.
Definition: send.c:131
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:153
int mutt_file_copy_stream(FILE *fp_in, FILE *fp_out)
Copy the contents of one file into another.
Definition: file.c:271
FILE * mutt_open_read(const char *path, pid_t *thepid)
Run a command to read from.
Definition: muttlib.c:1393
int filter_wait(pid_t pid)
Wait for the exit of a process and return its status.
Definition: filter.c:217
char * C_Signature
Config: File containing a signature to append to all mail.
Definition: send.c:132
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ remove_user()

static void remove_user ( struct AddressList *  al,
bool  leave_only 
)
static

Remove any address which matches the current user.

Parameters
alList of addresses
leave_onlyIf set, don't remove the user's address if it it the only one in the list

Definition at line 162 of file send.c.

163 {
164  struct Address *a = NULL, *tmp = NULL;
165  TAILQ_FOREACH_SAFE(a, al, entries, tmp)
166  {
167  if (mutt_addr_is_user(a) && (!leave_only || TAILQ_NEXT(a, entries)))
168  {
169  TAILQ_REMOVE(al, a, entries);
170  mutt_addr_free(&a);
171  }
172  }
173 }
#define TAILQ_FOREACH_SAFE(var, head, field, tvar)
Definition: queue.h:728
An email address.
Definition: address.h:34
void mutt_addr_free(struct Address **ptr)
Free a single Address.
Definition: address.c:440
#define TAILQ_REMOVE(head, elm, field)
Definition: queue.h:834
bool mutt_addr_is_user(const struct Address *addr)
Does the address belong to the user.
Definition: alias.c:686
#define TAILQ_NEXT(elm, field)
Definition: queue.h:825
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ add_mailing_lists()

static void add_mailing_lists ( struct AddressList *  out,
const struct AddressList *  t,
const struct AddressList *  c 
)
static

Search Address lists for mailing lists.

Parameters
outAddress list where to append matching mailing lists
t'To' Address list
c'Cc' Address list

Definition at line 181 of file send.c.

183 {
184  const struct AddressList *const als[] = { t, c };
185 
186  for (size_t i = 0; i < mutt_array_size(als); ++i)
187  {
188  const struct AddressList *al = als[i];
189  struct Address *a = NULL;
190  TAILQ_FOREACH(a, al, entries)
191  {
192  if (!a->group && mutt_is_mail_list(a))
193  {
195  }
196  }
197  }
198 }
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:718
bool mutt_is_mail_list(const struct Address *addr)
Is this the email address of a mailing list? - Implements addr_predicate_t.
Definition: hdrline.c:114
An email address.
Definition: address.h:34
struct Address * mutt_addr_copy(const struct Address *addr)
Copy the real address.
Definition: address.c:707
#define mutt_array_size(x)
Definition: memory.h:33
bool group
Group mailbox?
Definition: address.h:38
void mutt_addrlist_append(struct AddressList *al, struct Address *a)
Append an Address to an AddressList.
Definition: address.c:1402
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_edit_address()

int mutt_edit_address ( struct AddressList *  al,
const char *  field,
bool  expand_aliases 
)

Edit an email address.

Parameters
[in,out]alAddressList to edit
[in]fieldPrompt for user
[in]expand_aliasesIf true, expand Address aliases
Return values
0Success
-1Failure

Definition at line 208 of file send.c.

209 {
210  char buf[8192];
211  char *err = NULL;
212  int idna_ok = 0;
213 
214  do
215  {
216  buf[0] = '\0';
218  mutt_addrlist_write(al, buf, sizeof(buf), false);
219  if (mutt_get_field(field, buf, sizeof(buf), MUTT_ALIAS) != 0)
220  return -1;
222  mutt_addrlist_parse2(al, buf);
223  if (expand_aliases)
225  idna_ok = mutt_addrlist_to_intl(al, &err);
226  if (idna_ok != 0)
227  {
228  mutt_error(_("Bad IDN: '%s'"), err);
229  FREE(&err);
230  }
231  } while (idna_ok != 0);
232  return 0;
233 }
void mutt_expand_aliases(struct AddressList *al)
Expand aliases in a List of Addresses.
Definition: alias.c:303
#define MUTT_ALIAS
Do alias "completion" by calling up the alias-menu.
Definition: mutt.h:57
int mutt_addrlist_to_local(struct AddressList *al)
Convert an Address list from Punycode.
Definition: address.c:1299
void mutt_addrlist_clear(struct AddressList *al)
Unlink and free all Address in an AddressList.
Definition: address.c:1382
#define _(a)
Definition: message.h:28
int mutt_addrlist_parse2(struct AddressList *al, const char *s)
Parse a list of email addresses.
Definition: address.c:607
#define mutt_get_field(field, buf, buflen, complete)
Definition: curs_lib.h:90
int mutt_addrlist_to_intl(struct AddressList *al, char **err)
Convert an Address list to Punycode.
Definition: address.c:1217
#define mutt_error(...)
Definition: logging.h:84
#define FREE(x)
Definition: memory.h:40
size_t mutt_addrlist_write(const struct AddressList *al, char *buf, size_t buflen, bool display)
Write an Address to a buffer.
Definition: address.c:1138
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ edit_envelope()

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

243 {
244  char buf[8192];
245 
246 #ifdef USE_NNTP
247  if (OptNewsSend)
248  {
249  if (en->newsgroups)
250  mutt_str_strfcpy(buf, en->newsgroups, sizeof(buf));
251  else
252  buf[0] = '\0';
253  if (mutt_get_field("Newsgroups: ", buf, sizeof(buf), MUTT_COMP_NO_FLAGS) != 0)
254  return -1;
255  FREE(&en->newsgroups);
256  en->newsgroups = mutt_str_strdup(buf);
257 
258  if (en->followup_to)
259  mutt_str_strfcpy(buf, en->followup_to, sizeof(buf));
260  else
261  buf[0] = '\0';
262  if (C_AskFollowUp &&
263  (mutt_get_field("Followup-To: ", buf, sizeof(buf), MUTT_COMP_NO_FLAGS) != 0))
264  {
265  return -1;
266  }
267  FREE(&en->followup_to);
268  en->followup_to = mutt_str_strdup(buf);
269 
270  if (en->x_comment_to)
271  mutt_str_strfcpy(buf, en->x_comment_to, sizeof(buf));
272  else
273  buf[0] = '\0';
274  if (C_XCommentTo && C_AskXCommentTo &&
275  (mutt_get_field("X-Comment-To: ", buf, sizeof(buf), MUTT_COMP_NO_FLAGS) != 0))
276  {
277  return -1;
278  }
279  FREE(&en->x_comment_to);
280  en->x_comment_to = mutt_str_strdup(buf);
281  }
282  else
283 #endif
284  {
285  if ((mutt_edit_address(&en->to, _("To: "), true) == -1) || TAILQ_EMPTY(&en->to))
286  return -1;
287  if (C_Askcc && (mutt_edit_address(&en->cc, _("Cc: "), true) == -1))
288  return -1;
289  if (C_Askbcc && (mutt_edit_address(&en->bcc, _("Bcc: "), true) == -1))
290  return -1;
292  (mutt_edit_address(&en->from, "From: ", true) == -1))
293  {
294  return -1;
295  }
296  }
297 
298  if (en->subject)
299  {
300  if (C_FastReply)
301  return 0;
302  mutt_str_strfcpy(buf, en->subject, sizeof(buf));
303  }
304  else
305  {
306  const char *p = NULL;
307 
308  buf[0] = '\0';
309  struct ListNode *uh = NULL;
310  STAILQ_FOREACH(uh, &UserHeader, entries)
311  {
312  size_t plen = mutt_str_startswith(uh->data, "subject:", CASE_IGNORE);
313  if (plen)
314  {
315  p = mutt_str_skip_email_wsp(uh->data + plen);
316  mutt_str_strfcpy(buf, p, sizeof(buf));
317  }
318  }
319  }
320 
321  if ((mutt_get_field(_("Subject: "), buf, sizeof(buf), MUTT_COMP_NO_FLAGS) != 0) ||
322  (!buf[0] &&
323  (query_quadoption(C_AbortNosubject, _("No subject, abort?")) != MUTT_NO)))
324  {
325  mutt_message(_("No subject, aborting"));
326  return -1;
327  }
328  mutt_str_replace(&en->subject, buf);
329 
330  return 0;
331 }
enum QuadOption query_quadoption(enum QuadOption opt, const char *prompt)
Ask the user a quad-question.
Definition: init.c:1099
#define mutt_message(...)
Definition: logging.h:83
struct AddressList bcc
Email&#39;s &#39;Bcc&#39; list.
Definition: envelope.h:60
static size_t plen
Length of cached packet.
Definition: pgppacket.c:39
#define _(a)
Definition: message.h:28
#define mutt_get_field(field, buf, buflen, complete)
Definition: curs_lib.h:90
#define MUTT_COMP_NO_FLAGS
No flags are set.
Definition: mutt.h:56
unsigned char C_AbortNosubject
Config: Abort creating the email if subject is missing.
Definition: send.c:92
struct AddressList from
Email&#39;s &#39;From&#39; list.
Definition: envelope.h:57
struct AddressList cc
Email&#39;s &#39;Cc&#39; list.
Definition: envelope.h:59
#define SEND_LIST_REPLY
Reply to mailing list.
Definition: send.h:90
bool C_FastReply
Config: Don&#39;t prompt for the recipients and subject when replying/forwarding.
Definition: send.c:105
char * x_comment_to
List of &#39;X-comment-to&#39; fields.
Definition: envelope.h:78
bool C_AskXCommentTo
Config: (nntp) Ask the user for the &#39;X-Comment-To&#39; field before editing.
Definition: send.c:95
User answered &#39;No&#39;, or assume &#39;No&#39;.
Definition: quad.h:39
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:773
Ignore case when comparing strings.
Definition: string2.h:68
char * mutt_str_skip_email_wsp(const char *s)
Skip over whitespace as defined by RFC5322.
Definition: string.c:799
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:349
#define SEND_REPLY
Reply to sender.
Definition: send.h:88
void mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition: string.c:453
bool C_AskFollowUp
Config: (nntp) Ask the user for follow-up groups before editing.
Definition: send.c:94
size_t mutt_str_startswith(const char *str, const char *prefix, enum CaseSensitivity cs)
Check whether a string starts with a prefix.
Definition: string.c:168
#define SEND_GROUP_REPLY
Reply to all.
Definition: send.h:89
char * data
String.
Definition: list.h:35
char * subject
Email&#39;s subject.
Definition: envelope.h:66
char * newsgroups
List of newsgroups.
Definition: envelope.h:75
WHERE bool C_XCommentTo
Config: (nntp) Add &#39;X-Comment-To&#39; header that contains article author.
Definition: globals.h:283
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:380
char * followup_to
List of &#39;followup-to&#39; fields.
Definition: envelope.h:77
#define FREE(x)
Definition: memory.h:40
struct AddressList to
Email&#39;s &#39;To&#39; list.
Definition: envelope.h:58
#define TAILQ_EMPTY(head)
Definition: queue.h:714
WHERE bool OptNewsSend
(pseudo) used to change behavior when posting
Definition: options.h:47
A List node for strings.
Definition: list.h:33
WHERE bool C_Askbcc
Config: Ask the user for the blind-carbon-copy recipients.
Definition: globals.h:197
int mutt_edit_address(struct AddressList *al, const char *field, bool expand_aliases)
Edit an email address.
Definition: send.c:208
WHERE bool C_Askcc
Config: Ask the user for the carbon-copy recipients.
Definition: globals.h:198
bool C_ReplyWithXorig
Config: Create &#39;From&#39; header from &#39;X-Original-To&#39; header.
Definition: send.c:128
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ nntp_get_header()

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

342 {
343  SKIPWS(s);
344  return mutt_str_strdup(s);
345 }
#define SKIPWS(ch)
Definition: string2.h:47
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:380
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ process_user_recips()

static void process_user_recips ( struct Envelope env)
static

Process the user headers.

Parameters
envEnvelope to populate

Definition at line 352 of file send.c.

353 {
354  struct ListNode *uh = NULL;
355  STAILQ_FOREACH(uh, &UserHeader, entries)
356  {
357  size_t plen;
358  if ((plen = mutt_str_startswith(uh->data, "to:", CASE_IGNORE)))
359  mutt_addrlist_parse(&env->to, uh->data + plen);
360  else if ((plen = mutt_str_startswith(uh->data, "cc:", CASE_IGNORE)))
361  mutt_addrlist_parse(&env->cc, uh->data + plen);
362  else if ((plen = mutt_str_startswith(uh->data, "bcc:", CASE_IGNORE)))
363  mutt_addrlist_parse(&env->bcc, uh->data + plen);
364 #ifdef USE_NNTP
365  else if ((plen = mutt_str_startswith(uh->data, "newsgroups:", CASE_IGNORE)))
366  env->newsgroups = nntp_get_header(uh->data + plen);
367  else if ((plen = mutt_str_startswith(uh->data, "followup-to:", CASE_IGNORE)))
368  env->followup_to = nntp_get_header(uh->data + plen);
369  else if ((plen = mutt_str_startswith(uh->data, "x-comment-to:", CASE_IGNORE)))
370  env->x_comment_to = nntp_get_header(uh->data + plen);
371 #endif
372  }
373 }
int mutt_addrlist_parse(struct AddressList *al, const char *s)
Parse a list of email addresses.
Definition: address.c:458
struct AddressList bcc
Email&#39;s &#39;Bcc&#39; list.
Definition: envelope.h:60
static char * nntp_get_header(const char *s)
Get the trimmed header.
Definition: send.c:341
static size_t plen
Length of cached packet.
Definition: pgppacket.c:39
struct AddressList cc
Email&#39;s &#39;Cc&#39; list.
Definition: envelope.h:59
char * x_comment_to
List of &#39;X-comment-to&#39; fields.
Definition: envelope.h:78
Ignore case when comparing strings.
Definition: string2.h:68
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:349
size_t mutt_str_startswith(const char *str, const char *prefix, enum CaseSensitivity cs)
Check whether a string starts with a prefix.
Definition: string.c:168
char * data
String.
Definition: list.h:35
char * newsgroups
List of newsgroups.
Definition: envelope.h:75
char * followup_to
List of &#39;followup-to&#39; fields.
Definition: envelope.h:77
struct AddressList to
Email&#39;s &#39;To&#39; list.
Definition: envelope.h:58
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:

◆ process_user_header()

static void process_user_header ( struct Envelope env)
static

Process the user headers.

Parameters
envEnvelope to populate

Definition at line 379 of file send.c.

380 {
381  struct ListNode *uh = NULL;
382  STAILQ_FOREACH(uh, &UserHeader, entries)
383  {
384  size_t plen;
385  if ((plen = mutt_str_startswith(uh->data, "from:", CASE_IGNORE)))
386  {
387  /* User has specified a default From: address. Remove default address */
388  mutt_addrlist_clear(&env->from);
389  mutt_addrlist_parse(&env->from, uh->data + plen);
390  }
391  else if ((plen = mutt_str_startswith(uh->data, "reply-to:", CASE_IGNORE)))
392  {
394  mutt_addrlist_parse(&env->reply_to, uh->data + plen);
395  }
396  else if ((plen = mutt_str_startswith(uh->data, "message-id:", CASE_IGNORE)))
397  {
398  char *tmp = mutt_extract_message_id(uh->data + plen, NULL);
399  if (mutt_addr_valid_msgid(tmp))
400  {
401  FREE(&env->message_id);
402  env->message_id = tmp;
403  }
404  else
405  FREE(&tmp);
406  }
407  else if (!mutt_str_startswith(uh->data, "to:", CASE_IGNORE) &&
408  !mutt_str_startswith(uh->data, "cc:", CASE_IGNORE) &&
409  !mutt_str_startswith(uh->data, "bcc:", CASE_IGNORE) &&
410 #ifdef USE_NNTP
411  !mutt_str_startswith(uh->data, "newsgroups:", CASE_IGNORE) &&
412  !mutt_str_startswith(uh->data, "followup-to:", CASE_IGNORE) &&
413  !mutt_str_startswith(uh->data, "x-comment-to:", CASE_IGNORE) &&
414 #endif
415  !mutt_str_startswith(uh->data, "supersedes:", CASE_IGNORE) &&
416  !mutt_str_startswith(uh->data, "subject:", CASE_IGNORE) &&
417  !mutt_str_startswith(uh->data, "return-path:", CASE_IGNORE))
418  {
420  }
421  }
422 }
struct AddressList reply_to
Email&#39;s &#39;reply-to&#39;.
Definition: envelope.h:62
int mutt_addrlist_parse(struct AddressList *al, const char *s)
Parse a list of email addresses.
Definition: address.c:458
void mutt_addrlist_clear(struct AddressList *al)
Unlink and free all Address in an AddressList.
Definition: address.c:1382
static size_t plen
Length of cached packet.
Definition: pgppacket.c:39
struct ListHead userhdrs
user defined headers
Definition: envelope.h:83
char * message_id
Message ID.
Definition: envelope.h:69
struct AddressList from
Email&#39;s &#39;From&#39; list.
Definition: envelope.h:57
struct ListNode * mutt_list_insert_tail(struct ListHead *h, char *s)
Append a string to the end of a List.
Definition: list.c:65
Ignore case when comparing strings.
Definition: string2.h:68
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:349
size_t mutt_str_startswith(const char *str, const char *prefix, enum CaseSensitivity cs)
Check whether a string starts with a prefix.
Definition: string.c:168
char * data
String.
Definition: list.h:35
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:380
bool mutt_addr_valid_msgid(const char *msgid)
Is this a valid Message ID?
Definition: address.c:755
#define FREE(x)
Definition: memory.h:40
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:359
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_forward_intro()

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

431 {
432  if (!C_ForwardAttributionIntro || !fp)
433  return;
434 
435  char buf[1024];
436  setlocale(LC_TIME, NONULL(C_AttributionLocale));
437  mutt_make_string(buf, sizeof(buf), 0, C_ForwardAttributionIntro, NULL, m, e);
438  setlocale(LC_TIME, "");
439  fputs(buf, fp);
440  fputs("\n\n", fp);
441 }
#define NONULL(x)
Definition: string2.h:37
char * C_ForwardAttributionIntro
Config: Prefix message for forwarded messages.
Definition: send.c:110
WHERE char * C_AttributionLocale
Config: Locale for dates in the attribution message.
Definition: globals.h:100
#define mutt_make_string(BUF, BUFLEN, COLS, S, CTX, M, E)
Definition: hdrline.h:61
+ Here is the caller graph for this function:

◆ mutt_forward_trailer()

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

450 {
451  if (!C_ForwardAttributionTrailer || !fp)
452  return;
453 
454  char buf[1024];
455  setlocale(LC_TIME, NONULL(C_AttributionLocale));
456  mutt_make_string(buf, sizeof(buf), 0, C_ForwardAttributionTrailer, NULL, m, e);
457  setlocale(LC_TIME, "");
458  fputc('\n', fp);
459  fputs(buf, fp);
460  fputc('\n', fp);
461 }
#define NONULL(x)
Definition: string2.h:37
WHERE char * C_AttributionLocale
Config: Locale for dates in the attribution message.
Definition: globals.h:100
#define mutt_make_string(BUF, BUFLEN, COLS, S, CTX, M, E)
Definition: hdrline.h:61
char * C_ForwardAttributionTrailer
Config: Suffix message for forwarded messages.
Definition: send.c:111
+ Here is the caller graph for this function:

◆ include_forward()

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

472 {
473  CopyHeaderFlags chflags = CH_DECODE;
475 
478 
479  if ((WithCrypto != 0) && (e->security & SEC_ENCRYPT) && C_ForwardDecode)
480  {
481  /* make sure we have the user's passphrase before proceeding... */
483  return -1;
484  }
485 
486  mutt_forward_intro(m, e, fp_out);
487 
488  if (C_ForwardDecode)
489  {
490  cmflags |= MUTT_CM_DECODE | MUTT_CM_CHARCONV;
491  if (C_Weed)
492  {
493  chflags |= CH_WEED | CH_REORDER;
494  cmflags |= MUTT_CM_WEED;
495  }
496  }
497  if (C_ForwardQuote)
498  cmflags |= MUTT_CM_PREFIX;
499 
500  mutt_copy_message(fp_out, m, e, cmflags, chflags, 0);
501  mutt_forward_trailer(m, e, fp_out);
502  return 0;
503 }
#define WithCrypto
Definition: lib.h:163
WHERE bool C_ForwardDecode
Config: Decode the message when forwarding it.
Definition: globals.h:214
#define SEC_ENCRYPT
Email is encrypted.
Definition: lib.h:125
void mutt_forward_intro(struct Mailbox *m, struct Email *e, FILE *fp)
Add the "start of forwarded message" text.
Definition: send.c:430
#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:49
int mutt_copy_message(FILE *fp_out, struct Mailbox *m, struct Email *e, CopyMessageFlags cmflags, CopyHeaderFlags chflags, int wraplen)
Copy a message from a Mailbox.
Definition: copy.c:812
#define MUTT_MESSAGE_HOOK
message-hook: run before displaying a message
Definition: hook.h:52
uint16_t CopyMessageFlags
Flags for mutt_copy_message(), e.g. MUTT_CM_NOHEADER.
Definition: copy.h:31
#define MUTT_CM_NO_FLAGS
No flags are set.
Definition: copy.h:34
bool crypt_valid_passphrase(SecurityFlags flags)
Check that we have a usable passphrase, ask if not.
Definition: crypt.c:146
#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
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/lib.h pgplib...
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:449
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:215
void mutt_message_hook(struct Mailbox *m, struct Email *e, HookFlags type)
Perform a message hook.
Definition: hook.c:579
bool C_Weed
Config: Filter headers when displaying/forwarding/printing/replying.
Definition: email_globals.c:40
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ inline_forward_attachments()

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

Add attachments to an email, inline.

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

Definition at line 514 of file send.c.

516 {
517  struct Body **last = *plast;
518  struct Body *body = NULL;
519  struct Message *msg = NULL;
520  struct AttachCtx *actx = NULL;
521  int rc = 0, i;
522 
525 
526  msg = mx_msg_open(m, e->msgno);
527  if (!msg)
528  return -1;
529 
530  actx = mutt_mem_calloc(1, sizeof(*actx));
531  actx->email = e;
532  actx->fp_root = msg->fp;
533 
534  mutt_generate_recvattach_list(actx, actx->email, actx->email->content,
535  actx->fp_root, -1, 0, 0);
536 
537  for (i = 0; i < actx->idxlen; i++)
538  {
539  body = actx->idx[i]->content;
540  if ((body->type != TYPE_MULTIPART) && !mutt_can_decode(body) &&
541  !((body->type == TYPE_APPLICATION) &&
542  ((mutt_str_strcasecmp(body->subtype, "pgp-signature") == 0) ||
543  (mutt_str_strcasecmp(body->subtype, "x-pkcs7-signature") == 0) ||
544  (mutt_str_strcasecmp(body->subtype, "pkcs7-signature") == 0))))
545  {
546  /* Ask the quadoption only once */
547  if (*forwardq == -1)
548  {
550  /* L10N: This is the prompt for $forward_attachments.
551  When inline forwarding ($mime_forward answered "no"), this prompts
552  whether to add non-decodable attachments from the original email.
553  Text/plain parts and the like will already be included in the
554  message contents, but other attachment, such as PDF files, will also
555  be added as attachments to the new mail, if this is answered yes. */
556  _("Forward attachments?"));
557  if (*forwardq != MUTT_YES)
558  {
559  if (*forwardq == -1)
560  rc = -1;
561  goto cleanup;
562  }
563  }
564  if (mutt_body_copy(actx->idx[i]->fp, last, body) == -1)
565  {
566  rc = -1;
567  goto cleanup;
568  }
569  last = &((*last)->next);
570  }
571  }
572 
573 cleanup:
574  *plast = last;
575  mx_msg_close(m, &msg);
576  mutt_actx_free(&actx);
577  return rc;
578 }
void mutt_actx_free(struct AttachCtx **ptr)
Free an Attachment Context.
Definition: attach.c:140
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
void mutt_generate_recvattach_list(struct AttachCtx *actx, struct Email *e, struct Body *parts, FILE *fp, int parent_type, int level, bool decrypted)
Create a list of attachments.
Definition: recvattach.c:1223
enum QuadOption query_quadoption(enum QuadOption opt, const char *prompt)
Ask the user a quad-question.
Definition: init.c:1099
struct Email * email
Used by recvattach for updating.
Definition: attach.h:51
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:40
struct Body * content
List of MIME parts.
Definition: email.h:90
FILE * fp_root
Used by recvattach for updating.
Definition: attach.h:52
void mutt_parse_mime_message(struct Mailbox *m, struct Email *e)
Parse a MIME email.
Definition: mutt_parse.c:49
#define _(a)
Definition: message.h:28
short idxlen
Number of attachmentes.
Definition: attach.h:55
#define MUTT_MESSAGE_HOOK
message-hook: run before displaying a message
Definition: hook.h:52
The body of an email.
Definition: body.h:34
int mx_msg_close(struct Mailbox *m, struct Message **msg)
Close a message.
Definition: mx.c:1171
int mutt_body_copy(FILE *fp, struct Body **tgt, struct Body *src)
Create a send-mode duplicate from a receive-mode body.
Definition: mutt_body.c:48
char * subtype
content-type subtype
Definition: body.h:37
A local copy of an email.
Definition: mx.h:83
bool mutt_can_decode(struct Body *a)
Will decoding the attachment produce any output.
Definition: handler.c:1753
FILE * fp
Used in the recvattach menu.
Definition: attach.h:37
unsigned int type
content-type primary type
Definition: body.h:65
Type: &#39;multipart/*&#39;.
Definition: mime.h:37
struct Body * content
Attachment.
Definition: attach.h:36
int mutt_str_strcasecmp(const char *a, const char *b)
Compare two strings ignoring case, safely.
Definition: string.c:651
FILE * fp
pointer to the message data
Definition: mx.h:85
void mutt_message_hook(struct Mailbox *m, struct Email *e, HookFlags type)
Perform a message hook.
Definition: hook.c:579
A set of attachments.
Definition: attach.h:49
struct AttachPtr ** idx
Array of attachments.
Definition: attach.h:54
struct Message * mx_msg_open(struct Mailbox *m, int msgno)
return a stream pointer for a message
Definition: mx.c:1123
Type: &#39;application/*&#39;.
Definition: mime.h:33
int msgno
Number displayed to the user.
Definition: email.h:86
WHERE unsigned char C_ForwardAttachments
Config: Forward attachments when forwarding a message.
Definition: globals.h:182
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_inline_forward()

static int mutt_inline_forward ( struct Mailbox m,
struct Email e_edit,
struct Email e_cur,
FILE *  out 
)
static

Forward attachments, inline.

Parameters
mMailbox
e_editEmail to alter
e_curCurrent Email
outFile
Return values
0Success
-1Error

Definition at line 589 of file send.c.

591 {
592  int forwardq = -1;
593  struct Body **last = NULL;
594 
595  if (e_cur)
596  include_forward(m, e_cur, out);
597  else
598  {
599  for (int i = 0; i < m->vcount; i++)
600  {
601  struct Email *e = mutt_get_virt_email(m, i);
602  if (!e)
603  continue;
604  if (e->tagged)
605  include_forward(m, e, out);
606  }
607  }
608 
610  {
611  last = &e_edit->content;
612  while (*last)
613  last = &((*last)->next);
614 
615  if (e_cur)
616  {
617  if (inline_forward_attachments(m, e_cur, &last, &forwardq) != 0)
618  return -1;
619  }
620  else
621  {
622  for (int i = 0; i < m->vcount; i++)
623  {
624  struct Email *e = mutt_get_virt_email(m, i);
625  if (!e)
626  continue;
627  if (e->tagged)
628  {
629  if (inline_forward_attachments(m, e, &last, &forwardq) != 0)
630  return -1;
631  if (forwardq == MUTT_NO)
632  break;
633  }
634  }
635  }
636  }
637 
638  return 0;
639 }
The envelope/body of an email.
Definition: email.h:37
struct Email * mutt_get_virt_email(struct Mailbox *m, int vnum)
Get a virtual Email.
Definition: context.c:413
WHERE bool C_ForwardDecode
Config: Decode the message when forwarding it.
Definition: globals.h:214
struct Body * content
List of MIME parts.
Definition: email.h:90
static int inline_forward_attachments(struct Mailbox *m, struct Email *e, struct Body ***plast, int *forwardq)
Add attachments to an email, inline.
Definition: send.c:514
int vcount
The number of virtual messages.
Definition: mailbox.h:102
The body of an email.
Definition: body.h:34
bool tagged
Email is tagged.
Definition: email.h:44
static int include_forward(struct Mailbox *m, struct Email *e, FILE *fp_out)
Write out a forwarded message.
Definition: send.c:471
User answered &#39;No&#39;, or assume &#39;No&#39;.
Definition: quad.h:39
WHERE unsigned char C_ForwardAttachments
Config: Forward attachments when forwarding a message.
Definition: globals.h:182
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_make_attribution()

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

648 {
649  if (!C_Attribution || !fp_out)
650  return;
651 
652  char buf[1024];
653  setlocale(LC_TIME, NONULL(C_AttributionLocale));
654  mutt_make_string(buf, sizeof(buf), 0, C_Attribution, NULL, m, e);
655  setlocale(LC_TIME, "");
656  fputs(buf, fp_out);
657  fputc('\n', fp_out);
658 }
#define NONULL(x)
Definition: string2.h:37
WHERE char * C_AttributionLocale
Config: Locale for dates in the attribution message.
Definition: globals.h:100
#define mutt_make_string(BUF, BUFLEN, COLS, S, CTX, M, E)
Definition: hdrline.h:61
WHERE char * C_Attribution
Config: Message to start a reply, "On DATE, PERSON wrote:".
Definition: globals.h:99
+ Here is the caller graph for this function:

◆ mutt_make_post_indent()

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

667 {
668  if (!C_PostIndentString || !fp_out)
669  return;
670 
671  char buf[256];
672  mutt_make_string(buf, sizeof(buf), 0, C_PostIndentString, NULL, m, e);
673  fputs(buf, fp_out);
674  fputc('\n', fp_out);
675 }
#define mutt_make_string(BUF, BUFLEN, COLS, S, CTX, M, E)
Definition: hdrline.h:61
char * C_PostIndentString
Config: Suffix message to add after reply text.
Definition: send.c:122
+ Here is the caller graph for this function:

◆ include_reply()

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

686 {
687  CopyMessageFlags cmflags =
689  CopyHeaderFlags chflags = CH_DECODE;
690 
691  if ((WithCrypto != 0) && (e->security & SEC_ENCRYPT))
692  {
693  /* make sure we have the user's passphrase before proceeding... */
695  return -1;
696  }
697 
700 
701  mutt_make_attribution(m, e, fp_out);
702 
703  if (!C_Header)
704  cmflags |= MUTT_CM_NOHEADER;
705  if (C_Weed)
706  {
707  chflags |= CH_WEED | CH_REORDER;
708  cmflags |= MUTT_CM_WEED;
709  }
710 
711  mutt_copy_message(fp_out, m, e, cmflags, chflags, 0);
712 
713  mutt_make_post_indent(m, e, fp_out);
714 
715  return 0;
716 }
#define WithCrypto
Definition: lib.h:163
#define SEC_ENCRYPT
Email is encrypted.
Definition: lib.h:125
#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:49
int mutt_copy_message(FILE *fp_out, struct Mailbox *m, struct Email *e, CopyMessageFlags cmflags, CopyHeaderFlags chflags, int wraplen)
Copy a message from a Mailbox.
Definition: copy.c:812
#define MUTT_MESSAGE_HOOK
message-hook: run before displaying a message
Definition: hook.h:52
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:666
#define MUTT_CM_REPLYING
Replying the message.
Definition: copy.h:43
bool crypt_valid_passphrase(SecurityFlags flags)
Check that we have a usable passphrase, ask if not.
Definition: crypt.c:146
#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:216
#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-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/lib.h pgplib...
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:579
#define MUTT_CM_NOHEADER
Don&#39;t copy the message header.
Definition: copy.h:35
bool C_Weed
Config: Filter headers when displaying/forwarding/printing/replying.
Definition: email_globals.c:40
void mutt_make_attribution(struct Mailbox *m, struct Email *e, FILE *fp_out)
Add "on DATE, PERSON wrote" header.
Definition: send.c:647
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ choose_default_to()

static const struct AddressList* choose_default_to ( const struct Address from,
const struct Envelope env 
)
static

Pick the best 'to:' value.

Parameters
fromFrom Address
envEnvelope
Return values
ptrAddresses to use

Definition at line 724 of file send.c.

726 {
727  if (!C_ReplySelf && mutt_addr_is_user(from))
728  {
729  /* mail is from the user, assume replying to recipients */
730  return &env->to;
731  }
732  else
733  {
734  return &env->from;
735  }
736 }
bool C_ReplySelf
Config: Really reply to yourself, when replying to your own email.
Definition: send.c:126
struct AddressList from
Email&#39;s &#39;From&#39; list.
Definition: envelope.h:57
bool mutt_addr_is_user(const struct Address *addr)
Does the address belong to the user.
Definition: alias.c:686
struct AddressList to
Email&#39;s &#39;To&#39; list.
Definition: envelope.h:58
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ default_to()

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

Generate default email addresses.

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

Definition at line 747 of file send.c.

748 {
749  char prompt[256];
750  const struct Address *from = TAILQ_FIRST(&env->from);
751  const struct Address *reply_to = TAILQ_FIRST(&env->reply_to);
752 
753  if (flags && !TAILQ_EMPTY(&env->mail_followup_to) && (hmfupto == MUTT_YES))
754  {
755  mutt_addrlist_copy(to, &env->mail_followup_to, true);
756  return 0;
757  }
758 
759  /* Exit now if we're setting up the default Cc list for list-reply
760  * (only set if Mail-Followup-To is present and honoured). */
761  if (flags & SEND_LIST_REPLY)
762  return 0;
763 
764  const struct AddressList *default_to = choose_default_to(from, env);
765 
766  if (reply_to)
767  {
768  const bool from_is_reply_to = mutt_addr_cmp(from, reply_to);
769  const bool multiple_reply_to =
770  reply_to && TAILQ_NEXT(TAILQ_FIRST(&env->reply_to), entries);
771  if ((from_is_reply_to && !multiple_reply_to && !reply_to->personal) ||
772  (C_IgnoreListReplyTo && mutt_is_mail_list(reply_to) &&
773  (mutt_addrlist_search(&env->to, reply_to) || mutt_addrlist_search(&env->cc, reply_to))))
774  {
775  /* If the Reply-To: address is a mailing list, assume that it was
776  * put there by the mailing list, and use the From: address
777  *
778  * We also take the from header if our correspondent has a reply-to
779  * header which is identical to the electronic mail address given
780  * in his From header, and the reply-to has no display-name. */
781  mutt_addrlist_copy(to, &env->from, false);
782  }
783  else if (!(from_is_reply_to && !multiple_reply_to) && (C_ReplyTo != MUTT_YES))
784  {
785  /* There are quite a few mailing lists which set the Reply-To:
786  * header field to the list address, which makes it quite impossible
787  * to send a message to only the sender of the message. This
788  * provides a way to do that. */
789  /* L10N: Asks whether the user respects the reply-to header.
790  If she says no, neomutt will reply to the from header's address instead. */
791  snprintf(prompt, sizeof(prompt), _("Reply to %s%s?"), reply_to->mailbox,
792  multiple_reply_to ? ",..." : "");
793  switch (query_quadoption(C_ReplyTo, prompt))
794  {
795  case MUTT_YES:
796  mutt_addrlist_copy(to, &env->reply_to, false);
797  break;
798 
799  case MUTT_NO:
800  mutt_addrlist_copy(to, default_to, false);
801  break;
802 
803  default:
804  return -1; /* abort */
805  }
806  }
807  else
808  {
809  mutt_addrlist_copy(to, &env->reply_to, false);
810  }
811  }
812  else
813  {
814  mutt_addrlist_copy(to, default_to, false);
815  }
816 
817  return 0;
818 }
#define TAILQ_FIRST(head)
Definition: queue.h:716
struct AddressList mail_followup_to
Email&#39;s &#39;mail-followup-to&#39;.
Definition: envelope.h:63
struct AddressList reply_to
Email&#39;s &#39;reply-to&#39;.
Definition: envelope.h:62
enum QuadOption query_quadoption(enum QuadOption opt, const char *prompt)
Ask the user a quad-question.
Definition: init.c:1099
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:40
bool mutt_is_mail_list(const struct Address *addr)
Is this the email address of a mailing list? - Implements addr_predicate_t.
Definition: hdrline.c:114
void mutt_addrlist_copy(struct AddressList *dst, const struct AddressList *src, bool prune)
Copy a list of addresses into another list.
Definition: address.c:728
#define _(a)
Definition: message.h:28
An email address.
Definition: address.h:34
char * mailbox
Mailbox and host address.
Definition: address.h:37
bool C_IgnoreListReplyTo
Config: Ignore the &#39;Reply-To&#39; header when using <reply> on a mailing list.
Definition: send.c:117
static int default_to(struct AddressList *to, struct Envelope *env, SendFlags flags, int hmfupto)
Generate default email addresses.
Definition: send.c:747
unsigned char C_ReplyTo
Config: Address to use as a &#39;Reply-To&#39; header.
Definition: send.c:127
struct AddressList from
Email&#39;s &#39;From&#39; list.
Definition: envelope.h:57
struct AddressList cc
Email&#39;s &#39;Cc&#39; list.
Definition: envelope.h:59
#define SEND_LIST_REPLY
Reply to mailing list.
Definition: send.h:90
User answered &#39;No&#39;, or assume &#39;No&#39;.
Definition: quad.h:39
bool mutt_addr_cmp(const struct Address *a, const struct Address *b)
Compare two e-mail addresses.
Definition: address.c:855
bool mutt_addrlist_search(const struct AddressList *haystack, const struct Address *needle)
Search for an e-mail address in a list.
Definition: address.c:872
static const struct AddressList * choose_default_to(const struct Address *from, const struct Envelope *env)
Pick the best &#39;to:&#39; value.
Definition: send.c:724
char * personal
Real name of address.
Definition: address.h:36
struct AddressList to
Email&#39;s &#39;To&#39; list.
Definition: envelope.h:58
#define TAILQ_NEXT(elm, field)
Definition: queue.h:825
#define TAILQ_EMPTY(head)
Definition: queue.h:714
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_fetch_recips()

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

829 {
830  enum QuadOption hmfupto = MUTT_ABORT;
831  const struct Address *followup_to = TAILQ_FIRST(&in->mail_followup_to);
832 
833  if ((flags & (SEND_LIST_REPLY | SEND_GROUP_REPLY | SEND_GROUP_CHAT_REPLY)) && followup_to)
834  {
835  char prompt[256];
836  snprintf(prompt, sizeof(prompt), _("Follow-up to %s%s?"), followup_to->mailbox,
837  TAILQ_NEXT(TAILQ_FIRST(&in->mail_followup_to), entries) ? ",..." : "");
838 
839  hmfupto = query_quadoption(C_HonorFollowupTo, prompt);
840  if (hmfupto == MUTT_ABORT)
841  return -1;
842  }
843 
844  if (flags & SEND_LIST_REPLY)
845  {
846  add_mailing_lists(&out->to, &in->to, &in->cc);
847 
848  if (followup_to && (hmfupto == MUTT_YES) &&
849  (default_to(&out->cc, in, flags & SEND_LIST_REPLY, (hmfupto == MUTT_YES)) == MUTT_ABORT))
850  {
851  return -1; /* abort */
852  }
853  }
854  else if (flags & SEND_TO_SENDER)
855  {
856  mutt_addrlist_copy(&out->to, &in->from, false);
857  }
858  else
859  {
860  if (default_to(&out->to, in, flags & (SEND_GROUP_REPLY | SEND_GROUP_CHAT_REPLY),
861  (hmfupto == MUTT_YES)) == -1)
862  return -1; /* abort */
863 
864  if ((flags & (SEND_GROUP_REPLY | SEND_GROUP_CHAT_REPLY)) &&
865  (!followup_to || (hmfupto != MUTT_YES)))
866  {
867  /* if(!mutt_addr_is_user(in->to)) */
868  if (flags & SEND_GROUP_REPLY)
869  mutt_addrlist_copy(&out->cc, &in->to, true);
870  else
871  mutt_addrlist_copy(&out->to, &in->cc, true);
872  mutt_addrlist_copy(&out->cc, &in->cc, true);
873  }
874  }
875  return 0;
876 }
#define SEND_TO_SENDER
Compose new email to sender.
Definition: send.h:100
#define TAILQ_FIRST(head)
Definition: queue.h:716
struct AddressList mail_followup_to
Email&#39;s &#39;mail-followup-to&#39;.
Definition: envelope.h:63
User aborted the question (with Ctrl-G)
Definition: quad.h:38
enum QuadOption query_quadoption(enum QuadOption opt, const char *prompt)
Ask the user a quad-question.
Definition: init.c:1099
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:40
void mutt_addrlist_copy(struct AddressList *dst, const struct AddressList *src, bool prune)
Copy a list of addresses into another list.
Definition: address.c:728
#define _(a)
Definition: message.h:28
An email address.
Definition: address.h:34
char * mailbox
Mailbox and host address.
Definition: address.h:37
static int default_to(struct AddressList *to, struct Envelope *env, SendFlags flags, int hmfupto)
Generate default email addresses.
Definition: send.c:747
unsigned char C_HonorFollowupTo
Config: Honour the &#39;Mail-Followup-To&#39; header when group replying.
Definition: send.c:116
struct AddressList from
Email&#39;s &#39;From&#39; list.
Definition: envelope.h:57
struct AddressList cc
Email&#39;s &#39;Cc&#39; list.
Definition: envelope.h:59
#define SEND_LIST_REPLY
Reply to mailing list.
Definition: send.h:90
#define SEND_GROUP_REPLY
Reply to all.
Definition: send.h:89
static void add_mailing_lists(struct AddressList *out, const struct AddressList *t, const struct AddressList *c)
Search Address lists for mailing lists.
Definition: send.c:181
struct AddressList to
Email&#39;s &#39;To&#39; list.
Definition: envelope.h:58
#define TAILQ_NEXT(elm, field)
Definition: queue.h:825
#define SEND_GROUP_CHAT_REPLY
Reply to all recipients preserving To/Cc.
Definition: send.h:101
QuadOption
Possible values for a quad-option.
Definition: quad.h:36
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ add_references()

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

884 {
885  struct ListNode *np = NULL;
886 
887  struct ListHead *src = !STAILQ_EMPTY(&env->references) ? &env->references : &env->in_reply_to;
888  STAILQ_FOREACH(np, src, entries)
889  {
891  }
892 }
struct ListHead in_reply_to
in-reply-to header content
Definition: envelope.h:82
struct ListNode * mutt_list_insert_tail(struct ListHead *h, char *s)
Append a string to the end of a List.
Definition: list.c:65
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:349
char * data
String.
Definition: list.h:35
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:380
#define STAILQ_EMPTY(head)
Definition: queue.h:345
struct ListHead references
message references (in reverse order)
Definition: envelope.h:81
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:

◆ add_message_id()

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

900 {
901  if (env->message_id)
902  {
904  }
905 }
char * message_id
Message ID.
Definition: envelope.h:69
struct ListNode * mutt_list_insert_head(struct ListHead *h, char *s)
Insert a string at the beginning of a List.
Definition: list.c:46
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:380
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_fix_reply_recipients()

void mutt_fix_reply_recipients ( struct Envelope env)

Remove duplicate recipients.

Parameters
envEnvelope to fix

Definition at line 911 of file send.c.

912 {
913  if (!C_Metoo)
914  {
915  /* the order is important here. do the CC: first so that if the
916  * the user is the only recipient, it ends up on the TO: field */
917  remove_user(&env->cc, TAILQ_EMPTY(&env->to));
918  remove_user(&env->to, TAILQ_EMPTY(&env->cc) || C_ReplySelf);
919  }
920 
921  /* the CC field can get cluttered, especially with lists */
922  mutt_addrlist_dedupe(&env->to);
923  mutt_addrlist_dedupe(&env->cc);
924  mutt_addrlist_remove_xrefs(&env->to, &env->cc);
925 
926  if (!TAILQ_EMPTY(&env->cc) && TAILQ_EMPTY(&env->to))
927  {
928  TAILQ_SWAP(&env->to, &env->cc, Address, entries);
929  }
930 }
bool C_ReplySelf
Config: Really reply to yourself, when replying to your own email.
Definition: send.c:126
An email address.
Definition: address.h:34
void mutt_addrlist_dedupe(struct AddressList *al)
Remove duplicate addresses.
Definition: address.c:1319
struct AddressList cc
Email&#39;s &#39;Cc&#39; list.
Definition: envelope.h:59
bool C_Metoo
Config: Remove the user&#39;s address from the list of recipients.
Definition: send.c:119
void mutt_addrlist_remove_xrefs(const struct AddressList *a, struct AddressList *b)
Remove cross-references.
Definition: address.c:1355
struct AddressList to
Email&#39;s &#39;To&#39; list.
Definition: envelope.h:58
#define TAILQ_EMPTY(head)
Definition: queue.h:714
static void remove_user(struct AddressList *al, bool leave_only)
Remove any address which matches the current user.
Definition: send.c:162
#define TAILQ_SWAP(head1, head2, type, field)
Definition: queue.h:852
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_make_forward_subject()

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

Create a subject for a forwarded email.

Parameters
envEnvelope for result
mMailbox
eEmail

Definition at line 938 of file send.c.

939 {
940  if (!env)
941  return;
942 
943  char buf[256];
944 
945  /* set the default subject for the message. */
946  mutt_make_string(buf, sizeof(buf), 0, NONULL(C_ForwardFormat), NULL, m, e);
947  mutt_str_replace(&env->subject, buf);
948 }
#define NONULL(x)
Definition: string2.h:37
char * C_ForwardFormat
Config: printf-like format string to control the subject when forwarding a message.
Definition: send.c:113
#define mutt_make_string(BUF, BUFLEN, COLS, S, CTX, M, E)
Definition: hdrline.h:61
void mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition: string.c:453
char * subject
Email&#39;s subject.
Definition: envelope.h:66
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_make_misc_reply_headers()

void mutt_make_misc_reply_headers ( struct Envelope env,
struct Envelope curenv 
)

Set subject for a reply.

Parameters
envEnvelope for result
curenvEnvelope of source email

Definition at line 955 of file send.c.

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

◆ mutt_add_to_reference_headers()

void mutt_add_to_reference_headers ( struct Envelope env,
struct Envelope curenv 
)

Generate references for a reply email.

Parameters
envEnvelope for result
curenvEnvelope of source email

Definition at line 977 of file send.c.

978 {
979  add_references(&env->references, curenv);
980  add_message_id(&env->references, curenv);
981  add_message_id(&env->in_reply_to, curenv);
982 
983 #ifdef USE_NNTP
984  if (OptNewsSend && C_XCommentTo && !TAILQ_EMPTY(&curenv->from))
986 #endif
987 }
#define TAILQ_FIRST(head)
Definition: queue.h:716
static void add_references(struct ListHead *head, struct Envelope *env)
Add the email&#39;s references to a list.
Definition: send.c:883
static void add_message_id(struct ListHead *head, struct Envelope *env)
Add the email&#39;s message ID to a list.
Definition: send.c:899
struct ListHead in_reply_to
in-reply-to header content
Definition: envelope.h:82
struct AddressList from
Email&#39;s &#39;From&#39; list.
Definition: envelope.h:57
char * x_comment_to
List of &#39;X-comment-to&#39; fields.
Definition: envelope.h:78
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:380
WHERE bool C_XCommentTo
Config: (nntp) Add &#39;X-Comment-To&#39; header that contains article author.
Definition: globals.h:283
#define TAILQ_EMPTY(head)
Definition: queue.h:714
WHERE bool OptNewsSend
(pseudo) used to change behavior when posting
Definition: options.h:47
struct ListHead references
message references (in reverse order)
Definition: envelope.h:81
const char * mutt_get_name(const struct Address *a)
Pick the best name to display from an address.
Definition: sort.c:157
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ make_reference_headers()

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

Generate reference headers for an email.

Parameters
elList of source Emails
envEnvelope for result

Definition at line 994 of file send.c.

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

◆ envelope_defaults()

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

Fill in some defaults for a new email.

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

Definition at line 1031 of file send.c.

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

◆ generate_body()

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

Create a new email body.

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

Definition at line 1101 of file send.c.

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

◆ mutt_set_followup_to()

void mutt_set_followup_to ( struct Envelope env)

Set followup-to field.

Parameters
envEnvelope to modify

Definition at line 1213 of file send.c.

1214 {
1215  /* Only generate the Mail-Followup-To if the user has requested it, and
1216  * it hasn't already been set */
1217 
1218  if (!C_FollowupTo)
1219  return;
1220 #ifdef USE_NNTP
1221  if (OptNewsSend)
1222  {
1223  if (!env->followup_to && env->newsgroups && (strrchr(env->newsgroups, ',')))
1224  env->followup_to = mutt_str_strdup(env->newsgroups);
1225  return;
1226  }
1227 #endif
1228 
1229  if (TAILQ_EMPTY(&env->mail_followup_to))
1230  {
1231  if (mutt_is_list_recipient(false, env))
1232  {
1233  /* this message goes to known mailing lists, so create a proper
1234  * mail-followup-to header */
1235 
1236  mutt_addrlist_copy(&env->mail_followup_to, &env->to, false);
1237  mutt_addrlist_copy(&env->mail_followup_to, &env->cc, true);
1238  }
1239 
1240  /* remove ourselves from the mail-followup-to header */
1241  remove_user(&env->mail_followup_to, false);
1242 
1243  /* If we are not subscribed to any of the lists in question, re-add
1244  * ourselves to the mail-followup-to header. The mail-followup-to header
1245  * generated is a no-op with group-reply, but makes sure list-reply has the
1246  * desired effect. */
1247 
1248  if (!TAILQ_EMPTY(&env->mail_followup_to) &&
1249  !mutt_is_subscribed_list_recipient(false, env))
1250  {
1251  struct AddressList *al = NULL;
1252  if (!TAILQ_EMPTY(&env->reply_to))
1253  al = &env->reply_to;
1254  else if (!TAILQ_EMPTY(&env->from))
1255  al = &env->from;
1256 
1257  if (al)
1258  {
1259  struct Address *a = NULL;
1260  TAILQ_FOREACH_REVERSE(a, al, AddressList, entries)
1261  {
1263  }
1264  }
1265  else
1266  {
1268  }
1269  }
1270 
1272  }
1273 }
struct AddressList mail_followup_to
Email&#39;s &#39;mail-followup-to&#39;.
Definition: envelope.h:63
struct AddressList reply_to
Email&#39;s &#39;reply-to&#39;.
Definition: envelope.h:62
void mutt_addrlist_copy(struct AddressList *dst, const struct AddressList *src, bool prune)
Copy a list of addresses into another list.
Definition: address.c:728
An email address.
Definition: address.h:34
bool C_FollowupTo
Config: Add the &#39;Mail-Followup-To&#39; header is generated when sending mail.
Definition: send.c:109
struct Address * mutt_addr_copy(const struct Address *addr)
Copy the real address.
Definition: address.c:707
void mutt_addrlist_dedupe(struct AddressList *al)
Remove duplicate addresses.
Definition: address.c:1319
#define TAILQ_FOREACH_REVERSE(var, head, headname, field)
Definition: queue.h:738
struct AddressList from
Email&#39;s &#39;From&#39; list.
Definition: envelope.h:57
struct AddressList cc
Email&#39;s &#39;Cc&#39; list.
Definition: envelope.h:59
struct Address * mutt_default_from(void)
Get a default &#39;from&#39; Address.
Definition: send.c:1333
void mutt_addrlist_prepend(struct AddressList *al, struct Address *a)
Prepend an Address to an AddressList.
Definition: address.c:1413
char * newsgroups
List of newsgroups.
Definition: envelope.h:75
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:380
char * followup_to
List of &#39;followup-to&#39; fields.
Definition: envelope.h:77
int mutt_is_subscribed_list_recipient(bool all_addr, struct Envelope *e)
Matches subscribed mailing lists.
Definition: pattern.c:1814
struct AddressList to
Email&#39;s &#39;To&#39; list.
Definition: envelope.h:58
#define TAILQ_EMPTY(head)
Definition: queue.h:714
WHERE bool OptNewsSend
(pseudo) used to change behavior when posting
Definition: options.h:47
static void remove_user(struct AddressList *al, bool leave_only)
Remove any address which matches the current user.
Definition: send.c:162
int mutt_is_list_recipient(bool all_addr, struct Envelope *e)
Matches known mailing lists.
Definition: pattern.c:1826
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ set_reverse_name()

static void set_reverse_name ( struct AddressList *  al,
struct Envelope env 
)
static

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

Parameters
alAddressList to prepend the found address
envEnvelope to use

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

1285 {
1286  struct Address *a = NULL;
1287  if (TAILQ_EMPTY(al))
1288  {
1289  TAILQ_FOREACH(a, &env->to, entries)
1290  {
1291  if (mutt_addr_is_user(a))
1292  {
1294  break;
1295  }
1296  }
1297  }
1298 
1299  if (TAILQ_EMPTY(al))
1300  {
1301  TAILQ_FOREACH(a, &env->cc, entries)
1302  {
1303  if (mutt_addr_is_user(a))
1304  {
1306  break;
1307  }
1308  }
1309  }
1310 
1311  if (TAILQ_EMPTY(al))
1312  {
1313  struct Address *from = TAILQ_FIRST(&env->from);
1314  if (from && mutt_addr_is_user(from))
1315  {
1317  }
1318  }
1319 
1320  if (!TAILQ_EMPTY(al))
1321  {
1322  /* when $reverse_realname is not set, clear the personal name so that it
1323  * may be set via a reply- or send-hook. */
1324  if (!C_ReverseRealname)
1325  FREE(&TAILQ_FIRST(al)->personal);
1326  }
1327 }
#define TAILQ_FIRST(head)
Definition: queue.h:716
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:718
An email address.
Definition: address.h:34
struct Address * mutt_addr_copy(const struct Address *addr)
Copy the real address.
Definition: address.c:707
struct AddressList from
Email&#39;s &#39;From&#39; list.
Definition: envelope.h:57
struct AddressList cc
Email&#39;s &#39;Cc&#39; list.
Definition: envelope.h:59
bool C_ReverseRealname
Config: Set the &#39;From&#39; from the full &#39;To&#39; address the email was sent to.
Definition: send.c:130
char * personal
Real name of address.
Definition: address.h:36
#define FREE(x)
Definition: memory.h:40
bool mutt_addr_is_user(const struct Address *addr)
Does the address belong to the user.
Definition: alias.c:686
struct AddressList to
Email&#39;s &#39;To&#39; list.
Definition: envelope.h:58
#define TAILQ_EMPTY(head)
Definition: queue.h:714
void mutt_addrlist_append(struct AddressList *al, struct Address *a)
Append an Address to an AddressList.
Definition: address.c:1402
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_default_from()

struct Address* mutt_default_from ( void  )

Get a default 'from' Address.

Return values
ptrNewly allocated Address

Definition at line 1333 of file send.c.

1334 {
1335  /* Note: We let $from override $realname here.
1336  * Is this the right thing to do?
1337  */
1338 
1339  if (C_From)
1340  {
1341  return mutt_addr_copy(C_From);
1342  }
1343  else if (C_UseDomain)
1344  {
1345  struct Address *addr = mutt_addr_new();
1346  mutt_str_asprintf(&addr->mailbox, "%s@%s", NONULL(Username), NONULL(mutt_fqdn(true)));
1347  return addr;
1348  }
1349  else
1350  {
1351  return mutt_addr_create(NULL, Username);
1352  }
1353 }
WHERE char * Username
User&#39;s login name.
Definition: globals.h:52
#define NONULL(x)
Definition: string2.h:37
struct Address * mutt_addr_new(void)
Create a new Address.
Definition: address.c:385
An email address.
Definition: address.h:34
char * mailbox
Mailbox and host address.
Definition: address.h:37
struct Address * mutt_addr_copy(const struct Address *addr)
Copy the real address.
Definition: address.c:707
struct Address * mutt_addr_create(const char *personal, const char *mailbox)
Create and populate a new Address.
Definition: address.c:398
WHERE bool C_UseDomain
Config: Qualify local addresses using this domain.
Definition: globals.h:256
WHERE struct Address * C_From
Config: Default &#39;From&#39; address to use, if isn&#39;t otherwise set.
Definition: globals.h:94
const char * mutt_fqdn(bool may_hide_host)
Get the Fully-Qualified Domain Name.
Definition: sendlib.c:2526
int mutt_str_asprintf(char **strp, const char *fmt,...)
Definition: string.c:1217
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ send_message()

static int send_message ( struct Email e)
static

Send an email.

Parameters
eEmail
Return values
0Success
-1Failure

Definition at line 1361 of file send.c.

1362 {
1363  struct Buffer *tempfile = NULL;
1364  int rc = -1;
1365 #ifdef USE_SMTP
1366  short old_write_bcc;
1367 #endif
1368 
1369  /* Write out the message in MIME form. */
1370  tempfile = mutt_buffer_pool_get();
1371  mutt_buffer_mktemp(tempfile);
1372  FILE *fp_tmp = mutt_file_fopen(mutt_b2s(tempfile), "w");
1373  if (!fp_tmp)
1374  goto cleanup;
1375 
1376 #ifdef USE_SMTP
1377  old_write_bcc = C_WriteBcc;
1378  if (C_SmtpUrl)
1379  C_WriteBcc = false;
1380 #endif
1381 #ifdef MIXMASTER
1383  !STAILQ_EMPTY(&e->chain),
1385 #endif
1386 #ifndef MIXMASTER
1389 #endif
1390 #ifdef USE_SMTP
1391  if (old_write_bcc)
1392  C_WriteBcc = true;
1393 #endif
1394 
1395  fputc('\n', fp_tmp); /* tie off the header. */
1396 
1397  if ((mutt_write_mime_body(e->content, fp_tmp) == -1))
1398  goto cleanup;
1399 
1400  if (mutt_file_fclose(&fp_tmp) != 0)
1401  {
1402  mutt_perror(mutt_b2s(tempfile));
1403  unlink(mutt_b2s(tempfile));
1404  goto cleanup;
1405  }
1406 
1407 #ifdef MIXMASTER
1408  if (!STAILQ_EMPTY(&e->chain))
1409  {
1410  rc = mix_send_message(&e->chain, mutt_b2s(tempfile));
1411  goto cleanup;
1412  }
1413 #endif
1414 
1415 #ifdef USE_NNTP
1416  if (OptNewsSend)
1417  goto sendmail;
1418 #endif
1419 
1420 #ifdef USE_SMTP
1421  if (C_SmtpUrl)
1422  {
1423  rc = mutt_smtp_send(&e->env->from, &e->env->to, &e->env->cc, &e->env->bcc,
1424  mutt_b2s(tempfile), (e->content->encoding == ENC_8BIT));
1425  goto cleanup;
1426  }
1427 #endif
1428 
1429 sendmail:
1430  rc = mutt_invoke_sendmail(&e->env->from, &e->env->to, &e->env->cc, &e->env->bcc,
1431  mutt_b2s(tempfile), (e->content->encoding == ENC_8BIT));
1432 cleanup:
1433  if (fp_tmp)
1434  {
1435  mutt_file_fclose(&fp_tmp);
1436  unlink(mutt_b2s(tempfile));
1437  }
1438  mutt_buffer_pool_release(&tempfile);
1439  return rc;
1440 }
WHERE char * C_SmtpUrl
Config: (smtp) Url of the SMTP server.
Definition: globals.h:143
#define mutt_buffer_mktemp(buf)
Definition: muttlib.h:81
WHERE bool C_WriteBcc
Config: Write out the &#39;Bcc&#39; field when preparing to send a mail.
Definition: globals.h:259
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
#define mutt_perror(...)
Definition: logging.h:85
struct AddressList bcc
Email&#39;s &#39;Bcc&#39; list.
Definition: envelope.h:60
A normal Email, write full header + MIME headers.
Definition: sendlib.h:60
bool mutt_should_hide_protected_subject(struct Email *e)
Should NeoMutt hide the protected subject?
Definition: crypt.c:1088
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
struct Body * content
List of MIME parts.
Definition: email.h:90
String manipulation buffer.
Definition: buffer.h:33
8-bit text
Definition: mime.h:50
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:2320
int mutt_invoke_sendmail(struct AddressList *from, struct AddressList *to, struct AddressList *cc, struct AddressList *bcc, const char *msg, int eightbit)
Run sendmail.
Definition: sendlib.c:2818
struct AddressList from
Email&#39;s &#39;From&#39; list.
Definition: envelope.h:57
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:153
struct Envelope * env
Envelope information.
Definition: email.h:89
struct AddressList cc
Email&#39;s &#39;Cc&#39; list.
Definition: envelope.h:59
unsigned int encoding
content-transfer-encoding
Definition: body.h:66
#define mutt_b2s(buf)
Definition: buffer.h:41
struct ListHead chain
Mixmaster chain.
Definition: email.h:99
int mutt_write_mime_body(struct Body *a, FILE *fp)
Write a MIME part.
Definition: sendlib.c:553
int mix_send_message(struct ListHead *chain, const char *tempfile)
Send an email via Mixmaster.
Definition: remailer.c:906
#define STAILQ_EMPTY(head)
Definition: queue.h:345
struct AddressList to
Email&#39;s &#39;To&#39; list.
Definition: envelope.h:58
int mutt_smtp_send(const struct AddressList *from, const struct AddressList *to, const struct AddressList *cc, const struct AddressList *bcc, const char *msgfile, bool eightbit)
Send a message using SMTP.
Definition: smtp.c:763
WHERE bool OptNewsSend
(pseudo) used to change behavior when posting
Definition: options.h:47
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:588
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_encode_descriptions()

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

1448 {
1449  for (struct Body *t = b; t; t = t->next)
1450  {
1451  if (t->description)
1452  {
1453  rfc2047_encode(&t->description, NULL, sizeof("Content-Description:"), C_SendCharset);
1454  }
1455  if (recurse && t->parts)
1456  mutt_encode_descriptions(t->parts, recurse);
1457  }
1458 }
struct Body * next
next attachment in the list
Definition: body.h:53
The body of an email.
Definition: body.h:34
char * C_SendCharset
Config: Character sets for outgoing mail.
Definition: email_globals.c:38
void mutt_encode_descriptions(struct Body *b, bool recurse)
rfc2047 encode the content-descriptions
Definition: send.c:1447
void rfc2047_encode(char **pd, const char *specials, int col, const char *charsets)
RFC-2047-encode a string.
Definition: rfc2047.c:612
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ decode_descriptions()

static void decode_descriptions ( struct Body b)
static

rfc2047 decode them in case of an error

Parameters
bMIME parts to decode

Definition at line 1464 of file send.c.

1465 {
1466  for (struct Body *t = b; t; t = t->next)
1467  {
1468  if (t->description)
1469  {
1470  rfc2047_decode(&t->description);
1471  }
1472  if (t->parts)
1473  decode_descriptions(t->parts);
1474  }
1475 }
struct Body * next
next attachment in the list
Definition: body.h:53
The body of an email.
Definition: body.h:34
void rfc2047_decode(char **pd)
Decode any RFC2047-encoded header fields.
Definition: rfc2047.c:636
static void decode_descriptions(struct Body *b)
rfc2047 decode them in case of an error
Definition: send.c:1464
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fix_end_of_file()

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

1482 {
1483  FILE *fp = mutt_file_fopen(data, "a+");
1484  if (!fp)
1485  return;
1486  if (fseek(fp, -1, SEEK_END) >= 0)
1487  {
1488  int c = fgetc(fp);
1489  if (c != '\n')
1490  fputc('\n', fp);
1491  }
1492  mutt_file_fclose(&fp);
1493 }
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:153
char * data
Pointer to data.
Definition: buffer.h:35
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:588
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_resend_message()

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

Resend an email.

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

Definition at line 1504 of file send.c.

1505 {
1506  struct Email *e_new = email_new();
1507 
1508  if (mutt_prepare_template(fp, ctx->mailbox, e_new, e_cur, true) < 0)
1509  {
1510  email_free(&e_new);
1511  return -1;
1512  }
1513 
1514  if (WithCrypto)
1515  {
1516  /* mutt_prepare_template doesn't always flip on an application bit.
1517  * so fix that here */
1518  if (!(e_new->security & (APPLICATION_SMIME | APPLICATION_PGP)))
1519  {
1520  if (((WithCrypto & APPLICATION_SMIME) != 0) && C_SmimeIsDefault)
1521  e_new->security |= APPLICATION_SMIME;
1522  else if (WithCrypto & APPLICATION_PGP)
1523  e_new->security |= APPLICATION_PGP;
1524  else
1525  e_new->security |= APPLICATION_SMIME;
1526  }
1527 
1529  {
1530  e_new->security |= SEC_OPPENCRYPT;
1532  }
1533  }
1534 
1535  struct EmailList el = STAILQ_HEAD_INITIALIZER(el);
1536  emaillist_add_email(&el, e_cur);
1537  int rc = ci_send_message(SEND_RESEND, e_new, NULL, ctx, &el);
1538  emaillist_clear(&el);
1539 
1540  return rc;
1541 }
#define WithCrypto
Definition: lib.h:163
The envelope/body of an email.
Definition: email.h:37
int emaillist_add_email(struct EmailList *el, struct Email *e)
Add an Email to a list.
Definition: email.c:144
WHERE bool C_SmimeIsDefault
Config: Use SMIME rather than PGP by default.
Definition: globals.h:273
struct Mailbox * mailbox
Definition: context.h:51
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition: lib.h:138
#define SEND_RESEND
Reply using the current email as a template.
Definition: send.h:96
WHERE bool C_CryptOpportunisticEncrypt
Config: Enable encryption when the recipient&#39;s key is available.
Definition: globals.h:268
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: lib.h:137
int ci_send_message(SendFlags flags, struct Email *e_templ, const char *tempfile, struct Context *ctx, struct EmailList *el)
Send an email.
Definition: send.c:1893
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/lib.h pgplib...
Definition: email.h:39
#define SEC_OPPENCRYPT
Opportunistic encrypt mode.
Definition: lib.h:133
void crypt_opportunistic_encrypt(struct Email *e)
Can all recipients be determined.
Definition: crypt.c:1036
void emaillist_clear(struct EmailList *el)
Drop a private list of Emails.
Definition: email.c:123
#define STAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:321
struct Email * email_new(void)
Create a new Email.
Definition: email.c:68
void email_free(struct Email **ptr)
Free an Email.
Definition: email.c:41
int mutt_prepare_template(FILE *fp, struct Mailbox *m, struct Email *e_new, struct Email *e, bool resend)
Prepare a message template.
Definition: postpone.c:655
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ is_reply()

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

1551 {
1552  if (!reply || !reply->env || !orig || !orig->env)
1553  return false;
1554  return mutt_list_find(&orig->env->references, reply->env->message_id) ||
1555  mutt_list_find(&orig->env->in_reply_to, reply->env->message_id);
1556 }
struct ListHead in_reply_to
in-reply-to header content
Definition: envelope.h:82
char * message_id
Message ID.
Definition: envelope.h:69
struct Envelope * env
Envelope information.
Definition: email.h:89
struct ListNode * mutt_list_find(const struct ListHead *h, const char *data)
Find a string in a List.
Definition: list.c:103
struct ListHead references
message references (in reverse order)
Definition: envelope.h:81
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ search_attach_keyword()

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

1569 {
1570  /* Search for the regex in C_AbortNoattachRegex within a file */
1572  !C_QuoteRegex->regex)
1573  {
1574  return false;
1575  }
1576 
1577  FILE *fp_att = mutt_file_fopen(filename, "r");
1578  if (!fp_att)
1579  return false;
1580 
1581  char *inputline = mutt_mem_malloc(1024);
1582  bool found = false;
1583  while (!feof(fp_att))
1584  {
1585  fgets(inputline, 1024, fp_att);
1586  if (!mutt_is_quote_line(inputline, NULL) &&
1588  {
1589  found = true;
1590  break;
1591  }
1592  }
1593  FREE(&inputline);
1594  mutt_file_fclose(&fp_att);
1595  return found;
1596 }
struct Regex * C_AbortNoattachRegex
Config: Regex to match text indicating attachments are expected.
Definition: send.c:91
regex_t * regex
compiled expression
Definition: regex3.h:90
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:153
void * mutt_mem_malloc(size_t size)
Allocate memory on the heap.
Definition: memory.c:90
WHERE struct Regex * C_QuoteRegex
Config: Regex to match quoted text in a reply.
Definition: globals.h:175
bool mutt_regex_match(const struct Regex *regex, const char *str)
Shorthand to mutt_regex_capture()
Definition: regex.c:610
#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:938
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:588
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ save_fcc()

static int save_fcc ( struct Email e,
struct Buffer fcc,
struct Body clear_content,
char *  pgpkeylist,
SendFlags  flags,
char **  finalpath 
)
static

Save an Email to a 'sent mail' folder.

Parameters
[in]eEmail to save
[in]fccFolder to save to (can be comma-separated list)
[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 1609 of file send.c.

1611 {
1612  int rc = 0;
1613  struct Body *save_content = NULL;
1614 
1616 
1617  /* Don't save a copy when we are in batch-mode, and the FCC
1618  * folder is on an IMAP server: This would involve possibly lots
1619  * of user interaction, which is not available in batch mode.
1620  *
1621  * Note: A patch to fix the problems with the use of IMAP servers
1622  * from non-curses mode is available from Brendan Cully. However,
1623  * I'd like to think a bit more about this before including it. */
1624 
1625 #ifdef USE_IMAP
1626  if ((flags & SEND_BATCH) && !mutt_buffer_is_empty(fcc) &&
1627  (imap_path_probe(mutt_b2s(fcc), NULL) == MUTT_IMAP))
1628  {
1629  mutt_buffer_reset(fcc);
1630  mutt_error(_("Fcc to an IMAP mailbox is not supported in batch mode"));
1631  return rc;
1632  }
1633 #endif
1634 
1635  if (mutt_buffer_is_empty(fcc) || (mutt_str_strcmp("/dev/null", mutt_b2s(fcc)) == 0))
1636  return rc;
1637 
1638  struct Body *tmpbody = e->content;
1639  struct Body *save_sig = NULL;
1640  struct Body *save_parts = NULL;
1641 
1642  /* Before sending, we don't allow message manipulation because it
1643  * will break message signatures. This is especially complicated by
1644  * Protected Headers. */
1645  if (!C_FccBeforeSend)
1646  {
1647  if ((WithCrypto != 0) && (e->security & (SEC_ENCRYPT | SEC_SIGN | SEC_AUTOCRYPT)) && C_FccClear)
1648  {
1649  e->content = clear_content;
1652  }
1653 
1654  /* check to see if the user wants copies of all attachments */
1655  bool save_atts = true;
1656  if (e->content->type == TYPE_MULTIPART)
1657  {
1658  /* In batch mode, save attachments if the quadoption is yes or ask-yes */
1659  if (flags & SEND_BATCH)
1660  {
1661  if ((C_FccAttach == MUTT_NO) || (C_FccAttach == MUTT_ASKNO))
1662  save_atts = false;
1663  }
1664  else if (query_quadoption(C_FccAttach, _("Save attachments in Fcc?")) != MUTT_YES)
1665  save_atts = false;
1666  }
1667  if (!save_atts)
1668  {
1669  if ((WithCrypto != 0) && (e->security & (SEC_ENCRYPT | SEC_SIGN | SEC_AUTOCRYPT)) &&
1670  ((mutt_str_strcmp(e->content->subtype, "encrypted") == 0) ||
1671  (mutt_str_strcmp(e->content->subtype, "signed") == 0)))
1672  {
1673  if ((clear_content->type == TYPE_MULTIPART) &&
1674  (query_quadoption(C_FccAttach, _("Save attachments in Fcc?")) == MUTT_NO))
1675  {
1676  if (!(e->security & SEC_ENCRYPT) && (e->security & SEC_SIGN))
1677  {
1678  /* save initial signature and attachments */
1679  save_sig = e->content->parts->next;
1680  save_parts = clear_content->parts->next;
1681  }
1682 
1683  /* this means writing only the main part */
1684  e->content = clear_content->parts;
1685 
1686  if (mutt_protect(e, pgpkeylist, false) == -1)
1687  {
1688  /* we can't do much about it at this point, so
1689  * fallback to saving the whole thing to fcc */
1690  e->content = tmpbody;
1691  save_sig = NULL;
1692  goto full_fcc;
1693  }
1694 
1695  save_content = e->content;
1696  }
1697  }
1698  else
1699  {
1700  if (query_quadoption(C_FccAttach, _("Save attachments in Fcc?")) == MUTT_NO)
1701  e->content = e->content->parts;
1702  }
1703  }
1704  }
1705 
1706 full_fcc:
1707  if (e->content)
1708  {
1709  /* update received time so that when storing to a mbox-style folder
1710  * the From_ line contains the current time instead of when the
1711  * message was first postponed. */
1712  e->received = mutt_date_epoch();
1713  rc = mutt_write_multiple_fcc(mutt_b2s(fcc), e, NULL, false, NULL, finalpath);
1714  while (rc && !(flags & SEND_BATCH))
1715  {
1716  mutt_clear_error();
1717  int choice = mutt_multi_choice(
1718  /* L10N: Called when saving to $record or Fcc failed after sending.
1719  (r)etry tries the same mailbox again.
1720  alternate (m)ailbox prompts for a different mailbox to try.
1721  (s)kip aborts saving. */
1722  _("Fcc failed. (r)etry, alternate (m)ailbox, or (s)kip?"),
1723  /* L10N: These correspond to the "Fcc failed" multi-choice prompt
1724  (r)etry, alternate (m)ailbox, or (s)kip.
1725  Any similarity to famous leaders of the FSF is coincidental. */
1726  _("rms"));
1727  switch (choice)
1728  {
1729  case 2: /* alternate (m)ailbox */
1730  /* L10N: This is the prompt to enter an "alternate (m)ailbox" when the
1731  initial Fcc fails. */
1732  rc = mutt_buffer_enter_fname(_("Fcc mailbox"), fcc, true);
1733  if ((rc == -1) || mutt_buffer_is_empty(fcc))
1734  {
1735  rc = 0;
1736  break;
1737  }
1738  /* fall through */
1739 
1740  case 1: /* (r)etry */
1741  rc = mutt_write_multiple_fcc(mutt_b2s(fcc), e, NULL, false, NULL, finalpath);
1742  break;
1743 
1744  case -1: /* abort */
1745  case 3: /* (s)kip */
1746  rc = 0;
1747  break;
1748  }
1749  }
1750  }
1751 
1752  if (!C_FccBeforeSend)
1753  {
1754  e->content = tmpbody;
1755 
1756  if ((WithCrypto != 0) && save_sig)
1757  {
1758  /* cleanup the second signature structures */
1759  if (save_content->parts)
1760  {
1761  mutt_body_free(&save_content->parts->next);
1762  save_content->parts = NULL;
1763  }
1764  mutt_body_free(&save_content);
1765 
1766  /* restore old signature and attachments */
1767  e->content->parts->next = save_sig;
1768  e->content->parts->parts->next = save_parts;
1769  }
1770  else if ((WithCrypto != 0) && save_content)
1771  {
1772  /* destroy the new encrypted body. */
1773  mutt_body_free(&save_content);
1774  }
1775  }
1776 
1777  return 0;
1778 }
time_t mutt_date_epoch(void)
Return the number of seconds since the Unix epoch.
Definition: date.c:411
struct Envelope * mime_headers
Memory hole protected headers.
Definition: body.h:63
void mutt_buffer_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition: buffer.c:79
#define WithCrypto
Definition: lib.h:163
enum MailboxType imap_path_probe(const char *path, const struct stat *st)
Is this an IMAP Mailbox? - Implements MxOps::path_probe()
Definition: imap.c:2516
enum QuadOption query_quadoption(enum QuadOption opt, const char *prompt)
Ask the user a quad-question.
Definition: init.c:1099
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:40
#define SEC_ENCRYPT
Email is encrypted.
Definition: lib.h:125
bool C_FccBeforeSend
Config: Save FCCs before sending the message.
Definition: send.c:107
struct Body * content
List of MIME parts.
Definition: email.h:90
#define _(a)
Definition: message.h:28
struct Body * next
next attachment in the list
Definition: body.h:53
#define SEC_AUTOCRYPT
(Autocrypt) Message will be, or was Autocrypt encrypt+signed
Definition: lib.h:134
The body of an email.
Definition: body.h:34
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
Definition: mutt_logging.c:113
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:3206
char * subtype
content-type subtype
Definition: body.h:37
#define mutt_b2s(buf)
Definition: buffer.h:41
int mutt_multi_choice(const char *prompt, const char *letters)
Offer the user a multiple choice question.
Definition: curs_lib.c:911
unsigned char C_FccAttach
Config: Save send message with all their attachments.
Definition: send.c:106
User answered &#39;No&#39;, or assume &#39;No&#39;.
Definition: quad.h:39
void mutt_env_free(struct Envelope **ptr)
Free an Envelope.
Definition: envelope.c:96
int mutt_protect(struct Email *e, char *keylist, bool postpone)
Encrypt and/or sign a message.
Definition: crypt.c:171
struct Body * parts
parts of a multipart or message/rfc822
Definition: body.h:54
bool C_FccClear
Config: Save sent messages unencrypted and unsigned.
Definition: send.c:108
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/lib.h pgplib...
Definition: email.h:39
unsigned int type
content-type primary type
Definition: body.h:65
#define SEC_SIGN
Email is signed.
Definition: lib.h:126
Type: &#39;multipart/*&#39;.
Definition: mime.h:37
void mutt_buffer_expand_path(struct Buffer *buf)
Create the canonical path.
Definition: muttlib.c:328
Ask the user, defaulting to &#39;No&#39;.
Definition: quad.h:41
#define mutt_error(...)
Definition: logging.h:84
void mutt_body_free(struct Body **ptr)
Free a Body.
Definition: body.c:57
bool mutt_buffer_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition: buffer.c:252
&#39;IMAP&#39; Mailbox type
Definition: mailbox.h:53
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:638
#define mutt_buffer_enter_fname(prompt, fname, mailbox)
Definition: curs_lib.h:87
time_t received
Time when the message was placed in the mailbox.
Definition: email.h:82
#define SEND_BATCH
Send email in batch mode (without user interaction)
Definition: send.h:93
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ postpone_message()

static int postpone_message ( struct Email e_post,
struct Email e_cur,
const char *  fcc,
SendFlags  flags 
)
static

Save an Email for another day.

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

Definition at line 1789 of file send.c.

1791 {
1792  char *pgpkeylist = NULL;
1793  char *encrypt_as = NULL;
1794  struct Body *clear_content = NULL;
1795 
1796  if (!C_Postponed)
1797  {
1798  mutt_error(_("Can't postpone. $postponed is unset"));
1799  return -1;
1800  }
1801 
1802  if (e_post->content->next)
1803  e_post->content = mutt_make_multipart(e_post->content);
1804 
1805  mutt_encode_descriptions(e_post->content, true);
1806 
1807  if ((WithCrypto != 0) && C_PostponeEncrypt &&
1808  (e_post->security & (SEC_ENCRYPT | SEC_AUTOCRYPT)))
1809  {
1810  if (((WithCrypto & APPLICATION_PGP) != 0) && (e_post->security & APPLICATION_PGP))
1811  encrypt_as = C_PgpDefaultKey;
1812  else if (((WithCrypto & APPLICATION_SMIME) != 0) && (e_post->security & APPLICATION_SMIME))
1813  encrypt_as = C_SmimeDefaultKey;
1814  if (!encrypt_as)
1815  encrypt_as = C_PostponeEncryptAs;
1816 
1817 #ifdef USE_AUTOCRYPT
1818  if (e_post->security & SEC_AUTOCRYPT)
1819  {
1821  {
1822  e_post->content = mutt_remove_multipart(e_post->content);
1823  decode_descriptions(e_post->content);
1824  mutt_error(_("Error encrypting message. Check your crypt settings."));
1825  return -1;
1826  }
1827  encrypt_as = AutocryptDefaultKey;
1828  }
1829 #endif
1830 
1831  if (encrypt_as)
1832  {
1833  pgpkeylist = mutt_str_strdup(encrypt_as);
1834  clear_content = e_post->content;
1835  if (mutt_protect(e_post, pgpkeylist, true) == -1)
1836  {
1837  FREE(&pgpkeylist);
1838  e_post->content = mutt_remove_multipart(e_post->content);
1839  decode_descriptions(e_post->content);
1840  mutt_error(_("Error encrypting message. Check your crypt settings."));
1841  return -1;
1842  }
1843 
1844  FREE(&pgpkeylist);
1845 
1846  mutt_encode_descriptions(e_post->content, false);
1847  }
1848  }
1849 
1850  /* make sure the message is written to the right part of a maildir
1851  * postponed folder. */
1852  e_post->read = false;
1853  e_post->old = false;
1854 
1855  mutt_prepare_envelope(e_post->env, false);
1856  mutt_env_to_intl(e_post->env, NULL, NULL); /* Handle bad IDNAs the next time. */
1857 
1858  if (mutt_write_fcc(NONULL(C_Postponed), e_post,
1859  (e_cur && (flags & SEND_REPLY)) ? e_cur->env->message_id : NULL,
1860  true, fcc, NULL) < 0)
1861  {
1862  if (clear_content)
1863  {
1864  mutt_body_free(&e_post->content);
1865  e_post->content = clear_content;
1866  }
1867  mutt_env_free(&e_post->content->mime_headers); /* protected headers */
1868  e_post->content = mutt_remove_multipart(e_post->content);
1869  decode_descriptions(e_post->content);
1870  mutt_unprepare_envelope(e_post->env);
1871  return -1;
1872  }
1873 
1875 
1876  if (clear_content)
1877  mutt_body_free(&clear_content);
1878 
1879  return 0;
1880 }
char * C_PostponeEncryptAs
Config: Fallback encryption key for postponed messages.
Definition: send.c:124
#define NONULL(x)
Definition: string2.h:37
struct Envelope * mime_headers
Memory hole protected headers.
Definition: body.h:63
struct Body * mutt_remove_multipart(struct Body *b)
Extract the multipart body if it exists.
Definition: sendlib.c:1767
#define WithCrypto
Definition: lib.h:163
WHERE char * C_SmimeDefaultKey
Config: Default key for SMIME operations.
Definition: globals.h:164
#define SEC_ENCRYPT
Email is encrypted.
Definition: lib.h:125
WHERE char * AutocryptDefaultKey
Autocrypt default key id (used for postponing messages)
Definition: globals.h:88
struct Body * content
List of MIME parts.
Definition: email.h:90
bool C_PostponeEncrypt
Config: Self-encrypt postponed messages.
Definition: send.c:123
#define _(a)
Definition: message.h:28
struct Body * next
next attachment in the list
Definition: body.h:53
#define SEC_AUTOCRYPT
(Autocrypt) Message will be, or was Autocrypt encrypt+signed
Definition: lib.h:134
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:309
int mutt_write_fcc(const char *path, struct Email *e, const char *msgid, bool post, const char *fcc, char **finalpath)
Write email to FCC mailbox.
Definition: sendlib.c:3253
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:2998
bool read
Email is read.
Definition: email.h:51
char * message_id
Message ID.
Definition: envelope.h:69
bool old
Email is seen, but unread.
Definition: email.h:50
struct Envelope * env
Envelope information.
Definition: email.h:89
static void decode_descriptions(struct Body *b)
rfc2047 decode them in case of an error
Definition: send.c:1464
struct Body * mutt_make_multipart(struct Body *b)
Create a multipart email.
Definition: sendlib.c:1741
int mutt_autocrypt_set_sign_as_default_key(struct Email *e)
Set the Autocrypt default key for signing.
Definition: autocrypt.c:663
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition: lib.h:138
void mutt_unprepare_envelope(struct Envelope *env)
Undo the encodings of mutt_prepare_envelope()
Definition: sendlib.c:3037
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: lib.h:137
void mutt_encode_descriptions(struct Body *b, bool recurse)
rfc2047 encode the content-descriptions
Definition: send.c:1447
void mutt_env_free(struct Envelope **ptr)
Free an Envelope.
Definition: envelope.c:96
int mutt_protect(struct Email *e, char *keylist, bool postpone)
Encrypt and/or sign a message.
Definition: crypt.c:171
void mutt_update_num_postponed(void)
Force the update of the number of postponed messages.
Definition: postpone.c:199
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/lib.h pgplib...
Definition: email.h:39
#define SEND_REPLY
Reply to sender.
Definition: send.h:88
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:380
#define mutt_error(...)
Definition: logging.h:84
WHERE char * C_PgpDefaultKey
Config: Default key to use for PGP operations.
Definition: globals.h:160
#define FREE(x)
Definition: memory.h:40
void mutt_body_free(struct Body **ptr)
Free a Body.
Definition: body.c:57
WHERE char * C_Postponed
Config: Folder to store postponed messages.
Definition: globals.h:135
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ci_send_message()

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

Send an email.

Parameters
flagsSend mode, see SendFlags
e_templTemplate 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 1893 of file send.c.

1895 {
1896  char buf[1024];
1897  struct Buffer fcc = mutt_buffer_make(0); /* where to copy this message */
1898  FILE *fp_tmp = NULL;
1899  struct Body *pbody = NULL;
1900  int i;
1901  bool free_clear_content = false;
1902 
1903  struct Body *clear_content = NULL;
1904  char *pgpkeylist = NULL;
1905  /* save current value of "pgp_sign_as" and "smime_default_key" */
1906  char *pgp_signas = NULL;
1907  char *smime_signas = NULL;
1908  const char *tag = NULL;
1909  char *err = NULL;
1910  char *ctype = NULL;
1911  char *finalpath = NULL;
1912  struct EmailNode *en = NULL;
1913  struct Email *e_cur = NULL;
1914 
1915  if (el)
1916  en = STAILQ_FIRST(el);
1917  if (en)
1918  e_cur = STAILQ_NEXT(en, entries) ? NULL : en->email;
1919 
1920  int rc = -1;
1921 
1922 #ifdef USE_NNTP
1923  if (flags & SEND_NEWS)
1924  OptNewsSend = true;
1925  else
1926  OptNewsSend = false;
1927 #endif
1928 
1929  if (!flags && !e_templ && (C_Recall != MUTT_NO) &&
1930  mutt_num_postponed(ctx ? ctx->mailbox : NULL, true))
1931  {
1932  /* If the user is composing a new message, check to see if there
1933  * are any postponed messages first. */
1934  enum QuadOption ans =
1935  query_quadoption(C_Recall, _("Recall postponed message?"));
1936  if (ans == MUTT_ABORT)
1937  return rc;
1938 
1939  if (ans == MUTT_YES)
1940  flags |= SEND_POSTPONED;
1941  }
1942 
1943  /* Allocate the buffer due to the long lifetime, but
1944  * pre-resize it to ensure there are no NULL data field issues */
1945  mutt_buffer_alloc(&fcc, 1024);
1946 
1947  if (flags & SEND_POSTPONED)
1948  {
1950  pgp_signas = mutt_str_strdup(C_PgpSignAs);
1952  smime_signas = mutt_str_strdup(C_SmimeSignAs);
1953  }
1954 
1955  /* Delay expansion of aliases until absolutely necessary--shouldn't
1956  * be necessary unless we are prompting the user or about to execute a
1957  * send-hook. */
1958 
1959  if (!e_templ)
1960  {
1961  e_templ = email_new();
1962 
1963  if (flags == SEND_POSTPONED)
1964  {
1965  rc = mutt_get_postponed(ctx, e_templ, &e_cur, &fcc);
1966  if (rc < 0)
1967  {
1968  flags = SEND_POSTPONED;
1969  goto cleanup;
1970  }
1971  flags = rc;
1972 #ifdef USE_NNTP
1973  /* If postponed message is a news article, it have
1974  * a "Newsgroups:" header line, then set appropriate flag. */
1975  if (e_templ->env->newsgroups)
1976  {
1977  flags |= SEND_NEWS;
1978  OptNewsSend = true;
1979  }
1980  else
1981  {
1982  flags &= ~SEND_NEWS;
1983  OptNewsSend = false;
1984  }
1985 #endif
1986  }
1987 
1988  if (flags & (SEND_POSTPONED | SEND_RESEND))
1989  {
1990  fp_tmp = mutt_file_fopen(e_templ->content->filename, "a+");
1991  if (!fp_tmp)
1992  {
1993  mutt_perror(e_templ->content->filename);
1994  goto cleanup;
1995  }
1996  }
1997 
1998  if (!e_templ->env)
1999  e_templ->env = mutt_env_new();
2000  }
2001 
2002  /* Parse and use an eventual list-post header */
2003  if ((flags & SEND_LIST_REPLY) && e_cur && e_cur->env && e_cur->env->list_post)
2004  {
2005  /* Use any list-post header as a template */
2006  mutt_parse_mailto(e_templ->env, NULL, e_cur->env->list_post);
2007  /* We don't let them set the sender's address. */
2008  mutt_addrlist_clear(&e_templ->env->from);
2009  }
2010 
2011  if (!(flags & (SEND_KEY | SEND_POSTPONED | SEND_RESEND)))
2012  {
2013  /* When SEND_DRAFT_FILE is set, the caller has already
2014  * created the "parent" body structure. */
2015  if (!(flags & SEND_DRAFT_FILE))
2016  {
2017  pbody = mutt_body_new();
2018  pbody->next = e_templ->content; /* don't kill command-line attachments */
2019  e_templ->content = pbody;
2020 
2021  ctype = mutt_str_strdup(C_ContentType);
2022  if (!ctype)
2023  ctype = mutt_str_strdup("text/plain");
2024  mutt_parse_content_type(ctype, e_templ->content);
2025  FREE(&ctype);
2026  e_templ->content->unlink = true;
2027  e_templ->content->use_disp = false;
2028  e_templ->content->disposition = DISP_INLINE;
2029 
2030  if (tempfile)
2031  {
2032  fp_tmp = mutt_file_fopen(tempfile, "a+");
2033  e_templ->content->filename = mutt_str_strdup(tempfile);
2034  }
2035  else
2036  {
2037  mutt_mktemp(buf, sizeof(buf));
2038  fp_tmp = mutt_file_fopen(buf, "w+");
2039  e_templ->content->filename = mutt_str_strdup(buf);
2040  }
2041  }
2042  else
2043  fp_tmp = mutt_file_fopen(e_templ->content->filename, "a+");
2044 
2045  if (!fp_tmp)
2046  {
2047  mutt_debug(LL_DEBUG1, "can't create tempfile %s (errno=%d)\n",
2048  e_templ->content->filename, errno);
2049  mutt_perror(e_templ->content->filename);
2050  goto cleanup;
2051  }
2052  }
2053 
2054  /* this is handled here so that the user can match ~f in send-hook */
2055  if (e_cur && C_ReverseName && !(flags & (SEND_POSTPONED | SEND_RESEND)))
2056  {
2057  /* We shouldn't have to worry about alias expansion here since we are
2058  * either replying to a real or postponed message, therefore no aliases
2059  * should exist since the user has not had the opportunity to add
2060  * addresses to the list. We just have to ensure the postponed messages
2061  * have their aliases expanded. */
2062 
2063  if (!TAILQ_EMPTY(&e_templ->env->from))
2064  {
2065  mutt_debug(LL_DEBUG5, "e_templ->env->from before set_reverse_name: %s\n",
2066  TAILQ_FIRST(&e_templ->env->from)->mailbox);
2067  mutt_addrlist_clear(&e_templ->env->from);
2068  }
2069  set_reverse_name(&e_templ->env->from, e_cur->env);
2070  }
2071  if (e_cur && C_ReplyWithXorig && !(flags & (SEND_POSTPONED | SEND_RESEND | SEND_FORWARD)))
2072  {
2073  /* We shouldn't have to worry about freeing 'e_templ->env->from' before
2074  * setting it here since this code will only execute when doing some
2075  * sort of reply. The pointer will only be set when using the -H command
2076  * line option.
2077  *
2078  * If there is already a from address recorded in 'e_templ->env->from',
2079  * then it theoretically comes from C_ReverseName handling, and we don't use
2080  * the 'X-Orig-To header'. */
2081  if (!TAILQ_EMPTY(&e_cur->env->x_original_to) && TAILQ_EMPTY(&e_templ->env->from))
2082  {
2083  mutt_addrlist_copy(&e_templ->env->from, &e_cur->env->x_original_to, false);
2084  mutt_debug(LL_DEBUG5, "e_templ->env->from extracted from X-Original-To: header: %s\n",
2085  TAILQ_FIRST(&e_templ->env->from)->mailbox);
2086  }
2087  }
2088 
2089  if (!(flags & (SEND_POSTPONED | SEND_RESEND)) &&
2090  !((flags & SEND_DRAFT_FILE) && C_ResumeDraftFiles))
2091  {
2092  if ((flags & (SEND_REPLY | SEND_FORWARD | SEND_TO_SENDER)) && ctx &&
2093  (envelope_defaults(e_templ->env, ctx->mailbox, el, flags) == -1))
2094  {
2095  goto cleanup;
2096  }
2097 
2098  if (C_Hdrs)
2099  process_user_recips(e_templ->env);
2100 
2101  /* Expand aliases and remove duplicates/crossrefs */
2102  mutt_expand_aliases_env(e_templ->env);
2103 
2104  if (flags & SEND_REPLY)
2105  mutt_fix_reply_recipients(e_templ->env);
2106 
2107 #ifdef USE_NNTP
2108  if ((flags & SEND_NEWS) && ctx && (ctx->mailbox->type == MUTT_NNTP) &&
2109  !e_templ->env->newsgroups)
2110  {
2111  e_templ->env->newsgroups =
2112  mutt_str_strdup(((struct NntpMboxData *) ctx->mailbox->mdata)->group);
2113  }
2114 #endif
2115 
2116  if (!(flags & (SEND_MAILX | SEND_BATCH)) &&
2117  !(C_Autoedit && C_EditHeaders) && !((flags & SEND_REPLY) && C_FastReply))
2118  {
2119  if (edit_envelope(e_templ->env, flags) == -1)
2120  goto cleanup;
2121  }
2122 
2123  /* the from address must be set here regardless of whether or not
2124  * $use_from is set so that the '~P' (from you) operator in send-hook
2125  * patterns will work. if $use_from is unset, the from address is killed
2126  * after send-hooks are evaluated */
2127 
2128  const bool killfrom = TAILQ_EMPTY(&e_templ->env->from);
2129  if (killfrom)
2130  {
2132  }
2133 
2134  if ((flags & SEND_REPLY) && e_cur)
2135  {
2136  /* change setting based upon message we are replying to */
2137  mutt_message_hook(ctx ? ctx->mailbox : NULL, e_cur, MUTT_REPLY_HOOK);
2138 
2139  /* set the replied flag for the message we are generating so that the
2140  * user can use ~Q in a send-hook to know when reply-hook's are also
2141  * being used. */
2142  e_templ->replied = true;
2143  }
2144 
2145  /* change settings based upon recipients */
2146 
2147  mutt_message_hook(NULL, e_templ, MUTT_SEND_HOOK);
2148 
2149  /* Unset the replied flag from the message we are composing since it is
2150  * no longer required. This is done here because the FCC'd copy of
2151  * this message was erroneously get the 'R'eplied flag when stored in
2152  * a maildir-style mailbox. */
2153  e_templ->replied = false;
2154 
2155  /* $use_from and/or $from might have changed in a send-hook */
2156  if (killfrom)
2157  {
2158  mutt_addrlist_clear(&e_templ->env->from);
2159  if (C_UseFrom && !(flags & (SEND_POSTPONED | SEND_RESEND)))
2161  }
2162 
2163  if (C_Hdrs)
2164  process_user_header(e_templ->env);
2165 
2166  if (flags & SEND_BATCH)
2167  {
2168  if (mutt_file_copy_stream(stdin, fp_tmp) < 1)
2169  goto cleanup;
2170  }
2171 
2172  if (C_SigOnTop && !(flags & (SEND_MAILX | SEND_KEY | SEND_BATCH)) &&
2173  C_Editor && (mutt_str_strcmp(C_Editor, "builtin") != 0))
2174  {
2175  append_signature(fp_tmp);
2176  }
2177 
2178  /* include replies/forwarded messages, unless we are given a template */
2179  if (!tempfile && (ctx || !(flags & (SEND_REPLY | SEND_FORWARD))) &&
2180  (generate_body(fp_tmp, e_templ, flags, ctx ? ctx->mailbox : NULL, el) == -1))
2181  {
2182  goto cleanup;
2183  }
2184 
2185  if (!C_SigOnTop && !(flags & (SEND_MAILX | SEND_KEY | SEND_BATCH)) &&
2186  C_Editor && (mutt_str_strcmp(C_Editor, "builtin") != 0))
2187  {
2188  append_signature(fp_tmp);
2189  }
2190  }
2191 
2192  /* Only set format=flowed for new messages. postponed/resent/draftfiles
2193  * should respect the original email.
2194  *
2195  * This is set here so that send-hook can be used to turn the option on. */
2196  if (!(flags & (SEND_KEY | SEND_POSTPONED | SEND_RESEND | SEND_DRAFT_FILE)))
2197  {
2198  if (C_TextFlowed && (e_templ->content->type == TYPE_TEXT) &&
2199  (mutt_str_strcasecmp(e_templ->content->subtype, "plain") == 0))
2200  {
2201  mutt_param_set(&e_templ->content->parameter, "format", "flowed");
2202  }
2203  }
2204 
2205  /* This hook is even called for postponed messages, and can, e.g., be
2206  * used for setting the editor, the sendmail path, or the
2207  * envelope sender. */
2208  mutt_message_hook(NULL, e_templ, MUTT_SEND2_HOOK);
2209 
2210  /* wait until now to set the real name portion of our return address so
2211  * that $realname can be set in a send-hook */
2212  {
2213  struct Address *from = TAILQ_FIRST(&e_templ->env->from);
2214  if (from && !from->personal && !(flags & (SEND_RESEND | SEND_POSTPONED)))
2216  }
2217 
2218  if (!(((WithCrypto & APPLICATION_PGP) != 0) && (flags & SEND_KEY)))
2219  mutt_file_fclose(&fp_tmp);
2220 
2221  if (flags & SEND_MAILX)
2222  {
2223  if (mutt_builtin_editor(e_templ->content->filename, e_templ, e_cur) == -1)
2224  goto cleanup;
2225  }
2226  else if (!(flags & SEND_BATCH))
2227  {
2228  struct stat st;
2229  time_t mtime = mutt_file_decrease_mtime(e_templ->content->filename, NULL);
2230 
2231  mutt_update_encoding(e_templ->content);
2232 
2233  /* Select whether or not the user's editor should be called now. We
2234  * don't want to do this when:
2235  * 1) we are sending a key/cert
2236  * 2) we are forwarding a message and the user doesn't want to edit it.
2237  * This is controlled by the quadoption $forward_edit. However, if
2238  * both $edit_headers and $autoedit are set, we want to ignore the
2239  * setting of $forward_edit because the user probably needs to add the
2240  * recipients. */
2241  if (!(flags & SEND_KEY) &&
2242  (((flags & SEND_FORWARD) == 0) || (C_EditHeaders && C_Autoedit) ||
2243  (query_quadoption(C_ForwardEdit, _("Edit forwarded message?")) == MUTT_YES)))
2244  {
2245  /* If the this isn't a text message, look for a mailcap edit command */
2246  if (mutt_needs_mailcap(e_templ->content))
2247  {
2248  if (!mutt_edit_attachment(e_templ->content))
2249  goto cleanup;
2250  }
2251  else if (!C_Editor || (mutt_str_strcmp("builtin", C_Editor) == 0))
2252  mutt_builtin_editor(e_templ->content->filename, e_templ, e_cur);
2253  else if (C_EditHeaders)
2254  {
2255  mutt_env_to_local(e_templ->env);
2256  mutt_edit_headers(C_Editor, e_templ->content->filename, e_templ, &fcc);
2257  mutt_env_to_intl(e_templ->env, NULL, NULL);
2258  }
2259  else
2260  {
2262  if (stat(e_templ->content->filename, &st) == 0)
2263  {
2264  if (mtime != st.st_mtime)
2265  fix_end_of_file(e_templ->content->filename);
2266  }
2267  else
2268  mutt_perror(e_templ->content->filename);
2269  }
2270 
2271  mutt_message_hook(NULL, e_templ, MUTT_SEND2_HOOK);
2272  }
2273 
2274  if (!(flags & (SEND_POSTPONED | SEND_FORWARD | SEND_KEY | SEND_RESEND | SEND_DRAFT_FILE)))
2275  {
2276  if (stat(e_templ->content->filename, &st) == 0)
2277  {
2278  /* if the file was not modified, bail out now */
2279  if ((mtime == st.st_mtime) && !e_templ->content->next &&
2281  _("Abort unmodified message?")) == MUTT_YES))
2282  {
2283  mutt_message(_("Aborted unmodified message"));
2284  goto cleanup;
2285  }
2286  }
2287  else
2288  mutt_perror(e_templ->content->filename);
2289  }
2290  }
2291 
2292  /* Set the message security unless:
2293  * 1) crypto support is not enabled (WithCrypto==0)
2294  * 2) pgp: header field was present during message editing with $edit_headers (e_templ->security != 0)
2295  * 3) we are resending a message
2296  * 4) we are recalling a postponed message (don't override the user's saved settings)
2297  * 5) we are in mailx mode
2298  * 6) we are in batch mode
2299  *
2300  * This is done after allowing the user to edit the message so that security
2301  * settings can be configured with send2-hook and $edit_headers. */
2302  if ((WithCrypto != 0) && (e_templ->security == 0) &&
2303  !(flags & (SEND_BATCH | SEND_MAILX | SEND_POSTPONED | SEND_RESEND)))
2304  {
2305  if (
2306 #ifdef USE_AUTOCRYPT
2308 #else
2309  0
2310 #endif
2311  && e_cur && (e_cur->security & SEC_AUTOCRYPT))
2312  {
2314  }
2315  else
2316  {
2317  if (C_CryptAutosign)
2318  e_templ->security |= SEC_SIGN;
2319  if (C_CryptAutoencrypt)
2320  e_templ->security |= SEC_ENCRYPT;
2321  if (C_CryptReplyencrypt && e_cur && (e_cur->security & SEC_ENCRYPT))
2322  e_templ->security |= SEC_ENCRYPT;
2323  if (C_CryptReplysign && e_cur && (e_cur->security & SEC_SIGN))
2324  e_templ->security |= SEC_SIGN;
2325  if (C_CryptReplysignencrypted && e_cur && (e_cur->security & SEC_ENCRYPT))
2326  e_templ->security |= SEC_SIGN;
2327  if (((WithCrypto & APPLICATION_PGP) != 0) &&
2329  {
2330  if (C_PgpAutoinline)
2331  e_templ->security |= SEC_INLINE;
2332  if (C_PgpReplyinline && e_cur && (e_cur->security & SEC_INLINE))
2333  e_templ->security |= SEC_INLINE;
2334  }
2335  }
2336 
2337  if (e_templ->security || C_CryptOpportunisticEncrypt)
2338  {
2339  /* When replying / forwarding, use the original message's
2340  * crypto system. According to the documentation,
2341  * smime_is_default should be disregarded here.
2342  *
2343  * Problem: At least with forwarding, this doesn't really
2344  * make much sense. Should we have an option to completely
2345  * disable individual mechanisms at run-time? */
2346  if (e_cur)
2347  {
2348  if (((WithCrypto & APPLICATION_PGP) != 0) && C_CryptAutopgp &&
2349  (e_cur->security & APPLICATION_PGP))
2350  {
2351  e_templ->security |= APPLICATION_PGP;
2352  }
2353  else if (((WithCrypto & APPLICATION_SMIME) != 0) && C_CryptAutosmime &&
2354  (e_cur->security & APPLICATION_SMIME))
2355  {
2356  e_templ->security |= APPLICATION_SMIME;
2357  }
2358  }
2359 
2360  /* No crypto mechanism selected? Use availability + smime_is_default
2361  * for the decision. */
2362  if (!(e_templ->security & (APPLICATION_SMIME | APPLICATION_PGP)))
2363  {
2364  if (((WithCrypto & APPLICATION_SMIME) != 0) && C_CryptAutosmime && C_SmimeIsDefault)
2365  {
2366  e_templ->security |= APPLICATION_SMIME;
2367  }
2368  else if (((WithCrypto & APPLICATION_PGP) != 0) && C_CryptAutopgp)
2369  {
2370  e_templ->security |= APPLICATION_PGP;
2371  }
2372  else if (((WithCrypto & APPLICATION_SMIME) != 0) && C_CryptAutosmime)
2373  {
2374  e_templ->security |= APPLICATION_SMIME;
2375  }
2376  }
2377  }
2378 
2379  /* opportunistic encrypt relies on SMIME or PGP already being selected */
2381  {
2382  /* If something has already enabled encryption, e.g. C_CryptAutoencrypt
2383  * or C_CryptReplyencrypt, then don't enable opportunistic encrypt for
2384  * the message. */
2385  if (!(e_templ->security & (SEC_ENCRYPT | SEC_AUTOCRYPT)))
2386  {
2387  e_templ->security |= SEC_OPPENCRYPT;
2388  crypt_opportunistic_encrypt(e_templ);
2389  }
2390  }
2391 
2392  /* No permissible mechanisms found. Don't sign or encrypt. */
2393  if (!(e_templ->security & (APPLICATION_SMIME | APPLICATION_PGP)))
2394  e_templ->security = SEC_NO_FLAGS;
2395  }
2396 
2397  /* Deal with the corner case where the crypto module backend is not available.
2398  * This can happen if configured without PGP/SMIME and with GPGME, but
2399  * $crypt_use_gpgme is unset. */
2400  if (e_templ->security && !crypt_has_module_backend(e_templ->security))
2401  {
2402  mutt_error(_(
2403  "No crypto backend configured. Disabling message security setting."));
2404  e_templ->security = SEC_NO_FLAGS;
2405  }
2406 
2407  /* specify a default fcc. if we are in batchmode, only save a copy of
2408  * the message if the value of $copy is yes or ask-yes */
2409 
2410  if (mutt_buffer_is_empty(&fcc) && !(flags & SEND_POSTPONED_FCC) &&
2411  (!(flags & SEND_BATCH) || (C_Copy & 0x1)))
2412  {
2413  /* set the default FCC */
2414  const bool killfrom = TAILQ_EMPTY(&e_templ->env->from);
2415  if (killfrom)
2416  {
2418  }
2419  mutt_select_fcc(&fcc, e_templ);
2420  if (killfrom)
2421  {
2422  mutt_addrlist_clear(&e_templ->env->from);
2423  }
2424  }
2425 
2426  mutt_rfc3676_space_stuff(e_templ);
2427 
2428  mutt_update_encoding(e_templ->content);
2429 
2430  if (!(flags & (SEND_MAILX | SEND_BATCH)))
2431  {
2432  main_loop:
2433 
2435  i = mutt_compose_menu(e_templ, &fcc, e_cur,
2437  if (i == -1)
2438  {
2439 /* abort */
2440 #ifdef USE_NNTP
2441  if (flags & SEND_NEWS)
2442  mutt_message(_("Article not posted"));
2443  else
2444 #endif
2445  mutt_message(_("Mail not sent"));
2446  goto cleanup;
2447  }
2448  else if (i == 1)
2449  {
2450  if (postpone_message(e_templ, e_cur, mutt_b2s(&fcc), flags) != 0)
2451  goto main_loop;
2452  mutt_message(_("Message postponed"));
2453  rc = 1;
2454  goto cleanup;
2455  }
2456  }
2457 
2458 #ifdef USE_NNTP
2459  if (!(flags & SEND_NEWS))
2460 #endif
2461  if ((mutt_addrlist_count_recips(&e_templ->env->to) == 0) &&
2462  (mutt_addrlist_count_recips(&e_templ->env->cc) == 0) &&
2463  (mutt_addrlist_count_recips(&e_templ->env->bcc) == 0))
2464  {
2465  if (flags & SEND_BATCH)
2466  {
2467  puts(_("No recipients specified"));
2468  goto cleanup;
2469  }
2470 
2471  mutt_error(_("No recipients specified"));
2472  goto main_loop;
2473  }
2474 
2475  if (mutt_env_to_intl(e_templ->env, &tag, &err))
2476  {
2477  mutt_error(_("Bad IDN in '%s': '%s'"), tag, err);
2478  FREE(&err);
2479  if (flags & SEND_BATCH)
2480  goto cleanup;
2481  goto main_loop;
2482  }
2483 
2484  if (!e_templ->env->subject && !(flags & SEND_BATCH) &&
2485  (query_quadoption(C_AbortNosubject, _("No subject, abort sending?")) != MUTT_NO))
2486  {
2487  /* if the abort is automatic, print an error message */
2488  if (C_AbortNosubject == MUTT_YES)
2489  mutt_error(_("No subject specified"));
2490  goto main_loop;
2491  }
2492 #ifdef USE_NNTP
2493  if ((flags & SEND_NEWS) && !e_templ->env->subject)
2494  {
2495  mutt_error(_("No subject specified"));
2496  goto main_loop;
2497  }
2498 
2499  if ((flags & SEND_NEWS) && !e_templ->env->newsgroups)
2500  {
2501  mutt_error(_("No newsgroup specified"));
2502  goto main_loop;
2503  }
2504 #endif
2505 
2506  if (!(flags & SEND_BATCH) && (C_AbortNoattach != MUTT_NO) &&
2507  !e_templ->content->next && (e_templ->content->type == TYPE_TEXT) &&
2508  (mutt_str_strcasecmp(e_templ->content->subtype, "plain") == 0) &&
2509  search_attach_keyword(e_templ->content->filename) &&
2511  _("No attachments, cancel sending?")) != MUTT_NO))
2512  {
2513  /* if the abort is automatic, print an error message */
2514  if (C_AbortNoattach == MUTT_YES)
2515  {
2516  mutt_error(_("Message contains text matching "
2517  "\"$abort_noattach_regex\". Not sending."));
2518  }
2519  goto main_loop;
2520  }
2521 
2522  if (e_templ->content->next)
2523  e_templ->content = mutt_make_multipart(e_templ->content);
2524 
2525  /* Ok, we need to do it this way instead of handling all fcc stuff in
2526  * one place in order to avoid going to main_loop with encoded "env"
2527  * in case of error. Ugh. */
2528 
2529  mutt_encode_descriptions(e_templ->content, true);
2530 
2531  /* Make sure that clear_content and free_clear_content are
2532  * properly initialized -- we may visit this particular place in
2533  * the code multiple times, including after a failed call to
2534  * mutt_protect(). */
2535 
2536  clear_content = NULL;
2537  free_clear_content = false;
2538 
2539  if (WithCrypto)
2540  {
2541  if (e_templ->security & (SEC_ENCRYPT | SEC_SIGN | SEC_AUTOCRYPT))
2542  {
2543  /* save the decrypted attachments */
2544  clear_content = e_templ->content;
2545 
2546  if ((crypt_get_keys(e_templ, &pgpkeylist, 0) == -1) ||
2547  (mutt_protect(e_templ, pgpkeylist, false) == -1))
2548  {
2549  e_templ->content = mutt_remove_multipart(e_templ->content);
2550 
2551  FREE(&pgpkeylist);
2552 
2553  decode_descriptions(e_templ->content);
2554  goto main_loop;
2555  }
2556  mutt_encode_descriptions(e_templ->content, false);
2557  }
2558 
2559  /* at this point, e_templ->content is one of the following three things:
2560  * - multipart/signed. In this case, clear_content is a child
2561  * - multipart/encrypted. In this case, clear_content exists independently
2562  * - application/pgp. In this case, clear_content exists independently
2563  * - something else. In this case, it's the same as clear_content */
2564 
2565  /* This is ugly -- lack of "reporting back" from mutt_protect(). */
2566 
2567  if (clear_content && (e_templ->content != clear_content) &&
2568  (e_templ->content->parts != clear_content))
2569  free_clear_content = true;
2570  }
2571 
2572  if (!OptNoCurses && !(flags & SEND_MAILX))
2573  mutt_message(_("Sending message..."));
2574 
2575  mutt_prepare_envelope(e_templ->env, true);
2576 
2577  if (C_FccBeforeSend)
2578  save_fcc(e_templ, &fcc, clear_content, pgpkeylist, flags, &finalpath);
2579 
2580  i = send_message(e_templ);
2581  if (i < 0)
2582  {
2583  if (!(flags & SEND_BATCH))
2584  {
2585  if (!WithCrypto)
2586  ;
2587  else if ((e_templ->security & (SEC_ENCRYPT | SEC_AUTOCRYPT)) ||
2588  ((e_templ->security & SEC_SIGN) && (e_templ->content->type == TYPE_APPLICATION)))
2589  {
2590  if (e_templ->content != clear_content)
2591  {
2592  mutt_body_free(&e_templ->content); /* destroy PGP data */
2593  e_templ->content = clear_content; /* restore clear text. */
2594  }
2595  }
2596  else if ((e_templ->security & SEC_SIGN) && (e_templ->content->type == TYPE_MULTIPART))
2597  {
2598  mutt_body_free(&e_templ->content->parts->next); /* destroy sig */
2599  e_templ->content = mutt_remove_multipart(e_templ->content);
2600  }
2601 
2602  FREE(&pgpkeylist);
2603  mutt_env_free(&e_templ->content->mime_headers); /* protected headers */
2604  e_templ->content = mutt_remove_multipart(e_templ->content);
2605  decode_descriptions(e_templ->content);
2606  mutt_unprepare_envelope(e_templ->env);
2607  FREE(&finalpath);
2608  goto main_loop;
2609  }
2610  else
2611  {
2612  puts(_("Could not send the message"));
2613  goto cleanup;
2614  }
2615  }
2616 
2617  if (!C_FccBeforeSend)
2618  save_fcc(e_templ, &fcc, clear_content, pgpkeylist, flags, &finalpath);
2619 
2620  if (!OptNoCurses && !(flags & SEND_MAILX))
2621  {
2622  mutt_message((i != 0) ? _("Sending in background") :
2623  (flags & SEND_NEWS) ? _("Article posted") : /* USE_NNTP */
2624  _("Mail sent"));
2625 #ifdef USE_NOTMUCH
2626  if (C_NmRecord)
2627  nm_record_message(ctx ? ctx->mailbox : NULL, finalpath, e_cur);
2628 #endif
2629  mutt_sleep(0);
2630  }
2631 
2632  if (WithCrypto)
2633  FREE(&pgpkeylist);
2634 
2635  if ((WithCrypto != 0) && free_clear_content)
2636  mutt_body_free(&clear_content);
2637 
2638  /* set 'replied' flag only if the user didn't change/remove
2639  * In-Reply-To: and References: headers during edit */
2640  if (flags & SEND_REPLY)
2641  {
2642  if (!(flags & SEND_POSTPONED) && ctx && ctx->mailbox)
2643  {
2644  STAILQ_FOREACH(en, el, entries)
2645  {
2646  mutt_set_flag(ctx->mailbox, en->email, MUTT_REPLIED, is_reply(en->email, e_templ));
2647  }
2648  }
2649  }
2650 
2651  rc = 0;
2652 
2653 cleanup:
2654  mutt_buffer_dealloc(&fcc);
2655 
2656  if (flags & SEND_POSTPONED)
2657  {
2658  if (WithCrypto & APPLICATION_PGP)
2659  {
2660  FREE(&C_PgpSignAs);
2661  C_PgpSignAs = pgp_signas;
2662  }
2663  if (WithCrypto & APPLICATION_SMIME)
2664  {
2665  FREE(&C_SmimeSignAs);
2666  C_SmimeSignAs = smime_signas;
2667  }
2668  }
2669 
2670  mutt_file_fclose(&fp_tmp);
2671  if (!(flags & SEND_NO_FREE_HEADER))
2672  email_free(&e_templ);
2673 
2674  FREE(&finalpath);
2675  return rc;
2676 }
#define MUTT_SEND_HOOK
send-hook: when composing a new email
Definition: hook.h:47
int nm_record_message(struct Mailbox *m, char *path, struct Email *e)
Add a message to the Notmuch database.
void mutt_fix_reply_recipients(struct Envelope *env)
Remove duplicate recipients.
Definition: send.c:911
bool C_Hdrs
Config: Add custom headers to outgoing mail.
Definition: send.c:115
char * filename
when sending a message, this is the file to which this structure refers
Definition: body.h:46
enum MailboxType type
Mailbox type.
Definition: mailbox.h:105
WHERE bool C_Autocrypt
Config: Enables the Autocrypt feature.
Definition: globals.h:200
struct Envelope * mime_headers
Memory hole protected headers.
Definition: body.h:63
struct Body * mutt_remove_multipart(struct Body *b)
Extract the multipart body if it exists.
Definition: sendlib.c:1767
#define mutt_set_flag(m, e, flag, bf)
Definition: protos.h:70
#define WithCrypto
Definition: lib.h:163
#define SEND_POSTPONED_FCC
Used by mutt_get_postponed() to signal that the x-mutt-fcc header field was present.
Definition: send.h:97
#define SEND_TO_SENDER
Compose new email to sender.
Definition: send.h:100
The envelope/body of an email.
Definition: email.h:37
#define TAILQ_FIRST(head)
Definition: queue.h:716
#define mutt_perror(...)
Definition: logging.h:85
static int postpone_message(struct Email *e_post, struct Email *e_cur, const char *fcc, SendFlags flags)
Save an Email for another day.
Definition: send.c:1789
if(!test_colorize_)
Definition: acutest.h:484
static void fix_end_of_file(const char *data)
Ensure a file ends with a linefeed.
Definition: send.c:1481
WHERE bool C_AutocryptReply
Config: Replying to an autocrypt email automatically enables autocrypt in the reply.
Definition: globals.h:201
&#39;NNTP&#39; (Usenet) Mailbox type
Definition: mailbox.h:52
unsigned char C_AbortNoattach
Config: Abort sending the email if attachments are missing.
Definition: send.c:90
static bool search_attach_keyword(char *filename)
Search an email for &#39;attachment&#39; keywords.
Definition: send.c:1568
#define SEC_NO_FLAGS
No flags are set.
Definition: lib.h:124
User aborted the question (with Ctrl-G)
Definition: quad.h:38
enum QuadOption query_quadoption(enum QuadOption opt, const char *prompt)
Ask the user a quad-question.
Definition: init.c:1099
#define mutt_message(...)
Definition: logging.h:83
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:40
struct AddressList bcc
Email&#39;s &#39;Bcc&#39; list.
Definition: envelope.h:60
void mutt_addrlist_clear(struct AddressList *al)
Unlink and free all Address in an AddressList.
Definition: address.c:1382
#define SEND_DRAFT_FILE
Used by the -H flag.
Definition: send.h:99
#define SEC_ENCRYPT
Email is encrypted.
Definition: lib.h:125
void mutt_expand_aliases_env(struct Envelope *env)
Expand aliases in all the fields of an Envelope.
Definition: alias.c:317
static int envelope_defaults(struct Envelope *env, struct Mailbox *m, struct EmailList *el, SendFlags flags)
Fill in some defaults for a new email.
Definition: send.c:1031
static void process_user_header(struct Envelope *env)
Process the user headers.
Definition: send.c:379
#define SEND_FORWARD
Forward email.
Definition: send.h:91
void mutt_addrlist_copy(struct AddressList *dst, const struct AddressList *src, bool prune)
Copy a list of addresses into another list.
Definition: address.c:728
bool C_FccBeforeSend
Config: Save FCCs before sending the message.
Definition: send.c:107
struct Body * content
List of MIME parts.
Definition: email.h:90
struct Buffer mutt_buffer_make(size_t size)
Make a new buffer on the stack.
Definition: buffer.c:61
int mutt_edit_attachment(struct Body *a)
Edit an attachment.
Definition: mutt_attach.c:257
String manipulation buffer.
Definition: buffer.h:33
#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:93
WHERE bool C_PgpAutoinline
Config: Use old-style inline PGP messages (not recommended)
Definition: globals.h:277
struct Body * next
next attachment in the list
Definition: body.h:53
An email address.
Definition: address.h:34
WHERE unsigned char C_Copy
Config: Save outgoing emails to $record.
Definition: globals.h:180
WHERE bool OptNoCurses
(pseudo) when sending in batch mode
Definition: options.h:49
#define SEC_AUTOCRYPT
(Autocrypt) Message will be, or was Autocrypt encrypt+signed
Definition: lib.h:134
bool C_CryptAutosign
Config: Automatically PGP sign all outgoing mail.
Definition: send.c:99
int crypt_get_keys(struct Email *e, char **keylist, bool oppenc_mode)
Check we have all the keys we need.
Definition: crypt.c:958
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:309
#define SEND_POSTPONED
Recall a postponed email.
Definition: send.h:92
void mutt_buffer_pretty_mailbox(struct Buffer *buf)
Shorten a mailbox path using &#39;~&#39; or &#39;=&#39;.
Definition: muttlib.c:689
bool C_CryptReplysign
Config: Sign replies to signed messages.
Definition: send.c:102
Messages that have been replied to.
Definition: mutt.h:93
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:2998
unsigned int disposition
content-disposition
Definition: body.h:67
#define SEC_INLINE
Email has an inline signature.
Definition: lib.h:132
WHERE bool C_SmimeIsDefault
Config: Use SMIME rather than PGP by default.
Definition: globals.h:273
bool C_CryptAutosmime
Config: Allow automatic SMIME functions.
Definition: send.c:100
#define SEND_MAILX
Send email in Mailx compatibility mode.
Definition: send.h:94
void mutt_sleep(short s)
Sleep for a while.
Definition: muttlib.c:1535
WHERE bool C_EditHeaders
Config: Let the user edit the email headers whilst editing an email.
Definition: globals.h:212
struct Mailbox * mailbox
Definition: context.h:51
unsigned char C_Recall
Config: Recall postponed mesaages when asked to compose a message.
Definition: send.c:125
bool mutt_parse_mailto(struct Envelope *e, char **body, const char *src)
Parse a mailto:// url.
Definition: parse.c:1595
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:92
struct AddressList from
Email&#39;s &#39;From&#39; list.
Definition: envelope.h:57
void mutt_update_encoding(struct Body *a)
Update the encoding type.
Definition: sendlib.c:1480
static void process_user_recips(struct Envelope *env)
Process the user headers.
Definition: send.c:352
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:153
struct Envelope * env
Envelope information.
Definition: email.h:89
static void decode_descriptions(struct Body *b)
rfc2047 decode them in case of an error
Definition: send.c:1464
struct AddressList cc
Email&#39;s &#39;Cc&#39; list.
Definition: envelope.h:59
WHERE bool C_Autoedit
Config: Skip the initial compose menu and edit the email.
Definition: globals.h:203
void mutt_buffer_dealloc(struct Buffer *buf)
Release the memory allocated by a buffer.
Definition: buffer.c:294
#define SEND_LIST_REPLY
Reply to mailing list.
Definition: send.h:90
static bool is_reply(struct Email *reply, struct Email *orig)
Is one email a reply to another?
Definition: send.c:1550
void * mdata
Driver specific data.
Definition: mailbox.h:136
struct Envelope * mutt_env_new(void)
Create a new Envelope.
Definition: envelope.c:42
struct Body * mutt_make_multipart(struct Body *b)
Create a multipart email.
Definition: sendlib.c:1741
#define SEND_KEY
Mail a PGP public key.
Definition: send.h:95
char * subtype
content-type subtype
Definition: body.h:37
#define mutt_b2s(buf)
Definition: buffer.h:41
bool C_FastReply
Config: Don&#39;t prompt for the recipients and subject when replying/forwarding.
Definition: send.c:105
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition: lib.h:138
#define SEND_RESEND
Reply using the current email as a template.
Definition: send.h:96
void mutt_unprepare_envelope(struct Envelope *env)
Undo the encodings of mutt_prepare_envelope()
Definition: sendlib.c:3037
#define mutt_mktemp(buf, buflen)
Definition: muttlib.h:78
struct Address * mutt_default_from(void)
Get a default &#39;from&#39; Address.
Definition: send.c:1333
WHERE bool C_CryptOpportunisticEncrypt
Config: Enable encryption when the recipient&#39;s key is available.
Definition: globals.h:268
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: lib.h:137
bool C_ReverseName
Config: Set the &#39;From&#39; from the address the email was sent to.
Definition: send.c:129
User answered &#39;No&#39;, or assume &#39;No&#39;.
Definition: quad.h:39
void mutt_encode_descriptions(struct Body *b, bool recurse)
rfc2047 encode the content-descriptions
Definition: send.c:1447
void mutt_select_fcc(struct Buffer *path, struct Email *e)
Select the FCC path for an email.
Definition: hook.c:700
#define SEC_AUTOCRYPT_OVERRIDE
(Autocrypt) Indicates manual set/unset of encryption
Definition: lib.h:135
Type: &#39;text/*&#39;.
Definition: mime.h:38
static int generate_body(FILE *fp_tmp, struct Email *e, SendFlags flags, struct Mailbox *m, struct EmailList *el)
Create a new email body.
Definition: send.c:1101
void mutt_env_free(struct Envelope **ptr)
Free an Envelope.
Definition: envelope.c:96
int mutt_protect(struct Email *e, char *keylist, bool postpone)
Encrypt and/or sign a message.
Definition: crypt.c:171
struct Body * parts
parts of a multipart or message/rfc822
Definition: body.h:54
#define SEND_NEWS
Reply to a news article.
Definition: send.h:102
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:349
static void set_reverse_name(struct AddressList *al, struct Envelope *env)
Try to set the &#39;from&#39; field from the recipients.
Definition: send.c:1284
#define STAILQ_NEXT(elm, field)
Definition: queue.h:397
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/lib.h pgplib...
Definition: email.h:39
bool C_PgpReplyinline
Config: Reply using old-style inline PGP messages (not recommended)
Definition: send.c:121
#define SEND_REPLY
Reply to sender.
Definition: send.h:88
NNTP-specific Mailbox data -.
Definition: lib.h:140
#define SEC_OPPENCRYPT
Opportunistic encrypt mode.
Definition: lib.h:133
bool C_SigOnTop
Config: Insert the signature before the quoted text.
Definition: send.c:133
#define SEND_NO_FREE_HEADER
Used by the -E flag.
Definition: send.h:98
unsigned char C_ForwardEdit
Config: Automatically start the editor when forwarding a message.
Definition: send.c:112
unsigned int type
content-type primary type
Definition: body.h:65
char * list_post
This stores a mailto URL, or nothing.
Definition: envelope.h:65
bool C_CryptReplyencrypt
Config: Encrypt replies to encrypted messages.
Definition: send.c:101
#define SEC_SIGN
Email is signed.
Definition: lib.h:126
int mutt_addrlist_count_recips(const struct AddressList *al)
Count the number of Addresses with valid recipients.
Definition: address.c:835
bool crypt_has_module_backend(SecurityFlags type)
Is there a crypto backend for a given type?
Definition: cryptglue.c:160
char * personal
Real name of address.
Definition: address.h:36
int mutt_num_postponed(struct Mailbox *m, bool force)
Return the number of postponed messages.
Definition: postpone.c:86
WHERE bool C_TextFlowed
Config: Generate &#39;format=flowed&#39; messages.
Definition: globals.h:254
void mutt_parse_content_type(const char *s, struct Body *ct)
Parse a content type.
Definition: parse.c:456
void mutt_env_to_local(struct Envelope *env)
Convert an Envelope&#39;s Address fields to local format.
Definition: envelope.c:271
void mutt_edit_headers(const char *editor, const char *body, struct Email *e, struct Buffer *fcc)
Let the user edit the message header and body.
Definition: mutt_header.c:168
void crypt_opportunistic_encrypt(struct Email *e)
Can all recipients be determined.
Definition: crypt.c:1036
WHERE bool C_ResumeDraftFiles
Config: Process draft files like postponed messages.
Definition: globals.h:244
char * subject
Email&#39;s subject.
Definition: envelope.h:66
Type: &#39;multipart/*&#39;.
Definition: mime.h:37
Log at debug level 1.
Definition: logging.h:40
char * newsgroups
List of newsgroups.
Definition: envelope.h:75
#define MUTT_SEND2_HOOK
send2-hook: when changing fields in the compose menu
Definition: hook.h:56
bool use_disp
Content-Disposition uses filename= ?
Definition: body.h:68
int mutt_file_copy_stream(FILE *fp_in, FILE *fp_out)
Copy the contents of one file into another.
Definition: file.c:271
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:380
struct Email * email
Email in the list.
Definition: email.h:116
#define mutt_error(...)
Definition: logging.h:84
bool mutt_needs_mailcap(struct Body *m)
Does this type need a mailcap entry do display.
Definition: muttlib.c:410
int mutt_builtin_editor(const char *path, struct Email *e_new, struct Email *e_cur)
Show the user the built-in editor.
Definition: edit.c:401
bool unlink
If true, filename should be unlink()ed before free()ing this structure.
Definition: body.h:69
bool replied
Email has been replied to.
Definition: email.h:54
void mutt_rfc3676_space_stuff(struct Email *e)
Perform RFC3676 space stuffing on an Email.
Definition: rfc3676.c:463
static int edit_envelope(struct Envelope *en, SendFlags flags)
Edit Envelope fields.
Definition: send.c:242
int mutt_str_strcasecmp(const char *a, const char *b)
Compare two strings ignoring case, safely.
Definition: string.c:651
WHERE char * C_Editor
Config: External command to use as an email editor.
Definition: globals.h:111
bool C_UseFrom
Config: Set the &#39;From&#39; header for outgoing mail.
Definition: send.c:134
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:964
#define MUTT_REPLY_HOOK
reply-hook: when replying to an email
Definition: hook.h:55
#define FREE(x)
Definition: memory.h:40
#define MUTT_COMPOSE_NOFREEHEADER
Definition: compose.h:35
static int save_fcc(struct Email *e, struct Buffer *fcc, struct Body *clear_content, char *pgpkeylist, SendFlags flags, char **finalpath)
Save an Email to a &#39;sent mail&#39; folder.
Definition: send.c:1609
struct AddressList to
Email&#39;s &#39;To&#39; list.
Definition: envelope.h:58
List of Emails.
Definition: email.h:114
struct Email * email_new(void)
Create a new Email.
Definition: email.c:68
WHERE char * C_Realname
Config: Real name of the user.
Definition: globals.h:139
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
void mutt_message_hook(struct Mailbox *m, struct Email *e, HookFlags type)
Perform a message hook.
Definition: hook.c:579
void mutt_body_free(struct Body **ptr)
Free a Body.
Definition: body.c:57
#define TAILQ_EMPTY(head)
Definition: queue.h:714
WHERE bool OptNewsSend
(pseudo) used to change behavior when posting
Definition: options.h:47
Log at debug level 5.
Definition: logging.h:44
WHERE char * C_PgpSignAs
Config: Use this alternative key for signing messages.
Definition: globals.h:161
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:588
WHERE char * C_SmimeSignAs
Config: Use this alternative key for signing messages.
Definition: globals.h:165
static void append_signature(FILE *fp)
Append a signature to an email.
Definition: send.c:140
void email_free(struct Email **ptr)
Free an Email.
Definition: email.c:41
bool mutt_buffer_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition: buffer.c:252
char * C_ContentType
Config: Default "Content-Type" for newly composed messages.
Definition: send.c:96
Content is inline.
Definition: mime.h:62
struct ParameterList parameter
parameters of the content-type
Definition: body.h:39
struct AddressList x_original_to
Email&#39;s &#39;X-Orig-to&#39;.
Definition: envelope.h:64
#define STAILQ_FIRST(head)
Definition: queue.h:347
void mutt_edit_file(const char *editor, const char *file)
Let the user edit a file.
Definition: curs_lib.c:354
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:638
static int send_message(struct Email *e)
Send an email.
Definition: send.c:1361
int mutt_get_postponed(struct Context *ctx, struct Email *hdr, struct Email **cur, struct Buffer *fcc)
Recall a postponed message.
Definition: postpone.c:331
Type: &#39;application/*&#39;.
Definition: mime.h:33
QuadOption
Possible values for a quad-option.
Definition: quad.h:36
int mutt_compose_menu(struct Email *e, struct Buffer *fcc, struct Email *e_cur, int flags)
Allow the user to edit the message envelope.
Definition: compose.c:1111
void mutt_param_set(struct ParameterList *pl, const char *attribute, const char *value)
Set a Parameter.
Definition: parameter.c:110
#define SEND_BATCH
Send email in batch mode (without user interaction)
Definition: send.h:93
bool C_CryptReplysignencrypted
Config: Sign replies to encrypted messages.
Definition: send.c:103
bool C_NmRecord
Config: (notmuch) If the &#39;record&#39; mailbox (sent mail) should be indexed.
Definition: send.c:120
void mutt_addrlist_append(struct AddressList *al, struct Address *a)
Append an Address to an AddressList.
Definition: address.c:1402
void mutt_buffer_alloc(struct Buffer *buf, size_t new_size)
Make sure a buffer can store at least new_size bytes.
Definition: buffer.c:265
bool C_CryptAutopgp
Config: Allow automatic PGP functions.
Definition: send.c:98
bool C_CryptAutoencrypt
Config: Automatically PGP encrypt all outgoing mail.
Definition: send.c:97
bool C_ReplyWithXorig
Config: Create &#39;From&#39; header from &#39;X-Original-To&#39; header.
Definition: send.c:128
+ Here is the caller graph for this function:

Variable Documentation

◆ C_AbortNoattach

unsigned char C_AbortNoattach

Config: Abort sending the email if attachments are missing.

Definition at line 90 of file send.c.

◆ C_AbortNoattachRegex

struct Regex* C_AbortNoattachRegex

Config: Regex to match text indicating attachments are expected.

Definition at line 91 of file send.c.

◆ C_AbortNosubject

unsigned char C_AbortNosubject

Config: Abort creating the email if subject is missing.

Definition at line 92 of file send.c.

◆ C_AbortUnmodified

unsigned char C_AbortUnmodified

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

Definition at line 93 of file send.c.

◆ C_AskFollowUp

bool C_AskFollowUp

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

Definition at line 94 of file send.c.

◆ C_AskXCommentTo

bool C_AskXCommentTo

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

Definition at line 95 of file send.c.

◆ C_ContentType

char* C_ContentType

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

Definition at line 96 of file send.c.

◆ C_CryptAutoencrypt

bool C_CryptAutoencrypt

Config: Automatically PGP encrypt all outgoing mail.

Definition at line 97 of file send.c.

◆ C_CryptAutopgp

bool C_CryptAutopgp

Config: Allow automatic PGP functions.

Definition at line 98 of file send.c.

◆ C_CryptAutosign

bool C_CryptAutosign

Config: Automatically PGP sign all outgoing mail.

Definition at line 99 of file send.c.

◆ C_CryptAutosmime

bool C_CryptAutosmime

Config: Allow automatic SMIME functions.

Definition at line 100 of file send.c.

◆ C_CryptReplyencrypt

bool C_CryptReplyencrypt

Config: Encrypt replies to encrypted messages.

Definition at line 101 of file send.c.

◆ C_CryptReplysign

bool C_CryptReplysign

Config: Sign replies to signed messages.

Definition at line 102 of file send.c.

◆ C_CryptReplysignencrypted

bool C_CryptReplysignencrypted

Config: Sign replies to encrypted messages.

Definition at line 103 of file send.c.

◆ C_EmptySubject

char* C_EmptySubject

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

Definition at line 104 of file send.c.

◆ C_FastReply

bool C_FastReply

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

Definition at line 105 of file send.c.

◆ C_FccAttach

unsigned char C_FccAttach

Config: Save send message with all their attachments.

Definition at line 106 of file send.c.

◆ C_FccBeforeSend

bool C_FccBeforeSend

Config: Save FCCs before sending the message.

Definition at line 107 of file send.c.

◆ C_FccClear

bool C_FccClear

Config: Save sent messages unencrypted and unsigned.

Definition at line 108 of file send.c.

◆ C_FollowupTo

bool C_FollowupTo

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

Definition at line 109 of file send.c.

◆ C_ForwardAttributionIntro

char* C_ForwardAttributionIntro

Config: Prefix message for forwarded messages.

Definition at line 110 of file send.c.

◆ C_ForwardAttributionTrailer

char* C_ForwardAttributionTrailer

Config: Suffix message for forwarded messages.

Definition at line 111 of file send.c.

◆ C_ForwardEdit

unsigned char C_ForwardEdit

Config: Automatically start the editor when forwarding a message.

Definition at line 112 of file send.c.

◆ C_ForwardFormat

char* C_ForwardFormat

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

Definition at line 113 of file send.c.

◆ C_ForwardReferences

bool C_ForwardReferences

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

Definition at line 114 of file send.c.

◆ C_Hdrs

bool C_Hdrs

Config: Add custom headers to outgoing mail.

Definition at line 115 of file send.c.

◆ C_HonorFollowupTo

unsigned char C_HonorFollowupTo

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

Definition at line 116 of file send.c.

◆ C_IgnoreListReplyTo

bool C_IgnoreListReplyTo

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

Definition at line 117 of file send.c.

◆ C_Include

unsigned char C_Include

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

Definition at line 118 of file send.c.

◆ C_Metoo

bool C_Metoo

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

Definition at line 119 of file send.c.

◆ C_NmRecord

bool C_NmRecord

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

Definition at line 120 of file send.c.

◆ C_PgpReplyinline

bool C_PgpReplyinline

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

Definition at line 121 of file send.c.

◆ C_PostIndentString

char* C_PostIndentString

Config: Suffix message to add after reply text.

Definition at line 122 of file send.c.

◆ C_PostponeEncrypt

bool C_PostponeEncrypt

Config: Self-encrypt postponed messages.

Definition at line 123 of file send.c.

◆ C_PostponeEncryptAs

char* C_PostponeEncryptAs

Config: Fallback encryption key for postponed messages.

Definition at line 124 of file send.c.

◆ C_Recall

unsigned char C_Recall

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

Definition at line 125 of file send.c.

◆ C_ReplySelf

bool C_ReplySelf

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

Definition at line 126 of file send.c.

◆ C_ReplyTo

unsigned char C_ReplyTo

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

Definition at line 127 of file send.c.

◆ C_ReplyWithXorig

bool C_ReplyWithXorig

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

Definition at line 128 of file send.c.

◆ C_ReverseName

bool C_ReverseName

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

Definition at line 129 of file send.c.

◆ C_ReverseRealname

bool C_ReverseRealname

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

Definition at line 130 of file send.c.

◆ C_SigDashes

bool C_SigDashes

Config: Insert '– ' before the signature.

Definition at line 131 of file send.c.

◆ C_Signature

char* C_Signature

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

Definition at line 132 of file send.c.

◆ C_SigOnTop

bool C_SigOnTop

Config: Insert the signature before the quoted text.

Definition at line 133 of file send.c.

◆ C_UseFrom

bool C_UseFrom

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

Definition at line 134 of file send.c.