...
 
Commits (24)
  • Daniel Tameling's avatar
    Fix rendering of replacement_char when Charset_is_utf8 · 10a35e5d
    Daniel Tameling authored
    Use mutt_addwch instead of addch to draw the replacement_char in
    pager.c. The line to draw the replacement char was
    addch (replacement_char ())
    However, if Charset_is_utf8 is true, replacement_char returns 0xfffd,
    which is outside the range that addch can handle. Use mutt_addwch
    instead so that the pager displays the replacement char properly.
    10a35e5d
  • Kevin J. McCarthy's avatar
    Merge branch 'stable' · 7a1a121e
    Kevin J. McCarthy authored
    7a1a121e
  • Kevin J. McCarthy's avatar
    Revert $ssl_force_tls to default unset. · 376716eb
    Kevin J. McCarthy authored
    In theory it's a good idea encourage SSL usage everywhere.
    
    However ticket #210 showed that, in reality, that kind of change
    breaks configs and so is still not a good idea.
    
    $ssl_startls defaults set and will use STARTTLS if the server
    advertises it.
    376716eb
  • Kevin J. McCarthy's avatar
    Merge branch 'stable' · f2b05d7c
    Kevin J. McCarthy authored
    f2b05d7c
  • Kevin J. McCarthy's avatar
    Speed up thread sort when many long threads exist. · 0f8a079d
    Kevin J. McCarthy authored
    Merge request !75 reported a massive slowdown opening a mailbox with
    many long threads: on the order of an hour.
    
    This is because mutt_set_virtual() was iterating through the whole
    thread for each message.
    
    After taking a closer look at current Mutt behavior, it seems the
    num_hidden count is only needed in the root thread.  Quoting my
    comment in the merge request:
    
      The index-format expando %M only applies to root level headers, so
      there are no issues there.
    
      The only concern is the pattern ~v. Limiting always resets collapsed
      and num_hidden, so there also can't be any issues there. Tagging and
      other pattern operators only work on visible messages. So tagging
      while threads are sorted will only tag the root messages of
      collapsed threads.
    
      However, if you sort by thread, collapse a thread, and then sort by
      date, the collapsed and num_hidden fields are not reset for each
      header. In theory this would allow us to tag ~v with date
      ordering. However, in master the num_hidden is only set (by
      mutt_set_virtual()) for visible messages with a virtual number.
    
      So even in master, switching to date-order and tagging ~v will only
      tag the root messages of each collapsed thread.
    
    This commit removes the num_hidden setting in mutt_set_virtual(),
    instead directly assigning that value in the roothdr during a collapse
    operation.
    
    A subsequent commit will fix the behavior of ~v, when switching
    sorting from threaded to something else, by putting num_hidden in
    every header in the thread.  This is technically a change in behavior,
    so I will make that commit in the master branch.
    
    Thanks to Score_Under for the pull request and for testing my
    alternate solutions.
    0f8a079d
  • Kevin J. McCarthy's avatar
    Merge branch 'stable' · 8d77022b
    Kevin J. McCarthy authored
    8d77022b
  • Kevin J. McCarthy's avatar
    Fix ~v tagging when switching to non-threaded sorting. · 83be183b
    Kevin J. McCarthy authored
    Place num_hidden in all the collapsed thread messages, rather than
    just the visible ones (i.e. the root headers).
    
    This is a tweak to commit 0f8a079d, where I discovered the behavior
    inconsistent with the documentation.  I'm making this change in master
    due to the (tiny) behavior change.
    83be183b
  • Kevin J. McCarthy's avatar
    Fix crash when syncing large IMAP mailboxes. · 6051760c
    Kevin J. McCarthy authored
    imap_sync_mailbox() and imap_exec_msgset() make a copy of the headers
    before resorting them to generate a message-set, to avoid context
    changes.  I noticed the oddity in the past but didn't investigate
    deeply enough at the time. :-/
    
    The code in imap_sync_mailbox() was wrong for four reasons:
    1) Because IMAP_REOPEN_ALLOW is set, sync_helper() can trigger
       an imap_exec if the queue fills up, resulting in new messages
       being downloaded or expunges being triggered.
    
    2) The copy was only allocating msgcount headers, instead of hdrmax.
       Downloading new messages could then attempt to append beyond the end
       of the array if hdrmax > msgcount.
    
    3) New messages or expunges would disappear when the copy was restored
       afterwards.
    
    4) The callers of mx_sync_mailbox() are prepared for context changes,
       and will adjust the cursor properly to avoid jumps.
    
    The same problems can occur in imap_exec_msgset() when reopen is set.
    Not all of its callers enable reopen, or are prepared to deal with
    context changes though, so the copy is needed when reopen is not set.
    
    An alternative solution tried converting to call mutt_sort_headers()
    when possible.  However that solution turned out to visibly slow down
    syncs due to the double sorting.
    
    This commit instead turns off reopen for the duration of the msgset
    operations.
    
    While verifying all queued operations are flushed, I noticed the
    initial "quick delete" in imap_sync_mailbox() did not seem to be
    guaranteed to flush.  Ensure the imap_exec() further below is
    triggered if either the quick delete or sync_helper calls generate
    changes.  Change the quick delete to assign to "quickdel_rc" to make
    it clear the flush below is for both.
    
    Change the post sync/msgset check to look for both ((oldsort != Sort)
    || hdrs), just to make sure a memory leak doesn't occur.
    6051760c
  • Kevin J. McCarthy's avatar
    Merge branch 'stable' · f1808b6c
    Kevin J. McCarthy authored
    f1808b6c
  • Kevin J. McCarthy's avatar
    Create send.h header. · 3669133a
    Kevin J. McCarthy authored
    This will hold the send context, so we may as well pull the prototypes
    into the header file too.
    3669133a
  • Kevin J. McCarthy's avatar
    rename send_message to invoke_mta. · 565ef083
    Kevin J. McCarthy authored
    565ef083
  • Kevin J. McCarthy's avatar
    f8c9eb92
  • Kevin J. McCarthy's avatar
    Refactor mutt_send_message() into multiple functions. · 4a53e299
    Kevin J. McCarthy authored
    Create SEND_CONTEXT to contain all the state logic.
    4a53e299
  • Kevin J. McCarthy's avatar
    Add send_ctx to compose menu and get_postponed(). · e6c36335
    Kevin J. McCarthy authored
    This will be used to store and use sctx for sign_as values.
    e6c36335
  • Kevin J. McCarthy's avatar
    Pass sctx to mutt_builtin_editor and mutt_edit_headers. · 92d9e197
    Kevin J. McCarthy authored
    This will be used to set the sctx signas instead of globals for header
    editing.
    92d9e197
  • Kevin J. McCarthy's avatar
    Use sctx->signas values in compose menu. · 6e877691
    Kevin J. McCarthy authored
    todo: we need to fix the send_menus.
    We need to save/restore the globals in mutt_protect().
    6e877691
  • Kevin J. McCarthy's avatar
    Change mutt_protect() to use sctx signas values. · e5f5d879
    Kevin J. McCarthy authored
    Pass the sctx into postpone_message() and save_fcc() to it can be
    passed to mutt_protect.
    
    Change compose menu to show the sctx values, but fall back to the
    globals.
    e5f5d879
  • Kevin J. McCarthy's avatar
    Change send_menus to set sctx instead of globals. · cc25fd2b
    Kevin J. McCarthy authored
    Add a "cleared" bit for smime_crypt_alg.  Otherwise clearing the value
    in smime.c's menu would cause the compose menu and mutt_protect() to
    fall back to using SmimeCryptAlg.
    cc25fd2b
  • Kevin J. McCarthy's avatar
    f0b1b230
  • Kevin J. McCarthy's avatar
    wip - background.c · 6812412c
    Kevin J. McCarthy authored
    rebase this later when finish send.c refactor.
    6812412c
  • Kevin J. McCarthy's avatar
    wip: initial background edit work · ef339ec5
    Kevin J. McCarthy authored
    Add options.  Add comments and todos.
    ef339ec5
  • Kevin J. McCarthy's avatar
    Very basic background edit for <mail> without $edit_headers. · 060a5058
    Kevin J. McCarthy authored
    This is just to test the basic viability of the idea.
    
    Current limitations:
      - a single backgrounded process
      - hit "m" <mail> to resume.
      - only for the initial edit, with $edit_headers unset
    
    Todo:
      - expand to $edit_headers
      - expand to compose menu
      - put waitpid and SIGCHLD handling in
      - allow more than one background edit and a menu to choose
      - expand to replies
      - perhaps expand to other operations
    060a5058
  • Kevin J. McCarthy's avatar
    wip: first edit_headers background · 390da599
    Kevin J. McCarthy authored
    390da599
  • Kevin J. McCarthy's avatar
    wip: resume in compose menu. · e406fb97
    Kevin J. McCarthy authored
    e406fb97
