diff --git a/degesch.c b/degesch.c index ab4c3ed..a3dd2b6 100644 --- a/degesch.c +++ b/degesch.c @@ -2411,6 +2411,38 @@ ctcp_destroy (struct ctcp_chunk *list) // TODO: we will need a proper mode parser; to be shared with kike // TODO: we alse definitely need to parse server capability messages +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 + if (!channel) + return NULL; + } + else if (!buffer) + { + // Implying that the target is us + + // Don't make user buffers for servers (they can send NOTICEs) + if (!irc_find_userhost (msg->prefix)) + return ctx->server_buffer; + + char *nickname = irc_cut_nickname (msg->prefix); + buffer = irc_get_or_make_user_buffer (ctx, nickname); + free (nickname); + } + return buffer; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + static void irc_handle_join (struct app_context *ctx, const struct irc_message *msg) { @@ -2592,10 +2624,54 @@ irc_handle_nick (struct app_context *ctx, const struct irc_message *msg) refresh_prompt (ctx); } +static void +irc_handle_ctcp_reply (struct app_context *ctx, + const struct irc_message *msg, struct ctcp_chunk *chunk) +{ + char *nickname = irc_cut_nickname (msg->prefix); + char *nickname_utf8 = irc_to_utf8 (ctx, nickname); + char *tag_utf8 = irc_to_utf8 (ctx, chunk->tag.str); + char *text_utf8 = irc_to_utf8 (ctx, chunk->text.str); + + buffer_send_status (ctx, ctx->server_buffer, + "CTCP reply from %s: %s %s", nickname_utf8, tag_utf8, text_utf8); + + free (nickname); + free (nickname_utf8); + free (tag_utf8); + free (text_utf8); +} + +static void +irc_handle_notice_text (struct app_context *ctx, + const struct irc_message *msg, struct str *text) +{ + const char *target = msg->params.vector[0]; + struct buffer *buffer = irc_get_buffer_for_message (ctx, msg, target); + + if (buffer) + { + // TODO: highlights + buffer_send (ctx, buffer, BUFFER_LINE_NOTICE, 0, + .who = irc_to_utf8 (ctx, msg->prefix), + .text = irc_to_utf8 (ctx, text->str)); + } +} + static void irc_handle_notice (struct app_context *ctx, const struct irc_message *msg) { - // TODO: log a message + 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_notice_text (ctx, msg, &iter->text); + else + irc_handle_ctcp_reply (ctx, msg, iter); + ctcp_destroy (chunks); } static void @@ -2727,31 +2803,6 @@ irc_handle_ctcp_request (struct app_context *ctx, 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 - if (!channel) - 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)