Ticket #52297: mutt.2.patch

File mutt.2.patch, 96.6 KB (added by lbschenkel (Leonardo Brondani Schenkel), 4 years ago)
  • mail/mutt/Portfile

    diff --git a/mail/mutt/Portfile b/mail/mutt/Portfile
    a b  
    55
    66name                mutt
    77version             1.6.0
     8revision            1
    89categories          mail
    9 platforms           darwin
    10 license             GPL-2
    11 maintainers         nomaintainer
    12 
    13 description         The Mutt E-Mail Client
    14 long_description    Mutt is a small but very powerful text-based MIME \
    15                     mail client. Mutt is highly configurable, and is \
    16                     well suited to the mail power user with advanced \
    17                     features like key bindings, keyboard macros, mail \
    18                     threading, regular expression searches and \
    19                     a powerful pattern matching language for selecting \
    20                     groups of messages.
    21 homepage            http://www.mutt.org
    22 
    23 conflicts           neomutt
    24 depends_lib         port:gettext \
    25                     port:libiconv \
    26                     port:ncurses
    27 
    28 depends_run         path:share/curl/curl-ca-bundle.crt:curl-ca-bundle
    29 
    30 master_sites        https://bitbucket.org/mutt/mutt/downloads/
    31 checksums           ${distfiles} \
    32                     rmd160  1ea7153ef05413d0068b5478acad87927e5cecdb \
    33                     sha256  29afb6238ab7a540c0e3a78ce25c970f975ab6c0f0bc9f919993aab772136c19
    34 
    35 patch.pre_args      -p1
    36 # Fix for handling emails from bad clients w.r.t smime
    37 # See https://trac.macports.org/ticket/39362 and http://dev.mutt.org/trac/ticket/3285
    38 patchfiles-append   patch-thunderbird-fix.diff
    39 
    40 configure.args      --disable-warnings \
    41                     --mandir=${prefix}/share/man \
    42                     --with-docdir=${prefix}/share/doc/mutt \
    43                     --with-libiconv-prefix=${prefix} \
    44                     --with-curses=${prefix} \
    45                     --disable-silent-rules
    46 
    47 default_variants    +pop +imap +idn
    48 
    49 if {![variant_isset db4] && ![variant_isset qdbm] && ![variant_isset tokyocabinet]} {
    50     variant_set     gdbm
    51 }
    52 
    53 # These variants' patches modify Makefile.am
    54 if {[variant_isset compress] || [variant_isset sidebar]} {
    55     use_autoreconf  yes
    56 }
    57 
    58 post-destroot {
    59     # delete pgpring to avoid a conflict with signing-party
    60     delete ${destroot}${prefix}/bin/pgpring ${destroot}${prefix}/share/man/man1/pgpring.1
    61     # delete horribly outdated ca bundle, I hope people weren't using that!
    62     delete ${destroot}${prefix}/share/doc/mutt/samples/ca-bundle.crt
    63 }
    64 
    65 variant idn description {Internationalized Domain Name support} {
    66     configure.args-append   --with-idn=${prefix}
    67     depends_lib-append      port:libidn port:zlib
    68 }
    69 
    70 variant pop description {POP support} {
    71     configure.args-append   --enable-pop
    72 }
    73 variant imap description {IMAP support} {
    74     configure.args-append   --enable-imap
    75 }
    76 variant ssl description {Secure Sockets Layer support} {
    77     configure.args-append   --with-ssl=${prefix}
    78     depends_lib-append      path:lib/libssl.dylib:openssl
    79 }
    80 variant sasl description {Simple Authentication and Security Layer support} {
    81     configure.args-append   --with-sasl=${prefix}
    82     depends_lib-append      port:cyrus-sasl2
    83 }
    84 
    85 variant debug description {Debugging support} {
    86     configure.args-append   --enable-debug
    87 }
    88 
    89 variant gnuregex description {Use the GNU regular expression library} {
    90     configure.args-append   --with-regex
    91 }
    92 
    93 variant compress description {Compressed folders} {
    94     configure.args-append   --enable-compressed
    95     patch_sites-append      http://www.mutt.org.ua/download/mutt-1.5.24/
    96     patchfiles-append       patch-1.5.24.rr.compressed.gz
    97     checksums-append        patch-1.5.24.rr.compressed.gz \
    98                             rmd160  2bf71a26de195ce11ed4ffa25403363cab7c9b72 \
    99                             sha256  c5eb9b53f7bd3feaa5ee03722575f64e43512b756c099ffe20db6fe5c958e3dc
    100 }
    10110
    102 variant headercache conflicts db4 description {Enable header caching (requires gdbm, qdbm, or tokyocabinet)} {
    103     configure.args-append       --enable-hcache
    104     configure.ldflags-append    "-L/usr/lib"
    105 }
    106 
    107 variant qdbm conflicts db4 gdbm tokyocabinet description {Use QDBM database} {
    108     depends_lib-append      port:qdbm
    109     configure.args-append   --with-qdbm \
    110                             --without-bdb \
    111                             --without-gdbm \
    112                             --without-tokyocabinet
    113 }
    114 
    115 variant gdbm conflicts db4 qdbm tokyocabinet description {Use GNU dbm database} {
    116     depends_lib-append      port:gdbm
    117     configure.args-append   --with-gdbm \
    118                             --without-bdb \
    119                             --without-qdbm \
    120                             --without-tokyocabinet
    121 }
    122 
    123 variant db4 conflicts qdbm gdbm tokyocabinet description {Use Berkeley DB database} {
    124     depends_lib-append          port:db44
    125     configure.args-append       --with-bdb=${prefix} \
    126                                 --without-qdbm \
    127                                 --without-gdbm \
    128                                 --without-tokyocabinet
    129     configure.cppflags-append   "-I${prefix}/include/db44"
    130     configure.ldflags-append    "-L${prefix}/lib/db44"
    131 }
    132 
    133 variant tokyocabinet conflicts db4 gdbm qdbm description {Use Tokyo Cabinet database} {
    134     depends_lib-append      port:tokyocabinet
    135     configure.args-append   --with-tokyocabinet \
    136                             --without-bdb \
    137                             --without-gdbm \
    138                             --without-qdbm
    139 }
    140 
    141 # The patches for nntp and sidebar conflict, see ticket #15135
    142 variant nntp conflicts sidebar description {NNTP support} {
    143     configure.args-append   --enable-nntp
    144     patch_sites-append      http://www.mutt.org.ua/download/mutt-1.5.24/
    145     patchfiles-append       patch-1.5.24.vvv.nntp.gz
    146     checksums-append        patch-1.5.24.vvv.nntp.gz \
    147                             rmd160  028b86c3864ec2b8a485b998ce42d55fbb98e205 \
    148                             sha256  d34be4542d549aab6de9f7038c88b3eeefe826db643c92b27e1e65ab5f7d573e
    149 }
     11replaced_by         neomutt
     12PortGroup           obsolete 1.0
    15013
    151 variant deepif description {Allow nested if-else sequences in strings} {
    152     patch_sites-append      http://home.uchicago.edu/~dgc/sw/mutt/
    153     patchfiles-append       patch-1.5.8.dgc.deepif.1
    154     checksums-append        patch-1.5.8.dgc.deepif.1 \
    155                             rmd160  9372934147e8b832390c45833d0b8ce6c704dd24 \
    156                             sha256  570c343a440f5957e8e4639bda598c861cfaeae065a380a2c01ccb17d373ce6b
    157 }
    158 
    159 variant date_conditional requires deepif description \
    160     {Allow the format of dates in the index to vary based on how recent the message is} {
    161     # original, but now dgc hosts it with -p1
    162     #patch_sites-append http://www.schrab.com/aaron/mutt/
    163     patch_sites-append      http://home.uchicago.edu/~dgc/sw/mutt/
    164     patchfiles-append       patch-1.5.8.ats.date_conditional.1
    165     checksums-append        patch-1.5.8.ats.date_conditional.1 \
    166                             rmd160  fc3703edc66b5043227a7abcfed10a9c44873fd0 \
    167                             sha256  9e81f9f52577eb572e29651402ded3690e470d1628a890af9f3ad25b665d600f
    168 }
    169 
    170 variant xlabel description {Custom message-tagging - X-Label:} {
    171     patchfiles-append       patch-1.5.21.mp.xlabel_ext.9
    172 }
    173 
    174 variant smtp description {Include internal SMTP relay support} {
    175     configure.args-append   --enable-smtp
    176 }
    177 
    178 variant sidebar conflicts nntp trash description {Add a sidebar with a list of folders} {
    179     # http://www.lunar-linux.org/mutt-sidebar/
    180     #patch_sites-append      http://lunar-linux.org/~tchan/mutt:sidebar-patch
    181     patchfiles-append       patch-1.6.0.sidebar.20160408.macports.diff \
    182                             1-Make_hierarchy_separator_for_folder_indentation_configurable.patch \
    183                             2-Support_long_er__folder_names_in_sidebar.patch
    184     #checksums-append        patch-1.5.24.sidebar.20151111.txt \
    185     #                        rmd160  521938ab47440e93f73bc5ae358e867ab3d3212c \
    186     #                        sha256  66441edf056032119f854fc5ee86c73eece8b95dc998c0cfae5ed05b0b035070
    187 }
    188 
    189 # Trash patch from https://trac.macports.org/ticket/20412 conflicts with sidebar patch on global.h
    190 variant trash conflicts sidebar description {Add a Trash folder} {
    191     patchfiles-append       patch-1.5.24-trash_folder-purge_message.diff
    192 }
    193 
    194 variant gpgme description {Enable GPGME crypto support} {
    195     configure.args-append   --enable-gpgme \
    196                             --with-gpgme-prefix=${prefix}
    197     depends_lib-append      port:gpgme
    198 }
    199 
    200 notes "This port no longer installs the pgpring binary. Please install the signing-party port if you need it."
    201 
    202 livecheck.url       ${homepage}/download.html
    203 livecheck.type      regex
    204 livecheck.regex     {The current stable public release version is (\d+(?:\.\d+)*)}
  • deleted file mail/mutt/files/1-Make_hierarchy_separator_for_folder_indentation_configurable.patch

    diff --git a/mail/mutt/files/1-Make_hierarchy_separator_for_folder_indentation_configurable.patch b/mail/mutt/files/1-Make_hierarchy_separator_for_folder_indentation_configurable.patch
    deleted file mode 100644
    + -  
    1 # HG changeset patch
    2 # User Clemens Lang <cal@macports.org>
    3 # Date 1449516441 -3600
    4 #      Mon Dec 07 20:27:21 2015 +0100
    5 # Node ID 30679b45eeadb1ece557963cbd5915ab933fa747
    6 # Parent  7b9454058beba85a1878f6fd835fe1edf8b48279
    7 Make hierarchy separator for folder indentation configurable
    8 
    9 The sidebar-dotted patch from
    10   https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=523774
    11 supports folders from IMAP servers that use dots as hierarchy separator.
    12 However, in its implementation, it breaks the sidebar for users that use
    13 a slash as hierarchy separators and have dots in their folder names.
    14 
    15 Support both use cases by adding a new option sidebar_folder_delim_chars
    16 to configure the characters that separate hierarchies, similar to what
    17 imap_delim_chars does. Using imap_delim_chars directly is not a good
    18 idea because there might be users who do not use IMAP support in mutt.
    19 
    20 Signed-off-by: Clemens Lang <cal@macports.org>
    21 License: GPL-2.0+
    22 Upstream-Status: Submitted [private email 2015-12-07]
    23 
    24 diff --git a/globals.h b/globals.h
    25 --- a/globals.h
    26 +++ b/globals.h
    27 @@ -119,6 +119,7 @@
    28  WHERE char *Sendmail;
    29  WHERE char *Shell;
    30  WHERE char *SidebarDelim;
    31 +WHERE char *SidebarFolderDelimChars;
    32  WHERE char *SidebarFormat;
    33  WHERE char *SidebarIndentStr;
    34  WHERE char *Signature;
    35 diff --git a/init.h b/init.h
    36 --- a/init.h
    37 +++ b/init.h
    38 @@ -2066,6 +2066,12 @@
    39    ** .pp
    40    ** Should the sidebar shorten the path showed.
    41    */
    42 +  { "sidebar_folder_delim_chars", DT_STR, R_BOTH, UL &SidebarFolderDelimChars, UL "/." },
    43 +  /*
    44 +  ** .pp
    45 +  ** This contains the list of characters which you would like to treat
    46 +  ** as folder separators for displaying folders hierarchically in the sidebar.
    47 +  */
    48    {"sidebar_format", DT_STR, R_NONE, UL &SidebarFormat, UL "%B%?F? [%F]?%* %?N?%N/?%4S"},
    49    /*
    50    ** .pp
    51 diff --git a/sidebar.c b/sidebar.c
    52 --- a/sidebar.c
    53 +++ b/sidebar.c
    54 @@ -318,21 +318,20 @@
    55                 sidebar_folder_name = option(OPTSIDEBARSHORTPATH) ? mutt_basename(tmp->path) : tmp->path + maildir_is_prefix*(strlen(Maildir) + 1);
    56                 if ( maildir_is_prefix && option(OPTSIDEBARFOLDERINDENT) ) {
    57                         char *tmp_folder_name;
    58 +                       char *last_folder_name_part;
    59                         int i;
    60                         tmp_folder_name = tmp->path + strlen(Maildir) + 1;
    61 -                       for (i = 0; i < strlen(tmp->path) - strlen(Maildir); i++) {
    62 -                               if (tmp_folder_name[i] == '/'  || tmp_folder_name[i] == '.') sidebar_folder_depth++;
    63 -                       }   
    64 +                       last_folder_name_part = tmp_folder_name;
    65 +                       for (i = 0; i < strlen(tmp_folder_name); i++) {
    66 +                               if (strchr(NONULL(SidebarFolderDelimChars), tmp_folder_name[i])) {
    67 +                                       last_folder_name_part = tmp_folder_name + (i + 1);
    68 +                                       sidebar_folder_depth++;
    69 +                               }
    70 +                       }
    71                         if (sidebar_folder_depth > 0) {
    72                                 if (option(OPTSIDEBARSHORTPATH)) {
    73 -                                       tmp_folder_name = strrchr(tmp->path, '.');
    74 -                                       if (tmp_folder_name == NULL)
    75 -                                               tmp_folder_name = mutt_basename(tmp->path);
    76 -                                       else
    77 -                                               tmp_folder_name++;
    78 +                                       tmp_folder_name = last_folder_name_part;
    79                                 }
    80 -                               else
    81 -                                       tmp_folder_name = tmp->path + strlen(Maildir) + 1;
    82                                 sidebar_folder_name = malloc(strlen(tmp_folder_name) + sidebar_folder_depth*strlen(NONULL(SidebarIndentStr)) + 1);
    83                                 sidebar_folder_name[0]=0;
    84                                 for (i=0; i < sidebar_folder_depth; i++)
  • deleted file mail/mutt/files/2-Support_long_er__folder_names_in_sidebar.patch

    diff --git a/mail/mutt/files/2-Support_long_er__folder_names_in_sidebar.patch b/mail/mutt/files/2-Support_long_er__folder_names_in_sidebar.patch
    deleted file mode 100644
    + -  
    1 # HG changeset patch
    2 # User Clemens Lang <cal@macports.org>
    3 # Date 1449516538 -3600
    4 #      Mon Dec 07 20:28:58 2015 +0100
    5 # Node ID c5694b7d4b8f5acd857ad4681a29ca79c76d1e59
    6 # Parent  30679b45eeadb1ece557963cbd5915ab933fa747
    7 Support long(er) folder names in sidebar
    8 
    9 Folder names longer than 31 characters were previously cut off in the
    10 sidebar, even though the field provided space for 128 in the current
    11 implementation. Change to a generic sizeof() expression that will grow
    12 with the size of the declaration.
    13 
    14 Signed-off-by: Clemens Lang <cal@macports.org>
    15 License: GPL-2.0+
    16 Upstream-Status: Submitted [private email 2015-12-07]
    17 
    18 diff --git a/sidebar.c b/sidebar.c
    19 --- a/sidebar.c
    20 +++ b/sidebar.c
    21 @@ -157,7 +157,7 @@
    22      sbe.new = new;
    23      sbe.flagged = flagged;
    24      sbe.size = size;
    25 -    strncpy(sbe.box, box, 31);
    26 +    strncpy(sbe.box, box, sizeof(sbe.box) - 1);
    27  
    28      safe_realloc(&entry, SBvisual + 2);
    29      entry[SBvisual + 1] = '\0';
  • deleted file mail/mutt/files/patch-1.5.21.mp.xlabel_ext.9

    diff --git a/mail/mutt/files/patch-1.5.21.mp.xlabel_ext.9 b/mail/mutt/files/patch-1.5.21.mp.xlabel_ext.9
    deleted file mode 100644
    + -  
    1 --- a/copy.h.orig       2011-03-21 18:19:35.000000000 +0100
    2 +++ b/copy.h    2011-03-21 18:20:06.000000000 +0100
    3 @@ -53,6 +53,7 @@
    4  #define CH_UPDATE_IRT     (1<<16) /* update In-Reply-To: */
    5  #define CH_UPDATE_REFS    (1<<17) /* update References: */
    6  #define CH_DISPLAY        (1<<18) /* display result to user */
    7 +#define CH_UPDATE_LABEL   (1<<19) /*  update X-Label:  from hdr->env->x_label? */
    8  
    9  
    10  int mutt_copy_hdr (FILE *, FILE *, LOFF_T, LOFF_T, int, const char *);
    11 diff -r 25ea67e2a1f6 OPS
    12 --- a/OPS       Wed Apr 23 18:08:56 2008 -0500
    13 +++ b/OPS       Wed Apr 23 18:10:04 2008 -0500
    14 @@ -56,6 +56,7 @@
    15  OP_DISPLAY_ADDRESS "display full address of sender"
    16  OP_DISPLAY_HEADERS "display message and toggle header weeding"
    17  OP_DISPLAY_MESSAGE "display a message"
    18 +OP_EDIT_LABEL "add, change, or delete a message's label"
    19  OP_EDIT_MESSAGE "edit the raw message"
    20  OP_EDITOR_BACKSPACE "delete the char in front of the cursor"
    21  OP_EDITOR_BACKWARD_CHAR "move the cursor one character to the left"
    22 diff -r 25ea67e2a1f6 PATCHES
    23 --- a/PATCHES   Wed Apr 23 18:08:56 2008 -0500
    24 +++ b/PATCHES   Wed Apr 23 18:10:04 2008 -0500
    25 @@ -0,0 +1,1 @@
    26 +patch-1.5.16.dgc.xlabel_ext.9
    27 diff -r 25ea67e2a1f6 commands.c
    28 --- a/commands.c        Wed Apr 23 18:08:56 2008 -0500
    29 +++ b/commands.c        Wed Apr 23 18:10:04 2008 -0500
    30 @@ -509,9 +509,9 @@
    31    int method = Sort; /* save the current method in case of abort */
    32  
    33    switch (mutt_multi_choice (reverse ?
    34 -                            _("Rev-Sort (d)ate/(f)rm/(r)ecv/(s)ubj/t(o)/(t)hread/(u)nsort/si(z)e/s(c)ore/s(p)am?: ") :
    35 -                            _("Sort (d)ate/(f)rm/(r)ecv/(s)ubj/t(o)/(t)hread/(u)nsort/si(z)e/s(c)ore/s(p)am?: "),
    36 -                            _("dfrsotuzcp")))
    37 +                            _("Rev-Sort Date/Frm/Recv/Subj/tO/Thread/Unsort/siZe/sCore/sPam/Label?: ") :
    38 +                            _("Sort Date/Frm/Recv/Subj/tO/Thread/Unsort/siZe/sCore/sPam/Label?: "),
    39 +                            _("dfrsotuzcpl")))
    40    {
    41    case -1: /* abort - don't resort */
    42      return -1;
    43 @@ -554,6 +554,10 @@
    44  
    45    case 10: /* s(p)am */
    46      Sort = SORT_SPAM;
    47 +    break;
    48 +
    49 +  case 11: /* (l)abel */
    50 +    Sort = SORT_LABEL;
    51      break;
    52    }
    53    if (reverse)
    54 diff -r 25ea67e2a1f6 copy.c
    55 --- a/copy.c    Wed Apr 23 18:08:56 2008 -0500
    56 +++ b/copy.c    Wed Apr 23 18:10:04 2008 -0500
    57 @@ -110,6 +110,10 @@
    58           continue;
    59         ignore = 0;
    60        }
    61 +
    62 +      if (flags & CH_UPDATE_LABEL &&
    63 +         mutt_strncasecmp ("X-Label:", buf, 8) == 0)
    64 +       continue;
    65  
    66        if (!ignore && fputs (buf, out) == EOF)
    67         return (-1);
    68 @@ -464,6 +468,15 @@
    69        fprintf (out, "Lines: %d\n", h->lines);
    70    }
    71  
    72 +  if (flags & CH_UPDATE_LABEL && h->xlabel_changed)
    73 +  {
    74 +    h->xlabel_changed = 0;
    75 +    if (h->env->x_label != NULL)
    76 +      if (fprintf(out, "X-Label: %s\n", h->env->x_label) !=
    77 +                 10 + strlen(h->env->x_label))
    78 +        return -1;
    79 +  }
    80 +
    81    if ((flags & CH_NONEWLINE) == 0)
    82    {
    83      if (flags & CH_PREFIX)
    84 @@ -544,6 +557,9 @@
    85      else
    86        _mutt_make_string (prefix, sizeof (prefix), NONULL (Prefix), Context, hdr, 0);
    87    }
    88 +
    89 +  if (hdr->xlabel_changed)
    90 +    chflags |= CH_UPDATE_LABEL;
    91  
    92    if ((flags & M_CM_NOHEADER) == 0)
    93    {
    94 diff -r 25ea67e2a1f6 curs_main.c
    95 --- a/curs_main.c       Wed Apr 23 18:08:56 2008 -0500
    96 +++ b/curs_main.c       Wed Apr 23 18:10:04 2008 -0500
    97 @@ -1922,6 +1922,21 @@
    98         menu->redraw = REDRAW_FULL;
    99         break;
    100  
    101 +      case OP_EDIT_LABEL:
    102 +
    103 +       CHECK_MSGCOUNT;
    104 +       CHECK_READONLY;
    105 +       rc = mutt_label_message(tag ? NULL : CURHDR);
    106 +       if (rc > 0) {
    107 +         Context->changed = 1;
    108 +         menu->redraw = REDRAW_FULL;
    109 +         mutt_message ("%d label%s changed.", rc, rc == 1 ? "" : "s");
    110 +       }
    111 +       else {
    112 +         mutt_message _("No labels changed.");
    113 +       }
    114 +       break;
    115 +
    116        case OP_LIST_REPLY:
    117  
    118         CHECK_ATTACH;
    119 diff -r 25ea67e2a1f6 functions.h
    120 --- a/functions.h       Wed Apr 23 18:08:56 2008 -0500
    121 +++ b/functions.h       Wed Apr 23 18:10:04 2008 -0500
    122 @@ -99,6 +99,7 @@
    123    { "delete-thread",           OP_DELETE_THREAD,               "\004" },
    124    { "delete-subthread",                OP_DELETE_SUBTHREAD,            "\033d" },
    125    { "edit",                    OP_EDIT_MESSAGE,                "e" },
    126 +  { "edit-label",              OP_EDIT_LABEL,                  "y" },
    127    { "edit-type",               OP_EDIT_TYPE,                   "\005" },
    128    { "forward-message",         OP_FORWARD_MESSAGE,             "f" },
    129    { "flag-message",            OP_FLAG_MESSAGE,                "F" },
    130 @@ -184,6 +185,7 @@
    131    { "delete-thread",   OP_DELETE_THREAD,               "\004" },
    132    { "delete-subthread",        OP_DELETE_SUBTHREAD,            "\033d" },
    133    { "edit",            OP_EDIT_MESSAGE,                "e" },
    134 +  { "edit-label",      OP_EDIT_LABEL,                  "y" },
    135    { "edit-type",       OP_EDIT_TYPE,                   "\005" },
    136    { "forward-message", OP_FORWARD_MESSAGE,             "f" },
    137    { "flag-message",    OP_FLAG_MESSAGE,                "F" },
    138 diff -r 25ea67e2a1f6 headers.c
    139 --- a/headers.c Wed Apr 23 18:08:56 2008 -0500
    140 +++ b/headers.c Wed Apr 23 18:10:04 2008 -0500
    141 @@ -205,3 +205,59 @@
    142      }
    143    }
    144  }
    145 +
    146 +/*
    147 + * dgc: Add an X-Label: field.
    148 + */
    149 +static int label_message(HEADER *hdr, char *new)
    150 +{
    151 +       if (hdr == NULL)
    152 +               return 0;
    153 +       if (hdr->env->x_label == NULL && new == NULL)
    154 +               return 0;
    155 +       if (hdr->env->x_label != NULL && new != NULL &&
    156 +                       strcmp(hdr->env->x_label, new) == 0)
    157 +               return 0;
    158 +       if (hdr->env->x_label != NULL)
    159 +               FREE(&hdr->env->x_label);
    160 +       if (new == NULL)
    161 +               hdr->env->x_label = NULL;
    162 +       else
    163 +               hdr->env->x_label = safe_strdup(new);
    164 +       return hdr->changed = hdr->xlabel_changed = 1;
    165 +}
    166 +
    167 +int mutt_label_message(HEADER *hdr)
    168 +{
    169 +       char buf[LONG_STRING], *new;
    170 +       int i;
    171 +       int changed;
    172 +
    173 +       *buf = '\0';
    174 +       if (hdr != NULL && hdr->env->x_label != NULL) {
    175 +               strncpy(buf, hdr->env->x_label, LONG_STRING);
    176 +       }
    177 +
    178 +       mutt_get_field("Label: ", buf, sizeof(buf), 0 /* | M_CLEAR */);
    179 +       new = buf;
    180 +       SKIPWS(new);
    181 +       if (*new == '\0')
    182 +               new = NULL;
    183 +
    184 +       changed = 0;
    185 +       if (hdr != NULL) {
    186 +               changed += label_message(hdr, new);
    187 +       } else {
    188 +#define HDR_OF(index)  Context->hdrs[Context->v2r[(index)]]
    189 +               for (i = 0; i < Context->vcount; ++i) {
    190 +                       if (HDR_OF(i)->tagged)
    191 +                               if (label_message(HDR_OF(i), new)) {
    192 +                                       ++changed;
    193 +                                       mutt_set_flag(Context, HDR_OF(i),
    194 +                                               M_TAG, 0);
    195 +                               }
    196 +               }
    197 +       }
    198 +
    199 +       return changed;
    200 +}
    201 diff -r 25ea67e2a1f6 imap/imap.c
    202 --- a/imap/imap.c       Wed Apr 23 18:08:56 2008 -0500
    203 +++ b/imap/imap.c       Wed Apr 23 18:10:04 2008 -0500
    204 @@ -1169,7 +1169,7 @@
    205         * we delete the message and reupload it.
    206         * This works better if we're expunging, of course. */
    207        if ((h->env && (h->env->refs_changed || h->env->irt_changed)) ||
    208 -         h->attach_del)
    209 +         h->attach_del || h->xlabel_changed)
    210        {
    211          mutt_message (_("Saving changed messages... [%d/%d]"), n+1,
    212                        ctx->msgcount);
    213 @@ -1181,6 +1181,7 @@
    214         }
    215         else
    216           _mutt_save_message (h, appendctx, 1, 0, 0);
    217 +       h->xlabel_changed = 0;
    218        }
    219      }
    220    }
    221 diff -r 25ea67e2a1f6 imap/message.c
    222 --- a/imap/message.c    Wed Apr 23 18:08:56 2008 -0500
    223 +++ b/imap/message.c    Wed Apr 23 18:10:04 2008 -0500
    224 @@ -365,6 +365,7 @@
    225    IMAP_CACHE *cache;
    226    int read;
    227    int rc;
    228 +  char *x_label = NULL;
    229    /* Sam's weird courier server returns an OK response even when FETCH
    230     * fails. Thanks Sam. */
    231    short fetched = 0;
    232 diff -r 25ea67e2a1f6 mh.c
    233 --- a/mh.c      Wed Apr 23 18:08:56 2008 -0500
    234 +++ b/mh.c      Wed Apr 23 18:10:04 2008 -0500
    235 @@ -1537,7 +1537,7 @@
    236  {
    237    HEADER *h = ctx->hdrs[msgno];
    238  
    239 -  if (h->attach_del ||
    240 +  if (h->attach_del || h->xlabel_changed ||
    241        (h->env && (h->env->refs_changed || h->env->irt_changed)))
    242      if (mh_rewrite_message (ctx, msgno) != 0)
    243        return -1;
    244 @@ -1549,7 +1549,7 @@
    245  {
    246    HEADER *h = ctx->hdrs[msgno];
    247  
    248 -  if (h->attach_del ||
    249 +  if (h->attach_del || h->xlabel_changed ||
    250        (h->env && (h->env->refs_changed || h->env->irt_changed)))
    251    {
    252      /* when doing attachment deletion/rethreading, fall back to the MH case. */
    253 @@ -1671,6 +1671,7 @@
    254        }
    255      }
    256      else if (ctx->hdrs[i]->changed || ctx->hdrs[i]->attach_del ||
    257 +            ctx->hdrs[i]->xlabel_changed ||
    258              (ctx->magic == M_MAILDIR
    259               && (option (OPTMAILDIRTRASH) || ctx->hdrs[i]->trash)
    260               && (ctx->hdrs[i]->deleted != ctx->hdrs[i]->trash)))
    261 diff -r 25ea67e2a1f6 mutt.h
    262 --- a/mutt.h    Wed Apr 23 18:08:56 2008 -0500
    263 +++ b/mutt.h    Wed Apr 23 18:10:05 2008 -0500
    264 @@ -729,6 +730,7 @@
    265                                          * This flag is used by the maildir_trash
    266                                          * option.
    267                                          */
    268 +  unsigned int xlabel_changed : 1;     /* editable - used for syncing */
    269    
    270    /* timezone of the sender of this message */
    271    unsigned int zhours : 5;
    272 diff -r 25ea67e2a1f6 pager.c
    273 --- a/pager.c   Wed Apr 23 18:08:56 2008 -0500
    274 +++ b/pager.c   Wed Apr 23 18:10:05 2008 -0500
    275 @@ -2629,6 +2629,18 @@
    276         redraw = REDRAW_FULL;
    277         break;
    278  
    279 +     case OP_EDIT_LABEL:
    280 +        CHECK_MODE(IsHeader (extra));
    281 +        rc = mutt_label_message(extra->hdr);
    282 +        if (rc > 0) {
    283 +          Context->changed = 1;
    284 +          redraw = REDRAW_FULL;
    285 +          mutt_message ("%d label%s changed.", rc, rc == 1 ? "" : "s");
    286 +        }
    287 +        else {
    288 +          mutt_message _("No labels changed.");
    289 +        }
    290 +        break;
    291  
    292        case OP_MAIL_KEY:
    293          if (!(WithCrypto & APPLICATION_PGP))
    294 diff -r 25ea67e2a1f6 protos.h
    295 --- a/protos.h  Wed Apr 23 18:08:56 2008 -0500
    296 +++ b/protos.h  Wed Apr 23 18:10:05 2008 -0500
    297 @@ -188,6 +188,7 @@
    298  void mutt_edit_file (const char *, const char *);
    299  void mutt_edit_headers (const char *, const char *, HEADER *, char *, size_t);
    300  int mutt_filter_unprintable (char **);
    301 +int mutt_label_message (HEADER *);
    302  void mutt_curses_error (const char *, ...);
    303  void mutt_curses_message (const char *, ...);
    304  void mutt_enter_command (void);
    305 diff -r 25ea67e2a1f6 sort.c
    306 --- a/sort.c    Wed Apr 23 18:08:56 2008 -0500
    307 +++ b/sort.c    Wed Apr 23 18:10:05 2008 -0500
    308 @@ -210,6 +210,36 @@
    309    return (SORTCODE(result));
    310  }
    311  
    312 +int compare_label (const void *a, const void *b)
    313 +{
    314 +  HEADER **ppa = (HEADER **) a;
    315 +  HEADER **ppb = (HEADER **) b;
    316 +  int     ahas, bhas, result;
    317 +
    318 +  /* As with compare_spam, not all messages will have the x-label
    319 +   * property.  Blank X-Labels are treated as null in the index
    320 +   * display, so we'll consider them as null for sort, too.       */
    321 +  ahas = (*ppa)->env && (*ppa)->env->x_label && *((*ppa)->env->x_label);
    322 +  bhas = (*ppb)->env && (*ppb)->env->x_label && *((*ppb)->env->x_label);
    323 +
    324 +  /* First we bias toward a message with a label, if the other does not. */
    325 +  if (ahas && !bhas)
    326 +    return (SORTCODE(-1));
    327 +  if (!ahas && bhas)
    328 +    return (SORTCODE(1));
    329 +
    330 +  /* If neither has a label, use aux sort. */
    331 +  if (!ahas && !bhas)
    332 +  {
    333 +    AUXSORT(result, a, b);
    334 +    return (SORTCODE(result));
    335 +  }
    336 +
    337 +  /* If both have a label, we just do a lexical compare. */
    338 +  result = mutt_strcasecmp((*ppa)->env->x_label, (*ppb)->env->x_label);
    339 +  return (SORTCODE(result));
    340 +}
    341 +
    342  sort_t *mutt_get_sort_func (int method)
    343  {
    344    switch (method & SORT_MASK)
    345 @@ -232,6 +262,8 @@
    346        return (compare_score);
    347      case SORT_SPAM:
    348        return (compare_spam);
    349 +    case SORT_LABEL:
    350 +      return (compare_label);
    351      default:
    352        return (NULL);
    353    }
    354 diff -r 25ea67e2a1f6 sort.h
    355 --- a/sort.h    Wed Apr 23 18:08:56 2008 -0500
    356 +++ b/sort.h    Wed Apr 23 18:10:05 2008 -0500
    357 @@ -31,6 +31,7 @@
    358  #define SORT_KEYID     12
    359  #define SORT_TRUST     13
    360  #define SORT_SPAM      14
    361 +#define SORT_LABEL     15
    362  /* dgc: Sort & SortAux are shorts, so I'm bumping these bitflags up from
    363   * bits 4 & 5 to bits 8 & 9 to make room for more sort keys in the future. */
    364  #define SORT_MASK      0xff
    365 --- a/init.h.orig       2010-09-15 17:39:31.000000000 +0200
    366 +++ b/init.h    2011-03-21 18:23:20.000000000 +0100
    367 @@ -3380,6 +3380,7 @@
    368    { "to",              SORT_TO },
    369    { "score",           SORT_SCORE },
    370    { "spam",            SORT_SPAM },
    371 +  { "label",       SORT_LABEL },
    372    { NULL,               0 }
    373  };
    374  
    375 @@ -3399,6 +3400,7 @@
    376    { "to",              SORT_TO },
    377    { "score",           SORT_SCORE },
    378    { "spam",            SORT_SPAM },
    379 +  { "label",       SORT_LABEL },
    380    { NULL,               0 }
    381  };
    382  
    383 --- a/doc/manual.xml.head.orig  2010-08-24 18:34:21.000000000 +0200
    384 +++ b/doc/manual.xml.head       2011-03-21 18:28:37.000000000 +0100
    385 @@ -5823,6 +5823,18 @@
    386  </para>
    387  
    388  <para>
    389 +You can change or delete the ``X-Label:'' field within Mutt using the
    390 +``edit-label'' command, bound to the ``y'' key by default.  This works
    391 +for tagged messages, too.
    392 +</para>
    393 +
    394 +<para>
    395 +You can change or delete the ``X-Label:'' field within Mutt using the
    396 +``edit-label'' command, bound to the ``y'' key by default.  This works
    397 +for tagged messages, too.
    398 +</para>
    399 +
    400 +<para>
    401  Lastly, Mutt has the ability to <link linkend="sort">sort</link> the
    402  mailbox into <link linkend="threads">threads</link>.  A thread is a
    403  group of messages which all relate to the same subject.  This is usually
  • deleted file mail/mutt/files/patch-1.5.24-trash_folder-purge_message.diff

    diff --git a/mail/mutt/files/patch-1.5.24-trash_folder-purge_message.diff b/mail/mutt/files/patch-1.5.24-trash_folder-purge_message.diff
    deleted file mode 100644
    + -  
    1 # HG changeset patch
    2 # User Clemens Lang <cal@macports.org>
    3 # Date 1449948138 -3600
    4 #      Sat Dec 12 20:22:18 2015 +0100
    5 # Node ID 462bed648335a13643a39b7e5ee09bc396593a4a
    6 # Parent  72fbf15cd9a166881500dbcb43cb5747213077e9
    7 Update trash folder & purge patch for mutt 1.5.24
    8 
    9 diff --git a/OPS b/OPS
    10 --- a/OPS
    11 +++ b/OPS
    12 @@ -142,6 +142,7 @@
    13  OP_PREV_LINE "scroll up one line"
    14  OP_PREV_PAGE "move to the previous page"
    15  OP_PRINT "print the current entry"
    16 +OP_PURGE_MESSAGE "really delete the current entry, bypassing the trash folder"
    17  OP_QUERY "query external program for addresses"
    18  OP_QUERY_APPEND "append new query results to current results"
    19  OP_QUIT "save changes to mailbox and quit"
    20 diff --git a/PATCHES b/PATCHES
    21 --- a/PATCHES
    22 +++ b/PATCHES
    23 @@ -0,0 +1,1 @@
    24 +patch-1.5.24.trash_folder-purge_message
    25 diff --git a/commands.c b/commands.c
    26 --- a/commands.c
    27 +++ b/commands.c
    28 @@ -720,6 +720,7 @@
    29      if (option (OPTDELETEUNTAG))
    30        mutt_set_flag (Context, h, M_TAG, 0);
    31    }
    32 +  mutt_set_flag (Context, h, M_APPENDED, 1);
    33    
    34    return 0;
    35  }
    36 diff --git a/curs_main.c b/curs_main.c
    37 --- a/curs_main.c
    38 +++ b/curs_main.c
    39 @@ -1919,6 +1919,7 @@
    40         MAYBE_REDRAW (menu->redraw);
    41         break;
    42  
    43 +      case OP_PURGE_MESSAGE:
    44        case OP_DELETE:
    45  
    46         CHECK_MSGCOUNT;
    47 @@ -1930,6 +1931,7 @@
    48         if (tag)
    49         {
    50           mutt_tag_set_flag (M_DELETE, 1);
    51 +         mutt_tag_set_flag (M_PURGED, (op != OP_PURGE_MESSAGE) ? 0 : 1);
    52           if (option (OPTDELETEUNTAG))
    53             mutt_tag_set_flag (M_TAG, 0);
    54           menu->redraw = REDRAW_INDEX;
    55 @@ -1937,6 +1939,8 @@
    56         else
    57         {
    58           mutt_set_flag (Context, CURHDR, M_DELETE, 1);
    59 +         mutt_set_flag (Context, CURHDR, M_PURGED,
    60 +                        (op != OP_PURGE_MESSAGE) ? 0 : 1);
    61           if (option (OPTDELETEUNTAG))
    62             mutt_set_flag (Context, CURHDR, M_TAG, 0);
    63           if (option (OPTRESOLVE))
    64 @@ -2242,11 +2246,13 @@
    65         if (tag)
    66         {
    67           mutt_tag_set_flag (M_DELETE, 0);
    68 +         mutt_tag_set_flag (M_PURGED, 0);
    69           menu->redraw = REDRAW_INDEX;
    70         }
    71         else
    72         {
    73           mutt_set_flag (Context, CURHDR, M_DELETE, 0);
    74 +         mutt_set_flag (Context, CURHDR, M_PURGED, 0);
    75           if (option (OPTRESOLVE) && menu->current < Context->vcount - 1)
    76           {
    77             menu->current++;
    78 @@ -2268,9 +2274,11 @@
    79         CHECK_ACL(M_ACL_DELETE, _("Cannot undelete message(s)"));
    80  
    81         rc = mutt_thread_set_flag (CURHDR, M_DELETE, 0,
    82 -                                  op == OP_UNDELETE_THREAD ? 0 : 1);
    83 +                                  op == OP_UNDELETE_THREAD ? 0 : 1)
    84 +         + mutt_thread_set_flag (CURHDR, M_PURGED, 0,
    85 +                                 op == OP_UNDELETE_THREAD ? 0 : 1);
    86  
    87 -       if (rc != -1)
    88 +       if (rc > -1)
    89         {
    90           if (option (OPTRESOLVE))
    91           {
    92 diff --git a/flags.c b/flags.c
    93 --- a/flags.c
    94 +++ b/flags.c
    95 @@ -65,7 +65,13 @@
    96        {
    97         h->deleted = 0;
    98          update = 1;
    99 -       if (upd_ctx) ctx->deleted--;
    100 +        if (upd_ctx)
    101 +        {
    102 +          ctx->deleted--;
    103 +          if (h->appended)
    104 +            ctx->appended--;
    105 +        }
    106 +        h->appended = 0; /* when undeleting, also reset the appended flag */
    107  #ifdef USE_IMAP
    108          /* see my comment above */
    109         if (ctx->magic == M_IMAP)
    110 @@ -87,6 +93,27 @@
    111        }
    112        break;
    113  
    114 +    case M_APPENDED:
    115 +      if (bf)
    116 +      {
    117 +       if (!h->appended)
    118 +       {
    119 +         h->appended = 1;
    120 +         if (upd_ctx) ctx->appended++;
    121 +       }
    122 +      }
    123 +      break;
    124 +
    125 +    case M_PURGED:
    126 +      if (bf)
    127 +      {
    128 +       if (!h->purged)
    129 +         h->purged = 1;
    130 +      }
    131 +      else if (h->purged)
    132 +       h->purged = 0;
    133 +      break;
    134 +
    135      case M_NEW:
    136  
    137        if (!mutt_bit_isset(ctx->rights,M_ACL_SEEN))
    138 diff --git a/functions.h b/functions.h
    139 --- a/functions.h
    140 +++ b/functions.h
    141 @@ -121,6 +121,7 @@
    142    { "toggle-write",            OP_TOGGLE_WRITE,                "%" },
    143    { "next-thread",             OP_MAIN_NEXT_THREAD,            "\016" },
    144    { "next-subthread",          OP_MAIN_NEXT_SUBTHREAD,         "\033n" },
    145 +  { "purge-message",           OP_PURGE_MESSAGE,               NULL },
    146    { "query",                   OP_QUERY,                       "Q" },
    147    { "quit",                    OP_QUIT,                        "q" },
    148    { "reply",                   OP_REPLY,                       "r" },
    149 @@ -213,6 +214,7 @@
    150    { "print-message",   OP_PRINT,                       "p" },
    151    { "previous-thread", OP_MAIN_PREV_THREAD,            "\020" },
    152    { "previous-subthread",OP_MAIN_PREV_SUBTHREAD,       "\033p" },
    153 +  { "purge-message",   OP_PURGE_MESSAGE,               NULL },
    154    { "quit",            OP_QUIT,                        "Q" },
    155    { "exit",            OP_EXIT,                        "q" },
    156    { "reply",           OP_REPLY,                       "r" },
    157 diff --git a/globals.h b/globals.h
    158 --- a/globals.h
    159 +++ b/globals.h
    160 @@ -141,6 +141,7 @@
    161  WHERE char *Status;
    162  WHERE char *Tempdir;
    163  WHERE char *Tochars;
    164 +WHERE char *TrashPath;
    165  WHERE char *TSStatusFormat;
    166  WHERE char *TSIconFormat;
    167  WHERE short TSSupported;
    168 diff --git a/imap/message.c b/imap/message.c
    169 --- a/imap/message.c
    170 +++ b/imap/message.c
    171 @@ -886,6 +886,7 @@
    172          if (ctx->hdrs[n]->tagged)
    173          {
    174            mutt_set_flag (ctx, ctx->hdrs[n], M_DELETE, 1);
    175 +         mutt_set_flag (ctx, ctx->hdrs[n], M_APPENDED, 1);
    176            if (option (OPTDELETEUNTAG))
    177              mutt_set_flag (ctx, ctx->hdrs[n], M_TAG, 0);
    178          }
    179 @@ -893,6 +894,7 @@
    180      else
    181      {
    182        mutt_set_flag (ctx, h, M_DELETE, 1);
    183 +      mutt_set_flag (ctx, h, M_APPENDED, 1);
    184        if (option (OPTDELETEUNTAG))
    185          mutt_set_flag (ctx, h, M_TAG, 0);
    186      }
    187 diff --git a/init.h b/init.h
    188 --- a/init.h
    189 +++ b/init.h
    190 @@ -3367,6 +3367,16 @@
    191    ** provided that ``$$ts_enabled'' has been set. This string is identical in
    192    ** formatting to the one used by ``$$status_format''.
    193    */
    194 +  { "trash",           DT_PATH, R_NONE, UL &TrashPath, 0 },
    195 +  /*
    196 +  ** .pp
    197 +  ** If set, this variable specifies the path of the trash folder where the
    198 +  ** mails marked for deletion will be moved, instead of being irremediably
    199 +  ** purged.
    200 +  ** .pp
    201 +  ** NOTE: When you delete a message in the trash folder, it is really
    202 +  ** deleted, so that you have a way to clean the trash.
    203 +  */
    204  #ifdef USE_SOCKET
    205    { "tunnel",            DT_STR, R_NONE, UL &Tunnel, UL 0 },
    206    /*
    207 diff --git a/mutt.h b/mutt.h
    208 --- a/mutt.h
    209 +++ b/mutt.h
    210 @@ -182,6 +182,8 @@
    211    M_DELETE,
    212    M_UNDELETE,
    213    M_DELETED,
    214 +  M_APPENDED,
    215 +  M_PURGED,
    216    M_FLAG,
    217    M_TAG,
    218    M_UNTAG,
    219 @@ -711,6 +713,8 @@
    220    unsigned int mime : 1;               /* has a MIME-Version header? */
    221    unsigned int flagged : 1;            /* marked important? */
    222    unsigned int tagged : 1;
    223 +  unsigned int appended : 1; /* has been saved */
    224 +  unsigned int purged : 1;   /* bypassing the trash folder */
    225    unsigned int deleted : 1;
    226    unsigned int changed : 1;
    227    unsigned int attach_del : 1;                 /* has an attachment marked for deletion */
    228 @@ -883,6 +887,7 @@
    229    int new;                     /* how many new messages? */
    230    int unread;                  /* how many unread messages? */
    231    int deleted;                 /* how many deleted messages */
    232 +  int appended;                 /* how many saved messages? */
    233    int flagged;                 /* how many flagged messages */
    234    int msgnotreadyet;           /* which msg "new" in pager, -1 if none */
    235  
    236 diff --git a/muttlib.c b/muttlib.c
    237 --- a/muttlib.c
    238 +++ b/muttlib.c
    239 @@ -1511,7 +1511,9 @@
    240  
    241    if (magic > 0 && !mx_access (s, W_OK))
    242    {
    243 -    if (option (OPTCONFIRMAPPEND))
    244 +    if (option (OPTCONFIRMAPPEND) &&
    245 +       (!TrashPath || (mutt_strcmp (s, TrashPath) != 0)))
    246 +      /* if we're appending to the trash, there's no point in asking */
    247      {
    248        snprintf (tmp, sizeof (tmp), _("Append messages to %s?"), s);
    249        if ((rc = mutt_yesorno (tmp, M_YES)) == M_NO)
    250 diff --git a/mx.c b/mx.c
    251 --- a/mx.c
    252 +++ b/mx.c
    253 @@ -776,6 +776,54 @@
    254    return rc;
    255  }
    256  
    257 +/* move deleted mails to the trash folder */
    258 +static int trash_append (CONTEXT *ctx)
    259 +{
    260 +    CONTEXT *ctx_trash;
    261 +    int i = 0;
    262 +    struct stat st, stc;
    263 +
    264 +    if (!TrashPath || !ctx->deleted ||
    265 +       (ctx->magic == M_MAILDIR && option (OPTMAILDIRTRASH)))
    266 +      return 0;
    267 +
    268 +    for (;i < ctx->msgcount && (!ctx->hdrs[i]->deleted ||
    269 +                               ctx->hdrs[i]->appended); i++);
    270 +    if (i == ctx->msgcount)
    271 +      return 0; /* nothing to be done */
    272 +
    273 +    if (mutt_save_confirm (TrashPath, &st) != 0)
    274 +    {
    275 +      mutt_error _("message(s) not deleted");
    276 +      return -1;
    277 +    }
    278 +
    279 +    if (lstat (ctx->path, &stc) == 0 && stc.st_ino == st.st_ino
    280 +       && stc.st_dev == st.st_dev && stc.st_rdev == st.st_rdev)
    281 +      return 0;  /* we are in the trash folder: simple sync */
    282 +
    283 +    if ((ctx_trash = mx_open_mailbox (TrashPath, M_APPEND, NULL)) != NULL)
    284 +    {
    285 +      for (i = 0 ; i < ctx->msgcount ; i++)
    286 +       if (ctx->hdrs[i]->deleted && !ctx->hdrs[i]->appended
    287 +           && !ctx->hdrs[i]->purged
    288 +           && mutt_append_message (ctx_trash, ctx, ctx->hdrs[i], 0, 0) == -1)
    289 +         {
    290 +           mx_close_mailbox (ctx_trash, NULL);
    291 +           return -1;
    292 +         }
    293 +
    294 +      mx_close_mailbox (ctx_trash, NULL);
    295 +    }
    296 +    else
    297 +    {
    298 +      mutt_error _("Can't open trash folder");
    299 +      return -1;
    300 +    }
    301 +
    302 +    return 0;
    303 +}
    304 +
    305  /* save changes and close mailbox */
    306  int mx_close_mailbox (CONTEXT *ctx, int *index_hint)
    307  {
    308 @@ -912,6 +960,7 @@
    309           if (mutt_append_message (&f, ctx, ctx->hdrs[i], 0, CH_UPDATE_LEN) == 0)
    310           {
    311             mutt_set_flag (ctx, ctx->hdrs[i], M_DELETE, 1);
    312 +            mutt_set_flag (ctx, ctx->hdrs[i], M_APPENDED, 1);
    313           }
    314           else
    315           {
    316 @@ -936,6 +985,14 @@
    317      return 0;
    318    }
    319    
    320 +  /* copy mails to the trash before expunging */
    321 +  if (purge && ctx->deleted)
    322 +    if (trash_append (ctx) != 0)
    323 +    {
    324 +      ctx->closing = 0;
    325 +      return -1;
    326 +    }
    327 +
    328  #ifdef USE_IMAP
    329    /* allow IMAP to preserve the deleted flag across sessions */
    330    if (ctx->magic == M_IMAP)
    331 @@ -1140,6 +1197,12 @@
    332    msgcount = ctx->msgcount;
    333    deleted = ctx->deleted;
    334  
    335 +  if (purge && ctx->deleted)
    336 +  {
    337 +    if (trash_append (ctx) == -1)
    338 +      return -1;
    339 +  }
    340 +
    341  #ifdef USE_IMAP
    342    if (ctx->magic == M_IMAP)
    343      rc = imap_sync_mailbox (ctx, purge, index_hint);
    344 diff --git a/pager.c b/pager.c
    345 --- a/pager.c
    346 +++ b/pager.c
    347 @@ -2351,6 +2351,7 @@
    348         MAYBE_REDRAW (redraw);
    349         break;
    350  
    351 +      case OP_PURGE_MESSAGE:
    352        case OP_DELETE:
    353         CHECK_MODE(IsHeader (extra));
    354         CHECK_READONLY;
    355 @@ -2358,6 +2359,8 @@
    356         CHECK_ACL(M_ACL_DELETE, _("Cannot delete message"));
    357  
    358         mutt_set_flag (Context, extra->hdr, M_DELETE, 1);
    359 +       mutt_set_flag (Context, extra->hdr, M_PURGED,
    360 +                      ch != OP_PURGE_MESSAGE ? 0 : 1);
    361          if (option (OPTDELETEUNTAG))
    362           mutt_set_flag (Context, extra->hdr, M_TAG, 0);
    363         redraw = REDRAW_STATUS | REDRAW_INDEX;
    364 @@ -2688,6 +2691,7 @@
    365         CHECK_ACL(M_ACL_DELETE, _("Cannot undelete message"));
    366  
    367         mutt_set_flag (Context, extra->hdr, M_DELETE, 0);
    368 +       mutt_set_flag (Context, extra->hdr, M_PURGED, 0);
    369         redraw = REDRAW_STATUS | REDRAW_INDEX;
    370         if (option (OPTRESOLVE))
    371         {
    372 @@ -2704,9 +2708,11 @@
    373         CHECK_ACL(M_ACL_DELETE, _("Cannot undelete message(s)"));
    374  
    375         r = mutt_thread_set_flag (extra->hdr, M_DELETE, 0,
    376 +                                 ch == OP_UNDELETE_THREAD ? 0 : 1)
    377 +         + mutt_thread_set_flag (extra->hdr, M_PURGED, 0,
    378                                   ch == OP_UNDELETE_THREAD ? 0 : 1);
    379  
    380 -       if (r != -1)
    381 +       if (r > -1)
    382         {
    383           if (option (OPTRESOLVE))
    384           {
    385 diff --git a/pattern.c b/pattern.c
    386 --- a/pattern.c
    387 +++ b/pattern.c
    388 @@ -1367,8 +1367,10 @@
    389        {
    390         switch (op)
    391         {
    392 +         case M_UNDELETE:
    393 +           mutt_set_flag (Context, Context->hdrs[Context->v2r[i]], M_PURGED,
    394 +                          0);
    395           case M_DELETE:
    396 -         case M_UNDELETE:
    397             mutt_set_flag (Context, Context->hdrs[Context->v2r[i]], M_DELETE,
    398                           (op == M_DELETE));
    399             break;
    400 diff --git a/postpone.c b/postpone.c
    401 --- a/postpone.c
    402 +++ b/postpone.c
    403 @@ -277,6 +277,9 @@
    404    /* finished with this message, so delete it. */
    405    mutt_set_flag (PostContext, h, M_DELETE, 1);
    406  
    407 +  /* and consider it saved, so that it won't be moved to the trash folder */
    408 +  mutt_set_flag (PostContext, h, M_APPENDED, 1);
    409 +
    410    /* update the count for the status display */
    411    PostCount = PostContext->msgcount - PostContext->deleted;
    412  
  • deleted file mail/mutt/files/patch-1.6.0.sidebar.20160408.macports.diff

    diff --git a/mail/mutt/files/patch-1.6.0.sidebar.20160408.macports.diff b/mail/mutt/files/patch-1.6.0.sidebar.20160408.macports.diff
    deleted file mode 100644
    + -  
    1 diff -ruN mutt-1.6.0.orig/Makefile.am mutt-1.6.0/Makefile.am
    2 --- mutt-1.6.0.orig/Makefile.am 2016-04-02 20:12:22.000000000 +0200
    3 +++ mutt-1.6.0/Makefile.am      2016-04-08 20:21:12.000000000 +0200
    4 @@ -36,6 +36,8 @@
    5         muttlib.c editmsg.c mbyte.c mutt_idna.c \
    6         url.c ascii.c crypt-mod.c crypt-mod.h safe_asprintf.c
    7  
    8 +mutt_SOURCES += sidebar.c
    9 +
    10  nodist_mutt_SOURCES = $(BUILT_SOURCES)
    11  
    12  mutt_LDADD = $(MUTT_LIB_OBJECTS) $(LIBOBJS) $(LIBIMAP) $(MUTTLIBS) \
    13 diff -ruN mutt-1.6.0.orig/Makefile.in mutt-1.6.0/Makefile.in
    14 --- mutt-1.6.0.orig/Makefile.in 2016-04-02 20:14:47.000000000 +0200
    15 +++ mutt-1.6.0/Makefile.in      2016-04-08 20:26:33.000000000 +0200
    16 @@ -136,6 +136,7 @@
    17         editmsg.$(OBJEXT) mbyte.$(OBJEXT) mutt_idna.$(OBJEXT) \
    18         url.$(OBJEXT) ascii.$(OBJEXT) crypt-mod.$(OBJEXT) \
    19         safe_asprintf.$(OBJEXT)
    20 +am_mutt_OBJECTS += sidebar.$(OBJEXT)
    21  am__objects_1 =
    22  am__objects_2 = patchlist.$(OBJEXT) conststrings.$(OBJEXT) \
    23         $(am__objects_1)
    24 @@ -490,6 +491,8 @@
    25         muttlib.c editmsg.c mbyte.c mutt_idna.c \
    26         url.c ascii.c crypt-mod.c crypt-mod.h safe_asprintf.c
    27  
    28 +mutt_SOURCES += sidebar.c
    29 +
    30  nodist_mutt_SOURCES = $(BUILT_SOURCES)
    31  mutt_LDADD = $(MUTT_LIB_OBJECTS) $(LIBOBJS) $(LIBIMAP) $(MUTTLIBS) \
    32         $(INTLLIBS) $(LIBICONV)  $(GPGME_LIBS)
    33 @@ -816,6 +819,7 @@
    34  @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/send.Po@am__quote@
    35  @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sendlib.Po@am__quote@
    36  @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sha1.Po@am__quote@
    37 +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sidebar.Po@am__quote@
    38  @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/signal.Po@am__quote@
    39  @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/smime.Po@am__quote@
    40  @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/smtp.Po@am__quote@
    41 diff -ruN mutt-1.6.0.orig/OPS mutt-1.6.0/OPS
    42 --- mutt-1.6.0.orig/OPS 2016-04-02 20:12:22.000000000 +0200
    43 +++ mutt-1.6.0/OPS      2016-04-08 20:19:20.000000000 +0200
    44 @@ -179,3 +179,8 @@
    45  OP_MAIN_SHOW_LIMIT "show currently active limit pattern"
    46  OP_MAIN_COLLAPSE_THREAD "collapse/uncollapse current thread"
    47  OP_MAIN_COLLAPSE_ALL "collapse/uncollapse all threads"
    48 +OP_SIDEBAR_SCROLL_UP "scroll the mailbox pane up 1 page"
    49 +OP_SIDEBAR_SCROLL_DOWN "scroll the mailbox pane down 1 page"
    50 +OP_SIDEBAR_NEXT "go down to next mailbox"
    51 +OP_SIDEBAR_PREV "go to previous mailbox"
    52 +OP_SIDEBAR_OPEN "open hilighted mailbox"
    53 diff -ruN mutt-1.6.0.orig/PATCHES mutt-1.6.0/PATCHES
    54 --- mutt-1.6.0.orig/PATCHES     2016-04-02 20:12:22.000000000 +0200
    55 +++ mutt-1.6.0/PATCHES  2016-04-08 20:19:20.000000000 +0200
    56 @@ -0,0 +1 @@
    57 +patch-1.6.0.sidebar.20160408.macports.diff
    58 diff -ruN mutt-1.6.0.orig/buffy.c mutt-1.6.0/buffy.c
    59 --- mutt-1.6.0.orig/buffy.c     2016-04-02 20:12:22.000000000 +0200
    60 +++ mutt-1.6.0/buffy.c  2016-04-08 20:19:20.000000000 +0200
    61 @@ -161,6 +161,49 @@
    62    }
    63  }
    64  
    65 +static int buffy_compare_name(const void *a, const void *b) {
    66 +  const BUFFY *b1 = * (BUFFY * const *) a;
    67 +  const BUFFY *b2 = * (BUFFY * const *) b;
    68 +
    69 +  return mutt_strcoll(b1->path, b2->path);
    70 +}
    71 +
    72 +static BUFFY *buffy_sort(BUFFY *b)
    73 +{
    74 +  BUFFY *tmp = b;
    75 +  int buffycount = 0;
    76 +  BUFFY **ary;
    77 +  int i;
    78 +
    79 +  if (!option(OPTSIDEBARSORT))
    80 +    return b;
    81 +
    82 +  for (; tmp != NULL; tmp = tmp->next)
    83 +    buffycount++;
    84 +
    85 +  ary = (BUFFY **) safe_calloc(buffycount, sizeof (*ary));
    86 +
    87 +  tmp = b;
    88 +  for (i = 0; tmp != NULL; tmp = tmp->next, i++) {
    89 +    ary[i] = tmp;
    90 +  }
    91 +
    92 +  qsort(ary, buffycount, sizeof(*ary), buffy_compare_name);
    93 +
    94 +  for (i = 0; i < buffycount - 1; i++) {
    95 +    ary[i]->next = ary[i+1];
    96 +  }
    97 +  ary[buffycount - 1]->next = NULL;
    98 +  for (i = 1; i < buffycount; i++) {
    99 +    ary[i]->prev = ary[i-1];
    100 +  }
    101 +  ary[0]->prev = NULL;
    102 +
    103 +  tmp = ary[0];
    104 +  free(ary);
    105 +  return tmp;
    106 +}
    107 +
    108  BUFFY *mutt_find_mailbox (const char *path)
    109  {
    110    BUFFY *tmp = NULL;
    111 @@ -196,9 +239,13 @@
    112  static BUFFY *buffy_new (const char *path)
    113  {
    114    BUFFY* buffy;
    115 +  char rp[PATH_MAX];
    116 +  char *r;
    117  
    118    buffy = (BUFFY *) safe_calloc (1, sizeof (BUFFY));
    119    strfcpy (buffy->path, path, sizeof (buffy->path));
    120 +  r = realpath(path, rp);
    121 +  strfcpy (buffy->realpath, r ? rp : path, sizeof (buffy->realpath));
    122    buffy->next = NULL;
    123    buffy->magic = 0;
    124  
    125 @@ -243,8 +290,8 @@
    126      p = realpath (buf, f1);
    127      for (tmp = &Incoming; *tmp; tmp = &((*tmp)->next))
    128      {
    129 -      q = realpath ((*tmp)->path, f2);
    130 -      if (mutt_strcmp (p ? p : buf, q ? q : (*tmp)->path) == 0)
    131 +      q = (*tmp)->realpath;
    132 +      if (mutt_strcmp (p ? p : buf, q) == 0)
    133        {
    134         dprint(3,(debugfile,"mailbox '%s' already registered as '%s'\n", buf, (*tmp)->path));
    135         break;
    136 @@ -282,6 +329,7 @@
    137      else
    138        (*tmp)->size = 0;
    139    }
    140 +  Incoming = buffy_sort(Incoming);
    141    return 0;
    142  }
    143  
    144 @@ -306,6 +354,11 @@
    145        return 0;
    146    }
    147  
    148 +  if (option(OPTSIDEBAR) && mailbox->msg_unread > 0) {
    149 +      mailbox->new = 1;
    150 +      return 1;
    151 +  }
    152 +
    153    if ((dirp = opendir (path)) == NULL)
    154    {
    155      mailbox->magic = 0;
    156 @@ -357,6 +410,73 @@
    157  
    158    return 0;
    159  }
    160 
    161 + /* update message counts for the sidebar */
    162 +void buffy_maildir_update (BUFFY* mailbox)
    163 +{
    164 + char path[_POSIX_PATH_MAX];
    165 + DIR *dirp;
    166 + struct dirent *de;
    167 + char *p;
    168 +
    169 + if(!option(OPTSIDEBAR))
    170 +     return;
    171 +
    172 + mailbox->msgcount = 0;
    173 + mailbox->msg_unread = 0;
    174 + mailbox->msg_flagged = 0;
    175 +
    176 + snprintf (path, sizeof (path), "%s/new", mailbox->path);
    177 +       
    178 + if ((dirp = opendir (path)) == NULL)
    179 + {   
    180 +   mailbox->magic = 0;
    181 +   return;
    182 + }
    183 +       
    184 + while ((de = readdir (dirp)) != NULL)
    185 + {
    186 +   if (*de->d_name == '.')
    187 +     continue;
    188 +
    189 +   if (!(p = strstr (de->d_name, ":2,")) || !strchr (p + 3, 'T')) {
    190 +     mailbox->new = 1;
    191 +     mailbox->msgcount++;
    192 +     mailbox->msg_unread++;
    193 +   }
    194 + }
    195 +
    196 + closedir (dirp);
    197 + snprintf (path, sizeof (path), "%s/cur", mailbox->path);
    198 +       
    199 + if ((dirp = opendir (path)) == NULL)
    200 + {   
    201 +  mailbox->magic = 0;
    202 +   return;
    203 + }
    204 +       
    205 + while ((de = readdir (dirp)) != NULL)
    206 + {
    207 +   if (*de->d_name == '.')
    208 +     continue;
    209 +
    210 +   if (!(p = strstr (de->d_name, ":2,")) || !strchr (p + 3, 'T')) {
    211 +     mailbox->msgcount++;
    212 +     if ((p = strstr (de->d_name, ":2,"))) {
    213 +       if (!strchr (p + 3, 'T')) {
    214 +         if (!strchr (p + 3, 'S'))
    215 +           mailbox->msg_unread++;
    216 +         if (strchr(p + 3, 'F'))
    217 +           mailbox->msg_flagged++;
    218 +       }
    219 +     }
    220 +   }
    221 + }
    222 +
    223 + mailbox->sb_last_checked = time(NULL);
    224 + closedir (dirp);
    225 +}
    226 +
    227  /* returns 1 if mailbox has new mail */
    228  static int buffy_mbox_hasnew (BUFFY* mailbox, struct stat *sb)
    229  {
    230 @@ -368,7 +488,7 @@
    231    else
    232      statcheck = sb->st_mtime > sb->st_atime
    233        || (mailbox->newly_created && sb->st_ctime == sb->st_mtime && sb->st_ctime == sb->st_atime);
    234 -  if (statcheck)
    235 +  if ((!option(OPTSIDEBAR) && statcheck) || (option(OPTSIDEBAR) && mailbox->msg_unread > 0))
    236    {
    237      if (!option(OPTMAILCHECKRECENT) || sb->st_mtime > mailbox->last_visited)
    238      {
    239 @@ -388,6 +508,27 @@
    240    return rc;
    241  }
    242  
    243 +/* update message counts for the sidebar */
    244 +void buffy_mbox_update (BUFFY* mailbox, struct stat *sb)
    245 +{
    246 +  CONTEXT *ctx = NULL;
    247 +
    248 +  if(!option(OPTSIDEBAR))
    249 +      return;
    250 +  if(mailbox->sb_last_checked > sb->st_mtime && mailbox->msgcount != 0)
    251 +      return; /* no check necessary */
    252 +
    253 +  ctx = mx_open_mailbox(mailbox->path, M_READONLY | M_QUIET | M_NOSORT | M_PEEK, NULL);
    254 +  if(ctx)
    255 +  {
    256 +    mailbox->msgcount = ctx->msgcount;
    257 +    mailbox->msg_unread = ctx->unread;
    258 +    mailbox->msg_flagged = ctx->flagged;
    259 +    mailbox->sb_last_checked = time(NULL);
    260 +    mx_close_mailbox(ctx, 0);
    261 +  }
    262 +}
    263 +
    264  int mutt_buffy_check (int force)
    265  {
    266    BUFFY *tmp;
    267 @@ -461,17 +602,20 @@
    268        {
    269        case M_MBOX:
    270        case M_MMDF:
    271 +       buffy_mbox_update (tmp, &sb);
    272         if (buffy_mbox_hasnew (tmp, &sb) > 0)
    273           BuffyCount++;
    274         break;
    275  
    276        case M_MAILDIR:
    277 +       buffy_maildir_update (tmp);
    278         if (buffy_maildir_hasnew (tmp) > 0)
    279           BuffyCount++;
    280         break;
    281  
    282        case M_MH:
    283 -       mh_buffy(tmp);
    284 +       mh_buffy_update (tmp->path, &tmp->msgcount, &tmp->msg_unread, &tmp->msg_flagged, &tmp->sb_last_checked);
    285 +        mh_buffy(tmp);
    286         if (tmp->new)
    287           BuffyCount++;
    288         break;
    289 diff -ruN mutt-1.6.0.orig/buffy.h mutt-1.6.0/buffy.h
    290 --- mutt-1.6.0.orig/buffy.h     2016-04-02 20:12:22.000000000 +0200
    291 +++ mutt-1.6.0/buffy.h  2016-04-08 20:19:20.000000000 +0200
    292 @@ -23,13 +23,19 @@
    293  typedef struct buffy_t
    294  {
    295    char path[_POSIX_PATH_MAX];
    296 +  char realpath[_POSIX_PATH_MAX];
    297    off_t size;
    298    struct buffy_t *next;
    299 +  struct buffy_t *prev;
    300    short new;                   /* mailbox has new mail */
    301 +  int msgcount;                        /* total number of messages */
    302 +  int msg_unread;              /* number of unread messages */
    303 +  int msg_flagged;             /* number of flagged messages */
    304    short notified;              /* user has been notified */
    305    short magic;                 /* mailbox type */
    306    short newly_created;         /* mbox or mmdf just popped into existence */
    307    time_t last_visited;         /* time of last exit from this mailbox */
    308 +  time_t sb_last_checked;      /* time of last buffy check from sidebar */
    309  }
    310  BUFFY;
    311  
    312 diff -ruN mutt-1.6.0.orig/color.c mutt-1.6.0/color.c
    313 --- mutt-1.6.0.orig/color.c     2016-04-02 20:12:22.000000000 +0200
    314 +++ mutt-1.6.0/color.c  2016-04-08 20:19:20.000000000 +0200
    315 @@ -94,6 +94,8 @@
    316    { "underline",       MT_COLOR_UNDERLINE },
    317    { "index",           MT_COLOR_INDEX },
    318    { "prompt",          MT_COLOR_PROMPT },
    319 +  { "sidebar_new",     MT_COLOR_NEW },
    320 +  { "sidebar_flagged", MT_COLOR_FLAGGED },
    321    { NULL,              0 }
    322  };
    323  
    324 diff -ruN mutt-1.6.0.orig/compose.c mutt-1.6.0/compose.c
    325 --- mutt-1.6.0.orig/compose.c   2016-04-02 20:12:22.000000000 +0200
    326 +++ mutt-1.6.0/compose.c        2016-04-08 20:19:20.000000000 +0200
    327 @@ -72,7 +72,7 @@
    328  
    329  #define HDR_XOFFSET 10
    330  #define TITLE_FMT "%10s" /* Used for Prompts, which are ASCII */
    331 -#define W (COLS - HDR_XOFFSET)
    332 +#define W (COLS - HDR_XOFFSET - SidebarWidth)
    333  
    334  static const char * const Prompts[] =
    335  {
    336 @@ -110,7 +110,7 @@
    337  
    338  static void redraw_crypt_lines (HEADER *msg)
    339  {
    340 -  mvaddstr (HDR_CRYPT, 0, "Security: ");
    341 +  mvaddstr (HDR_CRYPT, SidebarWidth, "Security: ");
    342  
    343    if ((WithCrypto & (APPLICATION_PGP | APPLICATION_SMIME)) == 0)
    344    {
    345 @@ -145,7 +145,7 @@
    346        addstr (_(" (OppEnc mode)"));
    347  
    348    clrtoeol ();
    349 -  move (HDR_CRYPTINFO, 0);
    350 +  move (HDR_CRYPTINFO, SidebarWidth);
    351    clrtoeol ();
    352  
    353    if ((WithCrypto & APPLICATION_PGP)
    354 @@ -162,7 +162,7 @@
    355        && (msg->security & ENCRYPT)
    356        && SmimeCryptAlg
    357        && *SmimeCryptAlg) {
    358 -      mvprintw (HDR_CRYPTINFO, 40, "%s%s", _("Encrypt with: "),
    359 +      mvprintw (HDR_CRYPTINFO, SidebarWidth + 40, "%s%s", _("Encrypt with: "),
    360                 NONULL(SmimeCryptAlg));
    361    }
    362  }
    363 @@ -175,7 +175,7 @@
    364    int c;
    365    char *t;
    366  
    367 -  mvaddstr (HDR_MIX, 0,     "     Mix: ");
    368 +  mvaddstr (HDR_MIX, SidebarWidth,     "     Mix: ");
    369  
    370    if (!chain)
    371    {
    372 @@ -190,7 +190,7 @@
    373      if (t && t[0] == '0' && t[1] == '\0')
    374        t = "<random>";
    375      
    376 -    if (c + mutt_strlen (t) + 2 >= COLS)
    377 +    if (c + mutt_strlen (t) + 2 >= COLS - SidebarWidth)
    378        break;
    379  
    380      addstr (NONULL(t));
    381 @@ -242,7 +242,7 @@
    382  
    383    buf[0] = 0;
    384    rfc822_write_address (buf, sizeof (buf), addr, 1);
    385 -  mvprintw (line, 0, TITLE_FMT, Prompts[line - 1]);
    386 +  mvprintw (line, SidebarWidth, TITLE_FMT, Prompts[line - 1]);
    387    mutt_paddstr (W, buf);
    388  }
    389  
    390 @@ -252,10 +252,10 @@
    391    draw_envelope_addr (HDR_TO, msg->env->to);
    392    draw_envelope_addr (HDR_CC, msg->env->cc);
    393    draw_envelope_addr (HDR_BCC, msg->env->bcc);
    394 -  mvprintw (HDR_SUBJECT, 0, TITLE_FMT, Prompts[HDR_SUBJECT - 1]);
    395 +  mvprintw (HDR_SUBJECT, SidebarWidth, TITLE_FMT, Prompts[HDR_SUBJECT - 1]);
    396    mutt_paddstr (W, NONULL (msg->env->subject));
    397    draw_envelope_addr (HDR_REPLYTO, msg->env->reply_to);
    398 -  mvprintw (HDR_FCC, 0, TITLE_FMT, Prompts[HDR_FCC - 1]);
    399 +  mvprintw (HDR_FCC, SidebarWidth, TITLE_FMT, Prompts[HDR_FCC - 1]);
    400    mutt_paddstr (W, fcc);
    401  
    402    if (WithCrypto)
    403 @@ -266,7 +266,7 @@
    404  #endif
    405  
    406    SETCOLOR (MT_COLOR_STATUS);
    407 -  mvaddstr (HDR_ATTACH - 1, 0, _("-- Attachments"));
    408 +  mvaddstr (HDR_ATTACH - 1, SidebarWidth, _("-- Attachments"));
    409    clrtoeol ();
    410  
    411    NORMAL_COLOR;
    412 @@ -302,7 +302,7 @@
    413    /* redraw the expanded list so the user can see the result */
    414    buf[0] = 0;
    415    rfc822_write_address (buf, sizeof (buf), *addr, 1);
    416 -  move (line, HDR_XOFFSET);
    417 +  move (line, HDR_XOFFSET+SidebarWidth);
    418    mutt_paddstr (W, buf);
    419    
    420    return 0;
    421 @@ -564,7 +564,7 @@
    422         if (mutt_get_field ("Subject: ", buf, sizeof (buf), 0) == 0)
    423         {
    424           mutt_str_replace (&msg->env->subject, buf);
    425 -         move (HDR_SUBJECT, HDR_XOFFSET);
    426 +         move (HDR_SUBJECT, HDR_XOFFSET + SidebarWidth);
    427           if (msg->env->subject)
    428             mutt_paddstr (W, msg->env->subject);
    429           else
    430 @@ -582,7 +582,7 @@
    431         {
    432           strfcpy (fcc, buf, fcclen);
    433           mutt_pretty_mailbox (fcc, fcclen);
    434 -         move (HDR_FCC, HDR_XOFFSET);
    435 +         move (HDR_FCC, HDR_XOFFSET + SidebarWidth);
    436           mutt_paddstr (W, fcc);
    437           fccSet = 1;
    438         }
    439 diff -ruN mutt-1.6.0.orig/configure.ac mutt-1.6.0/configure.ac
    440 --- mutt-1.6.0.orig/configure.ac        2016-04-02 20:12:22.000000000 +0200
    441 +++ mutt-1.6.0/configure.ac     2016-04-08 20:19:20.000000000 +0200
    442 @@ -1301,6 +1301,8 @@
    443    AC_DEFINE(HAVE_LANGINFO_YESEXPR,1,[ Define if you have <langinfo.h> and nl_langinfo(YESEXPR). ])
    444  fi
    445  
    446 +AC_CHECK_FUNCS(fmemopen open_memstream)
    447 +
    448  dnl Documentation tools
    449  have_openjade="no"
    450  AC_PATH_PROG([OSPCAT], [ospcat], [none])
    451 diff -ruN mutt-1.6.0.orig/curs_main.c mutt-1.6.0/curs_main.c
    452 --- mutt-1.6.0.orig/curs_main.c 2016-04-02 20:12:22.000000000 +0200
    453 +++ mutt-1.6.0/curs_main.c      2016-04-08 20:19:20.000000000 +0200
    454 @@ -26,7 +26,9 @@
    455  #include "mailbox.h"
    456  #include "mapping.h"
    457  #include "sort.h"
    458 +#include "buffy.h"
    459  #include "mx.h"
    460 +#include "sidebar.h"
    461  
    462  #ifdef USE_POP
    463  #include "pop.h"
    464 @@ -595,20 +597,31 @@
    465         menu->redraw |= REDRAW_STATUS;
    466       if (do_buffy_notify)
    467       {
    468 -       if (mutt_buffy_notify () && option (OPTBEEPNEW))
    469 -       beep ();
    470 +       if (mutt_buffy_notify ())
    471 +       {
    472 +         menu->redraw |= REDRAW_STATUS;
    473 +         if (option (OPTBEEPNEW))
    474 +           beep ();
    475 +       }
    476       }
    477       else
    478         do_buffy_notify = 1;
    479      }
    480  
    481 +    if(option(OPTSIDEBAR))
    482 +        menu->redraw |= REDRAW_SIDEBAR;
    483 +
    484      if (op != -1)
    485        mutt_curs_set (0);
    486  
    487      if (menu->redraw & REDRAW_FULL)
    488      {
    489        menu_redraw_full (menu);
    490 +      draw_sidebar(menu->menu);
    491        mutt_show_error ();
    492 +    } else if(menu->redraw & REDRAW_SIDEBAR) {
    493 +        draw_sidebar(menu->menu);
    494 +        menu->redraw &= ~REDRAW_SIDEBAR;
    495      }
    496  
    497      if (menu->menu == MENU_MAIN)
    498 @@ -630,9 +643,12 @@
    499  
    500        if (menu->redraw & REDRAW_STATUS)
    501        {
    502 +        DrawFullLine = 1;
    503         menu_status_line (buf, sizeof (buf), menu, NONULL (Status));
    504 +        DrawFullLine = 0;
    505         move (option (OPTSTATUSONTOP) ? 0 : LINES-2, 0);
    506         SETCOLOR (MT_COLOR_STATUS);
    507 +        set_buffystats(Context);
    508         mutt_paddstr (COLS, buf);
    509         NORMAL_COLOR;
    510         menu->redraw &= ~REDRAW_STATUS;
    511 @@ -652,7 +668,7 @@
    512         menu->oldcurrent = -1;
    513  
    514        if (option (OPTARROWCURSOR))
    515 -       move (menu->current - menu->top + menu->offset, 2);
    516 +       move (menu->current - menu->top + menu->offset, SidebarWidth + 2);
    517        else if (option (OPTBRAILLEFRIENDLY))
    518         move (menu->current - menu->top + menu->offset, 0);
    519        else
    520 @@ -1091,6 +1107,7 @@
    521           break;
    522  
    523         CHECK_MSGCOUNT;
    524 +        CHECK_VISIBLE;
    525         CHECK_READONLY;
    526         {
    527           int oldvcount = Context->vcount;
    528 @@ -1150,6 +1167,7 @@
    529           menu->redraw = REDRAW_FULL;
    530         break;
    531  
    532 +      case OP_SIDEBAR_OPEN:
    533        case OP_MAIN_CHANGE_FOLDER:
    534        case OP_MAIN_NEXT_UNREAD_MAILBOX:
    535  
    536 @@ -1181,7 +1199,11 @@
    537         {
    538           mutt_buffy (buf, sizeof (buf));
    539  
    540 -         if (mutt_enter_fname (cp, buf, sizeof (buf), &menu->redraw, 1) == -1)
    541 +          if ( op == OP_SIDEBAR_OPEN ) {
    542 +              if(!CurBuffy)
    543 +                break;
    544 +            strncpy( buf, CurBuffy->path, sizeof(buf) ); 
    545 +           } else if (mutt_enter_fname (cp, buf, sizeof (buf), &menu->redraw, 1) == -1)
    546           {
    547             if (menu->menu == MENU_PAGER)
    548             {
    549 @@ -1199,6 +1221,7 @@
    550         }
    551  
    552         mutt_expand_path (buf, sizeof (buf));
    553 +        set_curbuffy(buf);
    554         if (mx_get_magic (buf) <= 0)
    555         {
    556           mutt_error (_("%s is not a mailbox."), buf);
    557 @@ -2310,6 +2333,12 @@
    558         mutt_what_key();
    559         break;
    560  
    561 +      case OP_SIDEBAR_SCROLL_UP:
    562 +      case OP_SIDEBAR_SCROLL_DOWN:
    563 +      case OP_SIDEBAR_NEXT:
    564 +      case OP_SIDEBAR_PREV:
    565 +        scroll_sidebar(op, menu->menu);
    566 +        break;
    567        default:
    568         if (menu->menu == MENU_MAIN)
    569           km_error_key (MENU_MAIN);
    570 diff -ruN mutt-1.6.0.orig/doc/Muttrc mutt-1.6.0/doc/Muttrc
    571 --- mutt-1.6.0.orig/doc/Muttrc  2016-04-02 20:15:01.000000000 +0200
    572 +++ mutt-1.6.0/doc/Muttrc       2016-04-08 20:19:20.000000000 +0200
    573 @@ -657,6 +657,26 @@
    574  # $crypt_autosign, $crypt_replysign and $smime_is_default.
    575  #
    576  #
    577 +# set sidebar_visible=no
    578 +#
    579 +# Name: sidebar_visible
    580 +# Type: boolean
    581 +# Default: no
    582 +#
    583 +#
    584 +# This specifies whether or not to show sidebar (left-side list of folders).
    585 +#
    586 +#
    587 +# set sidebar_width=0
    588 +#
    589 +# Name: sidebar_width
    590 +# Type: number
    591 +# Default: 0
    592 +#
    593 +#
    594 +# The width of the sidebar.
    595 +#
    596 +#
    597  # set crypt_autosign=no
    598  #
    599  # Name: crypt_autosign
    600 diff -ruN mutt-1.6.0.orig/flags.c mutt-1.6.0/flags.c
    601 --- mutt-1.6.0.orig/flags.c     2016-04-02 20:12:22.000000000 +0200
    602 +++ mutt-1.6.0/flags.c  2016-04-08 20:19:20.000000000 +0200
    603 @@ -22,8 +22,10 @@
    604  
    605  #include "mutt.h"
    606  #include "mutt_curses.h"
    607 +#include "mutt_menu.h"
    608  #include "sort.h"
    609  #include "mx.h"
    610 +#include "sidebar.h"
    611  
    612  void _mutt_set_flag (CONTEXT *ctx, HEADER *h, int flag, int bf, int upd_ctx)
    613  {
    614 @@ -263,6 +265,7 @@
    615     */
    616    if (h->searched && (changed != h->changed || deleted != ctx->deleted || tagged != ctx->tagged || flagged != ctx->flagged))
    617      h->searched = 0;
    618 +       draw_sidebar(0);
    619  }
    620  
    621  void mutt_tag_set_flag (int flag, int bf)
    622 diff -ruN mutt-1.6.0.orig/functions.h mutt-1.6.0/functions.h
    623 --- mutt-1.6.0.orig/functions.h 2016-04-02 20:12:22.000000000 +0200
    624 +++ mutt-1.6.0/functions.h      2016-04-08 20:19:20.000000000 +0200
    625 @@ -169,6 +169,11 @@
    626    { "decrypt-save",            OP_DECRYPT_SAVE,                NULL },
    627  
    628  
    629 + { "sidebar-scroll-up",        OP_SIDEBAR_SCROLL_UP, NULL },
    630 + { "sidebar-scroll-down",      OP_SIDEBAR_SCROLL_DOWN, NULL },
    631 + { "sidebar-next",             OP_SIDEBAR_NEXT, NULL },
    632 + { "sidebar-prev",             OP_SIDEBAR_PREV, NULL },
    633 + { "sidebar-open",             OP_SIDEBAR_OPEN, NULL },
    634    { NULL,                      0,                              NULL }
    635  };
    636  
    637 @@ -272,6 +277,11 @@
    638  
    639    { "what-key",                OP_WHAT_KEY,            NULL },
    640  
    641 +  { "sidebar-scroll-up",       OP_SIDEBAR_SCROLL_UP, NULL },
    642 +  { "sidebar-scroll-down",     OP_SIDEBAR_SCROLL_DOWN, NULL },
    643 +  { "sidebar-next",    OP_SIDEBAR_NEXT, NULL },
    644 +  { "sidebar-prev",    OP_SIDEBAR_PREV, NULL },
    645 +  { "sidebar-open", OP_SIDEBAR_OPEN, NULL },
    646    { NULL,              0,                              NULL }
    647  };
    648  
    649 diff -ruN mutt-1.6.0.orig/globals.h mutt-1.6.0/globals.h
    650 --- mutt-1.6.0.orig/globals.h   2016-04-02 20:12:22.000000000 +0200
    651 +++ mutt-1.6.0/globals.h        2016-04-08 20:19:20.000000000 +0200
    652 @@ -118,6 +118,9 @@
    653  WHERE char *SendCharset;
    654  WHERE char *Sendmail;
    655  WHERE char *Shell;
    656 +WHERE char *SidebarDelim;
    657 +WHERE char *SidebarFormat;
    658 +WHERE char *SidebarIndentStr;
    659  WHERE char *Signature;
    660  WHERE char *SimpleSearch;
    661  #if USE_SMTP
    662 @@ -214,6 +217,9 @@
    663  WHERE short ScoreThresholdRead;
    664  WHERE short ScoreThresholdFlag;
    665  
    666 +WHERE struct buffy_t *CurBuffy INITVAL(0);
    667 +WHERE short DrawFullLine INITVAL(0);
    668 +WHERE short SidebarWidth;
    669  #ifdef USE_IMAP
    670  WHERE short ImapKeepalive;
    671  WHERE short ImapPipelineDepth;
    672 diff -ruN mutt-1.6.0.orig/handler.c mutt-1.6.0/handler.c
    673 --- mutt-1.6.0.orig/handler.c   2016-04-02 20:12:22.000000000 +0200
    674 +++ mutt-1.6.0/handler.c        2016-04-08 20:19:20.000000000 +0200
    675 @@ -1603,6 +1603,11 @@
    676  
    677    fseeko (s->fpin, b->offset, 0);
    678  
    679 +#ifdef HAVE_FMEMOPEN
    680 +  char *temp;
    681 +  size_t tempsize;
    682 +#endif
    683 +
    684    /* see if we need to decode this part before processing it */
    685    if (b->encoding == ENCBASE64 || b->encoding == ENCQUOTEDPRINTABLE ||
    686        b->encoding == ENCUUENCODED || plaintext ||
    687 @@ -1618,6 +1623,14 @@
    688      {
    689        /* decode to a tempfile, saving the original destination */
    690        fp = s->fpout;
    691 +#ifdef HAVE_FMEMOPEN
    692 +     if ((s->fpout = open_memstream(&temp, &tempsize)) == NULL)
    693 +     {
    694 +       mutt_error _("Unable to open memory stream!");
    695 +       dprint (1, (debugfile, "Can't open memory stream.\n"));
    696 +       return -1;
    697 +     }
    698 +#else
    699        mutt_mktemp (tempfile, sizeof (tempfile));
    700        if ((s->fpout = safe_fopen (tempfile, "w")) == NULL)
    701        {
    702 @@ -1625,6 +1638,7 @@
    703          dprint (1, (debugfile, "Can't open %s.\n", tempfile));
    704          return -1;
    705        }
    706 +#endif
    707        /* decoding the attachment changes the size and offset, so save a copy
    708          * of the "real" values now, and restore them after processing
    709          */
    710 @@ -1653,9 +1667,19 @@
    711        /* restore final destination and substitute the tempfile for input */
    712        s->fpout = fp;
    713        fp = s->fpin;
    714 +#ifdef HAVE_FMEMOPEN
    715 +      if(tempsize)
    716 +        s->fpin = fmemopen(temp, tempsize, "r");
    717 +      else /* fmemopen cannot handle zero-length buffers */
    718 +        s->fpin = safe_fopen ("/dev/null", "r");
    719 +      if(s->fpin == NULL) {
    720 +       mutt_perror("failed to re-open memstream!");
    721 +       return (-1);
    722 +      }
    723 +#else
    724        s->fpin = fopen (tempfile, "r");
    725        unlink (tempfile);
    726 -
    727 +#endif
    728        /* restore the prefix */
    729        s->prefix = savePrefix;
    730      }
    731 @@ -1680,6 +1704,10 @@
    732  
    733        /* restore the original source stream */
    734        safe_fclose (&s->fpin);
    735 +#ifdef HAVE_FMEMOPEN
    736 +      if(tempsize)
    737 +          FREE(&temp);
    738 +#endif
    739        s->fpin = fp;
    740      }
    741    }
    742 diff -ruN mutt-1.6.0.orig/imap/command.c mutt-1.6.0/imap/command.c
    743 --- mutt-1.6.0.orig/imap/command.c      2016-04-02 20:12:22.000000000 +0200
    744 +++ mutt-1.6.0/imap/command.c   2016-04-08 20:19:20.000000000 +0200
    745 @@ -1016,6 +1016,13 @@
    746              opened */
    747           status->uidnext = oldun;
    748  
    749 +        /* Added to make the sidebar show the correct numbers */
    750 +        if (status->messages)
    751 +        {
    752 +          inc->msgcount = status->messages;
    753 +          inc->msg_unread = status->unseen;
    754 +        }
    755 +
    756          FREE (&value);
    757          return;
    758        }
    759 diff -ruN mutt-1.6.0.orig/imap/imap.c mutt-1.6.0/imap/imap.c
    760 --- mutt-1.6.0.orig/imap/imap.c 2016-04-02 20:12:22.000000000 +0200
    761 +++ mutt-1.6.0/imap/imap.c      2016-04-08 20:19:20.000000000 +0200
    762 @@ -1535,7 +1535,7 @@
    763  
    764      imap_munge_mbox_name (idata, munged, sizeof (munged), name);
    765      snprintf (command, sizeof (command),
    766 -             "STATUS %s (UIDNEXT UIDVALIDITY UNSEEN RECENT)", munged);
    767 +             "STATUS %s (UIDNEXT UIDVALIDITY UNSEEN RECENT MESSAGES)", munged);
    768  
    769      if (imap_exec (idata, command, IMAP_CMD_QUEUE) < 0)
    770      {
    771 diff -ruN mutt-1.6.0.orig/init.h mutt-1.6.0/init.h
    772 --- mutt-1.6.0.orig/init.h      2016-04-02 20:12:22.000000000 +0200
    773 +++ mutt-1.6.0/init.h   2016-04-08 20:19:20.000000000 +0200
    774 @@ -2049,6 +2049,54 @@
    775    ** not used.
    776    ** (PGP only)
    777    */
    778 +  {"sidebar_delim", DT_STR, R_BOTH, UL &SidebarDelim, UL "|"},
    779 +  /*
    780 +  ** .pp
    781 +  ** This specifies the delimiter between the sidebar (if visible) and
    782 +  ** other screens.
    783 +  */
    784 +  {"sidebar_indentstr", DT_STR, R_BOTH, UL &SidebarIndentStr, UL " "},
    785 +  /*
    786 +  ** .pp
    787 +  ** This specifies the string that is used to indent items
    788 +  ** with sidebar_folderindent= yes
    789 +  */
    790 +  { "sidebar_visible", DT_BOOL, R_BOTH, OPTSIDEBAR, 0 },
    791 +  /*
    792 +  ** .pp
    793 +  ** This specifies whether or not to show sidebar (left-side list of folders).
    794 +  */
    795 +  { "sidebar_sort", DT_BOOL, R_BOTH, OPTSIDEBARSORT, 0 },
    796 +  /*
    797 +  ** .pp
    798 +  ** This specifies whether or not to sort the sidebar alphabetically.
    799 +  */
    800 +  { "sidebar_width", DT_NUM, R_BOTH, UL &SidebarWidth, 0 },
    801 +  /*
    802 +  ** .pp
    803 +  ** The width of the sidebar.
    804 +  */
    805 +  { "sidebar_shortpath", DT_BOOL, R_BOTH, OPTSIDEBARSHORTPATH, 0 },
    806 +  /*
    807 +  ** .pp
    808 +  ** Should the sidebar shorten the path showed.
    809 +  */
    810 +  {"sidebar_format", DT_STR, R_NONE, UL &SidebarFormat, UL "%B%?F? [%F]?%* %?N?%N/?%4S"},
    811 +  /*
    812 +  ** .pp
    813 +  ** Format string for the sidebar. The sequences `%N', `%F' and `%S'
    814 +  ** will be replaced by the number of new or flagged messages or the total
    815 +  ** size of them mailbox. `%B' will be replaced with the name of the mailbox.
    816 +  ** The `%!' sequence will be expanded to `!' if there is one flagged message;
    817 +  ** to `!!' if there are two flagged messages; and to `n!' for n flagged
    818 +  ** messages, n>2.
    819 +  */
    820 +  { "sidebar_folderindent", DT_BOOL, R_BOTH, OPTSIDEBARFOLDERINDENT, 0 },
    821 +  /*
    822 +  ** .pp
    823 +  ** Should folders be indented in the sidebar.
    824 +  */
    825 +
    826    { "pgp_use_gpg_agent", DT_BOOL, R_NONE, OPTUSEGPGAGENT, 0},
    827    /*
    828    ** .pp
    829 diff -ruN mutt-1.6.0.orig/mailbox.h mutt-1.6.0/mailbox.h
    830 --- mutt-1.6.0.orig/mailbox.h   2016-04-02 20:12:22.000000000 +0200
    831 +++ mutt-1.6.0/mailbox.h        2016-04-08 20:19:20.000000000 +0200
    832 @@ -27,6 +27,7 @@
    833  #define M_NEWFOLDER    (1<<4) /* create a new folder - same as M_APPEND, but uses
    834                                 * safe_fopen() for mbox-style folders.
    835                                 */
    836 +#define M_PEEK         (1<<5) /* revert atime back after taking a look (if applicable) */
    837  
    838  /* mx_open_new_message() */
    839  #define M_ADD_FROM     (1<<0)  /* add a From_ line */
    840 diff -ruN mutt-1.6.0.orig/main.c mutt-1.6.0/main.c
    841 --- mutt-1.6.0.orig/main.c      2016-04-02 20:12:22.000000000 +0200
    842 +++ mutt-1.6.0/main.c   2016-04-08 20:19:20.000000000 +0200
    843 @@ -50,6 +50,7 @@
    844  #include <unistd.h>
    845  #include <errno.h>
    846  #include <sys/stat.h>
    847 +#include <limits.h>
    848  #include <sys/utsname.h>
    849  
    850  #ifdef HAVE_GETOPT_H
    851 @@ -557,7 +558,7 @@
    852  
    853  int main (int argc, char **argv)
    854  {
    855 -  char folder[_POSIX_PATH_MAX] = "";
    856 +  char folder[PATH_MAX] = "";
    857    char *subject = NULL;
    858    char *includeFile = NULL;
    859    char *draftFile = NULL;
    860 @@ -1184,6 +1185,13 @@
    861        strfcpy (folder, NONULL(Spoolfile), sizeof (folder));
    862      mutt_expand_path (folder, sizeof (folder));
    863  
    864 +    {
    865 +      char tmpfolder[PATH_MAX];
    866 +      strfcpy (tmpfolder, folder, sizeof (tmpfolder));
    867 +      if(!realpath(tmpfolder, folder))
    868 +          strfcpy (folder, tmpfolder, sizeof (tmpfolder));
    869 +    }
    870 +
    871      mutt_str_replace (&CurrentFolder, folder);
    872      mutt_str_replace (&LastFolder, folder);
    873  
    874 @@ -1206,6 +1214,7 @@
    875      if((Context = mx_open_mailbox (folder, ((flags & M_RO) || option (OPTREADONLY)) ? M_READONLY : 0, NULL))
    876         || !explicit_folder)
    877      {
    878 +      set_curbuffy(folder);
    879        mutt_index_menu ();
    880        if (Context)
    881         FREE (&Context);
    882 diff -ruN mutt-1.6.0.orig/mbox.c mutt-1.6.0/mbox.c
    883 --- mutt-1.6.0.orig/mbox.c      2016-04-02 20:12:22.000000000 +0200
    884 +++ mutt-1.6.0/mbox.c   2016-04-08 20:19:20.000000000 +0200
    885 @@ -100,6 +100,7 @@
    886      mutt_perror (ctx->path);
    887      return (-1);
    888    }
    889 +  ctx->atime = sb.st_atime;
    890    ctx->mtime = sb.st_mtime;
    891    ctx->size = sb.st_size;
    892  
    893 @@ -251,6 +252,7 @@
    894  
    895    ctx->size = sb.st_size;
    896    ctx->mtime = sb.st_mtime;
    897 +  ctx->atime = sb.st_atime;
    898  
    899  #ifdef NFS_ATTRIBUTE_HACK
    900    if (sb.st_mtime > sb.st_atime)
    901 diff -ruN mutt-1.6.0.orig/menu.c mutt-1.6.0/menu.c
    902 --- mutt-1.6.0.orig/menu.c      2016-04-02 20:12:22.000000000 +0200
    903 +++ mutt-1.6.0/menu.c   2016-04-08 20:19:20.000000000 +0200
    904 @@ -24,6 +24,7 @@
    905  #include "mutt_curses.h"
    906  #include "mutt_menu.h"
    907  #include "mbyte.h"
    908 +#include "sidebar.h"
    909  
    910  char* SearchBuffers[MENU_MAX];
    911  
    912 @@ -184,7 +185,7 @@
    913  {
    914    char *scratch = safe_strdup (s);
    915    int shift = option (OPTARROWCURSOR) ? 3 : 0;
    916 -  int cols = COLS - shift;
    917 +  int cols = COLS - shift - SidebarWidth;
    918  
    919    mutt_format_string (s, n, cols, cols, FMT_LEFT, ' ', scratch, mutt_strlen (scratch), 1);
    920    s[n - 1] = 0;
    921 @@ -237,6 +238,7 @@
    922    int do_color;
    923    int attr;
    924  
    925 +  draw_sidebar(1);
    926    for (i = menu->top; i < menu->top + menu->pagelen; i++)
    927    {
    928      if (i < menu->max)
    929 @@ -247,7 +249,7 @@
    930        menu_pad_string (buf, sizeof (buf));
    931  
    932        ATTRSET(attr);
    933 -      move(i - menu->top + menu->offset, 0);
    934 +      move(i - menu->top + menu->offset, SidebarWidth);
    935        do_color = 1;
    936  
    937        if (i == menu->current)
    938 @@ -270,7 +272,7 @@
    939      else
    940      {
    941        NORMAL_COLOR;
    942 -      CLEARLINE(i - menu->top + menu->offset);
    943 +      CLEARLINE_WIN (i - menu->top + menu->offset);
    944      }
    945    }
    946    NORMAL_COLOR;
    947 @@ -287,7 +289,7 @@
    948      return;
    949    }
    950    
    951 -  move (menu->oldcurrent + menu->offset - menu->top, 0);
    952 +  move (menu->oldcurrent + menu->offset - menu->top, SidebarWidth);
    953    ATTRSET(menu->color (menu->oldcurrent));
    954  
    955    if (option (OPTARROWCURSOR))
    956 @@ -299,13 +301,13 @@
    957      {
    958        menu_make_entry (buf, sizeof (buf), menu, menu->oldcurrent);
    959        menu_pad_string (buf, sizeof (buf));
    960 -      move (menu->oldcurrent + menu->offset - menu->top, 3);
    961 +      move (menu->oldcurrent + menu->offset - menu->top, SidebarWidth + 3);
    962        print_enriched_string (menu->color(menu->oldcurrent), (unsigned char *) buf, 1);
    963      }
    964  
    965      /* now draw it in the new location */
    966      SETCOLOR(MT_COLOR_INDICATOR);
    967 -    mvaddstr(menu->current + menu->offset - menu->top, 0, "->");
    968 +    mvaddstr(menu->current + menu->offset - menu->top, SidebarWidth, "->");
    969    }
    970    else
    971    {
    972 @@ -318,7 +320,7 @@
    973      menu_make_entry (buf, sizeof (buf), menu, menu->current);
    974      menu_pad_string (buf, sizeof (buf));
    975      SETCOLOR(MT_COLOR_INDICATOR);
    976 -    move(menu->current - menu->top + menu->offset, 0);
    977 +    move(menu->current - menu->top + menu->offset, SidebarWidth);
    978      print_enriched_string (menu->color(menu->current), (unsigned char *) buf, 0);
    979    }
    980    menu->redraw &= REDRAW_STATUS;
    981 @@ -330,7 +332,7 @@
    982    char buf[LONG_STRING];
    983    int attr = menu->color (menu->current);
    984    
    985 -  move (menu->current + menu->offset - menu->top, 0);
    986 +  move (menu->current + menu->offset - menu->top, SidebarWidth);
    987    menu_make_entry (buf, sizeof (buf), menu, menu->current);
    988    menu_pad_string (buf, sizeof (buf));
    989  
    990 @@ -873,7 +875,7 @@
    991      
    992      
    993      if (option (OPTARROWCURSOR))
    994 -      move (menu->current - menu->top + menu->offset, 2);
    995 +      move (menu->current - menu->top + menu->offset, SidebarWidth + 2);
    996      else if (option (OPTBRAILLEFRIENDLY))
    997        move (menu->current - menu->top + menu->offset, 0);
    998      else
    999 diff -ruN mutt-1.6.0.orig/mh.c mutt-1.6.0/mh.c
    1000 --- mutt-1.6.0.orig/mh.c        2016-04-02 20:12:22.000000000 +0200
    1001 +++ mutt-1.6.0/mh.c     2016-04-08 20:19:20.000000000 +0200
    1002 @@ -295,6 +295,32 @@
    1003    mhs_free_sequences (&mhs);
    1004  }
    1005  
    1006 +void mh_buffy_update (const char *path, int *msgcount, int *msg_unread, int *msg_flagged, time_t *sb_last_checked)
    1007 +{
    1008 +  int i;
    1009 +  struct mh_sequences mhs;
    1010 +  memset (&mhs, 0, sizeof (mhs));
    1011 +
    1012 +  if(!option(OPTSIDEBAR))
    1013 +      return;
    1014 +
    1015 +  if (mh_read_sequences (&mhs, path) < 0)
    1016 +    return;
    1017 +
    1018 +  msgcount = 0;
    1019 +  msg_unread = 0;
    1020 +  msg_flagged = 0;
    1021 +  for (i = 0; i <= mhs.max; i++)
    1022 +    msgcount++;
    1023 +    if (mhs_check (&mhs, i) & MH_SEQ_UNSEEN) {
    1024 +      msg_unread++;
    1025 +    }
    1026 +    if (mhs_check (&mhs, i) & MH_SEQ_FLAGGED)
    1027 +      msg_flagged++;
    1028 +  mhs_free_sequences (&mhs);
    1029 +  *sb_last_checked = time(NULL);
    1030 +}
    1031 +
    1032  static int mh_mkstemp (CONTEXT * dest, FILE ** fp, char **tgt)
    1033  {
    1034    int fd;
    1035 diff -ruN mutt-1.6.0.orig/mutt.h mutt-1.6.0/mutt.h
    1036 --- mutt-1.6.0.orig/mutt.h      2016-04-02 20:12:22.000000000 +0200
    1037 +++ mutt-1.6.0/mutt.h   2016-04-08 20:19:20.000000000 +0200
    1038 @@ -428,6 +428,10 @@
    1039    OPTSAVEEMPTY,
    1040    OPTSAVENAME,
    1041    OPTSCORE,
    1042 +  OPTSIDEBAR,
    1043 +  OPTSIDEBARSHORTPATH,
    1044 +  OPTSIDEBARSORT,
    1045 +  OPTSIDEBARFOLDERINDENT,
    1046    OPTSIGDASHES,
    1047    OPTSIGONTOP,
    1048    OPTSORTRE,
    1049 @@ -872,6 +876,7 @@
    1050  {
    1051    char *path;
    1052    FILE *fp;
    1053 +  time_t atime;
    1054    time_t mtime;
    1055    off_t size;
    1056    off_t vsize;
    1057 @@ -906,6 +911,7 @@
    1058    unsigned int quiet : 1;      /* inhibit status messages? */
    1059    unsigned int collapsed : 1;   /* are all threads collapsed? */
    1060    unsigned int closing : 1;    /* mailbox is being closed */
    1061 +  unsigned int peekonly : 1;   /* just taking a glance, revert atime */
    1062  
    1063    /* driver hooks */
    1064    void *data;                  /* driver specific data */
    1065 diff -ruN mutt-1.6.0.orig/mutt_curses.h mutt-1.6.0/mutt_curses.h
    1066 --- mutt-1.6.0.orig/mutt_curses.h       2016-04-02 20:12:22.000000000 +0200
    1067 +++ mutt-1.6.0/mutt_curses.h    2016-04-08 20:19:20.000000000 +0200
    1068 @@ -64,6 +64,7 @@
    1069  #undef lines
    1070  #endif /* lines */
    1071  
    1072 +#define CLEARLINE_WIN(x) move(x,SidebarWidth), clrtoeol()
    1073  #define CLEARLINE(x) move(x,0), clrtoeol()
    1074  #define CENTERLINE(x,y) move(y, (COLS-strlen(x))/2), addstr(x)
    1075  #define BEEP() do { if (option (OPTBEEP)) beep(); } while (0)
    1076 @@ -124,6 +125,8 @@
    1077    MT_COLOR_UNDERLINE,
    1078    MT_COLOR_INDEX,
    1079    MT_COLOR_PROMPT,
    1080 +  MT_COLOR_NEW,
    1081 +  MT_COLOR_FLAGGED,
    1082    MT_COLOR_MAX
    1083  };
    1084  
    1085 diff -ruN mutt-1.6.0.orig/mutt_menu.h mutt-1.6.0/mutt_menu.h
    1086 --- mutt-1.6.0.orig/mutt_menu.h 2016-04-02 20:12:22.000000000 +0200
    1087 +++ mutt-1.6.0/mutt_menu.h      2016-04-08 20:19:20.000000000 +0200
    1088 @@ -34,6 +34,7 @@
    1089  #define REDRAW_FULL            (1<<5)
    1090  #define REDRAW_BODY            (1<<6)
    1091  #define REDRAW_SIGWINCH                (1<<7)
    1092 +#define REDRAW_SIDEBAR         (1<<8)
    1093  
    1094  #define M_MODEFMT "-- Mutt: %s"
    1095  
    1096 diff -ruN mutt-1.6.0.orig/muttlib.c mutt-1.6.0/muttlib.c
    1097 --- mutt-1.6.0.orig/muttlib.c   2016-04-02 20:12:22.000000000 +0200
    1098 +++ mutt-1.6.0/muttlib.c        2016-04-08 20:19:20.000000000 +0200
    1099 @@ -1282,6 +1282,8 @@
    1100           pl = pw = 1;
    1101  
    1102         /* see if there's room to add content, else ignore */
    1103 +        if ( DrawFullLine )
    1104 +        {
    1105         if ((col < COLS && wlen < destlen) || soft)
    1106         {
    1107           int pad;
    1108 @@ -1325,6 +1327,52 @@
    1109           col += wid;
    1110           src += pl;
    1111         }
    1112 +        }
    1113 +        else
    1114 +        {
    1115 +       if ((col < COLS-SidebarWidth && wlen < destlen) || soft)
    1116 +        {
    1117 +         int pad;
    1118 +
    1119 +         /* get contents after padding */
    1120 +         mutt_FormatString (buf, sizeof (buf), 0, src + pl, callback, data, flags);
    1121 +         len = mutt_strlen (buf);
    1122 +         wid = mutt_strwidth (buf);
    1123 +
    1124 +         /* try to consume as many columns as we can, if we don't have
    1125 +          * memory for that, use as much memory as possible */
    1126 +         pad = (COLS - SidebarWidth - col - wid) / pw;
    1127 +         if (pad > 0 && wlen + (pad * pl) + len > destlen)
    1128 +           pad = ((signed)(destlen - wlen - len)) / pl;
    1129 +         if (pad > 0)
    1130 +         {
    1131 +           while (pad--)
    1132 +           {
    1133 +             memcpy (wptr, src, pl);
    1134 +             wptr += pl;
    1135 +             wlen += pl;
    1136 +             col += pw;
    1137 +           }
    1138 +         }
    1139 +         else if (soft && pad < 0)
    1140 +         {
    1141 +           /* \0-terminate dest for length computation in mutt_wstr_trunc() */
    1142 +           *wptr = 0;
    1143 +           /* make sure right part is at most as wide as display */
    1144 +           len = mutt_wstr_trunc (buf, destlen, COLS, &wid);
    1145 +           /* truncate left so that right part fits completely in */
    1146 +           wlen = mutt_wstr_trunc (dest, destlen - len, col + pad, &col);
    1147 +           wptr = dest + wlen;
    1148 +         }
    1149 +         if (len + wlen > destlen)
    1150 +           len = mutt_wstr_trunc (buf, destlen - wlen, COLS - SidebarWidth - col, NULL);
    1151 +         memcpy (wptr, buf, len);
    1152 +         wptr += len;
    1153 +         wlen += len;
    1154 +         col += wid;
    1155 +         src += pl;
    1156 +       }
    1157 +        }
    1158         break; /* skip rest of input */
    1159        }
    1160        else if (ch == '|')
    1161 diff -ruN mutt-1.6.0.orig/mx.c mutt-1.6.0/mx.c
    1162 --- mutt-1.6.0.orig/mx.c        2016-04-02 20:12:22.000000000 +0200
    1163 +++ mutt-1.6.0/mx.c     2016-04-08 20:19:20.000000000 +0200
    1164 @@ -580,6 +580,7 @@
    1165   *             M_APPEND        open mailbox for appending
    1166   *             M_READONLY      open mailbox in read-only mode
    1167   *             M_QUIET         only print error messages
    1168 + *             M_PEEK          revert atime where applicable
    1169   *     ctx     if non-null, context struct to use
    1170   */
    1171  CONTEXT *mx_open_mailbox (const char *path, int flags, CONTEXT *pctx)
    1172 @@ -602,6 +603,8 @@
    1173      ctx->quiet = 1;
    1174    if (flags & M_READONLY)
    1175      ctx->readonly = 1;
    1176 +  if (flags & M_PEEK)
    1177 +    ctx->peekonly = 1;
    1178  
    1179    if (flags & (M_APPEND|M_NEWFOLDER))
    1180    {
    1181 @@ -701,13 +704,26 @@
    1182  void mx_fastclose_mailbox (CONTEXT *ctx)
    1183  {
    1184    int i;
    1185 +#ifndef BUFFY_SIZE
    1186 +  struct utimbuf ut;
    1187 +#endif
    1188  
    1189    if(!ctx)
    1190      return;
    1191 +#ifndef BUFFY_SIZE
    1192 +  /* fix up the times so buffy won't get confused */
    1193 +  if (ctx->peekonly && ctx->path && ctx->mtime > ctx->atime)
    1194 +  {
    1195 +    ut.actime = ctx->atime;
    1196 +    ut.modtime = ctx->mtime;
    1197 +    utime (ctx->path, &ut);
    1198 +  }
    1199 +#endif
    1200  
    1201    /* never announce that a mailbox we've just left has new mail. #3290
    1202     * XXX: really belongs in mx_close_mailbox, but this is a nice hook point */
    1203 -  mutt_buffy_setnotified(ctx->path);
    1204 +  if(!ctx->peekonly)
    1205 +    mutt_buffy_setnotified(ctx->path);
    1206  
    1207    if (ctx->mx_close)
    1208      ctx->mx_close (ctx);
    1209 @@ -719,6 +735,8 @@
    1210    mutt_clear_threads (ctx);
    1211    for (i = 0; i < ctx->msgcount; i++)
    1212      mutt_free_header (&ctx->hdrs[i]);
    1213 +  ctx->msgcount -= ctx->deleted;
    1214 +  set_buffystats(ctx);
    1215    FREE (&ctx->hdrs);
    1216    FREE (&ctx->v2r);
    1217    FREE (&ctx->path);
    1218 @@ -812,6 +830,10 @@
    1219      if (!ctx->hdrs[i]->deleted && ctx->hdrs[i]->read
    1220          && !(ctx->hdrs[i]->flagged && option (OPTKEEPFLAGGED)))
    1221        read_msgs++;
    1222 +    if (ctx->hdrs[i]->deleted && !ctx->hdrs[i]->read)
    1223 +      ctx->unread--;
    1224 +    if (ctx->hdrs[i]->deleted && ctx->hdrs[i]->flagged)
    1225 +      ctx->flagged--;
    1226    }
    1227  
    1228    if (read_msgs && quadoption (OPT_MOVE) != M_NO)
    1229 diff -ruN mutt-1.6.0.orig/mx.h mutt-1.6.0/mx.h
    1230 --- mutt-1.6.0.orig/mx.h        2016-04-02 20:12:22.000000000 +0200
    1231 +++ mutt-1.6.0/mx.h     2016-04-08 20:19:20.000000000 +0200
    1232 @@ -57,6 +57,7 @@
    1233  int mh_read_dir (CONTEXT *, const char *);
    1234  int mh_sync_mailbox (CONTEXT *, int *);
    1235  int mh_check_mailbox (CONTEXT *, int *);
    1236 +void mh_buffy_update (const char *, int *, int *, int *, time_t *);
    1237  int mh_check_empty (const char *);
    1238  
    1239  int maildir_read_dir (CONTEXT *);
    1240 diff -ruN mutt-1.6.0.orig/pager.c mutt-1.6.0/pager.c
    1241 --- mutt-1.6.0.orig/pager.c     2016-04-02 20:12:22.000000000 +0200
    1242 +++ mutt-1.6.0/pager.c  2016-04-08 20:19:20.000000000 +0200
    1243 @@ -29,6 +29,7 @@
    1244  #include "pager.h"
    1245  #include "attach.h"
    1246  #include "mbyte.h"
    1247 +#include "sidebar.h"
    1248  
    1249  #include "mutt_crypt.h"
    1250  
    1251 @@ -1096,6 +1097,7 @@
    1252    wchar_t wc;
    1253    mbstate_t mbstate;
    1254    int wrap_cols = mutt_term_width ((flags & M_PAGER_NOWRAP) ? 0 : Wrap);
    1255 +  wrap_cols -= SidebarWidth;
    1256  
    1257    if (check_attachment_marker ((char *)buf) == 0)
    1258      wrap_cols = COLS;
    1259 @@ -1573,6 +1575,7 @@
    1260  
    1261    int bodyoffset = 1;                  /* offset of first line of real text */
    1262    int statusoffset = 0;                /* offset for the status bar */
    1263 +  int statuswidth;
    1264    int helpoffset = LINES - 2;          /* offset for the help bar. */
    1265    int bodylen = LINES - 2 - bodyoffset; /* length of displayable area */
    1266  
    1267 @@ -1747,7 +1750,7 @@
    1268      if ((redraw & REDRAW_BODY) || topline != oldtopline)
    1269      {
    1270        do {
    1271 -       move (bodyoffset, 0);
    1272 +       move (bodyoffset, SidebarWidth);
    1273         curline = oldtopline = topline;
    1274         lines = 0;
    1275         force_redraw = 0;
    1276 @@ -1760,6 +1763,7 @@
    1277                             &QuoteList, &q_level, &force_redraw, &SearchRE) > 0)
    1278             lines++;
    1279           curline++;
    1280 +         move(lines + bodyoffset, SidebarWidth);
    1281         }
    1282         last_offset = lineInfo[curline].offset;
    1283        } while (force_redraw);
    1284 @@ -1772,6 +1776,7 @@
    1285           addch ('~');
    1286         addch ('\n');
    1287         lines++;
    1288 +       move(lines + bodyoffset, SidebarWidth);
    1289        }
    1290        NORMAL_COLOR;
    1291  
    1292 @@ -1789,29 +1794,39 @@
    1293        hfi.ctx = Context;
    1294        hfi.pager_progress = pager_progress_str;
    1295  
    1296 +      statuswidth = COLS - (option(OPTSTATUSONTOP) && PagerIndexLines > 0 ? SidebarWidth : 0);
    1297 +
    1298        if (last_pos < sb.st_size - 1)
    1299         snprintf(pager_progress_str, sizeof(pager_progress_str), OFF_T_FMT "%%", (100 * last_offset / sb.st_size));
    1300        else
    1301         strfcpy(pager_progress_str, (topline == 0) ? "all" : "end", sizeof(pager_progress_str));
    1302  
    1303        /* print out the pager status bar */
    1304 -      move (statusoffset, 0);
    1305 +      move (statusoffset, SidebarWidth);
    1306        SETCOLOR (MT_COLOR_STATUS);
    1307 +      if(option(OPTSTATUSONTOP) && PagerIndexLines > 0) {
    1308 +          CLEARLINE_WIN (statusoffset);
    1309 +      } else {
    1310 +          CLEARLINE (statusoffset);
    1311 +          DrawFullLine = 1; /* for mutt_make_string_info */
    1312 +      }
    1313  
    1314        if (IsHeader (extra) || IsMsgAttach (extra))
    1315        {
    1316 -       size_t l1 = COLS * MB_LEN_MAX;
    1317 +       size_t l1 = statuswidth * MB_LEN_MAX;
    1318         size_t l2 = sizeof (buffer);
    1319         hfi.hdr = (IsHeader (extra)) ? extra->hdr : extra->bdy->hdr;
    1320         mutt_make_string_info (buffer, l1 < l2 ? l1 : l2, NONULL (PagerFmt), &hfi, M_FORMAT_MAKEPRINT);
    1321 -       mutt_paddstr (COLS, buffer);
    1322 +       mutt_paddstr (statuswidth, buffer);
    1323        }
    1324        else
    1325        {
    1326         char bn[STRING];
    1327         snprintf (bn, sizeof (bn), "%s (%s)", banner, pager_progress_str);
    1328 -       mutt_paddstr (COLS, bn);
    1329 +       mutt_paddstr (statuswidth, bn);
    1330        }
    1331 +      if(!option(OPTSTATUSONTOP) || PagerIndexLines == 0)
    1332 +          DrawFullLine = 0; /* reset */
    1333        NORMAL_COLOR;
    1334        if (option(OPTTSENABLED) && TSSupported)
    1335        {
    1336 @@ -1827,16 +1842,22 @@
    1337        /* redraw the pager_index indicator, because the
    1338         * flags for this message might have changed. */
    1339        menu_redraw_current (index);
    1340 +      draw_sidebar(MENU_PAGER);
    1341  
    1342        /* print out the index status bar */
    1343        menu_status_line (buffer, sizeof (buffer), index, NONULL(Status));
    1344  
    1345 -      move (indexoffset + (option (OPTSTATUSONTOP) ? 0 : (indexlen - 1)), 0);
    1346 +      move (indexoffset + (option (OPTSTATUSONTOP) ? 0 : (indexlen - 1)),
    1347 +          (option(OPTSTATUSONTOP) ? 0: SidebarWidth));
    1348        SETCOLOR (MT_COLOR_STATUS);
    1349 -      mutt_paddstr (COLS, buffer);
    1350 +      mutt_paddstr (COLS - (option(OPTSTATUSONTOP) ? 0 : SidebarWidth), buffer);
    1351        NORMAL_COLOR;
    1352      }
    1353  
    1354 +    /* if we're not using the index, update every time */
    1355 +    if ( index == 0 )
    1356 +      draw_sidebar(MENU_PAGER);
    1357 +
    1358      redraw = 0;
    1359  
    1360      if (option(OPTBRAILLEFRIENDLY)) {
    1361 @@ -2777,6 +2798,13 @@
    1362         mutt_what_key ();
    1363         break;
    1364  
    1365 +      case OP_SIDEBAR_SCROLL_UP:
    1366 +      case OP_SIDEBAR_SCROLL_DOWN:
    1367 +      case OP_SIDEBAR_NEXT:
    1368 +      case OP_SIDEBAR_PREV:
    1369 +       scroll_sidebar(ch, MENU_PAGER);
    1370 +       break;
    1371 +
    1372        default:
    1373         ch = -1;
    1374         break;
    1375 diff -ruN mutt-1.6.0.orig/pattern.c mutt-1.6.0/pattern.c
    1376 --- mutt-1.6.0.orig/pattern.c   2016-04-02 20:12:22.000000000 +0200
    1377 +++ mutt-1.6.0/pattern.c        2016-04-08 20:19:20.000000000 +0200
    1378 @@ -154,6 +154,10 @@
    1379    HEADER *h = ctx->hdrs[msgno];
    1380    char *buf;
    1381    size_t blen;
    1382 +#ifdef HAVE_FMEMOPEN
    1383 +  char *temp;
    1384 +  size_t tempsize;
    1385 +#endif
    1386  
    1387    if ((msg = mx_open_message (ctx, msgno)) != NULL)
    1388    {
    1389 @@ -163,12 +167,20 @@
    1390        memset (&s, 0, sizeof (s));
    1391        s.fpin = msg->fp;
    1392        s.flags = M_CHARCONV;
    1393 +#ifdef HAVE_FMEMOPEN
    1394 +      if((s.fpout = open_memstream(&temp, &tempsize)) == NULL)
    1395 +      {
    1396 +       mutt_perror ("Error opening memstream");
    1397 +       return (0);
    1398 +      }
    1399 +#else
    1400        mutt_mktemp (tempfile, sizeof (tempfile));
    1401        if ((s.fpout = safe_fopen (tempfile, "w+")) == NULL)
    1402        {
    1403         mutt_perror (tempfile);
    1404         return (0);
    1405        }
    1406 +#endif
    1407  
    1408        if (pat->op != M_BODY)
    1409         mutt_copy_header (msg->fp, h, s.fpout, CH_FROM | CH_DECODE, NULL);
    1410 @@ -184,7 +196,11 @@
    1411           if (s.fpout)
    1412           {
    1413             safe_fclose (&s.fpout);
    1414 +#ifdef HAVE_FMEMOPEN
    1415 +            FREE(&temp);
    1416 +#else
    1417             unlink (tempfile);
    1418 +#endif
    1419           }
    1420           return (0);
    1421         }
    1422 @@ -193,11 +209,28 @@
    1423         mutt_body_handler (h->content, &s);
    1424        }
    1425  
    1426 +#ifdef HAVE_FMEMOPEN
    1427 +      fclose(s.fpout);
    1428 +      lng = tempsize;
    1429 +
    1430 +      if(tempsize) {
    1431 +          if ((fp = fmemopen(temp, tempsize, "r")) == NULL) {
    1432 +            mutt_perror ("Error re-opening memstream");
    1433 +            return (0);
    1434 +          }
    1435 +      } else { /* fmemopen cannot handle empty buffers */
    1436 +          if ((fp = safe_fopen ("/dev/null", "r")) == NULL) {
    1437 +            mutt_perror ("Error opening /dev/null");
    1438 +            return (0);
    1439 +          }
    1440 +      }
    1441 +#else
    1442        fp = s.fpout;
    1443        fflush (fp);
    1444        fseek (fp, 0, 0);
    1445        fstat (fileno (fp), &st);
    1446        lng = (long) st.st_size;
    1447 +#endif
    1448      }
    1449      else
    1450      {
    1451 @@ -244,7 +277,12 @@
    1452      if (option (OPTTHOROUGHSRC))
    1453      {
    1454        safe_fclose (&fp);
    1455 +#ifdef HAVE_FMEMOPEN
    1456 +      if(tempsize)
    1457 +          FREE (&temp);
    1458 +#else
    1459        unlink (tempfile);
    1460 +#endif
    1461      }
    1462    }
    1463  
    1464 diff -ruN mutt-1.6.0.orig/protos.h mutt-1.6.0/protos.h
    1465 --- mutt-1.6.0.orig/protos.h    2016-04-02 20:12:22.000000000 +0200
    1466 +++ mutt-1.6.0/protos.h 2016-04-08 20:19:20.000000000 +0200
    1467 @@ -36,6 +36,13 @@
    1468    const char *pager_progress;
    1469  };
    1470  
    1471 +struct sidebar_entry {
    1472 +    char                box[SHORT_STRING];
    1473 +    unsigned int        size;
    1474 +    unsigned int        new;
    1475 +    unsigned int        flagged;
    1476 +};
    1477 +
    1478  void mutt_make_string_info (char *, size_t, const char *, struct hdr_format_info *, format_flag);
    1479  
    1480  int mutt_extract_token (BUFFER *, BUFFER *, int);
    1481 diff -ruN mutt-1.6.0.orig/sidebar.c mutt-1.6.0/sidebar.c
    1482 --- mutt-1.6.0.orig/sidebar.c   1970-01-01 01:00:00.000000000 +0100
    1483 +++ mutt-1.6.0/sidebar.c        2016-04-08 20:19:20.000000000 +0200
    1484 @@ -0,0 +1,410 @@
    1485 +/*
    1486 + * Copyright (C) ????-2004 Justin Hibbits <jrh29@po.cwru.edu>
    1487 + * Copyright (C) 2004 Thomer M. Gil <mutt@thomer.com>
    1488 + *
    1489 + *     This program is free software; you can redistribute it and/or modify
    1490 + *     it under the terms of the GNU General Public License as published by
    1491 + *     the Free Software Foundation; either version 2 of the License, or
    1492 + *     (at your option) any later version.
    1493 + *
    1494 + *     This program is distributed in the hope that it will be useful,
    1495 + *     but WITHOUT ANY WARRANTY; without even the implied warranty of
    1496 + *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    1497 + *     GNU General Public License for more details.
    1498 + *
    1499 + *     You should have received a copy of the GNU General Public License
    1500 + *     along with this program; if not, write to the Free Software
    1501 + *     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
    1502 + */
    1503 +
    1504 +
    1505 +#if HAVE_CONFIG_H
    1506 +# include "config.h"
    1507 +#endif
    1508 +
    1509 +#include "mutt.h"
    1510 +#include "mutt_menu.h"
    1511 +#include "mutt_curses.h"
    1512 +#include "sidebar.h"
    1513 +#include "buffy.h"
    1514 +#include <libgen.h>
    1515 +#include "keymap.h"
    1516 +#include <stdbool.h>
    1517 +
    1518 +/*BUFFY *CurBuffy = 0;*/
    1519 +static BUFFY *TopBuffy = 0;
    1520 +static BUFFY *BottomBuffy = 0;
    1521 +static int known_lines = 0;
    1522 +
    1523 +void calc_boundaries() {
    1524 +
    1525 +    BUFFY *tmp = Incoming;
    1526 +
    1527 +       int count = LINES - 2 - (option(OPTHELP) ? 1 : 0);
    1528 +
    1529 +       if ( known_lines != LINES ) {
    1530 +               TopBuffy = BottomBuffy = 0;
    1531 +               known_lines = LINES;
    1532 +       }
    1533 +       for ( ; tmp->next != 0; tmp = tmp->next )
    1534 +               tmp->next->prev = tmp;
    1535 +
    1536 +       if ( TopBuffy == 0 && BottomBuffy == 0 )
    1537 +               TopBuffy = Incoming;
    1538 +       if ( BottomBuffy == 0 ) {
    1539 +               BottomBuffy = TopBuffy;
    1540 +               while ( --count && BottomBuffy->next )
    1541 +                       BottomBuffy = BottomBuffy->next;
    1542 +       }
    1543 +       else if ( TopBuffy == CurBuffy->next ) {
    1544 +               BottomBuffy = CurBuffy;
    1545 +               tmp = BottomBuffy;
    1546 +               while ( --count && tmp->prev)
    1547 +                       tmp = tmp->prev;
    1548 +               TopBuffy = tmp;
    1549 +       }
    1550 +       else if ( BottomBuffy == CurBuffy->prev ) {
    1551 +               TopBuffy = CurBuffy;
    1552 +               tmp = TopBuffy;
    1553 +               while ( --count && tmp->next )
    1554 +                       tmp = tmp->next;
    1555 +               BottomBuffy = tmp;
    1556 +       }
    1557 +}
    1558 +
    1559 +static const char *
    1560 +sidebar_format_str (char *dest,
    1561 +                       size_t destlen,
    1562 +                       size_t col,
    1563 +                       char op,
    1564 +                       const char *src,
    1565 +                       const char *prefix,
    1566 +                       const char *ifstring,
    1567 +                       const char *elsestring,
    1568 +                       unsigned long data,
    1569 +                       format_flag flags)
    1570 +{
    1571 +/* casting from unsigned long - srsly?! */
    1572 +struct sidebar_entry *sbe = (struct sidebar_entry *) data;
    1573 +unsigned int optional;
    1574 +char fmt[SHORT_STRING], buf[SHORT_STRING];
    1575 +
    1576 +optional = flags & M_FORMAT_OPTIONAL;
    1577 +
    1578 +switch(op) {
    1579 +       case 'F':
    1580 +               if(!optional) {
    1581 +                       snprintf (fmt, sizeof (fmt), "%%%sd", prefix);
    1582 +                       snprintf (dest, destlen, fmt, sbe->flagged);
    1583 +               } else if(sbe->flagged == 0) {
    1584 +                       optional = 0;
    1585 +               }
    1586 +               break;
    1587 +
    1588 +       case '!':
    1589 +               if(sbe->flagged == 0)
    1590 +                       mutt_format_s(dest, destlen, prefix, "");
    1591 +               if(sbe->flagged == 1)
    1592 +                       mutt_format_s(dest, destlen, prefix, "!");
    1593 +               if(sbe->flagged == 2)
    1594 +                       mutt_format_s(dest, destlen, prefix, "!!");
    1595 +               if(sbe->flagged > 2) {
    1596 +                       snprintf (buf, sizeof (buf), "%d!", sbe->flagged);
    1597 +                       mutt_format_s(dest, destlen, prefix, buf);
    1598 +               }
    1599 +               break;
    1600 +
    1601 +       case 'S':
    1602 +                if(!optional) {
    1603 +                   snprintf (fmt, sizeof (fmt), "%%%sd", prefix);
    1604 +                   snprintf (dest, destlen, fmt, sbe->size);
    1605 +                } else if (sbe->size == 0) {
    1606 +                    optional = 0;
    1607 +                }
    1608 +               break;
    1609 +
    1610 +       case 'N':
    1611 +               if(!optional) {
    1612 +                       snprintf (fmt, sizeof (fmt), "%%%sd", prefix);
    1613 +                       snprintf (dest, destlen, fmt, sbe->new);
    1614 +               } else if(sbe->new == 0) {
    1615 +                       optional = 0;
    1616 +               }
    1617 +               break;
    1618 +
    1619 +       case 'B':
    1620 +               mutt_format_s(dest, destlen, prefix, sbe->box);
    1621 +               break;
    1622 +       }
    1623 +
    1624 +       if(optional)
    1625 +               mutt_FormatString (dest, destlen, col, ifstring, sidebar_format_str, (unsigned long) sbe, flags);
    1626 +       else if (flags & M_FORMAT_OPTIONAL)
    1627 +               mutt_FormatString (dest, destlen, col, elsestring, sidebar_format_str, (unsigned long) sbe, flags);
    1628 +
    1629 +       return (src);
    1630 +}
    1631 +
    1632 +char *make_sidebar_entry(char *box, unsigned int size, unsigned int new, unsigned int flagged) {
    1633 +    static char *entry = 0;
    1634 +    struct sidebar_entry sbe;
    1635 +    int SBvisual;
    1636 +
    1637 +    SBvisual = SidebarWidth - strlen(SidebarDelim);
    1638 +    if (SBvisual < 1)
    1639 +        return NULL;
    1640 +
    1641 +    sbe.new = new;
    1642 +    sbe.flagged = flagged;
    1643 +    sbe.size = size;
    1644 +    strncpy(sbe.box, box, 31);
    1645 +
    1646 +    safe_realloc(&entry, SBvisual + 2);
    1647 +    entry[SBvisual + 1] = '\0';
    1648 +
    1649 +    mutt_FormatString (entry, SBvisual+1, 0, SidebarFormat, sidebar_format_str, (unsigned long) &sbe, 0);
    1650 +
    1651 +    return entry;
    1652 +}
    1653 +
    1654 +void set_curbuffy(char buf[LONG_STRING])
    1655 +{
    1656 +  BUFFY* tmp = CurBuffy = Incoming;
    1657 +
    1658 +  if (!Incoming)
    1659 +    return;
    1660 +
    1661 +  while(1) {
    1662 +    if(!strcmp(tmp->path, buf) || !strcmp(tmp->realpath, buf)) {
    1663 +      CurBuffy = tmp;
    1664 +      break;
    1665 +    }
    1666 +
    1667 +    if(tmp->next)
    1668 +      tmp = tmp->next;
    1669 +    else
    1670 +      break;
    1671 +  }
    1672 +}
    1673 +
    1674 +int draw_sidebar(int menu) {
    1675 +
    1676 +       BUFFY *tmp;
    1677 +#ifndef USE_SLANG_CURSES
    1678 +        attr_t attrs;
    1679 +#endif
    1680 +        short delim_len = strlen(SidebarDelim);
    1681 +        short color_pair;
    1682 +
    1683 +        static bool initialized = false;
    1684 +        static int prev_show_value;
    1685 +        static short saveSidebarWidth;
    1686 +        int lines = 0;
    1687 +        int SidebarHeight;
    1688 +       
    1689 +        if(option(OPTSTATUSONTOP) || option(OPTHELP))
    1690 +                lines++; /* either one will occupy the first line */
    1691 +
    1692 +        /* initialize first time */
    1693 +        if(!initialized) {
    1694 +                prev_show_value = option(OPTSIDEBAR);
    1695 +                saveSidebarWidth = SidebarWidth;
    1696 +                if(!option(OPTSIDEBAR)) SidebarWidth = 0;
    1697 +                initialized = true;
    1698 +        }
    1699 +
    1700 +        /* save or restore the value SidebarWidth */
    1701 +        if(prev_show_value != option(OPTSIDEBAR)) {
    1702 +                if(prev_show_value && !option(OPTSIDEBAR)) {
    1703 +                        saveSidebarWidth = SidebarWidth;
    1704 +                        SidebarWidth = 0;
    1705 +                } else if(!prev_show_value && option(OPTSIDEBAR)) {
    1706 +                        mutt_buffy_check(1); /* we probably have bad or no numbers */
    1707 +                        SidebarWidth = saveSidebarWidth;
    1708 +                }
    1709 +                prev_show_value = option(OPTSIDEBAR);
    1710 +        }
    1711 +
    1712 +
    1713 +/*     if ( SidebarWidth == 0 ) return 0; */
    1714 +       if (SidebarWidth > 0 && option (OPTSIDEBAR)
    1715 +           && delim_len >= SidebarWidth) {
    1716 +         unset_option (OPTSIDEBAR);
    1717 +         /* saveSidebarWidth = SidebarWidth; */
    1718 +         if (saveSidebarWidth > delim_len) {
    1719 +           SidebarWidth = saveSidebarWidth;
    1720 +           mutt_error (_("Value for sidebar_delim is too long. Disabling sidebar."));
    1721 +           sleep (2);
    1722 +         } else {
    1723 +           SidebarWidth = 0;
    1724 +           mutt_error (_("Value for sidebar_delim is too long. Disabling sidebar. Please set your sidebar_width to a sane value."));
    1725 +           sleep (4); /* the advise to set a sane value should be seen long enough */
    1726 +         }
    1727 +         saveSidebarWidth = 0;
    1728 +         return (0);
    1729 +       }
    1730 +
    1731 +    if ( SidebarWidth == 0 || !option(OPTSIDEBAR)) {
    1732 +      if (SidebarWidth > 0) {
    1733 +        saveSidebarWidth = SidebarWidth;
    1734 +        SidebarWidth = 0;
    1735 +      }
    1736 +      unset_option(OPTSIDEBAR);
    1737 +      return 0;
    1738 +    }
    1739 +
    1740 +        /* get attributes for divider */
    1741 +       SETCOLOR(MT_COLOR_STATUS);
    1742 +#ifndef USE_SLANG_CURSES
    1743 +        attr_get(&attrs, &color_pair, 0);
    1744 +#else
    1745 +        color_pair = attr_get();
    1746 +#endif
    1747 +       SETCOLOR(MT_COLOR_NORMAL);
    1748 +
    1749 +       /* draw the divider */
    1750 +
    1751 +       SidebarHeight =  LINES - 1;
    1752 +       if(option(OPTHELP) || !option(OPTSTATUSONTOP))
    1753 +               SidebarHeight--;
    1754 +
    1755 +       for ( ; lines < SidebarHeight; lines++ ) {
    1756 +               move(lines, SidebarWidth - delim_len);
    1757 +               addstr(NONULL(SidebarDelim));
    1758 +#ifndef USE_SLANG_CURSES
    1759 +                mvchgat(lines, SidebarWidth - delim_len, delim_len, 0, color_pair, NULL);
    1760 +#endif
    1761 +       }
    1762 +
    1763 +       if ( Incoming == 0 ) return 0;
    1764 +        lines = 0;
    1765 +        if(option(OPTSTATUSONTOP) || option(OPTHELP))
    1766 +                lines++; /* either one will occupy the first line */
    1767 +
    1768 +       if ( known_lines != LINES || TopBuffy == 0 || BottomBuffy == 0 )
    1769 +               calc_boundaries(menu);
    1770 +       if ( CurBuffy == 0 ) CurBuffy = Incoming;
    1771 +
    1772 +       tmp = TopBuffy;
    1773 +
    1774 +       SETCOLOR(MT_COLOR_NORMAL);
    1775 +
    1776 +       for ( ; tmp && lines < SidebarHeight; tmp = tmp->next ) {
    1777 +               if ( tmp == CurBuffy )
    1778 +                       SETCOLOR(MT_COLOR_INDICATOR);
    1779 +               else if ( tmp->msg_unread > 0 )
    1780 +                       SETCOLOR(MT_COLOR_NEW);
    1781 +               else if ( tmp->msg_flagged > 0 )
    1782 +                       SETCOLOR(MT_COLOR_FLAGGED);
    1783 +               else
    1784 +                       SETCOLOR(MT_COLOR_NORMAL);
    1785 +
    1786 +               move( lines, 0 );
    1787 +               if ( Context && Context->path &&
    1788 +                        (!strcmp(tmp->path, Context->path)||
    1789 +                        !strcmp(tmp->realpath, Context->path)) ) {
    1790 +                       tmp->msg_unread = Context->unread;
    1791 +                       tmp->msgcount = Context->msgcount;
    1792 +                       tmp->msg_flagged = Context->flagged;
    1793 +               }
    1794 +               /* check whether Maildir is a prefix of the current folder's path */
    1795 +               short maildir_is_prefix = 0;
    1796 +               if ( (strlen(tmp->path) > strlen(Maildir)) &&
    1797 +                       (strncmp(Maildir, tmp->path, strlen(Maildir)) == 0) )
    1798 +                       maildir_is_prefix = 1;
    1799 +               /* calculate depth of current folder and generate its display name with indented spaces */
    1800 +               int sidebar_folder_depth = 0;
    1801 +               char *sidebar_folder_name;
    1802 +               sidebar_folder_name = option(OPTSIDEBARSHORTPATH) ? mutt_basename(tmp->path) : tmp->path + maildir_is_prefix*(strlen(Maildir) + 1);
    1803 +               if ( maildir_is_prefix && option(OPTSIDEBARFOLDERINDENT) ) {
    1804 +                       char *tmp_folder_name;
    1805 +                       int i;
    1806 +                       tmp_folder_name = tmp->path + strlen(Maildir) + 1;
    1807 +                       for (i = 0; i < strlen(tmp->path) - strlen(Maildir); i++) {
    1808 +                               if (tmp_folder_name[i] == '/'  || tmp_folder_name[i] == '.') sidebar_folder_depth++;
    1809 +                       }   
    1810 +                       if (sidebar_folder_depth > 0) {
    1811 +                               if (option(OPTSIDEBARSHORTPATH)) {
    1812 +                                       tmp_folder_name = strrchr(tmp->path, '.');
    1813 +                                       if (tmp_folder_name == NULL)
    1814 +                                               tmp_folder_name = mutt_basename(tmp->path);
    1815 +                                       else
    1816 +                                               tmp_folder_name++;
    1817 +                               }
    1818 +                               else
    1819 +                                       tmp_folder_name = tmp->path + strlen(Maildir) + 1;
    1820 +                               sidebar_folder_name = malloc(strlen(tmp_folder_name) + sidebar_folder_depth*strlen(NONULL(SidebarIndentStr)) + 1);
    1821 +                               sidebar_folder_name[0]=0;
    1822 +                               for (i=0; i < sidebar_folder_depth; i++)
    1823 +                                       strncat(sidebar_folder_name, NONULL(SidebarIndentStr), strlen(NONULL(SidebarIndentStr)));
    1824 +                               strncat(sidebar_folder_name, tmp_folder_name, strlen(tmp_folder_name));
    1825 +                       }
    1826 +               }
    1827 +               printw( "%.*s", SidebarWidth - delim_len + 1,
    1828 +                       make_sidebar_entry(sidebar_folder_name, tmp->msgcount,
    1829 +                       tmp->msg_unread, tmp->msg_flagged));
    1830 +               if (sidebar_folder_depth > 0)
    1831 +                       free(sidebar_folder_name);
    1832 +               lines++;
    1833 +       }
    1834 +       SETCOLOR(MT_COLOR_NORMAL);
    1835 +       for ( ; lines < SidebarHeight; lines++ ) {
    1836 +               int i = 0;
    1837 +               move( lines, 0 );
    1838 +               for ( ; i < SidebarWidth - delim_len; i++ )
    1839 +                       addch(' ');
    1840 +       }
    1841 +       return 0;
    1842 +}
    1843 +
    1844 +
    1845 +void set_buffystats(CONTEXT* Context)
    1846 +{
    1847 +        BUFFY *tmp = Incoming;
    1848 +        while(tmp) {
    1849 +                if(Context && (!strcmp(tmp->path, Context->path) ||
    1850 +                               !strcmp(tmp->realpath, Context->path))) {
    1851 +                       tmp->msg_unread = Context->unread;
    1852 +                       tmp->msgcount = Context->msgcount;
    1853 +                       tmp->msg_flagged = Context->flagged;
    1854 +                        break;
    1855 +                }
    1856 +                tmp = tmp->next;
    1857 +        }
    1858 +}
    1859 +
    1860 +void scroll_sidebar(int op, int menu)
    1861 +{
    1862 +        if(!SidebarWidth) return;
    1863 +        if(!CurBuffy) return;
    1864 +
    1865 +       switch (op) {
    1866 +               case OP_SIDEBAR_NEXT:
    1867 +                       if ( CurBuffy->next == NULL ) return;
    1868 +                       CurBuffy = CurBuffy->next;
    1869 +                       break;
    1870 +               case OP_SIDEBAR_PREV:
    1871 +                       if ( CurBuffy->prev == NULL ) return;
    1872 +                       CurBuffy = CurBuffy->prev;
    1873 +                       break;
    1874 +               case OP_SIDEBAR_SCROLL_UP:
    1875 +                       CurBuffy = TopBuffy;
    1876 +                       if ( CurBuffy != Incoming ) {
    1877 +                               calc_boundaries(menu);
    1878 +                               CurBuffy = CurBuffy->prev;
    1879 +                       }
    1880 +                       break;
    1881 +               case OP_SIDEBAR_SCROLL_DOWN:
    1882 +                       CurBuffy = BottomBuffy;
    1883 +                       if ( CurBuffy->next ) {
    1884 +                               calc_boundaries(menu);
    1885 +                               CurBuffy = CurBuffy->next;
    1886 +                       }
    1887 +                       break;
    1888 +               default:
    1889 +                       return;
    1890 +       }
    1891 +       calc_boundaries(menu);
    1892 +       draw_sidebar(menu);
    1893 +}
    1894 +
    1895 diff -ruN mutt-1.6.0.orig/sidebar.h mutt-1.6.0/sidebar.h
    1896 --- mutt-1.6.0.orig/sidebar.h   1970-01-01 01:00:00.000000000 +0100
    1897 +++ mutt-1.6.0/sidebar.h        2016-04-08 20:19:20.000000000 +0200
    1898 @@ -0,0 +1,36 @@
    1899 +/*
    1900 + * Copyright (C) ????-2004 Justin Hibbits <jrh29@po.cwru.edu>
    1901 + * Copyright (C) 2004 Thomer M. Gil <mutt@thomer.com>
    1902 + *
    1903 + *     This program is free software; you can redistribute it and/or modify
    1904 + *     it under the terms of the GNU General Public License as published by
    1905 + *     the Free Software Foundation; either version 2 of the License, or
    1906 + *     (at your option) any later version.
    1907 + *
    1908 + *     This program is distributed in the hope that it will be useful,
    1909 + *     but WITHOUT ANY WARRANTY; without even the implied warranty of
    1910 + *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    1911 + *     GNU General Public License for more details.
    1912 + *
    1913 + *     You should have received a copy of the GNU General Public License
    1914 + *     along with this program; if not, write to the Free Software
    1915 + *     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
    1916 + */
    1917 +
    1918 +#ifndef SIDEBAR_H
    1919 +#define SIDEBAR_H
    1920 +
    1921 +struct MBOX_LIST {
    1922 +       char *path;
    1923 +       int msgcount;
    1924 +       int new;
    1925 +} MBLIST;
    1926 +
    1927 +/* parameter is whether or not to go to the status line */
    1928 +/* used for omitting the last | that covers up the status bar in the index */
    1929 +int draw_sidebar(int);
    1930 +void scroll_sidebar(int, int);
    1931 +void set_curbuffy(char*);
    1932 +void set_buffystats(CONTEXT*);
    1933 +
    1934 +#endif /* SIDEBAR_H */
  • deleted file mail/mutt/files/patch-thunderbird-fix.diff

    diff --git a/mail/mutt/files/patch-thunderbird-fix.diff b/mail/mutt/files/patch-thunderbird-fix.diff
    deleted file mode 100644
    + -  
    1 Upstream-Status: Submitted [http://dev.mutt.org/trac/ticket/3285]
    2 --- a/crypt.c   2009-01-05 11:20:53.000000000 -0800
    3 +++ b/crypt.c   2009-06-29 16:55:12.000000000 -0700
    4 @@ -393,7 +393,14 @@
    5         */
    6        if (!ascii_strcasecmp (m->description, "S/MIME Encrypted Message"))
    7         return SMIMEENCRYPT;
    8 -      complain = 1;
    9 +
    10 +      /* Thunderbird 2.0.0.19 doesn't seem to be adding a Content-Description
    11 +       * If we make it all the way here, we know it's not signed as Thunderbird
    12 +       * sets the signed-data correctly, so we're going to assuming it's
    13 +       * encrypted
    14 +       */
    15 +
    16 +      return SMIMEENCRYPT;
    17      }
    18      else if (ascii_strcasecmp (m->subtype, "octet-stream"))
    19        return 0;