From a66bf15e672f51315147a334238a4df2b00d5318 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C5=99emysl=20Janouch?= Date: Sun, 26 Apr 2015 22:31:07 +0200 Subject: [PATCH] degesch: process CTCP in PRIVMSG Finally we can display /me. --- degesch.c | 66 +++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 55 insertions(+), 11 deletions(-) diff --git a/degesch.c b/degesch.c index 10a82c8..95350ae 100644 --- a/degesch.c +++ b/degesch.c @@ -2631,42 +2631,86 @@ irc_handle_ping (struct app_context *ctx, const struct irc_message *msg) } static void -irc_handle_privmsg (struct app_context *ctx, const struct irc_message *msg) +irc_handle_ctcp_request (struct app_context *ctx, + const struct irc_message *msg, struct ctcp_chunk *chunk) { - if (!msg->prefix || msg->params.len < 2) - return; + char *nickname = irc_cut_nickname (msg->prefix); + char *nickname_utf8 = irc_to_utf8 (ctx, nickname); + free (nickname); + char *tag_utf8 = irc_to_utf8 (ctx, chunk->tag.str); - const char *target = msg->params.vector[0]; - const char *message = msg->params.vector[1]; + buffer_send_status (ctx, ctx->server_buffer, + "CTCP requested by %s: %s", nickname_utf8, tag_utf8); + + // TODO: reply to other CTCPs; + // see http://www.irchelp.org/irchelp/rfc/ctcpspec.html + + free (nickname_utf8); + free (tag_utf8); +} + +static struct buffer * +irc_get_buffer_for_message (struct app_context *ctx, + const struct irc_message *msg, const char *target) +{ struct buffer *buffer = str_map_find (&ctx->irc_buffer_map, target); - if (irc_is_channel (ctx, target)) { struct channel *channel = str_map_find (&ctx->irc_channels, target); hard_assert ((channel && buffer) || (channel && !buffer) || (!channel && !buffer)); - // This is weird, ignoring + // This is weird if (!channel) - return; + return NULL; } else if (!buffer) { + // Implying that the target is us char *nickname = irc_cut_nickname (msg->prefix); buffer = irc_get_or_make_user_buffer (ctx, nickname); free (nickname); } + return buffer; +} + +static void +irc_handle_privmsg_text (struct app_context *ctx, + const struct irc_message *msg, struct str *text, bool is_action) +{ + const char *target = msg->params.vector[0]; + struct buffer *buffer = irc_get_buffer_for_message (ctx, msg, target); if (buffer) { - // TODO: handle CTCP messages // TODO: highlights - buffer_send (ctx, buffer, BUFFER_LINE_PRIVMSG, 0, + enum buffer_line_type type = is_action + ? BUFFER_LINE_ACTION + : BUFFER_LINE_PRIVMSG; + buffer_send (ctx, buffer, type, 0, .who = irc_to_utf8 (ctx, msg->prefix), - .text = irc_to_utf8 (ctx, message)); + .text = irc_to_utf8 (ctx, text->str)); } } +static void +irc_handle_privmsg (struct app_context *ctx, const struct irc_message *msg) +{ + if (!msg->prefix || msg->params.len < 2) + return; + + // This ignores empty messages which we should never receive anyway + struct ctcp_chunk *chunks = ctcp_parse (msg->params.vector[1]); + LIST_FOR_EACH (struct ctcp_chunk, iter, chunks) + if (!iter->is_extended) + irc_handle_privmsg_text (ctx, msg, &iter->text, false); + else if (!strcmp (iter->tag.str, "ACTION")) + irc_handle_privmsg_text (ctx, msg, &iter->text, true); + else + irc_handle_ctcp_request (ctx, msg, iter); + ctcp_destroy (chunks); +} + static void irc_handle_quit (struct app_context *ctx, const struct irc_message *msg) {