changeset: 7022:b8952095b583
user:      Kevin McCarthy <ke...@8t8.us>
date:      Thu Apr 27 21:22:08 2017 -0700
link:      http://dev.mutt.org/hg/mutt/rev/b8952095b583

Fix km_error_key() infinite loop and unget buffer pollution.

'bind pager \Ch help' produces an infinite loop when an unbound key is
pressed in the pager.  The reason is because km_error_key() tries to
verify that the key sequence is really bound to the OP_HELP operation.
It does this by using km_expand_key(), tokenize_unget_string() on the
resulting buffer, then checking if the next km_dokey() returns OP_HELP.

The problem is that km_expand_key() does not always produce a string
that is properly reparsed by tokenize_unget_string().  Control-h
sequences are expanded to ^H.  tokenize_unget_string() recognizes this
as two characters '^' and 'H'.  km_error_key() checks the OP returned,
which is OP_PAGER_TOP for the '^'.  This is not OP_HELP, so it prints
a generic error and returns.  This leaves the 'H' in the input buffer!
Since 'H' (by default) is unbound in the pager, it retriggers
km_error_key(), resulting in an infinite loop.

The same issues can occur without control sequences:
  bind generic ? noop
  bind generic dq help
In the index, hitting an unbound key will end up leaving 'q' in the unget
buffer, because 'd' is bound in the index menu and will be read by km_dokey().

A simple approach to fix this would be to just use the same code as in
mutt_make_help(), which has no double-check.  This would be no worse
than the help menu, but can generate an inaccurate error message (e.g
if '?' were bound to noop)

This patch instead uses OP_END_COND as a barrier in the unget buffer.
It directly inserts the keys in the OP_HELP keymap, instead of using
km_expand_key() + tokenize_unget_string().  After calling km_dokey()
it flushes the unget buffer to the OP_END_COND barrier.

Thanks to Walter Alejandro Iglesias for reporting the bug.

changeset: 7023:c65d0c23c142
user:      Kevin McCarthy <ke...@8t8.us>
date:      Thu Apr 27 21:23:25 2017 -0700
link:      http://dev.mutt.org/hg/mutt/rev/c65d0c23c142

merge stable

diffs (truncated from 4947 to 950 lines):

diff -r 9a0afe7815d1 -r c65d0c23c142 addrbook.c
--- a/addrbook.c        Wed Apr 26 15:40:34 2017 -0700
+++ b/addrbook.c        Thu Apr 27 21:23:25 2017 -0700
@@ -145,15 +145,13 @@
     mutt_error _("You have no aliases!");
     return;
   }
-  
-  /* tell whoever called me to redraw the screen when I return */
-  set_option (OPTNEEDREDRAW);
-  
+
   menu = mutt_new_menu (MENU_ALIAS);
   menu->make_entry = alias_entry;
   menu->tag = alias_tag;
   menu->title = _("Aliases");
   menu->help = mutt_compile_help (helpstr, sizeof (helpstr), MENU_ALIAS, 
AliasHelp);
+  mutt_push_current_menu (menu);
 
 new_aliases:
 
@@ -237,6 +235,7 @@
     rfc822_write_address (buf, buflen, AliasTable[t]->addr, 1);
   }
 
+  mutt_pop_current_menu (menu);
   mutt_menuDestroy (&menu);
   FREE (&AliasTable);
   
diff -r 9a0afe7815d1 -r c65d0c23c142 browser.c
--- a/browser.c Wed Apr 26 15:40:34 2017 -0700
+++ b/browser.c Thu Apr 27 21:23:25 2017 -0700
@@ -492,17 +492,20 @@
       tmp->msg_unread = Context->unread;
     }
 
+    strfcpy (buffer, NONULL (tmp->path), sizeof (buffer));
+    mutt_pretty_mailbox (buffer, sizeof (buffer));
+
 #ifdef USE_IMAP
     if (mx_is_imap (tmp->path))
     {
-      add_folder (menu, state, tmp->path, NULL, tmp);
+      add_folder (menu, state, buffer, NULL, tmp);
       continue;
     }
 #endif
 #ifdef USE_POP
     if (mx_is_pop (tmp->path))
     {
-      add_folder (menu, state, tmp->path, NULL, tmp);
+      add_folder (menu, state, buffer, NULL, tmp);
       continue;
     }
 #endif
@@ -528,9 +531,6 @@
        s.st_mtime = st2.st_mtime;
     }
 
-    strfcpy (buffer, NONULL(tmp->path), sizeof (buffer));
-    mutt_pretty_mailbox (buffer, sizeof (buffer));
-
     add_folder (menu, state, buffer, &s, tmp);
   }
   while ((tmp = tmp->next));
@@ -611,7 +611,7 @@
   char helpstr[LONG_STRING];
   char title[STRING];
   struct browser_state state;
-  MUTTMENU *menu;
+  MUTTMENU *menu = NULL;
   struct stat st;
   int i, killPrefix = 0;
   int multiple = (flags & MUTT_SEL_MULTI)  ? 1 : 0;
