NeoMutt  2019-12-07-168-gc45f47
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 ci_send_message(), e.g. SEND_REPLY. More...
 

Functions

int ci_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 ci_send_message(), e.g. SEND_REPLY.

Definition at line 86 of file send.h.

Function Documentation

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

1894 {
1895  char buf[1024];
1896  struct Buffer fcc = mutt_buffer_make(0); /* where to copy this message */
1897  FILE *fp_tmp = NULL;
1898  struct Body *pbody = NULL;
1899  int i;
1900  bool free_clear_content = false;
1901 
1902  struct Body *clear_content = NULL;
1903  char *pgpkeylist = NULL;
1904  /* save current value of "pgp_sign_as" and "smime_default_key" */
1905  char *pgp_signas = NULL;
1906  char *smime_signas = NULL;
1907  const char *tag = NULL;
1908  char *err = NULL;
1909  char *ctype = NULL;
1910  char *finalpath = NULL;
1911  struct EmailNode *en = NULL;
1912  struct Email *e_cur = NULL;
1913 
1914  if (el)
1915  en = STAILQ_FIRST(el);
1916  if (en)
1917  e_cur = STAILQ_NEXT(en, entries) ? NULL : en->email;
1918 
1919  int rc = -1;
1920 
1921 #ifdef USE_NNTP
1922  if (flags & SEND_NEWS)
1923  OptNewsSend = true;
1924  else
1925  OptNewsSend = false;
1926 #endif
1927 
1928  if (!flags && !e_templ && (C_Recall != MUTT_NO) &&
1929  mutt_num_postponed(ctx ? ctx->mailbox : NULL, true))
1930  {
1931  /* If the user is composing a new message, check to see if there
1932  * are any postponed messages first. */
1933  enum QuadOption ans =
1934  query_quadoption(C_Recall, _("Recall postponed message?"));
1935  if (ans == MUTT_ABORT)
1936  return rc;
1937 
1938  if (ans == MUTT_YES)
1939  flags |= SEND_POSTPONED;
1940  }
1941 
1942  /* Allocate the buffer due to the long lifetime, but
1943  * pre-resize it to ensure there are no NULL data field issues */
1944  mutt_buffer_alloc(&fcc, 1024);
1945 
1946  if (flags & SEND_POSTPONED)
1947  {
1949  pgp_signas = mutt_str_strdup(C_PgpSignAs);
1951  smime_signas = mutt_str_strdup(C_SmimeSignAs);
1952  }
1953 
1954  /* Delay expansion of aliases until absolutely necessary--shouldn't
1955  * be necessary unless we are prompting the user or about to execute a
1956  * send-hook. */
1957 
1958  if (!e_templ)
1959  {
1960  e_templ = email_new();
1961 
1962  if (flags == SEND_POSTPONED)
1963  {
1964  rc = mutt_get_postponed(ctx, e_templ, &e_cur, &fcc);
1965  if (rc < 0)
1966  {
1967  flags = SEND_POSTPONED;
1968  goto cleanup;
1969  }
1970  flags = rc;
1971 #ifdef USE_NNTP
1972  /* If postponed message is a news article, it have
1973  * a "Newsgroups:" header line, then set appropriate flag. */
1974  if (e_templ->env->newsgroups)
1975  {
1976  flags |= SEND_NEWS;
1977  OptNewsSend = true;
1978  }
1979  else
1980  {
1981  flags &= ~SEND_NEWS;
1982  OptNewsSend = false;
1983  }
1984 #endif
1985  }
1986 
1987  if (flags & (SEND_POSTPONED | SEND_RESEND))
1988  {
1989  fp_tmp = mutt_file_fopen(e_templ->content->filename, "a+");
1990  if (!fp_tmp)
1991  {
1992  mutt_perror(e_templ->content->filename);
1993  goto cleanup;
1994  }
1995  }
1996 
1997  if (!e_templ->env)
1998  e_templ->env = mutt_env_new();
1999  }
2000 
2001  /* Parse and use an eventual list-post header */
2002  if ((flags & SEND_LIST_REPLY) && e_cur && e_cur->env && e_cur->env->list_post)
2003  {
2004  /* Use any list-post header as a template */
2005  mutt_parse_mailto(e_templ->env, NULL, e_cur->env->list_post);
2006  /* We don't let them set the sender's address. */
2007  mutt_addrlist_clear(&e_templ->env->from);
2008  }
2009 
2010  if (!(flags & (SEND_KEY | SEND_POSTPONED | SEND_RESEND)))
2011  {
2012  /* When SEND_DRAFT_FILE is set, the caller has already
2013  * created the "parent" body structure. */
2014  if (!(flags & SEND_DRAFT_FILE))
2015  {
2016  pbody = mutt_body_new();
2017  pbody->next = e_templ->content; /* don't kill command-line attachments */
2018  e_templ->content = pbody;
2019 
2020  ctype = mutt_str_strdup(C_ContentType);
2021  if (!ctype)
2022  ctype = mutt_str_strdup("text/plain");
2023  mutt_parse_content_type(ctype, e_templ->content);
2024  FREE(&ctype);
2025  e_templ->content->unlink = true;
2026  e_templ->content->use_disp = false;
2027  e_templ->content->disposition = DISP_INLINE;
2028 
2029  if (tempfile)
2030  {
2031  fp_tmp = mutt_file_fopen(tempfile, "a+");
2032  e_templ->content->filename = mutt_str_strdup(tempfile);
2033  }
2034  else
2035  {
2036  mutt_mktemp(buf, sizeof(buf));
2037  fp_tmp = mutt_file_fopen(buf, "w+");
2038  e_templ->content->filename = mutt_str_strdup(buf);
2039  }
2040  }
2041  else
2042  fp_tmp = mutt_file_fopen(e_templ->content->filename, "a+");
2043 
2044  if (!fp_tmp)
2045  {
2046  mutt_debug(LL_DEBUG1, "can't create tempfile %s (errno=%d)\n",
2047  e_templ->content->filename, errno);
2048  mutt_perror(e_templ->content->filename);
2049  goto cleanup;
2050  }
2051  }
2052 
2053  /* this is handled here so that the user can match ~f in send-hook */
2054  if (e_cur && C_ReverseName && !(flags & (SEND_POSTPONED | SEND_RESEND)))
2055  {
2056  /* We shouldn't have to worry about alias expansion here since we are
2057  * either replying to a real or postponed message, therefore no aliases
2058  * should exist since the user has not had the opportunity to add
2059  * addresses to the list. We just have to ensure the postponed messages
2060  * have their aliases expanded. */
2061 
2062  if (!TAILQ_EMPTY(&e_templ->env->from))
2063  {
2064  mutt_debug(LL_DEBUG5, "e_templ->env->from before set_reverse_name: %s\n",
2065  TAILQ_FIRST(&e_templ->env->from)->mailbox);
2066  mutt_addrlist_clear(&e_templ->env->from);
2067  }
2068  set_reverse_name(&e_templ->env->from, e_cur->env);
2069  }
2070  if (e_cur && C_ReplyWithXorig && !(flags & (SEND_POSTPONED | SEND_RESEND | SEND_FORWARD)))
2071  {
2072  /* We shouldn't have to worry about freeing 'e_templ->env->from' before
2073  * setting it here since this code will only execute when doing some
2074  * sort of reply. The pointer will only be set when using the -H command
2075  * line option.
2076  *
2077  * If there is already a from address recorded in 'e_templ->env->from',
2078  * then it theoretically comes from C_ReverseName handling, and we don't use
2079  * the 'X-Orig-To header'. */
2080  if (!TAILQ_EMPTY(&e_cur->env->x_original_to) && TAILQ_EMPTY(&e_templ->env->from))
2081  {
2082  mutt_addrlist_copy(&e_templ->env->from, &e_cur->env->x_original_to, false);
2083  mutt_debug(LL_DEBUG5, "e_templ->env->from extracted from X-Original-To: header: %s\n",
2084  TAILQ_FIRST(&e_templ->env->from)->mailbox);
2085  }
2086  }
2087 
2088  if (!(flags & (SEND_POSTPONED | SEND_RESEND)) &&
2089  !((flags & SEND_DRAFT_FILE) && C_ResumeDraftFiles))
2090  {
2091  if ((flags & (SEND_REPLY | SEND_FORWARD | SEND_TO_SENDER)) && ctx &&
2092  (envelope_defaults(e_templ->env, ctx->mailbox, el, flags) == -1))
2093  {
2094  goto cleanup;
2095  }
2096 
2097  if (C_Hdrs)
2098  process_user_recips(e_templ->env);
2099 
2100  /* Expand aliases and remove duplicates/crossrefs */
2101  mutt_expand_aliases_env(e_templ->env);
2102 
2103  if (flags & SEND_REPLY)
2104  mutt_fix_reply_recipients(e_templ->env);
2105 
2106 #ifdef USE_NNTP
2107  if ((flags & SEND_NEWS) && ctx && (ctx->mailbox->magic == MUTT_NNTP) &&
2108  !e_templ->env->newsgroups)
2109  {
2110  e_templ->env->newsgroups =
2111  mutt_str_strdup(((struct NntpMboxData *) ctx->mailbox->mdata)->group);
2112  }
2113 #endif
2114 
2115  if (!(flags & (SEND_MAILX | SEND_BATCH)) &&
2116  !(C_Autoedit && C_EditHeaders) && !((flags & SEND_REPLY) && C_FastReply))
2117  {
2118  if (edit_envelope(e_templ->env, flags) == -1)
2119  goto cleanup;
2120  }
2121 
2122  /* the from address must be set here regardless of whether or not
2123  * $use_from is set so that the '~P' (from you) operator in send-hook
2124  * patterns will work. if $use_from is unset, the from address is killed
2125  * after send-hooks are evaluated */
2126 
2127  const bool killfrom = TAILQ_EMPTY(&e_templ->env->from);
2128  if (killfrom)
2129  {
2131  }
2132 
2133  if ((flags & SEND_REPLY) && e_cur)
2134  {
2135  /* change setting based upon message we are replying to */
2136  mutt_message_hook(ctx ? ctx->mailbox : NULL, e_cur, MUTT_REPLY_HOOK);
2137 
2138  /* set the replied flag for the message we are generating so that the
2139  * user can use ~Q in a send-hook to know when reply-hook's are also
2140  * being used. */
2141  e_templ->replied = true;
2142  }
2143 
2144  /* change settings based upon recipients */
2145 
2146  mutt_message_hook(NULL, e_templ, MUTT_SEND_HOOK);
2147 
2148  /* Unset the replied flag from the message we are composing since it is
2149  * no longer required. This is done here because the FCC'd copy of
2150  * this message was erroneously get the 'R'eplied flag when stored in
2151  * a maildir-style mailbox. */
2152  e_templ->replied = false;
2153 
2154  /* $use_from and/or $from might have changed in a send-hook */
2155  if (killfrom)
2156  {
2157  mutt_addrlist_clear(&e_templ->env->from);
2158  if (C_UseFrom && !(flags & (SEND_POSTPONED | SEND_RESEND)))
2160  }
2161 
2162  if (C_Hdrs)
2163  process_user_header(e_templ->env);
2164 
2165  if (flags & SEND_BATCH)
2166  mutt_file_copy_stream(stdin, fp_tmp);
2167 
2168  if (C_SigOnTop && !(flags & (SEND_MAILX | SEND_KEY | SEND_BATCH)) &&
2169  C_Editor && (mutt_str_strcmp(C_Editor, "builtin") != 0))
2170  {
2171  append_signature(fp_tmp);
2172  }
2173 
2174  /* include replies/forwarded messages, unless we are given a template */
2175  if (!tempfile && (ctx || !(flags & (SEND_REPLY | SEND_FORWARD))) &&
2176  (generate_body(fp_tmp, e_templ, flags, ctx ? ctx->mailbox : NULL, el) == -1))
2177  {
2178  goto cleanup;
2179  }
2180 
2181  if (!C_SigOnTop && !(flags & (SEND_MAILX | SEND_KEY | SEND_BATCH)) &&
2182  C_Editor && (mutt_str_strcmp(C_Editor, "builtin") != 0))
2183  {
2184  append_signature(fp_tmp);
2185  }
2186  }
2187 
2188  /* Only set format=flowed for new messages. postponed/resent/draftfiles
2189  * should respect the original email.
2190  *
2191  * This is set here so that send-hook can be used to turn the option on. */
2192  if (!(flags & (SEND_KEY | SEND_POSTPONED | SEND_RESEND | SEND_DRAFT_FILE)))
2193  {
2194  if (C_TextFlowed && (e_templ->content->type == TYPE_TEXT) &&
2195  (mutt_str_strcasecmp(e_templ->content->subtype, "plain") == 0))
2196  {
2197  mutt_param_set(&e_templ->content->parameter, "format", "flowed");
2198  }
2199  }
2200 
2201  /* This hook is even called for postponed messages, and can, e.g., be
2202  * used for setting the editor, the sendmail path, or the
2203  * envelope sender. */
2204  mutt_message_hook(NULL, e_templ, MUTT_SEND2_HOOK);
2205 
2206  /* wait until now to set the real name portion of our return address so
2207  * that $realname can be set in a send-hook */
2208  {
2209  struct Address *from = TAILQ_FIRST(&e_templ->env->from);
2210  if (from && !from->personal && !(flags & (SEND_RESEND | SEND_POSTPONED)))
2212  }
2213 
2214  if (!(((WithCrypto & APPLICATION_PGP) != 0) && (flags & SEND_KEY)))
2215  mutt_file_fclose(&fp_tmp);
2216 
2217  if (flags & SEND_MAILX)
2218  {
2219  if (mutt_builtin_editor(e_templ->content->filename, e_templ, e_cur) == -1)
2220  goto cleanup;
2221  }
2222  else if (!(flags & SEND_BATCH))
2223  {
2224  struct stat st;
2225  time_t mtime = mutt_file_decrease_mtime(e_templ->content->filename, NULL);
2226 
2227  mutt_update_encoding(e_templ->content);
2228 
2229  /* Select whether or not the user's editor should be called now. We
2230  * don't want to do this when:
2231  * 1) we are sending a key/cert
2232  * 2) we are forwarding a message and the user doesn't want to edit it.
2233  * This is controlled by the quadoption $forward_edit. However, if
2234  * both $edit_headers and $autoedit are set, we want to ignore the
2235  * setting of $forward_edit because the user probably needs to add the
2236  * recipients. */
2237  if (!(flags & SEND_KEY) &&
2238  (((flags & SEND_FORWARD) == 0) || (C_EditHeaders && C_Autoedit) ||
2239  (query_quadoption(C_ForwardEdit, _("Edit forwarded message?")) == MUTT_YES)))
2240  {
2241  /* If the this isn't a text message, look for a mailcap edit command */
2242  if (mutt_needs_mailcap(e_templ->content))
2243  {
2244  if (!mutt_edit_attachment(e_templ->content))
2245  goto cleanup;
2246  }
2247  else if (!C_Editor || (mutt_str_strcmp("builtin", C_Editor) == 0))
2248  mutt_builtin_editor(e_templ->content->filename, e_templ, e_cur);
2249  else if (C_EditHeaders)
2250  {
2251  mutt_env_to_local(e_templ->env);
2252  mutt_edit_headers(C_Editor, e_templ->content->filename, e_templ, &fcc);
2253  mutt_env_to_intl(e_templ->env, NULL, NULL);
2254  }
2255  else
2256  {
2258  if (stat(e_templ->content->filename, &st) == 0)
2259  {
2260  if (mtime != st.st_mtime)
2261  fix_end_of_file(e_templ->content->filename);
2262  }
2263  else
2264  mutt_perror(e_templ->content->filename);
2265  }
2266 
2267  mutt_message_hook(NULL, e_templ, MUTT_SEND2_HOOK);
2268  }
2269 
2270  if (!(flags & (SEND_POSTPONED | SEND_FORWARD | SEND_KEY | SEND_RESEND | SEND_DRAFT_FILE)))
2271  {
2272  if (stat(e_templ->content->filename, &st) == 0)
2273  {
2274  /* if the file was not modified, bail out now */
2275  if ((mtime == st.st_mtime) && !e_templ->content->next &&
2277  _("Abort unmodified message?")) == MUTT_YES))
2278  {
2279  mutt_message(_("Aborted unmodified message"));
2280  goto cleanup;
2281  }
2282  }
2283  else
2284  mutt_perror(e_templ->content->filename);
2285  }
2286  }
2287 
2288  /* Set the message security unless:
2289  * 1) crypto support is not enabled (WithCrypto==0)
2290  * 2) pgp: header field was present during message editing with $edit_headers (e_templ->security != 0)
2291  * 3) we are resending a message
2292  * 4) we are recalling a postponed message (don't override the user's saved settings)
2293  * 5) we are in mailx mode
2294  * 6) we are in batch mode
2295  *
2296  * This is done after allowing the user to edit the message so that security
2297  * settings can be configured with send2-hook and $edit_headers. */
2298  if ((WithCrypto != 0) && (e_templ->security == 0) &&
2299  !(flags & (SEND_BATCH | SEND_MAILX | SEND_POSTPONED | SEND_RESEND)))
2300  {
2301  if (
2302 #ifdef USE_AUTOCRYPT
2304 #else
2305  0
2306 #endif
2307  && e_cur && (e_cur->security & SEC_AUTOCRYPT))
2308  {
2310  }
2311  else
2312  {
2313  if (C_CryptAutosign)
2314  e_templ->security |= SEC_SIGN;
2315  if (C_CryptAutoencrypt)
2316  e_templ->security |= SEC_ENCRYPT;
2317  if (C_CryptReplyencrypt && e_cur && (e_cur->security & SEC_ENCRYPT))
2318  e_templ->security |= SEC_ENCRYPT;
2319  if (C_CryptReplysign && e_cur && (e_cur->security & SEC_SIGN))
2320  e_templ->security |= SEC_SIGN;
2321  if (C_CryptReplysignencrypted && e_cur && (e_cur->security & SEC_ENCRYPT))
2322  e_templ->security |= SEC_SIGN;
2323  if (((WithCrypto & APPLICATION_PGP) != 0) &&
2325  {
2326  if (C_PgpAutoinline)
2327  e_templ->security |= SEC_INLINE;
2328  if (C_PgpReplyinline && e_cur && (e_cur->security & SEC_INLINE))
2329  e_templ->security |= SEC_INLINE;
2330  }
2331  }
2332 
2333  if (e_templ->security || C_CryptOpportunisticEncrypt)
2334  {
2335  /* When replying / forwarding, use the original message's
2336  * crypto system. According to the documentation,
2337  * smime_is_default should be disregarded here.
2338  *
2339  * Problem: At least with forwarding, this doesn't really
2340  * make much sense. Should we have an option to completely
2341  * disable individual mechanisms at run-time? */
2342  if (e_cur)
2343  {
2344  if (((WithCrypto & APPLICATION_PGP) != 0) && C_CryptAutopgp &&
2345  (e_cur->security & APPLICATION_PGP))
2346  {
2347  e_templ->security |= APPLICATION_PGP;
2348  }
2349  else if (((WithCrypto & APPLICATION_SMIME) != 0) && C_CryptAutosmime &&
2350  (e_cur->security & APPLICATION_SMIME))
2351  {
2352  e_templ->security |= APPLICATION_SMIME;
2353  }
2354  }
2355 
2356  /* No crypto mechanism selected? Use availability + smime_is_default
2357  * for the decision. */
2358  if (!(e_templ->security & (APPLICATION_SMIME | APPLICATION_PGP)))
2359  {
2360  if (((WithCrypto & APPLICATION_SMIME) != 0) && C_CryptAutosmime && C_SmimeIsDefault)
2361  {
2362  e_templ->security |= APPLICATION_SMIME;
2363  }
2364  else if (((WithCrypto & APPLICATION_PGP) != 0) && C_CryptAutopgp)
2365  {
2366  e_templ->security |= APPLICATION_PGP;
2367  }
2368  else if (((WithCrypto & APPLICATION_SMIME) != 0) && C_CryptAutosmime)
2369  {
2370  e_templ->security |= APPLICATION_SMIME;
2371  }
2372  }
2373  }
2374 
2375  /* opportunistic encrypt relies on SMIME or PGP already being selected */
2377  {
2378  /* If something has already enabled encryption, e.g. C_CryptAutoencrypt
2379  * or C_CryptReplyencrypt, then don't enable opportunistic encrypt for
2380  * the message. */
2381  if (!(e_templ->security & (SEC_ENCRYPT | SEC_AUTOCRYPT)))
2382  {
2383  e_templ->security |= SEC_OPPENCRYPT;
2384  crypt_opportunistic_encrypt(e_templ);
2385  }
2386  }
2387 
2388  /* No permissible mechanisms found. Don't sign or encrypt. */
2389  if (!(e_templ->security & (APPLICATION_SMIME | APPLICATION_PGP)))
2390  e_templ->security = SEC_NO_FLAGS;
2391  }
2392 
2393  /* Deal with the corner case where the crypto module backend is not available.
2394  * This can happen if configured without pgp/smime and with gpgme, but
2395  * $crypt_use_gpgme is unset. */
2396  if (e_templ->security && !crypt_has_module_backend(e_templ->security))
2397  {
2398  mutt_error(_(
2399  "No crypto backend configured. Disabling message security setting."));
2400  e_templ->security = SEC_NO_FLAGS;
2401  }
2402 
2403  /* specify a default fcc. if we are in batchmode, only save a copy of
2404  * the message if the value of $copy is yes or ask-yes */
2405 
2406  if (mutt_buffer_is_empty(&fcc) && !(flags & SEND_POSTPONED_FCC) &&
2407  (!(flags & SEND_BATCH) || (C_Copy & 0x1)))
2408  {
2409  /* set the default FCC */
2410  const bool killfrom = TAILQ_EMPTY(&e_templ->env->from);
2411  if (killfrom)
2412  {
2414  }
2415  mutt_select_fcc(&fcc, e_templ);
2416  if (killfrom)
2417  {
2418  mutt_addrlist_clear(&e_templ->env->from);
2419  }
2420  }
2421 
2422  mutt_rfc3676_space_stuff(e_templ);
2423 
2424  mutt_update_encoding(e_templ->content);
2425 
2426  if (!(flags & (SEND_MAILX | SEND_BATCH)))
2427  {
2428  main_loop:
2429 
2431  i = mutt_compose_menu(e_templ, &fcc, e_cur,
2433  if (i == -1)
2434  {
2435 /* abort */
2436 #ifdef USE_NNTP
2437  if (flags & SEND_NEWS)
2438  mutt_message(_("Article not posted"));
2439  else
2440 #endif
2441  mutt_message(_("Mail not sent"));
2442  goto cleanup;
2443  }
2444  else if (i == 1)
2445  {
2446  if (postpone_message(e_templ, e_cur, mutt_b2s(&fcc), flags) != 0)
2447  goto main_loop;
2448  mutt_message(_("Message postponed"));
2449  rc = 1;
2450  goto cleanup;
2451  }
2452  }
2453 
2454 #ifdef USE_NNTP
2455  if (!(flags & SEND_NEWS))
2456 #endif
2457  if ((mutt_addrlist_count_recips(&e_templ->env->to) == 0) &&
2458  (mutt_addrlist_count_recips(&e_templ->env->cc) == 0) &&
2459  (mutt_addrlist_count_recips(&e_templ->env->bcc) == 0))
2460  {
2461  if (flags & SEND_BATCH)
2462  {
2463  puts(_("No recipients specified"));
2464  goto cleanup;
2465  }
2466 
2467  mutt_error(_("No recipients specified"));
2468  goto main_loop;
2469  }
2470 
2471  if (mutt_env_to_intl(e_templ->env, &tag, &err))
2472  {
2473  mutt_error(_("Bad IDN in '%s': '%s'"), tag, err);
2474  FREE(&err);
2475  if (flags & SEND_BATCH)
2476  goto cleanup;
2477  goto main_loop;
2478  }
2479 
2480  if (!e_templ->env->subject && !(flags & SEND_BATCH) &&
2481  (query_quadoption(C_AbortNosubject, _("No subject, abort sending?")) != MUTT_NO))
2482  {
2483  /* if the abort is automatic, print an error message */
2484  if (C_AbortNosubject == MUTT_YES)
2485  mutt_error(_("No subject specified"));
2486  goto main_loop;
2487  }
2488 #ifdef USE_NNTP
2489  if ((flags & SEND_NEWS) && !e_templ->env->subject)
2490  {
2491  mutt_error(_("No subject specified"));
2492  goto main_loop;
2493  }
2494 
2495  if ((flags & SEND_NEWS) && !e_templ->env->newsgroups)
2496  {
2497  mutt_error(_("No newsgroup specified"));
2498  goto main_loop;
2499  }
2500 #endif
2501 
2502  if (!(flags & SEND_BATCH) && (C_AbortNoattach != MUTT_NO) &&
2503  !e_templ->content->next && (e_templ->content->type == TYPE_TEXT) &&
2504  (mutt_str_strcasecmp(e_templ->content->subtype, "plain") == 0) &&
2505  search_attach_keyword(e_templ->content->filename) &&
2507  _("No attachments, cancel sending?")) != MUTT_NO))
2508  {
2509  /* if the abort is automatic, print an error message */
2510  if (C_AbortNoattach == MUTT_YES)
2511  {
2512  mutt_error(_("Message contains text matching "
2513  "\"$abort_noattach_regex\". Not sending."));
2514  }
2515  goto main_loop;
2516  }
2517 
2518  if (e_templ->content->next)
2519  e_templ->content = mutt_make_multipart(e_templ->content);
2520 
2521  /* Ok, we need to do it this way instead of handling all fcc stuff in
2522  * one place in order to avoid going to main_loop with encoded "env"
2523  * in case of error. Ugh. */
2524 
2525  mutt_encode_descriptions(e_templ->content, true);
2526 
2527  /* Make sure that clear_content and free_clear_content are
2528  * properly initialized -- we may visit this particular place in
2529  * the code multiple times, including after a failed call to
2530  * mutt_protect(). */
2531 
2532  clear_content = NULL;
2533  free_clear_content = false;
2534 
2535  if (WithCrypto)
2536  {
2537  if (e_templ->security & (SEC_ENCRYPT | SEC_SIGN | SEC_AUTOCRYPT))
2538  {
2539  /* save the decrypted attachments */
2540  clear_content = e_templ->content;
2541 
2542  if ((crypt_get_keys(e_templ, &pgpkeylist, 0) == -1) ||
2543  (mutt_protect(e_templ, pgpkeylist, false) == -1))
2544  {
2545  e_templ->content = mutt_remove_multipart(e_templ->content);
2546 
2547  FREE(&pgpkeylist);
2548 
2549  decode_descriptions(e_templ->content);
2550  goto main_loop;
2551  }
2552  mutt_encode_descriptions(e_templ->content, false);
2553  }
2554 
2555  /* at this point, e_templ->content is one of the following three things:
2556  * - multipart/signed. In this case, clear_content is a child
2557  * - multipart/encrypted. In this case, clear_content exists independently
2558  * - application/pgp. In this case, clear_content exists independently
2559  * - something else. In this case, it's the same as clear_content
2560  */
2561 
2562  /* This is ugly -- lack of "reporting back" from mutt_protect(). */
2563 
2564  if (clear_content && (e_templ->content != clear_content) &&
2565  (e_templ->content->parts != clear_content))
2566  free_clear_content = true;
2567  }
2568 
2569  if (!OptNoCurses && !(flags & SEND_MAILX))
2570  mutt_message(_("Sending message..."));
2571 
2572  mutt_prepare_envelope(e_templ->env, true);
2573 
2574  if (C_FccBeforeSend)
2575  save_fcc(e_templ, &fcc, clear_content, pgpkeylist, flags, &finalpath);
2576 
2577  i = send_message(e_templ);
2578  if (i < 0)
2579  {
2580  if (!(flags & SEND_BATCH))
2581  {
2582  if (!WithCrypto)
2583  ;
2584  else if ((e_templ->security & (SEC_ENCRYPT | SEC_AUTOCRYPT)) ||
2585  ((e_templ->security & SEC_SIGN) && (e_templ->content->type == TYPE_APPLICATION)))
2586  {
2587  if (e_templ->content != clear_content)
2588  {
2589  mutt_body_free(&e_templ->content); /* destroy PGP data */
2590  e_templ->content = clear_content; /* restore clear text. */
2591  }
2592  }
2593  else if ((e_templ->security & SEC_SIGN) && (e_templ->content->type == TYPE_MULTIPART))
2594  {
2595  mutt_body_free(&e_templ->content->parts->next); /* destroy sig */
2596  e_templ->content = mutt_remove_multipart(e_templ->content);
2597  }
2598 
2599  FREE(&pgpkeylist);
2600  mutt_env_free(&e_templ->content->mime_headers); /* protected headers */
2601  e_templ->content = mutt_remove_multipart(e_templ->content);
2602  decode_descriptions(e_templ->content);
2603  mutt_unprepare_envelope(e_templ->env);
2604  FREE(&finalpath);
2605  goto main_loop;
2606  }
2607  else
2608  {
2609  puts(_("Could not send the message"));
2610  goto cleanup;
2611  }
2612  }
2613 
2614  if (!C_FccBeforeSend)
2615  save_fcc(e_templ, &fcc, clear_content, pgpkeylist, flags, &finalpath);
2616 
2617  if (!OptNoCurses && !(flags & SEND_MAILX))
2618  {
2619  mutt_message((i != 0) ? _("Sending in background") :
2620  (flags & SEND_NEWS) ? _("Article posted") : /* USE_NNTP */
2621  _("Mail sent"));
2622 #ifdef USE_NOTMUCH
2623  if (C_NmRecord)
2624  nm_record_message(ctx ? ctx->mailbox : NULL, finalpath, e_cur);
2625 #endif
2626  mutt_sleep(0);
2627  }
2628 
2629  if (WithCrypto)
2630  FREE(&pgpkeylist);
2631 
2632  if ((WithCrypto != 0) && free_clear_content)
2633  mutt_body_free(&clear_content);
2634 
2635  /* set 'replied' flag only if the user didn't change/remove
2636  * In-Reply-To: and References: headers during edit */
2637  if (flags & SEND_REPLY)
2638  {
2639  if (!(flags & SEND_POSTPONED) && ctx && ctx->mailbox)
2640  {
2641  STAILQ_FOREACH(en, el, entries)
2642  {
2643  mutt_set_flag(ctx->mailbox, en->email, MUTT_REPLIED, is_reply(en->email, e_templ));
2644  }
2645  }
2646  }
2647 
2648  rc = 0;
2649 
2650 cleanup:
2651  mutt_buffer_dealloc(&fcc);
2652 
2653  if (flags & SEND_POSTPONED)
2654  {
2655  if (WithCrypto & APPLICATION_PGP)
2656  {
2657  FREE(&C_PgpSignAs);
2658  C_PgpSignAs = pgp_signas;
2659  }
2660  if (WithCrypto & APPLICATION_SMIME)
2661  {
2662  FREE(&C_SmimeSignAs);
2663  C_SmimeSignAs = smime_signas;
2664  }
2665  }
2666 
2667  mutt_file_fclose(&fp_tmp);
2668  if (!(flags & SEND_NO_FREE_HEADER))
2669  email_free(&e_templ);
2670 
2671  FREE(&finalpath);
2672  return rc;
2673 }
#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:912
bool C_Hdrs
Config: Add custom headers to outgoing mail.
Definition: send.c:114
char * filename
when sending a message, this is the file to which this structure refers
Definition: body.h:46
WHERE bool C_Autocrypt
Config: Enables the Autocrypt feature.
Definition: globals.h:198
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:1771
#define mutt_set_flag(m, e, flag, bf)
Definition: protos.h:70
#define WithCrypto
Definition: lib.h:161
#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:1790
static void fix_end_of_file(const char *data)
Ensure a file ends with a linefeed.
Definition: send.c:1482
WHERE bool C_AutocryptReply
Config: Replying to an autocrypt email automatically enables autocrypt in the reply.
Definition: globals.h:199
&#39;NNTP&#39; (Usenet) Mailbox type
Definition: mailbox.h:51
unsigned char C_AbortNoattach
Config: Abort sending the email if attachments are missing.
Definition: send.c:89
static bool search_attach_keyword(char *filename)
Search an email for &#39;attachment&#39; keywords.
Definition: send.c:1569
#define SEC_NO_FLAGS
No flags are set.
Definition: lib.h:122
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:1109
#define mutt_message(...)
Definition: logging.h:83
int mutt_parse_mailto(struct Envelope *e, char **body, const char *src)
Parse a mailto:// url.
Definition: parse.c:1595
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:123
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:1032
static void process_user_header(struct Envelope *env)
Process the user headers.
Definition: send.c:378
#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:106
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:92
WHERE bool C_PgpAutoinline
Config: Use old-style inline PGP messages (not recommended)
Definition: globals.h:278
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:179
WHERE bool OptNoCurses
(pseudo) when sending in batch mode
Definition: options.h:47
#define SEC_AUTOCRYPT
Message will be, or was Autocrypt encrypt+signed.
Definition: lib.h:132
bool C_CryptAutosign
Config: Automatically PGP sign all outgoing mail.
Definition: send.c:98
int crypt_get_keys(struct Email *e, char **keylist, bool oppenc_mode)
Check we have all the keys we need.
Definition: crypt.c:956
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:702
bool C_CryptReplysign
Config: Sign replies to signed messages.
Definition: send.c:101
Messages that have been replied to.
Definition: mutt.h:99
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:3002
unsigned int disposition
content-disposition
Definition: body.h:67
#define SEC_INLINE
Email has an inline signature.
Definition: lib.h:130
WHERE bool C_SmimeIsDefault
Config: Use SMIME rather than PGP by default.
Definition: globals.h:274
bool C_CryptAutosmime
Config: Allow automatic SMIME functions.
Definition: send.c:99
#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:1544
WHERE bool C_EditHeaders
Config: Let the user edit the email headers whilst editing an email.
Definition: globals.h:210
struct Mailbox * mailbox
Definition: context.h:50
unsigned char C_Recall
Config: Recall postponed mesaages when asked to compose a message.
Definition: send.c:124
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:91
struct AddressList from
Email&#39;s &#39;From&#39; list.
Definition: envelope.h:57
enum MailboxType magic
Mailbox type.
Definition: mailbox.h:104
void mutt_update_encoding(struct Body *a)
Update the encoding type.
Definition: sendlib.c:1484
static void process_user_recips(struct Envelope *env)
Process the user headers.
Definition: send.c:351
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:152
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:1465
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:201
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:1551
void * mdata
Driver specific data.
Definition: mailbox.h:135
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:1745
#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:104
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition: lib.h:136
#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:3041
#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:1334
WHERE bool C_CryptOpportunisticEncrypt
Config: Enable encryption when the recipient&#39;s key is available.
Definition: globals.h:269
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: lib.h:135
bool C_ReverseName
Config: Set the &#39;From&#39; from the address the email was sent to.
Definition: send.c:128
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:1448
void mutt_select_fcc(struct Buffer *path, struct Email *e)
Select the FCC path for an email.
Definition: hook.c:699
#define SEC_AUTOCRYPT_OVERRIDE
Indicates manual set/unset of encryption.
Definition: lib.h:133
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:1102
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:170
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:1285
#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:120
#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:131
bool C_SigOnTop
Config: Insert the signature before the quoted text.
Definition: send.c:132
#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:111
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:100
#define SEC_SIGN
Email is signed.
Definition: lib.h:124
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:163
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:257
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:1034
WHERE bool C_ResumeDraftFiles
Config: Process draft files like postponed messages.
Definition: globals.h:247
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:270
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:423
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:241
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:109
bool C_UseFrom
Config: Set the &#39;From&#39; header for outgoing mail.
Definition: send.c:133
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:961
#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:1610
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:138
#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:578
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:45
Log at debug level 5.
Definition: logging.h:44
WHERE char * C_PgpSignAs
Config: Use this alternative key for signing messages.
Definition: globals.h:160
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:585
WHERE char * C_SmimeSignAs
Config: Use this alternative key for signing messages.
Definition: globals.h:164
static void append_signature(FILE *fp)
Append a signature to an email.
Definition: send.c:139
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:95
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:352
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:1362
int mutt_get_postponed(struct Context *ctx, struct Email *hdr, struct Email **cur, struct Buffer *fcc)
Recall a postponed message.
Definition: postpone.c:328
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:1125
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:102
bool C_NmRecord
Config: (notmuch) If the &#39;record&#39; mailbox (sent mail) should be indexed.
Definition: send.c:119
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:97
bool C_CryptAutoencrypt
Config: Automatically PGP encrypt all outgoing mail.
Definition: send.c:96
bool C_ReplyWithXorig
Config: Create &#39;From&#39; header from &#39;X-Original-To&#39; header.
Definition: send.c:127
+ 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 978 of file send.c.

