/*
- * Copyright (C) 1996-2002 Michael R. Elkins <me@mutt.org>
+ * Copyright (C) 1996-2002,2004 Michael R. Elkins <me@mutt.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
#include "mime.h"
#include "mailbox.h"
#include "copy.h"
-#include "mx.h"
#include "mutt_crypt.h"
#include "mutt_idna.h"
#include "url.h"
if (option (OPTSIGDASHES))
fputs ("\n-- \n", f);
mutt_copy_stream (tmpfp, f);
- fclose (tmpfp);
+ safe_fclose (&tmpfp);
if (thepid != -1)
mutt_wait_filter (thepid);
}
}
else if (ascii_strncasecmp ("message-id:", uh->data, 11) == 0)
{
- char *tmp = mutt_extract_message_id (uh->data + 11);
+ char *tmp = mutt_extract_message_id (uh->data + 11, NULL);
if (rfc822_valid_msgid (tmp) >= 0)
{
FREE(&env->message_id);
else if (ascii_strncasecmp ("to:", uh->data, 3) != 0 &&
ascii_strncasecmp ("cc:", uh->data, 3) != 0 &&
ascii_strncasecmp ("bcc:", uh->data, 4) != 0 &&
- ascii_strncasecmp ("subject:", uh->data, 8) != 0)
+ ascii_strncasecmp ("subject:", uh->data, 8) != 0 &&
+ ascii_strncasecmp ("return-path:", uh->data, 12) != 0)
{
if (last)
{
if (option (OPTFORWQUOTE))
cmflags |= M_CM_PREFIX;
+ /* wrapping headers for forwarding is considered a display
+ * rather than send action */
+ chflags |= CH_DISPLAY;
+
mutt_copy_message (out, ctx, cur, cmflags, chflags);
mutt_forward_trailer (out);
return 0;
if (flags && env->mail_followup_to && hmfupto == M_YES)
{
- rfc822_append (to, env->mail_followup_to);
+ rfc822_append (to, env->mail_followup_to, 1);
return 0;
}
if (!option(OPTREPLYSELF) && mutt_addr_is_user (env->from))
{
/* mail is from the user, assume replying to recipients */
- rfc822_append (to, env->to);
+ rfc822_append (to, env->to, 1);
}
else if (env->reply_to)
{
* in his From header.
*
*/
- rfc822_append (to, env->from);
+ rfc822_append (to, env->from, 0);
}
else if (!(mutt_addrcmp (env->from, env->reply_to) &&
!env->reply_to->next) &&
switch (query_quadoption (OPT_REPLYTO, prompt))
{
case M_YES:
- rfc822_append (to, env->reply_to);
+ rfc822_append (to, env->reply_to, 0);
break;
case M_NO:
- rfc822_append (to, env->from);
+ rfc822_append (to, env->from, 0);
break;
default:
}
}
else
- rfc822_append (to, env->reply_to);
+ rfc822_append (to, env->reply_to, 0);
}
else
- rfc822_append (to, env->from);
+ rfc822_append (to, env->from, 0);
return (0);
}
if (flags & SENDLISTREPLY)
{
tmp = find_mailing_lists (in->to, in->cc);
- rfc822_append (&out->to, tmp);
+ rfc822_append (&out->to, tmp, 0);
rfc822_free_address (&tmp);
if (in->mail_followup_to && hmfupto == M_YES &&
if ((flags & SENDGROUPREPLY) && (!in->mail_followup_to || hmfupto != M_YES))
{
/* if(!mutt_addr_is_user(in->to)) */
- rfc822_append (&out->cc, in->to);
- rfc822_append (&out->cc, in->cc);
+ rfc822_append (&out->cc, in->to, 1);
+ rfc822_append (&out->cc, in->cc, 1);
}
}
return 0;
}
else
mutt_add_to_reference_headers (env, curenv, NULL, NULL);
+
+ /* if there's more than entry in In-Reply-To (i.e. message has
+ multiple parents), don't generate a References: header as it's
+ discouraged by RfC2822, sect. 3.6.4 */
+ if (ctx->tagged > 0 && env->in_reply_to && env->in_reply_to->next)
+ mutt_free_list (&env->references);
}
static int
* mail-followup-to header
*/
- t = rfc822_append (&e->mail_followup_to, e->to);
- rfc822_append (&t, e->cc);
+ t = rfc822_append (&e->mail_followup_to, e->to, 0);
+ rfc822_append (&t, e->cc, 1);
}
/* remove ourselves from the mail-followup-to header */
if (e->mail_followup_to && !mutt_is_list_recipient (0, e->to, e->cc))
{
if (e->reply_to)
- from = rfc822_cpy_adr (e->reply_to);
+ from = rfc822_cpy_adr (e->reply_to, 0);
else if (e->from)
- from = rfc822_cpy_adr (e->from);
+ from = rfc822_cpy_adr (e->from, 0);
else
from = mutt_default_from ();
if (tmp)
{
tmp = rfc822_cpy_adr_real (tmp);
+ /* when $reverse_realname is not set, clear the personal name so that it
+ * may be set vi a reply- or send-hook.
+ */
if (!option (OPTREVREAL))
FREE (&tmp->personal);
- if (!tmp->personal)
- tmp->personal = safe_strdup (Realname);
}
return (tmp);
}
#endif
/* Write out the message in MIME form. */
- mutt_mktemp (tempfile);
+ mutt_mktemp (tempfile, sizeof (tempfile));
if ((tempfp = safe_fopen (tempfile, "w")) == NULL)
return (-1);
if ((mutt_write_mime_body (msg->content, tempfp) == -1))
{
- fclose(tempfp);
+ safe_fclose (&tempfp);
unlink (tempfile);
return (-1);
}
return ci_send_message (SENDRESEND, msg, NULL, ctx, cur);
}
+static int is_reply (HEADER *reply, HEADER *orig)
+{
+ return mutt_find_list (orig->env->references, reply->env->message_id) ||
+ mutt_find_list (orig->env->in_reply_to, reply->env->message_id);
+}
+
+static int has_recips (ADDRESS *a)
+{
+ int c = 0;
+
+ for ( ; a; a = a->next)
+ {
+ if (!a->mailbox || a->group)
+ continue;
+ c++;
+ }
+ return c;
+}
+
int
ci_send_message (int flags, /* send mode */
HEADER *msg, /* template to use for new message */
if (!tempfile)
{
- mutt_mktemp (buffer);
+ mutt_mktemp (buffer, sizeof (buffer));
tempfp = safe_fopen (buffer, "w+");
msg->content->filename = safe_strdup (buffer);
}
msg->env->from = set_reverse_name (cur->env);
}
- if (!msg->env->from && option (OPTUSEFROM) && !(flags & (SENDPOSTPONED|SENDRESEND)))
- {
- msg->env->from = mutt_default_from ();
- if (!(flags & SENDBATCH))
- killfrom = 1; /* $use_from will be re-checked after send-hooks */
- }
-
- if (flags & SENDBATCH)
- {
- mutt_copy_stream (stdin, tempfp);
- if (option (OPTHDRS))
- {
- process_user_recips (msg->env);
- process_user_header (msg->env);
- }
- mutt_expand_aliases_env (msg->env);
- }
- else if (! (flags & (SENDPOSTPONED|SENDRESEND)))
+ if (! (flags & (SENDPOSTPONED|SENDRESEND)))
{
if ((flags & (SENDREPLY | SENDFORWARD)) && ctx &&
envelope_defaults (msg->env, ctx, cur, flags) == -1)
if (flags & SENDREPLY)
mutt_fix_reply_recipients (msg->env);
- if (! (flags & SENDMAILX) &&
+ if (! (flags & (SENDMAILX|SENDBATCH)) &&
! (option (OPTAUTOEDIT) && option (OPTEDITHDRS)) &&
! ((flags & SENDREPLY) && option (OPTFASTREPLY)))
{
if (option (OPTHDRS))
process_user_header (msg->env);
+ if (flags & SENDBATCH)
+ mutt_copy_stream (stdin, tempfp);
- if (option (OPTSIGONTOP) && (! (flags & (SENDMAILX | SENDKEY)) && Editor && mutt_strcmp (Editor, "builtin") != 0))
+ if (option (OPTSIGONTOP) && ! (flags & (SENDMAILX|SENDKEY|SENDBATCH))
+ && Editor && mutt_strcmp (Editor, "builtin") != 0)
append_signature (tempfp);
/* include replies/forwarded messages, unless we are given a template */
&& generate_body (tempfp, msg, flags, ctx, cur) == -1)
goto cleanup;
- if (!option (OPTSIGONTOP) && (! (flags & (SENDMAILX | SENDKEY)) && Editor && mutt_strcmp (Editor, "builtin") != 0))
+ if (!option (OPTSIGONTOP) && ! (flags & (SENDMAILX|SENDKEY|SENDBATCH))
+ && Editor && mutt_strcmp (Editor, "builtin") != 0)
append_signature (tempfp);
-
- /*
- * this wants to be done _after_ generate_body, so message-hooks
- * can take effect.
- */
-
- if (WithCrypto && !(flags & SENDMAILX))
- {
- if (option (OPTCRYPTAUTOSIGN))
- msg->security |= SIGN;
- if (option (OPTCRYPTAUTOENCRYPT))
- msg->security |= ENCRYPT;
- if (option (OPTCRYPTREPLYENCRYPT) && cur && (cur->security & ENCRYPT))
- msg->security |= ENCRYPT;
- if (option (OPTCRYPTREPLYSIGN) && cur && (cur->security & SIGN))
- msg->security |= SIGN;
- if (option (OPTCRYPTREPLYSIGNENCRYPTED) && cur && (cur->security & ENCRYPT))
- msg->security |= SIGN;
- if (WithCrypto & APPLICATION_PGP && (msg->security & (ENCRYPT | SIGN)))
- {
- if (option (OPTPGPAUTOINLINE))
- msg->security |= INLINE;
- if (option (OPTPGPREPLYINLINE) && cur && (cur->security & INLINE))
- msg->security |= INLINE;
- }
- }
-
- if (WithCrypto && msg->security)
- {
- /*
- * When reypling / forwarding, use the original message's
- * crypto system. According to the documentation,
- * smime_is_default should be disregarded here.
- *
- * Problem: At least with forwarding, this doesn't really
- * make much sense. Should we have an option to completely
- * disable individual mechanisms at run-time?
- */
- if (cur)
- {
- if ((WithCrypto & APPLICATION_PGP) && option (OPTCRYPTAUTOPGP)
- && (cur->security & APPLICATION_PGP))
- msg->security |= APPLICATION_PGP;
- else if ((WithCrypto & APPLICATION_SMIME) && option (OPTCRYPTAUTOSMIME)
- && (cur->security & APPLICATION_SMIME))
- msg->security |= APPLICATION_SMIME;
- }
-
- /*
- * No crypto mechanism selected? Use availability + smime_is_default
- * for the decision.
- */
- if (!(msg->security & (APPLICATION_SMIME | APPLICATION_PGP)))
- {
- if ((WithCrypto & APPLICATION_SMIME) && option (OPTCRYPTAUTOSMIME)
- && option (OPTSMIMEISDEFAULT))
- msg->security |= APPLICATION_SMIME;
- else if ((WithCrypto & APPLICATION_PGP) && option (OPTCRYPTAUTOPGP))
- msg->security |= APPLICATION_PGP;
- else if ((WithCrypto & APPLICATION_SMIME) && option (OPTCRYPTAUTOSMIME))
- msg->security |= APPLICATION_SMIME;
- }
- }
-
- /* No permissible mechanisms found. Don't sign or encrypt. */
- if (!(msg->security & (APPLICATION_SMIME|APPLICATION_PGP)))
- msg->security = 0;
}
/*
* don't want to do this when:
* 1) we are sending a key/cert
* 2) we are forwarding a message and the user doesn't want to edit it.
- * This is controled by the quadoption $forward_edit. However, if
+ * This is controlled by the quadoption $forward_edit. However, if
* both $edit_headers and $autoedit are set, we want to ignore the
* setting of $forward_edit because the user probably needs to add the
* recipients.
}
}
+ /*
+ * Set the message security unless:
+ * 1) crypto support is not enabled (WithCrypto==0)
+ * 2) pgp: header field was present during message editing with $edit_headers (msg->security != 0)
+ * 3) we are resending a message
+ * 4) we are recalling a postponed message (don't override the user's saved settings)
+ * 5) we are in mailx mode
+ * 6) we are in batch mode
+ *
+ * This is done after allowing the user to edit the message so that security
+ * settings can be configured with send2-hook and $edit_headers.
+ */
+ if (WithCrypto && (msg->security == 0) && !(flags & (SENDBATCH | SENDMAILX | SENDPOSTPONED | SENDRESEND)))
+ {
+ if (option (OPTCRYPTAUTOSIGN))
+ msg->security |= SIGN;
+ if (option (OPTCRYPTAUTOENCRYPT))
+ msg->security |= ENCRYPT;
+ if (option (OPTCRYPTREPLYENCRYPT) && cur && (cur->security & ENCRYPT))
+ msg->security |= ENCRYPT;
+ if (option (OPTCRYPTREPLYSIGN) && cur && (cur->security & SIGN))
+ msg->security |= SIGN;
+ if (option (OPTCRYPTREPLYSIGNENCRYPTED) && cur && (cur->security & ENCRYPT))
+ msg->security |= SIGN;
+ if (WithCrypto & APPLICATION_PGP && (msg->security & (ENCRYPT | SIGN)))
+ {
+ if (option (OPTPGPAUTOINLINE))
+ msg->security |= INLINE;
+ if (option (OPTPGPREPLYINLINE) && cur && (cur->security & INLINE))
+ msg->security |= INLINE;
+ }
+
+ if (msg->security)
+ {
+ /*
+ * When replying / forwarding, use the original message's
+ * crypto system. According to the documentation,
+ * smime_is_default should be disregarded here.
+ *
+ * Problem: At least with forwarding, this doesn't really
+ * make much sense. Should we have an option to completely
+ * disable individual mechanisms at run-time?
+ */
+ if (cur)
+ {
+ if ((WithCrypto & APPLICATION_PGP) && option (OPTCRYPTAUTOPGP)
+ && (cur->security & APPLICATION_PGP))
+ msg->security |= APPLICATION_PGP;
+ else if ((WithCrypto & APPLICATION_SMIME) && option (OPTCRYPTAUTOSMIME)
+ && (cur->security & APPLICATION_SMIME))
+ msg->security |= APPLICATION_SMIME;
+ }
+
+ /*
+ * No crypto mechanism selected? Use availability + smime_is_default
+ * for the decision.
+ */
+ if (!(msg->security & (APPLICATION_SMIME | APPLICATION_PGP)))
+ {
+ if ((WithCrypto & APPLICATION_SMIME) && option (OPTCRYPTAUTOSMIME)
+ && option (OPTSMIMEISDEFAULT))
+ msg->security |= APPLICATION_SMIME;
+ else if ((WithCrypto & APPLICATION_PGP) && option (OPTCRYPTAUTOPGP))
+ msg->security |= APPLICATION_PGP;
+ else if ((WithCrypto & APPLICATION_SMIME) && option (OPTCRYPTAUTOSMIME))
+ msg->security |= APPLICATION_SMIME;
+ }
+ }
+
+ /* No permissible mechanisms found. Don't sign or encrypt. */
+ if (!(msg->security & (APPLICATION_SMIME|APPLICATION_PGP)))
+ msg->security = 0;
+ }
+
/* specify a default fcc. if we are in batchmode, only save a copy of
* the message if the value of $copy is yes or ask-yes */
main_loop:
fcc_error = 0; /* reset value since we may have failed before */
- mutt_pretty_mailbox (fcc);
+ mutt_pretty_mailbox (fcc, sizeof (fcc));
i = mutt_compose_menu (msg, fcc, sizeof (fcc), cur);
if (i == -1)
{
}
}
- if (!msg->env->to && !msg->env->cc && !msg->env->bcc)
+ if (!has_recips (msg->env->to) && !has_recips (msg->env->cc) &&
+ !has_recips (msg->env->bcc))
{
if (! (flags & SENDBATCH))
{
msg->content = clear_content;
/* check to see if the user wants copies of all attachments */
- if (!option (OPTFCCATTACH) && msg->content->type == TYPEMULTIPART)
+ if (query_quadoption (OPT_FCCATTACH, _("Save attachments in Fcc?")) != M_YES &&
+ msg->content->type == TYPEMULTIPART)
{
if (WithCrypto
&& (mutt_strcmp (msg->content->subtype, "encrypted") == 0 ||
* the send failed as well so we give the user a chance to fix the
* error.
*/
- if (fcc_error || (i = send_message (msg)) == -1)
+ if (fcc_error || (i = send_message (msg)) < 0)
{
if (!(flags & SENDBATCH))
{
if (WithCrypto && free_clear_content)
mutt_free_body (&clear_content);
+ /* set 'replied' flag only if the user didn't change/remove
+ In-Reply-To: and References: headers during edit */
if (flags & SENDREPLY)
{
if (cur && ctx)
- mutt_set_flag (ctx, cur, M_REPLIED, 1);
+ mutt_set_flag (ctx, cur, M_REPLIED, is_reply (cur, msg));
else if (!(flags & SENDPOSTPONED) && ctx && ctx->tagged)
{
for (i = 0; i < ctx->vcount; i++)
if (ctx->hdrs[ctx->v2r[i]]->tagged)
- mutt_set_flag (ctx, ctx->hdrs[ctx->v2r[i]], M_REPLIED, 1);
+ mutt_set_flag (ctx, ctx->hdrs[ctx->v2r[i]], M_REPLIED,
+ is_reply (ctx->hdrs[ctx->v2r[i]], msg));
}
}