@@ -722,6 +722,7 @@
 
   menu->help = mutt_compile_help (helpstr, sizeof (helpstr), MENU_FOLDER,
     FolderHelp);
+  mutt_push_current_menu (menu);
 
   init_menu (&state, menu, title, sizeof (title), buffy);
 
@@ -908,7 +909,6 @@
        }
 
        destroy_state (&state);
-       mutt_menuDestroy (&menu);
        goto bail;
 
       case OP_BROWSER_TELL:
@@ -954,7 +954,6 @@
          menu->current = 0; 
          menu->top = 0; 
          init_menu (&state, menu, title, sizeof (title), buffy);
-         MAYBE_REDRAW (menu->redraw);
        }
        /* else leave error on screen */
        break;
@@ -977,7 +976,6 @@
            menu->current = 0;
            menu->top = 0;
            init_menu (&state, menu, title, sizeof (title), buffy);
-           MAYBE_REDRAW (menu->redraw);
          }
        }
        break;
@@ -1015,7 +1013,6 @@
              state.entrylen--;
              mutt_message _("Mailbox deleted.");
              init_menu (&state, menu, title, sizeof (title), buffy);
-             MAYBE_REDRAW (menu->redraw);
            }
          }
          else
@@ -1080,7 +1077,6 @@
                  mutt_error _("Error scanning directory.");
                  if (examine_directory (menu, &state, LastDir, prefix) == -1)
                  {
-                   mutt_menuDestroy (&menu);
                    goto bail;
                  }
                }
@@ -1095,7 +1091,6 @@
              mutt_perror (buf);
          }
        }
-       MAYBE_REDRAW (menu->redraw);
        break;
        
       case OP_ENTER_MASK:
@@ -1151,7 +1146,6 @@
            else
            {
              mutt_error _("Error scanning directory.");
-             mutt_menuDestroy (&menu);
              goto bail;
            }
            killPrefix = 0;
@@ -1162,7 +1156,6 @@
            }
          }
        }
-       MAYBE_REDRAW (menu->redraw);
        break;
 
       case OP_SORT:
@@ -1246,10 +1239,8 @@
        {
          strfcpy (f, buf, flen);
          destroy_state (&state);
-         mutt_menuDestroy (&menu);
          goto bail;
        }
-       MAYBE_REDRAW (menu->redraw);
        break;
 
       case OP_BROWSER_VIEW_FILE:
@@ -1264,7 +1255,6 @@
        {
          strfcpy (f, state.entry[menu->current].name, flen);
          destroy_state (&state);
-         mutt_menuDestroy (&menu);
          goto bail;
        }
        else
@@ -1296,7 +1286,13 @@
   }
   
   bail:
-  
+
+  if (menu)
+  {
+    mutt_pop_current_menu (menu);
+    mutt_menuDestroy (&menu);
+  }
+
   if (!folder)
     strfcpy (LastDir, LastDirBackup, sizeof (LastDir));
   
diff -r 9a0afe7815d1 -r c65d0c23c142 buffy.c
--- a/buffy.c   Wed Apr 26 15:40:34 2017 -0700
+++ b/buffy.c   Thu Apr 27 21:23:25 2017 -0700
@@ -27,6 +27,7 @@
 #include "mx.h"
 
 #include "mutt_curses.h"
+#include "mutt_menu.h"
 
 #ifdef USE_SIDEBAR
 #include "sidebar.h"
@@ -580,7 +581,7 @@
         (orig_count != tmp->msg_count) ||
         (orig_unread != tmp->msg_unread) ||
         (orig_flagged != tmp->msg_flagged))
-      SidebarNeedsRedraw = 1;
+      mutt_set_current_menu_redraw (REDRAW_SIDEBAR);
 #endif
 
     if (!tmp->new)
diff -r 9a0afe7815d1 -r c65d0c23c142 color.c
--- a/color.c   Wed Apr 26 15:40:34 2017 -0700
+++ b/color.c   Thu Apr 27 21:23:25 2017 -0700
@@ -22,6 +22,7 @@
 
 #include "mutt.h"
 #include "mutt_curses.h"
+#include "mutt_menu.h"
 #include "mapping.h"
 
 #include <string.h>