979 {
980  add_references(&env->references, curenv);
981  add_message_id(&env->references, curenv);
982  add_message_id(&env->in_reply_to, curenv);
983 
984 #ifdef USE_NNTP
985  if (OptNewsSend && C_XCommentTo && !TAILQ_EMPTY(&curenv->from))
987 #endif
988 }
#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:884
static void add_message_id(struct ListHead *head, struct Envelope *env)
Add the email&#39;s message ID to a list.
Definition: send.c:900
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:284
#define TAILQ_EMPTY(head)
Definition: queue.h:714
WHERE bool OptNewsSend
(pseudo) used to change behavior when posting
Definition: options.h:45
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 1334 of file send.c.

1335 {
1336  /* Note: We let $from override $realname here.
1337  * Is this the right thing to do?
1338  */
1339 
1340  if (C_From)
1341  {
1342  return mutt_addr_copy(C_From);
1343  }
1344  else if (C_UseDomain)
1345  {
1346  struct Address *addr = mutt_addr_new();
1347  mutt_str_asprintf(&addr->mailbox, "%s@%s", NONULL(Username), NONULL(mutt_fqdn(true)));
1348  return addr;
1349  }
1350  else
1351  {
1352  return mutt_addr_create(NULL, Username);
1353  }
1354 }
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:259
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:2530
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:

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

