degesch: some basic RPL_ISUPPORT parsing
This commit is contained in:
parent
36185ddeee
commit
0b91604acd
60
degesch.c
60
degesch.c
@ -1035,6 +1035,11 @@ struct server
|
||||
|
||||
// IRC:
|
||||
|
||||
// TODO: casemapping-specific strxfrm and/or tolower (CASEMAPPING=rfc1459)
|
||||
// TODO: channel name prefixes (CHANTYPES=#& + IDCHAN)
|
||||
char *irc_channel_prefixes; ///< Channel user prefixes
|
||||
char *irc_channel_modes; ///< Channel user modes
|
||||
|
||||
struct str_map irc_users; ///< IRC user data
|
||||
struct str_map irc_channels; ///< IRC channel data
|
||||
struct str_map irc_buffer_map; ///< Maps IRC identifiers to buffers
|
||||
@ -1063,6 +1068,10 @@ server_init (struct server *self, struct poller *poller)
|
||||
str_init (&self->read_buffer);
|
||||
self->state = IRC_DISCONNECTED;
|
||||
|
||||
// RFC 1459 as per the RPL_ISUPPORT draft
|
||||
self->irc_channel_prefixes = xstrdup ("@+");
|
||||
self->irc_channel_modes = xstrdup ("ov");
|
||||
|
||||
str_map_init (&self->irc_users);
|
||||
self->irc_users.key_xfrm = irc_strxfrm;
|
||||
str_map_init (&self->irc_channels);
|
||||
@ -1110,6 +1119,9 @@ server_free (struct server *self)
|
||||
free (self->irc_user_mode);
|
||||
free (self->irc_user_host);
|
||||
|
||||
free (self->irc_channel_prefixes);
|
||||
free (self->irc_channel_modes);
|
||||
|
||||
str_map_free (&self->irc_users);
|
||||
str_map_free (&self->irc_channels);
|
||||
str_map_free (&self->irc_buffer_map);
|
||||
@ -4418,8 +4430,7 @@ irc_process_names (struct server *s, struct channel *channel)
|
||||
for (size_t i = 0; i < updates->len; i++)
|
||||
{
|
||||
const char *item = updates->vector[i];
|
||||
// FIXME: use server-specific chanmode characters
|
||||
const char *nick = item + strspn (item, "@+");
|
||||
const char *nick = item + strspn (item, s->irc_channel_modes);
|
||||
struct channel_user *channel_user = str_map_find (&map, nick);
|
||||
if (!channel_user)
|
||||
{
|
||||
@ -4459,6 +4470,43 @@ irc_handle_rpl_endofnames (struct server *s, const struct irc_message *msg)
|
||||
irc_process_names (s, channel);
|
||||
}
|
||||
|
||||
static void
|
||||
irc_handle_isupport_prefix (struct server *s, char *value)
|
||||
{
|
||||
char *modes = value;
|
||||
char *prefixes = strchr (value, ')');
|
||||
size_t n_prefixes = prefixes - modes;
|
||||
if (*modes++ != '(' || !prefixes++ || strlen (value) != 2 * n_prefixes--)
|
||||
return;
|
||||
|
||||
free (s->irc_channel_modes);
|
||||
free (s->irc_channel_prefixes);
|
||||
|
||||
s->irc_channel_modes = xstrndup (modes, n_prefixes);
|
||||
s->irc_channel_prefixes = xstrndup (prefixes, n_prefixes);
|
||||
}
|
||||
|
||||
static void
|
||||
irc_handle_rpl_isupport (struct server *s, const struct irc_message *msg)
|
||||
{
|
||||
if (msg->params.len < 2)
|
||||
return;
|
||||
|
||||
for (size_t i = 1; i < msg->params.len - 1; i++)
|
||||
{
|
||||
// TODO: if the parameter starts with "-", it resets to default
|
||||
char *param = msg->params.vector[i];
|
||||
char *value = param + strcspn (param, "=");
|
||||
if (*value) *value++ = '\0';
|
||||
|
||||
if (!strcmp (param, "PREFIX"))
|
||||
irc_handle_isupport_prefix (s, value);
|
||||
}
|
||||
|
||||
// TODO: initialize key_strxfrm according to server properties;
|
||||
// note that collisions may arise on reconnecting
|
||||
}
|
||||
|
||||
static void
|
||||
irc_process_numeric (struct server *s,
|
||||
const struct irc_message *msg, unsigned long numeric)
|
||||
@ -4491,14 +4539,8 @@ irc_process_numeric (struct server *s,
|
||||
if (msg->params.len == 2)
|
||||
irc_try_parse_welcome_for_userhost (s, msg->params.vector[1]);
|
||||
break;
|
||||
case IRC_RPL_ISUPPORT:
|
||||
// TODO: parse this, mainly PREFIX; see
|
||||
// http://www.irc.org/tech_docs/draft-brocklesby-irc-isupport-03.txt
|
||||
|
||||
// TODO: initialize key_strxfrm according to server properties;
|
||||
// note that collisions may arise on reconnecting
|
||||
break;
|
||||
|
||||
case IRC_RPL_ISUPPORT: irc_handle_rpl_isupport (s, msg); 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;
|
||||
|
Loading…
Reference in New Issue
Block a user