@@ -494,7 +495,7 @@
   if (do_cache && !option (OPTNOCURSES))
   {
     int i;
-    set_option (OPTFORCEREDRAWINDEX);
+    mutt_set_menu_redraw_full (MENU_MAIN);
     /* force re-caching of index colors */
     for (i = 0; Context && i < Context->msgcount; i++)
       Context->hdrs[i]->pair = 0;
@@ -771,7 +772,7 @@
   else if (object == MT_COLOR_INDEX)
   {
     r = add_pattern (&ColorIndexList, buf->data, 1, fg, bg, attr, err, 1);
-    set_option (OPTFORCEREDRAWINDEX);
+    mutt_set_menu_redraw_full (MENU_MAIN);
   }
   else if (object == MT_COLOR_QUOTED)
   {
diff -r 9a0afe7815d1 -r c65d0c23c142 commands.c
--- a/commands.c        Wed Apr 26 15:40:34 2017 -0700
+++ b/commands.c        Thu Apr 27 21:23:25 2017 -0700
@@ -238,7 +238,7 @@
   return rc;
 }
 
-void ci_bounce_message (HEADER *h, int *redraw)
+void ci_bounce_message (HEADER *h)
 {
   char prompt[SHORT_STRING];
   char scratch[SHORT_STRING];
@@ -276,13 +276,6 @@
     strfcpy(prompt, _("Bounce tagged messages to: "), sizeof(prompt));
   
   rc = mutt_get_field (prompt, buf, sizeof (buf), MUTT_ALIAS);
-
-  if (option (OPTNEEDREDRAW))
-  {
-    unset_option (OPTNEEDREDRAW);
-    *redraw = REDRAW_FULL;
-  }
-
   if (rc || !buf[0])
     return;
 
@@ -413,10 +406,12 @@
       mutt_perror _("Can't create filter process");
       return 1;
     }
-      
+
+    set_option (OPTKEEPQUIET);
     pipe_msg (h, fpout, decode, print);
     safe_fclose (&fpout);
     rc = mutt_wait_filter (thepid);
+    unset_option (OPTKEEPQUIET);
   }
   else
   { /* handle tagged messages */
@@ -447,12 +442,14 @@
            mutt_perror _("Can't create filter process");
            return 1;
          }
+          set_option (OPTKEEPQUIET);
           pipe_msg (Context->hdrs[Context->v2r[i]], fpout, decode, print);
           /* add the message separator */
           if (sep)  fputs (sep, fpout);
          safe_fclose (&fpout);
          if (mutt_wait_filter (thepid) != 0)
            rc = 1;
+          unset_option (OPTKEEPQUIET);
         }
       }
     }
@@ -464,6 +461,7 @@
        mutt_perror _("Can't create filter process");
        return 1;
       }
+      set_option (OPTKEEPQUIET);
       for (i = 0; i < Context->vcount; i++)
       {
         if (Context->hdrs[Context->v2r[i]]->tagged)
@@ -477,6 +475,7 @@
       safe_fclose (&fpout);
       if (mutt_wait_filter (thepid) != 0)
        rc = 1;
+      unset_option (OPTKEEPQUIET);
     }
   }
 
@@ -534,12 +533,13 @@
 
   switch (mutt_multi_choice (reverse ?
        /* L10N: The following three are the sort/reverse sort prompts.
-        * Capital letters must match the order of the characters in the third
-        * string.
+        * Letters must match the order of the characters in the third
+        * string.  Note that mutt now supports multiline prompts, so
+        * it's okay for the translation to take up to three lines.
         */
-                            _("Rev-Sort 
Date/Frm/Recv/Subj/tO/Thread/Unsort/siZe/sCore/sPam/Label?: ") :
-                            _("Sort 
Date/Frm/Recv/Subj/tO/Thread/Unsort/siZe/sCore/sPam/Label?: "),
-                            _("dfrsotuzcpl")))
+       _("Rev-Sort Date/Frm/Recv/Subj/tO/Thread/Unsort/siZe/sCore/sPam/Label?: 
") :
+       _("Sort Date/Frm/Recv/Subj/tO/Thread/Unsort/siZe/sCore/sPam/Label?: "),
+       _("dfrsotuzcpl")))
   {
   case -1: /* abort - don't resort */
     return -1;
@@ -734,8 +734,7 @@
 }
 
 /* returns 0 if the copy/save was successful, or -1 on error/abort */
-int mutt_save_message (HEADER *h, int delete, 
-                      int decode, int decrypt, int *redraw)
+int mutt_save_message (HEADER *h, int delete, int decode, int decrypt)
 {
   int i, need_buffy_cleanup;
   int need_passphrase = 0, app=0;
@@ -743,9 +742,6 @@
   CONTEXT ctx;
   struct stat st;
 
-  *redraw = 0;
-
-  
   snprintf (prompt, sizeof (prompt),
            decode  ? (delete ? _("Decode-save%s to mailbox") :
                       _("Decode-copy%s to mailbox")) :
@@ -793,17 +789,9 @@
   }
 
   mutt_pretty_mailbox (buf, sizeof (buf));
-  if (mutt_enter_fname (prompt, buf, sizeof (buf), redraw, 0) == -1)
+  if (mutt_enter_fname (prompt, buf, sizeof (buf), 0) == -1)
     return (-1);
 
-  if (*redraw != REDRAW_FULL)
-  {
-    if (!h)
-      *redraw = REDRAW_INDEX | REDRAW_STATUS;
-    else
-      *redraw = REDRAW_STATUS;
-  }
-
   if (!buf[0])
     return (-1);
  
diff -r 9a0afe7815d1 -r c65d0c23c142 compose.c
--- a/compose.c Wed Apr 26 15:40:34 2017 -0700
+++ b/compose.c Thu Apr 27 21:23:25 2017 -0700
@@ -273,7 +273,7 @@
   NORMAL_COLOR;
 }
 
-static int edit_address_list (int line, ADDRESS **addr)
+static void edit_address_list (int line, ADDRESS **addr)
 {
   char buf[HUGE_STRING] = ""; /* needs to be large for alias expansion */
   char *err = NULL;
@@ -287,12 +287,6 @@
     *addr = mutt_expand_aliases (*addr);
   }
 
-  if (option (OPTNEEDREDRAW))
-  {
-    unset_option (OPTNEEDREDRAW);
-    return (REDRAW_FULL);
-  }
-
   if (mutt_addrlist_to_intl (*addr, &err) != 0)
   {
     mutt_error (_("Warning: '%s' is a bad IDN."), err);
@@ -305,8 +299,6 @@
   rfc822_write_address (buf, sizeof (buf), *addr, 1);
   mutt_window_move (MuttIndexWindow, line, HDR_XOFFSET);
   mutt_paddstr (W, buf);
-  
-  return 0;
 }
 
 static int delete_attachment (MUTTMENU *menu, short *idxlen, int x)
@@ -476,6 +468,54 @@
         (unsigned long) menu, 0);
 }
 
