<<< Date Index >>>     <<< Thread Index >>>

Re: Bug#222191: patch-1.4.1.tt.compat.1 for mutt fixes this bug



Hi.

I rewrote compat patch for 1.5.6 and divided it according to the function.

- assuemd_charset patch
$assumed_charset
  This  variable is a colon-separated list of character encoding schemes 
  for messages without character encoding indication.  Header field values
  and message body content without character encoding indication would be 
  assumed that they are written in one of this list. By default, all the 
  header fields and message body without any charset indication are assumed
  to be in "us-ascii".
  However, only the first content is valid for the message body. 
  This variable is valid only if $strict_mime is unset.

$file_charset
  This variable is a colon-separated list of character encoding schemes for
  text file attatchments. If unset, $charset value will be used instead.

$strict_mime
  When unset, non MIME-compliant messages that doesn't have any charset 
  indication in "Content-Type" field can be displayed (non MIME-compliant
  messages are often generated by old mailers or buggy mailers like MS 
  Outlook Express).  See also $assumed_charset.
  This option also replaces linear-white-space between encoded-word and 
  *text to a single space to prevent the display of MIME-encoded "Subject"
  field from being devided into multiple lines.


- adjust_edited_file patch
If the edited file has not ended with a new-line, a new-line will be added 
in the end of the file.
When a character of the end of the edited file is not ASCII, the file 
to be converted to stateful charset to send does not end with the state 
of ASCII.
This patch corrects the problem.


- adjust_line patch
Mutt has some mistakes in the handling of the number of column and 
the number of bytes about the display of a line.
This patch corrects the bug.


- create_rfc2047_params patch
I think that especially explanation is not needed.
This patch may not be committed.


-- 
TAKIZAWA Takashi
http://www.emaillab.org/

diff -uNr mutt-1.5.6.orig/charset.c mutt-1.5.6/charset.c
--- mutt-1.5.6.orig/charset.c   Tue Jan 21 21:25:21 2003
+++ mutt-1.5.6/charset.c        Sun Feb 15 15:13:26 2004
@@ -581,3 +581,86 @@
     iconv_close (fc->cd);
   FREE (_fc);
 }
+
+char *mutt_get_first_charset (const char *charset)
+{
+  static char fcharset[SHORT_STRING];
+  const char *c, *c1;
+
+  c = charset;
+  if (!mutt_strlen(c))
+    return "us-ascii";
+  if (!(c1 = strchr (c, ':')))
+    return charset;
+  strfcpy (fcharset, c, c1 - c + 1);
+  return fcharset;
+}
+
+static size_t convert_string (ICONV_CONST char *f, size_t flen,
+                             const char *from, const char *to,
+                             char **t, size_t *tlen)
+{
+  iconv_t cd;
+  char *buf, *ob;
+  size_t obl, n;
+  int e;
+
+  cd = mutt_iconv_open (to, from, 0);
+  if (cd == (iconv_t)(-1))
+    return (size_t)(-1);
+  obl = 4 * flen + 1;
+  ob = buf = safe_malloc (obl);
+  n = iconv (cd, &f, &flen, &ob, &obl);
+  if (n == (size_t)(-1) || iconv (cd, 0, 0, &ob, &obl) == (size_t)(-1))
+  {
+    e = errno;
+    FREE (&buf);
+    iconv_close (cd);
+    errno = e;
+    return (size_t)(-1);
+  }
+  *ob = '\0';
+
+  *tlen = ob - buf;
+
+  safe_realloc ((void **) &buf, ob - buf + 1);
+  *t = buf;
+  iconv_close (cd);
+
+  return n;
+}
+
+int mutt_convert_nonmime_string (char **ps)
+{
+  const char *c, *c1;
+
+  for (c = AssumedCharset; c; c = c1 ? c1 + 1 : 0)
+  {
+    char *u = *ps;
+    char *s;
+    char *fromcode;
+    size_t m, n;
+    size_t ulen = mutt_strlen (*ps);
+    size_t slen;
+
+    if (!u || !*u)
+      return 0;
+
+    c1 = strchr (c, ':');
+    n = c1 ? c1 - c : mutt_strlen (c);
+    if (!n)
+      continue;
+    fromcode = safe_malloc (n + 1);
+    strfcpy (fromcode, c, n + 1);
+    m = convert_string (u, ulen, fromcode, Charset, &s, &slen);
+    FREE (&fromcode);
+    if (m != (size_t)(-1))
+    {
+      FREE (ps);
+      *ps = s;
+      return 0;
+    }
+  }
+  return -1;
+}
+
diff -uNr mutt-1.5.6.orig/charset.h mutt-1.5.6/charset.h
--- mutt-1.5.6.orig/charset.h   Tue Mar  4 16:49:43 2003
+++ mutt-1.5.6/charset.h        Sun Feb 15 15:06:19 2004
@@ -35,6 +35,8 @@
 #endif
 
 int mutt_convert_string (char **, const char *, const char *, int);