208 {
209  char buf[8192];
210  char *err = NULL;
211  int idna_ok = 0;
212 
213  do
214  {
215  buf[0] = '\0';
217  mutt_addrlist_write(al, buf, sizeof(buf), false);
218  if (mutt_get_field(field, buf, sizeof(buf), MUTT_ALIAS) != 0)
219  return -1;
221  mutt_addrlist_parse2(al, buf);
222  if (expand_aliases)
224  idna_ok = mutt_addrlist_to_intl(al, &err);
225  if (idna_ok != 0)
226  {
227  mutt_error(_("Bad IDN: '%s'"), err);
228  FREE(&err);
229  }
230  } while (idna_ok != 0);
231  return 0;
232 }
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:63
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:

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

1449 {
1450  for (struct Body *t = b; t; t = t->next)
1451  {
1452  if (t->description)
1453  {
1454  rfc2047_encode(&t->description, NULL, sizeof("Content-Description:"), C_SendCharset);
1455  }
1456  if (recurse && t->parts)
1457  mutt_encode_descriptions(t->parts, recurse);
1458  }
1459 }
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:1448
void rfc2047_encode(char **pd, const char *specials, int col, const char *charsets)
RFC-2047-encode a string.
Definition: rfc2047.c:627
+ 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 829 of file send.c.

