kike: implement LIST
This commit is contained in:
		@@ -634,7 +634,7 @@ str_map_iter_init (struct str_map_iter *self, struct str_map *map)
 | 
				
			|||||||
	self->link = NULL;
 | 
						self->link = NULL;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static bool
 | 
					static void *
 | 
				
			||||||
str_map_iter_next (struct str_map_iter *self)
 | 
					str_map_iter_next (struct str_map_iter *self)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct str_map *map = self->map;
 | 
						struct str_map *map = self->map;
 | 
				
			||||||
@@ -643,10 +643,10 @@ str_map_iter_next (struct str_map_iter *self)
 | 
				
			|||||||
	while (!self->link)
 | 
						while (!self->link)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		if (self->next_index >= map->len)
 | 
							if (self->next_index >= map->len)
 | 
				
			||||||
			return false;
 | 
								return NULL;
 | 
				
			||||||
		self->link = map->map[self->next_index++];
 | 
							self->link = map->map[self->next_index++];
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return true;
 | 
						return self->link->data;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static uint64_t
 | 
					static uint64_t
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										53
									
								
								src/kike.c
									
									
									
									
									
								
							
							
						
						
									
										53
									
								
								src/kike.c
									
									
									
									
									
								
							@@ -325,6 +325,8 @@ struct channel
 | 
				
			|||||||
	char *key;                          ///< Channel key
 | 
						char *key;                          ///< Channel key
 | 
				
			||||||
	long user_limit;                    ///< User limit or -1
 | 
						long user_limit;                    ///< User limit or -1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						char *topic;                        ///< Channel topic
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct channel_user *users;         ///< Channel users
 | 
						struct channel_user *users;         ///< Channel users
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct str_vector ban_list;         ///< Ban list
 | 
						struct str_vector ban_list;         ///< Ban list
 | 
				
			||||||
@@ -347,6 +349,7 @@ channel_free (struct channel *self)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	free (self->name);
 | 
						free (self->name);
 | 
				
			||||||
	free (self->key);
 | 
						free (self->key);
 | 
				
			||||||
 | 
						free (self->topic);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct channel_user *link, *tmp;
 | 
						struct channel_user *link, *tmp;
 | 
				
			||||||
	for (link = self->users; link; link = tmp)
 | 
						for (link = self->users; link; link = tmp)
 | 
				
			||||||
@@ -627,6 +630,8 @@ enum
 | 
				
			|||||||
	IRC_RPL_LUSERME               = 255,
 | 
						IRC_RPL_LUSERME               = 255,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	IRC_RPL_USERHOST              = 302,
 | 
						IRC_RPL_USERHOST              = 302,
 | 
				
			||||||
 | 
						IRC_RPL_LIST                  = 322,
 | 
				
			||||||
 | 
						IRC_RPL_LISTEND               = 323,
 | 
				
			||||||
	IRC_RPL_VERSION               = 351,
 | 
						IRC_RPL_VERSION               = 351,
 | 
				
			||||||
	IRC_RPL_MOTD                  = 372,
 | 
						IRC_RPL_MOTD                  = 372,
 | 
				
			||||||
	IRC_RPL_MOTDSTART             = 375,
 | 
						IRC_RPL_MOTDSTART             = 375,
 | 
				
			||||||
@@ -662,6 +667,8 @@ static const char *g_default_replies[] =
 | 
				
			|||||||
	[IRC_RPL_LUSERME] = ":I have %d clients and %d servers",
 | 
						[IRC_RPL_LUSERME] = ":I have %d clients and %d servers",
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	[IRC_RPL_USERHOST] = ":%s",
 | 
						[IRC_RPL_USERHOST] = ":%s",
 | 
				
			||||||
 | 
						[IRC_RPL_LIST] = "%s %d :%s",
 | 
				
			||||||
 | 
						[IRC_RPL_LISTEND] = ":End of LIST",
 | 
				
			||||||
	[IRC_RPL_VERSION] = "%s.%d %s :%s",
 | 
						[IRC_RPL_VERSION] = "%s.%d %s :%s",
 | 
				
			||||||
	[IRC_RPL_MOTD] = ":- %s",
 | 
						[IRC_RPL_MOTD] = ":- %s",
 | 
				
			||||||
	[IRC_RPL_MOTDSTART] = ":- %s Message of the day - ",
 | 
						[IRC_RPL_MOTDSTART] = ":- %s Message of the day - ",
 | 
				
			||||||
@@ -998,6 +1005,51 @@ irc_handle_privmsg (const struct irc_message *msg, struct client *c)
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					irc_send_rpl_list (struct client *c, const struct channel *chan)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int visible = 0;
 | 
				
			||||||
 | 
						for (struct channel_user *user = chan->users;
 | 
				
			||||||
 | 
							 user; user = user->next)
 | 
				
			||||||
 | 
							visible++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						irc_send_reply (c, IRC_RPL_LIST, chan->name, visible, chan->topic);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					irc_handle_list (const struct irc_message *msg, struct client *c)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (msg->params.len > 1 && !irc_is_this_me (c->ctx, msg->params.vector[1]))
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							irc_send_reply (c, IRC_ERR_NOSUCHSERVER, msg->params.vector[1]);
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct channel *chan;
 | 
				
			||||||
 | 
						if (msg->params.len == 0)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							struct str_map_iter iter;
 | 
				
			||||||
 | 
							str_map_iter_init (&iter, &c->ctx->channels);
 | 
				
			||||||
 | 
							while ((chan = str_map_iter_next (&iter)))
 | 
				
			||||||
 | 
								if (!(chan->modes & (IRC_CHAN_MODE_PRIVATE | IRC_CHAN_MODE_SECRET))
 | 
				
			||||||
 | 
								 || client_on_channel (c, chan))
 | 
				
			||||||
 | 
									irc_send_rpl_list (c, chan);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							struct str_vector channels;
 | 
				
			||||||
 | 
							str_vector_init (&channels);
 | 
				
			||||||
 | 
							split_str_ignore_empty (msg->params.vector[0], ',', &channels);
 | 
				
			||||||
 | 
							for (size_t i = 0; i < channels.len; i++)
 | 
				
			||||||
 | 
								if ((chan = str_map_find (&c->ctx->channels, channels.vector[i]))
 | 
				
			||||||
 | 
								 && (!(chan->modes & IRC_CHAN_MODE_SECRET)
 | 
				
			||||||
 | 
								 || client_on_channel (c, chan)))
 | 
				
			||||||
 | 
									irc_send_rpl_list (c, chan);
 | 
				
			||||||
 | 
							str_vector_free (&channels);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						irc_send_reply (c, IRC_RPL_LISTEND);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// -----------------------------------------------------------------------------
 | 
					// -----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct irc_command
 | 
					struct irc_command
 | 
				
			||||||
@@ -1028,6 +1080,7 @@ irc_register_handlers (struct server_context *ctx)
 | 
				
			|||||||
		{ "VERSION",  true,  irc_handle_version  },
 | 
							{ "VERSION",  true,  irc_handle_version  },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		{ "PRIVMSG",  true,  irc_handle_privmsg  },
 | 
							{ "PRIVMSG",  true,  irc_handle_privmsg  },
 | 
				
			||||||
 | 
							{ "LIST",     true,  irc_handle_list     },
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (size_t i = 0; i < N_ELEMENTS (message_handlers); i++)
 | 
						for (size_t i = 0; i < N_ELEMENTS (message_handlers); i++)
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user