Index: mutt/ChangeLog diff -u mutt/ChangeLog:3.188 mutt/ChangeLog:3.231 --- mutt/ChangeLog:3.188 Wed Nov 5 21:09:35 2003 +++ mutt/ChangeLog Sun Feb 1 19:01:19 2004 @@ -1,3 +1,209 @@ +2004-02-01 18:00:16 Mike Schiraldi <1074468571@schiraldi.org> (roessler) + + * init.c: As you all know, running "mutt -F foo.rc" will have + mutt read foo.rc as its config file. However, there is a bug -- + if you specify a directory (like accidentally typing "mutt -F + /etc/mutt") mutt will silently ignore the flag and leave you + wondering why it isn't working. + + Emil Sit posted a patch for this in March of 2002, but it seems + to have slipped through the cracks. Here's the patch again; + please consider it for inclusion. + +2004-02-01 17:50:43 Luke Mewburn (roessler) + + * buffy.c: Put a zero byte into the string, not into the pointer. + +2004-02-01 17:48:25 Dan Ohnesorg (roessler) + + * po/cs.po: update + +2004-02-01 17:45:33 Thomas Roessler (roessler) + + * doc/manual.sgml.head: A cross-reference was missing. + + * doc/manual.sgml.head: Improve documentation of alterantes. + + * alias.c, doc/manual.sgml.head, doc/muttrc.man.head, globals.h, + hdrline.c, init.c, init.h, mutt.h, mutt_regex.h, muttlib.c, + protos.h: Turn alternates, lists, and subscribe into regular + expression lists. + +2004-01-12 22:56:58 Christoph Ludwig (roessler) + + * smime_keys.pl: Avoid a Perl warning. + +2004-01-12 20:24:09 Matt Kraai (roessler) + + * doc/manual.sgml.head: A newline was missing from the + documentation; #1754. (The actual commit message for this + change is garbage; wrong window.) + +2004-01-12 19:59:38 Thomas Roessler (roessler) + + * crypt.c: Retainable PGP signatures were broken badly. #1757. + +2004-01-05 11:55:14 Robert Schiele (roessler) + + * mutt_sasl.c: Back out part of the previous SASL/IPv6 patch + due to portability issues. + +2004-01-04 10:55:20 Ren Clerc (roessler) + + * init.h: Fix hide_missing / hide_limited documentation. + +2004-01-04 10:51:49 Thomas Roessler (roessler) + + * hdrline.c: Permit list patterns that match the domain name of + an address; these patterns begin with '@'. Example: subscribe + @bugs.guug.de matches all messages sent to the bug tracking + system. + +2004-01-04 10:30:52 Thomas Roessler (roessler) + + * po/ru.po: Argh, I shouldn't replace files by patches. + +2004-01-04 10:25:13 Cameron Patrick (roessler) + + * menu.c: Fix #1697 (Debian #219594.) + +2004-01-04 10:21:19 Roland Rosenfeld (roessler) + + * po/de.po: update + +2004-01-04 10:19:45 TAKAHASHI Tamotsu (roessler) + + * po/ja.po: update + +2004-01-04 10:08:02 Pawel Dziekonski (roessler) + + * po/pl.po: update + +2004-01-04 10:03:46 Michael Elkins (roessler) + + * send.c: Fix #1488 (Debian#1882526): Honor Reply-To while + generating Mail-Followup-To headers. + +2004-01-04 09:59:42 Thomas Roessler (roessler) + + * init.h: Fix #1738; documentation issue re $from, $use_from. + +2004-01-04 09:52:55 Michael Elkins (roessler) + + * hook.c, send.c: Fix #1724, cannot use ~h pattern match with + reply-hook. + +2004-01-04 09:49:23 Vsevolod Volkov (roessler) + + * pop.h, pop_lib.c: Attached patch provides support of STLS + (STARTTLS) command in POP3 protocol. + + * po/ru.po: update + +2004-01-04 09:45:05 Brendan Cully (roessler) + + * imap/imap.c: Fix #1703. + +2004-01-04 09:42:35 Thomas Roessler (roessler) + + * smime.c: Fix a NULL pointer deference noted by Will Fiveash + . + +2003-12-30 13:04:20 Thomas Roessler (roessler) + + * commands.c, crypt.c, mutt.h, mutt_crypt.h, smime.c: Handle + partially signed messages more reasonably. See #1743. + +2003-12-29 11:44:35 Alain Bench (roessler) + + * commands.c: Fix #844. + +2003-12-29 11:37:41 Patrick Welche (roessler) + + * m4/gssapi.m4, mutt_sasl.c: A while ago I posted a similar + patch which is necessary as when mutt tries to connect to an + imap server over ipv6 it stores the address in a sockaddr which + may not be large enough to hold the ipv6 address. + +2003-12-17 17:42:02 Scott Koranda (roessler) + + * crypt.c: pkcs7-signature wasn't recognized properly in one + more place. + +2003-12-17 08:46:50 Michael Elkins (roessler) + + * rfc1524.c: Fix possible core dump in mailcap nametemplate + handling. + +2003-12-10 00:48:57 Thomas Roessler (roessler) + + * thread.c: Avoid NULL pointer deference in threading code. + +2003-12-03 08:19:11 Alain Bench (roessler) + + * pager.c: Fix 1716. + +2003-11-15 09:32:30 Velko Hristov (roessler) + + * po/bg.po: updat + +2003-11-12 22:31:51 Edmund GRIMLEY EVANS (roessler) + + * po/eo.po: update + +2003-11-12 14:01:03 Ren Clerc (roessler) + + * po/nl.po: update + +2003-11-12 13:49:32 Thomas Roessler (roessler) + + * configure.in, mutt_idna.c, mutt_idna.h, mutt_socket.c: Fix + IDN API incompatibility problems. + +2003-11-12 11:47:46 duvall@emufarm.org (roessler) + + * configure.in: Fix 1515, 1693. + +2003-11-12 11:40:27 Thomas Roessler (roessler) + + * mh.c, sort.c: Fix dangling pointer problems in threading code. + Noted and tracked down by q4xk3j002@sneakemail.com who also + provided the initial fix. + + CORRECTION: q4xk3j002 (whoever that is) reported the bug, + but thr problem was tracked down and fixed by YONETANI + Tomokazu + +2003-11-11 10:19:22 Ronny Haryanto (roessler) + + * po/id.po: update + +2003-11-10 18:02:26 Rudy Taraschi (roessler) + + * mutt_socket.c: Fix double-free problems related to IDN support. + +2003-11-10 10:37:10 Vincent Lefevre (roessler) + + * po/fr.po: update + +2003-11-09 21:41:28 Thomas Roessler (roessler) + + * mh.c: Fix #1692. + +2003-11-09 09:38:32 Thomas Roessler (roessler) + + * send.c: Commit the fix for #1509. This must have been lost + earlier this year. + +2003-11-05 20:09:36 Thomas Roessler (roessler) + + * po/ja.po, po/ko.po, po/lt.po, po/nl.po, po/pl.po, po/pt_BR.po, + po/ru.po, po/sk.po, po/sv.po, po/tr.po, po/uk.po, po/zh_CN.po, + po/zh_TW.po, ChangeLog, VERSION, po/bg.po, po/ca.po, po/cs.po, + po/da.po, po/de.po, po/el.po, po/eo.po, po/es.po, po/et.po, + po/fr.po, po/gl.po, po/hu.po, po/id.po, po/it.po: automatic + post-release commit for mutt-1.5.5.1 + 2003-11-05 12:17:10 Thomas Roessler (roessler) * Makefile.am: Include regex.c and snprintf.c with the Index: mutt/VERSION diff -u mutt/VERSION:3.7 mutt/VERSION:3.8 --- mutt/VERSION:3.7 Wed Nov 5 21:09:35 2003 +++ mutt/VERSION Sun Feb 1 19:26:11 2004 @@ -1 +1 @@ -1.5.5.1 +1.5.6 Index: mutt/alias.c diff -u mutt/alias.c:3.8 mutt/alias.c:3.9 --- mutt/alias.c:3.8 Thu Jul 24 20:40:50 2003 +++ mutt/alias.c Sun Feb 1 18:10:43 2004 @@ -529,25 +529,49 @@ { /* NULL address is assumed to be the user. */ if (!addr) + { + dprint (5, (debugfile, "mail_addr_is_user: yes, NULL address\n")); return 1; + } if (!addr->mailbox) + { + dprint (5, (debugfile, "mail_addr_is_user: no, no mailbox\n")); return 0; + } if (ascii_strcasecmp (addr->mailbox, Username) == 0) + { + dprint (5, (debugfile, "mail_addr_is_user: yes, %s = %s\n", addr->mailbox, Username)); return 1; + } if (string_is_address(addr->mailbox, Username, Hostname)) + { + dprint (5, (debugfile, "mail_addr_is_user: yes, %s = %s @ %s \n", addr->mailbox, Username, Hostname)); return 1; + } if (string_is_address(addr->mailbox, Username, mutt_fqdn(0))) + { + dprint (5, (debugfile, "mail_addr_is_user: yes, %s = %s @ %s \n", addr->mailbox, Username, mutt_fqdn (0))); return 1; + } if (string_is_address(addr->mailbox, Username, mutt_fqdn(1))) + { + dprint (5, (debugfile, "mail_addr_is_user: yes, %s = %s @ %s \n", addr->mailbox, Username, mutt_fqdn (1))); return 1; + } if (From && !ascii_strcasecmp (From->mailbox, addr->mailbox)) + { + dprint (5, (debugfile, "mail_addr_is_user: yes, %s = %s\n", addr->mailbox, From->mailbox)); return 1; + } - if (Alternates.pattern && - regexec (Alternates.rx, addr->mailbox, 0, NULL, 0) == 0) + if (mutt_match_rx_list (addr->mailbox, Alternates)) + { + dprint (5, (debugfile, "mail_addr_is_user: yes, %s matched by alternates.\n", addr->mailbox)); return 1; + } + dprint (5, (debugfile, "mail_addr_is_user: no, all failed.\n")); return 0; } Index: mutt/buffy.c diff -u mutt/buffy.c:3.8 mutt/buffy.c:3.9 --- mutt/buffy.c:3.8 Tue Aug 5 15:55:47 2003 +++ mutt/buffy.c Sun Feb 1 18:50:43 2004 @@ -506,7 +506,7 @@ { case 0: - s = '\0'; + *s = '\0'; break; case 1: @@ -515,7 +515,7 @@ tmp = tmp->next; if (!tmp) { - s = '\0'; + *s = '\0'; mutt_buffy_check (1); /* buffy was wrong - resync things */ break; } @@ -541,7 +541,7 @@ } if (count >= 3) { - s = '\0'; + *s = '\0'; mutt_buffy_check (1); /* buffy was wrong - resync things */ break; } Index: mutt/commands.c diff -u mutt/commands.c:3.20 mutt/commands.c:3.22 --- mutt/commands.c:3.20 Sat Oct 4 22:34:59 2003 +++ mutt/commands.c Tue Dec 30 14:04:20 2003 @@ -183,15 +183,22 @@ else mutt_error ( _("S/MIME certificate owner does not match sender.")); } + else if (cur->security & PARTSIGN) + mutt_message (_("Warning: Part of this message has not been signed.")); else if (cur->security & SIGN || cur->security & BADSIGN) mutt_error ( _("S/MIME signature could NOT be verified.")); } if (WithCrypto && (cur->security & APPLICATION_PGP) && (cmflags & M_CM_VERIFY)) - mutt_message ((cur->security & GOODSIGN) ? - _("PGP signature successfully verified.") : - _("PGP signature could NOT be verified.")); + { + if (cur->security & GOODSIGN) + mutt_message (_("PGP signature successfully verified.")); + else if (cur->security & PARTSIGN) + mutt_message (_("Warning: Part of this message has not been signed.")); + else + mutt_message (_("PGP signature could NOT be verified.")); + } /* Invoke the builtin pager */ memset (&info, 0, sizeof (pager_t)); @@ -641,16 +648,17 @@ { *chflags = CH_XMIT | CH_MIME | CH_TXTPLAIN; *cmflags = M_CM_DECODE | M_CM_CHARCONV; - } - /* respect $weed only if decode doesn't kick in - * for decrypt. - */ + if (!decrypt) /* If decode doesn't kick in for decrypt, */ + { + *chflags |= CH_DECODE; /* then decode RFC 2047 headers, */ - if (decode && !decrypt && option (OPTWEED)) - { - *chflags |= CH_WEED; - *cmflags |= M_CM_WEED; + if (option (OPTWEED)) + { + *chflags |= CH_WEED; /* and respect $weed. */ + *cmflags |= M_CM_WEED; + } + } } } Index: mutt/configure.in diff -u mutt/configure.in:3.11 mutt/configure.in:3.13 --- mutt/configure.in:3.11 Wed Sep 3 19:12:52 2003 +++ mutt/configure.in Wed Nov 12 14:49:32 2003 @@ -638,7 +638,6 @@ AC_DEFINE(USE_SASL,1, [ Define if want to use the Cyrus SASL library for POP/IMAP authentication. ]) need_sasl=yes - need_md5=no fi ]) AM_CONDITIONAL(USE_SASL, test x$need_sasl = xyes) @@ -671,7 +670,6 @@ AC_DEFINE(USE_SASL2,1, [ Define if want to use version 2 of the Cyrus SASL library. ]) need_sasl=yes - need_md5=no fi ]) AM_CONDITIONAL(USE_SASL, test x$need_sasl = xyes) @@ -687,7 +685,12 @@ ] ) -AC_CHECK_LIB(idn, idna_to_ascii_from_utf8) +if test "x$with_idn" != "xno"; then + AC_CHECK_LIB(idn, stringprep_check_version) + AC_CHECK_FUNCS(idna_to_unicode_utf8_from_utf8 idna_to_unicode_8z8z) + AC_CHECK_FUNCS(idna_to_ascii_from_utf8 idna_to_ascii_8z) + AC_CHECK_FUNCS(idna_to_ascii_lz idna_to_ascii_from_locale) +fi if test "$need_md5" = "yes" then Index: mutt/crypt.c diff -u mutt/crypt.c:3.19 mutt/crypt.c:3.22 --- mutt/crypt.c:3.19 Fri Sep 19 15:03:25 2003 +++ mutt/crypt.c Mon Jan 12 20:59:38 2004 @@ -210,6 +210,8 @@ if ((WithCrypto & APPLICATION_SMIME)) tmp_smime_pbody = msg->content; + if ((WithCrypto & APPLICATION_PGP)) + tmp_pgp_pbody = msg->content; if (msg->security & SIGN) { @@ -267,7 +269,7 @@ if ((WithCrypto & APPLICATION_PGP) && (msg->security & APPLICATION_PGP)) { - if (!(pbody = crypt_pgp_encrypt_message (msg->content, keylist, + if (!(pbody = crypt_pgp_encrypt_message (tmp_pgp_pbody, keylist, flags & SIGN))) { @@ -275,9 +277,9 @@ if (flags != msg->security) { /* remove the outer multipart layer */ - msg->content = mutt_remove_multipart (msg->content); + tmp_pgp_pbody = mutt_remove_multipart (tmp_pgp_pbody); /* get rid of the signature */ - mutt_free_body (&msg->content->next); + mutt_free_body (&tmp_pgp_pbody->next); } return (-1); @@ -288,8 +290,8 @@ */ if (flags != msg->security) { - mutt_remove_multipart (msg->content); - mutt_free_body (&msg->content->next); + tmp_pgp_pbody = mutt_remove_multipart (tmp_pgp_pbody); + mutt_free_body (&tmp_pgp_pbody->next); } } } @@ -466,6 +468,9 @@ if (!WithCrypto) return 0; + + if (!m) + return 0; if (m->type == TYPEAPPLICATION) { @@ -491,15 +496,27 @@ t |= mutt_is_multipart_encrypted(m); t |= mutt_is_multipart_signed (m); - if (t && m->goodsig) t |= GOODSIGN; + if (t && m->goodsig) + t |= GOODSIGN; } if (m->type == TYPEMULTIPART || m->type == TYPEMESSAGE) { BODY *p; + int u, v, w; + + u = m->parts ? 0xffffffff : 0; /* Bits set in all parts */ + w = 0; /* Bits set in any part */ for (p = m->parts; p; p = p->next) - t |= crypt_query (p) & ~GOODSIGN; + { + v = crypt_query (p); + u &= v; w |= v; + } + t |= u | (w & ~GOODSIGN); + + if ((w & GOODSIGN) && !(u & GOODSIGN)) + t |= PARTSIGN; } return t; @@ -871,7 +888,8 @@ if ((WithCrypto & APPLICATION_SMIME) && signatures[i]->type == TYPEAPPLICATION - && !mutt_strcasecmp(signatures[i]->subtype, "x-pkcs7-signature")) + && (!mutt_strcasecmp(signatures[i]->subtype, "x-pkcs7-signature") + || !mutt_strcasecmp(signatures[i]->subtype, "pkcs7-signature"))) { if (crypt_smime_verify_one (signatures[i], s, tempfile) != 0) goodsig = 0; @@ -888,7 +906,7 @@ mutt_unlink (tempfile); b->goodsig = goodsig; - b->badsig = goodsig; /* XXX - WHAT!?!?!? */ + b->badsig = !goodsig; /* Now display the signed body */ state_attach_puts (_("[-- The following data is signed --]\n\n"), s); Index: mutt/globals.h diff -u mutt/globals.h:3.6 mutt/globals.h:3.7 --- mutt/globals.h:3.6 Tue Jul 15 13:41:32 2003 +++ mutt/globals.h Sun Feb 1 18:10:43 2004 @@ -121,8 +121,10 @@ WHERE LIST *Ignore INITVAL(0); WHERE LIST *MimeLookupList INITVAL(0); WHERE LIST *UnIgnore INITVAL(0); -WHERE LIST *MailLists INITVAL(0); -WHERE LIST *SubscribedLists INITVAL(0); + +WHERE RX_LIST *Alternates INITVAL(0); +WHERE RX_LIST *MailLists INITVAL(0); +WHERE RX_LIST *SubscribedLists INITVAL(0); /* bit vector for boolean variables */ #ifdef MAIN_C Index: mutt/hdrline.c diff -u mutt/hdrline.c:3.9 mutt/hdrline.c:3.11 --- mutt/hdrline.c:3.9 Mon Mar 3 15:01:06 2003 +++ mutt/hdrline.c Sun Feb 1 18:10:43 2004 @@ -28,25 +28,14 @@ #include #include -static int _mutt_is_mail_list (ADDRESS *addr, LIST *p) -{ - if (addr->mailbox) - { - for (;p; p = p->next) - if (mutt_strncasecmp (addr->mailbox, p->data, mutt_strlen (p->data)) == 0) - return 1; - } - return 0; -} - int mutt_is_mail_list (ADDRESS *addr) { - return _mutt_is_mail_list (addr, MailLists); + return mutt_match_rx_list (addr->mailbox, MailLists); } int mutt_is_subscribed_list (ADDRESS *addr) { - return _mutt_is_mail_list (addr, SubscribedLists); + return mutt_match_rx_list (addr->mailbox, SubscribedLists); } /* Search for a mailing list in the list of addresses pointed to by adr. Index: mutt/hook.c diff -u mutt/hook.c:3.7 mutt/hook.c:3.8 --- mutt/hook.c:3.7 Tue Jan 21 13:33:41 2003 +++ mutt/hook.c Sun Jan 4 10:52:55 2004 @@ -149,7 +149,7 @@ if (data & (M_SENDHOOK | M_SAVEHOOK | M_FCCHOOK | M_MESSAGEHOOK | M_REPLYHOOK)) { if ((pat = mutt_pattern_comp (pattern.data, - (data & (M_SENDHOOK | M_REPLYHOOK | M_FCCHOOK)) ? 0 : M_FULL_MSG, + (data & (M_SENDHOOK | M_FCCHOOK)) ? 0 : M_FULL_MSG, err)) == NULL) goto error; } Index: mutt/init.c diff -u mutt/init.c:3.15 mutt/init.c:3.19 --- mutt/init.c:3.15 Tue Aug 5 15:55:47 2003 +++ mutt/init.c Sun Feb 1 19:00:16 2004 @@ -320,6 +320,52 @@ } } +static int add_to_rx_list (RX_LIST **list, const char *s, int flags, BUFFER *err) +{ + RX_LIST *t, *last = NULL; + REGEXP *rx; + + if (!s || !*s) + return 0; + + if (!(rx = mutt_compile_regexp (s, flags))) + { + snprintf (err->data, err->dsize, "Bad regexp: %s\n", s); + return -1; + } + + /* check to make sure the item is not already on this list */ + for (last = *list; last; last = last->next) + { + if (ascii_strcasecmp (rx->pattern, last->rx->pattern) == 0) + { + /* already on the list, so just ignore it */ + last = NULL; + break; + } + if (!last->next) + break; + } + + if (!*list || last) + { + t = mutt_new_rx_list(); + t->rx = rx; + if (last) + { + last->next = t; + last = last->next; + } + else + *list = last = t; + } + else /* duplicate */ + mutt_free_regexp (&rx); + + return 0; +} + + static void remove_from_list (LIST **l, const char *str) { LIST *p, *last = NULL; @@ -350,6 +396,36 @@ } } +static void remove_from_rx_list (RX_LIST **l, const char *str) +{ + RX_LIST *p, *last = NULL; + + if (mutt_strcmp ("*", str) == 0) + mutt_free_rx_list (l); /* ``unCMD *'' means delete all current entries */ + else + { + p = *l; + last = NULL; + while (p) + { + if (ascii_strcasecmp (str, p->rx->pattern) == 0) + { + mutt_free_regexp (&p->rx); + if (last) + last->next = p->next; + else + (*l) = p->next; + FREE (&p); + } + else + { + last = p; + p = p->next; + } + } + } +} + static int parse_unignore (BUFFER *buf, BUFFER *s, unsigned long data, BUFFER *err) { do @@ -392,6 +468,42 @@ return 0; } +static int _parse_rx_list (BUFFER *buf, BUFFER *s, unsigned long data, BUFFER *err, int flags) +{ + do + { + mutt_extract_token (buf, s, 0); + if (add_to_rx_list ((RX_LIST **) data, buf->data, flags, err) != 0) + return -1; + + } + while (MoreArgs (s)); + + return 0; +} + +static int parse_rx_list (BUFFER *buf, BUFFER *s, unsigned long data, BUFFER *err) +{ + return _parse_rx_list (buf, s, data, err, REG_ICASE); +} + +static int parse_rx_unlist (BUFFER *buf, BUFFER *s, unsigned long data, BUFFER *err) +{ + do + { + mutt_extract_token (buf, s, 0); + if (mutt_strcmp (buf->data, "*") == 0) + { + mutt_free_rx_list ((RX_LIST **) data); + break; + } + remove_from_rx_list ((RX_LIST **) data, buf->data); + } + while (MoreArgs (s)); + + return 0; +} + static int parse_unlist (BUFFER *buf, BUFFER *s, unsigned long data, BUFFER *err) { do @@ -418,8 +530,8 @@ do { mutt_extract_token (buf, s, 0); - remove_from_list (&MailLists, buf->data); - remove_from_list (&SubscribedLists, buf->data); + remove_from_rx_list (&MailLists, buf->data); + remove_from_rx_list (&SubscribedLists, buf->data); } while (MoreArgs (s)); @@ -431,8 +543,10 @@ do { mutt_extract_token (buf, s, 0); - add_to_list (&MailLists, buf->data); - add_to_list (&SubscribedLists, buf->data); + if (add_to_rx_list (&MailLists, buf->data, REG_ICASE, err) != 0) + return -1; + if (add_to_rx_list (&SubscribedLists, buf->data, REG_ICASE, err) != 0) + return -1; } while (MoreArgs (s)); @@ -1254,6 +1368,18 @@ char *linebuf = NULL; size_t buflen; pid_t pid; + struct stat s; + + if (stat (rcfile, &s) < 0) + { + snprintf (err->data, err->dsize, _("%s: stat: %s"), rcfile, strerror (errno)); + return (-1); + } + if (!S_ISREG (s.st_mode)) + { + snprintf (err->data, err->dsize, _("%s: not a regular file"), rcfile); + return (-1); + } if ((f = mutt_open_read (rcfile, &pid)) == NULL) { Index: mutt/init.h diff -u mutt/init.h:3.40 mutt/init.h:3.43 --- mutt/init.h:3.40 Thu Sep 4 17:10:09 2003 +++ mutt/init.h Sun Feb 1 18:10:43 2004 @@ -157,13 +157,6 @@ ** message could include a line like "[-- PGP output follows ..." and ** give it the same color as your attachment color. */ - { "alternates", DT_RX, R_BOTH, UL &Alternates, 0 }, - /* - ** .pp - ** A regexp that allows you to specify \fIalternate\fP addresses where - ** you receive mail. This affects Mutt's idea about messages from you - ** and addressed to you. - */ { "arrow_cursor", DT_BOOL, R_BOTH, OPTARROWCURSOR, 0 }, /* ** .pp @@ -402,7 +395,7 @@ ** variable at the time the hook is declared. The default value matches ** if the message is either from a user matching the regular expression ** given, or if it is from you (if the from address matches - ** ``$$alternates'') and is to or cc'ed to a user matching the given + ** ``alternates'') and is to or cc'ed to a user matching the given ** regular expression. */ { "delete", DT_QUAD, R_NONE, OPT_DELETE, M_ASKYES }, @@ -641,7 +634,8 @@ ** .pp ** When set, this variable contains a default from address. It ** can be overridden using my_hdr (including from send-hooks) and - ** ``$$reverse_name''. + ** ``$$reverse_name''. This variable is ignored if ``$$use_from'' + ** is unset. ** .pp ** Defaults to the contents of the environment variable EMAIL. */ @@ -701,28 +695,28 @@ { "hide_limited", DT_BOOL, R_TREE|R_INDEX, OPTHIDELIMITED, 0 }, /* ** .pp - ** When set, mutt will not show the presence of missing messages in the - ** thread tree. + ** When set, mutt will not show the presence of messages that are hidden + ** by limiting, in the thread tree. */ { "hide_missing", DT_BOOL, R_TREE|R_INDEX, OPTHIDEMISSING, 1 }, /* ** .pp - ** When set, mutt will not show the presence of messages that are hidden - ** by limiting, in the thread tree. + ** When set, mutt will not show the presence of missing messages in the + ** thread tree. */ { "hide_top_limited", DT_BOOL, R_TREE|R_INDEX, OPTHIDETOPLIMITED, 0 }, /* ** .pp - ** When set, mutt will not show the presence of missing messages at the - ** top of threads in the thread tree. Note that when $$hide_limited is - ** set, this option will have no effect. + ** When set, mutt will not show the presence of messages that are hidden + ** by limiting, at the top of threads in the thread tree. Note that when + ** $$hide_missing is set, this option will have no effect. */ { "hide_top_missing", DT_BOOL, R_TREE|R_INDEX, OPTHIDETOPMISSING, 1 }, /* ** .pp - ** When set, mutt will not show the presence of messages that are hidden - ** by limiting, at the top of threads in the thread tree.Note that when - ** $$hide_missing is set, this option will have no effect. + ** When set, mutt will not show the presence of missing messages at the + ** top of threads in the thread tree. Note that when $$hide_limited is + ** set, this option will have no effect. */ { "history", DT_NUM, R_NONE, UL &HistSize, 10 }, /* @@ -1033,8 +1027,8 @@ { "metoo", DT_BOOL, R_NONE, OPTMETOO, 0 }, /* ** .pp - ** If unset, Mutt will remove your address (see the ``$$alternates'' - ** variable) from the list of recipients when replying to a message. + ** If unset, Mutt will remove your address (see the ``alternates'' + ** command) from the list of recipients when replying to a message. */ { "menu_scroll", DT_BOOL, R_NONE, OPTMENUSCROLL, 0 }, /* @@ -2733,7 +2727,10 @@ /* functions used to parse commands in a rc file */ static int parse_list (BUFFER *, BUFFER *, unsigned long, BUFFER *); +static int parse_rx_list (BUFFER *, BUFFER *, unsigned long, BUFFER *); static int parse_unlist (BUFFER *, BUFFER *, unsigned long, BUFFER *); +static int parse_rx_unlist (BUFFER *, BUFFER *, unsigned long, BUFFER *); + static int parse_unlists (BUFFER *, BUFFER *, unsigned long, BUFFER *); static int parse_alias (BUFFER *, BUFFER *, unsigned long, BUFFER *); static int parse_unalias (BUFFER *, BUFFER *, unsigned long, BUFFER *); @@ -2753,6 +2750,8 @@ }; struct command_t Commands[] = { + { "alternates", parse_rx_list, UL &Alternates }, + { "unalternates", parse_rx_unlist, UL &Alternates }, #ifdef USE_SOCKET { "account-hook", mutt_parse_hook, M_ACCOUNTHOOK }, #endif @@ -2774,7 +2773,7 @@ { "iconv-hook", mutt_parse_hook, M_ICONVHOOK }, #endif { "ignore", parse_ignore, 0 }, - { "lists", parse_list, UL &MailLists }, + { "lists", parse_rx_list, UL &MailLists }, { "macro", mutt_parse_macro, 0 }, { "mailboxes", mutt_parse_mailboxes, M_MAILBOXES }, { "unmailboxes", mutt_parse_mailboxes, M_UNMAILBOXES }, @@ -2807,6 +2806,6 @@ { "unmy_hdr", parse_unmy_hdr, 0 }, { "unscore", mutt_parse_unscore, 0 }, { "unset", parse_set, M_SET_UNSET }, - { "unsubscribe", parse_unlist, UL &SubscribedLists }, + { "unsubscribe", parse_rx_unlist, UL &SubscribedLists }, { NULL } }; Index: mutt/menu.c diff -u mutt/menu.c:3.10 mutt/menu.c:3.11 --- mutt/menu.c:3.10 Sat Oct 4 22:34:59 2003 +++ mutt/menu.c Sun Jan 4 11:25:13 2004 @@ -38,6 +38,7 @@ size_t k; size_t n = mutt_strlen ((char *)s); mbstate_t mbstate; + short f1, f2, b1, b2; memset (&mbstate, 0, sizeof (mbstate)); while (*s) @@ -45,7 +46,12 @@ if (*s < M_TREE_MAX) { if (do_color) - SETCOLOR (MT_COLOR_TREE); + { + pair_content(PAIR_NUMBER(ColorDefs[MT_COLOR_TREE]), &f1, &b1); + pair_content(PAIR_NUMBER(attr), &f2, &b2); + if (b1 == b2) + SETCOLOR (MT_COLOR_TREE); + } while (*s && *s < M_TREE_MAX) { switch (*s) Index: mutt/mh.c diff -u mutt/mh.c:3.17 mutt/mh.c:3.19 --- mutt/mh.c:3.17 Fri Sep 19 15:03:25 2003 +++ mutt/mh.c Wed Nov 12 12:40:27 2003 @@ -1401,7 +1401,9 @@ if (ctx->hdrs[i]->active) ctx->hdrs[i]->index = j++; } + mx_update_tables (ctx, 0); + mutt_clear_threads (ctx); } static void maildir_update_flags (CONTEXT *ctx, HEADER *o, HEADER *n) @@ -1517,7 +1519,7 @@ ctx->hdrs[i]->active = 0; maildir_canon_filename (buf, ctx->hdrs[i]->path, sizeof (buf)); p = hash_find (fnames, buf); - if (p) + if (p && p->h) { /* message already exists, merge flags */ ctx->hdrs[i]->active = 1; Index: mutt/mutt.h diff -u mutt/mutt.h:3.21 mutt/mutt.h:3.23 --- mutt/mutt.h:3.21 Sat Oct 4 22:34:59 2003 +++ mutt/mutt.h Sun Feb 1 18:10:43 2004 @@ -75,6 +75,8 @@ #define INITVAL(x) #endif +#include "mutt_regex.h" + /* flags for mutt_copy_header() */ #define CH_UPDATE 1 /* update the status and x-status fields? */ #define CH_WEED (1<<1) /* weed the headers? */ @@ -504,8 +506,16 @@ struct list_t *next; } LIST; +typedef struct rx_list_t +{ + REGEXP *rx; + struct rx_list_t *next; +} RX_LIST; + #define mutt_new_list() safe_calloc (1, sizeof (LIST)) +#define mutt_new_rx_list() safe_calloc (1, sizeof (RX_LIST)) void mutt_free_list (LIST **); +void mutt_free_rx_list (RX_LIST **); int mutt_matches_ignore (const char *, LIST *); /* add an element to a list */ @@ -622,7 +632,7 @@ */ unsigned int goodsig : 1; /* good cryptographic signature */ - unsigned int badsig : 1; /* bad cryptographic signature (needed to check encrypted s/mime-signatures */ + unsigned int badsig : 1; /* bad cryptographic signature (needed to check encrypted s/mime-signatures) */ unsigned int collapsed : 1; /* used by recvattach */ @@ -630,7 +640,7 @@ typedef struct header { - unsigned int security : 7; /* bit 0-4: flags, bit 5,6: application. + unsigned int security : 9; /* bit 0-6: flags, bit 7,8: application. see: crypt.h pgplib.h, smime.h */ unsigned int mime : 1; /* has a Mime-Version header? */ @@ -720,7 +730,6 @@ HEADER *sort_key; } THREAD; -#include "mutt_regex.h" /* flag to mutt_pattern_comp() */ #define M_FULL_MSG 1 /* enable body and header matching */ Index: mutt/mutt_crypt.h diff -u mutt/mutt_crypt.h:3.4 mutt/mutt_crypt.h:3.5 --- mutt/mutt_crypt.h:3.4 Fri Jan 31 00:54:30 2003 +++ mutt/mutt_crypt.h Tue Dec 30 14:04:20 2003 @@ -24,7 +24,7 @@ #ifndef MUTT_CRYPT_H #define MUTT_CRYPT_H -#include "mutt.h" /* Need this to declarer BODY, ADDTESS. STATE etc. */ +#include "mutt.h" /* Need this to declare BODY, ADDRESS. STATE etc. */ /* FIXME: They should be pointer to anonymous structures for better information hiding. */ @@ -33,16 +33,18 @@ #define ENCRYPT (1 << 0) #define SIGN (1 << 1) #define GOODSIGN (1 << 2) -#define BADSIGN (1 << 3) /* FIXME: value also used below for PGPKEY */ -#define SIGNOPAQUE (1 << 4) +#define BADSIGN (1 << 3) +#define PARTSIGN (1 << 4) +#define SIGNOPAQUE (1 << 5) +/* (1 << 6) is used by PGPKEY below. */ -#define APPLICATION_PGP (1 << 5) -#define APPLICATION_SMIME (1 << 6) +#define APPLICATION_PGP (1 << 7) +#define APPLICATION_SMIME (1 << 8) #define PGPENCRYPT (APPLICATION_PGP | ENCRYPT) #define PGPSIGN (APPLICATION_PGP | SIGN) #define PGPGOODSIGN (APPLICATION_PGP | GOODSIGN) -#define PGPKEY (APPLICATION_PGP | (1 << 3)) +#define PGPKEY (APPLICATION_PGP | (1 << 6)) #define SMIMEENCRYPT (APPLICATION_SMIME | ENCRYPT) #define SMIMESIGN (APPLICATION_SMIME | SIGN) Index: mutt/mutt_idna.c diff -u mutt/mutt_idna.c:3.7 mutt/mutt_idna.c:3.8 --- mutt/mutt_idna.c:3.7 Fri Sep 19 15:03:25 2003 +++ mutt/mutt_idna.c Wed Nov 12 14:49:32 2003 @@ -47,7 +47,7 @@ goto notrans; /* Is this the right function? Interesting effects with some bad identifiers! */ - if (idna_to_unicode_utf8_from_utf8 (in, out, 1, 0) != IDNA_SUCCESS) + if (idna_to_unicode_8z8z (in, out, 1) != IDNA_SUCCESS) goto notrans; if (mutt_convert_string (out, "utf-8", Charset, M_ICONV_HOOK_TO) == -1) goto notrans; @@ -63,7 +63,7 @@ char *tmp = safe_strdup (*out); if (mutt_convert_string (&tmp, Charset, "utf-8", M_ICONV_HOOK_FROM) == -1) irrev = 1; - if (!irrev && idna_to_ascii_from_utf8 (tmp, &t2, 1, 0) != IDNA_SUCCESS) + if (!irrev && idna_to_ascii_8z (tmp, &t2, 1) != IDNA_SUCCESS) irrev = 1; if (!irrev && ascii_strcasecmp (t2, in)) { @@ -101,7 +101,7 @@ if (mutt_convert_string (&tmp, Charset, "utf-8", M_ICONV_HOOK_FROM) == -1) rv = -1; - if (!rv && idna_to_ascii_from_utf8 (tmp, out, 1, 0) != IDNA_SUCCESS) + if (!rv && idna_to_ascii_8z (tmp, out, 1) != IDNA_SUCCESS) rv = -2; FREE (&tmp); Index: mutt/mutt_idna.h diff -u mutt/mutt_idna.h:3.1 mutt/mutt_idna.h:3.2 --- mutt/mutt_idna.h:3.1 Mon Mar 3 15:01:06 2003 +++ mutt/mutt_idna.h Wed Nov 12 14:49:32 2003 @@ -40,4 +40,18 @@ const char *mutt_addr_for_display (ADDRESS *a); +/* Work around incompatibilities in the libidn API */ + +#ifdef HAVE_LIBIDN +# if (!defined(HAVE_IDNA_TO_ASCII_8Z) && defined(HAVE_IDNA_TO_ASCII_FROM_UTF8)) +# define idna_to_ascii_8z(a,b,c) idna_to_ascii_from_utf8(a,b,(c)&1,((c)&2)?1:0) +# endif +# if (!defined(HAVE_IDNA_TO_ASCII_LZ) && defined(HAVE_IDNA_TO_ASCII_FROM_LOCALE)) +# define idna_to_ascii_lz(a,b,c) idna_to_ascii_from_locale(a,b,(c)&1,((c)&2)?1:0) +# endif +# if (!defined(HAVE_IDNA_TO_UNICODE_8Z8Z) && defined(HAVE_IDNA_TO_UNICODE_UTF8_FROM_UTF8)) +# define idna_to_unicode_8z8z(a,b,c) idna_to_unicode_utf8_from_utf8(a,b,(c)&1,((c)&2)?1:0) +# endif +#endif + #endif Index: mutt/mutt_regex.h diff -u mutt/mutt_regex.h:3.1 mutt/mutt_regex.h:3.2 --- mutt/mutt_regex.h:3.1 Wed Dec 11 12:19:40 2002 +++ mutt/mutt_regex.h Sun Feb 1 18:10:43 2004 @@ -46,7 +46,6 @@ int not; /* do not match */ } REGEXP; -WHERE REGEXP Alternates; WHERE REGEXP Mask; WHERE REGEXP QuoteRegexp; WHERE REGEXP ReplyRegexp; Index: mutt/mutt_sasl.c diff -u mutt/mutt_sasl.c:3.4 mutt/mutt_sasl.c:3.6 --- mutt/mutt_sasl.c:3.4 Thu Sep 11 18:59:54 2003 +++ mutt/mutt_sasl.c Mon Jan 5 12:55:14 2004 @@ -32,6 +32,50 @@ #include #include +#ifdef USE_SASL2 +static int getnameinfo_err(int ret) +{ + int err; + dprint (1, (debugfile, "getnameinfo: ")); + switch(ret) + { + case EAI_AGAIN: + dprint (1, (debugfile, "The name could not be resolved at this time. Future attempts may succeed.\n")); + err=SASL_TRYAGAIN; + break; + case EAI_BADFLAGS: + dprint (1, (debugfile, "The flags had an invalid value.\n")); + err=SASL_BADPARAM; + break; + case EAI_FAIL: + dprint (1, (debugfile, "A non-recoverable error occurred.\n")); + err=SASL_FAIL; + break; + case EAI_FAMILY: + dprint (1, (debugfile, "The address family was not recognized or the address length was invalid for the specified family.\n")); + err=SASL_BADPROT; + break; + case EAI_MEMORY: + dprint (1, (debugfile, "There was a memory allocation failure.\n")); + err=SASL_NOMEM; + break; + case EAI_NONAME: + dprint (1, (debugfile, "The name does not resolve for the supplied parameters. NI_NAMEREQD is set and the host's name cannot be located, or both nodename and servname were null.\n")); + err=SASL_FAIL; /* no real equivalent */ + break; + case EAI_SYSTEM: + dprint (1, (debugfile, "A system error occurred. The error code can be found in errno(%d,%s)).\n",errno,strerror(errno))); + err=SASL_FAIL; /* no real equivalent */ + break; + default: + dprint (1, (debugfile, "Unknown error %d\n",ret)); + err=SASL_FAIL; /* no real equivalent */ + break; + } + return err; +} +#endif + /* arbitrary. SASL will probably use a smaller buffer anyway. OTOH it's * been a while since I've had access to an SASL server which negotiated * a protection buffer. */ @@ -64,15 +108,18 @@ static int iptostring(const struct sockaddr *addr, socklen_t addrlen, char *out, unsigned outlen) { char hbuf[NI_MAXHOST], pbuf[NI_MAXSERV]; + int ret; if(!addr || !out) return SASL_BADPARAM; - getnameinfo(addr, addrlen, hbuf, sizeof(hbuf), pbuf, sizeof(pbuf), - NI_NUMERICHOST | + ret=getnameinfo(addr, addrlen, hbuf, sizeof(hbuf), pbuf, sizeof(pbuf), + NI_NUMERICHOST | #ifdef NI_WITHSCOPEID - NI_WITHSCOPEID | + NI_WITHSCOPEID | #endif - NI_NUMERICSERV); + NI_NUMERICSERV); + if(ret) + return getnameinfo_err(ret); if(outlen < strlen(hbuf) + strlen(pbuf) + 2) return SASL_BUFOVER; @@ -124,7 +171,7 @@ { sasl_security_properties_t secprops; #ifdef USE_SASL2 - struct sockaddr local, remote; + struct sockaddr_storage local, remote; socklen_t size; char iplocalport[IP_PORT_BUFLEN], ipremoteport[IP_PORT_BUFLEN]; #else @@ -151,23 +198,23 @@ #ifdef USE_SASL2 size = sizeof (local); - if (getsockname (conn->fd, &local, &size)){ + if (getsockname (conn->fd, (struct sockaddr *)&local, &size)){ dprint (1, (debugfile, "mutt_sasl_client_new: getsockname for local failed\n")); return -1; } else - if (iptostring(&local, size, iplocalport, IP_PORT_BUFLEN) != SASL_OK){ + if (iptostring((struct sockaddr *)&local, size, iplocalport, IP_PORT_BUFLEN) != SASL_OK){ dprint (1, (debugfile, "mutt_sasl_client_new: iptostring for local failed\n")); return -1; } size = sizeof (remote); - if (getpeername (conn->fd, &remote, &size)){ + if (getpeername (conn->fd, (struct sockaddr *)&remote, &size)){ dprint (1, (debugfile, "mutt_sasl_client_new: getsockname for remote failed\n")); return -1; } else - if (iptostring(&remote, size, ipremoteport, IP_PORT_BUFLEN) != SASL_OK){ + if (iptostring((struct sockaddr *)&remote, size, ipremoteport, IP_PORT_BUFLEN) != SASL_OK){ dprint (1, (debugfile, "mutt_sasl_client_new: iptostring for remote failed\n")); return -1; } Index: mutt/mutt_socket.c diff -u mutt/mutt_socket.c:3.3 mutt/mutt_socket.c:3.5 --- mutt/mutt_socket.c:3.3 Tue Mar 4 10:51:07 2003 +++ mutt/mutt_socket.c Wed Nov 12 14:49:32 2003 @@ -26,9 +26,7 @@ # include "mutt_ssl.h" #endif -#ifdef HAVE_LIBIDN -#include -#endif +#include "mutt_idna.h" #include #include @@ -413,7 +411,7 @@ snprintf (port, sizeof (port), "%d", conn->account.port); # ifdef HAVE_LIBIDN - if (idna_to_ascii_from_locale (conn->account.host, &host_idna, 1, 0) != IDNA_SUCCESS) + if (idna_to_ascii_lz (conn->account.host, &host_idna, 1) != IDNA_SUCCESS) { mutt_error (_("Bad IDN \"%s\"."), conn->account.host); return -1; @@ -470,7 +468,7 @@ sin.sin_family = AF_INET; # ifdef HAVE_LIBIDN - if (idna_to_ascii_from_locale (conn->account.host, &host_idna, 1, 0) != IDNA_SUCCESS) + if (idna_to_ascii_lz (conn->account.host, &host_idna, 1) != IDNA_SUCCESS) { mutt_error (_("Bad IDN \"%s\"."), conn->account.host); return -1; @@ -483,13 +481,17 @@ if ((he = gethostbyname (host_idna)) == NULL) { +# ifdef HAVE_LIBIDN FREE (&host_idna); +# endif mutt_error (_("Could not find the host \"%s\""), conn->account.host); return -1; } - + +# ifdef HAVE_LIBIDN FREE (&host_idna); +# endif mutt_message (_("Connecting to %s..."), conn->account.host); Index: mutt/muttlib.c diff -u mutt/muttlib.c:3.17 mutt/muttlib.c:3.18 --- mutt/muttlib.c:3.17 Sat Oct 4 22:34:59 2003 +++ mutt/muttlib.c Sun Feb 1 18:10:43 2004 @@ -1346,3 +1346,51 @@ return vstring; } +REGEXP *mutt_compile_regexp (const char *s, int flags) +{ + REGEXP *pp = safe_calloc (sizeof (REGEXP), 1); + pp->pattern = safe_strdup (s); + pp->rx = safe_calloc (sizeof (regex_t), 1); + if (REGCOMP (pp->rx, NONULL(s), flags) != 0) + mutt_free_regexp (&pp); + + return pp; +} + +void mutt_free_regexp (REGEXP **pp) +{ + FREE (&(*pp)->pattern); + regfree ((*pp)->rx); + FREE (&(*pp)->rx); + FREE (pp); +} + +void mutt_free_rx_list (RX_LIST **list) +{ + RX_LIST *p; + + if (!list) return; + while (*list) + { + p = *list; + *list = (*list)->next; + mutt_free_regexp (&p->rx); + FREE (&p); + } +} + +int mutt_match_rx_list (const char *s, RX_LIST *l) +{ + if (!s) return 0; + + for (; l; l = l->next) + { + if (regexec (l->rx->rx, s, (size_t) 0, (regmatch_t *) 0, (int) 0) == 0) + { + dprint (5, (debugfile, "mutt_match_rx_list: %s matches %s\n", s, l->rx->pattern)); + return 1; + } + } + + return 0; +} Index: mutt/pager.c diff -u mutt/pager.c:3.12 mutt/pager.c:3.13 --- mutt/pager.c:3.12 Sat Oct 4 22:34:59 2003 +++ mutt/pager.c Wed Dec 3 09:19:11 2003 @@ -2372,7 +2372,7 @@ case OP_MAIL: CHECK_MODE(IsHeader (extra) && !IsAttach (extra)); CHECK_ATTACH; - ci_send_message (0, NULL, NULL, NULL, NULL); + ci_send_message (0, NULL, NULL, extra->ctx, extra->hdr); redraw = REDRAW_FULL; break; Index: mutt/pop.h diff -u mutt/pop.h:3.0 mutt/pop.h:3.1 --- mutt/pop.h:3.0 Thu Jan 24 13:10:51 2002 +++ mutt/pop.h Sun Jan 4 10:49:23 2004 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2000-2001 Vsevolod Volkov + * Copyright (C) 2000-2003 Vsevolod Volkov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -59,7 +59,9 @@ CONNECTION *conn; unsigned int status : 2; unsigned int capabilities : 1; + unsigned int use_stls : 2; unsigned int cmd_capa : 1; /* optional command CAPA */ + unsigned int cmd_stls : 1; /* optional command STLS */ unsigned int cmd_user : 2; /* optional command USER */ unsigned int cmd_uidl : 2; /* optional command UIDL */ unsigned int cmd_top : 2; /* optional command TOP */ Index: mutt/pop_lib.c diff -u mutt/pop_lib.c:3.4 mutt/pop_lib.c:3.5 --- mutt/pop_lib.c:3.4 Fri Sep 19 15:03:26 2003 +++ mutt/pop_lib.c Sun Jan 4 10:49:23 2004 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2000-2002 Vsevolod Volkov + * Copyright (C) 2000-2003 Vsevolod Volkov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,6 +20,9 @@ #include "mx.h" #include "url.h" #include "pop.h" +#ifdef USE_SSL +# include "mutt_ssl.h" +#endif #include #include @@ -85,11 +88,15 @@ if (!ascii_strncasecmp (line, "SASL", 4)) { + FREE (&pop_data->auth_list); c = line + 4; SKIPWS (c); pop_data->auth_list = safe_strdup (c); } + else if (!ascii_strncasecmp (line, "STLS", 4)) + pop_data->cmd_stls = 1; + else if (!ascii_strncasecmp (line, "USER", 4)) pop_data->cmd_user = 1; @@ -129,43 +136,46 @@ * -1 - conection lost, * -2 - execution error. */ -static int pop_capabilities (POP_DATA *pop_data) +static int pop_capabilities (POP_DATA *pop_data, int mode) { char buf[LONG_STRING]; - char *msg = NULL; + /* don't check capabilities on reconnect */ if (pop_data->capabilities) return 0; - pop_data->cmd_capa = 0; - pop_data->cmd_user = 0; - pop_data->cmd_uidl = 0; - pop_data->cmd_top = 0; - pop_data->resp_codes = 0; - pop_data->expire = 1; - pop_data->login_delay = 0; - FREE (&pop_data->auth_list); + /* init capabilities */ + if (mode == 0) + { + pop_data->cmd_capa = 0; + pop_data->cmd_stls = 0; + pop_data->cmd_user = 0; + pop_data->cmd_uidl = 0; + pop_data->cmd_top = 0; + pop_data->resp_codes = 0; + pop_data->expire = 1; + pop_data->login_delay = 0; + FREE (&pop_data->auth_list); + } - strfcpy (buf, "CAPA\r\n", sizeof (buf)); - switch (pop_fetch_data (pop_data, buf, NULL, fetch_capa, pop_data)) + /* Execute CAPA command */ + if (mode == 0 || pop_data->cmd_capa) { - case 0: + strfcpy (buf, "CAPA\r\n", sizeof (buf)); + switch (pop_fetch_data (pop_data, buf, NULL, fetch_capa, pop_data)) { - pop_data->cmd_capa = 1; - - if (!pop_data->expire) - msg = _("Unable to leave messages on server."); - if (!pop_data->cmd_top) - msg = _("Command TOP is not supported by server."); - if (!pop_data->cmd_uidl) - msg = _("Command UIDL is not supported by server."); - break; + case 0: + { + pop_data->cmd_capa = 1; + break; + } + case -1: + return -1; } - case -1: - return -1; } - if (!pop_data->cmd_capa) + /* CAPA not supported, use defaults */ + if (mode == 0 && !pop_data->cmd_capa) { pop_data->cmd_user = 2; pop_data->cmd_uidl = 2; @@ -176,13 +186,24 @@ return -1; } - if (msg) + /* Check capabilities */ + if (mode == 2) { - mutt_error (msg); - return -2; - } + char *msg = NULL; - pop_data->capabilities = 1; + if (!pop_data->expire) + msg = _("Unable to leave messages on server."); + if (!pop_data->cmd_top) + msg = _("Command TOP is not supported by server."); + if (!pop_data->cmd_uidl) + msg = _("Command UIDL is not supported by server."); + if (msg && pop_data->cmd_capa) + { + mutt_error (msg); + return -2; + } + pop_data->capabilities = 1; + } return 0; } @@ -240,7 +261,7 @@ return ret; } - ret = pop_capabilities (pop_data); + ret = pop_capabilities (pop_data, 0); if (ret == -1) goto err_conn; if (ret == -2) @@ -249,6 +270,53 @@ return -2; } +#if defined(USE_SSL) && !defined(USE_NSS) + /* Attempt STLS if available and desired. */ + if (pop_data->cmd_stls && !pop_data->conn->ssf) + { + if (pop_data->use_stls == 0) + { + ret = query_quadoption (OPT_SSLSTARTTLS, + _("Secure connection with TLS?")); + if (ret == -1) + return -2; + pop_data->use_stls = 1; + if (ret == M_YES) + pop_data->use_stls = 2; + } + if (pop_data->use_stls == 2) + { + strfcpy (buf, "STLS\r\n", sizeof (buf)); + ret = pop_query (pop_data, buf, sizeof (buf)); + if (ret == -1) + goto err_conn; + if (ret != 0) + { + mutt_error ("%s", pop_data->err_msg); + mutt_sleep (2); + } + else if (mutt_ssl_starttls (pop_data->conn)) + { + mutt_error (_("Could not negotiate TLS connection")); + mutt_sleep (2); + return -2; + } + else + { + /* recheck capabilities after STLS completes */ + ret = pop_capabilities (pop_data, 1); + if (ret == -1) + goto err_conn; + if (ret == -2) + { + mutt_sleep (2); + return -2; + } + } + } + } +#endif + ret = pop_authenticate (pop_data); if (ret == -1) goto err_conn; @@ -256,6 +324,16 @@ mutt_clear_error (); if (ret != 0) return ret; + + /* recheck capabilities after authentication */ + ret = pop_capabilities (pop_data, 2); + if (ret == -1) + goto err_conn; + if (ret == -2) + { + mutt_sleep (2); + return -2; + } /* get total size of mailbox */ strfcpy (buf, "STAT\r\n", sizeof (buf)); Index: mutt/protos.h diff -u mutt/protos.h:3.18 mutt/protos.h:3.19 --- mutt/protos.h:3.18 Sat Oct 4 22:34:59 2003 +++ mutt/protos.h Sun Feb 1 18:10:43 2004 @@ -136,6 +136,8 @@ const char *mutt_fqdn(short); +REGEXP *mutt_compile_regexp (const char *, int); + void mutt_account_hook (const char* url); void mutt_add_to_reference_headers (ENVELOPE *env, ENVELOPE *curenv, LIST ***pp, LIST ***qq); void mutt_adv_mktemp (char *, size_t); @@ -181,6 +183,7 @@ void mutt_free_envelope (ENVELOPE **); void mutt_free_header (HEADER **); void mutt_free_parameter (PARAMETER **); +void mutt_free_regexp (REGEXP **); void mutt_generate_header (char *, size_t, HEADER *, int); void mutt_help (int); void mutt_draw_tree (CONTEXT *); @@ -287,6 +290,7 @@ int mutt_is_text_part (BODY *); int mutt_is_valid_mailbox (const char *); int mutt_lookup_mime_type (BODY *, const char *); +int mutt_match_rx_list (const char *, RX_LIST *); int mutt_messages_in_thread (CONTEXT *, HEADER *, int); int mutt_multi_choice (char *prompt, char *letters); int mutt_needs_mailcap (BODY *); Index: mutt/reldate.h diff -u mutt/reldate.h:3.5 mutt/reldate.h:3.6 --- mutt/reldate.h:3.5 Wed Nov 5 10:51:09 2003 +++ mutt/reldate.h Sun Feb 1 19:26:11 2004 @@ -1 +1 @@ -const char *ReleaseDate = "2003-11-05"; +const char *ReleaseDate = "2004-02-01"; Index: mutt/rfc1524.c diff -u mutt/rfc1524.c:3.4 mutt/rfc1524.c:3.5 --- mutt/rfc1524.c:3.4 Fri Sep 19 15:03:26 2003 +++ mutt/rfc1524.c Wed Dec 17 09:46:50 2003 @@ -469,7 +469,7 @@ } else if (!oldfile) { - snprintf (newfile, nflen, nametemplate, "mutt"); + mutt_expand_fmt (newfile, nflen, nametemplate, "mutt"); } else /* oldfile && nametemplate */ { Index: mutt/send.c diff -u mutt/send.c:3.26 mutt/send.c:3.29 --- mutt/send.c:3.26 Fri Sep 19 14:56:49 2003 +++ mutt/send.c Sun Jan 4 11:03:46 2004 @@ -859,7 +859,9 @@ if (e->mail_followup_to && !mutt_is_list_recipient (0, e->to, e->cc)) { - if (e->from) + if (e->reply_to) + from = rfc822_cpy_adr (e->reply_to); + else if (e->from) from = rfc822_cpy_adr (e->from); else from = mutt_default_from (); @@ -1194,7 +1196,7 @@ if ((flags & SENDREPLY) && cur) { /* change setting based upon message we are replying to */ - mutt_message_hook (NULL, cur, M_REPLYHOOK); + mutt_message_hook (ctx, cur, M_REPLYHOOK); /* * set the replied flag for the message we are generating so that the @@ -1303,7 +1305,7 @@ && !(flags & (SENDRESEND|SENDPOSTPONED))) msg->env->from->personal = safe_strdup (Realname); - if ((WithCrypto & APPLICATION_PGP) && !(flags & SENDKEY)) + if (!((WithCrypto & APPLICATION_PGP) && (flags & SENDKEY))) safe_fclose (&tempfp); if (flags & SENDMAILX) Index: mutt/smime.c diff -u mutt/smime.c:3.29 mutt/smime.c:3.31 --- mutt/smime.c:3.29 Fri Sep 19 15:03:26 2003 +++ mutt/smime.c Sun Jan 4 10:42:35 2004 @@ -692,10 +692,10 @@ } snprintf (SmimeKeyToUse, sizeof (SmimeKeyToUse), "%s/%s", - NONULL (SmimeKeys), SmimeDefaultKey); + NONULL (SmimeKeys), NONULL (SmimeDefaultKey)); snprintf (SmimeCertToUse, sizeof (SmimeCertToUse), "%s/%s", - NONULL (SmimeCertificates), SmimeDefaultKey); + NONULL (SmimeCertificates), NONULL (SmimeDefaultKey)); } void smime_getkeys (ENVELOPE *env) @@ -1837,9 +1837,10 @@ m->goodsig = 1; FREE (&line); } - else { + else + { m->goodsig = p->goodsig; - m->badsig = p->badsig; + m->badsig = p->badsig; } fclose (smimeerr); Index: mutt/smime_keys.pl diff -u mutt/smime_keys.pl:3.15 mutt/smime_keys.pl:3.16 --- mutt/smime_keys.pl:3.15 Wed Apr 2 11:05:19 2003 +++ mutt/smime_keys.pl Mon Jan 12 23:56:58 2004 @@ -934,6 +934,7 @@ # returns a file name which does not exist for tmp file creation my $filename = shift; my $option = shift; + $option = "notemp" if (not defined($option)); if (! $tmpdir and $option eq "temp") { $tmpdir = mutt_Q 'tmpdir'; $tmpdir = newfile("$tmpdir/smime"); Index: mutt/sort.c diff -u mutt/sort.c:3.4 mutt/sort.c:3.5 --- mutt/sort.c:3.4 Wed Mar 5 22:18:24 2003 +++ mutt/sort.c Wed Nov 12 12:40:27 2003 @@ -194,7 +194,7 @@ * in that routine, so we must make sure to zero the vcount member. */ ctx->vcount = 0; - ctx->tree = 0; + mutt_clear_threads (ctx); return; /* nothing to do! */ } Index: mutt/thread.c diff -u mutt/thread.c:3.7 mutt/thread.c:3.8 --- mutt/thread.c:3.7 Fri Sep 19 15:03:26 2003 +++ mutt/thread.c Wed Dec 10 01:48:57 2003 @@ -72,7 +72,7 @@ return (1); } } - + /* if we have no visible parent or previous sibling, display the subject */ return (1); } @@ -947,16 +947,19 @@ if (!option (OPTSTRICTTHREADS)) pseudo_threads (ctx); - ctx->tree = mutt_sort_subthreads (ctx->tree, init); - - /* restore the oldsort order. */ - Sort = oldsort; + if (ctx->tree) + { + ctx->tree = mutt_sort_subthreads (ctx->tree, init); - /* Put the list into an array. */ - linearize_tree (ctx); + /* restore the oldsort order. */ + Sort = oldsort; + + /* Put the list into an array. */ + linearize_tree (ctx); - /* Draw the thread tree. */ - mutt_draw_tree (ctx); + /* Draw the thread tree. */ + mutt_draw_tree (ctx); + } } static HEADER *find_virtual (THREAD *cur, int reverse) Index: mutt/doc/manual.sgml.head diff -u mutt/doc/manual.sgml.head:3.22 mutt/doc/manual.sgml.head:3.26 --- mutt/doc/manual.sgml.head:3.22 Sat Oct 4 22:54:37 2003 +++ mutt/doc/manual.sgml.head Sun Feb 1 18:45:33 2004 @@ -1165,10 +1165,32 @@ unignore posted-to: +Alternative addresses