#include "module.h" #define AUTHOR "SGR" #define VERSION "1.04" /* ----------------------------------------------------------- * Name: cs_inhabitforbidden * Author: SGR * Date: 31/01/2004 * ----------------------------------------------------------- * Functions: m_cs_checkshouldjoin, m_cs_joinandlock * Limitations: None Known. * Tested: Ultimate(2.8.x), Unreal(3.2), Viagra. * ----------------------------------------------------------- * This module has 2 configurable options. * * This module will cause ChanServ to 'join and lock' any * forbidden or suspended channels. The TOPIC of these * locked channels will include the reason and user who * forbid the channel in the 1st place. * * Please note, from the instant you load this module to the * time you unload it; ChanServ will be in ALL forbidden * and suspended channels. * ----------------------------------------------------------- * Change Log: * * 1: Works. * * 2: Added re-join on kick + optional don't use mode +s * config option. * 2: Fixed a typo in a logging line. * * 3: Added code to 'auto re-lock' channels that are FORBIDDEN * or SUSPENDED as and when users JOIN or SJOIN them. * (i.e. In case of netsplits and so on) * * 4: Removed un-needed set of sstrdup() and free() calls. * * 5: Added Anope-1.7.x update. * * ----------------------------------------------------------- */ /* ---------------------------------------------------------------------- */ /* START OF CONFIGURATION BLOCK - please read the comments :) */ /* ---------------------------------------------------------------------- */ /* Define this to NOT have FORBIDDEN and SUSPENDED channels applied with * mode +s. This will allow all users to see who forbid the channel and * the forbid reason that was provided. * (To define this, remove the // from the beginning of the line) */ //#define DONT_SET_MODE_s /* [REQUIRED] If you are using Anope-1.7.x or later, leave this alone. * Otherwise change it to '#undef ANOPE17x' (no quotes). * * THIS IS IMPORTANT * */ #define ANOPE17x /* ---------------------------------------------------------------------- */ /* DO NOT EDIT BELOW THIS LINE UNLESS YOU KNOW WHAT YOU ARE DOING */ /* ---------------------------------------------------------------------- */ int myKickCheckFORBIDSUSPEND(char *source, int ac, char **av); int m_cs_checkshouldjoin(User *u); int m_cs_checkshouldpart(User *u); void m_cs_joinandlock(ChannelInfo *ci); int on_join_forbid_suspend_relock(char *source, int ac, char **av); #if defined(IRC_BAHAMUT) || defined(IRC_HYBRID) || defined(IRC_PTLINK) int on_sjoin_forbid_suspend_relock(char *source, int ac, char **av); #endif int AnopeInit(int argc, char **argv) { int i; ChannelInfo *ci; Command *c; Message *msg = NULL; alog("Loading module cs_inhabitforbidden.so"); alog("[cs_inhabitforbidden] Joining %s to Forbidden / Suspended channels.", s_ChanServ); for (i = 0; i < 256; i++) { for (ci = chanlists[i]; ci; ci = ci->next) { if ((ci->name[0] == '#')) { if ((ci->flags & CI_VERBOTEN) || (ci->flags & CI_SUSPENDED)) { m_cs_joinandlock(ci); } } } } c = createCommand("FORBID", m_cs_checkshouldjoin, NULL,-1,-1,-1,-1,-1); moduleAddCommand(CHANSERV, c, MOD_TAIL); c = createCommand("SUSPEND", m_cs_checkshouldjoin, NULL,-1,-1,-1,-1,-1); moduleAddCommand(CHANSERV, c, MOD_TAIL); c= createCommand("DROP", m_cs_checkshouldpart, NULL,-1,-1,-1,-1,-1); moduleAddCommand(CHANSERV, c, MOD_TAIL); c = createCommand("UNSUSPEND", m_cs_checkshouldpart, NULL,-1,-1,-1,-1,-1); moduleAddCommand(CHANSERV, c, MOD_TAIL); msg = createMessage("KICK",myKickCheckFORBIDSUSPEND); moduleAddMessage(msg,MOD_TAIL); msg = createMessage("JOIN",on_join_forbid_suspend_relock); moduleAddMessage(msg,MOD_TAIL); #if defined(IRC_BAHAMUT) || defined(IRC_HYBRID) || defined(IRC_PTLINK) msg = createMessage("SJOIN",on_sjoin_forbid_suspend_relock); moduleAddMessage(msg,MOD_TAIL); #endif alog("[cs_inhabitforbidden] %s will now join and 'lock' all FOBIDDEN and", s_ChanServ); alog("[cs_inhabitforbidden] suspended channels."); alog("[cs_inhabitforbidden] Yayness!(tm) - MODULE LOADED AND ACTIVE"); moduleAddAuthor(AUTHOR); moduleAddVersion(VERSION); return MOD_CONT; } void AnopeFini(void) { int i; ChannelInfo *ci; alog("Having %s part all FORBIDDEN and SUSPENDED channels.", s_ChanServ); for (i = 0; i < 256; i++) { for (ci = chanlists[i]; ci; ci = ci->next) { if ((ci->flags & CI_VERBOTEN) || (ci->flags & CI_SUSPENDED)) { send_cmd(s_ChanServ, "PART %s", ci->name); } } } alog("Unloading module cs_inhabitforbidden.so"); } int m_cs_checkshouldjoin(User *u) { ChannelInfo *ci; char *temp = moduleGetLastBuffer(); char *chan = strtok(temp, " "); if (!chan) { return MOD_CONT; } if ((ci = cs_findchan(chan)) && (ci->name[0] == '#') && ((ci->flags & CI_VERBOTEN) || (ci->flags & CI_SUSPENDED))) { m_cs_joinandlock(ci); } return MOD_CONT; } int m_cs_checkshouldpart(User *u) { ChannelInfo *ci; char *temp = moduleGetLastBuffer(); char *chan = strtok(temp, " "); if (!chan) { return MOD_CONT; } if ((ci = cs_findchan(chan))) { if (((ci->flags & CI_VERBOTEN) || (ci->flags & CI_SUSPENDED))) { return MOD_CONT; } } #ifdef ANOPE17x anope_cmd_part(s_ChanServ, temp, NULL); if (ci && ci->c) { restore_topic(ci->name); check_modes(ci->c); } #else send_cmd(s_ChanServ, "PART %s", temp); #endif return MOD_CONT; } void m_cs_joinandlock(ChannelInfo *ci) { #ifdef ANOPE17x char temp[512]; anope_cmd_join(s_ChanServ, ci->name, time(NULL)); anope_cmd_mode(s_ChanServ, ci->name, "+o %s", s_ChanServ); #ifdef DONT_SET_MODE_s anope_cmd_mode(s_ChanServ, ci->name, "+ntim"); #else anope_cmd_mode(s_ChanServ, ci->name, "+ntims"); #endif snprintf(temp, 512, "This channel has been FORBIDDEN or SUSPENDED. [By: %s] [Reason: %s]", ci->forbidby, (ci->forbidreason ? ci->forbidreason : "None.")); anope_cmd_topic(s_ChanServ, ci->name, s_ChanServ, temp, time(NULL)); return; #endif #if defined(IRC_BAHAMUT) send_cmd(s_ChanServ, "SJOIN %lu %s", time(NULL), ci->name); #elif defined(IRC_HYBRID) send_cmd(NULL, "SJOIN %ld %s + :@%s", time(NULL), ci->name, s_ChanServ); #else send_cmd(s_ChanServ, "JOIN %s", ci->name); #endif send_cmd(s_ChanServ, "MODE %s +o %s %lu", ci->name, s_ChanServ, time(NULL)); #ifndef DONT_SET_MODE_s send_cmd(s_ChanServ, "MODE %s +ntisml 1 %lu", ci->name, time(NULL)); #else send_cmd(s_ChanServ, "MODE %s +ntiml 1 %lu", ci->name, time(NULL)); #endif send_cmd(s_ChanServ, "TOPIC %s :This channel has been FORBIDDEN or SUSPENDED. [By: %s] [Reason: %s]", ci->name, ci->forbidby, (ci->forbidreason ? ci->forbidreason : "None.")); return; } int myKickCheckFORBIDSUSPEND(char *source, int ac, char **av) { ChannelInfo *ci; if ((!*source) || (ac < 1) || (readonly) || (!av[0]) || (!av[1])) { return MOD_CONT; } if ((stricmp(av[1],s_ChanServ) !=0) || (!(ci = cs_findchan(av[0])))) { return MOD_CONT; } if (!((ci->flags & CI_VERBOTEN) || (ci->flags & CI_SUSPENDED))) { return MOD_CONT; } alog("[cs_inhabitforbidden]: %s got kicked from FORBIDDED/SUSPENDED channel %s (Re-Joining)", s_ChanServ, ci->name); m_cs_joinandlock(ci); return MOD_STOP; } int on_join_forbid_suspend_relock(char *source, int ac, char **av) { char *s; char *t; ChannelInfo *ci; t = av[0]; while (*(s = t)) { t = s + strcspn(s, ","); if (*t) { *t++ = 0; } ci = cs_findchan(s); if (ci) { if ((ci->flags & CI_VERBOTEN) || (ci->flags & CI_SUSPENDED)) { m_cs_joinandlock(ci); } } } return MOD_CONT; } #if defined(IRC_BAHAMUT) || defined(IRC_HYBRID) || defined(IRC_PTLINK) int on_sjoin_forbid_suspend_relock(char *source, int ac, char **av) { ChannelInfo *ci; if (ac > 1) { ci = cs_findchan(av[1]); if (ci) { if ((ci->flags & CI_VERBOTEN) || (ci->flags & CI_SUSPENDED)) { m_cs_joinandlock(ci); } } } return MOD_CONT; } #endif