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;
|
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++)
|
||||||
|
Loading…
Reference in New Issue
Block a user