aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--degesch.c103
1 files changed, 77 insertions, 26 deletions
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)
{
@@ -2593,9 +2625,53 @@ irc_handle_nick (struct app_context *ctx, const struct irc_message *msg)
}
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)