From 0d63e59beb5d1dd1f6b47f1c61a356f89eae77ee Mon Sep 17 00:00:00 2001
From: Přemysl Janouch <p.janouch@gmail.com>
Date: Fri, 17 Apr 2015 22:20:48 +0200
Subject: degesch: add irc_to_utf8()

And use it.
---
 degesch.c | 28 +++++++++++++++++++---------
 1 file changed, 19 insertions(+), 9 deletions(-)

diff --git a/degesch.c b/degesch.c
index 6dd6be7..f38f299 100644
--- a/degesch.c
+++ b/degesch.c
@@ -296,8 +296,7 @@ struct app_context
 
 	iconv_t term_to_utf8;               ///< Terminal encoding to UTF-8
 	iconv_t term_from_utf8;             ///< UTF-8 to terminal encoding
-	// XXX: shouldn't it be rather UTF-8 from Latin 1?
-	iconv_t term_from_latin1;           ///< ISO Latin 1 to terminal encoding
+	iconv_t latin1_to_utf8;             ///< ISO Latin 1 to UTF-8
 
 	int lines;                          ///< Current terminal height
 	int columns;                        ///< Current ternimal width
@@ -340,8 +339,8 @@ app_context_init (struct app_context *self)
 
 	if ((self->term_from_utf8 =
 		iconv_open (encoding, "UTF-8")) == (iconv_t) -1
-	 || (self->term_from_latin1 =
-		iconv_open (encoding, "ISO-8859-1")) == (iconv_t) -1
+	 || (self->latin1_to_utf8 =
+		iconv_open ("UTF-8", "ISO-8859-1")) == (iconv_t) -1
 	 || (self->term_to_utf8 =
 		iconv_open ("UTF-8", nl_langinfo (CODESET))) == (iconv_t) -1)
 		exit_fatal ("creating the UTF-8 conversion object failed: %s",
@@ -375,7 +374,7 @@ app_context_free (struct app_context *self)
 
 	poller_free (&self->poller);
 
-	iconv_close (self->term_from_latin1);
+	iconv_close (self->latin1_to_utf8);
 	iconv_close (self->term_from_utf8);
 	iconv_close (self->term_to_utf8);
 
@@ -1465,6 +1464,15 @@ init_readline (void)
 // TODO: we will need a proper mode parser; to be shared with kike
 // TODO: we alse definitely need to parse server capability messages
 
+static char *
+irc_to_utf8 (struct app_context *ctx, const char *text)
+{
+	size_t len = strlen (text) + 1;
+	if (utf8_validate (text, len))
+		return xstrdup (text);
+	return iconv_xstrdup (ctx->latin1_to_utf8, (char *) text, len, NULL);
+}
+
 static void
 irc_handle_ping (struct app_context *ctx, const struct irc_message *msg)
 {
@@ -1506,8 +1514,9 @@ irc_process_message (const struct irc_message *msg,
 		if (ctx->readline_prompt_shown)
 			app_readline_hide (&state);
 
-		// TODO: ensure proper encoding
-		fprintf (stderr, "[%s] ==> \"%s\"\n", "IRC", raw);
+		char *utf8 = irc_to_utf8 (ctx, raw);
+		fprintf (stderr, "[IRC] ==> \"%s\"\n", utf8);
+		free (utf8);
 
 		if (ctx->readline_prompt_shown)
 			app_readline_restore (&state, ctx->readline_prompt);
@@ -1539,10 +1548,11 @@ irc_process_message (const struct irc_message *msg,
 	unsigned long dummy;
 	if (xstrtoul (&dummy, msg->command, 10))
 	{
-		// TODO: check for valid UTF-8 and eventually try recoding from fallback
 		char *reconstructed = join_str_vector (&msg->params, ' ');
-		buffer_send_status (ctx, ctx->server_buffer, "%s", reconstructed);
+		char *utf8 = irc_to_utf8 (ctx, reconstructed);
 		free (reconstructed);
+		buffer_send_status (ctx, ctx->server_buffer, "%s", utf8);
+		free (utf8);
 	}
 }
 
-- 
cgit v1.2.3-70-g09d2