while (true)
{
ob = bufo, obl = sizeof(bufo);
- mutt_ch_iconv(cd, &ib, &ibl, &ob, &obl, 0, "?");
+ mutt_ch_iconv(cd, &ib, &ibl, &ob, &obl, 0, "?", NULL);
if (ob == bufo)
break;
state_prefix_put(bufo, ob - bufo, s);
if (Charset)
{
char *t = mutt_str_strdup(*s);
- if (t && !mutt_ch_convert_string(&t, Charset, "utf-8", 0))
+ if (t && mutt_ch_convert_string(&t, Charset, "utf-8", 0) == 0)
{
FREE(s);
if (idata->unicode)
else
t = utf7_to_utf8(*s, strlen(*s), 0, 0);
- if (t && !mutt_ch_convert_string(&t, "utf-8", Charset, 0))
+ if (t && mutt_ch_convert_string(&t, "utf-8", Charset, 0) == 0)
{
FREE(s);
*s = t;
* @param[in,out] outbytesleft Length of result buffer
* @param[in] inrepls Input replacement characters
* @param[in] outrepl Output replacement characters
+ * @param[out] iconverrno Errno if iconv() fails, 0 if it succeeds
* @retval num Number of characters converted
*
* Like iconv, but keeps going even when the input is invalid
* if you're supplying an outrepl, the target charset should be.
*/
size_t mutt_ch_iconv(iconv_t cd, const char **inbuf, size_t *inbytesleft, char **outbuf,
- size_t *outbytesleft, const char **inrepls, const char *outrepl)
+ size_t *outbytesleft, const char **inrepls, const char *outrepl,
+ int *iconverrno)
{
size_t rc = 0;
const char *ib = *inbuf;
while (true)
{
+ errno = 0;
const size_t ret1 = iconv(cd, (ICONV_CONST char **) &ib, &ibl, &ob, &obl);
if (ret1 != (size_t) -1)
rc += ret1;
+ if (iconverrno)
+ *iconverrno = errno;
+
if (ibl && obl && errno == EILSEQ)
{
if (inrepls)
* @param[in] from Current character set
* @param[in] to Target character set
* @param[in] flags Flags, e.g.
- * @retval 0 Success
- * @retval -1 Error
+ * @retval 0 Success
+ * @retval -1 Invalid arguments or failure to open an iconv channel
+ * @retval errno Failure in iconv conversion
*
* Parameter flags is given as-is to mutt_ch_iconv_open().
* See there for its meaning and usage policy.
iconv_t cd;
const char *repls[] = { "\357\277\275", "?", 0 };
char *s = *ps;
+ int rc = 0;
if (!s || !*s)
return 0;
- if (to && from && (cd = mutt_ch_iconv_open(to, from, flags)) != (iconv_t) -1)
- {
- size_t len;
- const char *ib = NULL;
- char *buf = NULL, *ob = NULL;
- size_t ibl, obl;
- const char **inrepls = NULL;
- char *outrepl = NULL;
-
- if (mutt_ch_is_utf8(to))
- outrepl = "\357\277\275";
- else if (mutt_ch_is_utf8(from))
- inrepls = repls;
- else
- outrepl = "?";
+ if (!to || !from)
+ return -1;
- len = strlen(s);
- ib = s;
- ibl = len + 1;
- obl = MB_LEN_MAX * ibl;
- ob = buf = mutt_mem_malloc(obl + 1);
+ cd = mutt_ch_iconv_open(to, from, flags);
+ if (cd == (iconv_t) -1)
+ return -1;
- mutt_ch_iconv(cd, &ib, &ibl, &ob, &obl, inrepls, outrepl);
- iconv_close(cd);
+ size_t len;
+ const char *ib = NULL;
+ char *buf = NULL, *ob = NULL;
+ size_t ibl, obl;
+ const char **inrepls = NULL;
+ char *outrepl = NULL;
+
+ if (mutt_ch_is_utf8(to))
+ outrepl = "\357\277\275";
+ else if (mutt_ch_is_utf8(from))
+ inrepls = repls;
+ else
+ outrepl = "?";
- *ob = '\0';
+ len = strlen(s);
+ ib = s;
+ ibl = len + 1;
+ obl = MB_LEN_MAX * ibl;
+ ob = buf = mutt_mem_malloc(obl + 1);
- FREE(ps);
- *ps = buf;
+ mutt_ch_iconv(cd, &ib, &ibl, &ob, &obl, inrepls, outrepl, &rc);
+ iconv_close(cd);
- mutt_str_adjust(ps);
- return 0;
- }
- else
- return -1;
+ *ob = '\0';
+
+ FREE(ps);
+ *ps = buf;
+
+ mutt_str_adjust(ps);
+ return rc;
}
/**
if (fc->ibl)
{
size_t obl = sizeof(fc->bufo);
- mutt_ch_iconv(fc->cd, (const char **) &fc->ib, &fc->ibl, &fc->ob, &obl, fc->inrepls, 0);
+ mutt_ch_iconv(fc->cd, (const char **) &fc->ib, &fc->ibl, &fc->ob, &obl, fc->inrepls, 0, NULL);
if (fc->p < fc->ob)
return (unsigned char) *(fc->p)++;
}
t[n] = '\0';
s = mutt_str_substr_dup(u, u + ulen);
- if (mutt_ch_convert_string(&s, fromcode, t, 0))
+ if (mutt_ch_convert_string(&s, fromcode, t, 0) != 0)
{
FREE(&t);
FREE(&s);
const char * mutt_ch_charset_lookup(const char *chs);
iconv_t mutt_ch_iconv_open(const char *tocode, const char *fromcode, int flags);
-size_t mutt_ch_iconv(iconv_t cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft, const char **inrepls, const char *outrepl);
+size_t mutt_ch_iconv(iconv_t cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft, const char **inrepls, const char *outrepl, int *iconverrno);
const char * mutt_ch_iconv_lookup(const char *chs);
int mutt_ch_convert_string(char **ps, const char *from, const char *to, int flags);
int mutt_ch_convert_nonmime_string(char **ps);
#endif /* HAVE_LIBIDN */
/* we don't want charset-hook effects, so we set flags to 0 */
- if (mutt_ch_convert_string(&local_user, "utf-8", Charset, 0) == -1)
+ if (mutt_ch_convert_string(&local_user, "utf-8", Charset, 0) != 0)
goto cleanup;
- if (mutt_ch_convert_string(&local_domain, "utf-8", Charset, 0) == -1)
+ if (mutt_ch_convert_string(&local_domain, "utf-8", Charset, 0) != 0)
goto cleanup;
/* make sure that we can convert back and come out with the same
{
reversed_user = mutt_str_strdup(local_user);
- if (mutt_ch_convert_string(&reversed_user, Charset, "utf-8", 0) == -1)
+ if (mutt_ch_convert_string(&reversed_user, Charset, "utf-8", 0) != 0)
{
mutt_debug(1, "Not reversible. Charset conv to utf-8 failed for user = '%s'.\n",
reversed_user);
reversed_domain = mutt_str_strdup(local_domain);
- if (mutt_ch_convert_string(&reversed_domain, Charset, "utf-8", 0) == -1)
+ if (mutt_ch_convert_string(&reversed_domain, Charset, "utf-8", 0) != 0)
{
mutt_debug(1, "Not reversible. Charset conv to utf-8 failed for domain = '%s'.\n",
reversed_domain);
char *intl_domain = mutt_str_strdup(domain);
/* we don't want charset-hook effects, so we set flags to 0 */
- if (mutt_ch_convert_string(&intl_user, Charset, "utf-8", 0) == -1)
+ if (mutt_ch_convert_string(&intl_user, Charset, "utf-8", 0) != 0)
goto cleanup;
- if (mutt_ch_convert_string(&intl_domain, Charset, "utf-8", 0) == -1)
+ if (mutt_ch_convert_string(&intl_domain, Charset, "utf-8", 0) != 0)
goto cleanup;
#ifdef HAVE_LIBIDN
/* Try to convert to UTF-8. */
char *u = mutt_str_substr_dup(d, d + dlen);
- if (mutt_ch_convert_string(&u, fromcode, icode, 0))
+ if (mutt_ch_convert_string(&u, fromcode, icode, 0) != 0)
{
rc = 1;
icode = 0;