summaryrefslogtreecommitdiff
path: root/degesch.c
diff options
context:
space:
mode:
Diffstat (limited to 'degesch.c')
-rw-r--r--degesch.c38
1 files changed, 34 insertions, 4 deletions
diff --git a/degesch.c b/degesch.c
index f556241..fb3cee3 100644
--- a/degesch.c
+++ b/degesch.c
@@ -1733,6 +1733,9 @@ struct server
char *irc_idchan_prefixes; ///< Prefixes for "safe channels"
char *irc_statusmsg; ///< Prefixes for channel targets
+ char irc_extban_prefix; ///< EXTBAN prefix or \0
+ char *irc_extban_types; ///< EXTBAN types
+
char *irc_chanmodes_list; ///< Channel modes for lists
char *irc_chanmodes_param_always; ///< Channel modes with mandatory param
char *irc_chanmodes_param_when_set; ///< Channel modes with param when set
@@ -1781,6 +1784,9 @@ server_init_specifics (struct server *self)
self->irc_idchan_prefixes = xstrdup ("");
self->irc_statusmsg = xstrdup ("");
+ self->irc_extban_prefix = 0;
+ self->irc_extban_types = xstrdup ("");
+
self->irc_chanmodes_list = xstrdup ("b");
self->irc_chanmodes_param_always = xstrdup ("k");
self->irc_chanmodes_param_when_set = xstrdup ("l");
@@ -1799,6 +1805,8 @@ server_free_specifics (struct server *self)
free (self->irc_idchan_prefixes);
free (self->irc_statusmsg);
+ free (self->irc_extban_types);
+
free (self->irc_chanmodes_list);
free (self->irc_chanmodes_param_always);
free (self->irc_chanmodes_param_when_set);
@@ -3039,6 +3047,20 @@ irc_skip_statusmsg (struct server *s, const char *target)
return target + (*target && strchr (s->irc_statusmsg, *target));
}
+static bool
+irc_is_extban (struct server *s, const char *target)
+{
+ // Some servers have a prefix, and some support negation
+ if (s->irc_extban_prefix && *target++ != s->irc_extban_prefix)
+ return false;
+ if (*target == '~')
+ target++;
+
+ // XXX: we don't know if it's supposed to have an argument, or not
+ return *target && strchr (s->irc_extban_types, *target++)
+ && strchr (":\0", *target);
+}
+
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// As of 2020, everything should be in UTF-8. And if it's not, we'll decode it
@@ -7927,6 +7949,16 @@ irc_handle_isupport_statusmsg (struct server *s, char *value)
}
static void
+irc_handle_isupport_extban (struct server *s, char *value)
+{
+ s->irc_extban_prefix = 0;
+ if (*value && *value != ',')
+ s->irc_extban_prefix = *value++;
+
+ cstr_set (&s->irc_extban_types, xstrdup (*value == ',' ? ++value : ""));
+}
+
+static void
irc_handle_isupport_chanmodes (struct server *s, char *value)
{
struct strv v = strv_make ();
@@ -7982,6 +8014,7 @@ dispatch_isupport (struct server *s, const char *name, char *value)
MATCH ("CHANTYPES", irc_handle_isupport_chantypes);
MATCH ("IDCHAN", irc_handle_isupport_idchan);
MATCH ("STATUSMSG", irc_handle_isupport_statusmsg);
+ MATCH ("EXTBAN", irc_handle_isupport_extban);
MATCH ("CHANMODES", irc_handle_isupport_chanmodes);
MATCH ("MODES", irc_handle_isupport_modes);
@@ -11646,10 +11679,7 @@ mass_channel_mode_mask_list
for (size_t i = 0; i < v.len; i++)
{
char *target = v.vector[i];
- // TODO: support EXTBAN=<[PREFIX],TYPES> and leave those alone, too.
- // The type may be prefixed by ~, and must be followed by \0 or ':'.
- // Make a function like irc_is_extban().
- if (strpbrk (target, "!@*?"))
+ if (strpbrk (target, "!@*?") || irc_is_extban (a->s, target))
continue;
v.vector[i] = xstrdup_printf ("%s!*@*", target);