830 {
831  enum QuadOption hmfupto = MUTT_ABORT;
832  const struct Address *followup_to = TAILQ_FIRST(&in->mail_followup_to);
833 
834  if ((flags & (SEND_LIST_REPLY | SEND_GROUP_REPLY | SEND_GROUP_CHAT_REPLY)) && followup_to)
835  {
836  char prompt[256];
837  snprintf(prompt, sizeof(prompt), _("Follow-up to %s%s?"), followup_to->mailbox,
838  TAILQ_NEXT(TAILQ_FIRST(&in->mail_followup_to), entries) ? ",..." : "");
839 
840  hmfupto = query_quadoption(C_HonorFollowupTo, prompt);
841  if (hmfupto == MUTT_ABORT)
842  return -1;
843  }
844 
845  if (flags & SEND_LIST_REPLY)
846  {
847  add_mailing_lists(&out->to, &in->to, &in->cc);
848 
849  if (followup_to && (hmfupto == MUTT_YES) &&
850  (default_to(&out->cc, in, flags & SEND_LIST_REPLY, (hmfupto == MUTT_YES)) == MUTT_ABORT))
851  {
852  return -1; /* abort */
853  }
854  }
855  else if (flags & SEND_TO_SENDER)
856  {
857  mutt_addrlist_copy(&out->to, &in->from, false);
858  }
859  else
860  {
861  if (default_to(&out->to, in, flags & (SEND_GROUP_REPLY | SEND_GROUP_CHAT_REPLY),
862  (hmfupto == MUTT_YES)) == -1)
863  return -1; /* abort */
864 
865  if ((flags & (SEND_GROUP_REPLY | SEND_GROUP_CHAT_REPLY)) &&
866  (!followup_to || (hmfupto != MUTT_YES)))
867  {
868  /* if(!mutt_addr_is_user(in->to)) */
869  if (flags & SEND_GROUP_REPLY)
870  mutt_addrlist_copy(&out->cc, &in->to, true);
871  else
872  mutt_addrlist_copy(&out->to, &in->cc, true);
873  mutt_addrlist_copy(&out->cc, &in->cc, true);
874  }
875  }
876  return 0;
877 }
#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:1109
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:748
unsigned char C_HonorFollowupTo
Config: Honour the &#39;Mail-Followup-To&#39; header when group replying.
Definition: send.c:115
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:180
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 912 of file send.c.

