changeset: 6520:a6919571eb59
user: Kevin McCarthy <[email protected]>
date: Sun Oct 18 19:45:51 2015 +0800
link: http://dev.mutt.org/hg/mutt/rev/a6919571eb59
Fix next_token() oob read. (closes #3787)
With specially crafted input to 'mutt -H', the line "Return-Path:<() "
is read and passed to mutt_parse_rfc822_line(). "<() " is then passed
through to rfc822_parse_adrlist().
Eventually, inside next_token(), is_special(*s) is called when s
points to the end of the string ('\0'). This macro calls strchr,
which will actually match and return a pointer to the trailing '\0' in
RFC822Specials! This causes "s + 1" to be returned, skipping past the
end of string inside parse_mailboxdomain().
This patch adds a check to make sure *s is non-null before calling
is_special(*s).
changeset: 6521:41af5a753d6f
user: Kevin McCarthy <[email protected]>
date: Sun Oct 18 20:05:37 2015 +0800
link: http://dev.mutt.org/hg/mutt/rev/41af5a753d6f
merge stable
diffs (truncated from 13180 to 950 lines):
diff -r 590ff6eebe1a -r 41af5a753d6f UPDATING
--- a/UPDATING Wed Sep 30 11:21:06 2015 +0800
+++ b/UPDATING Sun Oct 18 20:05:37 2015 +0800
@@ -4,6 +4,10 @@
The keys used are:
!: modified feature, -: deleted feature, +: new feature
+default (unreleased):
+ + New expandos %r and %R for comma separated list of To: and Cc:
+ recipients respectively
+
1.5.24 (2015-08-31):
+ terminal status-line (TS) support, a.k.a. xterm title. see the
diff -r 590ff6eebe1a -r 41af5a753d6f alias.c
--- a/alias.c Wed Sep 30 11:21:06 2015 +0800
+++ b/alias.c Sun Oct 18 20:05:37 2015 +0800
@@ -256,7 +256,7 @@
mutt_check_alias_name (tmp, buf, sizeof (buf));
retry_name:
- /* add a new alias */
+ /* L10N: prompt to add a new alias */
if (mutt_get_field (_("Alias as: "), buf, sizeof (buf), 0) != 0 || !buf[0])
return;
diff -r 590ff6eebe1a -r 41af5a753d6f browser.c
--- a/browser.c Wed Sep 30 11:21:06 2015 +0800
+++ b/browser.c Sun Oct 18 20:05:37 2015 +0800
@@ -896,7 +896,7 @@
else
set_option (OPTIMAPLSUB);
- mutt_ungetch (0, OP_CHECK_NEW);
+ mutt_unget_event (0, OP_CHECK_NEW);
break;
case OP_CREATE_MAILBOX:
diff -r 590ff6eebe1a -r 41af5a753d6f commands.c
--- a/commands.c Wed Sep 30 11:21:06 2015 +0800
+++ b/commands.c Sun Oct 18 20:05:37 2015 +0800
@@ -228,7 +228,7 @@
mutt_set_flag (Context, cur, M_READ, 1);
if (r != -1 && option (OPTPROMPTAFTER))
{
- mutt_ungetch (mutt_any_key_to_continue _("Command: "), 0);
+ mutt_unget_event (mutt_any_key_to_continue _("Command: "), 0);
rc = km_dokey (MENU_PAGER);
}
else
diff -r 590ff6eebe1a -r 41af5a753d6f compose.c
--- a/compose.c Wed Sep 30 11:21:06 2015 +0800
+++ b/compose.c Sun Oct 18 20:05:37 2015 +0800
@@ -754,7 +754,7 @@
ctx = mx_open_mailbox (fname, M_READONLY, NULL);
if (ctx == NULL)
{
- mutt_perror (fname);
+ mutt_error (_("Unable to open mailbox %s"), fname);
break;
}
@@ -1023,6 +1023,8 @@
{
if (stat(idx[menu->current]->content->filename, &st) == -1)
{
+ /* L10N:
+ "stat" is a system call. Do "man 2 stat" for more information.
*/
mutt_error (_("Can't stat %s: %s"), fname, strerror (errno));
break;
}
@@ -1234,14 +1236,20 @@
if ((WithCrypto & APPLICATION_SMIME)
&& (msg->security & APPLICATION_SMIME))
{
- if (mutt_yesorno (_("S/MIME already selected. Clear & continue ? "),
- M_YES) != M_YES)
- {
- mutt_clear_error ();
- break;
- }
+ if (msg->security & (ENCRYPT | SIGN))
+ {
+ if (mutt_yesorno (_("S/MIME already selected. Clear & continue ?
"),
+ M_YES) != M_YES)
+ {
+ mutt_clear_error ();
+ break;
+ }
+ msg->security &= ~(ENCRYPT | SIGN);
+ }
msg->security &= ~APPLICATION_SMIME;
msg->security |= APPLICATION_PGP;
+ crypt_opportunistic_encrypt (msg);
+ redraw_crypt_lines (msg);
}
msg->security = crypt_pgp_send_menu (msg, &menu->redraw);
redraw_crypt_lines (msg);
@@ -1261,14 +1269,20 @@
if ((WithCrypto & APPLICATION_PGP)
&& (msg->security & APPLICATION_PGP))
{
- if (mutt_yesorno (_("PGP already selected. Clear & continue ? "),
- M_YES) != M_YES)
- {
- mutt_clear_error ();
- break;
- }
+ if (msg->security & (ENCRYPT | SIGN))
+ {
+ if (mutt_yesorno (_("PGP already selected. Clear & continue ? "),
+ M_YES) != M_YES)
+ {
+ mutt_clear_error ();
+ break;
+ }
+ msg->security &= ~(ENCRYPT | SIGN);
+ }
msg->security &= ~APPLICATION_PGP;
msg->security |= APPLICATION_SMIME;
+ crypt_opportunistic_encrypt (msg);
+ redraw_crypt_lines (msg);
}
msg->security = crypt_smime_send_menu(msg, &menu->redraw);
redraw_crypt_lines (msg);
diff -r 590ff6eebe1a -r 41af5a753d6f crypt-gpgme.c
--- a/crypt-gpgme.c Wed Sep 30 11:21:06 2015 +0800
+++ b/crypt-gpgme.c Sun Oct 18 20:05:37 2015 +0800
@@ -1362,6 +1362,8 @@
continue;
if (aka)
{
+ /* TODO: need to account for msg wide characters
+ * and "aka" translation length */
msglen = mutt_strlen (msg) - 4;
for (i = 0; i < msglen; i++)
state_attach_puts(" ", s);
@@ -1381,6 +1383,8 @@
}
msglen = mutt_strlen (msg) - 8;
+ /* TODO: need to account for msg wide characters
+ * and "created" translation length */
for (i = 0; i < msglen; i++)
state_attach_puts(" ", s);
state_attach_puts (_("created: "), s);
@@ -1404,6 +1408,7 @@
gpgme_verify_result_t result;
gpgme_signature_t sig;
gpgme_error_t err = GPG_ERR_NO_ERROR;
+ char buf[LONG_STRING];
result = gpgme_op_verify_result (ctx);
if (result)
@@ -1453,11 +1458,10 @@
; /* No state information so no way to print anything. */
else if (err)
{
- state_attach_puts (_("Error getting key information for KeyID "), s);
- state_attach_puts ( fpr, s );
- state_attach_puts (_(": "), s);
- state_attach_puts ( gpgme_strerror (err), s );
- state_attach_puts ("\n", s);
+ snprintf (buf, sizeof (buf),
+ _("Error getting key information for KeyID %s: %s\n"),
+ fpr, gpgme_strerror (err));
+ state_attach_puts (buf, s);
anybad = 1;
}
else if ((sum & GPGME_SIGSUM_GREEN))
@@ -1489,6 +1493,9 @@
/* 0 indicates no expiration */
if (sig->exp_timestamp)
{
+ /* L10N:
+ This is trying to match the width of the
+ "Problem signature from:" translation just above. */
state_attach_puts (_(" expires: "), s);
print_time (sig->exp_timestamp, s);
state_attach_puts ("\n", s);
@@ -3366,6 +3373,10 @@
continue;
s = uid->uid;
+ /* L10N:
+ Fill dots to make the DOTFILL entries the same length.
+ In English, msgid "Fingerprint: " is the longest entry for this menu.
+ Your language may vary. */
fputs (idx ? _(" aka ......: ") :_("Name ......: "), fp);
if (uid->invalid)
{
@@ -3389,6 +3400,7 @@
#else
strftime (shortbuf, sizeof shortbuf, "%c", tm);
#endif
+ /* L10N: DOTFILL */
fprintf (fp, _("Valid From : %s\n"), shortbuf);
}
@@ -3402,6 +3414,7 @@
#else
strftime (shortbuf, sizeof shortbuf, "%c", tm);
#endif
+ /* L10N: DOTFILL */
fprintf (fp, _("Valid To ..: %s\n"), shortbuf);
}
@@ -3415,8 +3428,10 @@
if (key->subkeys)
aval = key->subkeys->length;
+ /* L10N: DOTFILL */
fprintf (fp, _("Key Type ..: %s, %lu bit %s\n"), s2, aval, s);
+ /* L10N: DOTFILL */
fprintf (fp, _("Key Usage .: "));
delim = "";
@@ -3440,6 +3455,7 @@
if (key->subkeys)
{
s = key->subkeys->fpr;
+ /* L10N: DOTFILL */
fputs (_("Fingerprint: "), fp);
if (is_pgp && strlen (s) == 40)
{
@@ -3472,6 +3488,7 @@
{
s = key->issuer_serial;
if (s)
+ /* L10N: DOTFILL */
fprintf (fp, _("Serial-No .: 0x%s\n"), s);
}
@@ -3480,6 +3497,7 @@
s = key->issuer_name;
if (s)
{
+ /* L10N: DOTFILL */
fprintf (fp, _("Issued By .: "));
parse_and_print_user_id (fp, s);
putc ('\n', fp);
@@ -3499,6 +3517,7 @@
putc ('\n', fp);
if ( strlen (s) == 16)
s += 8; /* display only the short keyID */
+ /* L10N: DOTFILL */
fprintf (fp, _("Subkey ....: 0x%s"), s);
if (subkey->revoked)
{
@@ -3532,6 +3551,7 @@
#else
strftime (shortbuf, sizeof shortbuf, "%c", tm);
#endif
+ /* L10N: DOTFILL */
fprintf (fp, _("Valid From : %s\n"), shortbuf);
}
@@ -3545,6 +3565,7 @@
#else
strftime (shortbuf, sizeof shortbuf, "%c", tm);
#endif
+ /* L10N: DOTFILL */
fprintf (fp, _("Valid To ..: %s\n"), shortbuf);
}
@@ -3558,8 +3579,10 @@
else
aval = 0;
+ /* L10N: DOTFILL */
fprintf (fp, _("Key Type ..: %s, %lu bit %s\n"), "PGP", aval, s);
+ /* L10N: DOTFILL */
fprintf (fp, _("Key Usage .: "));
delim = "";
@@ -4010,8 +4033,14 @@
ts = _("keys matching");
if (p)
+ /* L10N:
+ %1$s is one of the previous four entries.
+ %2$s is an address.
+ e.g. "S/MIME keys matching <[email protected]>." */
snprintf (buf, sizeof (buf), _("%s <%s>."), ts, p->mailbox);
else
+ /* L10N:
+ e.g. 'S/MIME keys matching "Michael Elkins".' */
snprintf (buf, sizeof (buf), _("%s \"%s\"."), ts, s);
menu->title = buf;
}
@@ -4590,6 +4619,10 @@
att->use_disp = 0;
att->type = TYPEAPPLICATION;
att->subtype = safe_strdup ("pgp-keys");
+ /* L10N:
+ MIME description for exported (attached) keys.
+ You can translate this entry to a non-ASCII string (it will be encoded),
+ but it may be safer to keep it untranslated. */
snprintf (buff, sizeof (buff), _("PGP Key 0x%s."), crypt_keyid (key));
att->description = safe_strdup (buff);
mutt_update_encoding (att);
@@ -4678,6 +4711,10 @@
if (is_smime)
{
prompt = _("S/MIME (s)ign, sign (a)s, (p)gp, (c)lear, or (o)ppenc mode
off? ");
+ /* L10N: The 'f' is from "forget it", an old undocumented synonym of
+ 'clear'. Please use a corresponding letter in your language.
+ Alternatively, you may duplicate the letter 'c' is translated to.
+ This comment also applies to the five following letter sequences. */
letters = _("sapfco");
choices = "SapFCo";
}
diff -r 590ff6eebe1a -r 41af5a753d6f curs_lib.c
--- a/curs_lib.c Wed Sep 30 11:21:06 2015 +0800
+++ b/curs_lib.c Sun Oct 18 20:05:37 2015 +0800
@@ -48,9 +48,20 @@
* is impossible to unget function keys in SLang, so roll our own input
* buffering routines.
*/
-size_t UngetCount = 0;
-static size_t UngetBufLen = 0;
-static event_t *KeyEvent;
+
+/* These are used for macros and exec/push commands.
+ * They can be temporarily ignored by setting OPTIGNOREMACROEVENTS
+ */
+static size_t MacroBufferCount = 0;
+static size_t MacroBufferLen = 0;
+static event_t *MacroEvents;
+
+/* These are used in all other "normal" situations, and are not
+ * ignored when setting OPTIGNOREMACROEVENTS
+ */
+static size_t UngetCount = 0;
+static size_t UngetLen = 0;
+static event_t *UngetKeyEvents;
void mutt_refresh (void)
{
@@ -83,8 +94,11 @@
event_t err = {-1, OP_NULL }, ret;
event_t timeout = {-2, OP_NULL};
- if (!option(OPTUNBUFFEREDINPUT) && UngetCount)
- return (KeyEvent[--UngetCount]);
+ if (UngetCount)
+ return (UngetKeyEvents[--UngetCount]);
+
+ if (!option(OPTIGNOREMACROEVENTS) && MacroBufferCount)
+ return (MacroEvents[--MacroBufferCount]);
SigInt = 0;
@@ -118,7 +132,7 @@
{
/* send ALT-x as ESC-x */
ch &= ~0x80;
- mutt_ungetch (ch, 0);
+ mutt_unget_event (ch, 0);
ret.ch = '\033';
ret.op = 0;
return ret;
@@ -157,9 +171,9 @@
{
int rc;
- set_option (OPTUNBUFFEREDINPUT);
+ set_option (OPTIGNOREMACROEVENTS);
rc = mutt_get_field (msg, buf, buflen, flags);
- unset_option (OPTUNBUFFEREDINPUT);
+ unset_option (OPTIGNOREMACROEVENTS);
return (rc);
}
@@ -595,7 +609,7 @@
char *pc = safe_malloc (mutt_strlen (prompt) + 3);
sprintf (pc, "%s: ", prompt); /* __SPRINTF_CHECKED__ */
- mutt_ungetch (ch.op ? 0 : ch.ch, ch.op ? ch.op : 0);
+ mutt_unget_event (ch.op ? 0 : ch.ch, ch.op ? ch.op : 0);
if (_mutt_get_field (pc, buf, blen, (buffy ? M_EFILE : M_FILE) | M_CLEAR,
multiple, files, numfiles)
!= 0)
buf[0] = 0;
@@ -606,22 +620,60 @@
return 0;
}
-void mutt_ungetch (int ch, int op)
+void mutt_unget_event (int ch, int op)
{
event_t tmp;
tmp.ch = ch;
tmp.op = op;
- if (UngetCount >= UngetBufLen)
- safe_realloc (&KeyEvent, (UngetBufLen += 128) * sizeof(event_t));
+ if (UngetCount >= UngetLen)
+ safe_realloc (&UngetKeyEvents, (UngetLen += 16) * sizeof(event_t));
- KeyEvent[UngetCount++] = tmp;
+ UngetKeyEvents[UngetCount++] = tmp;
+}
+
+void mutt_unget_string (char *s)
+{
+ char *p = s + mutt_strlen (s) - 1;
+
+ while (p >= s)
+ {
+ mutt_unget_event ((unsigned char)*p--, 0);
+ }
+}
+
+/*
+ * Adds the ch/op to the macro buffer.
+ * This should be used for macros, push, and exec commands only.
+ */
+void mutt_push_macro_event (int ch, int op)
+{
+ event_t tmp;
+
+ tmp.ch = ch;
+ tmp.op = op;
+
+ if (MacroBufferCount >= MacroBufferLen)
+ safe_realloc (&MacroEvents, (MacroBufferLen += 128) * sizeof(event_t));
+
+ MacroEvents[MacroBufferCount++] = tmp;
+}
+
+void mutt_flush_macro_to_endcond (void)
+{
+ UngetCount = 0;
+ while (MacroBufferCount > 0)
+ {
+ if (MacroEvents[--MacroBufferCount].op == OP_END_COND)
+ return;
+ }
}
void mutt_flushinp (void)
{
UngetCount = 0;
+ MacroBufferCount = 0;
flushinp ();
}
diff -r 590ff6eebe1a -r 41af5a753d6f curs_main.c
--- a/curs_main.c Wed Sep 30 11:21:06 2015 +0800
+++ b/curs_main.c Sun Oct 18 20:05:37 2015 +0800
@@ -93,7 +93,8 @@
#define CHECK_ACL(aclbit,action) \
if (!mutt_bit_isset(Context->rights,aclbit)) { \
mutt_flushinp(); \
- mutt_error (_("Cannot %s: Operation not permitted by
ACL"), action); \
+ /* L10N: %s is one of the CHECK_ACL entries below. */ \
+ mutt_error (_("%s: Operation not permitted by ACL"),
action); \
break; \
}
@@ -108,8 +109,6 @@
#define OLDHDR Context->hdrs[Context->v2r[menu->oldcurrent]]
#define UNREAD(h) mutt_thread_contains_unread (Context, h)
-extern size_t UngetCount;
-
/* de facto standard escapes for tsl/fsl */
static char *tsl = "\033]0;";
static char *fsl = "\007";
@@ -728,12 +727,7 @@
if (!Context->tagged)
{
- event_t tmp;
- while(UngetCount>0)
- {
- tmp=mutt_getch();
- if(tmp.op==OP_END_COND)break;
- }
+ mutt_flush_macro_to_endcond ();
mutt_message _("Nothing to do.");
continue;
}
@@ -818,7 +812,7 @@
CHECK_MSGCOUNT;
CHECK_VISIBLE;
- if (isdigit (LastKey)) mutt_ungetch (LastKey, 0);
+ if (isdigit (LastKey)) mutt_unget_event (LastKey, 0);
buf[0] = 0;
if (mutt_get_field (_("Jump to message: "), buf, sizeof (buf), 0) != 0
|| !buf[0])
@@ -874,7 +868,8 @@
CHECK_MSGCOUNT;
CHECK_VISIBLE;
CHECK_READONLY;
- CHECK_ACL(M_ACL_DELETE, _("delete message(s)"));
+ /* L10N: CHECK_ACL */
+ CHECK_ACL(M_ACL_DELETE, _("Cannot delete message(s)"));
CHECK_ATTACH;
mutt_pattern_func (M_DELETE, _("Delete messages matching: "));
@@ -903,7 +898,7 @@
else
{
char buf[STRING];
- /* i18n: ask for a limit to apply */
+ /* L10N: ask for a limit to apply */
snprintf (buf, sizeof(buf), _("Limit: %s"),Context->pattern);
mutt_message ("%s", buf);
}
@@ -1047,7 +1042,8 @@
CHECK_MSGCOUNT;
CHECK_VISIBLE;
CHECK_READONLY;
- CHECK_ACL(M_ACL_DELETE, _("undelete message(s)"));
+ /* L10N: CHECK_ACL */
+ CHECK_ACL(M_ACL_DELETE, _("Cannot undelete message(s)"));
if (mutt_pattern_func (M_UNDELETE, _("Undelete messages matching: "))
== 0)
menu->redraw = REDRAW_INDEX | REDRAW_STATUS;
@@ -1354,7 +1350,8 @@
CHECK_MSGCOUNT;
CHECK_VISIBLE;
CHECK_READONLY;
- CHECK_ACL(M_ACL_DELETE, _("link threads"));
+ /* L10N: CHECK_ACL */
+ CHECK_ACL(M_ACL_DELETE, _("Cannot link threads"));
if ((Sort & SORT_MASK) != SORT_THREADS)
mutt_error _("Threading is not enabled.");
@@ -1605,8 +1602,20 @@
if (menu->current == -1)
{
menu->current = menu->oldcurrent;
- mutt_error ("%s%s.", (op == OP_MAIN_NEXT_NEW || op ==
OP_MAIN_PREV_NEW) ? _("No new messages") : _("No unread messages"),
- Context->pattern ? _(" in this limited view") : "");
+ if (op == OP_MAIN_NEXT_NEW || op == OP_MAIN_PREV_NEW)
+ {
+ if (Context->pattern)
+ mutt_error (_("No new messages in this limited view."));
+ else
+ mutt_error (_("No new messages."));
+ }
+ else
+ {
+ if (Context->pattern)
+ mutt_error (_("No unread messages in this limited view."));
+ else
+ mutt_error (_("No unread messages."));
+ }
}
else if (menu->menu == MENU_PAGER)
{
@@ -1622,7 +1631,8 @@
CHECK_MSGCOUNT;
CHECK_VISIBLE;
CHECK_READONLY;
- CHECK_ACL(M_ACL_WRITE, _("flag message"));
+ /* L10N: CHECK_ACL */
+ CHECK_ACL(M_ACL_WRITE, _("Cannot flag message"));
if (tag)
{
@@ -1659,7 +1669,8 @@
CHECK_MSGCOUNT;
CHECK_VISIBLE;
CHECK_READONLY;
- CHECK_ACL(M_ACL_SEEN, _("toggle new"));
+ /* L10N: CHECK_ACL */
+ CHECK_ACL(M_ACL_SEEN, _("Cannot toggle new"));
if (tag)
{
@@ -1913,7 +1924,8 @@
CHECK_MSGCOUNT;
CHECK_VISIBLE;
CHECK_READONLY;
- CHECK_ACL(M_ACL_DELETE, _("delete message"));
+ /* L10N: CHECK_ACL */
+ CHECK_ACL(M_ACL_DELETE, _("Cannot delete message"));
if (tag)
{
@@ -1954,7 +1966,8 @@
CHECK_MSGCOUNT;
CHECK_VISIBLE;
CHECK_READONLY;
- CHECK_ACL(M_ACL_DELETE, _("delete message(s)"));
+ /* L10N: CHECK_ACL */
+ CHECK_ACL(M_ACL_DELETE, _("Cannot delete message(s)"));
rc = mutt_thread_set_flag (CURHDR, M_DELETE, 1,
op == OP_DELETE_THREAD ? 0 : 1);
@@ -1995,7 +2008,8 @@
CHECK_VISIBLE;
CHECK_READONLY;
CHECK_ATTACH;
- CHECK_ACL(M_ACL_INSERT, _("edit message"));
+ /* L10N: CHECK_ACL */
+ CHECK_ACL(M_ACL_INSERT, _("Cannot edit message"));
if (option (OPTPGPAUTODEC) && (tag || !(CURHDR->security &
PGP_TRADITIONAL_CHECKED)))
mutt_check_traditional_pgp (tag ? NULL : CURHDR, &menu->redraw);
@@ -2126,7 +2140,8 @@
CHECK_MSGCOUNT;
CHECK_VISIBLE;
CHECK_READONLY;
- CHECK_ACL(M_ACL_SEEN, _("mark message(s) as read"));
+ /* L10N: CHECK_ACL */
+ CHECK_ACL(M_ACL_SEEN, _("Cannot mark message(s) as read"));
rc = mutt_thread_set_flag (CURHDR, M_READ, 1,
op == OP_MAIN_READ_THREAD ? 0 : 1);
@@ -2221,7 +2236,8 @@
CHECK_MSGCOUNT;
CHECK_VISIBLE;
CHECK_READONLY;
- CHECK_ACL(M_ACL_DELETE, _("undelete message"));
+ /* L10N: CHECK_ACL */
+ CHECK_ACL(M_ACL_DELETE, _("Cannot undelete message"));
if (tag)
{
@@ -2248,7 +2264,8 @@
CHECK_MSGCOUNT;
CHECK_VISIBLE;
CHECK_READONLY;
- CHECK_ACL(M_ACL_DELETE, _("undelete message(s)"));
+ /* L10N: CHECK_ACL */
+ CHECK_ACL(M_ACL_DELETE, _("Cannot undelete message(s)"));
rc = mutt_thread_set_flag (CURHDR, M_DELETE, 0,
op == OP_UNDELETE_THREAD ? 0 : 1);
diff -r 590ff6eebe1a -r 41af5a753d6f doc/devel-notes.txt
--- a/doc/devel-notes.txt Wed Sep 30 11:21:06 2015 +0800
+++ b/doc/devel-notes.txt Sun Oct 18 20:05:37 2015 +0800
@@ -196,6 +196,10 @@
from the times when this was an iso-8859-1 source code tree,
please feel free to fix them.
+- prefix translator comments with L10N:
+ /* L10N: this is a translator comment */
+ puts(_("String to translate));
+
Documentation
-------------
diff -r 590ff6eebe1a -r 41af5a753d6f edit.c
--- a/edit.c Wed Sep 30 11:21:06 2015 +0800
+++ b/edit.c Sun Oct 18 20:05:37 2015 +0800
@@ -393,6 +393,11 @@
be_print_header (msg->env);
for (i = 0; i < buflen; i++)
addstr (buf[i]);
+ /* L10N:
+ This entry is shown AFTER the message content,
+ not IN the middle of the content.
+ So it doesn't mean "(message will continue)"
+ but means "(press any key to continue using mutt)". */
addstr (_("(continue)\n"));
break;
case 'q':
diff -r 590ff6eebe1a -r 41af5a753d6f editmsg.c
--- a/editmsg.c Wed Sep 30 11:21:06 2015 +0800
+++ b/editmsg.c Sun Oct 18 20:05:37 2015 +0800
@@ -146,6 +146,7 @@
if (mx_open_mailbox (ctx->path, M_APPEND, &tmpctx) == NULL)
{
rc = -1;
+ /* L10N: %s is from strerror(errno) */
mutt_error (_("Can't append to folder: %s"), strerror (errno));
goto bail;
}
diff -r 590ff6eebe1a -r 41af5a753d6f hdrline.c
--- a/hdrline.c Wed Sep 30 11:21:06 2015 +0800
+++ b/hdrline.c Sun Oct 18 20:05:37 2015 +0800
@@ -219,6 +219,8 @@
* %N = score
* %O = like %L, except using address instead of name
* %P = progress indicator for builtin pager
+ * %r = comma separated list of To: recipients
+ * %R = comma separated list of Cc: recipients
* %s = subject
* %S = short message status (e.g., N/O/D/!/r/-)
* %t = `to:' field (recipients)
@@ -548,6 +550,22 @@
strfcpy(dest, NONULL(hfi->pager_progress), destlen);
break;
+ case 'r':
+ buf2[0] = 0;
+ rfc822_write_address(buf2, sizeof(buf2), hdr->env->to, 1);
+ if (optional && buf2[0] == '\0')
+ optional = 0;
+ mutt_format_s (dest, destlen, prefix, buf2);
+ break;
+
+ case 'R':
+ buf2[0] = 0;
+ rfc822_write_address(buf2, sizeof(buf2), hdr->env->cc, 1);
+ if (optional && buf2[0] == '\0')
+ optional = 0;
+ mutt_format_s (dest, destlen, prefix, buf2);
+ break;
+
case 's':
if (flags & M_FORMAT_TREE && !hdr->collapsed)
diff -r 590ff6eebe1a -r 41af5a753d6f imap/browse.c
--- a/imap/browse.c Wed Sep 30 11:21:06 2015 +0800
+++ b/imap/browse.c Sun Oct 18 20:05:37 2015 +0800
@@ -43,8 +43,8 @@
IMAP_DATA* idata;
IMAP_LIST list;
char buf[LONG_STRING];
- char buf2[LONG_STRING];
char mbox[LONG_STRING];
+ char munged_mbox[LONG_STRING];
char list_cmd[5];
int n;
int nsup;
@@ -72,13 +72,7 @@
if (mx.mbox && mx.mbox[0] != '\0')
{
int rc;
- char *ptr;
imap_fix_path (idata, mx.mbox, mbox, sizeof (mbox));
- ptr = safe_strdup (mbox);
- imap_utf7_encode (&ptr);
- mbox[sizeof (mbox) - 1] = '\0';
- strncpy (mbox, ptr, sizeof (mbox) - 1);
- FREE (&ptr);
n = mutt_strlen (mbox);
dprint (3, (debugfile, "imap_browse: mbox: %s\n", mbox));
@@ -87,7 +81,8 @@
* aren't already going to */
if (mbox[n-1] != idata->delim)
{
- snprintf (buf, sizeof (buf), "%s \"\" \"%s\"", list_cmd, mbox);
+ imap_munge_mbox_name (idata, munged_mbox, sizeof (munged_mbox), mbox);
+ snprintf (buf, sizeof (buf), "%s \"\" %s", list_cmd, munged_mbox);
imap_cmd_start (idata, buf);
idata->cmdtype = IMAP_CT_LIST;
idata->cmddata = &list;
@@ -180,9 +175,9 @@
dprint (3, (debugfile, "imap_browse: Quoting mailbox scan: %s -> ", mbox));
snprintf (buf, sizeof (buf), "%s%%", mbox);
- imap_quote_string (buf2, sizeof (buf2), buf);
- dprint (3, (debugfile, "%s\n", buf2));
- snprintf (buf, sizeof (buf), "%s \"\" %s", list_cmd, buf2);
+ imap_munge_mbox_name (idata, munged_mbox, sizeof (munged_mbox), buf);
+ dprint (3, (debugfile, "%s\n", munged_mbox));
+ snprintf (buf, sizeof (buf), "%s \"\" %s", list_cmd, munged_mbox);
if (browse_add_list_result (idata, buf, state, 0))
goto fail;
@@ -392,8 +387,12 @@
return rc == IMAP_CMD_OK ? 0 : -1;
}
-/* imap_add_folder: add a folder name to the browser list, formatting it as
- * necessary. */
+/* imap_add_folder:
+ * add a folder name to the browser list, formatting it as necessary.
+ *
+ * The folder parameter should already be 'unmunged' via
+ * imap_unmunge_mbox_name().
+ */
static void imap_add_folder (char delim, char *folder, int noselect,
int noinferiors, struct browser_state *state, short isparent)
{
@@ -404,8 +403,6 @@
if (imap_parse_path (state->folder, &mx))
return;
- imap_unmunge_mbox_name (folder);
-
if (state->entrylen + 1 == state->entrymax)
{
safe_realloc (&state->entry,
diff -r 590ff6eebe1a -r 41af5a753d6f imap/command.c
--- a/imap/command.c Wed Sep 30 11:21:06 2015 +0800
+++ b/imap/command.c Sun Oct 18 20:05:37 2015 +0800
@@ -51,6 +51,7 @@
static void cmd_parse_myrights (IMAP_DATA* idata, const char* s);
static void cmd_parse_search (IMAP_DATA* idata, const char* s);
static void cmd_parse_status (IMAP_DATA* idata, char* s);
+static void cmd_parse_enabled (IMAP_DATA* idata, const char* s);
static const char * const Capabilities[] = {
"IMAP4",
@@ -65,6 +66,7 @@
"LOGINDISABLED",
"IDLE",
"SASL-IR",
+ "ENABLE",
NULL
};
@@ -522,6 +524,8 @@
cmd_parse_search (idata, s);
else if (ascii_strncasecmp ("STATUS", s, 6) == 0)
cmd_parse_status (idata, s);
+ else if (ascii_strncasecmp ("ENABLED", s, 7) == 0)
+ cmd_parse_enabled (idata, s);
else if (ascii_strncasecmp ("BYE", s, 3) == 0)
{
dprint (2, (debugfile, "Handling BYE\n"));
@@ -728,7 +732,7 @@
}
else
{
- imap_unmunge_mbox_name (s);
+ imap_unmunge_mbox_name (idata, s);
list->name = s;
}
@@ -917,7 +921,7 @@
{
s = imap_next_word (mailbox);
*(s - 1) = '\0';
- imap_unmunge_mbox_name (mailbox);
+ imap_unmunge_mbox_name (idata, mailbox);
}
status = imap_mboxcache_get (idata, mailbox, 1);
@@ -1022,3 +1026,16 @@
FREE (&mx.mbox);
}
}
+
+/* cmd_parse_enabled: record what the server has enabled */
+static void cmd_parse_enabled (IMAP_DATA* idata, const char* s)
+{
+ dprint (2, (debugfile, "Handling ENABLED\n"));
+
+ while ((s = imap_next_word ((char*)s)) && *s != '\0')
+ {
+ if (ascii_strncasecmp(s, "UTF8=ACCEPT", 11) == 0 ||
+ ascii_strncasecmp(s, "UTF8=ONLY", 9) == 0)
+ idata->unicode = 1;
+ }
+}
diff -r 590ff6eebe1a -r 41af5a753d6f imap/imap.c
--- a/imap/imap.c Wed Sep 30 11:21:06 2015 +0800
+++ b/imap/imap.c Sun Oct 18 20:05:37 2015 +0800
@@ -92,7 +92,7 @@
return 0;
}
- imap_munge_mbox_name (mbox, sizeof (mbox), mailbox);
+ imap_munge_mbox_name (idata, mbox, sizeof (mbox), mailbox);
if (mutt_bit_isset (idata->capabilities, IMAP4REV1))
snprintf (buf, sizeof (buf), "STATUS %s (UIDVALIDITY)", mbox);
@@ -117,7 +117,7 @@
{
char buf[LONG_STRING], mbox[LONG_STRING];
- imap_munge_mbox_name (mbox, sizeof (mbox), mailbox);
+ imap_munge_mbox_name (idata, mbox, sizeof (mbox), mailbox);
snprintf (buf, sizeof (buf), "CREATE %s", mbox);
if (imap_exec (idata, buf, 0) != 0)
@@ -135,8 +135,8 @@
char newmbox[LONG_STRING];
char buf[LONG_STRING];
- imap_munge_mbox_name (oldmbox, sizeof (oldmbox), mx->mbox);
- imap_munge_mbox_name (newmbox, sizeof (newmbox), newname);
+ imap_munge_mbox_name (idata, oldmbox, sizeof (oldmbox), mx->mbox);
+ imap_munge_mbox_name (idata, newmbox, sizeof (newmbox), newname);
snprintf (buf, sizeof (buf), "RENAME %s %s", oldmbox, newmbox);
@@ -162,7 +162,7 @@
idata = ctx->data;
}
- imap_munge_mbox_name (mbox, sizeof (mbox), mx.mbox);
+ imap_munge_mbox_name (idata, mbox, sizeof (mbox), mx.mbox);
snprintf (buf, sizeof (buf), "DELETE %s", mbox);
if (imap_exec ((IMAP_DATA*) idata, buf, 0) != 0)
@@ -386,6 +386,9 @@
{
/* capabilities may have changed */
imap_exec (idata, "CAPABILITY", IMAP_CMD_QUEUE);
+ /* enable RFC6855, if the server supports that */
+ if (mutt_bit_isset (idata->capabilities, ENABLE))
+ imap_exec (idata, "ENABLE UTF8=ACCEPT", IMAP_CMD_QUEUE);
/* get root delimiter, '/' as default */
idata->delim = '/';
imap_exec (idata, "LIST \"\" \"\"", IMAP_CMD_QUEUE);
@@ -596,7 +599,7 @@
idata->newMailCount = 0;
mutt_message (_("Selecting %s..."), idata->mailbox);
- imap_munge_mbox_name (buf, sizeof(buf), idata->mailbox);
+ imap_munge_mbox_name (idata, buf, sizeof(buf), idata->mailbox);
/* pipeline ACL test */
if (mutt_bit_isset (idata->capabilities, ACL))
@@ -1521,7 +1524,7 @@
if (!lastdata)
lastdata = idata;
- imap_munge_mbox_name (munged, sizeof (munged), name);
+ imap_munge_mbox_name (idata, munged, sizeof (munged), name);
snprintf (command, sizeof (command),
"STATUS %s (UIDNEXT UIDVALIDITY UNSEEN RECENT)", munged);
@@ -1569,9 +1572,9 @@
else if (mutt_bit_isset(idata->capabilities,IMAP4REV1) ||
mutt_bit_isset(idata->capabilities,STATUS))
{
- imap_munge_mbox_name (mbox, sizeof(mbox), buf);
+ imap_munge_mbox_name (idata, mbox, sizeof(mbox), buf);
snprintf (buf, sizeof (buf), "STATUS %s (%s)", mbox, "MESSAGES");
- imap_unmunge_mbox_name (mbox);
+ imap_unmunge_mbox_name (idata, mbox);
}
else
/* Server does not support STATUS, and this is not the current mailbox.
@@ -1851,14 +1854,14 @@
mutt_message (_("Subscribing to %s..."), buf);
else
mutt_message (_("Unsubscribing from %s..."), buf);
- imap_munge_mbox_name (mbox, sizeof(mbox), buf);
+ imap_munge_mbox_name (idata, mbox, sizeof(mbox), buf);
snprintf (buf, sizeof (buf), "%sSUBSCRIBE %s", subscribe ? "" : "UN", mbox);
if (imap_exec (idata, buf, 0) < 0)
goto fail;
- imap_unmunge_mbox_name(mx.mbox);
+ imap_unmunge_mbox_name(idata, mx.mbox);
if (subscribe)
mutt_message (_("Subscribed to %s"), mx.mbox);
else
diff -r 590ff6eebe1a -r 41af5a753d6f imap/imap_private.h
--- a/imap/imap_private.h Wed Sep 30 11:21:06 2015 +0800
+++ b/imap/imap_private.h Sun Oct 18 20:05:37 2015 +0800