NeoMutt  2020-04-24
Teaching an old dog new tricks
DOXYGEN
send.h File Reference

Prepare and send an email. More...

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

Go to the source code of this file.

Macros

#define SEND_NO_FLAGS   0
 No flags are set. More...
 
#define SEND_REPLY   (1 << 0)
 Reply to sender. More...
 
#define SEND_GROUP_REPLY   (1 << 1)
 Reply to all. More...
 
#define SEND_LIST_REPLY   (1 << 2)
 Reply to mailing list. More...
 
#define SEND_FORWARD   (1 << 3)
 Forward email. More...
 
#define SEND_POSTPONED   (1 << 4)
 Recall a postponed email. More...
 
#define SEND_BATCH   (1 << 5)
 Send email in batch mode (without user interaction) More...
 
#define SEND_MAILX   (1 << 6)
 Send email in Mailx compatibility mode. More...
 
#define SEND_KEY   (1 << 7)
 Mail a PGP public key. More...
 
#define SEND_RESEND   (1 << 8)
 Reply using the current email as a template. More...
 
#define SEND_POSTPONED_FCC   (1 << 9)
 Used by mutt_get_postponed() to signal that the x-mutt-fcc header field was present. More...
 
#define SEND_NO_FREE_HEADER   (1 << 10)
 Used by the -E flag. More...
 
#define SEND_DRAFT_FILE   (1 << 11)
 Used by the -H flag. More...
 
#define SEND_TO_SENDER   (1 << 12)
 Compose new email to sender. More...
 
#define SEND_GROUP_CHAT_REPLY   (1 << 13)
 Reply to all recipients preserving To/Cc. More...
 
#define SEND_NEWS   (1 << 14)
 Reply to a news article. More...
 

Typedefs

typedef uint16_t SendFlags
 Flags for mutt_send_message(), e.g. SEND_REPLY. More...
 

Functions

int mutt_send_message (SendFlags flags, struct Email *e_templ, const char *tempfile, struct Context *ctx, struct EmailList *el)
 Send an email. More...
 
void mutt_add_to_reference_headers (struct Envelope *env, struct Envelope *curenv)
 Generate references for a reply email. More...
 
struct Addressmutt_default_from (void)
 Get a default 'from' Address. More...
 
int mutt_edit_address (struct AddressList *al, const char *field, bool expand_aliases)
 Edit an email address. More...
 
void mutt_encode_descriptions (struct Body *b, bool recurse)
 rfc2047 encode the content-descriptions More...
 
int mutt_fetch_recips (struct Envelope *out, struct Envelope *in, SendFlags flags)
 Generate recpients for a reply email. More...
 
void mutt_fix_reply_recipients (struct Envelope *env)
 Remove duplicate recipients. 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...
 
void mutt_make_attribution (struct Mailbox *m, struct Email *e, FILE *fp_out)
 Add "on DATE, PERSON wrote" header. 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_make_post_indent (struct Mailbox *m, struct Email *e, FILE *fp_out)
 Add suffix to replied email text. More...
 
struct Addressmutt_remove_xrefs (struct Address *a, struct Address *b)
 
int mutt_resend_message (FILE *fp, struct Context *ctx, struct Email *e_cur)
 Resend an email. More...
 
void mutt_set_followup_to (struct Envelope *e)
 Set followup-to field. 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
  • Richard Russon

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

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

Definition in file send.h.

Macro Definition Documentation

◆ SEND_NO_FLAGS

#define SEND_NO_FLAGS   0

No flags are set.

Definition at line 87 of file send.h.

◆ SEND_REPLY

#define SEND_REPLY   (1 << 0)

Reply to sender.

Definition at line 88 of file send.h.

◆ SEND_GROUP_REPLY

#define SEND_GROUP_REPLY   (1 << 1)

Reply to all.

Definition at line 89 of file send.h.

◆ SEND_LIST_REPLY

#define SEND_LIST_REPLY   (1 << 2)

Reply to mailing list.

Definition at line 90 of file send.h.

◆ SEND_FORWARD

#define SEND_FORWARD   (1 << 3)

Forward email.

Definition at line 91 of file send.h.