+typedef struct
+{
+  HEADER *msg;
+  char *fcc;
+} compose_redraw_data_t;
+
+static void compose_menu_redraw (MUTTMENU *menu)
+{
+  char buf[LONG_STRING];
+  compose_redraw_data_t *rd = menu->redraw_data;
+
+  if (!rd)
+    return;
+
+  if (menu->redraw & REDRAW_FULL)
+  {
+    menu_redraw_full (menu);
+
+    draw_envelope (rd->msg, rd->fcc);
+    menu->offset = HDR_ATTACH;
+    menu->pagelen = MuttIndexWindow->rows - HDR_ATTACH;
+  }
+
+  menu_check_recenter (menu);
+
+  if (menu->redraw & REDRAW_STATUS)
+  {
+    compose_status_line (buf, sizeof (buf), 0, MuttStatusWindow->cols, menu, 
NONULL(ComposeFormat));
+    mutt_window_move (MuttStatusWindow, 0, 0);
+    SETCOLOR (MT_COLOR_STATUS);
+    mutt_paddstr (MuttStatusWindow->cols, buf);
+    NORMAL_COLOR;
+    menu->redraw &= ~REDRAW_STATUS;
+  }
+
+#ifdef USE_SIDEBAR
+  if (menu->redraw & REDRAW_SIDEBAR)
+    menu_redraw_sidebar (menu);
+#endif
+
+  if (menu->redraw & REDRAW_INDEX)
+    menu_redraw_index (menu);
+  else if (menu->redraw & (REDRAW_MOTION | REDRAW_MOTION_RESYNCH))
+    menu_redraw_motion (menu);
+  else if (menu->redraw == REDRAW_CURRENT)
+    menu_redraw_current (menu);
+}
+
 
 /* return values:
  *
@@ -505,6 +545,10 @@
   /* Sort, SortAux could be changed in mutt_index_menu() */
   int oldSort, oldSortAux;
   struct stat st;
+  compose_redraw_data_t rd;
+
+  rd.msg = msg;
+  rd.fcc = fcc;
 
   mutt_attach_init (msg->content);
   idx = mutt_gen_attach_list (msg->content, -1, idx, &idxlen, &idxmax, 0, 1);