913 {
914  if (!C_Metoo)
915  {
916  /* the order is important here. do the CC: first so that if the
917  * the user is the only recipient, it ends up on the TO: field */
918  remove_user(&env->cc, TAILQ_EMPTY(&env->to));
919  remove_user(&env->to, TAILQ_EMPTY(&env->cc) || C_ReplySelf);
920  }
921 
922  /* the CC field can get cluttered, especially with lists */
923  mutt_addrlist_dedupe(&env->to);
924  mutt_addrlist_dedupe(&env->cc);
925  mutt_addrlist_remove_xrefs(&env->to, &env->cc);
926 
927  if (!TAILQ_EMPTY(&env->cc) && TAILQ_EMPTY(&env->to))
928  {
929  TAILQ_SWAP(&env->to, &env->cc, Address, entries);
930  }
931 }
bool C_ReplySelf
Config: Really reply to yourself, when replying to your own email.
Definition: send.c:125
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:118
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:161
#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 429 of file send.c.

430 {
431  if (!C_ForwardAttributionIntro || !fp)
432  return;
433 
434  char buf[1024];
435  setlocale(LC_TIME, NONULL(C_AttributionLocale));
436  mutt_make_string(buf, sizeof(buf), 0, C_ForwardAttributionIntro, NULL, m, e);
437  setlocale(LC_TIME, "");
438  fputs(buf, fp);
439  fputs("\n\n", fp);
440 }
#define NONULL(x)
Definition: string2.h:37
char * C_ForwardAttributionIntro
Config: Prefix message for forwarded messages.
Definition: send.c:109
WHERE char * C_AttributionLocale
Config: Locale for dates in the attribution message.
Definition: globals.h:98
#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 448 of file send.c.