+char *mutt_get_first_charset (const char *);
+int mutt_convert_nonmime_string (char **);
 
 iconv_t mutt_iconv_open (const char *, const char *, int);
 size_t mutt_iconv (iconv_t, ICONV_CONST char **, size_t *, char **, size_t *, 
ICONV_CONST char **, const char *);
diff -uNr mutt-1.5.6.orig/globals.h mutt-1.5.6/globals.h
--- mutt-1.5.6.orig/globals.h   Mon Feb  2 02:15:17 2004
+++ mutt-1.5.6/globals.h        Sun Feb 15 15:06:19 2004
@@ -32,6 +32,7 @@
 
 WHERE char *AliasFile;
 WHERE char *AliasFmt;
+WHERE char *AssumedCharset;
 WHERE char *AttachSep;
 WHERE char *Attribution;
 WHERE char *AttachFormat;
@@ -45,6 +46,7 @@
 WHERE char *DsnReturn;
 WHERE char *Editor;
 WHERE char *EscChar;
+WHERE char *FileCharset;
 WHERE char *FolderFormat;
 WHERE char *ForwFmt;
 WHERE char *Fqdn;
diff -uNr mutt-1.5.6.orig/handler.c mutt-1.5.6/handler.c
--- mutt-1.5.6.orig/handler.c   Wed Nov  5 18:41:31 2003
+++ mutt-1.5.6/handler.c        Sun Feb 15 15:06:19 2004
@@ -1718,11 +1718,21 @@
   int istext = mutt_is_text_part (b);
   iconv_t cd = (iconv_t)(-1);
 
-  if (istext && s->flags & M_CHARCONV)
+  if (istext)
   {
-    char *charset = mutt_get_parameter ("charset", b->parameter);
-    if (charset && Charset)
-      cd = mutt_iconv_open (Charset, charset, M_ICONV_HOOK_FROM);
+    if(s->flags & M_CHARCONV)
+    {
+      char *charset = mutt_get_parameter ("charset", b->parameter);
+      if (!option (OPTSTRICTMIME) && !charset)
+        charset = mutt_get_first_charset (AssumedCharset);
+      if (charset && Charset)
+        cd = mutt_iconv_open (Charset, charset, M_ICONV_HOOK_FROM);
+    }
+    else
+    {
+      if (b->file_charset)
+        cd = mutt_iconv_open (Charset, b->file_charset, M_ICONV_HOOK_FROM);
+    }
   }
 
   fseek (s->fpin, b->offset, 0);
diff -uNr mutt-1.5.6.orig/init.h mutt-1.5.6/init.h
--- mutt-1.5.6.orig/init.h      Mon Feb  2 02:15:17 2004
+++ mutt-1.5.6/init.h   Sun Feb 15 15:07:40 2004
@@ -184,6 +184,23 @@
   ** If set, Mutt will prompt you for carbon-copy (Cc) recipients before
   ** editing the body of an outgoing message.
   */  