@@ -516,22 +560,20 @@
   menu->tag = mutt_tag_attach;
   menu->data = idx;
   menu->help = mutt_compile_help (helpstr, sizeof (helpstr), MENU_COMPOSE, 
ComposeHelp);
+  menu->custom_menu_redraw = compose_menu_redraw;
+  menu->redraw_data = &rd;
+  mutt_push_current_menu (menu);
 
   while (loop)
   {
     switch (op = mutt_menuLoop (menu))
     {
-      case OP_REDRAW:
-       draw_envelope (msg, fcc);
-       menu->offset = HDR_ATTACH;
-       menu->pagelen = MuttIndexWindow->rows - HDR_ATTACH;
-       break;
       case OP_COMPOSE_EDIT_FROM:
-       menu->redraw = edit_address_list (HDR_FROM, &msg->env->from);
+       edit_address_list (HDR_FROM, &msg->env->from);
         mutt_message_hook (NULL, msg, MUTT_SEND2HOOK);
        break;
       case OP_COMPOSE_EDIT_TO:
-       menu->redraw = edit_address_list (HDR_TO, &msg->env->to);
+       edit_address_list (HDR_TO, &msg->env->to);
        if (option (OPTCRYPTOPPORTUNISTICENCRYPT))
        {
          crypt_opportunistic_encrypt (msg);
@@ -540,7 +582,7 @@
         mutt_message_hook (NULL, msg, MUTT_SEND2HOOK);
         break;
       case OP_COMPOSE_EDIT_BCC:
-       menu->redraw = edit_address_list (HDR_BCC, &msg->env->bcc);
+       edit_address_list (HDR_BCC, &msg->env->bcc);
        if (option (OPTCRYPTOPPORTUNISTICENCRYPT))
        {
          crypt_opportunistic_encrypt (msg);
@@ -549,7 +591,7 @@
         mutt_message_hook (NULL, msg, MUTT_SEND2HOOK);
        break;
       case OP_COMPOSE_EDIT_CC:
-       menu->redraw = edit_address_list (HDR_CC, &msg->env->cc);
+       edit_address_list (HDR_CC, &msg->env->cc);
        if (option (OPTCRYPTOPPORTUNISTICENCRYPT))
        {
          crypt_opportunistic_encrypt (msg);
@@ -574,7 +616,7 @@
         mutt_message_hook (NULL, msg, MUTT_SEND2HOOK);
         break;
       case OP_COMPOSE_EDIT_REPLY_TO:
-       menu->redraw = edit_address_list (HDR_REPLYTO, &msg->env->reply_to);
+       edit_address_list (HDR_REPLYTO, &msg->env->reply_to);
         mutt_message_hook (NULL, msg, MUTT_SEND2HOOK);
        break;
       case OP_COMPOSE_EDIT_FCC:
@@ -587,7 +629,6 @@
          mutt_paddstr (W, fcc);
          fccSet = 1;
        }
-       MAYBE_REDRAW (menu->redraw);
         mutt_message_hook (NULL, msg, MUTT_SEND2HOOK);
         break;
       case OP_COMPOSE_EDIT_MESSAGE:
@@ -666,12 +707,6 @@
          FREE (&idx[idxlen]);
 
        menu->redraw |= REDRAW_STATUS;
-
-       if (option(OPTNEEDREDRAW))
-       {
-         menu->redraw = REDRAW_FULL;
-         unset_option(OPTNEEDREDRAW);
-       }
        
         mutt_message_hook (NULL, msg, MUTT_SEND2HOOK);
         break;
@@ -687,7 +722,7 @@
          numfiles = 0;
          files = NULL;
 
-         if (_mutt_enter_fname (prompt, fname, sizeof (fname), &menu->redraw, 
0, 1, &files, &numfiles) == -1 ||
+         if (_mutt_enter_fname (prompt, fname, sizeof (fname), 0, 1, &files, 
&numfiles) == -1 ||
              *fname == '\0')
            break;
 
@@ -739,7 +774,7 @@
            mutt_pretty_mailbox (fname, sizeof (fname));
          }
 
-         if (mutt_enter_fname (prompt, fname, sizeof (fname), &menu->redraw, 
1) == -1 || !fname[0])
+         if (mutt_enter_fname (prompt, fname, sizeof (fname), 1) == -1 || 
!fname[0])
            break;
 
          mutt_expand_path (fname, sizeof (fname));
@@ -1164,7 +1199,6 @@
       case OP_SAVE:
        CHECK_COUNT;
        mutt_save_attachment_list (NULL, menu->tagprefix, menu->tagprefix ?  
msg->content : idx[menu->current]->content, NULL, menu);
-       MAYBE_REDRAW (menu->redraw);
         /* no send2hook, since this doesn't modify the message */
        break;
 
@@ -1250,7 +1284,7 @@
        if (idxlen)
          msg->content = idx[0]->content;
        if (mutt_enter_fname (_("Write message to mailbox"), fname, sizeof 
(fname),
-                             &menu->redraw, 1) != -1 && fname[0])
+                             1) != -1 && fname[0])
        {
          mutt_message (_("Writing message to %s ..."), fname);
          mutt_expand_path (fname, sizeof (fname));
@@ -1288,7 +1322,7 @@
           crypt_opportunistic_encrypt (msg);
           redraw_crypt_lines (msg);
        }
-       msg->security = crypt_pgp_send_menu (msg, &menu->redraw);
+       msg->security = crypt_pgp_send_menu (msg);
        redraw_crypt_lines (msg);
         mutt_message_hook (NULL, msg, MUTT_SEND2HOOK);
         break;
@@ -1321,7 +1355,7 @@
           crypt_opportunistic_encrypt (msg);
           redraw_crypt_lines (msg);
        }
-       msg->security = crypt_smime_send_menu(msg, &menu->redraw);
+       msg->security = crypt_smime_send_menu(msg);
        redraw_crypt_lines (msg);
         mutt_message_hook (NULL, msg, MUTT_SEND2HOOK);
         break;
@@ -1330,25 +1364,15 @@
 #ifdef MIXMASTER
       case OP_COMPOSE_MIX:
       
-       mix_make_chain (&msg->chain, &menu->redraw);
+       mix_make_chain (&msg->chain);
         mutt_message_hook (NULL, msg, MUTT_SEND2HOOK);
         break;
 #endif
 
     }