449 {
450  if (!C_ForwardAttributionTrailer || !fp)
451  return;
452 
453  char buf[1024];
454  setlocale(LC_TIME, NONULL(C_AttributionLocale));
455  mutt_make_string(buf, sizeof(buf), 0, C_ForwardAttributionTrailer, NULL, m, e);
456  setlocale(LC_TIME, "");
457  fputc('\n', fp);
458  fputs(buf, fp);
459  fputc('\n', fp);
460 }
#define NONULL(x)
Definition: string2.h:37
WHERE char * C_AttributionLocale
Config: Locale for dates in the attribution message.
Definition: globals.h:98
#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:110
+ 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 648 of file send.c.

649 {
650  if (!C_Attribution || !fp_out)
651  return;
652 
653  char buf[1024];
654  setlocale(LC_TIME, NONULL(C_AttributionLocale));
655  mutt_make_string(buf, sizeof(buf), 0, C_Attribution, NULL, m, e);
656  setlocale(LC_TIME, "");
657  fputs(buf, fp_out);
658  fputc('\n', fp_out);
659 }
#define NONULL(x)
Definition: string2.h:37
WHERE char * C_AttributionLocale
Config: Locale for dates in the attribution message.
Definition: globals.h:98
#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:97
+ 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 939 of file send.c.

