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);
|
||||
}
|
||||
|
||||
// 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));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user