From 6dd539d760a52b263c9e1933d7f60148c693c960 Mon Sep 17 00:00:00 2001 From: Bram Matthys Date: Sun, 22 Aug 2021 12:01:54 +0200 Subject: [PATCH] Move channel mode +m to module chanmodes/moderated (and nearly all the code related to it) --- doc/conf/modules.default.conf | 1 + include/struct.h | 1 - src/channel.c | 1 - src/modules/chanmodes/Makefile.in | 6 +- src/modules/chanmodes/moderated.c | 95 +++++++++++++++++++++++++++++++ src/modules/message.c | 20 ------- src/modules/mode.c | 1 - src/modules/part.c | 6 -- src/modules/topic.c | 7 ++- 9 files changed, 106 insertions(+), 32 deletions(-) create mode 100644 src/modules/chanmodes/moderated.c diff --git a/doc/conf/modules.default.conf b/doc/conf/modules.default.conf index f3ec7b528..071e6dd65 100644 --- a/doc/conf/modules.default.conf +++ b/doc/conf/modules.default.conf @@ -149,6 +149,7 @@ loadmodule "chanmodes/limit"; /* +l */ loadmodule "chanmodes/inviteonly"; /* +i */ loadmodule "chanmodes/secret"; /* +s */ loadmodule "chanmodes/private"; /* +p */ +loadmodule "chanmodes/moderated"; /* +m */ loadmodule "chanmodes/noexternalmsgs"; /* +n */ loadmodule "chanmodes/floodprot"; /* +f */ loadmodule "chanmodes/nocolor"; /* +c */ diff --git a/include/struct.h b/include/struct.h index b418ec780..eef996071 100644 --- a/include/struct.h +++ b/include/struct.h @@ -2112,7 +2112,6 @@ struct Ban { /* Don't blindly change these MODE_* values, see comment 20 lines up! */ #define MODE_CHANOP CHFL_CHANOP #define MODE_VOICE CHFL_VOICE -#define MODE_MODERATED 0x0010 #define MODE_TOPICLIMIT 0x0020 #define MODE_CHANOWNER 0x0040 #define MODE_CHANADMIN 0x0080 diff --git a/src/channel.c b/src/channel.c index 68f93a231..afe5482e7 100644 --- a/src/channel.c +++ b/src/channel.c @@ -56,7 +56,6 @@ CoreChannelModeTable corechannelmodetable[] = { {MODE_VOICE, 'v', 1, 1}, {MODE_HALFOP, 'h', 0, 1}, {MODE_CHANOP, 'o', 0, 1}, - {MODE_MODERATED, 'm', 1, 0}, {MODE_TOPICLIMIT, 't', 1, 0}, {MODE_RGSTR, 'r', 0, 0}, {MODE_CHANADMIN, 'a', 0, 1}, diff --git a/src/modules/chanmodes/Makefile.in b/src/modules/chanmodes/Makefile.in index 66e500f1c..fb48b4dc9 100644 --- a/src/modules/chanmodes/Makefile.in +++ b/src/modules/chanmodes/Makefile.in @@ -33,7 +33,7 @@ INCLUDES = ../../include/channel.h \ R_MODULES= \ key.so limit.so inviteonly.so secret.so private.so \ - noexternalmsgs.so \ + moderated.so noexternalmsgs.so \ nocolor.so stripcolor.so issecure.so permanent.so floodprot.so \ noctcp.so link.so censor.so delayjoin.so noknock.so noinvite.so operonly.so \ nonotice.so regonly.so nonickchange.so nokick.so regonlyspeak.so \ @@ -78,6 +78,10 @@ noexternalmsgs.so: noexternalmsgs.c $(INCLUDES) $(CC) $(CFLAGS) $(MODULEFLAGS) -DDYNAMIC_LINKING \ -o noexternalmsgs.so noexternalmsgs.c +moderated.so: moderated.c $(INCLUDES) + $(CC) $(CFLAGS) $(MODULEFLAGS) -DDYNAMIC_LINKING \ + -o moderated.so moderated.c + issecure.so: issecure.c $(INCLUDES) $(CC) $(CFLAGS) $(MODULEFLAGS) -DDYNAMIC_LINKING \ -o issecure.so issecure.c diff --git a/src/modules/chanmodes/moderated.c b/src/modules/chanmodes/moderated.c new file mode 100644 index 000000000..4bc410983 --- /dev/null +++ b/src/modules/chanmodes/moderated.c @@ -0,0 +1,95 @@ +/* + * Channel Mode +m + * (C) Copyright 2021 Syzop and the UnrealIRCd team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 1, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "unrealircd.h" + + +ModuleHeader MOD_HEADER + = { + "chanmodes/moderated", + "6.0", + "Channel Mode +m", + "UnrealIRCd Team", + "unrealircd-6", + }; + +Cmode_t EXTCMODE_MODERATED; + +#define IsModerated(channel) (channel->mode.extmode & EXTCMODE_MODERATED) + +int moderated_can_send_to_channel(Client *client, Channel *channel, Membership *lp, char **msg, char **errmsg, SendType sendtype); +char *moderated_pre_local_part(Client *client, Channel *channel, char *text); + +MOD_INIT() +{ + CmodeInfo req; + + MARK_AS_OFFICIAL_MODULE(modinfo); + + memset(&req, 0, sizeof(req)); + req.paracount = 0; + req.flag = 'm'; + req.is_ok = extcmode_default_requirehalfop; + CmodeAdd(modinfo->handle, req, &EXTCMODE_MODERATED); + + HookAdd(modinfo->handle, HOOKTYPE_CAN_SEND_TO_CHANNEL, 0, moderated_can_send_to_channel); + HookAddPChar(modinfo->handle, HOOKTYPE_PRE_LOCAL_PART, 0, moderated_pre_local_part); + + return MOD_SUCCESS; +} + +MOD_LOAD() +{ + return MOD_SUCCESS; +} + +MOD_UNLOAD() +{ + return MOD_SUCCESS; +} + +int moderated_can_send_to_channel(Client *client, Channel *channel, Membership *lp, char **msg, char **errmsg, SendType sendtype) +{ + if (IsModerated(channel) && (!lp || !(lp->flags & CHFL_OVERLAP)) && + !op_can_override("channel:override:message:moderated",client,channel,NULL)) + { + Hook *h; + for (h = Hooks[HOOKTYPE_CAN_BYPASS_CHANNEL_MESSAGE_RESTRICTION]; h; h = h->next) + { + int i = (*(h->func.intfunc))(client, channel, BYPASS_CHANMSG_MODERATED); + if (i == HOOK_ALLOW) + return HOOK_CONTINUE; /* bypass +m restriction */ + if (i != HOOK_CONTINUE) + break; + } + + *errmsg = "You need voice (+v)"; + return HOOK_DENY; /* BLOCK message */ + } + + return HOOK_CONTINUE; +} + +/** Remove PART reason too if the channel is +m, -t, and user not +vhoaq */ +char *moderated_pre_local_part(Client *client, Channel *channel, char *text) +{ + if (IsModerated(channel) && !has_voice(client, channel) && !is_half_op(client, channel)) + return NULL; + return text; +} diff --git a/src/modules/message.c b/src/modules/message.c index 03c84f882..cc6d66dd1 100644 --- a/src/modules/message.c +++ b/src/modules/message.c @@ -796,26 +796,6 @@ int _can_send_to_channel(Client *client, Channel *channel, char **msgtext, char member = IsMember(client, channel); lp = find_membership_link(client->user->channel, channel); - if (channel->mode.mode & MODE_MODERATED && - !op_can_override("channel:override:message:moderated",client,channel,NULL) && - (!lp /* FIXME: UGLY */ - || !(lp->flags & (CHFL_CHANOP | CHFL_VOICE | CHFL_CHANOWNER | CHFL_HALFOP | CHFL_CHANADMIN)))) - { - /* Channel is moderated (+m). - * Reject, unless HOOKTYPE_CAN_BYPASS_MODERATED tells otherwise. - */ - for (h = Hooks[HOOKTYPE_CAN_BYPASS_CHANNEL_MESSAGE_RESTRICTION]; h; h = h->next) - { - i = (*(h->func.intfunc))(client, channel, BYPASS_CHANMSG_MODERATED); - if (i != HOOK_CONTINUE) - break; - } - if (i != HOOK_ALLOW) - { - *errmsg = "You need voice (+v)"; - return 0; - } - } /* Modules can plug in as well */ for (h = Hooks[HOOKTYPE_CAN_SEND_TO_CHANNEL]; h; h = h->next) diff --git a/src/modules/mode.c b/src/modules/mode.c index 55a095f3b..56da99f35 100644 --- a/src/modules/mode.c +++ b/src/modules/mode.c @@ -785,7 +785,6 @@ int do_mode_char(Channel *channel, long modetype, char modechar, char *param, break; } goto setmode; - case MODE_MODERATED: case MODE_TOPICLIMIT: goto setmode; setmode: diff --git a/src/modules/part.c b/src/modules/part.c index fa42b7a3b..bba22feb7 100644 --- a/src/modules/part.c +++ b/src/modules/part.c @@ -136,12 +136,6 @@ CMD_FUNC(cmd_part) comment = NULL; if (comment && is_banned(client, channel, BANCHK_LEAVE_MSG, &comment, NULL)) comment = NULL; - /* Same for +m */ - if ((channel->mode.mode & MODE_MODERATED) && comment && - !has_voice(client, channel) && !is_half_op(client, channel)) - { - comment = NULL; - } } if (MyConnect(client)) diff --git a/src/modules/topic.c b/src/modules/topic.c index a3a270ba4..ce2fd08fa 100644 --- a/src/modules/topic.c +++ b/src/modules/topic.c @@ -216,8 +216,11 @@ CMD_FUNC(cmd_topic) if (MyUser(client) && newtopic) topic = newtopic; /* process is_banned() changes of topic (eg: text replacement), but only for local clients */ - /* -t, +m, and not +vhoaq */ - if (((flags&CHFL_OVERLAP) == 0) && (channel->mode.mode & MODE_MODERATED)) + /* -t, +m, and not +vhoaq + * TODO: it's not really sane to have this here, we could use HOOKTYPE_PRE_LOCAL_TOPIC, + * but then we have the override shit too, hmmm. + */ + if (((flags&CHFL_OVERLAP) == 0) && has_channel_mode(channel, 'm')) { char buf[512];