unrealircd

- supernets unrealircd source & configuration
git clone git://git.acid.vegas/unrealircd.git
Log | Files | Refs | Archive | README | LICENSE

moderated.c (3661B)

      1 /*
      2  * Channel Mode +m
      3  * (C) Copyright 2021 Syzop and the UnrealIRCd team
      4  *
      5  * This program is free software; you can redistribute it and/or modify
      6  * it under the terms of the GNU General Public License as published by
      7  * the Free Software Foundation; either version 1, or (at your option)
      8  * any later version.
      9  *
     10  * This program is distributed in the hope that it will be useful,
     11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13  * GNU General Public License for more details.
     14  *
     15  * You should have received a copy of the GNU General Public License
     16  * along with this program; if not, write to the Free Software
     17  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
     18  */
     19 
     20 #include "unrealircd.h"
     21 
     22 
     23 ModuleHeader MOD_HEADER
     24   = {
     25 	"chanmodes/moderated",
     26 	"6.0",
     27 	"Channel Mode +m",
     28 	"UnrealIRCd Team",
     29 	"unrealircd-6",
     30     };
     31 
     32 /* Global variables */
     33 Cmode_t EXTCMODE_MODERATED;
     34 
     35 /* Forward declarations */
     36 int moderated_can_send_to_channel(Client *client, Channel *channel, Membership *lp, const char **msg, const char **errmsg, SendType sendtype);
     37 const char *moderated_pre_local_part(Client *client, Channel *channel, const char *text);
     38 int moderated_can_set_topic(Client *client, Channel *channel, const char *topic, const char **errmsg);
     39 
     40 /* Macros */
     41 #define IsModerated(channel)    (channel->mode.mode & EXTCMODE_MODERATED)
     42 
     43 MOD_INIT()
     44 {
     45 	CmodeInfo req;
     46 
     47 	MARK_AS_OFFICIAL_MODULE(modinfo);
     48 
     49 	memset(&req, 0, sizeof(req));
     50 	req.paracount = 0;
     51 	req.letter = 'm';
     52 	req.is_ok = extcmode_default_requirehalfop;
     53 	CmodeAdd(modinfo->handle, req, &EXTCMODE_MODERATED);
     54 
     55 	HookAdd(modinfo->handle, HOOKTYPE_CAN_SEND_TO_CHANNEL, 0, moderated_can_send_to_channel);
     56 	HookAddConstString(modinfo->handle, HOOKTYPE_PRE_LOCAL_PART, 0, moderated_pre_local_part);
     57 	HookAdd(modinfo->handle, HOOKTYPE_CAN_SET_TOPIC, 0, moderated_can_set_topic);
     58 
     59 	return MOD_SUCCESS;
     60 }
     61 
     62 MOD_LOAD()
     63 {
     64 	return MOD_SUCCESS;
     65 }
     66 
     67 MOD_UNLOAD()
     68 {
     69 	return MOD_SUCCESS;
     70 }
     71 
     72 int moderated_can_send_to_channel(Client *client, Channel *channel, Membership *m, const char **msg, const char **errmsg, SendType sendtype)
     73 {
     74 	if (IsModerated(channel) && (!m || !check_channel_access_membership(m, "vhoaq")) &&
     75 	    !op_can_override("channel:override:message:moderated",client,channel,NULL))
     76 	{
     77 		Hook *h;
     78 		for (h = Hooks[HOOKTYPE_CAN_BYPASS_CHANNEL_MESSAGE_RESTRICTION]; h; h = h->next)
     79 		{
     80 			int i = (*(h->func.intfunc))(client, channel, BYPASS_CHANMSG_MODERATED);
     81 			if (i == HOOK_ALLOW)
     82 				return HOOK_CONTINUE; /* bypass +m restriction */
     83 			if (i != HOOK_CONTINUE)
     84 				break;
     85 		}
     86 
     87 		*errmsg = "You need voice (+v)";
     88 		return HOOK_DENY; /* BLOCK message */
     89 	}
     90 
     91 	return HOOK_CONTINUE;
     92 }
     93 
     94 /** Remove PART reason too if the channel is +m, -t, and user not +vhoaq */
     95 const char *moderated_pre_local_part(Client *client, Channel *channel, const char *text)
     96 {
     97 	if (IsModerated(channel) && !check_channel_access(client, channel, "v") && !check_channel_access(client, channel, "h"))
     98 		return NULL;
     99 	return text;
    100 }
    101 
    102 int moderated_can_set_topic(Client *client, Channel *channel, const char *topic, const char **errmsg)
    103 {
    104 	static char errmsg_buf[NICKLEN+256];
    105 
    106 	/* Channel is +m but user is not +vhoaq: reject the topic change */
    107 	if (has_channel_mode(channel, 'm') && !check_channel_access(client, channel, "vhoaq"))
    108 	{
    109 		char buf[512];
    110 		snprintf(buf, sizeof(buf), "Voice (+v) or higher is required in order to change the topic on %s (channel is +m)", channel->name);
    111 		buildnumeric(errmsg_buf, sizeof(errmsg_buf), client, ERR_CANNOTDOCOMMAND, "TOPIC", buf);
    112 		*errmsg = errmsg_buf;
    113 		return EX_DENY;
    114 	}
    115 
    116 	return EX_ALLOW;
    117 }