move rfc2047.c into lib-mime, reindent it.
authorPierre Habouzit <madcoder@debian.org>
Fri, 3 Nov 2006 23:04:45 +0000 (00:04 +0100)
committerPierre Habouzit <madcoder@debian.org>
Fri, 3 Nov 2006 23:04:45 +0000 (00:04 +0100)
replace str_replace with m_strreplace. I don't like that function at all.

Signed-off-by: Pierre Habouzit <madcoder@debian.org>
33 files changed:
alias.c
attach.c
browser.c
charset.h
compose.c
crypt-gpgme.c
curs_main.c
edit.c
gnupgparse.c
history.c
init.c
lib-lib/str.h
lib-mime/Makefile.am
lib-mime/mime.h
lib-mime/rfc2047.c [new file with mode: 0644]
lib/str.c
lib/str.h
main.c
menu.c
mh.c
muttlib.c
parse.c
pgp.c
pgpkey.c
postpone.c
recvattach.c
rfc1524.c
rfc2047.c [deleted file]
rfc3676.c
send.c
sendlib.c
smime.c
url.c

diff --git a/alias.c b/alias.c
index 9be40dc..bc5a25a 100644 (file)
--- a/alias.c
+++ b/alias.c
@@ -101,7 +101,7 @@ static address_t *mutt_expand_aliases_r (address_t * a, LIST ** expn)
           char namebuf[STRING];
 
           mutt_gecos_name (namebuf, sizeof (namebuf), pw);
-          str_replace (&a->personal, namebuf);
+          m_strreplace (&a->personal, namebuf);
         }
       }
     }
