From 83532821ae9fab034d0d630b78330c9ea4ff4cf3 Mon Sep 17 00:00:00 2001 From: Pierre Habouzit Date: Sat, 4 Nov 2006 00:04:45 +0100 Subject: [PATCH] move rfc2047.c into lib-mime, reindent it. replace str_replace with m_strreplace. I don't like that function at all. Signed-off-by: Pierre Habouzit --- alias.c | 2 +- attach.c | 2 +- browser.c | 2 +- charset.h | 4 +- compose.c | 8 +- crypt-gpgme.c | 4 +- curs_main.c | 6 +- edit.c | 4 +- gnupgparse.c | 4 +- history.c | 2 +- init.c | 8 +- lib-lib/str.h | 5 + lib-mime/Makefile.am | 2 +- lib-mime/mime.h | 4 +- lib-mime/rfc2047.c | 842 +++++++++++++++++++++++++++++++++++++++++++ lib/str.c | 6 - lib/str.h | 1 - main.c | 6 +- menu.c | 2 +- mh.c | 12 +- muttlib.c | 4 +- parse.c | 12 +- pgp.c | 2 +- pgpkey.c | 2 +- postpone.c | 8 +- recvattach.c | 2 +- rfc1524.c | 2 +- rfc2047.c | 833 ------------------------------------------ rfc3676.c | 2 +- send.c | 6 +- sendlib.c | 4 +- smime.c | 18 +- url.c | 2 +- 33 files changed, 914 insertions(+), 909 deletions(-) create mode 100644 lib-mime/rfc2047.c delete mode 100644 rfc2047.c diff --git a/alias.c b/alias.c index 9be40dc..bc5a25a 100644 --- 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); } } } diff --git a/attach.c b/attach.c index c590309..5f588b7 100644 --- 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) diff --git a/browser.c b/browser.c index e22e1ea..d91d0ef 100644 --- 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; diff --git a/charset.h b/charset.h index f8fcc98..5b3b732 100644 --- 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); } diff --git a/compose.c b/compose.c index 3d5f39c..3401388 100644 --- 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; diff --git a/crypt-gpgme.c b/crypt-gpgme.c index 32efdb7..4255156 100644 --- a/crypt-gpgme.c +++ b/crypt-gpgme.c @@ -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); diff --git a/curs_main.c b/curs_main.c index a62f166..36ed33a 100644 --- a/curs_main.c +++ b/curs_main.c @@ -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 --- 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); diff --git a/gnupgparse.c b/gnupgparse.c index b9f00ba..cdce751 100644 --- a/gnupgparse.c +++ b/gnupgparse.c @@ -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); diff --git a/history.c b/history.c index e138f29..92bdb9f 100644 --- 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 --- 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; diff --git a/lib-lib/str.h b/lib-lib/str.h index 29b8817..55a89b9 100644 --- a/lib-lib/str.h +++ b/lib-lib/str.h @@ -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); diff --git a/lib-mime/Makefile.am b/lib-mime/Makefile.am index b7835fa..8bb51b1 100644 --- a/lib-mime/Makefile.am +++ b/lib-mime/Makefile.am @@ -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 diff --git a/lib-mime/mime.h b/lib-mime/mime.h index 2382579..464a840 100644 --- a/lib-mime/mime.h +++ b/lib-mime/mime.h @@ -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 index 0000000..6e79bee --- /dev/null +++ b/lib-mime/rfc2047.c @@ -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 + * Copyright (C) 2000-2001 Edmund Grimley Evans + * + * 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 +#include +#include + +#include + +#include "mutt.h" +#include "charset.h" +#include "thread.h" + +#include +#include +#include +#include +#include + +/* If you are debugging this file, comment out the following line. */ +/*#define NDEBUG*/ + +#ifdef NDEBUG +#define assert(x) +#else +#include +#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); + } +} diff --git a/lib/str.c b/lib/str.c index a91dd17..9f0eae6 100644 --- a/lib/str.c +++ b/lib/str.c @@ -17,12 +17,6 @@ #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) diff --git a/lib/str.h b/lib/str.h index 636e288..0f9a686 100644 --- 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 --- 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 --- 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 --- 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. diff --git a/muttlib.c b/muttlib.c index 2b0c41f..65705ca 100644 --- 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 --- 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 --- 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; diff --git a/pgpkey.c b/pgpkey.c index a14ec77..e289083 100644 --- 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; diff --git a/postpone.c b/postpone.c index fd338e5..7cfe924 100644 --- a/postpone.c +++ b/postpone.c @@ -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); diff --git a/recvattach.c b/recvattach.c index fd064cc..91428f1 100644 --- a/recvattach.c +++ b/recvattach.c @@ -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); diff --git a/rfc1524.c b/rfc1524.c index d45c474..3cea0a8 100644 --- 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 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 - * Copyright (C) 2000-2001 Edmund Grimley Evans - * - * 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 -#include -#include - -#include - -#include "mutt.h" -#include "charset.h" -#include "thread.h" - -#include -#include -#include -#include -#include - -/* If you are debugging this file, comment out the following line. */ -/*#define NDEBUG*/ - -#ifdef NDEBUG -#define assert(x) -#else -#include -#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); - } -} diff --git a/rfc3676.c b/rfc3676.c index de9e0b6..c194540 100644 --- 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 --- 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, diff --git a/sendlib.c b/sendlib.c index 2a62bd3..1762394 100644 --- 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 --- 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 --- 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-") -- 2.20.1