940 {
941  if (!env)
942  return;
943 
944  char buf[256];
945 
946  /* set the default subject for the message. */
947  mutt_make_string(buf, sizeof(buf), 0, NONULL(C_ForwardFormat), NULL, m, e);
948  mutt_str_replace(&env->subject, buf);
949 }
#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:112
#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 956 of file send.c.

957 {
958  if (!env || !curenv)
959  return;
960 
961  /* This takes precedence over a subject that might have
962  * been taken from a List-Post header. Is that correct? */
963  if (curenv->real_subj)
964  {
965  FREE(&env->subject);
966  env->subject = mutt_mem_malloc(mutt_str_strlen(curenv->real_subj) + 5);
967  sprintf(env->subject, "Re: %s", curenv->real_subj);
968  }
969  else if (!env->subject)
971 }
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:103
+ 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 667 of file send.c.

668 {
669  if (!C_PostIndentString || !fp_out)
670  return;
671 
672  char buf[256];
673  mutt_make_string(buf, sizeof(buf), 0, C_PostIndentString, NULL, m, e);
674  fputs(buf, fp_out);
675  fputc('\n', fp_out);
676 }
#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:121
+ 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 1505 of file send.c.

1506 {
1507  struct Email *e_new = email_new();
1508 
1509  if (mutt_prepare_template(fp, ctx->mailbox, e_new, e_cur, true) < 0)
1510  {
1511  email_free(&e_new);
1512  return -1;
1513  }
1514 
1515  if (WithCrypto)
1516  {
1517  /* mutt_prepare_template doesn't always flip on an application bit.
1518  * so fix that here */
1519  if (!(e_new->security & (APPLICATION_SMIME | APPLICATION_PGP)))
1520  {
1521  if (((WithCrypto & APPLICATION_SMIME) != 0) && C_SmimeIsDefault)
1522  e_new->security |= APPLICATION_SMIME;
1523  else if (WithCrypto & APPLICATION_PGP)
1524  e_new->security |= APPLICATION_PGP;
1525  else
1526  e_new->security |= APPLICATION_SMIME;
1527  }
1528 
1530  {
1531  e_new->security |= SEC_OPPENCRYPT;
1533  }
1534  }
1535 
1536  struct EmailList el = STAILQ_HEAD_INITIALIZER(el);
1537  emaillist_add_email(&el, e_cur);
1538  int rc = ci_send_message(SEND_RESEND, e_new, NULL, ctx, &el);
1539  emaillist_clear(&el);
1540 
1541  return rc;
1542 }
#define WithCrypto
Definition: lib.h:161
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:274
struct Mailbox * mailbox
Definition: context.h:50
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition: lib.h:136
#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:269
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: lib.h:135
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:1892
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:131
void crypt_opportunistic_encrypt(struct Email *e)
Can all recipients be determined.
Definition: crypt.c:1034
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:644
+ 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 1214 of file send.c.

