kike: implement LIST
This commit is contained in:
parent
97f35bedfd
commit
96f4b81182
@ -634,7 +634,7 @@ str_map_iter_init (struct str_map_iter *self, struct str_map *map)
|
||||
self->link = NULL;
|
||||
}
|
||||
|
||||
static bool
|
||||
static void *
|
||||
str_map_iter_next (struct str_map_iter *self)
|
||||
{
|
||||
struct str_map *map = self->map;
|
||||
@ -643,10 +643,10 @@ str_map_iter_next (struct str_map_iter *self)
|
||||
while (!self->link)
|
||||
{
|
||||
if (self->next_index >= map->len)
|
||||
return false;
|
||||
return NULL;
|
||||
self->link = map->map[self->next_index++];
|
||||
}
|
||||
return true;
|
||||
return self->link->data;
|
||||
}
|
||||
|
||||
static uint64_t
|
||||
|
53
src/kike.c
53
src/kike.c
@ -325,6 +325,8 @@ struct channel
|
||||
char *key; ///< Channel key
|
||||
long user_limit; ///< User limit or -1
|
||||
|
||||
char *topic; ///< Channel topic
|
||||
|
||||
struct channel_user *users; ///< Channel users
|
||||
|
||||
struct str_vector ban_list; ///< Ban list
|
||||
@ -347,6 +349,7 @@ channel_free (struct channel *self)
|
||||
{
|
||||
free (self->name);
|
||||
free (self->key);
|
||||
free (self->topic);
|
||||
|
||||
struct channel_user *link, *tmp;
|
||||
for (link = self->users; link; link = tmp)
|
||||
@ -627,6 +630,8 @@ enum
|
||||
IRC_RPL_LUSERME = 255,
|
||||
|
||||
IRC_RPL_USERHOST = 302,
|
||||
IRC_RPL_LIST = 322,
|
||||
IRC_RPL_LISTEND = 323,
|
||||
IRC_RPL_VERSION = 351,
|
||||
IRC_RPL_MOTD = 372,
|
||||
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_USERHOST] = ":%s",
|
||||
[IRC_RPL_LIST] = "%s %d :%s",
|
||||
[IRC_RPL_LISTEND] = ":End of LIST",
|
||||
[IRC_RPL_VERSION] = "%s.%d %s :%s",
|
||||
[IRC_RPL_MOTD] = ":- %s",
|
||||
[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
|
||||
@ -1028,6 +1080,7 @@ irc_register_handlers (struct server_context *ctx)
|
||||
{ "VERSION", true, irc_handle_version },
|
||||
|
||||
{ "PRIVMSG", true, irc_handle_privmsg },
|
||||
{ "LIST", true, irc_handle_list },
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < N_ELEMENTS (message_handlers); i++)
|
||||
|
Loading…
Reference in New Issue
Block a user