diff --git a/NEWS b/NEWS index 614c600..43e0363 100644 --- a/NEWS +++ b/NEWS @@ -15,6 +15,8 @@ * degesch: made "/help /command" work the same way as "/help command" does + * degesch: /ban and /unban don't mangle extended bans anymore + * censor.lua: now stripping colours from censored messages; their attributes are also configurable rather than always black on black 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 @@ -7926,6 +7948,16 @@ irc_handle_isupport_statusmsg (struct server *s, char *value) cstr_set (&s->irc_statusmsg, xstrdup (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) { @@ -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);