degesch: encoding fixes
Shouldn't be totally broken anymore.
This commit is contained in:
parent
c38dfced51
commit
4393e48145
125
degesch.c
125
degesch.c
|
@ -1453,13 +1453,47 @@ initiate_quit (struct app_context *ctx)
|
||||||
try_finish_quit (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,
|
static bool irc_send (struct app_context *ctx,
|
||||||
const char *format, ...) ATTRIBUTE_PRINTF (2, 3);
|
const char *format, ...) ATTRIBUTE_PRINTF (2, 3);
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
irc_send (struct app_context *ctx, const char *format, ...)
|
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_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)
|
if (g_debug_mode)
|
||||||
{
|
{
|
||||||
|
@ -1467,25 +1501,14 @@ irc_send (struct app_context *ctx, const char *format, ...)
|
||||||
if (ctx->readline_prompt_shown)
|
if (ctx->readline_prompt_shown)
|
||||||
app_readline_hide (&state);
|
app_readline_hide (&state);
|
||||||
|
|
||||||
fputs ("[IRC] <== \"", stderr);
|
char *term = irc_to_term (ctx, str.str);
|
||||||
va_start (ap, format);
|
fprintf (stderr, "[IRC] <== \"%s\"\n", term);
|
||||||
vfprintf (stderr, format, ap);
|
free (term);
|
||||||
va_end (ap);
|
|
||||||
fputs ("\"\n", stderr);
|
|
||||||
|
|
||||||
if (ctx->readline_prompt_shown)
|
if (ctx->readline_prompt_shown)
|
||||||
app_readline_restore (&state, ctx->readline_prompt);
|
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");
|
str_append (&str, "\r\n");
|
||||||
va_end (ap);
|
|
||||||
|
|
||||||
bool result = true;
|
bool result = true;
|
||||||
if (ctx->ssl)
|
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 will need a proper mode parser; to be shared with kike
|
||||||
// TODO: we alse definitely need to parse server capability messages
|
// 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
|
static void
|
||||||
irc_handle_join (struct app_context *ctx, const struct irc_message *msg)
|
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)
|
if (buffer)
|
||||||
{
|
{
|
||||||
buffer_send (ctx, buffer, BUFFER_LINE_JOIN, 0,
|
buffer_send (ctx, buffer, BUFFER_LINE_JOIN, 0,
|
||||||
.who = xstrdup (msg->prefix),
|
.who = irc_to_utf8 (ctx, msg->prefix),
|
||||||
.object = xstrdup (channel_name));
|
.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)
|
if (buffer)
|
||||||
{
|
{
|
||||||
buffer_send (ctx, buffer, BUFFER_LINE_KICK, 0,
|
buffer_send (ctx, buffer, BUFFER_LINE_KICK, 0,
|
||||||
.who = xstrdup (msg->prefix),
|
.who = irc_to_utf8 (ctx, msg->prefix),
|
||||||
.object = xstrdup (target),
|
.object = irc_to_utf8 (ctx, target),
|
||||||
.reason = xstrdup (message));
|
.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);
|
str_map_set (&ctx->irc_buffer_map, user->nickname, NULL);
|
||||||
|
|
||||||
buffer_send (ctx, pm_buffer, BUFFER_LINE_NICK, 0,
|
buffer_send (ctx, pm_buffer, BUFFER_LINE_NICK, 0,
|
||||||
.who = xstrdup (msg->prefix),
|
.who = irc_to_utf8 (ctx, msg->prefix),
|
||||||
.object = xstrdup (new_nickname));
|
.object = irc_to_utf8 (ctx, new_nickname));
|
||||||
// TODO: use a full weechat-style buffer name here
|
// TODO: use a full weechat-style buffer name here
|
||||||
buffer_rename (ctx, pm_buffer, new_nickname);
|
buffer_rename (ctx, pm_buffer, new_nickname);
|
||||||
}
|
}
|
||||||
|
@ -2064,7 +2078,7 @@ irc_handle_nick (struct app_context *ctx, const struct irc_message *msg)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
buffer_send (ctx, buffer, BUFFER_LINE_NICK, 0,
|
buffer_send (ctx, buffer, BUFFER_LINE_NICK, 0,
|
||||||
.object = xstrdup (new_nickname));
|
.object = irc_to_utf8 (ctx, new_nickname));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
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);
|
str_map_find (&ctx->irc_buffer_map, iter->channel->name);
|
||||||
hard_assert (buffer != NULL);
|
hard_assert (buffer != NULL);
|
||||||
buffer_send (ctx, buffer, BUFFER_LINE_NICK, 0,
|
buffer_send (ctx, buffer, BUFFER_LINE_NICK, 0,
|
||||||
.who = xstrdup (msg->prefix),
|
.who = irc_to_utf8 (ctx, msg->prefix),
|
||||||
.object = xstrdup (new_nickname));
|
.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)
|
if (buffer)
|
||||||
{
|
{
|
||||||
buffer_send (ctx, buffer, BUFFER_LINE_PART, 0,
|
buffer_send (ctx, buffer, BUFFER_LINE_PART, 0,
|
||||||
.who = xstrdup (msg->prefix),
|
.who = irc_to_utf8 (ctx, msg->prefix),
|
||||||
.object = xstrdup (channel_name),
|
.object = irc_to_utf8 (ctx, channel_name),
|
||||||
.reason = xstrdup (message));
|
.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: handle CTCP messages
|
||||||
// TODO: highlights
|
// TODO: highlights
|
||||||
buffer_send (ctx, buffer, BUFFER_LINE_PRIVMSG, 0,
|
buffer_send (ctx, buffer, BUFFER_LINE_PRIVMSG, 0,
|
||||||
.who = xstrdup (msg->prefix),
|
.who = irc_to_utf8 (ctx, msg->prefix),
|
||||||
.text = xstrdup (message));
|
.text = irc_to_utf8 (ctx, message));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2206,8 +2220,8 @@ irc_handle_quit (struct app_context *ctx, const struct irc_message *msg)
|
||||||
if (buffer)
|
if (buffer)
|
||||||
{
|
{
|
||||||
buffer_send (ctx, buffer, BUFFER_LINE_QUIT, 0,
|
buffer_send (ctx, buffer, BUFFER_LINE_QUIT, 0,
|
||||||
.who = xstrdup (msg->prefix),
|
.who = irc_to_utf8 (ctx, msg->prefix),
|
||||||
.reason = xstrdup (message));
|
.reason = irc_to_utf8 (ctx, message));
|
||||||
|
|
||||||
// TODO: set some kind of a flag in the buffer and when the user
|
// 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.
|
// 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);
|
buffer = str_map_find (&ctx->irc_buffer_map, iter->channel->name);
|
||||||
if (buffer)
|
if (buffer)
|
||||||
buffer_send (ctx, buffer, BUFFER_LINE_QUIT, 0,
|
buffer_send (ctx, buffer, BUFFER_LINE_QUIT, 0,
|
||||||
.who = xstrdup (msg->prefix),
|
.who = irc_to_utf8 (ctx, msg->prefix),
|
||||||
.reason = xstrdup (message));
|
.reason = irc_to_utf8 (ctx, message));
|
||||||
|
|
||||||
// This destroys "iter" which doesn't matter to us
|
// This destroys "iter" which doesn't matter to us
|
||||||
irc_remove_user_from_channel (user, iter->channel);
|
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)
|
if (buffer)
|
||||||
{
|
{
|
||||||
buffer_send (ctx, buffer, BUFFER_LINE_TOPIC, 0,
|
buffer_send (ctx, buffer, BUFFER_LINE_TOPIC, 0,
|
||||||
.who = xstrdup (msg->prefix),
|
.who = irc_to_utf8 (ctx, msg->prefix),
|
||||||
.text = xstrdup (topic));
|
.text = irc_to_utf8 (ctx, topic));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2338,10 +2352,9 @@ irc_process_numeric (struct app_context *ctx,
|
||||||
// and send it to the server buffer
|
// and send it to the server buffer
|
||||||
char *reconstructed = join_str_vector (©, ' ');
|
char *reconstructed = join_str_vector (©, ' ');
|
||||||
str_vector_free (©);
|
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);
|
free (reconstructed);
|
||||||
buffer_send_status (ctx, ctx->server_buffer, "%s", utf8);
|
|
||||||
free (utf8);
|
|
||||||
|
|
||||||
switch (numeric)
|
switch (numeric)
|
||||||
{
|
{
|
||||||
|
@ -2380,9 +2393,9 @@ irc_process_message (const struct irc_message *msg,
|
||||||
if (ctx->readline_prompt_shown)
|
if (ctx->readline_prompt_shown)
|
||||||
app_readline_hide (&state);
|
app_readline_hide (&state);
|
||||||
|
|
||||||
char *utf8 = irc_to_utf8 (ctx, raw);
|
char *term = irc_to_term (ctx, raw);
|
||||||
fprintf (stderr, "[IRC] ==> \"%s\"\n", utf8);
|
fprintf (stderr, "[IRC] ==> \"%s\"\n", term);
|
||||||
free (utf8);
|
free (term);
|
||||||
|
|
||||||
if (ctx->readline_prompt_shown)
|
if (ctx->readline_prompt_shown)
|
||||||
app_readline_restore (&state, ctx->readline_prompt);
|
app_readline_restore (&state, ctx->readline_prompt);
|
||||||
|
@ -2577,10 +2590,10 @@ log_outcoming_privmsg (struct app_context *ctx,
|
||||||
{
|
{
|
||||||
if (buffer)
|
if (buffer)
|
||||||
buffer_send (ctx, buffer, BUFFER_LINE_PRIVMSG, 0,
|
buffer_send (ctx, buffer, BUFFER_LINE_PRIVMSG, 0,
|
||||||
.who = xstrdup (ctx->irc_user->nickname),
|
.who = irc_to_utf8 (ctx, ctx->irc_user->nickname),
|
||||||
.text = xstrdup (line));
|
.text = irc_to_utf8 (ctx, line));
|
||||||
else
|
else
|
||||||
// TODO: fix logging
|
// TODO: fix logging and encoding
|
||||||
buffer_send (ctx, ctx->server_buffer, BUFFER_LINE_STATUS, 0,
|
buffer_send (ctx, ctx->server_buffer, BUFFER_LINE_STATUS, 0,
|
||||||
.text = xstrdup_printf ("MSG(%s): %s", a->target, line));
|
.text = xstrdup_printf ("MSG(%s): %s", a->target, line));
|
||||||
}
|
}
|
||||||
|
@ -2595,10 +2608,10 @@ log_outcoming_notice (struct app_context *ctx,
|
||||||
{
|
{
|
||||||
if (buffer)
|
if (buffer)
|
||||||
buffer_send (ctx, buffer, BUFFER_LINE_NOTICE, 0,
|
buffer_send (ctx, buffer, BUFFER_LINE_NOTICE, 0,
|
||||||
.who = xstrdup (ctx->irc_user->nickname),
|
.who = irc_to_utf8 (ctx, ctx->irc_user->nickname),
|
||||||
.text = xstrdup (line));
|
.text = irc_to_utf8 (ctx, line));
|
||||||
else
|
else
|
||||||
// TODO: fix logging
|
// TODO: fix logging and encoding
|
||||||
buffer_send (ctx, ctx->server_buffer, BUFFER_LINE_STATUS, 0,
|
buffer_send (ctx, ctx->server_buffer, BUFFER_LINE_STATUS, 0,
|
||||||
.text = xstrdup_printf ("Notice -> %s: %s", a->target, line));
|
.text = xstrdup_printf ("Notice -> %s: %s", a->target, line));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue