degesch: parse more of RPL_ISUPPORT
This commit is contained in:
parent
81aff58f73
commit
2242724c34
132
degesch.c
132
degesch.c
@ -1035,11 +1035,6 @@ struct server
|
|||||||
|
|
||||||
// IRC:
|
// 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_users; ///< IRC user data
|
||||||
struct str_map irc_channels; ///< IRC channel data
|
struct str_map irc_channels; ///< IRC channel data
|
||||||
struct str_map irc_buffer_map; ///< Maps IRC identifiers to buffers
|
struct str_map irc_buffer_map; ///< Maps IRC identifiers to buffers
|
||||||
@ -1048,6 +1043,22 @@ struct server
|
|||||||
char *irc_user_mode; ///< Our current user mode
|
char *irc_user_mode; ///< Our current user mode
|
||||||
char *irc_user_host; ///< Our current user@host
|
char *irc_user_host; ///< Our current user@host
|
||||||
|
|
||||||
|
// Server-specific information (from RPL_ISUPPORT):
|
||||||
|
|
||||||
|
// TODO: implement a generic strcmp() on top of "irc_tolower"
|
||||||
|
/// Convert an IRC identifier character to lower-case
|
||||||
|
int (*irc_tolower) (int);
|
||||||
|
|
||||||
|
/// Key conversion function for hashmap lookups
|
||||||
|
size_t (*irc_strxfrm) (char *, const char *, size_t);
|
||||||
|
|
||||||
|
char *irc_chantypes; ///< Channel types (name prefixes)
|
||||||
|
char *irc_idchan_prefixes; ///< Prefixes for "safe channels"
|
||||||
|
char *irc_statusmsg; ///< Prefixes for channel targets
|
||||||
|
|
||||||
|
char *irc_chanuser_prefixes; ///< Channel user prefixes
|
||||||
|
char *irc_chanuser_modes; ///< Channel user modes
|
||||||
|
|
||||||
// Events:
|
// Events:
|
||||||
|
|
||||||
struct poller_timer ping_tmr; ///< We should send a ping
|
struct poller_timer ping_tmr; ///< We should send a ping
|
||||||
@ -1068,9 +1079,16 @@ server_init (struct server *self, struct poller *poller)
|
|||||||
str_init (&self->read_buffer);
|
str_init (&self->read_buffer);
|
||||||
self->state = IRC_DISCONNECTED;
|
self->state = IRC_DISCONNECTED;
|
||||||
|
|
||||||
// RFC 1459 as per the RPL_ISUPPORT draft
|
// Defaults as per the RPL_ISUPPORT draft
|
||||||
self->irc_channel_prefixes = xstrdup ("@+");
|
self->irc_tolower = irc_tolower;
|
||||||
self->irc_channel_modes = xstrdup ("ov");
|
self->irc_strxfrm = irc_strxfrm;
|
||||||
|
|
||||||
|
self->irc_chantypes = xstrdup ("#&");
|
||||||
|
self->irc_idchan_prefixes = xstrdup ("");
|
||||||
|
self->irc_statusmsg = xstrdup ("");
|
||||||
|
|
||||||
|
self->irc_chanuser_prefixes = xstrdup ("@+");
|
||||||
|
self->irc_chanuser_modes = xstrdup ("ov");
|
||||||
|
|
||||||
str_map_init (&self->irc_users);
|
str_map_init (&self->irc_users);
|
||||||
self->irc_users.key_xfrm = irc_strxfrm;
|
self->irc_users.key_xfrm = irc_strxfrm;
|
||||||
@ -1119,8 +1137,12 @@ server_free (struct server *self)
|
|||||||
free (self->irc_user_mode);
|
free (self->irc_user_mode);
|
||||||
free (self->irc_user_host);
|
free (self->irc_user_host);
|
||||||
|
|
||||||
free (self->irc_channel_prefixes);
|
free (self->irc_chantypes);
|
||||||
free (self->irc_channel_modes);
|
free (self->irc_idchan_prefixes);
|
||||||
|
free (self->irc_statusmsg);
|
||||||
|
|
||||||
|
free (self->irc_chanuser_prefixes);
|
||||||
|
free (self->irc_chanuser_modes);
|
||||||
|
|
||||||
str_map_free (&self->irc_users);
|
str_map_free (&self->irc_users);
|
||||||
str_map_free (&self->irc_channels);
|
str_map_free (&self->irc_channels);
|
||||||
@ -3731,7 +3753,6 @@ irc_is_highlight (struct server *s, const char *message)
|
|||||||
// --- Input handling ----------------------------------------------------------
|
// --- Input handling ----------------------------------------------------------
|
||||||
|
|
||||||
// TODO: we will need a proper mode parser; to be shared with kike
|
// TODO: we will need a proper mode parser; to be shared with kike
|
||||||
// TODO: we alse definitely need to parse server capability messages
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
irc_handle_join (struct server *s, const struct irc_message *msg)
|
irc_handle_join (struct server *s, const struct irc_message *msg)
|
||||||
@ -4430,7 +4451,7 @@ irc_process_names (struct server *s, struct channel *channel)
|
|||||||
for (size_t i = 0; i < updates->len; i++)
|
for (size_t i = 0; i < updates->len; i++)
|
||||||
{
|
{
|
||||||
const char *item = updates->vector[i];
|
const char *item = updates->vector[i];
|
||||||
const char *nick = item + strspn (item, s->irc_channel_modes);
|
const char *nick = item + strspn (item, s->irc_chanuser_modes);
|
||||||
struct channel_user *channel_user = str_map_find (&map, nick);
|
struct channel_user *channel_user = str_map_find (&map, nick);
|
||||||
if (!channel_user)
|
if (!channel_user)
|
||||||
{
|
{
|
||||||
@ -4479,11 +4500,72 @@ irc_handle_isupport_prefix (struct server *s, char *value)
|
|||||||
if (*modes++ != '(' || !prefixes++ || strlen (value) != 2 * n_prefixes--)
|
if (*modes++ != '(' || !prefixes++ || strlen (value) != 2 * n_prefixes--)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
free (s->irc_channel_modes);
|
free (s->irc_chanuser_modes);
|
||||||
free (s->irc_channel_prefixes);
|
free (s->irc_chanuser_prefixes);
|
||||||
|
|
||||||
s->irc_channel_modes = xstrndup (modes, n_prefixes);
|
s->irc_chanuser_modes = xstrndup (modes, n_prefixes);
|
||||||
s->irc_channel_prefixes = xstrndup (prefixes, n_prefixes);
|
s->irc_chanuser_prefixes = xstrndup (prefixes, n_prefixes);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
irc_handle_isupport_casemapping (struct server *s, char *value)
|
||||||
|
{
|
||||||
|
// TODO: reinitialize hashtables with the new tolower() and strxfrm(),
|
||||||
|
// note that collisions may arise on reconnecting
|
||||||
|
|
||||||
|
if (!strcmp (value, "ascii"))
|
||||||
|
{
|
||||||
|
s->irc_tolower = tolower_ascii;
|
||||||
|
s->irc_strxfrm = tolower_ascii_strxfrm;
|
||||||
|
}
|
||||||
|
else if (!strcmp (value, "rfc1459"))
|
||||||
|
{
|
||||||
|
s->irc_tolower = irc_tolower;
|
||||||
|
s->irc_strxfrm = irc_strxfrm;
|
||||||
|
}
|
||||||
|
else if (!strcmp (value, "rfc1459-strict"))
|
||||||
|
{
|
||||||
|
// TODO: implement
|
||||||
|
s->irc_tolower = irc_tolower;
|
||||||
|
s->irc_strxfrm = irc_strxfrm;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
irc_handle_isupport_chantypes (struct server *s, char *value)
|
||||||
|
{
|
||||||
|
free (s->irc_chantypes);
|
||||||
|
s->irc_chantypes = xstrdup (value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
irc_handle_isupport_idchan (struct server *s, char *value)
|
||||||
|
{
|
||||||
|
struct str prefixes;
|
||||||
|
str_init (&prefixes);
|
||||||
|
|
||||||
|
struct str_vector v;
|
||||||
|
str_vector_init (&v);
|
||||||
|
split_str_ignore_empty (value, ',', &v);
|
||||||
|
for (size_t i = 0; i < v.len; i++)
|
||||||
|
{
|
||||||
|
// Not using or validating the numeric part
|
||||||
|
const char *pair = v.vector[i];
|
||||||
|
const char *colon = strchr (pair, ':');
|
||||||
|
if (colon)
|
||||||
|
str_append_data (&prefixes, pair, colon - pair);
|
||||||
|
}
|
||||||
|
str_vector_free (&v);
|
||||||
|
|
||||||
|
free (s->irc_idchan_prefixes);
|
||||||
|
s->irc_idchan_prefixes = str_steal (&prefixes);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
irc_handle_isupport_statusmsg (struct server *s, char *value)
|
||||||
|
{
|
||||||
|
free (s->irc_statusmsg);
|
||||||
|
s->irc_statusmsg = xstrdup (value);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -4522,14 +4604,22 @@ irc_handle_rpl_isupport (struct server *s, const struct irc_message *msg)
|
|||||||
str_init (&value_unescaped);
|
str_init (&value_unescaped);
|
||||||
unescape_isupport_value (value, &value_unescaped);
|
unescape_isupport_value (value, &value_unescaped);
|
||||||
|
|
||||||
if (!strcmp (param, "PREFIX"))
|
if (!strcmp (param, "PREFIX"))
|
||||||
irc_handle_isupport_prefix (s, value_unescaped.str);
|
irc_handle_isupport_prefix (s, value_unescaped.str);
|
||||||
|
else if (!strcmp (param, "CASEMAPPING"))
|
||||||
|
irc_handle_isupport_casemapping (s, value_unescaped.str);
|
||||||
|
else if (!strcmp (param, "CHANTYPES"))
|
||||||
|
irc_handle_isupport_chantypes (s, value_unescaped.str);
|
||||||
|
else if (!strcmp (param, "IDCHAN"))
|
||||||
|
irc_handle_isupport_idchan (s, value_unescaped.str);
|
||||||
|
else if (!strcmp (param, "STATUSMSG"))
|
||||||
|
irc_handle_isupport_statusmsg (s, value_unescaped.str);
|
||||||
|
|
||||||
|
// TODO: also parse MODES, TARGMAX, CHANMODES and make use of them
|
||||||
|
// to split client commands as necessary
|
||||||
|
|
||||||
str_free (&value_unescaped);
|
str_free (&value_unescaped);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: initialize key_strxfrm according to server properties;
|
|
||||||
// note that collisions may arise on reconnecting
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
Loading…
Reference in New Issue
Block a user