+  { "assumed_charset", DT_STR, R_NONE, UL &AssumedCharset, UL "us-ascii"},
+  /*
+  ** .pp
+  ** This variable is a colon-separated list of character encoding
+  ** schemes for messages without character encoding indication.
+  ** Header field values and message body content without character encoding
+  ** indication would be assumed that they are written in one of this list.
+  ** By default, all the header fields and message body without any charset
+  ** indication are assumed to be in "us-ascii".
+  ** .pp
+  ** For example, Japanese users might prefer this:
+  ** .pp
+  **   set assumed_charset="iso-2022-jp:euc-jp:shift_jis:utf-8"
+  ** .pp
+  ** However, only the first content is valid for the message body.
+  ** This variable is valid only if $$strict_mime is unset.
+  */
   { "attach_format",   DT_STR,  R_NONE, UL &AttachFormat, UL "%u%D%I %t%4n 
%T%.40d%> [%.7m/%.10M, %.6e%?C?, %C?, %s] " },
   /*
   ** .pp
@@ -532,6 +549,20 @@
   ** signed.
   ** (PGP only)
   */
+  { "file_charset",    DT_STR,  R_NONE, UL &FileCharset, UL 0 },
+  /*
+  ** .pp
+  ** This variable is a colon-separated list of character encoding
+  ** schemes for text file attatchments.
+  ** If unset, $$charset value will be used instead.
+  ** For example, the following configuration would work for Japanese
+  ** text handling:
+  ** .pp
+  **   set file_charset="iso-2022-jp:euc-jp:shift_jis:utf-8"
+  ** .pp
+  ** Note: "iso-2022-*" must be put at the head of the value as shown above
+  ** if included.
+  */
   { "folder",          DT_PATH, R_NONE, UL &Maildir, UL "~/Mail" },
   /*
   ** .pp
@@ -2476,6 +2507,19 @@
   ** Setting this variable causes the ``status bar'' to be displayed on
   ** the first line of the screen rather than near the bottom.
   */
+  { "strict_mime",    DT_BOOL, R_NONE, OPTSTRICTMIME, 1 },
+  /*
+  ** .pp
+  ** When unset, non MIME-compliant messages that doesn't have any
+  ** charset indication in ``Content-Type'' field can be displayed
+  ** (non MIME-compliant messages are often generated by old mailers
+  ** or buggy mailers like MS Outlook Express).
+  ** See also $$assumed_charset.
+  ** .pp
+  ** This option also replaces linear-white-space between encoded-word
+  ** and *text to a single space to prevent the display of MIME-encoded
+  ** ``Subject'' field from being devided into multiple lines.
+  */
   { "strict_threads",  DT_BOOL, R_RESORT|R_RESORT_INIT|R_INDEX, 
OPTSTRICTTHREADS, 0 },
   /*
   ** .pp
diff -uNr mutt-1.5.6.orig/mutt.h mutt-1.5.6/mutt.h
--- mutt-1.5.6.orig/mutt.h      Mon Feb  2 02:15:17 2004
+++ mutt-1.5.6/mutt.h   Sun Feb 15 15:06:19 2004
@@ -406,6 +406,7 @@
   OPTSIGONTOP,
   OPTSORTRE,
   OPTSTATUSONTOP,
+  OPTSTRICTMIME,
   OPTSTRICTTHREADS,
   OPTSUSPEND,
   OPTTEXTFLOWED,
@@ -599,6 +600,7 @@
                                 * If NULL, filename is used 
                                 * instead.
                                 */
+  char *file_charset;           /* charset of attached file */
   CONTENT *content;             /* structure used to store detailed info about
                                 * the content of the attachment.  this is used
                                 * to determine what content-transfer-encoding
diff -uNr mutt-1.5.6.orig/parse.c mutt-1.5.6/parse.c
--- mutt-1.5.6.orig/parse.c     Wed Nov  5 18:41:33 2003
+++ mutt-1.5.6/parse.c  Sun Feb 15 15:06:19 2004
@@ -208,9 +208,23 @@
 
       if (*s == '"')
       {
+        int state_ascii = 1;
        s++;
-       for (i=0; *s && *s != '"' && i < sizeof (buffer) - 1; i++, s++)
+       for (i=0; *s && i < sizeof (buffer) - 1; i++, s++)
        {
+         if (!option (OPTSTRICTMIME)) {
+            /* As iso-2022-* has a characer of '"' with non-ascii state,
+            * ignore it. */
+            if (*s == 0x1b && i < sizeof (buffer) - 2)
+            {
+              if (s[1] == '(' && (s[2] == 'B' || s[2] == 'J'))
+                state_ascii = 1;
+              else
+                state_ascii = 0;
+            }
+          }
+          if (state_ascii && *s == '"')
+            break;
          if (*s == '\\')
          {
            /* Quote the next character */
@@ -379,7 +393,9 @@
   if (ct->type == TYPETEXT)
   {
     if (!(pc = mutt_get_parameter ("charset", ct->parameter)))
-      mutt_set_parameter ("charset", "us-ascii", &ct->parameter);
+      mutt_set_parameter ("charset", option (OPTSTRICTMIME) ? "us-ascii" :
+                         (const char *) mutt_get_first_charset 
(AssumedCharset),
+                         &ct->parameter);
   }
 
 }
