aboutsummaryrefslogtreecommitdiff
path: root/degesch.c
diff options
context:
space:
mode:
Diffstat (limited to 'degesch.c')
-rw-r--r--degesch.c90
1 files changed, 88 insertions, 2 deletions
diff --git a/degesch.c b/degesch.c
index eca8a89..20e1ff7 100644
--- a/degesch.c
+++ b/degesch.c
@@ -1206,8 +1206,33 @@ init_buffers (struct app_context *ctx)
LIST_APPEND_WITH_TAIL (ctx->buffers, ctx->buffers_tail, server);
}
+// --- Users, channels ---------------------------------------------------------
+
// --- Supporting code ---------------------------------------------------------
+static char *
+irc_cut_nickname (const char *prefix)
+{
+ return xstrndup (prefix, strcspn (prefix, "!@"));
+}
+
+static bool
+irc_is_this_us (struct app_context *ctx, const char *prefix)
+{
+ char *nick = irc_cut_nickname (prefix);
+ bool result = !irc_strcmp (nick, ctx->irc_nickname);
+ free (nick);
+ return result;
+}
+
+static bool
+irc_is_channel (struct app_context *ctx, const char *ident)
+{
+ (void) ctx; // TODO: parse prefixes from server features
+
+ return *ident && !!strchr ("#&+!", *ident);
+}
+
static void
irc_shutdown (struct app_context *ctx)
{
@@ -1712,8 +1737,69 @@ irc_to_utf8 (struct app_context *ctx, const char *text)
static void
irc_handle_join (struct app_context *ctx, const struct irc_message *msg)
{
- // TODO: if the user is us, create a new buffer and activate it.
- // TODO: log a message
+ if (!msg->prefix || msg->params.len < 1)
+ return;
+
+ const char *target = msg->params.vector[0];
+ if (!irc_is_channel (ctx, target))
+ return;
+
+ struct channel *channel = str_map_find (&ctx->irc_channels, target);
+ struct buffer *buffer = str_map_find (&ctx->irc_buffer_map, target);
+ hard_assert ((channel && buffer) ||
+ (channel && !buffer) || (!channel && !buffer));
+
+ // We've joined a new channel
+ if (!channel && irc_is_this_us (ctx, msg->prefix))
+ {
+ channel = channel_new ();
+ channel->name = xstrdup (target);
+ channel->mode = xstrdup ("");
+ channel->topic = NULL;
+ str_map_set (&ctx->irc_channels, channel->name, channel);
+
+ buffer = buffer_new ();
+ buffer->type = BUFFER_CHANNEL;
+ buffer->name = xstrdup (target);
+ buffer->channel = channel_ref (channel);
+ LIST_APPEND_WITH_TAIL (ctx->buffers, ctx->buffers_tail, buffer);
+ str_map_set (&ctx->irc_buffer_map, channel->name, buffer);
+
+ buffer_activate (ctx, buffer);
+ }
+
+ // This is weird, ignoring
+ if (!channel)
+ return;
+
+ // Get or make a user object
+ char *nickname = irc_cut_nickname (msg->prefix);
+ struct user *user = str_map_find (&ctx->irc_users, nickname);
+ if (!user)
+ {
+ user = user_new ();
+ user->nickname = nickname;
+ str_map_set (&ctx->irc_users, user->nickname, user);
+ }
+ else
+ free (nickname);
+
+ // Link the user with the channel
+ struct user_channel *user_channel = user_channel_new ();
+ user_channel->channel = channel_ref (channel);
+ LIST_PREPEND (user->channels, user_channel);
+
+ struct channel_user *channel_user = channel_user_new ();
+ channel_user->user = user_ref (user);
+ channel_user->modes = xstrdup ("");
+ LIST_PREPEND (channel->users, channel_user);
+
+ // Finally log the message
+ if (buffer)
+ {
+ buffer_send (ctx, buffer, BUFFER_LINE_JOIN, 0,
+ msg->prefix, NULL, "%s", target);
+ }
}
static void