◆ SEND_POSTPONED

#define SEND_POSTPONED   (1 << 4)

Recall a postponed email.

Definition at line 92 of file send.h.

◆ SEND_BATCH

#define SEND_BATCH   (1 << 5)

Send email in batch mode (without user interaction)

Definition at line 93 of file send.h.

◆ SEND_MAILX

#define SEND_MAILX   (1 << 6)

Send email in Mailx compatibility mode.

Definition at line 94 of file send.h.

◆ SEND_KEY

#define SEND_KEY   (1 << 7)

Mail a PGP public key.

Definition at line 95 of file send.h.

◆ SEND_RESEND

#define SEND_RESEND   (1 << 8)

Reply using the current email as a template.

Definition at line 96 of file send.h.

◆ SEND_POSTPONED_FCC

#define SEND_POSTPONED_FCC   (1 << 9)

Used by mutt_get_postponed() to signal that the x-mutt-fcc header field was present.

Definition at line 97 of file send.h.

◆ SEND_NO_FREE_HEADER

#define SEND_NO_FREE_HEADER   (1 << 10)

Used by the -E flag.

Definition at line 98 of file send.h.

◆ SEND_DRAFT_FILE

#define SEND_DRAFT_FILE   (1 << 11)

Used by the -H flag.

Definition at line 99 of file send.h.

◆ SEND_TO_SENDER

#define SEND_TO_SENDER   (1 << 12)

Compose new email to sender.

Definition at line 100 of file send.h.

◆ SEND_GROUP_CHAT_REPLY

#define SEND_GROUP_CHAT_REPLY   (1 << 13)

Reply to all recipients preserving To/Cc.

Definition at line 101 of file send.h.

◆ SEND_NEWS

#define SEND_NEWS   (1 << 14)

Reply to a news article.

Definition at line 102 of file send.h.

Typedef Documentation

◆ SendFlags

typedef uint16_t SendFlags

Flags for mutt_send_message(), e.g. SEND_REPLY.

Definition at line 86 of file send.h.

Function Documentation

◆ mutt_send_message()