-
-    /* Draw formatted compose status line */
-    if (menu->redraw & REDRAW_STATUS) 
-    {
-        compose_status_line (buf, sizeof (buf), 0, MuttStatusWindow->cols, 
menu, NONULL(ComposeFormat));
-       mutt_window_move (MuttStatusWindow, 0, 0);
-       SETCOLOR (MT_COLOR_STATUS);
-       mutt_paddstr (MuttStatusWindow->cols, buf);
-       NORMAL_COLOR;
-       menu->redraw &= ~REDRAW_STATUS;
-    }
   }
 
+  mutt_pop_current_menu (menu);
   mutt_menuDestroy (&menu);
 
   if (idxlen)
diff -r 9a0afe7815d1 -r c65d0c23c142 configure.ac
--- a/configure.ac      Wed Apr 26 15:40:34 2017 -0700
+++ b/configure.ac      Thu Apr 27 21:23:25 2017 -0700
@@ -710,6 +710,11 @@
             AC_CHECK_DECLS([SSL_set_mode, SSL_MODE_AUTO_RETRY],,
               AC_MSG_ERROR([Unable to find decent SSL header]), [[#include 
<openssl/ssl.h>]])
 
+            AC_CHECK_DECL([X509_V_FLAG_PARTIAL_CHAIN],
+              AC_DEFINE(HAVE_SSL_PARTIAL_CHAIN,1,[ Define if OpenSSL supports 
partial chains. ]),
+              ,
+              [[#include <openssl/x509_vfy.h>]])
+
             AC_DEFINE(USE_SSL,1,[ Define if you want support for SSL. ])
             AC_DEFINE(USE_SSL_OPENSSL,1,[ Define if you want support for SSL 
via OpenSSL. ])
             LIBS="$saved_LIBS"
diff -r 9a0afe7815d1 -r c65d0c23c142 crypt-gpgme.c
--- a/crypt-gpgme.c     Wed Apr 26 15:40:34 2017 -0700
+++ b/crypt-gpgme.c     Thu Apr 27 21:23:25 2017 -0700
@@ -4031,6 +4031,7 @@
   menu->make_entry = crypt_entry;
   menu->help = helpstr;
   menu->data = key_table;
+  mutt_push_current_menu (menu);
 
   {
     const char *ts;
@@ -4139,10 +4140,9 @@
         }
     }
   
+  mutt_pop_current_menu (menu);
   mutt_menuDestroy (&menu);
   FREE (&key_table);
-
-  set_option (OPTNEEDREDRAW);
   
   return k;
 }
@@ -4701,7 +4701,7 @@
   init_smime ();
 }
 
-static int gpgme_send_menu (HEADER *msg, int *redraw, int is_smime)
+static int gpgme_send_menu (HEADER *msg, int is_smime)
 {
   crypt_key_t *p;
   char input_signas[SHORT_STRING];
@@ -4806,7 +4806,6 @@
 
         msg->security |= SIGN;
       }
-      *redraw = REDRAW_FULL;
       break;
 
     case 'b': /* (b)oth */
@@ -4853,14 +4852,14 @@
   return (msg->security);
 }
 
-int pgp_gpgme_send_menu (HEADER *msg, int *redraw)
+int pgp_gpgme_send_menu (HEADER *msg)
 {
-  return gpgme_send_menu (msg, redraw, 0);
+  return gpgme_send_menu (msg, 0);
 }
 
-int smime_gpgme_send_menu (HEADER *msg, int *redraw)
+int smime_gpgme_send_menu (HEADER *msg)
 {
-  return gpgme_send_menu (msg, redraw, 1);
+  return gpgme_send_menu (msg, 1);
 }
 
 static int verify_sender (HEADER *h, gpgme_protocol_t protocol)
diff -r 9a0afe7815d1 -r c65d0c23c142 crypt-gpgme.h
--- a/crypt-gpgme.h     Wed Apr 26 15:40:34 2017 -0700
+++ b/crypt-gpgme.h     Thu Apr 27 21:23:25 2017 -0700
@@ -48,8 +48,8 @@
 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 *redraw);
-int smime_gpgme_send_menu (HEADER *msg, int *redraw);
+int pgp_gpgme_send_menu (HEADER *msg);
+int smime_gpgme_send_menu (HEADER *msg);
 
 int smime_gpgme_verify_sender (HEADER *h);
 
diff -r 9a0afe7815d1 -r c65d0c23c142 crypt-mod-pgp-classic.c
--- a/crypt-mod-pgp-classic.c   Wed Apr 26 15:40:34 2017 -0700
+++ b/crypt-mod-pgp-classic.c   Thu Apr 27 21:23:25 2017 -0700
@@ -61,9 +61,9 @@
   return pgp_verify_one (sigbdy, s, tempf);
 }
 
