summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--degesch.c62
1 files changed, 49 insertions, 13 deletions
diff --git a/degesch.c b/degesch.c
index 50544d5..57d8f78 100644
--- a/degesch.c
+++ b/degesch.c
@@ -4387,6 +4387,50 @@ irc_handle_rpl_userhost (struct server *s, const struct irc_message *msg)
}
static void
+irc_handle_rpl_namreply (struct server *s, const struct irc_message *msg)
+{
+ if (msg->params.len < 4)
+ return;
+
+ const char *channel_name = msg->params.vector[2];
+ const char *nicks = msg->params.vector[3];
+
+ // Just push the nicknames to a string vector for later processing
+ struct channel *channel = str_map_find (&s->irc_channels, channel_name);
+ if (channel)
+ split_str_ignore_empty (nicks, ' ', &channel->names_buf);
+}
+
+static void
+irc_process_names (struct server *s, struct channel *channel)
+{
+ // TODO: overwrite users with "channel->names_buf", which contains
+ // [@+]-prefixed nicknames; take care to combine channel user modes
+
+ str_vector_reset (&channel->names_buf);
+}
+
+static void
+irc_handle_rpl_endofnames (struct server *s, const struct irc_message *msg)
+{
+ if (msg->params.len < 2)
+ return;
+
+ const char *channel_name = msg->params.vector[1];
+ struct channel *channel = str_map_find (&s->irc_channels, channel_name);
+ if (!strcmp (channel_name, "*"))
+ {
+ struct str_map_iter iter;
+ str_map_iter_init (&iter, &s->irc_channels);
+ struct channel *channel;
+ while ((channel = str_map_iter_next (&iter)))
+ irc_process_names (s, channel);
+ }
+ else if (channel)
+ irc_process_names (s, channel);
+}
+
+static void
irc_process_numeric (struct server *s,
const struct irc_message *msg, unsigned long numeric)
{
@@ -4425,16 +4469,11 @@ irc_process_numeric (struct server *s,
// TODO: initialize key_strxfrm according to server properties;
// note that collisions may arise on reconnecting
break;
- case IRC_RPL_USERHOST:
- irc_handle_rpl_userhost (s, msg);
- break;
- case IRC_RPL_NAMREPLY:
- // TODO: find the channel and if found, push nicks to names_buf
- break;
- case IRC_RPL_ENDOFNAMES:
- // TODO: find the channel and if found, overwrite users;
- // however take care to combine channel user modes
- break;
+
+ case IRC_RPL_USERHOST: irc_handle_rpl_userhost (s, msg); break;
+ case IRC_RPL_NAMREPLY: irc_handle_rpl_namreply (s, msg); break;
+ case IRC_RPL_ENDOFNAMES: irc_handle_rpl_endofnames (s, msg); break;
+
case IRC_ERR_NICKNAMEINUSE:
// TODO: if (state == IRC_CONNECTED), use a different nick;
// either use a number suffix, or accept commas in "nickname" config
@@ -5786,9 +5825,6 @@ g_command_handlers[] =
{ "list", "List channels and their topic",
"[<channel>[,<channel>...]] [<server>]",
handle_command_list },
- // XXX: for NAMES with no arguments, how do we tell the end of it all?
- // Maybe we just surf through all channels and process the lists
- // as they are.
{ "names", "List users on channel",
"[<channel>[,<channel>...]]",
handle_command_names },