From 4393e48145989906ac05cc622a6fcbac6d414e8f Mon Sep 17 00:00:00 2001
From: Přemysl Janouch
Date: Sat, 25 Apr 2015 14:53:29 +0200
Subject: degesch: encoding fixes
Shouldn't be totally broken anymore.
---
degesch.c | 125 ++++++++++++++++++++++++++++++++++----------------------------
1 file changed, 69 insertions(+), 56 deletions(-)
diff --git a/degesch.c b/degesch.c
index c3aab2d..095e05e 100644
--- a/degesch.c
+++ b/degesch.c
@@ -1453,13 +1453,47 @@ initiate_quit (struct app_context *ctx)
try_finish_quit (ctx);
}
+// As of 2015, everything should be in UTF-8. And if it's not, we'll decode it
+// as ISO Latin 1. This function should not be called on the whole message.
+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);
+}
+
+// This function is used to output debugging IRC traffic to the terminal.
+// It's far from ideal, as any non-UTF-8 text degrades the entire line to
+// ISO Latin 1. But it should work good enough most of the time.
+static char *
+irc_to_term (struct app_context *ctx, const char *text)
+{
+ char *utf8 = irc_to_utf8 (ctx, text);
+ char *term = iconv_xstrdup (ctx->term_from_utf8, utf8, -1, NULL);
+ free (utf8);
+ return term;
+}
+
static bool irc_send (struct app_context *ctx,
const char *format, ...) ATTRIBUTE_PRINTF (2, 3);
static bool
irc_send (struct app_context *ctx, const char *format, ...)
{
+ if (!soft_assert (ctx->irc_fd != -1))
+ {
+ print_debug ("tried sending a message to a dead server connection");
+ return false;
+ }
+
va_list ap;
+ va_start (ap, format);
+ struct str str;
+ str_init (&str);
+ str_append_vprintf (&str, format, ap);
+ va_end (ap);
if (g_debug_mode)
{
@@ -1467,25 +1501,14 @@ irc_send (struct app_context *ctx, const char *format, ...)
if (ctx->readline_prompt_shown)
app_readline_hide (&state);
- fputs ("[IRC] <== \"", stderr);
- va_start (ap, format);
- vfprintf (stderr, format, ap);
- va_end (ap);
- fputs ("\"\n", stderr);
+ char *term = irc_to_term (ctx, str.str);
+ fprintf (stderr, "[IRC] <== \"%s\"\n", term);
+ free (term);
if (ctx->readline_prompt_shown)
app_readline_restore (&state, ctx->readline_prompt);
}
-
- if (!soft_assert (ctx->irc_fd != -1))
- return false;
-
- va_start (ap, format);
- struct str str;
- str_init (&str);
- str_append_vprintf (&str, format, ap);
str_append (&str, "\r\n");
- va_end (ap);
bool result = true;
if (ctx->ssl)
@@ -1902,15 +1925,6 @@ 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_join (struct app_context *ctx, const struct irc_message *msg)
{
@@ -1969,8 +1983,8 @@ irc_handle_join (struct app_context *ctx, const struct irc_message *msg)
if (buffer)
{
buffer_send (ctx, buffer, BUFFER_LINE_JOIN, 0,
- .who = xstrdup (msg->prefix),
- .object = xstrdup (channel_name));
+ .who = irc_to_utf8 (ctx, msg->prefix),
+ .object = irc_to_utf8 (ctx, channel_name));
}
}
@@ -2003,9 +2017,9 @@ irc_handle_kick (struct app_context *ctx, const struct irc_message *msg)
if (buffer)
{
buffer_send (ctx, buffer, BUFFER_LINE_KICK, 0,
- .who = xstrdup (msg->prefix),
- .object = xstrdup (target),
- .reason = xstrdup (message));
+ .who = irc_to_utf8 (ctx, msg->prefix),
+ .object = irc_to_utf8 (ctx, target),
+ .reason = irc_to_utf8 (ctx, message));
}
}
@@ -2045,8 +2059,8 @@ irc_handle_nick (struct app_context *ctx, const struct irc_message *msg)
str_map_set (&ctx->irc_buffer_map, user->nickname, NULL);
buffer_send (ctx, pm_buffer, BUFFER_LINE_NICK, 0,
- .who = xstrdup (msg->prefix),
- .object = xstrdup (new_nickname));
+ .who = irc_to_utf8 (ctx, msg->prefix),
+ .object = irc_to_utf8 (ctx, new_nickname));
// TODO: use a full weechat-style buffer name here
buffer_rename (ctx, pm_buffer, new_nickname);
}
@@ -2064,7 +2078,7 @@ irc_handle_nick (struct app_context *ctx, const struct irc_message *msg)
continue;
buffer_send (ctx, buffer, BUFFER_LINE_NICK, 0,
- .object = xstrdup (new_nickname));
+ .object = irc_to_utf8 (ctx, new_nickname));
}
}
else
@@ -2076,8 +2090,8 @@ irc_handle_nick (struct app_context *ctx, const struct irc_message *msg)
str_map_find (&ctx->irc_buffer_map, iter->channel->name);
hard_assert (buffer != NULL);
buffer_send (ctx, buffer, BUFFER_LINE_NICK, 0,
- .who = xstrdup (msg->prefix),
- .object = xstrdup (new_nickname));
+ .who = irc_to_utf8 (ctx, msg->prefix),
+ .object = irc_to_utf8 (ctx, new_nickname));
}
}
@@ -2128,9 +2142,9 @@ irc_handle_part (struct app_context *ctx, const struct irc_message *msg)
if (buffer)
{
buffer_send (ctx, buffer, BUFFER_LINE_PART, 0,
- .who = xstrdup (msg->prefix),
- .object = xstrdup (channel_name),
- .reason = xstrdup (message));
+ .who = irc_to_utf8 (ctx, msg->prefix),
+ .object = irc_to_utf8 (ctx, channel_name),
+ .reason = irc_to_utf8 (ctx, message));
}
}
@@ -2175,8 +2189,8 @@ irc_handle_privmsg (struct app_context *ctx, const struct irc_message *msg)
// TODO: handle CTCP messages
// TODO: highlights
buffer_send (ctx, buffer, BUFFER_LINE_PRIVMSG, 0,
- .who = xstrdup (msg->prefix),
- .text = xstrdup (message));
+ .who = irc_to_utf8 (ctx, msg->prefix),
+ .text = irc_to_utf8 (ctx, message));
}
}
@@ -2206,8 +2220,8 @@ irc_handle_quit (struct app_context *ctx, const struct irc_message *msg)
if (buffer)
{
buffer_send (ctx, buffer, BUFFER_LINE_QUIT, 0,
- .who = xstrdup (msg->prefix),
- .reason = xstrdup (message));
+ .who = irc_to_utf8 (ctx, msg->prefix),
+ .reason = irc_to_utf8 (ctx, message));
// TODO: set some kind of a flag in the buffer and when the user
// reappers on a channel (JOIN), log a "is back online" message.
@@ -2221,8 +2235,8 @@ irc_handle_quit (struct app_context *ctx, const struct irc_message *msg)
buffer = str_map_find (&ctx->irc_buffer_map, iter->channel->name);
if (buffer)
buffer_send (ctx, buffer, BUFFER_LINE_QUIT, 0,
- .who = xstrdup (msg->prefix),
- .reason = xstrdup (message));
+ .who = irc_to_utf8 (ctx, msg->prefix),
+ .reason = irc_to_utf8 (ctx, message));
// This destroys "iter" which doesn't matter to us
irc_remove_user_from_channel (user, iter->channel);
@@ -2255,8 +2269,8 @@ irc_handle_topic (struct app_context *ctx, const struct irc_message *msg)
if (buffer)
{
buffer_send (ctx, buffer, BUFFER_LINE_TOPIC, 0,
- .who = xstrdup (msg->prefix),
- .text = xstrdup (topic));
+ .who = irc_to_utf8 (ctx, msg->prefix),
+ .text = irc_to_utf8 (ctx, topic));
}
}
@@ -2338,10 +2352,9 @@ irc_process_numeric (struct app_context *ctx,
// and send it to the server buffer
char *reconstructed = join_str_vector (©, ' ');
str_vector_free (©);
- char *utf8 = irc_to_utf8 (ctx, reconstructed);
+ buffer_send (ctx, ctx->server_buffer, BUFFER_LINE_STATUS, 0,
+ .text = irc_to_utf8 (ctx, reconstructed));
free (reconstructed);
- buffer_send_status (ctx, ctx->server_buffer, "%s", utf8);
- free (utf8);
switch (numeric)
{
@@ -2380,9 +2393,9 @@ irc_process_message (const struct irc_message *msg,
if (ctx->readline_prompt_shown)
app_readline_hide (&state);
- char *utf8 = irc_to_utf8 (ctx, raw);
- fprintf (stderr, "[IRC] ==> \"%s\"\n", utf8);
- free (utf8);
+ char *term = irc_to_term (ctx, raw);
+ fprintf (stderr, "[IRC] ==> \"%s\"\n", term);
+ free (term);
if (ctx->readline_prompt_shown)
app_readline_restore (&state, ctx->readline_prompt);
@@ -2577,10 +2590,10 @@ log_outcoming_privmsg (struct app_context *ctx,
{
if (buffer)
buffer_send (ctx, buffer, BUFFER_LINE_PRIVMSG, 0,
- .who = xstrdup (ctx->irc_user->nickname),
- .text = xstrdup (line));
+ .who = irc_to_utf8 (ctx, ctx->irc_user->nickname),
+ .text = irc_to_utf8 (ctx, line));
else
- // TODO: fix logging
+ // TODO: fix logging and encoding
buffer_send (ctx, ctx->server_buffer, BUFFER_LINE_STATUS, 0,
.text = xstrdup_printf ("MSG(%s): %s", a->target, line));
}
@@ -2595,10 +2608,10 @@ log_outcoming_notice (struct app_context *ctx,
{
if (buffer)
buffer_send (ctx, buffer, BUFFER_LINE_NOTICE, 0,
- .who = xstrdup (ctx->irc_user->nickname),
- .text = xstrdup (line));
+ .who = irc_to_utf8 (ctx, ctx->irc_user->nickname),
+ .text = irc_to_utf8 (ctx, line));
else
- // TODO: fix logging
+ // TODO: fix logging and encoding
buffer_send (ctx, ctx->server_buffer, BUFFER_LINE_STATUS, 0,
.text = xstrdup_printf ("Notice -> %s: %s", a->target, line));
}
--
cgit v1.2.3-70-g09d2