-static int crypt_mod_pgp_send_menu (HEADER *msg, int *redraw)
+static int crypt_mod_pgp_send_menu (HEADER *msg)
 {
-  return pgp_send_menu (msg, redraw);
+  return pgp_send_menu (msg);
 }
 
 static BODY *crypt_mod_pgp_encrypt_message (BODY *a, char *keylist, int sign)
diff -r 9a0afe7815d1 -r c65d0c23c142 crypt-mod-pgp-gpgme.c
--- a/crypt-mod-pgp-gpgme.c     Wed Apr 26 15:40:34 2017 -0700
+++ b/crypt-mod-pgp-gpgme.c     Thu Apr 27 21:23:25 2017 -0700
@@ -85,9 +85,9 @@
   return pgp_gpgme_verify_one (sigbdy, s, tempf);
 }
 
-static int crypt_mod_pgp_send_menu (HEADER *msg, int *redraw)
+static int crypt_mod_pgp_send_menu (HEADER *msg)
 {
-  return pgp_gpgme_send_menu (msg, redraw);
+  return pgp_gpgme_send_menu (msg);
 }
 
 static BODY *crypt_mod_pgp_encrypt_message (BODY *a, char *keylist, int sign)
diff -r 9a0afe7815d1 -r c65d0c23c142 crypt-mod-smime-classic.c
--- a/crypt-mod-smime-classic.c Wed Apr 26 15:40:34 2017 -0700
+++ b/crypt-mod-smime-classic.c Thu Apr 27 21:23:25 2017 -0700
@@ -61,9 +61,9 @@
   return smime_verify_one (sigbdy, s, tempf);
 }
 
-static int crypt_mod_smime_send_menu (HEADER *msg, int *redraw)
+static int crypt_mod_smime_send_menu (HEADER *msg)
 {
-  return smime_send_menu (msg, redraw);
+  return smime_send_menu (msg);
 }
 
 static void crypt_mod_smime_getkeys (ENVELOPE *env)
diff -r 9a0afe7815d1 -r c65d0c23c142 crypt-mod-smime-gpgme.c
--- a/crypt-mod-smime-gpgme.c   Wed Apr 26 15:40:34 2017 -0700
+++ b/crypt-mod-smime-gpgme.c   Thu Apr 27 21:23:25 2017 -0700
@@ -70,9 +70,9 @@
   return smime_gpgme_verify_one (sigbdy, s, tempf);
 }
 
-static int crypt_mod_smime_send_menu (HEADER *msg, int *redraw)
+static int crypt_mod_smime_send_menu (HEADER *msg)
 {
-  return smime_gpgme_send_menu (msg, redraw);
+  return smime_gpgme_send_menu (msg);
 }
 
 static BODY *crypt_mod_smime_build_smime_entity (BODY *a, char *certlist)
diff -r 9a0afe7815d1 -r c65d0c23c142 crypt-mod.h
--- a/crypt-mod.h       Wed Apr 26 15:40:34 2017 -0700
+++ b/crypt-mod.h       Thu Apr 27 21:23:25 2017 -0700
@@ -53,7 +53,7 @@
 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, int *redraw);
+typedef int (*crypt_func_send_menu_t) (HEADER *msg);
 
  /* (SMIME) */
 typedef void (*crypt_func_smime_getkeys_t) (ENVELOPE *env);
diff -r 9a0afe7815d1 -r c65d0c23c142 cryptglue.c
--- a/cryptglue.c       Wed Apr 26 15:40:34 2017 -0700
+++ b/cryptglue.c       Thu Apr 27 21:23:25 2017 -0700
@@ -246,10 +246,10 @@
 }
 
 
-int crypt_pgp_send_menu (HEADER *msg, int *redraw)
+int crypt_pgp_send_menu (HEADER *msg)
 {
   if (CRYPT_MOD_CALL_CHECK (PGP, send_menu))
-    return (CRYPT_MOD_CALL (PGP, send_menu)) (msg, redraw);
+    return (CRYPT_MOD_CALL (PGP, send_menu)) (msg);
 
   return 0;
 }
@@ -380,10 +380,10 @@
   return -1;
 }
 
-int crypt_smime_send_menu (HEADER *msg, int *redraw)
+int crypt_smime_send_menu (HEADER *msg)
 {
   if (CRYPT_MOD_CALL_CHECK (SMIME, send_menu))
-    return (CRYPT_MOD_CALL (SMIME, send_menu)) (msg, redraw);
+    return (CRYPT_MOD_CALL (SMIME, send_menu)) (msg);
 
   return 0;
 }
diff -r 9a0afe7815d1 -r c65d0c23c142 curs_lib.c
--- a/curs_lib.c        Wed Apr 26 15:40:34 2017 -0700
+++ b/curs_lib.c        Thu Apr 27 21:23:25 2017 -0700
@@ -71,6 +71,9 @@
 mutt_window_t *MuttSidebarWindow = NULL;
 #endif
 