int mutt_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  {
2170  mutt_error(_("Refusing to send an empty email"));
2171  mutt_message(_("Try: echo | neomutt -s 'subject' user@example.com"));
2172  goto cleanup;
2173  }
2174  }
2175 
2176  if (C_SigOnTop && !(flags & (SEND_MAILX | SEND_KEY | SEND_BATCH)) &&
2177  C_Editor && (mutt_str_strcmp(C_Editor, "builtin") != 0))
2178  {
2179  append_signature(fp_tmp);
2180  }
2181 
2182  /* include replies/forwarded messages, unless we are given a template */
2183  if (!tempfile && (ctx || !(flags & (SEND_REPLY | SEND_FORWARD))) &&
2184  (generate_body(fp_tmp, e_templ, flags, ctx ? ctx->mailbox : NULL, el) == -1))
2185  {
2186  goto cleanup;
2187  }
2188 
2189  if (!C_SigOnTop && !(flags & (SEND_MAILX | SEND_KEY | SEND_BATCH)) &&
2190  C_Editor && (mutt_str_strcmp(C_Editor, "builtin") != 0))
2191  {
2192  append_signature(fp_tmp);
2193  }
2194  }
2195 
2196  /* Only set format=flowed for new messages. postponed/resent/draftfiles
2197  * should respect the original email.
2198  *
2199  * This is set here so that send-hook can be used to turn the option on. */
2200  if (!(flags & (SEND_KEY | SEND_POSTPONED | SEND_RESEND | SEND_DRAFT_FILE)))
2201  {
2202  if (C_TextFlowed && (e_templ->content->type == TYPE_TEXT) &&
2203  (mutt_str_strcasecmp(e_templ->content->subtype, "plain") == 0))
2204  {
2205  mutt_param_set(&e_templ->content->parameter, "format", "flowed");
2206  }
2207  }
2208 
2209  /* This hook is even called for postponed messages, and can, e.g., be
2210  * used for setting the editor, the sendmail path, or the
2211  * envelope sender. */
2212  mutt_message_hook(NULL, e_templ, MUTT_SEND2_HOOK);
2213 
2214  /* wait until now to set the real name portion of our return address so
2215  * that $realname can be set in a send-hook */
2216  {
2217  struct Address *from = TAILQ_FIRST(&e_templ->env->from);
2218  if (from && !from->personal && !(flags & (SEND_RESEND | SEND_POSTPONED)))
2220  }
2221 
2222  if (!(((WithCrypto & APPLICATION_PGP) != 0) && (flags & SEND_KEY)))
2223  mutt_file_fclose(&fp_tmp);
2224 
2225  if (flags & SEND_MAILX)
2226  {
2227  if (mutt_builtin_editor(e_templ->content->filename, e_templ, e_cur) == -1)
2228  goto cleanup;
2229  }
2230  else if (!(flags & SEND_BATCH))
2231  {
2232  struct stat st;
2233  time_t mtime = mutt_file_decrease_mtime(e_templ->content->filename, NULL);
2234 
2235  mutt_update_encoding(e_templ->content);
2236 
2237  /* Select whether or not the user's editor should be called now. We
2238  * don't want to do this when:
2239  * 1) we are sending a key/cert
2240  * 2) we are forwarding a message and the user doesn't want to edit it.
2241  * This is controlled by the quadoption $forward_edit. However, if
2242  * both $edit_headers and $autoedit are set, we want to ignore the
2243  * setting of $forward_edit because the user probably needs to add the
2244  * recipients. */
2245  if (!(flags & SEND_KEY) &&
2246  (((flags & SEND_FORWARD) == 0) || (C_EditHeaders && C_Autoedit) ||
2247  (query_quadoption(C_ForwardEdit, _("Edit forwarded message?")) == MUTT_YES)))
2248  {
2249  /* If the this isn't a text message, look for a mailcap edit command */
2250  if (mutt_needs_mailcap(e_templ->content))
2251  {
2252  if (!mutt_edit_attachment(e_templ->content))
2253  goto cleanup;
2254  }
2255  else if (!C_Editor || (mutt_str_strcmp("builtin", C_Editor) == 0))
2256  mutt_builtin_editor(e_templ->content->filename, e_templ, e_cur);
2257  else if (C_EditHeaders)
2258  {
2259  mutt_env_to_local(e_templ->env);
2260  mutt_edit_headers(C_Editor, e_templ->content->filename, e_templ, &fcc);
2261  mutt_env_to_intl(e_templ->env, NULL, NULL);
2262  }
2263  else
2264  {
2266  if (stat(e_templ->content->filename, &st) == 0)
2267  {
2268  if (mtime != st.st_mtime)
2269  fix_end_of_file(e_templ->content->filename);
2270  }
2271  else
2272  mutt_perror(e_templ->content->filename);
2273  }
2274 
2275  mutt_message_hook(NULL, e_templ, MUTT_SEND2_HOOK);
2276  }
2277 
2278  if (!(flags & (SEND_POSTPONED | SEND_FORWARD | SEND_KEY | SEND_RESEND | SEND_DRAFT_FILE)))
2279  {
2280  if (stat(e_templ->content->filename, &st) == 0)
2281  {
2282  /* if the file was not modified, bail out now */
2283  if ((mtime == st.st_mtime) && !e_templ->content->next &&
2285  _("Abort unmodified message?")) == MUTT_YES))
2286  {
2287  mutt_message(_("Aborted unmodified message"));
2288  goto cleanup;
2289  }
2290  }
2291  else
2292  mutt_perror(e_templ->content->filename);
2293  }
2294  }
2295 
2296  /* Set the message security unless:
2297  * 1) crypto support is not enabled (WithCrypto==0)
2298  * 2) pgp: header field was present during message editing with $edit_headers (e_templ->security != 0)
2299  * 3) we are resending a message
2300  * 4) we are recalling a postponed message (don't override the user's saved settings)
2301  * 5) we are in mailx mode
2302  * 6) we are in batch mode
2303  *
2304  * This is done after allowing the user to edit the message so that security
2305  * settings can be configured with send2-hook and $edit_headers. */
2306  if ((WithCrypto != 0) && (e_templ->security == 0) &&
2307  !(flags & (SEND_BATCH | SEND_MAILX | SEND_POSTPONED | SEND_RESEND)))
2308  {
2309  if (
2310 #ifdef USE_AUTOCRYPT
2312 #else
2313  0
2314 #endif
2315  && e_cur && (e_cur->security & SEC_AUTOCRYPT))
2316  {
2318  }
2319  else
2320  {
2321  if (C_CryptAutosign)
2322  e_templ->security |= SEC_SIGN;
2323  if (C_CryptAutoencrypt)
2324  e_templ->security |= SEC_ENCRYPT;
2325  if (C_CryptReplyencrypt && e_cur && (e_cur->security & SEC_ENCRYPT))
2326  e_templ->security |= SEC_ENCRYPT;
2327  if (C_CryptReplysign && e_cur && (e_cur->security & SEC_SIGN))
2328  e_templ->security |= SEC_SIGN;
2329  if (C_CryptReplysignencrypted && e_cur && (e_cur->security & SEC_ENCRYPT))
2330  e_templ->security |= SEC_SIGN;
2331  if (((WithCrypto & APPLICATION_PGP) != 0) &&
2333  {
2334  if (C_PgpAutoinline)
2335  e_templ->security |= SEC_INLINE;
2336  if (C_PgpReplyinline && e_cur && (e_cur->security & SEC_INLINE))
2337  e_templ->security |= SEC_INLINE;
2338  }
2339  }
2340 
2341  if (e_templ->security || C_CryptOpportunisticEncrypt)
2342  {
2343  /* When replying / forwarding, use the original message's
2344  * crypto system. According to the documentation,
2345  * smime_is_default should be disregarded here.
2346  *
2347  * Problem: At least with forwarding, this doesn't really
2348  * make much sense. Should we have an option to completely
2349  * disable individual mechanisms at run-time? */
2350  if (e_cur)
2351  {
2352  if (((WithCrypto & APPLICATION_PGP) != 0) && C_CryptAutopgp &&
2353  (e_cur->security & APPLICATION_PGP))
2354  {
2355  e_templ->security |= APPLICATION_PGP;
2356  }
2357  else if (((WithCrypto & APPLICATION_SMIME) != 0) && C_CryptAutosmime &&
2358  (e_cur->security & APPLICATION_SMIME))
2359  {
2360  e_templ->security |= APPLICATION_SMIME;
2361  }
2362  }
2363 
2364  /* No crypto mechanism selected? Use availability + smime_is_default
2365  * for the decision. */
2366  if (!(e_templ->security & (APPLICATION_SMIME | APPLICATION_PGP)))
2367  {
2368  if (((WithCrypto & APPLICATION_SMIME) != 0) && C_CryptAutosmime && C_SmimeIsDefault)
2369  {
2370  e_templ->security |= APPLICATION_SMIME;
2371  }
2372  else if (((WithCrypto & APPLICATION_PGP) != 0) && C_CryptAutopgp)
2373  {
2374  e_templ->security |= APPLICATION_PGP;
2375  }
2376  else if (((WithCrypto & APPLICATION_SMIME) != 0) && C_CryptAutosmime)
2377  {
2378  e_templ->security |= APPLICATION_SMIME;
2379  }
2380  }
2381  }
2382 
2383  /* opportunistic encrypt relies on SMIME or PGP already being selected */
2385  {
2386  /* If something has already enabled encryption, e.g. C_CryptAutoencrypt
2387  * or C_CryptReplyencrypt, then don't enable opportunistic encrypt for
2388  * the message. */
2389  if (!(e_templ->security & (SEC_ENCRYPT | SEC_AUTOCRYPT)))
2390  {
2391  e_templ->security |= SEC_OPPENCRYPT;
2392  crypt_opportunistic_encrypt(e_templ);
2393  }
2394  }
2395 
2396  /* No permissible mechanisms found. Don't sign or encrypt. */
2397  if (!(e_templ->security & (APPLICATION_SMIME | APPLICATION_PGP)))
2398  e_templ->security = SEC_NO_FLAGS;
2399  }
2400 
2401  /* Deal with the corner case where the crypto module backend is not available.
2402  * This can happen if configured without PGP/SMIME and with GPGME, but
2403  * $crypt_use_gpgme is unset. */
2404  if (e_templ->security && !crypt_has_module_backend(e_templ->security))
2405  {
2406  mutt_error(_(
2407  "No crypto backend configured. Disabling message security setting."));
2408  e_templ->security = SEC_NO_FLAGS;
2409  }
2410 
2411  /* specify a default fcc. if we are in batchmode, only save a copy of
2412  * the message if the value of $copy is yes or ask-yes */
2413 
2414  if (mutt_buffer_is_empty(&fcc) && !(flags & SEND_POSTPONED_FCC) &&
2415  (!(flags & SEND_BATCH) || (C_Copy & 0x1)))
2416  {
2417  /* set the default FCC */
2418  const bool killfrom = TAILQ_EMPTY(&e_templ->env->from);
2419  if (killfrom)
2420  {
2422  }
2423  mutt_select_fcc(&fcc, e_templ);
2424  if (killfrom)
2425  {
2426  mutt_addrlist_clear(&e_templ->env->from);
2427  }
2428  }
2429 
2430  mutt_rfc3676_space_stuff(e_templ);
2431 
2432  mutt_update_encoding(e_templ->content);
2433 
2434  if (!(flags & (SEND_MAILX | SEND_BATCH)))
2435  {
2436  main_loop:
2437 
2439  i = mutt_compose_menu(e_templ, &fcc, e_cur,
2441  if (i == -1)
2442  {
2443 /* abort */
2444 #ifdef USE_NNTP
2445  if (flags & SEND_NEWS)
2446  mutt_message(_("Article not posted"));
2447  else
2448 #endif
2449  mutt_message(_("Mail not sent"));
2450  goto cleanup;
2451  }
2452  else if (i == 1)
2453  {
2454  if (postpone_message(e_templ, e_cur, mutt_b2s(&fcc), flags) != 0)
2455  goto main_loop;
2456  mutt_message(_("Message postponed"));
2457  rc = 1;
2458  goto cleanup;
2459  }
2460  }
2461 
2462 #ifdef USE_NNTP
2463  if (!(flags & SEND_NEWS))
2464 #endif
2465  if ((mutt_addrlist_count_recips(&e_templ->env->to) == 0) &&
2466  (mutt_addrlist_count_recips(&e_templ->env->cc) == 0) &&
2467  (mutt_addrlist_count_recips(&e_templ->env->bcc) == 0))
2468  {
2469  if (flags & SEND_BATCH)
2470  {
2471  puts(_("No recipients specified"));
2472  goto cleanup;
2473  }
2474 
2475  mutt_error(_("No recipients specified"));
2476  goto main_loop;
2477  }
2478 
2479  if (mutt_env_to_intl(e_templ->env, &tag, &err))
2480  {
2481  mutt_error(_("Bad IDN in '%s': '%s'"), tag, err);
2482  FREE(&err);
2483  if (flags & SEND_BATCH)
2484  goto cleanup;
2485  goto main_loop;
2486  }
2487 
2488  if (!e_templ->env->subject && !(flags & SEND_BATCH) &&
2489  (query_quadoption(C_AbortNosubject, _("No subject, abort sending?")) != MUTT_NO))
2490  {
2491  /* if the abort is automatic, print an error message */
2492  if (C_AbortNosubject == MUTT_YES)
2493  mutt_error(_("No subject specified"));
2494  goto main_loop;
2495  }
2496 #ifdef USE_NNTP
2497  if ((flags & SEND_NEWS) && !e_templ->env->subject)
2498  {
2499  mutt_error(_("No subject specified"));
2500  goto main_loop;
2501  }
2502 
2503  if ((flags & SEND_NEWS) && !e_templ->env->newsgroups)
2504  {
2505  mutt_error(_("No newsgroup specified"));
2506  goto main_loop;
2507  }
2508 #endif
2509 
2510  if (!(flags & SEND_BATCH) && (C_AbortNoattach != MUTT_NO) &&
2511  !e_templ->content->next && (e_templ->content->type == TYPE_TEXT) &&
2512  (mutt_str_strcasecmp(e_templ->content->subtype, "plain") == 0) &&
2513  search_attach_keyword(e_templ->content->filename) &&
2515  _("No attachments, cancel sending?")) != MUTT_NO))
2516  {
2517  /* if the abort is automatic, print an error message */
2518  if (C_AbortNoattach == MUTT_YES)
2519  {
2520  mutt_error(_("Message contains text matching "
2521  "\"$abort_noattach_regex\". Not sending."));
2522  }
2523  goto main_loop;
2524  }
2525 
2526  if (e_templ->content->next)
2527  e_templ->content = mutt_make_multipart(e_templ->content);
2528 
2529  /* Ok, we need to do it this way instead of handling all fcc stuff in
2530  * one place in order to avoid going to main_loop with encoded "env"
2531  * in case of error. Ugh. */
2532 
2533  mutt_encode_descriptions(e_templ->content, true);
2534 
2535  /* Make sure that clear_content and free_clear_content are
2536  * properly initialized -- we may visit this particular place in
2537  * the code multiple times, including after a failed call to
2538  * mutt_protect(). */
2539 
2540  clear_content = NULL;
2541  free_clear_content = false;
2542 
2543  if (WithCrypto)
2544  {
2545  if (e_templ->security & (SEC_ENCRYPT | SEC_SIGN | SEC_AUTOCRYPT))
2546  {
2547  /* save the decrypted attachments */
2548  clear_content = e_templ->content;
2549 
2550  if ((crypt_get_keys(e_templ, &pgpkeylist, 0) == -1) ||
2551  (mutt_protect(e_templ, pgpkeylist, false) == -1))
2552  {
2553  e_templ->content = mutt_remove_multipart(e_templ->content);
2554 
2555  FREE(&pgpkeylist);
2556 
2557  decode_descriptions(e_templ->content);
2558  goto main_loop;
2559  }
2560  mutt_encode_descriptions(e_templ->content, false);
2561  }
2562 
2563  /* at this point, e_templ->content is one of the following three things:
2564  * - multipart/signed. In this case, clear_content is a child
2565  * - multipart/encrypted. In this case, clear_content exists independently
2566  * - application/pgp. In this case, clear_content exists independently
2567  * - something else. In this case, it's the same as clear_content */
2568 
2569  /* This is ugly -- lack of "reporting back" from mutt_protect(). */
2570 
2571  if (clear_content && (e_templ->content != clear_content) &&
2572  (e_templ->content->parts != clear_content))
2573  free_clear_content = true;
2574  }
2575 
2576  if (!OptNoCurses && !(flags & SEND_MAILX))
2577  mutt_message(_("Sending message..."));
2578 
2579  mutt_prepare_envelope(e_templ->env, true);
2580 
2581  if (C_FccBeforeSend)
2582  save_fcc(e_templ, &fcc, clear_content, pgpkeylist, flags, &finalpath);
2583 
2584  i = invoke_mta(e_templ);
2585  if (i < 0)
2586  {
2587  if (!(flags & SEND_BATCH))
2588  {
2589  if (!WithCrypto)
2590  ;
2591  else if ((e_templ->security & (SEC_ENCRYPT | SEC_AUTOCRYPT)) ||
2592  ((e_templ->security & SEC_SIGN) && (e_templ->content->type == TYPE_APPLICATION)))
2593  {
2594  if (e_templ->content != clear_content)
2595  {
2596  mutt_body_free(&e_templ->content); /* destroy PGP data */
2597  e_templ->content = clear_content; /* restore clear text. */
2598  }
2599  }
2600  else if ((e_templ->security & SEC_SIGN) && (e_templ->content->type == TYPE_MULTIPART))
2601  {
2602  mutt_body_free(&e_templ->content->parts->next); /* destroy sig */
2603  e_templ->content = mutt_remove_multipart(e_templ->content);
2604  }
2605 
2606  FREE(&pgpkeylist);
2607  mutt_env_free(&e_templ->content->mime_headers); /* protected headers */
2608  e_templ->content = mutt_remove_multipart(e_templ->content);
2609  decode_descriptions(e_templ->content);
2610  mutt_unprepare_envelope(e_templ->env);
2611  FREE(&finalpath);
2612  goto main_loop;
2613  }
2614  else
2615  {
2616  puts(_("Could not send the message"));
2617  goto cleanup;
2618  }
2619  }
2620 
2621  if (!C_FccBeforeSend)
2622  save_fcc(e_templ, &fcc, clear_content, pgpkeylist, flags, &finalpath);
2623 
2624  if (!OptNoCurses && !(flags & SEND_MAILX))
2625  {
2626  mutt_message((i != 0) ? _("Sending in background") :
2627  (flags & SEND_NEWS) ? _("Article posted") : /* USE_NNTP */
2628  _("Mail sent"));
2629 #ifdef USE_NOTMUCH
2630  if (C_NmRecord)
2631  nm_record_message(ctx ? ctx->mailbox : NULL, finalpath, e_cur);
2632 #endif
2633  mutt_sleep(0);
2634  }
2635 
2636  if (WithCrypto)
2637  FREE(&pgpkeylist);
2638 
2639  if ((WithCrypto != 0) && free_clear_content)
2640  mutt_body_free(&clear_content);
2641 
2642  /* set 'replied' flag only if the user didn't change/remove
2643  * In-Reply-To: and References: headers during edit */
2644  if (flags & SEND_REPLY)
2645  {
2646  if (!(flags & SEND_POSTPONED) && ctx && ctx->mailbox)
2647  {
2648  STAILQ_FOREACH(en, el, entries)
2649  {
2650  mutt_set_flag(ctx->mailbox, en->email, MUTT_REPLIED, is_reply(en->email, e_templ));
2651  }
2652  }
2653  }
2654 
2655  rc = 0;
2656 
2657 cleanup:
2658  mutt_buffer_dealloc(&fcc);
2659 
2660  if (flags & SEND_POSTPONED)
2661  {
2662  if (WithCrypto & APPLICATION_PGP)
2663  {
2664  FREE(&C_PgpSignAs);
2665  C_PgpSignAs = pgp_signas;
2666  }
2667  if (WithCrypto & APPLICATION_SMIME)
2668  {
2669  FREE(&C_SmimeSignAs);
2670  C_SmimeSignAs = smime_signas;
2671  }
2672  }
2673 
2674  mutt_file_fclose(&fp_tmp);
2675  if (!(flags & SEND_NO_FREE_HEADER))
2676  email_free(&e_templ);
2677 
2678  FREE(&finalpath);
2679  return rc;
2680 }
#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:1772
#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:499
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:1112
#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:1412
#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:734
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:688
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:3003
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:1606
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:1746
#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:3042
#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:694
#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:841
bool crypt_has_module_backend(SecurityFlags type)
Is there a crypto backend for a given type?
Definition: cryptglue.c:172
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:455
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:409
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:654
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
static int invoke_mta(struct Email *e)
Send an email.
Definition: send.c:1361
#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:576
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:353
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:641
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:1317
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:1432
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:

◆ 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:

◆ 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:713
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:2531
int mutt_str_asprintf(char **strp, const char *fmt,...)
Definition: string.c:1220
+ 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:1329
void mutt_addrlist_clear(struct AddressList *al)
Unlink and free all Address in an AddressList.
Definition: address.c:1412
#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:613
#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:1247
#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:1144
+ 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:

◆ 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:1112
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:734
#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:

◆ 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:1349
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:1385
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_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:

◆ 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_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:455
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:692
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_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:

◆ mutt_remove_xrefs()

struct Address* mutt_remove_xrefs ( struct Address a,
struct Address b 
)

◆ 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 = mutt_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
int mutt_send_message(SendFlags flags, struct Email *e_templ, const char *tempfile, struct Context *ctx, struct EmailList *el)
Send an email.
Definition: send.c:1893
#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
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:

◆ 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:734
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:713
void mutt_addrlist_dedupe(struct AddressList *al)
Remove duplicate addresses.
Definition: address.c:1349
#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:1443
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:1813
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:1825
+ Here is the call graph for this function:
+ 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.