diff options
| -rw-r--r-- | degesch.c | 90 | 
1 files changed, 88 insertions, 2 deletions
| @@ -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 | 
