Skip to content

Commit

Permalink
Attempt to convert output to locale charset from UTF-8
Browse files Browse the repository at this point in the history
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
  • Loading branch information
David Woodhouse authored and David Woodhouse committed Jul 28, 2014
1 parent 887172d commit 27dcb57
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 1 deletion.
2 changes: 1 addition & 1 deletion Makefile.am
Expand Up @@ -16,7 +16,7 @@ AM_CPPFLAGS = -DLOCALEDIR="\"$(localedir)\""

openconnect_SOURCES = xml.c main.c
openconnect_CFLAGS = $(AM_CFLAGS) $(SSL_CFLAGS) $(DTLS_SSL_CFLAGS) $(LIBXML2_CFLAGS) $(LIBPROXY_CFLAGS) $(ZLIB_CFLAGS) $(LIBSTOKEN_CFLAGS) $(LIBOATH_CFLAGS) $(GSSAPI_CFLAGS)
openconnect_LDADD = libopenconnect.la $(LIBXML2_LIBS) $(LIBPROXY_LIBS) $(LIBINTL)
openconnect_LDADD = libopenconnect.la $(LIBXML2_LIBS) $(LIBPROXY_LIBS) $(LIBINTL) $(LIBICONV)

library_srcs = ssl.c http.c auth.c library.c compat.c dtls.c cstp.c \
mainloop.c script.c ntlm.c digest.c
Expand Down
26 changes: 26 additions & 0 deletions configure.ac
Expand Up @@ -179,6 +179,32 @@ AC_CHECK_FUNCS(setenv unsetenv)
AC_ENABLE_SHARED
AC_DISABLE_STATIC

have_iconv=no
LIBICONV=
AC_MSG_CHECKING([for iconv support])
AC_LINK_IFELSE([AC_LANG_PROGRAM([
#include <iconv.h>],[
iconv_t ic = iconv_open("","");])],
[AC_MSG_RESULT(yes)
have_iconv=yes],
[oldLIBS="$LIBS"
LIBS="$LIBS -liconv"
AC_LINK_IFELSE([AC_LANG_PROGRAM([
#include <iconv.h>],[
iconv_t ic = iconv_open("","");])],
[AC_MSG_RESULT(yes (with -liconv))
have_iconv=yes
LIBICONV=-liconv],
[AC_MSG_RESULT(no)])
LIBS="$oldLIBS"])

if test "$have_iconv" = "yes"; then
AC_SUBST(LIBICONV)
AC_DEFINE(HAVE_ICONV, 1, [Have iconv() function])
fi

AC_CHECK_FUNC(nl_langinfo, [AC_DEFINE(HAVE_NL_LANGINFO, 1, [Have nl_langinfo() function])], [])

AC_ARG_ENABLE([nls],
[ --disable-nls do not use Native Language Support],
[USE_NLS=$enableval], [USE_NLS=yes])
Expand Down
78 changes: 78 additions & 0 deletions main.c
Expand Up @@ -245,6 +245,79 @@ static struct option long_options[] = {
OPTION(NULL, 0, 0)
};

#if defined(HAVE_NL_LANGINFO) && defined(HAVE_ICONV)
#include <iconv.h>
#include <langinfo.h>

static const char *legacy_charset;

static int vfprintf_utf8(FILE *f, const char *fmt, va_list args)
{
char *utf8_str;
iconv_t ic;
int ret;
char outbuf[80];
char *ic_in, *ic_out;
size_t insize, outsize;

if (!legacy_charset)
return vfprintf(f, fmt, args);

ret = vasprintf(&utf8_str, fmt, args);
if (ret < 0)
return -1;

ic = iconv_open(legacy_charset, "UTF-8");
if (ic == (iconv_t) -1) {
/* Better than nothing... */
ret = fprintf(f, "%s", utf8_str);
free(utf8_str);
return ret;
}

ic_in = utf8_str;
insize = strlen(utf8_str);
ret = 0;

while (insize) {
ic_out = outbuf;
outsize = sizeof(outbuf) - 1;

if (iconv(ic, &ic_in, &insize, &ic_out, &outsize) == (size_t)-1) {
if (errno == EILSEQ) {
do {
ic_in++;
insize--;
} while (insize && (ic_in[0] & 0xc0) == 0x80);
ic_out[0] = '?';
outsize--;
} else if (errno != E2BIG)
break;
}
ret += fwrite(outbuf, 1, sizeof(outbuf) - 1 - outsize, f);
}

iconv_close(ic);

return ret;
}

static int fprintf_utf8(FILE *f, const char *fmt, ...)
{
va_list args;
int ret;

va_start(args, fmt);
ret = vfprintf_utf8(f, fmt, args);
va_end(args);

return ret;
}

#define fprintf fprintf_utf8
#define vfprintf vfprintf_utf8
#endif

static void helpmessage(void)
{
printf(_("For assistance with OpenConnect, please see the web page at\n"
Expand Down Expand Up @@ -665,6 +738,11 @@ int main(int argc, char **argv)
bindtextdomain("openconnect", LOCALEDIR);
setlocale(LC_ALL, "");
#endif
#if defined(HAVE_NL_LANGINFO) && defined(HAVE_ICONV)
legacy_charset = nl_langinfo(CODESET);
if (legacy_charset && !strcmp(legacy_charset, "UTF-8"))
legacy_charset = NULL;
#endif

if (strcmp(openconnect_version_str, openconnect_binary_version)) {
fprintf(stderr, _("WARNING: This version of openconnect is %s but\n"
Expand Down

0 comments on commit 27dcb57

Please sign in to comment.