......@@ -27,8 +27,8 @@ BUILT_SOURCES = keymap_defs.h patchlist.c reldate.h conststrings.c version.h $(H
bin_PROGRAMS = mutt $(DOTLOCK_TARGET) $(PGPAUX_TARGET)
mutt_SOURCES = \
addrbook.c alias.c attach.c base64.c browser.c buffer.c buffy.c color.c \
crypt.c cryptglue.c \
addrbook.c alias.c attach.c background.c base64.c browser.c buffer.c \
buffy.c color.c crypt.c cryptglue.c \
commands.c complete.c compose.c copy.c curs_lib.c curs_main.c date.c \
edit.c enter.c flags.c init.c filter.c from.c \
getdomain.c group.c \
......@@ -77,7 +77,7 @@ EXTRA_DIST = COPYRIGHT GPL OPS OPS.PGP OPS.CRYPT OPS.SMIME TODO UPDATING \
rfc2231.h rfc822.h rfc3676.h sha1.h sort.h mime.types VERSION prepare \
_mutt_regex.h OPS.MIX README.SECURITY remailer.c remailer.h browser.h \
mbyte.h lib.h extlib.c pgpewrap.c smime_keys.pl pgplib.h \
README.SSL smime.h group.h mutt_zstrm.h \
README.SSL smime.h group.h mutt_zstrm.h send.h background.h \
muttbug pgppacket.h depcomp ascii.h BEWARE PATCHES patchlist.sh \
ChangeLog mkchangelog.sh mkreldate.sh mutt_idna.h sidebar.h OPS.SIDEBAR \
snprintf.c regex.c crypt-gpgme.h hcachever.pl \
......
......@@ -26,6 +26,7 @@
#include "mime.h"
#include "mutt_idna.h"
#include "mailbox.h"
#include "send.h"
#include "autocrypt.h"
#include "autocrypt_private.h"
......
/*
* Copyright (C) 1996-2000,2013 Michael R. Elkins <me@mutt.org>
* Copyright (C) 2020 Kevin J. McCarthy <kevin@8t8.us>
*
* 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#if HAVE_CONFIG_H
# include "config.h"
#endif
#include "mutt.h"
#include "send.h"
#include "background.h"
#include <stdlib.h>
#include <signal.h>
#include <string.h>
#include <sys/wait.h>
#include <unistd.h>
static pid_t mutt_background_run (const char *cmd)
{
struct sigaction act;
pid_t thepid;
int fd;
if (!cmd || !*cmd)
return (0);
/* must ignore SIGINT and SIGQUIT */
mutt_block_signals_system ();
if ((thepid = fork ()) == 0)
{
/* give up controlling terminal */
setsid ();
/* this ensures the child can't use stdin to take control of the
* terminal */
#if defined(OPEN_MAX)
for (fd = 0; fd < OPEN_MAX; fd++)
close (fd);
#elif defined(_POSIX_OPEN_MAX)
for (fd = 0; fd < _POSIX_OPEN_MAX; fd++)
close (fd);
#else
close (0);
close (1);
close (2);
#endif
/* reset signals for the child; not really needed, but... */
mutt_unblock_signals_system (0);
act.sa_handler = SIG_DFL;
act.sa_flags = 0;
sigemptyset (&act.sa_mask);
sigaction (SIGTERM, &act, NULL);
sigaction (SIGTSTP, &act, NULL);
sigaction (SIGCONT, &act, NULL);
execle (EXECSHELL, "sh", "-c", cmd, NULL, mutt_envlist ());
_exit (127); /* execl error */
}
/* reset SIGINT, SIGQUIT and SIGCHLD */
mutt_unblock_signals_system (1);
return (thepid);
}
int mutt_background_edit_file (SEND_CONTEXT *sctx, const char *editor,
const char *filename)
{
BUFFER *cmd;
pid_t pid;
int rc = -1;
cmd = mutt_buffer_pool_get ();
mutt_expand_file_fmt (cmd, editor, filename);
pid = mutt_background_run (mutt_b2s (cmd));
if (pid <= 0)
{
mutt_error (_("Error running \"%s\"!"), mutt_b2s (cmd));
mutt_sleep (2);
goto cleanup;
}
sctx->background_pid = pid;
BackgroundProcess = sctx;
rc = 0;
cleanup:
mutt_buffer_pool_release (&cmd);
return rc;
}
/*
* Copyright (C) 2020 Kevin J. McCarthy <kevin@8t8.us>
*
* 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef _BACKGROUND_H
#define _BACKGROUND_H 1
WHERE SEND_CONTEXT *BackgroundProcess;
int mutt_background_edit_file (SEND_CONTEXT *sctx, const char *editor,
const char *filename);
#endif
......@@ -35,6 +35,7 @@
#include "sort.h"
#include "charset.h"
#include "rfc3676.h"
#include "background.h"
#ifdef MIXMASTER
#include "remailer.h"
......@@ -172,6 +173,7 @@ typedef struct
{
HEADER *msg;
BUFFER *fcc;
SEND_CONTEXT *sctx;
#ifdef USE_AUTOCRYPT
autocrypt_rec_t autocrypt_rec;
int autocrypt_rec_override;
......@@ -279,6 +281,7 @@ static void autocrypt_compose_menu (HEADER *msg)
static void redraw_crypt_lines (compose_redraw_data_t *rd)
{
HEADER *msg = rd->msg;
SEND_CONTEXT *sctx = rd->sctx;
SETCOLOR (MT_COLOR_COMPOSE_HEADER);
mutt_window_mvprintw (MuttIndexWindow, HDR_CRYPT, 0,
......@@ -340,7 +343,8 @@ static void redraw_crypt_lines (compose_redraw_data_t *rd)
SETCOLOR (MT_COLOR_COMPOSE_HEADER);
printw ("%*s", HeaderPadding[HDR_CRYPTINFO], _(Prompts[HDR_CRYPTINFO]));
NORMAL_COLOR;
printw ("%s", PgpSignAs ? PgpSignAs : _("<default>"));
printw ("%s", sctx->pgp_sign_as ? sctx->pgp_sign_as :
(PgpSignAs ? PgpSignAs : _("<default>")));
}
if ((WithCrypto & APPLICATION_SMIME)
......@@ -349,18 +353,23 @@ static void redraw_crypt_lines (compose_redraw_data_t *rd)
SETCOLOR (MT_COLOR_COMPOSE_HEADER);
printw ("%*s", HeaderPadding[HDR_CRYPTINFO], _(Prompts[HDR_CRYPTINFO]));
NORMAL_COLOR;
printw ("%s", SmimeSignAs ? SmimeSignAs : _("<default>"));
printw ("%s", sctx->smime_sign_as ? sctx->smime_sign_as :
(SmimeSignAs ? SmimeSignAs : _("<default>")));
}
/* Note: the smime crypt alg can be cleared in smime.c.
* this causes a NULL sctx->smime_crypt_alg to override SmimeCryptAlg.
*/
if ((WithCrypto & APPLICATION_SMIME)
&& (msg->security & APPLICATION_SMIME)
&& (msg->security & ENCRYPT)
&& SmimeCryptAlg)
&& (sctx->smime_crypt_alg ||
(!sctx->smime_crypt_alg_cleared && SmimeCryptAlg)))
{
SETCOLOR (MT_COLOR_COMPOSE_HEADER);
mutt_window_mvprintw (MuttIndexWindow, HDR_CRYPTINFO, 40, "%s", _("Encrypt with: "));
NORMAL_COLOR;
printw ("%s", NONULL(SmimeCryptAlg));
printw ("%s", sctx->smime_crypt_alg ? sctx->smime_crypt_alg : SmimeCryptAlg );
}
#ifdef USE_AUTOCRYPT
......@@ -638,7 +647,7 @@ static int delete_attachment (ATTACH_CONTEXT *actx, int x)
* leak because mutt_free_body() frees body->parts, not
* body->hdr->content.
*
* Other ci_send_message() message constructors are careful to free
* Other mutt_send_message() message constructors are careful to free
* any body->parts, removing depth:
* - mutt_prepare_template() used by postponed, resent, and draft files
* - mutt_copy_body() used by the recvattach menu and $forward_attachments.
......@@ -1009,12 +1018,11 @@ static void compose_menu_redraw (MUTTMENU *menu)
* 1 message should be postponed
* 0 normal exit
* -1 abort message
* 2 edit was backgrounded
*/
int mutt_compose_menu (HEADER *msg, /* structure for new message */
BUFFER *fcc, /* where to save a copy of the message */
HEADER *cur, /* current message */
int flags)
int mutt_compose_menu (SEND_CONTEXT *sctx)
{
HEADER *msg; /* structure for new message */
char helpstr[LONG_STRING];
char buf[LONG_STRING];
BUFFER *fname = NULL;
......@@ -1032,10 +1040,13 @@ int mutt_compose_menu (HEADER *msg, /* structure for new message */
struct stat st;
compose_redraw_data_t rd = {0};
msg = sctx->msg;
init_header_padding ();
rd.msg = msg;
rd.fcc = fcc;
rd.fcc = sctx->fcc;
rd.sctx = sctx;
menu = mutt_new_menu (MENU_COMPOSE);
menu->offset = HDR_ATTACH;
......@@ -1056,6 +1067,18 @@ int mutt_compose_menu (HEADER *msg, /* structure for new message */
fname = mutt_buffer_new ();
mutt_buffer_increase_size (fname, LONG_STRING);
/* Another alternative would be to create a resume op and:
* mutt_unget_event (0, OP_COMPOSE_EDIT_MESSAGE_RESUME);
*/
if (sctx->state)
{
if (sctx->state == SEND_STATE_COMPOSE_EDIT)
goto edit_message_resume;
if (sctx->state == SEND_STATE_COMPOSE_EDIT_HEADERS)
goto edit_headers_resume;
sctx->state = 0;
}
while (loop)
{
switch (op = mutt_menuLoop (menu))
......@@ -1101,13 +1124,13 @@ int mutt_compose_menu (HEADER *msg, /* structure for new message */
mutt_message_hook (NULL, msg, MUTT_SEND2HOOK);
break;
case OP_COMPOSE_EDIT_FCC:
mutt_buffer_strcpy (fname, mutt_b2s (fcc));
mutt_buffer_strcpy (fname, mutt_b2s (sctx->fcc));
if (mutt_buffer_get_field (_("Fcc: "), fname, MUTT_FILE | MUTT_CLEAR) == 0)
{
mutt_buffer_strcpy (fcc, mutt_b2s (fname));
mutt_buffer_pretty_mailbox (fcc);
mutt_buffer_strcpy (sctx->fcc, mutt_b2s (fname));
mutt_buffer_pretty_mailbox (sctx->fcc);
mutt_window_move (MuttIndexWindow, HDR_FCC, HDR_XOFFSET);
mutt_paddstr (W, mutt_b2s (fcc));
mutt_paddstr (W, mutt_b2s (sctx->fcc));
fccSet = 1;
}
mutt_message_hook (NULL, msg, MUTT_SEND2HOOK);
......@@ -1116,7 +1139,22 @@ int mutt_compose_menu (HEADER *msg, /* structure for new message */
if (Editor && (mutt_strcmp ("builtin", Editor) != 0) && !option (OPTEDITHDRS))
{
mutt_rfc3676_space_unstuff (msg);
mutt_edit_file (Editor, msg->content->filename);
if ((sctx->flags & SENDBACKGROUNDEDIT) && option (OPTBACKGROUNDEDIT))
{
if (mutt_background_edit_file (sctx, Editor,
msg->content->filename) == 0)
{
sctx->state = SEND_STATE_COMPOSE_EDIT;
loop = 0;
r = 2;
break;
}
}
else
mutt_edit_file (Editor, msg->content->filename);
edit_message_resume:
sctx->state = 0;
mutt_rfc3676_space_stuff (msg);
mutt_update_encoding (msg->content);
menu->redraw = REDRAW_FULL;
......@@ -1133,8 +1171,26 @@ int mutt_compose_menu (HEADER *msg, /* structure for new message */
{
char *tag = NULL, *err = NULL;
mutt_env_to_local (msg->env);
mutt_edit_headers (NONULL (Editor), msg->content->filename, msg,
fcc);
if ((sctx->flags & SENDBACKGROUNDEDIT) && option (OPTBACKGROUNDEDIT))
{
if (mutt_edit_headers (Editor, sctx, MUTT_EDIT_HEADERS_BACKGROUND) == 2)
{
sctx->state = SEND_STATE_COMPOSE_EDIT_HEADERS;
loop = 0;
r = 2;
break;
}
}
else
mutt_edit_headers (NONULL (Editor), sctx, 0);
edit_headers_resume:
if (sctx->state == SEND_STATE_COMPOSE_EDIT_HEADERS)
{
mutt_edit_headers (Editor, sctx, MUTT_EDIT_HEADERS_RESUME);
sctx->state = 0;
}
if (mutt_env_to_intl (msg->env, &tag, &err))
{
mutt_error (_("Bad IDN in \"%s\": '%s'"), tag, err);
......@@ -1148,7 +1204,7 @@ int mutt_compose_menu (HEADER *msg, /* structure for new message */
attachment list could change if the user invokes ~v to edit
the message with headers, in which we need to execute the
code below to regenerate the index array */
mutt_builtin_editor (msg->content->filename, msg, cur);
mutt_builtin_editor (sctx);
}
mutt_rfc3676_space_stuff (msg);
......@@ -1466,13 +1522,13 @@ int mutt_compose_menu (HEADER *msg, /* structure for new message */
break;
#endif
if (!fccSet && mutt_buffer_len (fcc))
if (!fccSet && mutt_buffer_len (sctx->fcc))
{
if ((i = query_quadoption (OPT_COPY,
_("Save a copy of this message?"))) == -1)
break;
else if (i == MUTT_NO)
mutt_buffer_clear (fcc);
mutt_buffer_clear (sctx->fcc);
}
loop = 0;
......@@ -1709,7 +1765,7 @@ int mutt_compose_menu (HEADER *msg, /* structure for new message */
if (actx->idx[i]->unowned)
actx->idx[i]->content->unlink = 0;
if (!(flags & MUTT_COMPOSE_NOFREEHEADER))
if (!(sctx->flags & SENDNOFREEHEADER))
{
for (i = 0; i < actx->idxlen; i++)
{
......@@ -1774,7 +1830,7 @@ int mutt_compose_menu (HEADER *msg, /* structure for new message */
if (msg->content->next)
msg->content = mutt_make_multipart_mixed (msg->content);
if (mutt_write_fcc (mutt_b2s (fname), msg, NULL, 0, NULL) == 0)
if (mutt_write_fcc (mutt_b2s (fname), sctx, NULL, 0, NULL) == 0)
mutt_message _("Message written.");
msg->content = mutt_remove_multipart_mixed (msg->content);
......@@ -1808,7 +1864,7 @@ int mutt_compose_menu (HEADER *msg, /* structure for new message */
msg->security |= APPLICATION_PGP;
update_crypt_info (&rd);
}
msg->security = crypt_pgp_send_menu (msg);
crypt_pgp_send_menu (sctx);
update_crypt_info (&rd);
mutt_message_hook (NULL, msg, MUTT_SEND2HOOK);
break;
......@@ -1845,7 +1901,7 @@ int mutt_compose_menu (HEADER *msg, /* structure for new message */
msg->security |= APPLICATION_SMIME;
update_crypt_info (&rd);
}
msg->security = crypt_smime_send_menu(msg);
crypt_smime_send_menu (sctx);
update_crypt_info (&rd);
mutt_message_hook (NULL, msg, MUTT_SEND2HOOK);
break;
......
......@@ -5271,13 +5271,16 @@ void smime_gpgme_init (void)
init_smime ();
}
static int gpgme_send_menu (HEADER *msg, int is_smime)
static void gpgme_send_menu (SEND_CONTEXT *sctx, int is_smime)
{
HEADER *msg;
crypt_key_t *p;
char input_signas[SHORT_STRING];
char *prompt, *letters, *choices;
int choice;
msg = sctx->msg;
if (is_smime)
msg->security |= APPLICATION_SMIME;
else
......@@ -5371,7 +5374,8 @@ static int gpgme_send_menu (HEADER *msg, int is_smime)
{
snprintf (input_signas, sizeof (input_signas), "0x%s",
crypt_fpr_or_lkeyid (p));
mutt_str_replace (is_smime? &SmimeSignAs : &PgpSignAs, input_signas);
mutt_str_replace (is_smime? &sctx->smime_sign_as : &sctx->pgp_sign_as,
input_signas);
crypt_free_key (&p);
msg->security |= SIGN;
......@@ -5418,18 +5422,16 @@ static int gpgme_send_menu (HEADER *msg, int is_smime)
break;
}
}
return (msg->security);
}
int pgp_gpgme_send_menu (HEADER *msg)
void pgp_gpgme_send_menu (SEND_CONTEXT *sctx)
{
return gpgme_send_menu (msg, 0);
gpgme_send_menu (sctx, 0);
}
int smime_gpgme_send_menu (HEADER *msg)
void smime_gpgme_send_menu (SEND_CONTEXT *sctx)
{
return gpgme_send_menu (msg, 1);
gpgme_send_menu (sctx, 1);
}
static int verify_sender (HEADER *h, gpgme_protocol_t protocol)
......
......@@ -48,8 +48,8 @@ BODY *smime_gpgme_sign_message (BODY *a);
int pgp_gpgme_verify_one (BODY *sigbdy, STATE *s, const char *tempfile);
int smime_gpgme_verify_one (BODY *sigbdy, STATE *s, const char *tempfile);
int pgp_gpgme_send_menu (HEADER *msg);
int smime_gpgme_send_menu (HEADER *msg);
void pgp_gpgme_send_menu (SEND_CONTEXT *sctx);
void smime_gpgme_send_menu (SEND_CONTEXT *sctx);
int smime_gpgme_verify_sender (HEADER *h);
......
......@@ -61,9 +61,9 @@ static int crypt_mod_pgp_verify_one (BODY *sigbdy, STATE *s, const char *tempf)
return pgp_verify_one (sigbdy, s, tempf);
}
static int crypt_mod_pgp_send_menu (HEADER *msg)
static void crypt_mod_pgp_send_menu (SEND_CONTEXT *sctx)
{
return pgp_send_menu (msg);
pgp_send_menu (sctx);
}
static BODY *crypt_mod_pgp_encrypt_message (BODY *a, char *keylist, int sign)
......
......@@ -85,9 +85,9 @@ static int crypt_mod_pgp_verify_one (BODY *sigbdy, STATE *s, const char *tempf)
return pgp_gpgme_verify_one (sigbdy, s, tempf);
}
static int crypt_mod_pgp_send_menu (HEADER *msg)
static void crypt_mod_pgp_send_menu (SEND_CONTEXT *sctx)
{
return pgp_gpgme_send_menu (msg);
pgp_gpgme_send_menu (sctx);
}
static BODY *crypt_mod_pgp_encrypt_message (BODY *a, char *keylist, int sign)
......
......@@ -61,9 +61,9 @@ static int crypt_mod_smime_verify_one (BODY *sigbdy, STATE *s, const char *tempf
return smime_verify_one (sigbdy, s, tempf);
}
static int crypt_mod_smime_send_menu (HEADER *msg)
static void crypt_mod_smime_send_menu (SEND_CONTEXT *sctx)
{
return smime_send_menu (msg);
smime_send_menu (sctx);
}
static void crypt_mod_smime_getkeys (ENVELOPE *env)
......
......@@ -70,9 +70,9 @@ static int crypt_mod_smime_verify_one (BODY *sigbdy, STATE *s, const char *tempf
return smime_gpgme_verify_one (sigbdy, s, tempf);
}
static int crypt_mod_smime_send_menu (HEADER *msg)
static void crypt_mod_smime_send_menu (SEND_CONTEXT *sctx)
{
return smime_gpgme_send_menu (msg);
smime_gpgme_send_menu (sctx);
}
static BODY *crypt_mod_smime_build_smime_entity (BODY *a, char *certlist)
......
......@@ -53,7 +53,7 @@ typedef int (*crypt_func_verify_one_t) (BODY *sigbdy, STATE *s,
typedef void (*crypt_func_pgp_extract_keys_from_attachment_list_t)
(FILE *fp, int tag, BODY *top);
typedef int (*crypt_func_send_menu_t) (HEADER *msg);
typedef void (*crypt_func_send_menu_t) (SEND_CONTEXT *sctx);
/* (SMIME) */
typedef void (*crypt_func_smime_getkeys_t) (ENVELOPE *env);
......
......@@ -128,18 +128,24 @@ int crypt_valid_passphrase(int flags)
/* In postpone mode, signing is automatically disabled. */
int mutt_protect (HEADER *msg, char *keylist, int postpone)
int mutt_protect (SEND_CONTEXT *sctx, char *keylist, int postpone)
{
HEADER *msg;
BODY *pbody = NULL, *tmp_pbody = NULL;
BODY *tmp_smime_pbody = NULL;
BODY *tmp_pgp_pbody = NULL;
ENVELOPE *protected_headers = NULL;
int security, sign, has_retainable_sig = 0;
int i;
int i, rc = -1;
char *orig_pgp_sign_as = NULL,
*orig_smime_sign_as = NULL,
*orig_smime_crypt_alg = NULL;
if (!WithCrypto)
return -1;
msg = sctx->msg;
security = msg->security;
sign = security & (AUTOCRYPT | SIGN);
if (postpone)
......@@ -156,6 +162,26 @@ int mutt_protect (HEADER *msg, char *keylist, int postpone)
!crypt_valid_passphrase (security))
return (-1);
/* Override with sctx settings, if they are set.
* This can happen with the compose send_menus and when resuming a
* postponed message.
*/
if (sctx->pgp_sign_as)
{
orig_pgp_sign_as = safe_strdup (PgpSignAs);
mutt_str_replace (&PgpSignAs, sctx->pgp_sign_as);
}
if (sctx->smime_sign_as)
{
orig_smime_sign_as = safe_strdup (SmimeSignAs);
mutt_str_replace (&SmimeSignAs, sctx->smime_sign_as);
}
if (sctx->smime_crypt_alg || sctx->smime_crypt_alg_cleared)
{
orig_smime_crypt_alg = safe_strdup (SmimeCryptAlg);
mutt_str_replace (&SmimeCryptAlg, sctx->smime_crypt_alg);
}
if ((WithCrypto & APPLICATION_PGP) &&
!(security & AUTOCRYPT) &&
((security & PGPINLINE) == PGPINLINE))
......@@ -167,7 +193,7 @@ int mutt_protect (HEADER *msg, char *keylist, int postpone)
_("Inline PGP can't be used with attachments. Revert to PGP/MIME?"))) != MUTT_YES)
{
mutt_error _("Mail not sent: inline PGP can't be used with attachments.");
return -1;
goto cleanup;
}
}
else if (!mutt_strcasecmp ("flowed",
......@@ -177,7 +203,7 @@ int mutt_protect (HEADER *msg, char *keylist, int postpone)
_("Inline PGP can't be used with format=flowed. Revert to PGP/MIME?"))) != MUTT_YES)
{
mutt_error _("Mail not sent: inline PGP can't be used with format=flowed.");
return -1;
goto cleanup;
}
}
else
......@@ -188,14 +214,15 @@ int mutt_protect (HEADER *msg, char *keylist, int postpone)
if (pbody)
{
msg->content = pbody;
return 0;
rc = 0;
goto cleanup;
}
/* otherwise inline won't work...ask for revert */
if ((i = query_quadoption (OPT_PGPMIMEAUTO, _("Message can't be sent inline. Revert to using PGP/MIME?"))) != MUTT_YES)
{
mutt_error _("Mail not sent.");
return -1;
goto cleanup;
}
}
......@@ -263,7 +290,7 @@ int mutt_protect (HEADER *msg, char *keylist, int postpone)
&& (security & APPLICATION_SMIME))
{
if (!(tmp_pbody = crypt_smime_sign_message (msg->content)))
goto bail;
goto cleanup;
pbody = tmp_smime_pbody = tmp_pbody;
}
......@@ -272,7 +299,7 @@ int mutt_protect (HEADER *msg, char *keylist, int postpone)
&& (!(security & (ENCRYPT | AUTOCRYPT)) || option (OPTPGPRETAINABLESIG)))
{
if (!(tmp_pbody = crypt_pgp_sign_message (msg->content)))
goto bail;
goto cleanup;
has_retainable_sig = 1;
sign = 0;
......@@ -297,7 +324,7 @@ int mutt_protect (HEADER *msg, char *keylist, int postpone)
keylist)))
{
/* signed ? free it! */
goto bail;
goto cleanup;
}
/* free tmp_body if messages was signed AND encrypted ... */
if (tmp_smime_pbody != msg->content && tmp_smime_pbody != tmp_pbody)
......@@ -327,7 +354,7 @@ int mutt_protect (HEADER *msg, char *keylist, int postpone)
mutt_free_body (&tmp_pgp_pbody->next);
}
goto bail;
goto cleanup;
}
/* destroy temporary signature envelope when doing retainable
......@@ -345,12 +372,21 @@ int mutt_protect (HEADER *msg, char *keylist, int postpone)
if (pbody)
{
msg->content = pbody;
return 0;
rc = 0;
}
bail:
mutt_free_envelope (&msg->content->mime_headers);
return -1;
cleanup:
if (rc != 0)
mutt_free_envelope (&msg->content->mime_headers);
if (sctx->pgp_sign_as)
mutt_str_replace (&PgpSignAs, orig_pgp_sign_as);
if (sctx->smime_sign_as)
mutt_str_replace (&SmimeSignAs, orig_smime_sign_as);
if (sctx->smime_crypt_alg || sctx->smime_crypt_alg_cleared)
mutt_str_replace (&SmimeCryptAlg, orig_smime_crypt_alg);
return rc;
}
......
......@@ -315,12 +315,10 @@ int crypt_pgp_verify_one (BODY *sigbdy, STATE *s, const char *tempf)
}
int crypt_pgp_send_menu (HEADER *msg)
void crypt_pgp_send_menu (SEND_CONTEXT *sctx)
{
if (CRYPT_MOD_CALL_CHECK (PGP, send_menu))
return (CRYPT_MOD_CALL (PGP, send_menu)) (msg);
return 0;
(CRYPT_MOD_CALL (PGP, send_menu)) (sctx);
}
......@@ -449,12 +447,10 @@ int crypt_smime_verify_one (BODY *sigbdy, STATE *s, const char *tempf)
return -1;
}
int crypt_smime_send_menu (HEADER *msg)
void crypt_smime_send_menu (SEND_CONTEXT *sctx)
{
if (CRYPT_MOD_CALL_CHECK (SMIME, send_menu))
return (CRYPT_MOD_CALL (SMIME, send_menu)) (msg);
return 0;
(CRYPT_MOD_CALL (SMIME, send_menu)) (sctx);
}
void crypt_smime_set_sender (const char *sender)
......
......@@ -28,6 +28,8 @@
#include "sort.h"
#include "buffy.h"
#include "mx.h"
#include "send.h"
#include "background.h"
#ifdef USE_SIDEBAR
#include "sidebar.h"
......@@ -2085,7 +2087,7 @@ int mutt_index_menu (void)
CHECK_ATTACH;
CHECK_MSGCOUNT;
CHECK_VISIBLE;
ci_send_message (SENDTOSENDER, NULL, NULL, Context, tag ? NULL : CURHDR);
mutt_send_message (SENDTOSENDER, NULL, NULL, Context, tag ? NULL : CURHDR);
menu->redraw = REDRAW_FULL;
break;
......@@ -2204,7 +2206,7 @@ int mutt_index_menu (void)
CHECK_ATTACH;
if (option (OPTPGPAUTODEC) && (tag || !(CURHDR->security & PGP_TRADITIONAL_CHECKED)))
mutt_check_traditional_pgp (tag ? NULL : CURHDR, &menu->redraw);
ci_send_message (SENDFORWARD, NULL, NULL, Context, tag ? NULL : CURHDR);
mutt_send_message (SENDFORWARD, NULL, NULL, Context, tag ? NULL : CURHDR);
menu->redraw = REDRAW_FULL;
break;
......@@ -2238,7 +2240,21 @@ int mutt_index_menu (void)
case OP_MAIL:
CHECK_ATTACH;
ci_send_message (0, NULL, NULL, Context, NULL);
if (BackgroundProcess)
{
SEND_CONTEXT *sctx = BackgroundProcess;
BackgroundProcess = NULL;
/* this is a quick hack for now */
waitpid (sctx->background_pid, NULL, 0);
if (mutt_send_message_resume (sctx) == 2)
mutt_message ("Editing backgrounded. Hit m to restart");
}
else
{
if (mutt_send_message (SENDBACKGROUNDEDIT, NULL, NULL,
Context, NULL) == 2)
mutt_message ("Editing backgrounded. Hit m to restart");
}
menu->redraw = REDRAW_FULL;
break;
......@@ -2246,7 +2262,7 @@ int mutt_index_menu (void)
if (!(WithCrypto & APPLICATION_PGP))
break;
CHECK_ATTACH;
ci_send_message (SENDKEY, NULL, NULL, NULL, NULL);
mutt_send_message (SENDKEY, NULL, NULL, NULL, NULL);
menu->redraw = REDRAW_FULL;
break;
......@@ -2382,7 +2398,7 @@ int mutt_index_menu (void)
case OP_RECALL_MESSAGE:
CHECK_ATTACH;
ci_send_message (SENDPOSTPONED, NULL, NULL, Context, NULL);
mutt_send_message (SENDPOSTPONED, NULL, NULL, Context, NULL);
menu->redraw = REDRAW_FULL;
break;
......@@ -2424,7 +2440,7 @@ int mutt_index_menu (void)
if (option (OPTPGPAUTODEC) && (tag || !(CURHDR->security & PGP_TRADITIONAL_CHECKED)))
mutt_check_traditional_pgp (tag ? NULL : CURHDR, &menu->redraw);
ci_send_message (replyflags, NULL, NULL, Context, tag ? NULL : CURHDR);
mutt_send_message (replyflags, NULL, NULL, Context, tag ? NULL : CURHDR);
menu->redraw = REDRAW_FULL;
break;
}
......
......@@ -316,8 +316,10 @@ static void be_edit_header (ENVELOPE *e, int force)
}
}
int mutt_builtin_editor (const char *path, HEADER *msg, HEADER *cur)
int mutt_builtin_editor (SEND_CONTEXT *sctx)
{
HEADER *msg, *cur;
const char *path;
char **buf = NULL;
int bufmax = 0, buflen = 0;
char tmp[LONG_STRING];
......@@ -326,6 +328,10 @@ int mutt_builtin_editor (const char *path, HEADER *msg, HEADER *cur)
int i;
char *p;
msg = sctx->msg;
cur = sctx->cur;
path = sctx->msg->content->filename;
scrollok (stdscr, TRUE);
be_edit_header (msg->env, 0);
......@@ -450,7 +456,7 @@ int mutt_builtin_editor (const char *path, HEADER *msg, HEADER *cur)
if (option (OPTEDITHDRS))
{
mutt_env_to_local (msg->env);
mutt_edit_headers (NONULL(Visual), path, msg, NULL);
mutt_edit_headers (NONULL(Visual), sctx, 0);
if (mutt_env_to_intl (msg->env, &tag, &err))
printw (_("Bad IDN in %s: '%s'\n"), tag, err);
}
......
......@@ -26,6 +26,7 @@
#include "mutt_regex.h"
#include "mbyte.h"
#include "charset.h"
#include "send.h"
#include <ctype.h>
#include <stdlib.h>
......
This diff is collapsed.
......@@ -1086,13 +1086,25 @@ int imap_exec_msgset (IMAP_DATA* idata, const char* pre, const char* post,
BUFFER* cmd;
int pos;
int rc;
int count = 0;
int count = 0, reopen_set = 0;
cmd = mutt_buffer_new ();
/* We make a copy of the headers just in case resorting doesn't give
exactly the original order (duplicate messages?), because other parts of
the ctx are tied to the header order. This may be overkill. */
/* Unlike imap_sync_mailbox(), this function can be called when
* IMAP_REOPEN_ALLOW is not set. In that case, the caller isn't
* prepared to handle context changes. Resorting may not always
* give the same order, so we must make a copy.
*
* See the comment in imap_sync_mailbox() for the dangers of running
* even queued execs while reopen is set. To prevent memory
* corruption and data loss we must disable reopen for the duration
* of the swapped hdrs.
*/
if (idata->reopen & IMAP_REOPEN_ALLOW)
{
idata->reopen &= ~IMAP_REOPEN_ALLOW;
reopen_set = 1;
}
oldsort = Sort;
if (Sort != SORT_ORDER)
{
......@@ -1129,12 +1141,14 @@ int imap_exec_msgset (IMAP_DATA* idata, const char* pre, const char* post,
out:
mutt_buffer_free (&cmd);
if (oldsort != Sort)
if ((oldsort != Sort) || hdrs)
{
Sort = oldsort;
FREE (&idata->ctx->hdrs);
idata->ctx->hdrs = hdrs;
}
if (reopen_set)
idata->reopen |= IMAP_REOPEN_ALLOW;
return rc;
}
......@@ -1278,7 +1292,7 @@ int imap_sync_mailbox (CONTEXT* ctx, int expunge, int* index_hint)
HEADER** hdrs = NULL;
int oldsort;
int n;
int rc;
int rc, quickdel_rc = 0;
idata = (IMAP_DATA*) ctx->data;
......@@ -1298,22 +1312,24 @@ int imap_sync_mailbox (CONTEXT* ctx, int expunge, int* index_hint)
/* if we are expunging anyway, we can do deleted messages very quickly... */
if (expunge && mutt_bit_isset (ctx->rights, MUTT_ACL_DELETE))
{
if ((rc = imap_exec_msgset (idata, "UID STORE", "+FLAGS.SILENT (\\Deleted)",
MUTT_DELETED, 1, 0)) < 0)
if ((quickdel_rc = imap_exec_msgset (idata,
"UID STORE", "+FLAGS.SILENT (\\Deleted)",
MUTT_DELETED, 1, 0)) < 0)
{
rc = quickdel_rc;
mutt_error (_("Expunge failed"));
mutt_sleep (1);
goto out;
}
if (rc > 0)
if (quickdel_rc > 0)
{
/* mark these messages as unchanged so second pass ignores them. Done
* here so BOGUS UW-IMAP 4.7 SILENT FLAGS updates are ignored. */
for (n = 0; n < ctx->msgcount; n++)
if (ctx->hdrs[n]->deleted && ctx->hdrs[n]->changed)
ctx->hdrs[n]->active = 0;
mutt_message (_("Marking %d messages deleted..."), rc);
mutt_message (_("Marking %d messages deleted..."), quickdel_rc);
}
}
......@@ -1391,7 +1407,25 @@ int imap_sync_mailbox (CONTEXT* ctx, int expunge, int* index_hint)
imap_hcache_close (idata);
#endif
/* presort here to avoid doing 10 resorts in imap_exec_msgset */
/* presort here to avoid doing 10 resorts in imap_exec_msgset.
*
* Note: sync_helper() may trigger an imap_exec() if the queue fills
* up. Because IMAP_REOPEN_ALLOW is set, this may result in new
* messages being downloaded or an expunge being processed. For new
* messages this would both result in memory corruption (since we're
* alloc'ing msgcount instead of hdrmax pointers) and data loss of
* the new messages. For an expunge, the restored hdrs would point
* to headers that have been freed.
*
* Since reopen is allowed, we could change this to call
* mutt_sort_headers() before and after instead, but the double sort
* is noticeably slower.
*
* So instead, just turn off reopen_allow for the duration of the
* swapped hdrs. The imap_exec() below flushes the queue out,
* giving the opportunity to process any reopen events.
*/
imap_disallow_reopen (ctx);
oldsort = Sort;
if (Sort != SORT_ORDER)
{
......@@ -1414,15 +1448,18 @@ int imap_sync_mailbox (CONTEXT* ctx, int expunge, int* index_hint)
if (rc >= 0)
rc |= sync_helper (idata, MUTT_ACL_WRITE, MUTT_REPLIED, "\\Answered");
if (oldsort != Sort)
if ((oldsort != Sort) || hdrs)
{
Sort = oldsort;
FREE (&ctx->hdrs);
ctx->hdrs = hdrs;
}
imap_allow_reopen (ctx);
/* Flush the queued flags if any were changed in sync_helper. */
if (rc > 0)
/* Flush the queued flags if any were changed in sync_helper.
* The real (non-flag) changes loop might have flushed quickdel_rc
* queued commands, so we double check the cmdbuf isn't empty. */
if (((rc > 0) || (quickdel_rc > 0)) && mutt_buffer_len (idata->cmdbuf))
if (imap_exec (idata, NULL, 0) != IMAP_CMD_OK)
rc = -1;
......
......@@ -374,6 +374,11 @@ struct option_t MuttVars[] = {
** .pp
** Also see $$fast_reply.
*/
{ "background_edit", DT_BOOL, R_NONE, {.l=OPTBACKGROUNDEDIT}, {.l=0} },
/*
** .pp
** ADD DOCUMENTATION.
*/
{ "beep", DT_BOOL, R_NONE, {.l=OPTBEEP}, {.l=1} },
/*
** .pp
......@@ -3888,7 +3893,7 @@ struct option_t MuttVars[] = {
** The file containing a client certificate and its associated private
** key.
*/
{ "ssl_force_tls", DT_BOOL, R_NONE, {.l=OPTSSLFORCETLS}, {.l=1} },
{ "ssl_force_tls", DT_BOOL, R_NONE, {.l=OPTSSLFORCETLS}, {.l=0} },
/*
** .pp
** If this variable is \fIset\fP, Mutt will require that all connections
......
......@@ -31,6 +31,9 @@
#include "url.h"
#include "mutt_crypt.h"
#include "mutt_idna.h"
#include "send.h"
#include "background.h"
#ifdef USE_SIDEBAR
#include "sidebar.h"
#endif
......@@ -957,7 +960,7 @@ int main (int argc, char **argv, char **environ)
{
if (!option (OPTNOCURSES))
mutt_flushinp ();
ci_send_message (SENDPOSTPONED, NULL, NULL, NULL, NULL);
mutt_send_message (SENDPOSTPONED, NULL, NULL, NULL, NULL);
}
else if (subject || msg || sendflags || draftFile || includeFile || attach ||
optind < argc)
......@@ -1100,7 +1103,7 @@ int main (int argc, char **argv, char **environ)
sendflags |= SENDNOFREEHEADER;
/* Parse the draftFile into the full HEADER/BODY structure.
* Set SENDDRAFTFILE so ci_send_message doesn't overwrite
* Set SENDDRAFTFILE so mutt_send_message doesn't overwrite
* our msg->content.
*/
if (draftFile)
......@@ -1202,7 +1205,7 @@ int main (int argc, char **argv, char **environ)
mutt_free_list (&attach);
}
rv = ci_send_message (sendflags, msg, bodyfile, NULL, NULL);
rv = mutt_send_message (sendflags, msg, bodyfile, NULL, NULL);
if (edit_infile)
{
......
......@@ -203,9 +203,8 @@ typedef enum
#define MUTT_THREAD_COLLAPSE (1<<0)
#define MUTT_THREAD_UNCOLLAPSE (1<<1)
#define MUTT_THREAD_GET_HIDDEN (1<<2)
#define MUTT_THREAD_UNREAD (1<<3)
#define MUTT_THREAD_NEXT_UNREAD (1<<4)
#define MUTT_THREAD_UNREAD (1<<2)
#define MUTT_THREAD_NEXT_UNREAD (1<<3)
enum
{
......@@ -343,7 +342,7 @@ enum
OPT_MAX
};
/* flags to ci_send_message() */
/* flags to mutt_send_message() */
#define SENDREPLY (1<<0)
#define SENDGROUPREPLY (1<<1)
#define SENDLISTREPLY (1<<2)
......@@ -358,9 +357,11 @@ enum
#define SENDDRAFTFILE (1<<11) /* Used by the -H flag */
#define SENDTOSENDER (1<<12)
#define SENDGROUPCHATREPLY (1<<13)
#define SENDBACKGROUNDEDIT (1<<14) /* Allow background editing */
/* flags for mutt_compose_menu() */
#define MUTT_COMPOSE_NOFREEHEADER (1<<0)
/* flags for mutt_edit_headers() */
#define MUTT_EDIT_HEADERS_BACKGROUND 1
#define MUTT_EDIT_HEADERS_RESUME 2
/* flags to _mutt_select_file() */
#define MUTT_SEL_BUFFY (1<<0)
......@@ -389,6 +390,7 @@ enum
OPTAUTOSUBSCRIBE,
OPTAUTOTAG,
OPTBEEP,
OPTBACKGROUNDEDIT,
OPTBEEPNEW,
OPTBOUNCEDELIVERED,
OPTCHANGEFOLDERNEXT,
......@@ -886,7 +888,9 @@ typedef struct header
/* the following are used to support collapsing threads */
unsigned int collapsed : 1; /* is this message part of a collapsed thread? */
unsigned int limited : 1; /* is this message in a limited view? */
size_t num_hidden; /* number of hidden messages in this view */
size_t num_hidden; /* number of hidden messages in this view.
* only valid for the root header, when
* collapsed is set. */
short recipient; /* user_is_recipient()'s return value, cached */
......@@ -1169,6 +1173,7 @@ typedef struct
#define MUTT_PARTS_TOPLEVEL (1<<0) /* is the top-level part */
#include "send.h"
#include "ascii.h"
#include "protos.h"
#include "lib.h"
......
......@@ -111,7 +111,7 @@ typedef struct pgp_keyinfo *pgp_key_t;
/* Some prototypes -- old crypt.h. */
int mutt_protect (HEADER *, char *, int);
int mutt_protect (SEND_CONTEXT *, char *, int);
int mutt_is_multipart_encrypted (BODY *);
......@@ -131,7 +131,7 @@ int mutt_protected_headers_handler (BODY *, STATE *);
int mutt_signed_handler (BODY *, STATE *);
int mutt_parse_crypt_hdr (const char *, int, int);
int mutt_parse_crypt_hdr (const char *, int, int, SEND_CONTEXT *);
void convert_to_7bit (BODY *);
......@@ -249,7 +249,7 @@ BODY *crypt_pgp_encrypt_message (HEADER *msg, BODY *a, char *keylist, int sign);
/* Invoke the PGP command to import a key. */
void crypt_pgp_invoke_import (const char *fname);
int crypt_pgp_send_menu (HEADER *msg);
void crypt_pgp_send_menu (SEND_CONTEXT *sctx);
/* fixme: needs documentation */
int crypt_pgp_verify_one (BODY *sigbdy, STATE *s, const char *tempf);
......@@ -299,7 +299,7 @@ BODY *crypt_smime_build_smime_entity (BODY *a, char *certlist);
/* Add a certificate and update index file (externally). */
void crypt_smime_invoke_import (const char *infile, const char *mailbox);
int crypt_smime_send_menu (HEADER *msg);
void crypt_smime_send_menu (SEND_CONTEXT *sctx);
void crypt_smime_set_sender (const char *sender);
......
......@@ -31,6 +31,8 @@
#include "mbyte.h"
#include "sort.h"
#include "buffy.h"
#include "send.h"
#ifdef USE_SIDEBAR
#include "sidebar.h"
#endif
......@@ -1286,7 +1288,7 @@ static int format_line (struct line_t **lineInfo, int n, unsigned char *buf,
break;
++col;
if (pa)
addch (replacement_char ());
mutt_addwch (replacement_char ());
}
}
*pspace = space;
......@@ -2506,7 +2508,7 @@ search_next:
mutt_attach_mail_sender (extra->fp, extra->hdr, extra->actx,
extra->bdy);
else
ci_send_message (SENDTOSENDER, NULL, NULL, extra->ctx, extra->hdr);
mutt_send_message (SENDTOSENDER, NULL, NULL, extra->ctx, extra->hdr);
pager_menu->redraw = REDRAW_FULL;
break;
......@@ -2651,7 +2653,7 @@ search_next:
case OP_MAIL:
CHECK_MODE(IsHeader (extra) && !IsAttach (extra));
CHECK_ATTACH;
ci_send_message (0, NULL, NULL, extra->ctx, NULL);
mutt_send_message (0, NULL, NULL, extra->ctx, NULL);
pager_menu->redraw = REDRAW_FULL;
break;
......@@ -2674,7 +2676,7 @@ search_next:
mutt_attach_reply (extra->fp, extra->hdr, extra->actx,
extra->bdy, replyflags);
else
ci_send_message (replyflags, NULL, NULL, extra->ctx, extra->hdr);
mutt_send_message (replyflags, NULL, NULL, extra->ctx, extra->hdr);
pager_menu->redraw = REDRAW_FULL;
break;
}
......@@ -2682,7 +2684,7 @@ search_next:
case OP_RECALL_MESSAGE:
CHECK_MODE(IsHeader (extra) && !IsAttach(extra));
CHECK_ATTACH;
ci_send_message (SENDPOSTPONED, NULL, NULL, extra->ctx, extra->hdr);
mutt_send_message (SENDPOSTPONED, NULL, NULL, extra->ctx, extra->hdr);
pager_menu->redraw = REDRAW_FULL;
break;
......@@ -2693,7 +2695,7 @@ search_next:
mutt_attach_forward (extra->fp, extra->hdr, extra->actx,
extra->bdy);
else
ci_send_message (SENDFORWARD, NULL, NULL, extra->ctx, extra->hdr);
mutt_send_message (SENDFORWARD, NULL, NULL, extra->ctx, extra->hdr);
pager_menu->redraw = REDRAW_FULL;
break;
......@@ -2869,7 +2871,7 @@ search_next:
}
CHECK_MODE(IsHeader(extra));
CHECK_ATTACH;
ci_send_message (SENDKEY, NULL, NULL, extra->ctx, extra->hdr);
mutt_send_message (SENDKEY, NULL, NULL, extra->ctx, extra->hdr);
pager_menu->redraw = REDRAW_FULL;
break;
......
......@@ -1797,16 +1797,19 @@ cleanup:
return b;
}
int pgp_send_menu (HEADER *msg)
void pgp_send_menu (SEND_CONTEXT *sctx)
{
HEADER *msg;
pgp_key_t p;
char input_signas[SHORT_STRING];
char *prompt, *letters, *choices;
char promptbuf[LONG_STRING];
int choice;
msg = sctx->msg;
if (!(WithCrypto & APPLICATION_PGP))
return msg->security;
return;
/* If autoinline and no crypto options set, then set inline. */
if (option (OPTPGPAUTOINLINE) &&
......@@ -1918,7 +1921,7 @@ int pgp_send_menu (HEADER *msg)
{
snprintf (input_signas, sizeof (input_signas), "0x%s",
pgp_fpr_or_lkeyid (p));
mutt_str_replace (&PgpSignAs, input_signas);
mutt_str_replace (&sctx->pgp_sign_as, input_signas);
pgp_free_key (&p);
msg->security |= SIGN;
......@@ -1955,8 +1958,6 @@ int pgp_send_menu (HEADER *msg)
break;
}
}
return (msg->security);
}
......
......@@ -104,6 +104,6 @@ BODY *pgp_traditional_encryptsign (BODY *, int, char *);
BODY *pgp_encrypt_message (BODY *, char *, int);
BODY *pgp_sign_message (BODY *);
int pgp_send_menu (HEADER *msg);
void pgp_send_menu (SEND_CONTEXT *sctx);
#endif /* CRYPT_BACKEND_CLASSIC_PGP */
......@@ -223,20 +223,15 @@ static HEADER *select_msg (void)
/* args:
* ctx Context info, used when recalling a message to which
* we reply.
* hdr envelope/attachment info for recalled message
* cur if message was a reply, `cur' is set to the message which
* `hdr' is in reply to
* fcc fcc for the recalled message
* sctx Send Context info.
*
* return vals:
* -1 error/no messages
* 0 normal exit
* SENDREPLY recalled message is a reply
*/
int mutt_get_postponed (CONTEXT *ctx, HEADER *hdr, HEADER **cur, BUFFER *fcc)
int mutt_get_postponed (CONTEXT *ctx, SEND_CONTEXT *sctx)
{
HEADER *h;
int code = SENDPOSTPONED;
LIST *tmp;
LIST *last = NULL;
LIST *next;
......@@ -293,7 +288,7 @@ int mutt_get_postponed (CONTEXT *ctx, HEADER *hdr, HEADER **cur, BUFFER *fcc)
return (-1);
}
if (mutt_prepare_template (NULL, PostContext, hdr, h, 0) < 0)
if (mutt_prepare_template (NULL, PostContext, sctx->msg, h, 0) < 0)
{
mx_fastclose_mailbox (PostContext);
FREE (&PostContext);
......@@ -319,7 +314,7 @@ int mutt_get_postponed (CONTEXT *ctx, HEADER *hdr, HEADER **cur, BUFFER *fcc)
FREE (&PostContext);
for (tmp = hdr->env->userhdrs; tmp; )
for (tmp = sctx->msg->env->userhdrs; tmp; )
{
if (ascii_strncasecmp ("X-Mutt-References:", tmp->data, 18) == 0)
{
......@@ -330,7 +325,7 @@ int mutt_get_postponed (CONTEXT *ctx, HEADER *hdr, HEADER **cur, BUFFER *fcc)
p = skip_email_wsp(tmp->data + 18);
if (!ctx->id_hash)
ctx->id_hash = mutt_make_id_hash (ctx);
*cur = hash_find (ctx->id_hash, p);
sctx->cur = hash_find (ctx->id_hash, p);
}
/* Remove the X-Mutt-References: header field. */
......@@ -338,25 +333,25 @@ int mutt_get_postponed (CONTEXT *ctx, HEADER *hdr, HEADER **cur, BUFFER *fcc)
if (last)
last->next = tmp->next;
else
hdr->env->userhdrs = tmp->next;
sctx->msg->env->userhdrs = tmp->next;
tmp->next = NULL;
mutt_free_list (&tmp);
tmp = next;
if (*cur)
code |= SENDREPLY;
if (sctx->cur)
sctx->flags |= SENDREPLY;
}
else if (ascii_strncasecmp ("X-Mutt-Fcc:", tmp->data, 11) == 0)
{
p = skip_email_wsp(tmp->data + 11);
mutt_buffer_strcpy (fcc, p);
mutt_buffer_pretty_mailbox (fcc);
mutt_buffer_strcpy (sctx->fcc, p);
mutt_buffer_pretty_mailbox (sctx->fcc);
/* remove the X-Mutt-Fcc: header field */
next = tmp->next;
if (last)
last->next = tmp->next;
else
hdr->env->userhdrs = tmp->next;
sctx->msg->env->userhdrs = tmp->next;
tmp->next = NULL;
mutt_free_list (&tmp);
tmp = next;
......@@ -365,7 +360,7 @@ int mutt_get_postponed (CONTEXT *ctx, HEADER *hdr, HEADER **cur, BUFFER *fcc)
* user to not make a copy if the header field is present, but empty.
* see http://dev.mutt.org/trac/ticket/3653
*/
code |= SENDPOSTPONEDFCC;
sctx->flags |= SENDPOSTPONEDFCC;
}
else if ((WithCrypto & APPLICATION_PGP)
&& (mutt_strncmp ("Pgp:", tmp->data, 4) == 0 /* this is generated
......@@ -373,16 +368,16 @@ int mutt_get_postponed (CONTEXT *ctx, HEADER *hdr, HEADER **cur, BUFFER *fcc)
*/
|| mutt_strncmp ("X-Mutt-PGP:", tmp->data, 11) == 0))
{
hdr->security = mutt_parse_crypt_hdr (strchr (tmp->data, ':') + 1, 1,
APPLICATION_PGP);
hdr->security |= APPLICATION_PGP;
sctx->msg->security = mutt_parse_crypt_hdr (strchr (tmp->data, ':') + 1, 1,
APPLICATION_PGP, sctx);
sctx->msg->security |= APPLICATION_PGP;
/* remove the pgp field */
next = tmp->next;
if (last)
last->next = tmp->next;
else
hdr->env->userhdrs = tmp->next;
sctx->msg->env->userhdrs = tmp->next;
tmp->next = NULL;
mutt_free_list (&tmp);
tmp = next;
......@@ -390,16 +385,16 @@ int mutt_get_postponed (CONTEXT *ctx, HEADER *hdr, HEADER **cur, BUFFER *fcc)
else if ((WithCrypto & APPLICATION_SMIME)
&& mutt_strncmp ("X-Mutt-SMIME:", tmp->data, 13) == 0)
{
hdr->security = mutt_parse_crypt_hdr (strchr (tmp->data, ':') + 1, 1,
APPLICATION_SMIME);
hdr->security |= APPLICATION_SMIME;
sctx->msg->security = mutt_parse_crypt_hdr (strchr (tmp->data, ':') + 1, 1,
APPLICATION_SMIME, sctx);
sctx->msg->security |= APPLICATION_SMIME;
/* remove the smime field */
next = tmp->next;
if (last)
last->next = tmp->next;
else
hdr->env->userhdrs = tmp->next;
sctx->msg->env->userhdrs = tmp->next;
tmp->next = NULL;
mutt_free_list (&tmp);
tmp = next;
......@@ -409,12 +404,12 @@ int mutt_get_postponed (CONTEXT *ctx, HEADER *hdr, HEADER **cur, BUFFER *fcc)
else if (mutt_strncmp ("X-Mutt-Mix:", tmp->data, 11) == 0)
{
char *t;
mutt_free_list (&hdr->chain);
mutt_free_list (&sctx->msg->chain);
t = strtok (tmp->data + 11, " \t\n");
while (t)
{
hdr->chain = mutt_add_list (hdr->chain, t);
sctx->msg->chain = mutt_add_list (sctx->msg->chain, t);
t = strtok (NULL, " \t\n");
}
......@@ -422,7 +417,7 @@ int mutt_get_postponed (CONTEXT *ctx, HEADER *hdr, HEADER **cur, BUFFER *fcc)
if (last)
last->next = tmp->next;
else
hdr->env->userhdrs = tmp->next;
sctx->msg->env->userhdrs = tmp->next;
tmp->next = NULL;
mutt_free_list (&tmp);
tmp = next;
......@@ -437,14 +432,15 @@ int mutt_get_postponed (CONTEXT *ctx, HEADER *hdr, HEADER **cur, BUFFER *fcc)
}
if (option (OPTCRYPTOPPORTUNISTICENCRYPT))
crypt_opportunistic_encrypt (hdr);
crypt_opportunistic_encrypt (sctx->msg);
return (code);
return (0);
}
int mutt_parse_crypt_hdr (const char *p, int set_empty_signas, int crypt_app)
int mutt_parse_crypt_hdr (const char *p, int set_empty_signas, int crypt_app,
SEND_CONTEXT *sctx)
{
char smime_cryptalg[LONG_STRING] = "\0";
char sign_as[LONG_STRING] = "\0", *q;
......@@ -560,19 +556,19 @@ int mutt_parse_crypt_hdr (const char *p, int set_empty_signas, int crypt_app)
/* the cryptalg field must not be empty */
if ((WithCrypto & APPLICATION_SMIME) && *smime_cryptalg)
mutt_str_replace (&SmimeCryptAlg, smime_cryptalg);
mutt_str_replace (&sctx->smime_crypt_alg, smime_cryptalg);