index c590309..5f588b7 100644 (file)
--- a/attach.c
+++ b/attach.c
@@ -66,7 +66,7 @@ int mutt_get_tmp_attachment (BODY * a)
 
   if ((fpin = fopen (a->filename, "r")) && (fpout = safe_fopen (tempfile, "w"))) {      /* __FOPEN_CHECKED__ */
     mutt_copy_stream (fpin, fpout);
-    str_replace (&a->filename, tempfile);
+    m_strreplace(&a->filename, tempfile);
     a->unlink = 1;
 
     if (a->stamp >= st.st_mtime)
index e22e1ea..d91d0ef 100644 (file)
--- a/browser.c
+++ b/browser.c
@@ -1204,7 +1204,7 @@ void _mutt_select_file (char *f, size_t flen, int flags, char ***files,
           mutt_error ("%s", buf);
         }
         else {
-          str_replace (&Mask.pattern, buf);
+          m_strreplace(&Mask.pattern, buf);
           regfree (Mask.rx);
           p_delete(&Mask.rx);
           Mask.rx = rx;
index f8fcc98..5b3b732 100644 (file)
--- a/charset.h
+++ b/charset.h
@@ -29,8 +29,8 @@ typedef void *iconv_t;
 #  define my_iconv(a,b,c,d,e)  0
 #  define iconv_close(a)       0
 #else
-static inline size_t my_iconv(iconv_t ict, const char **inbuf, size_t *ilen,
-                              char **outbuf, size_t *olen)
+static inline ssize_t my_iconv(iconv_t ict, const char **inbuf, size_t *ilen,
+                               char **outbuf, size_t *olen)
 {
     return iconv(ict, (char **)inbuf, ilen, outbuf, olen);
 }
index 3d5f39c..3401388 100644 (file)
--- a/compose.c
+++ b/compose.c
@@ -673,7 +673,7 @@ int mutt_compose_menu (HEADER * msg,    /* structure for new message */
       else
         buf[0] = 0;
       if (mutt_get_field ("Subject: ", buf, sizeof (buf), 0) == 0) {
-        str_replace (&msg->env->subject, buf);
+        m_strreplace(&msg->env->subject, buf);
         move (HDR_SUBJECT, HDR_XOFFSET + SW);
         clrtoeol ();
         if (msg->env->subject)
@@ -1002,7 +1002,7 @@ int mutt_compose_menu (HEADER * msg,    /* structure for new message */
                NONULL(idx[menu->current]->content->description));
       /* header names should not be translated */
       if (mutt_get_field ("Description: ", buf, sizeof (buf), 0) == 0) {
-        str_replace (&idx[menu->current]->content->description, buf);
+        m_strreplace(&idx[menu->current]->content->description, buf);
         menu->redraw = REDRAW_CURRENT;
       }
       mutt_message_hook (NULL, msg, M_SEND2HOOK);
@@ -1150,7 +1150,7 @@ int mutt_compose_menu (HEADER * msg,    /* structure for new message */
         if (mutt_rename_file (idx[menu->current]->content->filename, fname))
           break;
 
-        str_replace (&idx[menu->current]->content->filename, fname);
+        m_strreplace(&idx[menu->current]->content->filename, fname);
         menu->redraw = REDRAW_CURRENT;
 
         if (idx[menu->current]->content->stamp >= st.st_mtime)
@@ -1212,7 +1212,7 @@ int mutt_compose_menu (HEADER * msg,    /* structure for new message */
         update_idx (menu, idx, idxlen++);
 
         idx[menu->current]->content->type = itype;
-        str_replace (&idx[menu->current]->content->subtype, p);
+        m_strreplace(&idx[menu->current]->content->subtype, p);
         idx[menu->current]->content->unlink = 1;
         menu->redraw |= REDRAW_INDEX | REDRAW_STATUS;
 
index 32efdb7..4255156 100644 (file)
@@ -3636,7 +3636,7 @@ static crypt_key_t *crypt_ask_for_key (char *tag,
 
     if (whatfor) {
       if (l)
-        str_replace (&l->dflt, resp);
+        m_strreplace(&l->dflt, resp);
       else {
         l = p_new(struct crypt_cache, 1);
         l->next = id_defaults;
@@ -3854,7 +3854,7 @@ static int gpgme_send_menu (HEADER * msg, int *redraw, int is_smime)
                                 is_smime ? APPLICATION_SMIME :
                                 APPLICATION_PGP, NULL))) {
       snprintf (input_signas, sizeof (input_signas), "0x%s", crypt_keyid (p));
-      str_replace (is_smime ? &SmimeDefaultKey : &PgpSignAs,
+      m_strreplace(is_smime ? &SmimeDefaultKey : &PgpSignAs,
                         input_signas);
       crypt_free_key (&p);
 
index a62f166..36ed33a 100644 (file)
@@ -1233,18 +1233,18 @@ int mutt_index_menu (void)
         mutt_error (_("%s is not a mailbox."), buf);
         break;
       }
-      str_replace (&CurrentFolder, buf);
+      m_strreplace(&CurrentFolder, buf);
 
       if (Context) {
         int check;
 
 #ifdef USE_COMPRESSED
         if (Context->compressinfo && Context->realpath)
-          str_replace (&LastFolder, Context->realpath);
+          m_strreplace(&LastFolder, Context->realpath);
         else
 #endif
 
-          str_replace (&LastFolder, Context->path);
+          m_strreplace(&LastFolder, Context->path);
         oldcount = Context ? Context->msgcount : 0;
 
         if ((check = mx_close_mailbox (Context, &index_hint)) != 0) {
diff --git a/edit.c b/edit.c
index f6cfcf6..ff19e35 100644 (file)
--- a/edit.c
+++ b/edit.c
@@ -249,7 +249,7 @@ static void be_edit_header (ENVELOPE * e, int force)
     addstr ("Subject: ");
     m_strcpy(tmp, sizeof(tmp), NONULL(e->subject));
     if (mutt_enter_string (tmp, sizeof (tmp), LINES - 1, 9, 0) == 0)
-      str_replace (&e->subject, tmp);
+      m_strreplace(&e->subject, tmp);
     addch ('\n');
   }
 
@@ -382,7 +382,7 @@ int mutt_builtin_editor (const char *path, HEADER * msg, HEADER * cur)
           addstr (_("missing filename.\n"));
         break;
       case 's':
-        str_replace (&msg->env->subject, p);
+        m_strreplace(&msg->env->subject, p);
         break;
       case 't':
         msg->env->to = rfc822_parse_adrlist (msg->env->to, p);
index b9f00ba..cdce751 100644 (file)
@@ -204,7 +204,7 @@ static pgp_key_t parse_pub_line (char *buf, int *is_subkey, pgp_key_t k)
         debug_print (2, ("key id: %s\n", p));
 
         if (!(*is_subkey && option (OPTPGPIGNORESUB)))
-          str_replace (&k->keyid, p);
+          m_strreplace(&k->keyid, p);
         break;
 
       }
@@ -310,7 +310,7 @@ pgp_key_t pgp_get_candidates (pgp_ring_t keyring, LIST * hints)
   if ((devnull = open ("/dev/null", O_RDWR)) == -1)
     return NULL;
 
-  str_replace (&_chs, Charset);
+  m_strreplace(&_chs, Charset);
 
   thepid = pgp_invoke_list_keys (NULL, &fp, NULL, -1, -1, devnull,
                                  keyring, hints);
index e138f29..92bdb9f 100644 (file)
--- a/history.c
+++ b/history.c
@@ -72,7 +72,7 @@ void mutt_history_add (history_class_t hclass, const char *s)
     if (prev < 0)
       prev = HistSize - 1;
     if (!h->hist[prev] || m_strcmp(h->hist[prev], s) != 0) {
-      str_replace (&h->hist[h->last++], s);
+      m_strreplace(&h->hist[h->last++], s);
       if (h->last > HistSize - 1)
         h->last = 0;
     }
diff --git a/init.c b/init.c
index f52b183..624ef3b 100644 (file)
--- a/init.c
+++ b/init.c
@@ -315,7 +315,7 @@ static int path_from_string (struct option_t* dst, const char* val,
   path[0] = '\0';
   m_strcpy(path, sizeof(path), val);
   mutt_expand_path (path, sizeof(path));
-  str_replace ((char **) dst->data, path);
+  m_strreplace((char **) dst->data, path);
   return (1);
 }
 
@@ -327,7 +327,7 @@ static int str_from_string (struct option_t* dst, const char* val,
   if (!check_special (dst->option, (unsigned long) val, errbuf, errlen))
     return (0);
 
-  str_replace ((char**) dst->data, val);
+  m_strreplace((char**) dst->data, val);
   return (1);
 }
 
@@ -342,7 +342,7 @@ static int user_from_string (struct option_t* dst, const char* val,
     dst->data = (unsigned long) m_strdup(val);
   else {
     char* s = (char*) dst->data;
-    str_replace (&s, val);
+    m_strreplace(&s, val);
   }
   if (m_strlen(dst->init) == 0)
     dst->init = m_strdup((char*) dst->data);
@@ -467,7 +467,7 @@ static int rx_from_string (struct option_t* dst, const char* val,
     p_delete(&p->rx);
   }
 
-  str_replace (&p->pattern, val);
+  m_strreplace(&p->pattern, val);
   p->rx = rx;
   p->not = not;
 
index 29b8817..55a89b9 100644 (file)
@@ -100,6 +100,11 @@ static inline char *m_strdup(const char *s) {
     return len ? p_dup(s, len + 1) : NULL;
 }
 
+static inline char *m_strreplace(char **p, const char *s) {
+    p_delete(p);
+    return (*p = m_strdup(s));
+}
+
 ssize_t m_strcpy(char *dst, ssize_t n, const char *src);
 ssize_t m_strncpy(char *dst, ssize_t n, const char *src, ssize_t l);
 
index b7835fa..8bb51b1 100644 (file)
@@ -1,6 +1,6 @@
 noinst_LIBRARIES = libmime.a
 
-libmime_a_SOURCES = mime.h mime.c rfc822.c rfc2231.c
+libmime_a_SOURCES = mime.h mime.c rfc822.c rfc2047.c rfc2231.c
 
 noinst_HEADERS    = mime.h
 
index 2382579..464a840 100644 (file)
@@ -160,11 +160,9 @@ extern const char RFC822Specials[];
 char *mutt_choose_charset(const char *fromcode, const char *charsets,
                           char *u, size_t ulen, char **d, size_t *dlen);
 
-void _rfc2047_encode_string(char **, int, int);
+void rfc2047_encode_string(char **);
 void rfc2047_encode_adrlist(address_t *, const char *);
 
-#define rfc2047_encode_string(a) _rfc2047_encode_string (a, 0, 32);
-
 void rfc2047_decode(char **);
 void rfc2047_decode_adrlist(address_t *);
 void rfc2047_decode_envelope(ENVELOPE* e);
diff --git a/lib-mime/rfc2047.c b/lib-mime/rfc2047.c
new file mode 100644 (file)
index 0000000..6e79bee
--- /dev/null
@@ -0,0 +1,842 @@
+/*
+ *  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
+ *  the Free Software Foundation; either version 2 of the License, or (at
+ *  your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA 02110-1301, USA.
+ *
+ *  Copyright © 2006 Pierre Habouzit
+ */
+
+/*
+ * Copyright notice from original mutt:
+ * Copyright (C) 1996-2000 Michael R. Elkins <me@mutt.org>
+ * Copyright (C) 2000-2001 Edmund Grimley Evans <edmundo@rano.org>
+ *
+ * This file is part of mutt-ng, see http://www.muttng.org/.
+ * It's licensed under the GNU General Public License,
+ * please see the file GPL in the top level source directory.
+ */
+
+#include <lib-lib/mem.h>
+#include <lib-lib/str.h>
+#include <lib-lib/ascii.h>
+
+#include <lib-mime/mime.h>
+
+#include "mutt.h"
+#include "charset.h"
+#include "thread.h"
+
+#include <ctype.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* If you are debugging this file, comment out the following line. */
+/*#define NDEBUG*/
+
+#ifdef NDEBUG
+#define assert(x)
+#else
+#include <assert.h>
+#endif
+
+#define ENCWORD_LEN_MAX 75
+#define ENCWORD_LEN_MIN 9       /* m_strlen("=?.?.?.?=") */
+
+#define HSPACE(x) ((x) == '\0' || (x) == ' ' || (x) == '\t')
+
+#define CONTINUATION_BYTE(c) (((c) & 0xc0) == 0x80)
+
+typedef size_t (*encoder_t) (char *, const char *, size_t,
+                             const char *);
+
+/* converts f of len flen and charset from
+       into *t of len *tlen and charset to 
+
+   returns -1 on error
+   returns number of converted chars from f, see iconv(3)
+ */
+static ssize_t
+convert_string(const char *from, const char *f, ssize_t flen,
+               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 -1;
+
+    obl = 4 * flen + 1;
+    ob = buf = p_new(char, obl);
+    n = my_iconv(cd, &f, &flen, &ob, &obl);
+
+    if (n < 0 || my_iconv(cd, 0, 0, &ob, &obl) < 0) {
+        e = errno;
+        p_delete(&buf);
+        iconv_close (cd);
+        errno = e;
+        return -1;
+    }
+
+    *ob = '\0';
+    *tlen = ob - buf;
+
+    p_realloc(&buf, ob - buf + 1);
+    *t = buf;
+    iconv_close (cd);
+
+    return n;
+}
+
+char *mutt_choose_charset(const char *fromcode, const char *charsets,
+                          char *u, size_t ulen, char **d, size_t *dlen)
+{
+    char canonical_buff[LONG_STRING];
+    char *e = 0, *tocode = 0;
+    size_t elen = 0, bestn = 0;
+    const char *p, *q;
+
+    for (p = charsets; p; p = q ? q + 1 : 0) {
+        char *s, *t;
+        size_t slen, n;
+
+        q = strchr (p, ':');
+
+        n = q ? q - p : m_strlen(p);
+
+        if (!n ||
+            /* Assume that we never need more than 12 characters of
+               encoded-text to encode a single character. */
+            n > (ENCWORD_LEN_MAX - ENCWORD_LEN_MIN + 2 - 12))
+            continue;
+
+        t = p_dupstr(p, n);
+
+        n = convert_string(fromcode, u, ulen, t, &s, &slen);
+        if (n == (size_t) (-1))
+            continue;
+
+        if (!tocode || n < bestn) {
+            bestn = n;
+            p_delete(&tocode);
+            tocode = t;
+            if (d) {
+                p_delete(&e);
+                e = s;
+            } else {
+                p_delete(&s);
+            }
+            elen = slen;
+            if (!bestn)
+                break;
+        } else {
+            p_delete(&t);
+            p_delete(&s);
+        }
+    }
+
+    if (tocode) {
+        if (d)
+            *d = e;
+        if (dlen)
+            *dlen = elen;
+
+        mutt_canonical_charset(canonical_buff, sizeof(canonical_buff), tocode);
+        m_strreplace(&tocode, canonical_buff);
+    }
+
+    return tocode;
+}
+
+static size_t b_encoder (char *s, const char *d, size_t dlen,
+                         const char *tocode)
+{
+    char *s0 = s;
+
+    memcpy (s, "=?", 2), s += 2;
+    memcpy (s, tocode, m_strlen(tocode)), s += m_strlen(tocode);
+    memcpy (s, "?B?", 3), s += 3;
+    for (;;) {
+        if (!dlen)
+            break;
+        else if (dlen == 1) {
+            *s++ = __m_b64chars[(*d >> 2) & 0x3f];
+            *s++ = __m_b64chars[(*d & 0x03) << 4];
+            *s++ = '=';
+            *s++ = '=';
+            break;
+        }
+        else if (dlen == 2) {
+            *s++ = __m_b64chars[(*d >> 2) & 0x3f];
+            *s++ = __m_b64chars[((*d & 0x03) << 4) | ((d[1] >> 4) & 0x0f)];
+            *s++ = __m_b64chars[(d[1] & 0x0f) << 2];
+            *s++ = '=';
+            break;
+        }
+        else {
+            *s++ = __m_b64chars[(*d >> 2) & 0x3f];
+            *s++ = __m_b64chars[((*d & 0x03) << 4) | ((d[1] >> 4) & 0x0f)];
+            *s++ = __m_b64chars[((d[1] & 0x0f) << 2) | ((d[2] >> 6) & 0x03)];
+            *s++ = __m_b64chars[d[2] & 0x3f];
+            d += 3, dlen -= 3;
+        }
+    }
+    memcpy (s, "?=", 2), s += 2;
+    return s - s0;
+}
+
+static size_t q_encoder (char *s, const char *d, size_t dlen,
+                         const char *tocode)
+{
+    char *s0 = s;
+
+    memcpy (s, "=?", 2), s += 2;
+    memcpy (s, tocode, m_strlen(tocode)), s += m_strlen(tocode);
+    memcpy (s, "?Q?", 3), s += 3;
+    while (dlen--) {
+        unsigned char c = *d++;
+
+        if (c == ' ')
+            *s++ = '_';
+        else if (c >= 0x7f || c < 0x20 || c == '_' || strchr (MimeSpecials, c)) {
+            *s++ = '=';
+            *s++ = __m_b36chars_upper[c >> 4];
+            *s++ = __m_b36chars_upper[c & 0xf];
+        }
+        else
+            *s++ = c;
+    }
+    memcpy (s, "?=", 2), s += 2;
+    return s - s0;
+}
+
+/*
+ * Return 0 if and set *encoder and *wlen if the data (d, dlen) could
+ * be converted to an encoded word of length *wlen using *encoder.
+ * Otherwise return an upper bound on the maximum length of the data
+ * which could be converted.
+ * The data is converted from fromcode (which must be stateless) to
+ * tocode, unless fromcode is 0, in which case the data is assumed to
+ * be already in tocode, which should be 8-bit and stateless.
+ */
+static size_t try_block (const char *d, size_t dlen,
+                         const char *fromcode, const char *tocode,
+                         encoder_t * encoder, size_t * wlen)
+{
+    char buf1[ENCWORD_LEN_MAX - ENCWORD_LEN_MIN + 1];
+    iconv_t cd;
+    const char *ib;
+    char *ob, *p;
+    size_t ibl, obl;
+    int count, len, len_b, len_q;
+
+    if (fromcode) {
+        cd = mutt_iconv_open (tocode, fromcode, 0);
+        assert (cd != (iconv_t) (-1));
+        ib = d, ibl = dlen, ob = buf1, obl = sizeof (buf1) - m_strlen(tocode);
+        if (my_iconv(cd, &ib, &ibl, &ob, &obl) == (size_t) (-1) ||
+            my_iconv(cd, 0, 0, &ob, &obl) == (size_t) (-1)) {
+            assert (errno == E2BIG);
+            iconv_close (cd);
+            assert (ib > d);
+            return (ib - d == dlen) ? dlen : ib - d + 1;
+        }
+        iconv_close (cd);
+    }
+    else {
+        if (dlen > sizeof (buf1) - m_strlen(tocode))
+            return sizeof (buf1) - m_strlen(tocode) + 1;
+        memcpy (buf1, d, dlen);
+        ob = buf1 + dlen;
+    }
+
+    count = 0;
+    for (p = buf1; p < ob; p++) {
+        unsigned char c = *p;
+
+        assert (strchr (MimeSpecials, '?'));
+        if (c >= 0x7f || c < 0x20 || *p == '_' ||
+            (c != ' ' && strchr (MimeSpecials, *p)))
+            ++count;
+    }
+
+    len = ENCWORD_LEN_MIN - 2 + m_strlen(tocode);
+    len_b = len + (((ob - buf1) + 2) / 3) * 4;
+    len_q = len + (ob - buf1) + 2 * count;
+
+    /* Apparently RFC 1468 says to use B encoding for iso-2022-jp. */
+    if (!ascii_strcasecmp (tocode, "ISO-2022-JP"))
+        len_q = ENCWORD_LEN_MAX + 1;
+
+    if (len_b < len_q && len_b <= ENCWORD_LEN_MAX) {
+        *encoder = b_encoder;
+        *wlen = len_b;
+        return 0;
+    }
+    else if (len_q <= ENCWORD_LEN_MAX) {
+        *encoder = q_encoder;
+        *wlen = len_q;
+        return 0;
+    }
+    else
+        return dlen;
+}
+
+/*
+ * Encode the data (d, dlen) into s using the encoder.
+ * Return the length of the encoded word.
+ */
+static size_t encode_block (char *s, char *d, size_t dlen,
+                            const char *fromcode, const char *tocode,
+                            encoder_t encoder)
+{
+    char buf1[ENCWORD_LEN_MAX - ENCWORD_LEN_MIN + 1];
+    iconv_t cd;
+    const char *ib;
+    char *ob;
+    size_t ibl, obl, n1, n2;
+
+    if (fromcode) {
+        cd = mutt_iconv_open (tocode, fromcode, 0);
+        assert (cd != (iconv_t) (-1));
+        ib = d, ibl = dlen, ob = buf1, obl = sizeof (buf1) - m_strlen(tocode);
+        n1 = my_iconv(cd, &ib, &ibl, &ob, &obl);
+        n2 = my_iconv(cd, 0, 0, &ob, &obl);
+        assert (n1 != (size_t) (-1) && n2 != (size_t) (-1));
+        iconv_close (cd);
+        return (*encoder) (s, buf1, ob - buf1, tocode);
+    }
+    else
+        return (*encoder) (s, d, dlen, tocode);
+}
+
+/*
+ * Discover how much of the data (d, dlen) can be converted into
+ * a single encoded word. Return how much data can be converted,
+ * and set the length *wlen of the encoded word and *encoder.
+ * We start in column col, which limits the length of the word.
+ */
+static size_t choose_block (char *d, size_t dlen, int col,
+                            const char *fromcode, const char *tocode,
+                            encoder_t * encoder, size_t * wlen)
+{
+    size_t n, nn;
+    int utf8 = fromcode && !ascii_strcasecmp (fromcode, "UTF-8");
+
+    n = dlen;
+    for (;;) {
+        assert (d + n > d);
+        nn = try_block (d, n, fromcode, tocode, encoder, wlen);
+        if (!nn && (col + *wlen <= ENCWORD_LEN_MAX + 1 || n <= 1))
+            break;
+        n = (nn ? nn : n) - 1;
+        assert (n > 0);
+        if (utf8)
+            while (n > 1 && CONTINUATION_BYTE (d[n]))
+                --n;
+    }
+    return n;
+}
+
+/*
+ * Place the result of RFC-2047-encoding (d, dlen) into the dynamically
+ * allocated buffer (e, elen). The input data is in charset fromcode
+ * and is converted into a charset chosen from charsets.
+ * Return 1 if the conversion to UTF-8 failed, 2 if conversion from UTF-8
+ * failed, otherwise 0. If conversion failed, fromcode is assumed to be
+ * compatible with us-ascii and the original data is used.
+ * The input data is assumed to be a single line starting at column col;
+ * if col is non-zero, the preceding character was a space.
+ */
+static int rfc2047_encode (const char *d, size_t dlen, int col,
+                           const char *fromcode, const char *charsets,
+                           char **e, size_t * elen, char *specials)
+{
+    int ret = 0;
+    char *buf;
+    size_t bufpos, buflen;
+    char *u, *t0, *t1, *t;
+    char *s0, *s1;
+    size_t ulen, r, n, wlen;
+    encoder_t encoder;
+    char *tocode1 = 0;
+    const char *tocode;
+    const char *icode = "UTF-8";
+
+    /* Try to convert to UTF-8. */
+    if (convert_string(fromcode, d, dlen, icode, &u, &ulen)) {
+        ret = 1;
+        icode = 0;
+        u = p_dupstr(d, ulen = dlen);
+    }
+
+    /* Find earliest and latest things we must encode. */
+    s0 = s1 = t0 = t1 = 0;
+    for (t = u; t < u + ulen; t++) {
+        if ((*t & 0x80) ||
+            (*t == '=' && t[1] == '?' && (t == u || HSPACE (*(t - 1))))) {
+            if (!t0)
+                t0 = t;
+            t1 = t;
+        }
+        else if (specials && strchr (specials, *t)) {
+            if (!s0)
+                s0 = t;
+            s1 = t;
+        }
+    }
+
+    /* If we have something to encode, include RFC822 specials */
+    if (t0 && s0 && s0 < t0)
+        t0 = s0;
+    if (t1 && s1 && s1 > t1)
+        t1 = s1;
+
+    if (!t0) {
+        /* No encoding is required. */
+        *e = u;
+        *elen = ulen;
+        return ret;
+    }
+
+    /* Choose target charset. */
+    tocode = fromcode;
+    if (icode) {
+        if ((tocode1 = mutt_choose_charset (icode, charsets, u, ulen, 0, 0)))
+            tocode = tocode1;
+        else
+            ret = 2, icode = 0;
+    }
+
+    /* Hack to avoid labelling 8-bit data as us-ascii. */
+    if (!icode && mutt_is_us_ascii (tocode))
+        tocode = "unknown-8bit";
+
+    /* Adjust t0 for maximum length of line. */
+    t = u + (ENCWORD_LEN_MAX + 1) - col - ENCWORD_LEN_MIN;
+    if (t < u)
+        t = u;
+    if (t < t0)
+        t0 = t;
+
+
+    /* Adjust t0 until we can encode a character after a space. */
+    for (; t0 > u; t0--) {
+        if (!HSPACE (*(t0 - 1)))
+            continue;
+        t = t0 + 1;
+        if (icode)
+            while (t < u + ulen && CONTINUATION_BYTE (*t))
+                ++t;
+        if (!try_block (t0, t - t0, icode, tocode, &encoder, &wlen) &&
+            col + (t0 - u) + wlen <= ENCWORD_LEN_MAX + 1)
+            break;
+    }
+
+    /* Adjust t1 until we can encode a character before a space. */
+    for (; t1 < u + ulen; t1++) {
+        if (!HSPACE (*t1))
+            continue;
+        t = t1 - 1;
+        if (icode)
+            while (CONTINUATION_BYTE (*t))
+                --t;
+        if (!try_block (t, t1 - t, icode, tocode, &encoder, &wlen) &&
+            1 + wlen + (u + ulen - t1) <= ENCWORD_LEN_MAX + 1)
+            break;
+    }
+
+    /* We shall encode the region [t0,t1). */
+
+    /* Initialise the output buffer with the us-ascii prefix. */
+    buflen = 2 * ulen;
+    buf = p_new(char, buflen);
+    bufpos = t0 - u;
+    memcpy (buf, u, t0 - u);
+
+    col += t0 - u;
+
+    t = t0;
+    for (;;) {
+        /* Find how much we can encode. */
+        n = choose_block (t, t1 - t, col, icode, tocode, &encoder, &wlen);
+        if (n == t1 - t) {
+            /* See if we can fit the us-ascii suffix, too. */
+            if (col + wlen + (u + ulen - t1) <= ENCWORD_LEN_MAX + 1)
+                break;
+            n = t1 - t - 1;
+            if (icode)
+                while (CONTINUATION_BYTE (t[n]))
+                    --n;
+            assert (t + n >= t);
+            if (!n) {
+                /* This should only happen in the really stupid case where the
+                   only word that needs encoding is one character long, but
+                   there is too much us-ascii stuff after it to use a single
+                   encoded word. We add the next word to the encoded region
+                   and try again. */
+                assert (t1 < u + ulen);
+                for (t1++; t1 < u + ulen && !HSPACE (*t1); t1++);
+                continue;
+            }
+            n = choose_block (t, n, col, icode, tocode, &encoder, &wlen);
+        }
+
+        /* Add to output buffer. */
+#define LINEBREAK "\n\t"
+        if (bufpos + wlen + m_strlen(LINEBREAK) > buflen) {
+            buflen = bufpos + wlen + m_strlen(LINEBREAK);
+            p_realloc(&buf, buflen);
+        }
+        r = encode_block (buf + bufpos, t, n, icode, tocode, encoder);
+        assert (r == wlen);
+        bufpos += wlen;
+        memcpy (buf + bufpos, LINEBREAK, m_strlen(LINEBREAK));
+        bufpos += m_strlen(LINEBREAK);
+#undef LINEBREAK
+
+        col = 1;
+
+        t += n;
+    }
+
+    /* Add last encoded word and us-ascii suffix to buffer. */
+    buflen = bufpos + wlen + (u + ulen - t1);
+    p_realloc(&buf, buflen + 1);
+    r = encode_block (buf + bufpos, t, t1 - t, icode, tocode, encoder);
+    assert (r == wlen);
+    bufpos += wlen;
+    memcpy (buf + bufpos, t1, u + ulen - t1);
+
+    p_delete(&tocode1);
+    p_delete(&u);
+
+    buf[buflen] = '\0';
+
+    *e = buf;
+    *elen = buflen + 1;
+    return ret;
+}
+
+void _rfc2047_encode_string (char **pd, int encode_specials, int col)
+{
+    char *e;
+    size_t elen;
+    const char *charsets;
+
+    if (!Charset || !*pd)
+        return;
+
+    charsets = SendCharset;
+    if (!charsets || !*charsets)
+        charsets = "UTF-8";
+
+    rfc2047_encode (*pd, m_strlen(*pd), col,
+                    Charset, charsets, &e, &elen,
+                    encode_specials ? RFC822Specials : NULL);
+
+    p_delete(pd);
+    *pd = e;
+}
+
+void rfc2047_encode_string(char **pd) {
+    _rfc2047_encode_string(a, 0, 32);
+}
+
+void rfc2047_encode_adrlist (address_t * addr, const char *tag)
+{
+    address_t *ptr = addr;
+    int col = tag ? m_strlen(tag) + 2 : 32;
+
+    while (ptr) {
+        if (ptr->personal)
+            _rfc2047_encode_string (&ptr->personal, 1, col);
+        ptr = ptr->next;
+    }
+}
+
+static int rfc2047_decode_word (char *d, const char *s, size_t len)
+{
+    const char *pp, *pp1;
+    char *pd, *d0;
+    const char *t, *t1;
+    int enc = 0, count = 0;
+    char *charset = NULL;
+
+    pd = d0 = p_new(char, m_strlen(s));
+
+    for (pp = s; (pp1 = strchr (pp, '?')); pp = pp1 + 1) {
+        count++;
+        switch (count) {
+          case 2:
+            /* ignore language specification a la RFC 2231 */
+            t = pp1;
+            if ((t1 = memchr (pp, '*', t - pp)))
+                t = t1;
+            charset = p_dupstr(pp, t - pp);
+            break;
+          case 3:
+            if (toupper ((unsigned char) *pp) == 'Q')
+                enc = ENCQUOTEDPRINTABLE;
+            else if (toupper ((unsigned char) *pp) == 'B')
+                enc = ENCBASE64;
+            else {
+                p_delete(&charset);
+                p_delete(&d0);
+                return (-1);
+            }
+            break;
+          case 4:
+            if (enc == ENCQUOTEDPRINTABLE) {
+                for (; pp < pp1; pp++) {
+                    if (*pp == '_')
+                        *pd++ = ' ';
+                    else if (*pp == '=' && hexval(pp[1]) >= 0 && hexval(pp[2]) >= 0) {
+                        *pd++ = (hexval (pp[1]) << 4) | hexval (pp[2]);
+                        pp += 2;
+                    }
+                    else
+                        *pd++ = *pp;
+                }
+                *pd = 0;
+            }
+            else if (enc == ENCBASE64) {
+                int c, b = 0, k = 0;
+
+                for (; pp < pp1; pp++) {
+                    if (*pp == '=')
+                        break;
+                    if ((c = base64val(*pp)) < 0)
+                        continue;
+                    if (k + 6 >= 8) {
+                        k -= 2;
+                        *pd++ = b | (c >> k);
+                        b = c << (8 - k);
+                    }
+                    else {
+                        b |= c << (k + 2);
+                        k += 6;
+                    }
+                }
+                *pd = 0;
+            }
+            break;
+        }
+    }
+
+    if (charset)
+        mutt_convert_string (&d0, charset, Charset, M_ICONV_HOOK_FROM);
+    m_strcpy(d, len, d0);
+    p_delete(&charset);
+    p_delete(&d0);
+    return (0);
+}
+
+/*
+ * Find the start and end of the first encoded word in the string.
+ * We use the grammar in section 2 of RFC 2047, but the "encoding"
+ * must be B or Q. Also, we don't require the encoded word to be
+ * separated by linear-white-space (section 5(1)).
+ */
+static const char *find_encoded_word (const char *s, const char **x)
+{
+    const char *p, *q;
+
+    q = s;
+    while ((p = strstr (q, "=?"))) {
+        for (q = p + 2;
+             0x20 < *q && *q < 0x7f && !strchr ("()<>@,;:\"/[]?.=", *q); q++);
+        if (q[0] != '?' || !strchr ("BbQq", q[1]) || q[2] != '?')
+            continue;
+        for (q = q + 3; 0x20 <= *q && *q < 0x7f && *q != '?'; q++);
+        if (q[0] != '?' || q[1] != '=') {
+            --q;
+            continue;
+        }
+
+        *x = q + 2;
+        return p;
+    }
+
+    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 m, n;
+    int found_encoded = 0;
+    char *d0, *d;
+    const char *s = *pd;
+    size_t dlen;
+
+    if (!s || !*s)
+        return;
+
+    dlen = 4 * m_strlen(s);        /* should be enough */
+    d = d0 = p_new(char, dlen + 1);
+
+    while (*s && dlen > 0) {
+        if (!(p = find_encoded_word (s, &q))) {
+            /* no encoded words */
+            if (!option (OPTSTRICTMIME)) {
+                n = m_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 = p_dupstr(s, n);
+                    if (mutt_convert_nonmime_string (&t) == 0) {
+                        tlen = m_strlen(t);
+                        strncpy (d, t, tlen);
+                        d += tlen;
+                    }
+                    else {
+                        strncpy (d, s, n);
+                        d += n;
+                    }
+                    p_delete(&t);
+                    break;
+                }
+            }
+            strncpy (d, s, dlen);
+            d += dlen;
+            break;
+        }
+
+        if (p != s) {
+            n = (size_t) (p - s);
+            /* ignore spaces between encoded words
+             * and linear white spaces between encoded word and *text */
+            if (!option (OPTSTRICTMIME)) {
+                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);
+        found_encoded = 1;
+        s = q;
+        n = m_strlen(d);
+        dlen -= n;
+        d += n;
+    }
+    *d = 0;
+
+    p_delete(pd);
+    *pd = d0;
+    str_adjust (pd);
+}
+
+void rfc2047_decode_adrlist (address_t * a)
+{
+    while (a) {
+        if (a->personal)
+            rfc2047_decode (&a->personal);
+        a = a->next;
+    }
+}
+
+void rfc2047_decode_envelope (ENVELOPE* e) {
+
+    if (!e)
+        return;
+
+    /* do RFC2047 decoding */
+    rfc2047_decode_adrlist (e->from);
+    rfc2047_decode_adrlist (e->to);
+    rfc2047_decode_adrlist (e->cc);
+    rfc2047_decode_adrlist (e->bcc);
+    rfc2047_decode_adrlist (e->reply_to);
+    rfc2047_decode_adrlist (e->mail_followup_to);
+    rfc2047_decode_adrlist (e->return_path);
+    rfc2047_decode_adrlist (e->sender);
+
+    if (e->subject) {
+        rfc2047_decode (&e->subject);
+        mutt_adjust_subject (e);
+    }
+}
index a91dd17..9f0eae6 100644 (file)
--- a/lib/str.c
+++ b/lib/str.c
 
 #include "str.h"
 
-void str_replace (char **p, const char *s)
-{
-  p_delete(p);
-  *p = m_strdup(s);
-}
-
 void str_adjust (char **p)
 {
   if (!p || !*p)
index 636e288..0f9a686 100644 (file)
--- a/lib/str.h
+++ b/lib/str.h
@@ -18,7 +18,6 @@
 char *str_tolower (char*);
 char *str_substrcpy (char*, const char*, const char*, size_t);
 char *str_substrdup (const char*, const char*);
-void str_replace (char**, const char*);
 void str_adjust (char**);
 int str_eq (const char*, const char*);
 const char *str_isstr (const char*, const char*);
diff --git a/main.c b/main.c
index 2fd4155..a2fad56 100644 (file)
--- a/main.c
+++ b/main.c
@@ -631,7 +631,7 @@ int main (int argc, char **argv)
       break;
 
     case 'F':
-      str_replace (&Muttrc, optarg);
+      m_strreplace(&Muttrc, optarg);
       break;
 
     case 'f':
@@ -1008,8 +1008,8 @@ int main (int argc, char **argv)
 #endif
       mutt_expand_path (folder, sizeof (folder));
 
-    str_replace (&CurrentFolder, folder);
-    str_replace (&LastFolder, folder);
+    m_strreplace(&CurrentFolder, folder);
+    m_strreplace(&LastFolder, folder);
 
     if (flags & M_IGNORE) {
       /* check to see if there are any messages in the folder */
diff --git a/menu.c b/menu.c
index 91abff1..05b6b11 100644 (file)
--- a/menu.c
+++ b/menu.c
@@ -687,7 +687,7 @@ static int menu_search (MUTTMENU * menu, int op)
                         _("Reverse search for: "),
                         buf, sizeof (buf), M_CLEAR) != 0 || !buf[0])
       return (-1);
-    str_replace (&menu->searchBuf, buf);
+    m_strreplace(&menu->searchBuf, buf);
     menu->searchDir = (op == OP_SEARCH) ? M_SEARCH_DOWN : M_SEARCH_UP;
   }
   else {
diff --git a/mh.c b/mh.c
index 09a2fb3..a013376 100644 (file)
--- a/mh.c
+++ b/mh.c
@@ -495,7 +495,7 @@ static void maildir_parse_flags (HEADER * h, const char *path)
   if ((p = strrchr (path, ':')) != NULL && m_strncmp(p + 1, "2,", 2) == 0) {
     p += 3;
 
-    str_replace (&h->maildir_flags, p);
+    m_strreplace(&h->maildir_flags, p);
     q = h->maildir_flags;
 
     while (*p) {
@@ -1134,7 +1134,7 @@ static int maildir_commit_message (MESSAGE * msg, CONTEXT * ctx, HEADER * hdr)
 
     if (safe_rename (msg->path, full) == 0) {
       if (hdr)
-        str_replace (&hdr->path, path);
+        m_strreplace(&hdr->path, path);
       p_delete(&msg->path);
 
       /*
@@ -1220,7 +1220,7 @@ static int _mh_commit_message (MESSAGE * msg, CONTEXT * ctx, HEADER * hdr,
     snprintf (path, sizeof (path), "%s/%s", ctx->path, tmp);
     if (safe_rename (msg->path, path) == 0) {
       if (hdr)
-        str_replace (&hdr->path, tmp);
+        m_strreplace(&hdr->path, tmp);
       p_delete(&msg->path);
       break;
     }
@@ -1299,7 +1299,7 @@ static int mh_rewrite_message (CONTEXT * ctx, int msgno)
     if (ctx->magic == M_MH && rc == 0) {
       snprintf (newpath, _POSIX_PATH_MAX, "%s/%s", ctx->path, h->path);
       if ((rc = safe_rename (newpath, oldpath)) == 0)
-        str_replace (&h->path, partpath);
+        m_strreplace(&h->path, partpath);
     }
   }
   else
@@ -1377,7 +1377,7 @@ static int maildir_sync_message (CONTEXT * ctx, int msgno)
       mutt_perror ("rename");
       return (-1);
     }
-    str_replace (&h->path, partpath);
+    m_strreplace(&h->path, partpath);
   }
   return (0);
 }
@@ -1631,7 +1631,7 @@ static int maildir_check_mailbox (CONTEXT * ctx, int *index_hint, int unused)
        * subdirectory.  If so, update the associated filename.
        */
       if (m_strcmp(ctx->hdrs[i]->path, p->h->path))
-        str_replace (&ctx->hdrs[i]->path, p->h->path);
+        m_strreplace(&ctx->hdrs[i]->path, p->h->path);
 
       /* if the user hasn't modified the flags on this message, update
        * the flags we just detected.
index 2b0c41f..65705ca 100644 (file)
--- a/muttlib.c
+++ b/muttlib.c
@@ -503,7 +503,7 @@ void mutt_set_parameter (const char *attribute, const char *value,
 
   for (q = *p; q; q = q->next) {
     if (ascii_strcasecmp (attribute, q->attribute) == 0) {
-      str_replace (&q->value, value);
+      m_strreplace(&q->value, value);
       return;
     }
   }
@@ -829,7 +829,7 @@ int mutt_check_overwrite (const char *attname, const char *path,
               (_("File is a directory, save under it? [(y)es, (n)o, (a)ll]"),
                _("yna"))) {
       case 3:                  /* all */
-        str_replace (directory, fname);
+        m_strreplace(directory, fname);
         break;
       case 1:                  /* yes */
         p_delete(directory);
diff --git a/parse.c b/parse.c
index df02f23..9d1fcba 100644 (file)
--- a/parse.c
+++ b/parse.c
@@ -395,7 +395,7 @@ static void parse_content_disposition (char *s, BODY * ct)
     s = vskipspaces(s + 1);
     if ((s = mutt_get_parameter("filename",
                                 (parms = parse_parameters (s)))) != 0)
-      str_replace (&ct->filename, s);
+      m_strreplace(&ct->filename, s);
     if ((s = mutt_get_parameter ("name", parms)) != 0)
       ct->form_name = m_strdup(s);
     mutt_free_parameter (&parms);
@@ -445,7 +445,7 @@ BODY *mutt_read_mime_header (FILE * fp, int digest)
       else if (!ascii_strcasecmp ("disposition", line + 8))
         parse_content_disposition (c, p);
       else if (!ascii_strcasecmp ("description", line + 8)) {
-        str_replace (&p->description, c);
+        m_strreplace(&p->description, c);
         rfc2047_decode (&p->description);
       }
     }
@@ -458,7 +458,7 @@ BODY *mutt_read_mime_header (FILE * fp, int digest)
       else if (!ascii_strcasecmp ("content-lines", line + 6))
         mutt_set_parameter ("content-lines", c, &(p->parameter));
       else if (!ascii_strcasecmp ("data-description", line + 6)) {
-        str_replace (&p->description, c);
+        m_strreplace(&p->description, c);
         rfc2047_decode (&p->description);
       }
     }
@@ -514,7 +514,7 @@ void mutt_parse_part (FILE * fp, BODY * b)
   /* try to recover from parsing error */
   if (!b->parts) {
     b->type = TYPETEXT;
-    str_replace (&b->subtype, "plain");
+    m_strreplace(&b->subtype, "plain");
   }
 }
 
@@ -990,7 +990,7 @@ int mutt_parse_rfc822_line (ENVELOPE * e, HEADER * hdr, char *line, char *p,
       }
       else if (ascii_strcasecmp (line + 8, "description") == 0) {
         if (hdr) {
-          str_replace (&hdr->content->description, p);
+          m_strreplace(&hdr->content->description, p);
           rfc2047_decode (&hdr->content->description);
         }
         matched = 1;
@@ -1005,7 +1005,7 @@ int mutt_parse_rfc822_line (ENVELOPE * e, HEADER * hdr, char *line, char *p,
 
   case 'd':
     if (!ascii_strcasecmp ("ate", line + 1)) {
-      str_replace (&e->date, p);
+      m_strreplace(&e->date, p);
       if (hdr)
         hdr->date_sent = mutt_parse_date (p, hdr);
       matched = 1;
diff --git a/pgp.c b/pgp.c
index ab582c3..a17b481 100644 (file)
--- a/pgp.c
+++ b/pgp.c
@@ -1521,7 +1521,7 @@ int pgp_send_menu (HEADER * msg, int *redraw)
          pgp_ask_for_key (_("Sign as: "), NULL, KEYFLAG_CANSIGN,
                           PGP_PUBRING))) {
       snprintf (input_signas, sizeof (input_signas), "0x%s", pgp_keyid (p));
-      str_replace (&PgpSignAs, input_signas);
+      m_strreplace(&PgpSignAs, input_signas);
       pgp_free_key (&p);
 
       msg->security |= SIGN;
index a14ec77..e289083 100644 (file)
--- a/pgpkey.c
+++ b/pgpkey.c
@@ -662,7 +662,7 @@ pgp_key_t pgp_ask_for_key (char *tag, char *whatfor,
 
     if (whatfor) {
       if (l)
-        str_replace (&l->dflt, resp);
+        m_strreplace(&l->dflt, resp);
       else {
         l = p_new(struct pgp_cache, 1);
         l->next = id_defaults;
index fd338e5..7cfe924 100644 (file)
@@ -489,10 +489,10 @@ int mutt_parse_crypt_hdr (char *p, int set_signas)
 
   /* the cryptalg field must not be empty */
   if ((WithCrypto & APPLICATION_SMIME) && *smime_cryptalg)
-    str_replace (&SmimeCryptAlg, smime_cryptalg);
+    m_strreplace(&SmimeCryptAlg, smime_cryptalg);
 
   if ((WithCrypto & APPLICATION_PGP) && (set_signas || *pgp_sign_as))
-    str_replace (&PgpSignAs, pgp_sign_as);
+    m_strreplace(&PgpSignAs, pgp_sign_as);
 
   return pgp;
 }
@@ -646,7 +646,7 @@ int mutt_prepare_template (FILE * fp, CONTEXT * ctx, HEADER * newhdr,
       newhdr->security |= mutt_is_application_pgp (newhdr->content);
 
       b->type = TYPETEXT;
-      str_replace (&b->subtype, "plain");
+      m_strreplace(&b->subtype, "plain");
       mutt_delete_parameter ("x-action", &b->parameter);
     }
     else
@@ -655,7 +655,7 @@ int mutt_prepare_template (FILE * fp, CONTEXT * ctx, HEADER * newhdr,
     if (safe_fclose (&s.fpout) != 0)
       goto bail;
 
-    str_replace (&b->filename, file);
+    m_strreplace(&b->filename, file);
     b->unlink = 1;
 
     mutt_stamp_attachment (b);
index fd064cc..91428f1 100644 (file)
@@ -105,7 +105,7 @@ void mutt_update_tree (ATTACHPTR ** idx, short idxlen)
 
     if (idx[x]->tree) {
       if (m_strcmp(idx[x]->tree, buf) != 0)
-        str_replace (&idx[x]->tree, buf);
+        m_strreplace(&idx[x]->tree, buf);
     }
     else
       idx[x]->tree = m_strdup(buf);
index d45c474..3cea0a8 100644 (file)
--- a/rfc1524.c
+++ b/rfc1524.c
@@ -143,7 +143,7 @@ static int get_field_text (char *field, char **entry,
   if (*field == '=') {
     if (entry) {
       field = vskipspaces(field + 1);
-      str_replace (entry, field);
+      m_strreplace(entry, field);
     }
     return 1;
   }
diff --git a/rfc2047.c b/rfc2047.c
deleted file mode 100644 (file)
index bed0353..0000000
--- a/rfc2047.c
+++ /dev/null
@@ -1,833 +0,0 @@
-/*
- *  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
- *  the Free Software Foundation; either version 2 of the License, or (at
- *  your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful, but
- *  WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- *  MA 02110-1301, USA.
- *
- *  Copyright © 2006 Pierre Habouzit
- */
-
-/*
- * Copyright notice from original mutt:
- * Copyright (C) 1996-2000 Michael R. Elkins <me@mutt.org>
- * Copyright (C) 2000-2001 Edmund Grimley Evans <edmundo@rano.org>
- *
- * This file is part of mutt-ng, see http://www.muttng.org/.
- * It's licensed under the GNU General Public License,
- * please see the file GPL in the top level source directory.
- */
-
-#if HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include <lib-lib/mem.h>
-#include <lib-lib/str.h>
-#include <lib-lib/ascii.h>
-
-#include <lib-mime/mime.h>
-
-#include "mutt.h"
-#include "charset.h"
-#include "thread.h"
-
-#include <ctype.h>
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-/* If you are debugging this file, comment out the following line. */
-/*#define NDEBUG*/
-
-#ifdef NDEBUG
-#define assert(x)
-#else
-#include <assert.h>
-#endif
-
-#define ENCWORD_LEN_MAX 75
-#define ENCWORD_LEN_MIN 9       /* m_strlen("=?.?.?.?=") */
-
-#define HSPACE(x) ((x) == '\0' || (x) == ' ' || (x) == '\t')
-
-#define CONTINUATION_BYTE(c) (((c) & 0xc0) == 0x80)
-
-typedef size_t (*encoder_t) (char *, const char *, size_t,
-                             const char *);
-
-static size_t convert_string (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 = p_new(char, obl);
-  n = my_iconv(cd, &f, &flen, &ob, &obl);
-  if (n == (size_t) (-1) || my_iconv(cd, 0, 0, &ob, &obl) == (size_t) (-1)) {
-    e = errno;
-    p_delete(&buf);
-    iconv_close (cd);
-    errno = e;
-    return (size_t) (-1);
-  }
-  *ob = '\0';
-
-  *tlen = ob - buf;
-
-  p_realloc(&buf, ob - buf + 1);
-  *t = buf;
-  iconv_close (cd);
-
-  return n;
-}
-
-char *mutt_choose_charset (const char *fromcode, const char *charsets,
-                           char *u, size_t ulen, char **d, size_t * dlen)
-{
-  char canonical_buff[LONG_STRING];
-  char *e = 0, *tocode = 0;
-  size_t elen = 0, bestn = 0;
-  const char *p, *q;
-
-  for (p = charsets; p; p = q ? q + 1 : 0) {
-    char *s, *t;
-    size_t slen, n;
-
-    q = strchr (p, ':');
-
-    n = q ? q - p : m_strlen(p);
-
-    if (!n ||
-        /* Assume that we never need more than 12 characters of
-           encoded-text to encode a single character. */
-        n > (ENCWORD_LEN_MAX - ENCWORD_LEN_MIN + 2 - 12))
-      continue;
-
-    t = p_dupstr(p, n);
-
-    n = convert_string (u, ulen, fromcode, t, &s, &slen);
-    if (n == (size_t) (-1))
-      continue;
-
-    if (!tocode || n < bestn) {
-      bestn = n;
-      p_delete(&tocode);
-      tocode = t;
-      if (d) {
-        p_delete(&e);
-        e = s;
-      }
-      else
-        p_delete(&s);
-      elen = slen;
-      if (!bestn)
-        break;
-    }
-    else {
-      p_delete(&t);
-      p_delete(&s);
-    }
-  }
-  if (tocode) {
-    if (d)
-      *d = e;
-    if (dlen)
-      *dlen = elen;
-
-    mutt_canonical_charset (canonical_buff, sizeof (canonical_buff), tocode);
-    str_replace (&tocode, canonical_buff);
-  }
-  return tocode;
-}
-
-static size_t b_encoder (char *s, const char *d, size_t dlen,
-                         const char *tocode)
-{
-  char *s0 = s;
-
-  memcpy (s, "=?", 2), s += 2;
-  memcpy (s, tocode, m_strlen(tocode)), s += m_strlen(tocode);
-  memcpy (s, "?B?", 3), s += 3;
-  for (;;) {
-    if (!dlen)
-      break;
-    else if (dlen == 1) {
-      *s++ = __m_b64chars[(*d >> 2) & 0x3f];
-      *s++ = __m_b64chars[(*d & 0x03) << 4];
-      *s++ = '=';
-      *s++ = '=';
-      break;
-    }
-    else if (dlen == 2) {
-      *s++ = __m_b64chars[(*d >> 2) & 0x3f];
-      *s++ = __m_b64chars[((*d & 0x03) << 4) | ((d[1] >> 4) & 0x0f)];
-      *s++ = __m_b64chars[(d[1] & 0x0f) << 2];
-      *s++ = '=';
-      break;
-    }
-    else {
-      *s++ = __m_b64chars[(*d >> 2) & 0x3f];
-      *s++ = __m_b64chars[((*d & 0x03) << 4) | ((d[1] >> 4) & 0x0f)];
-      *s++ = __m_b64chars[((d[1] & 0x0f) << 2) | ((d[2] >> 6) & 0x03)];
-      *s++ = __m_b64chars[d[2] & 0x3f];
-      d += 3, dlen -= 3;
-    }
-  }
-  memcpy (s, "?=", 2), s += 2;
-  return s - s0;
-}
-
-static size_t q_encoder (char *s, const char *d, size_t dlen,
-                         const char *tocode)
-{
-  char hex[] = "0123456789ABCDEF";
-  char *s0 = s;
-
-  memcpy (s, "=?", 2), s += 2;
-  memcpy (s, tocode, m_strlen(tocode)), s += m_strlen(tocode);
-  memcpy (s, "?Q?", 3), s += 3;
-  while (dlen--) {
-    unsigned char c = *d++;
-
-    if (c == ' ')
-      *s++ = '_';
-    else if (c >= 0x7f || c < 0x20 || c == '_' || strchr (MimeSpecials, c)) {
-      *s++ = '=';
-      *s++ = hex[(c & 0xf0) >> 4];
-      *s++ = hex[c & 0x0f];
-    }
-    else
-      *s++ = c;
-  }
-  memcpy (s, "?=", 2), s += 2;
-  return s - s0;
-}
-
-/*
- * Return 0 if and set *encoder and *wlen if the data (d, dlen) could
- * be converted to an encoded word of length *wlen using *encoder.
- * Otherwise return an upper bound on the maximum length of the data
- * which could be converted.
- * The data is converted from fromcode (which must be stateless) to
- * tocode, unless fromcode is 0, in which case the data is assumed to
- * be already in tocode, which should be 8-bit and stateless.
- */
-static size_t try_block (const char *d, size_t dlen,
-                         const char *fromcode, const char *tocode,
-                         encoder_t * encoder, size_t * wlen)
-{
-  char buf1[ENCWORD_LEN_MAX - ENCWORD_LEN_MIN + 1];
-  iconv_t cd;
-  const char *ib;
-  char *ob, *p;
-  size_t ibl, obl;
-  int count, len, len_b, len_q;
-
-  if (fromcode) {
-    cd = mutt_iconv_open (tocode, fromcode, 0);
-    assert (cd != (iconv_t) (-1));
-    ib = d, ibl = dlen, ob = buf1, obl = sizeof (buf1) - m_strlen(tocode);
-    if (my_iconv(cd, &ib, &ibl, &ob, &obl) == (size_t) (-1) ||
-        my_iconv(cd, 0, 0, &ob, &obl) == (size_t) (-1)) {
-      assert (errno == E2BIG);
-      iconv_close (cd);
-      assert (ib > d);
-      return (ib - d == dlen) ? dlen : ib - d + 1;
-    }
-    iconv_close (cd);
-  }
-  else {
-    if (dlen > sizeof (buf1) - m_strlen(tocode))
-      return sizeof (buf1) - m_strlen(tocode) + 1;
-    memcpy (buf1, d, dlen);
-    ob = buf1 + dlen;
-  }
-
-  count = 0;
-  for (p = buf1; p < ob; p++) {
-    unsigned char c = *p;
-
-    assert (strchr (MimeSpecials, '?'));
-    if (c >= 0x7f || c < 0x20 || *p == '_' ||
-        (c != ' ' && strchr (MimeSpecials, *p)))
-      ++count;
-  }
-
-  len = ENCWORD_LEN_MIN - 2 + m_strlen(tocode);
-  len_b = len + (((ob - buf1) + 2) / 3) * 4;
-  len_q = len + (ob - buf1) + 2 * count;
-
-  /* Apparently RFC 1468 says to use B encoding for iso-2022-jp. */
-  if (!ascii_strcasecmp (tocode, "ISO-2022-JP"))
-    len_q = ENCWORD_LEN_MAX + 1;
-
-  if (len_b < len_q && len_b <= ENCWORD_LEN_MAX) {
-    *encoder = b_encoder;
-    *wlen = len_b;
-    return 0;
-  }
-  else if (len_q <= ENCWORD_LEN_MAX) {
-    *encoder = q_encoder;
-    *wlen = len_q;
-    return 0;
-  }
-  else
-    return dlen;
-}
-
-/*
- * Encode the data (d, dlen) into s using the encoder.
- * Return the length of the encoded word.
- */
-static size_t encode_block (char *s, char *d, size_t dlen,
-                            const char *fromcode, const char *tocode,
-                            encoder_t encoder)
-{
-  char buf1[ENCWORD_LEN_MAX - ENCWORD_LEN_MIN + 1];
-  iconv_t cd;
-  const char *ib;
-  char *ob;
-  size_t ibl, obl, n1, n2;
-
-  if (fromcode) {
-    cd = mutt_iconv_open (tocode, fromcode, 0);
-    assert (cd != (iconv_t) (-1));
-    ib = d, ibl = dlen, ob = buf1, obl = sizeof (buf1) - m_strlen(tocode);
-    n1 = my_iconv(cd, &ib, &ibl, &ob, &obl);
-    n2 = my_iconv(cd, 0, 0, &ob, &obl);
-    assert (n1 != (size_t) (-1) && n2 != (size_t) (-1));
-    iconv_close (cd);
-    return (*encoder) (s, buf1, ob - buf1, tocode);
-  }
-  else
-    return (*encoder) (s, d, dlen, tocode);
-}
-
-/*
- * Discover how much of the data (d, dlen) can be converted into
- * a single encoded word. Return how much data can be converted,
- * and set the length *wlen of the encoded word and *encoder.
- * We start in column col, which limits the length of the word.
- */
-static size_t choose_block (char *d, size_t dlen, int col,
-                            const char *fromcode, const char *tocode,
-                            encoder_t * encoder, size_t * wlen)
-{
-  size_t n, nn;
-  int utf8 = fromcode && !ascii_strcasecmp (fromcode, "UTF-8");
-
-  n = dlen;
-  for (;;) {
-    assert (d + n > d);
-    nn = try_block (d, n, fromcode, tocode, encoder, wlen);
-    if (!nn && (col + *wlen <= ENCWORD_LEN_MAX + 1 || n <= 1))
-      break;
-    n = (nn ? nn : n) - 1;
-    assert (n > 0);
-    if (utf8)
-      while (n > 1 && CONTINUATION_BYTE (d[n]))
-        --n;
-  }
-  return n;
-}
-
-/*
- * Place the result of RFC-2047-encoding (d, dlen) into the dynamically
- * allocated buffer (e, elen). The input data is in charset fromcode
- * and is converted into a charset chosen from charsets.
- * Return 1 if the conversion to UTF-8 failed, 2 if conversion from UTF-8
- * failed, otherwise 0. If conversion failed, fromcode is assumed to be
- * compatible with us-ascii and the original data is used.
- * The input data is assumed to be a single line starting at column col;
- * if col is non-zero, the preceding character was a space.
- */
-static int rfc2047_encode (const char *d, size_t dlen, int col,
-                           const char *fromcode, const char *charsets,
-                           char **e, size_t * elen, char *specials)
-{
-  int ret = 0;
-  char *buf;
-  size_t bufpos, buflen;
-  char *u, *t0, *t1, *t;
-  char *s0, *s1;
-  size_t ulen, r, n, wlen;
-  encoder_t encoder;
-  char *tocode1 = 0;
-  const char *tocode;
-  const char *icode = "UTF-8";
-
-  /* Try to convert to UTF-8. */
-  if (convert_string (d, dlen, fromcode, icode, &u, &ulen)) {
-    ret = 1;
-    icode = 0;
-    u = p_dupstr(d, ulen = dlen);
-  }
-
-  /* Find earliest and latest things we must encode. */
-  s0 = s1 = t0 = t1 = 0;
-  for (t = u; t < u + ulen; t++) {
-    if ((*t & 0x80) ||
-        (*t == '=' && t[1] == '?' && (t == u || HSPACE (*(t - 1))))) {
-      if (!t0)
-        t0 = t;
-      t1 = t;
-    }
-    else if (specials && strchr (specials, *t)) {
-      if (!s0)
-        s0 = t;
-      s1 = t;
-    }
-  }
-
-  /* If we have something to encode, include RFC822 specials */
-  if (t0 && s0 && s0 < t0)
-    t0 = s0;
-  if (t1 && s1 && s1 > t1)
-    t1 = s1;
-
-  if (!t0) {
-    /* No encoding is required. */
-    *e = u;
-    *elen = ulen;
-    return ret;
-  }
-
-  /* Choose target charset. */
-  tocode = fromcode;
-  if (icode) {
-    if ((tocode1 = mutt_choose_charset (icode, charsets, u, ulen, 0, 0)))
-      tocode = tocode1;
-    else
-      ret = 2, icode = 0;
-  }
-
-  /* Hack to avoid labelling 8-bit data as us-ascii. */
-  if (!icode && mutt_is_us_ascii (tocode))
-    tocode = "unknown-8bit";
-
-  /* Adjust t0 for maximum length of line. */
-  t = u + (ENCWORD_LEN_MAX + 1) - col - ENCWORD_LEN_MIN;
-  if (t < u)
-    t = u;
-  if (t < t0)
-    t0 = t;
-
-
-  /* Adjust t0 until we can encode a character after a space. */
-  for (; t0 > u; t0--) {
-    if (!HSPACE (*(t0 - 1)))
-      continue;
-    t = t0 + 1;
-    if (icode)
-      while (t < u + ulen && CONTINUATION_BYTE (*t))
-        ++t;
-    if (!try_block (t0, t - t0, icode, tocode, &encoder, &wlen) &&
-        col + (t0 - u) + wlen <= ENCWORD_LEN_MAX + 1)
-      break;
-  }
-
-  /* Adjust t1 until we can encode a character before a space. */
-  for (; t1 < u + ulen; t1++) {
-    if (!HSPACE (*t1))
-      continue;
-    t = t1 - 1;
-    if (icode)
-      while (CONTINUATION_BYTE (*t))
-        --t;
-    if (!try_block (t, t1 - t, icode, tocode, &encoder, &wlen) &&
-        1 + wlen + (u + ulen - t1) <= ENCWORD_LEN_MAX + 1)
-      break;
-  }
-
-  /* We shall encode the region [t0,t1). */
-
-  /* Initialise the output buffer with the us-ascii prefix. */
-  buflen = 2 * ulen;
-  buf = p_new(char, buflen);
-  bufpos = t0 - u;
-  memcpy (buf, u, t0 - u);
-
-  col += t0 - u;
-
-  t = t0;
-  for (;;) {
-    /* Find how much we can encode. */
-    n = choose_block (t, t1 - t, col, icode, tocode, &encoder, &wlen);
-    if (n == t1 - t) {
-      /* See if we can fit the us-ascii suffix, too. */
-      if (col + wlen + (u + ulen - t1) <= ENCWORD_LEN_MAX + 1)
-        break;
-      n = t1 - t - 1;
-      if (icode)
-        while (CONTINUATION_BYTE (t[n]))
-          --n;
-      assert (t + n >= t);
-      if (!n) {
-        /* This should only happen in the really stupid case where the
-           only word that needs encoding is one character long, but
-           there is too much us-ascii stuff after it to use a single
-           encoded word. We add the next word to the encoded region
-           and try again. */
-        assert (t1 < u + ulen);
-        for (t1++; t1 < u + ulen && !HSPACE (*t1); t1++);
-        continue;
-      }
-      n = choose_block (t, n, col, icode, tocode, &encoder, &wlen);
-    }
-
-    /* Add to output buffer. */
-#define LINEBREAK "\n\t"
-    if (bufpos + wlen + m_strlen(LINEBREAK) > buflen) {
-      buflen = bufpos + wlen + m_strlen(LINEBREAK);
-      p_realloc(&buf, buflen);
-    }
-    r = encode_block (buf + bufpos, t, n, icode, tocode, encoder);
-    assert (r == wlen);
-    bufpos += wlen;
-    memcpy (buf + bufpos, LINEBREAK, m_strlen(LINEBREAK));
-    bufpos += m_strlen(LINEBREAK);
-#undef LINEBREAK
-
-    col = 1;
-
-    t += n;
-  }
-
-  /* Add last encoded word and us-ascii suffix to buffer. */
-  buflen = bufpos + wlen + (u + ulen - t1);
-  p_realloc(&buf, buflen + 1);
-  r = encode_block (buf + bufpos, t, t1 - t, icode, tocode, encoder);
-  assert (r == wlen);
-  bufpos += wlen;
-  memcpy (buf + bufpos, t1, u + ulen - t1);
-
-  p_delete(&tocode1);
-  p_delete(&u);
-
-  buf[buflen] = '\0';
-
-  *e = buf;
-  *elen = buflen + 1;
-  return ret;
-}
-
-void _rfc2047_encode_string (char **pd, int encode_specials, int col)
-{
-  char *e;
-  size_t elen;
-  const char *charsets;
-
-  if (!Charset || !*pd)
-    return;
-
-  charsets = SendCharset;
-  if (!charsets || !*charsets)
-    charsets = "UTF-8";
-
-  rfc2047_encode (*pd, m_strlen(*pd), col,
-                  Charset, charsets, &e, &elen,
-                  encode_specials ? RFC822Specials : NULL);
-
-  p_delete(pd);
-  *pd = e;
-}
-
-void rfc2047_encode_adrlist (address_t * addr, const char *tag)
-{
-  address_t *ptr = addr;
-  int col = tag ? m_strlen(tag) + 2 : 32;
-
-  while (ptr) {
-    if (ptr->personal)
-      _rfc2047_encode_string (&ptr->personal, 1, col);
-    ptr = ptr->next;
-  }
-}
-
-static int rfc2047_decode_word (char *d, const char *s, size_t len)
-{
-  const char *pp, *pp1;
-  char *pd, *d0;
-  const char *t, *t1;
-  int enc = 0, count = 0;
-  char *charset = NULL;
-
-  pd = d0 = p_new(char, m_strlen(s));
-
-  for (pp = s; (pp1 = strchr (pp, '?')); pp = pp1 + 1) {
-    count++;
-    switch (count) {
-    case 2:
-      /* ignore language specification a la RFC 2231 */
-      t = pp1;
-      if ((t1 = memchr (pp, '*', t - pp)))
-        t = t1;
-      charset = p_dupstr(pp, t - pp);
-      break;
-    case 3:
-      if (toupper ((unsigned char) *pp) == 'Q')
-        enc = ENCQUOTEDPRINTABLE;
-      else if (toupper ((unsigned char) *pp) == 'B')
-        enc = ENCBASE64;
-      else {
-        p_delete(&charset);
-        p_delete(&d0);
-        return (-1);
-      }
-      break;
-    case 4:
-      if (enc == ENCQUOTEDPRINTABLE) {
-        for (; pp < pp1; pp++) {
-          if (*pp == '_')
-            *pd++ = ' ';
-          else if (*pp == '=' && hexval(pp[1]) >= 0 && hexval(pp[2]) >= 0) {
-            *pd++ = (hexval (pp[1]) << 4) | hexval (pp[2]);
-            pp += 2;
-          }
-          else
-            *pd++ = *pp;
-        }
-        *pd = 0;
-      }
-      else if (enc == ENCBASE64) {
-        int c, b = 0, k = 0;
-
-        for (; pp < pp1; pp++) {
-          if (*pp == '=')
-            break;
-          if ((c = base64val(*pp)) < 0)
-            continue;
-          if (k + 6 >= 8) {
-            k -= 2;
-            *pd++ = b | (c >> k);
-            b = c << (8 - k);
-          }
-          else {
-            b |= c << (k + 2);
-            k += 6;
-          }
-        }
-        *pd = 0;
-      }
-      break;
-    }
-  }
-
-  if (charset)
-    mutt_convert_string (&d0, charset, Charset, M_ICONV_HOOK_FROM);
-  m_strcpy(d, len, d0);
-  p_delete(&charset);
-  p_delete(&d0);
-  return (0);
-}
-
-/*
- * Find the start and end of the first encoded word in the string.
- * We use the grammar in section 2 of RFC 2047, but the "encoding"
- * must be B or Q. Also, we don't require the encoded word to be
- * separated by linear-white-space (section 5(1)).
- */
-static const char *find_encoded_word (const char *s, const char **x)
-{
-  const char *p, *q;
-
-  q = s;
-  while ((p = strstr (q, "=?"))) {
-    for (q = p + 2;
-         0x20 < *q && *q < 0x7f && !strchr ("()<>@,;:\"/[]?.=", *q); q++);
-    if (q[0] != '?' || !strchr ("BbQq", q[1]) || q[2] != '?')
-      continue;
-    for (q = q + 3; 0x20 <= *q && *q < 0x7f && *q != '?'; q++);
-    if (q[0] != '?' || q[1] != '=') {
-      --q;
-      continue;
-    }
-
-    *x = q + 2;
-    return p;
-  }
-
-  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 m, n;
-  int found_encoded = 0;
-  char *d0, *d;
-  const char *s = *pd;
-  size_t dlen;
-
-  if (!s || !*s)
-    return;
-
-  dlen = 4 * m_strlen(s);        /* should be enough */
-  d = d0 = p_new(char, dlen + 1);
-
-  while (*s && dlen > 0) {
-    if (!(p = find_encoded_word (s, &q))) {
-      /* no encoded words */
-      if (!option (OPTSTRICTMIME)) {
-        n = m_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 = p_dupstr(s, n);
-          if (mutt_convert_nonmime_string (&t) == 0) {
-            tlen = m_strlen(t);
-            strncpy (d, t, tlen);
-            d += tlen;
-          }
-          else {
-            strncpy (d, s, n);
-            d += n;
-          }
-          p_delete(&t);
-          break;
-        }
-      }
-      strncpy (d, s, dlen);
-      d += dlen;
-      break;
-    }
-
-    if (p != s) {
-      n = (size_t) (p - s);
-      /* ignore spaces between encoded words
-       * and linear white spaces between encoded word and *text */
-      if (!option (OPTSTRICTMIME)) {
-        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);
-    found_encoded = 1;
-    s = q;
-    n = m_strlen(d);
-    dlen -= n;
-    d += n;
-  }
-  *d = 0;
-
-  p_delete(pd);
-  *pd = d0;
-  str_adjust (pd);
-}
-
-void rfc2047_decode_adrlist (address_t * a)
-{
-  while (a) {
-    if (a->personal)
-      rfc2047_decode (&a->personal);
-    a = a->next;
-  }
-}
-
-void rfc2047_decode_envelope (ENVELOPE* e) {
-
-  if (!e)
-    return;
-
-  /* do RFC2047 decoding */
-  rfc2047_decode_adrlist (e->from);
-  rfc2047_decode_adrlist (e->to);
-  rfc2047_decode_adrlist (e->cc);
-  rfc2047_decode_adrlist (e->bcc);
-  rfc2047_decode_adrlist (e->reply_to);
-  rfc2047_decode_adrlist (e->mail_followup_to);
-  rfc2047_decode_adrlist (e->return_path);
-  rfc2047_decode_adrlist (e->sender);
-
-  if (e->subject) {
-    rfc2047_decode (&e->subject);
-    mutt_adjust_subject (e);
-  }
-}
index de9e0b6..c194540 100644 (file)
--- a/rfc3676.c
+++ b/rfc3676.c
@@ -272,5 +272,5 @@ void rfc3676_space_stuff (HEADER* hdr) {
   fclose (out);
   mutt_set_mtime (hdr->content->filename, tmpfile);
   unlink (hdr->content->filename);
-  str_replace (&hdr->content->filename, tmpfile);
+  m_strreplace(&hdr->content->filename, tmpfile);
 }
diff --git a/send.c b/send.c
index 9932e67..7b4b9bc 100644 (file)
--- a/send.c
+++ b/send.c
@@ -296,7 +296,7 @@ static int edit_envelope (ENVELOPE * en, int flags)
 
     return (-1);
   }
-  str_replace (&en->subject, buf);
+  m_strreplace(&en->subject, buf);
 
   return 0;
 }
@@ -350,7 +350,7 @@ static void process_user_header (ENVELOPE * env)
       env->reply_to = rfc822_parse_adrlist (env->reply_to, uh->data + 9);
     }
     else if (ascii_strncasecmp ("message-id:", uh->data, 11) == 0)
-      str_replace (&env->message_id, uh->data + 11);
+      m_strreplace(&env->message_id, uh->data + 11);
     else if (ascii_strncasecmp ("to:", uh->data, 3) != 0 &&
              ascii_strncasecmp ("cc:", uh->data, 3) != 0 &&
              ascii_strncasecmp ("bcc:", uh->data, 4) != 0 &&
@@ -633,7 +633,7 @@ void mutt_make_forward_subject (ENVELOPE * env, CONTEXT * ctx, HEADER * cur)
 
   /* set the default subject for the message. */
   mutt_make_string (buffer, sizeof (buffer), NONULL (ForwFmt), ctx, cur);
-  str_replace (&env->subject, buffer);
+  m_strreplace(&env->subject, buffer);
 }
 
 void mutt_make_misc_reply_headers (ENVELOPE * env, CONTEXT * ctx,
index 2a62bd3..1762394 100644 (file)
--- a/sendlib.c
+++ b/sendlib.c
@@ -955,8 +955,8 @@ bye:
 
   if (type != TYPEOTHER || *xtype != '\0') {
     att->type = type;
-    str_replace (&att->subtype, subtype);
-    str_replace (&att->xtype, xtype);
+    m_strreplace(&att->subtype, subtype);
+    m_strreplace(&att->xtype, xtype);
   }
 
   return (type);
diff --git a/smime.c b/smime.c
index 1e173f6..3db7185 100644 (file)
--- a/smime.c
+++ b/smime.c
@@ -1906,10 +1906,10 @@ int smime_send_menu (HEADER * msg, int *redraw)
             switch (choice = mutt_multi_choice (_("1: DES, 2: Triple-DES "),
                                                 _("dt"))) {
               case 1:
-                str_replace (&SmimeCryptAlg, "des");
+                m_strreplace(&SmimeCryptAlg, "des");
                 break;
               case 2:
-                str_replace (&SmimeCryptAlg, "des3");
+                m_strreplace(&SmimeCryptAlg, "des3");
                 break;
             }
             break;
@@ -1918,13 +1918,13 @@ int smime_send_menu (HEADER * msg, int *redraw)
             switch (choice = mutt_multi_choice (_("1: RC2-40, 2: RC2-64, 3: RC2-128 "),
                                                 _("468"))) {
               case 1:
-                str_replace (&SmimeCryptAlg, "rc2-40");
+                m_strreplace(&SmimeCryptAlg, "rc2-40");
                 break;
               case 2:
-                str_replace (&SmimeCryptAlg, "rc2-64");
+                m_strreplace(&SmimeCryptAlg, "rc2-64");
                 break;
               case 3:
-                str_replace (&SmimeCryptAlg, "rc2-128");
+                m_strreplace(&SmimeCryptAlg, "rc2-128");
                 break;
             }
             break;
@@ -1933,13 +1933,13 @@ int smime_send_menu (HEADER * msg, int *redraw)
             switch (choice = mutt_multi_choice (_("1: AES128, 2: AES192, 3: AES256 "),
                                                 _("895"))) {
               case 1:
-                str_replace (&SmimeCryptAlg, "aes128");
+                m_strreplace(&SmimeCryptAlg, "aes128");
                 break;
               case 2:
-                str_replace (&SmimeCryptAlg, "aes192");
+                m_strreplace(&SmimeCryptAlg, "aes192");
                 break;
               case 3:
-                str_replace (&SmimeCryptAlg, "aes256");
+                m_strreplace(&SmimeCryptAlg, "aes256");
                 break;
             }
             break;
@@ -1969,7 +1969,7 @@ int smime_send_menu (HEADER * msg, int *redraw)
   case 4:                      /* sign (a)s */
 
     if ((p = smime_ask_for_key (_("Sign as: "), NULL, 0))) {
-      str_replace (&SmimeDefaultKey, p);
+      m_strreplace(&SmimeDefaultKey, p);
 
       msg->security |= SIGN;
 
diff --git a/url.c b/url.c
index 9ca480b..81b47c7 100644 (file)
--- a/url.c
+++ b/url.c
@@ -234,7 +234,7 @@ int url_parse_mailto (ENVELOPE * e, char **body, const char *src)
 
     if (!ascii_strcasecmp (tag, "body")) {
       if (body)
-        str_replace (body, value);
+        m_strreplace(body, value);
     }
     else {
 #define SAFEPFX (option (OPTSTRICTMAILTO) ? "" : "X-Mailto-")