1215 {
1216  /* Only generate the Mail-Followup-To if the user has requested it, and
1217  * it hasn't already been set */
1218 
1219  if (!C_FollowupTo)
1220  return;
1221 #ifdef USE_NNTP
1222  if (OptNewsSend)
1223  {
1224  if (!env->followup_to && env->newsgroups && (strrchr(env->newsgroups, ',')))
1225  env->followup_to = mutt_str_strdup(env->newsgroups);
1226  return;
1227  }
1228 #endif
1229 
1230  if (TAILQ_EMPTY(&env->mail_followup_to))
1231  {
1232  if (mutt_is_list_recipient(false, env))
1233  {
1234  /* this message goes to known mailing lists, so create a proper
1235  * mail-followup-to header */
1236 
1237  mutt_addrlist_copy(&env->mail_followup_to, &env->to, false);
1238  mutt_addrlist_copy(&env->mail_followup_to, &env->cc, true);
1239  }
1240 
1241  /* remove ourselves from the mail-followup-to header */
1242  remove_user(&env->mail_followup_to, false);
1243 
1244  /* If we are not subscribed to any of the lists in question, re-add
1245  * ourselves to the mail-followup-to header. The mail-followup-to header
1246  * generated is a no-op with group-reply, but makes sure list-reply has the
1247  * desired effect. */
1248 
1249  if (!TAILQ_EMPTY(&env->mail_followup_to) &&
1250  !mutt_is_subscribed_list_recipient(false, env))
1251  {
1252  struct AddressList *al = NULL;
1253  if (!TAILQ_EMPTY(&env->reply_to))
1254  al = &env->reply_to;
1255  else if (!TAILQ_EMPTY(&env->from))
1256  al = &env->from;
1257 
1258  if (al)
1259  {
1260  struct Address *a = NULL;
1261  TAILQ_FOREACH_REVERSE(a, al, AddressList, entries)
1262  {
1264  }
1265  }
1266  else
1267  {
1269  }
1270  }
1271 
1273  }
1274 }
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:108
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:1334
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:1816
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:45
static void remove_user(struct AddressList *al, bool leave_only)
Remove any address which matches the current user.
Definition: send.c:161
int mutt_is_list_recipient(bool all_addr, struct Envelope *e)
Matches known mailing lists.
Definition: pattern.c:1828
+ 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 89 of file send.c.

◆ C_AbortNoattachRegex

struct Regex* C_AbortNoattachRegex

Config: Regex to match text indicating attachments are expected.

Definition at line 90 of file send.c.

◆ C_AbortNosubject

unsigned char C_AbortNosubject

Config: Abort creating the email if subject is missing.

Definition at line 91 of file send.c.

◆ C_AbortUnmodified

unsigned char C_AbortUnmodified

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

Definition at line 92 of file send.c.

◆ C_AskFollowUp

bool C_AskFollowUp

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

Definition at line 93 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 94 of file send.c.

◆ C_ContentType

char* C_ContentType

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

Definition at line 95 of file send.c.

◆ C_CryptAutoencrypt

bool C_CryptAutoencrypt

Config: Automatically PGP encrypt all outgoing mail.

Definition at line 96 of file send.c.

◆ C_CryptAutopgp

bool C_CryptAutopgp

Config: Allow automatic PGP functions.

Definition at line 97 of file send.c.

◆ C_CryptAutosign

bool C_CryptAutosign

Config: Automatically PGP sign all outgoing mail.

Definition at line 98 of file send.c.

◆ C_CryptAutosmime

bool C_CryptAutosmime

Config: Allow automatic SMIME functions.

Definition at line 99 of file send.c.

◆ C_CryptReplyencrypt

bool C_CryptReplyencrypt

Config: Encrypt replies to encrypted messages.

Definition at line 100 of file send.c.

◆ C_CryptReplysign

bool C_CryptReplysign

Config: Sign replies to signed messages.

Definition at line 101 of file send.c.

◆ C_CryptReplysignencrypted

bool C_CryptReplysignencrypted

Config: Sign replies to encrypted messages.

Definition at line 102 of file send.c.

◆ C_EmptySubject

char* C_EmptySubject

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

Definition at line 103 of file send.c.

◆ C_FastReply

bool C_FastReply

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

Definition at line 104 of file send.c.

◆ C_FccAttach

unsigned char C_FccAttach

Config: Save send message with all their attachments.

Definition at line 105 of file send.c.

◆ C_FccBeforeSend

bool C_FccBeforeSend

Config: Save FCCs before sending the message.

Definition at line 106 of file send.c.

◆ C_FccClear

bool C_FccClear

Config: Save sent messages unencrypted and unsigned.

Definition at line 107 of file send.c.

◆ C_FollowupTo

bool C_FollowupTo

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

Definition at line 108 of file send.c.

◆ C_ForwardAttributionIntro

char* C_ForwardAttributionIntro

Config: Prefix message for forwarded messages.

Definition at line 109 of file send.c.

◆ C_ForwardAttributionTrailer

char* C_ForwardAttributionTrailer

Config: Suffix message for forwarded messages.

Definition at line 110 of file send.c.

◆ C_ForwardEdit

unsigned char C_ForwardEdit

Config: Automatically start the editor when forwarding a message.

Definition at line 111 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 112 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 113 of file send.c.

◆ C_Hdrs

bool C_Hdrs

Config: Add custom headers to outgoing mail.

Definition at line 114 of file send.c.

◆ C_HonorFollowupTo

unsigned char C_HonorFollowupTo

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

Definition at line 115 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 116 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 117 of file send.c.

◆ C_Metoo

bool C_Metoo

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

Definition at line 118 of file send.c.

◆ C_NmRecord

bool C_NmRecord

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

Definition at line 119 of file send.c.

◆ C_PgpReplyinline

bool C_PgpReplyinline

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

Definition at line 120 of file send.c.

◆ C_PostIndentString

char* C_PostIndentString

Config: Suffix message to add after reply text.

Definition at line 121 of file send.c.

◆ C_PostponeEncrypt

bool C_PostponeEncrypt

Config: Self-encrypt postponed messages.

Definition at line 122 of file send.c.

◆ C_PostponeEncryptAs

char* C_PostponeEncryptAs

Config: Fallback encryption key for postponed messages.

Definition at line 123 of file send.c.

◆ C_Recall

unsigned char C_Recall

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

Definition at line 124 of file send.c.

◆ C_ReplySelf

bool C_ReplySelf

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

Definition at line 125 of file send.c.

◆ C_ReplyTo

unsigned char C_ReplyTo

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

Definition at line 126 of file send.c.

◆ C_ReplyWithXorig

bool C_ReplyWithXorig

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

Definition at line 127 of file send.c.

◆ C_ReverseName

bool C_ReverseName

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

Definition at line 128 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 129 of file send.c.

◆ C_SigDashes

bool C_SigDashes

Config: Insert '– ' before the signature.

Definition at line 130 of file send.c.

◆ C_Signature

char* C_Signature

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

Definition at line 131 of file send.c.

◆ C_SigOnTop

bool C_SigOnTop

Config: Insert the signature before the quoted text.

Definition at line 132 of file send.c.

◆ C_UseFrom

bool C_UseFrom

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

Definition at line 133 of file send.c.