+static void reflow_message_window_rows (int mw_rows);
+
+
 void mutt_refresh (void)
 {
   /* don't refresh when we are waiting for a child. */
@@ -94,7 +97,7 @@
 {
   keypad (stdscr, TRUE);
   clearok (stdscr, TRUE);
-  set_option (OPTNEEDREDRAW);
+  mutt_set_current_menu_redraw_full ();
 }
 
 event_t mutt_getch (void)
@@ -162,6 +165,15 @@
   
   do
   {
+#if defined (USE_SLANG_CURSES) || defined (HAVE_RESIZETERM)
+    if (SigWinch)
+    {
+      SigWinch = 0;
+      mutt_resize_screen ();
+      clearok(stdscr, TRUE);
+      mutt_current_menu_redraw ();
+    }
+#endif
     mutt_window_clearline (MuttMessageWindow, 0);
     SETCOLOR (MT_COLOR_PROMPT);
     addstr ((char *)field); /* cast to get around bad prototypes */
@@ -173,7 +185,7 @@
   while (ret == 1);
   mutt_window_clearline (MuttMessageWindow, 0);
   mutt_free_enter_state (&es);
-  
+
   return (ret);
 }
 
@@ -220,8 +232,9 @@
   char *yes = _("yes");
   char *no = _("no");
   char *answer_string;
-  size_t answer_string_len;
-  size_t msglen;
+  int answer_string_wid, msg_wid;
+  size_t trunc_msg_len;
+  int redraw = 1, prompt_lines = 1;
 
 #ifdef HAVE_LANGINFO_YESEXPR
   char *expr;
@@ -239,8 +252,6 @@
             !REGCOMP (&reno, expr, REG_NOSUB);
 #endif
 
-  mutt_window_clearline (MuttMessageWindow, 0);
-
   /*
    * In order to prevent the default answer to the question to wrapped
    * around the screen in the even the question is wider than the screen,
@@ -248,19 +259,55 @@
    * to fit.
    */
   safe_asprintf (&answer_string, " ([%s]/%s): ", def == MUTT_YES ? yes : no, 
def == MUTT_YES ? no : yes);
-  answer_string_len = mutt_strwidth (answer_string);
-  /* maxlen here is sort of arbitrary, so pick a reasonable upper bound */
-  msglen = mutt_wstr_trunc (msg, 4*MuttMessageWindow->cols, 
MuttMessageWindow->cols - answer_string_len, NULL);
-  SETCOLOR (MT_COLOR_PROMPT);
-  addnstr (msg, msglen);
-  addstr (answer_string);
-  NORMAL_COLOR;
-  FREE (&answer_string);
+  answer_string_wid = mutt_strwidth (answer_string);
+  msg_wid = mutt_strwidth (msg);
 
   FOREVER
   {
+    if (redraw || SigWinch)
+    {
+      redraw = 0;
+#if defined (USE_SLANG_CURSES) || defined (HAVE_RESIZETERM)
+      if (SigWinch)
+      {
+        SigWinch = 0;
+        mutt_resize_screen ();
+        clearok (stdscr, TRUE);
+        mutt_current_menu_redraw ();
+      }
+#endif
+      if (MuttMessageWindow->cols)
+      {
+        prompt_lines = (msg_wid + answer_string_wid + MuttMessageWindow->cols 
- 1) /
+          MuttMessageWindow->cols;
+        prompt_lines = MAX (1, MIN (3, prompt_lines));
+      }
+      if (prompt_lines != MuttMessageWindow->rows)
+      {
+        reflow_message_window_rows (prompt_lines);
+        mutt_current_menu_redraw ();
+      }
+
+      /* maxlen here is sort of arbitrary, so pick a reasonable upper bound */
+      trunc_msg_len = mutt_wstr_trunc (msg, 4 * prompt_lines * 
MuttMessageWindow->cols,
+                                       prompt_lines * MuttMessageWindow->cols 
- answer_string_wid,
+                                       NULL);
+
+      mutt_window_move (MuttMessageWindow, 0, 0);
+      SETCOLOR (MT_COLOR_PROMPT);
+      addnstr (msg, trunc_msg_len);
+      addstr (answer_string);
+      NORMAL_COLOR;
+      mutt_window_clrtoeol (MuttMessageWindow);
+    }
+
     mutt_refresh ();
+    /* SigWinch is not processed unless timeout is set */
+    timeout (30 * 1000);
     ch = mutt_getch ();
+    timeout (-1);
+    if (ch.ch == -2)
+      continue;
     if (CI_is_return (ch.ch))
       break;
     if (ch.ch < 0)
@@ -297,6 +344,8 @@
     }
   }
 
+  FREE (&answer_string);
+
 #ifdef HAVE_LANGINFO_YESEXPR    
   if (reyes_ok)
     regfree (& reyes);
@@ -304,6 +353,14 @@
     regfree (& reno);
 #endif
 
+  if (MuttMessageWindow->rows != 1)

Reply via email to