diff -uNr mutt-1.5.6.orig/rfc2047.c mutt-1.5.6/rfc2047.c
--- mutt-1.5.6.orig/rfc2047.c   Wed Nov  5 18:41:33 2003
+++ mutt-1.5.6/rfc2047.c        Sun Feb 15 15:13:58 2004
@@ -706,13 +706,54 @@
   return 0;
 }
 
+/* return length of linear white space */
+static size_t lwslen (const char *s, size_t n)
+{
+  const char *p = s;
+  size_t len = n;
+
+  if (n <= 0)
+    return 0;
+
+  for (; p < s + n; p++)
+    if (!strchr (" \t\r\n", *p))
+    {
+      len = (size_t)(p - s);
+      break;
+    }
+  if (strchr ("\r\n", *(p-1))) /* LWS doesn't end with CRLF */
+    len = (size_t)0;
+  return len;
+}
+
+/* return length of linear white space : reverse */
+static size_t lwsrlen (const char *s, size_t n)
+{
+  const char *p = s + n - 1;
+  size_t len = n;
+
+  if (n <= 0)
+    return 0;
+
+  if (strchr ("\r\n", *p)) /* LWS doesn't end with CRLF */
+    return (size_t)0;
+
+  for (; p >= s; p--)
+    if (!strchr (" \t\r\n", *p))
+    {
+      len = (size_t)(s + n - 1 - p);
+      break;
+    }
+  return len;
+}
+
 /* try to decode anything that looks like a valid RFC2047 encoded
  * header field, ignoring RFC822 parsing rules
  */
 void rfc2047_decode (char **pd)
 {
   const char *p, *q;
-  size_t n;
+  size_t m, n;
   int found_encoded = 0;
   char *d0, *d;
   const char *s = *pd;
@@ -729,6 +770,37 @@
     if (!(p = find_encoded_word (s, &q)))
     {
       /* no encoded words */
+      if (!option (OPTSTRICTMIME))
+      {
+        n = mutt_strlen (s);
+        if (found_encoded && (m = lwslen (s, n)) != 0)
+        {
+          if (m != n)
+            *d = ' ', d++, dlen--;
+          n -= m, s += m;
+        }
+        if (ascii_strcasecmp (AssumedCharset, "us-ascii"))
+        {
+          char *t;
+          size_t tlen;
+
+          t = safe_malloc (n + 1);
+          strfcpy (t, s, n + 1);
+          if (mutt_convert_nonmime_string (&t) == 0)
+          {
+            tlen = mutt_strlen (t);
+            strncpy (d, t, tlen);
+            d += tlen;
+          }
+          else
+          {
+            strncpy (d, s, n);
+            d += n;
+          }
+          FREE (&t);
+          break;
+        }
+      }
       strncpy (d, s, dlen);
       d += dlen;
       break;
@@ -737,15 +809,37 @@
     if (p != s)
     {
       n = (size_t) (p - s);
-      /* ignore spaces between encoded words */
-      if (!found_encoded || strspn (s, " \t\r\n") != n)
+      /* ignore spaces between encoded words
+       * and linear white spaces between encoded word and *text */
+      if (!option (OPTSTRICTMIME))
       {
-       if (n > dlen)
-         n = dlen;
-       memcpy (d, s, n);
-       d += n;
-       dlen -= n;
+        if (found_encoded && (m = lwslen (s, n)) != 0)
+        {
+          if (m != n)
+            *d = ' ', d++, dlen--;
+          n -= m, s += m;
+        }
+
+        if ((m = n - lwsrlen (s, n)) != 0)
+        {
+          if (m > dlen)
+            m = dlen;
+          memcpy (d, s, m);
+          d += m;
+          dlen -= m;
+          if (m != n)
+            *d = ' ', d++, dlen--;
+        }
       }
+      else if (!found_encoded || strspn (s, " \t\r\n") != n)
+      {
+        if (n > dlen)
+          n = dlen;
+        memcpy (d, s, n);
+        d += n;
+        dlen -= n;
+      }
+
     }
 
     rfc2047_decode_word (d, p, dlen);
@@ -766,7 +860,7 @@
 {
   while (a)
   {
-    if (a->personal && strstr (a->personal, "=?") != NULL)
+    if (a->personal)
       rfc2047_decode (&a->personal);
 #ifdef EXACT_ADDRESS
     if (a->val && strstr (a->val, "=?") != NULL)
diff -uNr mutt-1.5.6.orig/rfc2231.c mutt-1.5.6/rfc2231.c
--- mutt-1.5.6.orig/rfc2231.c   Wed Nov  5 18:41:33 2003
+++ mutt-1.5.6/rfc2231.c        Sun Feb 15 15:06:19 2004
@@ -113,6 +113,11 @@
 
       if (option (OPTRFC2047PARAMS) && p->value && strstr (p->value, "=?"))
        rfc2047_decode (&p->value);
+      else if (!option (OPTSTRICTMIME))
+      {
+        if (ascii_strcasecmp (AssumedCharset, "us-ascii"))
+          mutt_convert_nonmime_string (&p->value);
+      }
 
       *last = p;
       last = &p->next;
diff -uNr mutt-1.5.6.orig/sendlib.c mutt-1.5.6/sendlib.c
--- mutt-1.5.6.orig/sendlib.c   Wed Nov  5 18:41:33 2003
+++ mutt-1.5.6/sendlib.c        Sun Feb 15 15:11:33 2004
@@ -496,7 +496,7 @@
   }
 
   if (a->type == TYPETEXT && (!a->noconv))
-    fc = fgetconv_open (fpin, Charset, 
+    fc = fgetconv_open (fpin, a->file_charset, 
                        mutt_get_body_charset (send_charset, sizeof 
(send_charset), a),
                        0);
   else
@@ -896,6 +896,7 @@
   CONTENT *info;
   CONTENT_STATE state;
   FILE *fp = NULL;
+  char *fromcode;
   char *tocode;
   char buffer[100];
   char chsbuf[STRING];
@@ -930,15 +931,18 @@
   if (b != NULL && b->type == TYPETEXT && (!b->noconv && !b->force_charset))
   {
     char *chs = mutt_get_parameter ("charset", b->parameter);
+    char *fchs = b->use_disp ? ((FileCharset && *FileCharset) ?
+                                FileCharset : Charset) : Charset;
     if (Charset && (chs || SendCharset) &&
-       convert_file_from_to (fp, Charset, chs ? chs : SendCharset,
-                             0, &tocode, info) != (size_t)(-1))
+        convert_file_from_to (fp, fchs, chs ? chs : SendCharset,
+                              &fromcode, &tocode, info) != (size_t)(-1))
     {
       if (!chs)
       {
        mutt_canonical_charset (chsbuf, sizeof (chsbuf), tocode);
        mutt_set_parameter ("charset", chsbuf, &b->parameter);
       }
+      b->file_charset = fromcode;
       FREE (&tocode);
       safe_fclose (&fp);
       return info;
@@ -1318,6 +1322,7 @@
   body->unlink = 1;
   body->use_disp = 0;
   body->disposition = DISPINLINE;
+  body->noconv = 1;
 
   mutt_parse_mime_message (ctx, hdr);
 
diff -uNr mutt-1.5.6.orig/PATCHES mutt-1.5.6/PATCHES
--- mutt-1.5.6.orig/PATCHES     Mon Feb  2 02:42:47 2004
+++ mutt-1.5.6/PATCHES  Sun Feb 15 15:14:55 2004
@@ -0,0 +1 @@
+patch-1.5.6.tt.assumed_charset.1
diff -uNr mutt-1.5.6.orig/PATCHES mutt-1.5.6/PATCHES
--- mutt-1.5.6.orig/PATCHES     Mon Feb  2 02:42:47 2004
+++ mutt-1.5.6/PATCHES  Sun Feb 15 18:12:21 2004
@@ -0,0 +1 @@
+patch-1.5.6.tt.adjust_edited_file.1
diff -uNr mutt-1.5.6.orig/curs_lib.c mutt-1.5.6/curs_lib.c
--- mutt-1.5.6.orig/curs_lib.c  Wed Nov  5 18:41:31 2003
+++ mutt-1.5.6/curs_lib.c       Sun Feb 15 18:12:11 2004
@@ -43,6 +43,19 @@
 static size_t UngetBufLen = 0;
 static event_t *KeyEvent;
 
+static void adjust_edited_file (const char *data)
+{
+  FILE *fp;
+  int c;
+
+  if ((fp = safe_fopen (data, "a+")) == NULL)
+    return;
+  fseek (fp,-1,SEEK_END);
+  if ((c = fgetc(fp)) != '\n')
+    fputc ('\n', fp);
+  safe_fclose (&fp);
+}
+
 void mutt_refresh (void)
 {
   /* don't refresh when we are waiting for a child. */
@@ -147,6 +160,7 @@
   mutt_expand_file_fmt (cmd, sizeof (cmd), editor, data);
   if (mutt_system (cmd) == -1)
     mutt_error (_("Error running \"%s\"!"), cmd);
+  adjust_edited_file (data);
   keypad (stdscr, TRUE);
   clearok (stdscr, TRUE);
 }
diff -uNr mutt-1.5.6.orig/curs_lib.c mutt-1.5.6/curs_lib.c
--- mutt-1.5.6.orig/curs_lib.c  Wed Nov  5 18:41:31 2003
+++ mutt-1.5.6/curs_lib.c       Sun Feb 15 18:04:18 2004
@@ -575,7 +575,7 @@
       wc = replacement_char ();
     }
     if (arboreal && wc < M_TREE_MAX)
-      w = 1; /* hack */
+      w = mutt_mbswidth ((char *)s,1);
     else
     {
       if (!IsWPrint (wc))
diff -uNr mutt-1.5.6.orig/muttlib.c mutt-1.5.6/muttlib.c
--- mutt-1.5.6.orig/muttlib.c   Mon Feb  2 02:15:17 2004
+++ mutt-1.5.6/muttlib.c        Sun Feb 15 18:04:18 2004
@@ -23,6 +23,7 @@
 #include "mailbox.h"
 #include "mx.h"
 #include "url.h"
+#include "mbyte.h"
 
 #include "reldate.h"
 
@@ -913,6 +914,42 @@
 }
 
 
+/* return width of multibyte character string */
+size_t mutt_mbswidth (char *s, size_t n)
+{
+  wchar_t wc;
+  size_t j,k,l,m;
+  mbstate_t mbstate;
+
+  l = 0;
+  if (!s)
+    return 0;
+  memset (&mbstate, 0, sizeof (mbstate));
+  while (*s && n)
+  {
+    j = (int)*s;
+    if (j < M_TREE_MAX)
+    {
+      if (Charset_is_utf8)
+        l += 1;        /* FIXME: width of WACS character is not always 1 */
+      else
+        l++;
+      s++, n--;
+    }
+    else
+    {
+      k = mbrtowc (&wc, s, n, &mbstate);
+      if (k == (size_t)(-1) || k == (size_t)(-2))
+        break;
+      m = wcwidth (wc);
+      l += (m > 0) ? m : 0;
+      s += k, n -= k;
+    }
+  }
+  return l;
+}
+
+
 void mutt_FormatString (char *dest,            /* output buffer */
                        size_t destlen,         /* output buffer len */
                        const char *src,        /* template string */
@@ -1024,7 +1061,7 @@
            len = destlen - wlen;
          memcpy (wptr, buf, len);
          wptr += len;
-         wlen += len;
+         wlen += mutt_mbswidth (buf, len);
        }
        break; /* skip rest of input */
       }
@@ -1075,7 +1112,7 @@
 
        memcpy (wptr, buf, len);
        wptr += len;
-       wlen += len;
+       wlen += mutt_mbswidth (buf, len);
       }
     }
     else if (*src == '\\')
diff -uNr mutt-1.5.6.orig/pager.c mutt-1.5.6/pager.c
--- mutt-1.5.6.orig/pager.c     Mon Feb  2 02:10:57 2004
+++ mutt-1.5.6/pager.c  Sun Feb 15 18:04:18 2004
@@ -1706,15 +1706,17 @@
       CLEARLINE (statusoffset);
       if (IsHeader (extra))
       {
-       _mutt_make_string (buffer,
-                          COLS-9 < sizeof (buffer) ? COLS-9 : sizeof (buffer),
-                          NONULL (PagerFmt), Context, extra->hdr, 
M_FORMAT_MAKEPRINT);
+       size_t l1 = (COLS - 9) * MB_LEN_MAX;
+       size_t l2 = sizeof (buffer);
+       _mutt_make_string (buffer, l1 < l2 ? l1 : l2, NONULL (PagerFmt),
+                          Context, extra->hdr, M_FORMAT_MAKEPRINT);
       }
       else if (IsMsgAttach (extra))
       {
-       _mutt_make_string (buffer,
-                          COLS - 9 < sizeof (buffer) ? COLS - 9: sizeof 
(buffer),
-                          NONULL (PagerFmt), Context, extra->bdy->hdr, 
M_FORMAT_MAKEPRINT);
+       size_t l1 = (COLS - 9) * MB_LEN_MAX;
+       size_t l2 = sizeof (buffer);
+       _mutt_make_string (buffer, l1 < l2 ? l1 : l2, NONULL (PagerFmt),
+                          Context, extra->bdy->hdr, M_FORMAT_MAKEPRINT);
       }
       mutt_paddstr (COLS-10, IsHeader (extra) || IsMsgAttach (extra) ?
                    buffer : banner);
diff -uNr mutt-1.5.6.orig/protos.h mutt-1.5.6/protos.h
--- mutt-1.5.6.orig/protos.h    Mon Feb  2 02:15:17 2004
+++ mutt-1.5.6/protos.h Sun Feb 15 18:04:18 2004
@@ -350,6 +350,7 @@
 
 /* utf8.c */
 int mutt_wctoutf8 (char *s, unsigned int c);
+size_t mutt_mbswidth (char *s, size_t n);
 
 #ifdef LOCALES_HACK
 #define IsPrint(c) (isprint((unsigned char)(c)) || \
diff -uNr mutt-1.5.6.orig/PATCHES mutt-1.5.6/PATCHES
--- mutt-1.5.6.orig/PATCHES     Mon Feb  2 02:42:47 2004
+++ mutt-1.5.6/PATCHES  Sun Feb 15 18:04:31 2004
@@ -0,0 +1 @@
+patch-1.5.6.tt.adjust_line.1
diff -uNr mutt-1.5.6.orig/init.h mutt-1.5.6/init.h
--- mutt-1.5.6.orig/init.h      Mon Feb  2 02:15:17 2004
+++ mutt-1.5.6/init.h   Sun Feb 15 14:59:43 2004
@@ -369,6 +369,17 @@
   ** ``$$crypt_replyencrypt'',
   ** ``$$crypt_autosign'', ``$$crypt_replysign'' and ``$$smime_is_default''.
   */
+  { "create_rfc2047_parameters", DT_BOOL, R_NONE, OPTCREATERFC2047PARAMS, 0 },
+  /*
+  ** .pp
+  ** When this variable is set, Mutt will add the following RFC-2047-encoded
+  ** MIME parameter to Content-Type header field as filename for attachment:
+  ** name="=?iso-2022-jp?B?GyRCO244MxsoQi50eHQ=?="
+  ** .pp
+  ** Note: this use of RFC 2047's encoding is explicitly prohibited
+  ** by the standard. You may set this variable only if a mailer
+  ** of recipients can not parse RFC 2231 parameters.
+  */
   { "date_format",     DT_STR,  R_BOTH, UL &DateFmt, UL "!%a, %b %d, %Y at 
%I:%M:%S%p %Z" },
   /*
   ** .pp
diff -uNr mutt-1.5.6.orig/mutt.h mutt-1.5.6/mutt.h
--- mutt-1.5.6.orig/mutt.h      Mon Feb  2 02:15:17 2004
+++ mutt-1.5.6/mutt.h   Sun Feb 15 14:59:43 2004
@@ -332,6 +332,7 @@
   OPTCOLLAPSEUNREAD,
   OPTCONFIRMAPPEND,
   OPTCONFIRMCREATE,
+  OPTCREATERFC2047PARAMS,
   OPTDELETEUNTAG,
   OPTDIGESTCOLLAPSE,
   OPTDUPTHREADS,
diff -uNr mutt-1.5.6.orig/sendlib.c mutt-1.5.6/sendlib.c
--- mutt-1.5.6.orig/sendlib.c   Wed Nov  5 18:41:33 2003
+++ mutt-1.5.6/sendlib.c        Sun Feb 15 14:59:43 2004
@@ -403,6 +403,33 @@
     }
   }
 
+  if (a->use_disp && option (OPTCREATERFC2047PARAMS))
+  {
+    if(!(fn = a->d_filename))
+      fn = a->filename;
+
+    if (fn)
+    {
+      char *tmp;
+
+      /* Strip off the leading path... */
+      if ((t = strrchr (fn, '/')))
+       t++;
+      else
+        t = fn;
+
+      /* length of content-type */
+      len = 21 + mutt_strlen (TYPE (a)) + mutt_strlen (a->subtype);
+
+      buffer[0] = 0;
+      tmp = safe_strdup (t);
+      _rfc2047_encode_string (&tmp, 0, len);
+      rfc822_cat (buffer, sizeof (buffer), tmp, MimeSpecials);
+      FREE (&tmp);
+      fprintf (f, "; name=%s", buffer);
+    }
+  }
+
   fputc ('\n', f);
 
   if (a->description)
diff -uNr mutt-1.5.6.orig/PATCHES mutt-1.5.6/PATCHES
--- mutt-1.5.6.orig/PATCHES     Mon Feb  2 02:42:47 2004
+++ mutt-1.5.6/PATCHES  Sun Feb 15 15:00:10 2004
@@ -0,0 +1 @@
+patch-1.5.6.tt.create_rfc2047_params.1