* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
- * InspIRCd: (C) 2002-2008 InspIRCd Development Team
- * See: http://www.inspircd.org/wiki/index.php/Credits
+ * InspIRCd: (C) 2002-2009 InspIRCd Development Team
+ * See: http://wiki.inspircd.org/Credits
*
* This program is free but copyrighted software; see
* the file COPYING for details.
#include "u_listmode.h"
/* $ModDesc: Allows an extended ban (+b) syntax redirecting banned users to another channel */
+/* $ModDep: ../../include/u_listmode.h */
-/* Originally written by Om, January 2008
+/* Originally written by Om, January 2009
*/
class BanRedirectEntry : public classbase
class BanRedirect : public ModeWatcher
{
- private:
- InspIRCd* Srv;
public:
BanRedirect(InspIRCd* Instance)
- : ModeWatcher(Instance, 'b', MODETYPE_CHANNEL), Srv(Instance)
+ : ModeWatcher(Instance, 'b', MODETYPE_CHANNEL)
{
}
if(mask[CHAN].length())
{
- if(!IS_LOCAL(source) || Srv->IsChannel(mask[CHAN].c_str(), ServerInstance->Config->Limits.ChanMax))
+ if (IS_LOCAL(source))
{
+ if (!ServerInstance->IsChannel(mask[CHAN].c_str(), ServerInstance->Config->Limits.ChanMax))
+ {
+ source->WriteNumeric(403, "%s %s :Invalid channel name in redirection (%s)", source->nick.c_str(), channel->name.c_str(), mask[CHAN].c_str());
+ return false;
+ }
+
+ Channel *c = ServerInstance->FindChan(mask[CHAN].c_str());
+ if (!c)
+ {
+ source->WriteNumeric(690, "%s :Target channel %s must exist to be set as a redirect.",source->nick.c_str(),mask[CHAN].c_str());
+ return false;
+ }
+ else if (c->GetStatus(source) < STATUS_OP)
+ {
+ source->WriteNumeric(690, "%s :You must be opped on %s to set it as a redirect.",source->nick.c_str(), mask[CHAN].c_str());
+ return false;
+ }
+
if (assign(channel->name) == mask[CHAN])
{
source->WriteNumeric(690, "%s %s :You cannot set a ban redirection to the channel the ban is on", source->nick.c_str(), channel->name.c_str());
return false;
}
- else
+ }
+
+ if(adding)
+ {
+ /* It's a properly valid redirecting ban, and we're adding it */
+ if(!channel->GetExt("banredirects", redirects))
{
- if(adding)
- {
- /* It's a properly valid redirecting ban, and we're adding it */
- if(!channel->GetExt("banredirects", redirects))
- {
- redirects = new BanRedirectList;
- channel->Extend("banredirects", redirects);
- }
+ redirects = new BanRedirectList;
+ channel->Extend("banredirects", redirects);
+ }
- /* Here 'param' doesn't have the channel on it yet */
- redirects->push_back(BanRedirectEntry(mask[CHAN].c_str(), param.c_str()));
+ /* Here 'param' doesn't have the channel on it yet */
+ redirects->push_back(BanRedirectEntry(mask[CHAN].c_str(), param.c_str()));
- /* Now it does */
- param.append(mask[CHAN]);
- }
- else
+ /* Now it does */
+ param.append(mask[CHAN]);
+ }
+ else
+ {
+ /* Removing a ban, if there's no extensible there are no redirecting bans and we're fine. */
+ if(channel->GetExt("banredirects", redirects))
+ {
+ /* But there were, so we need to remove the matching one if there is one */
+
+ for(BanRedirectList::iterator redir = redirects->begin(); redir != redirects->end(); redir++)
{
- /* Removing a ban, if there's no extensible there are no redirecting bans and we're fine. */
- if(channel->GetExt("banredirects", redirects))
+ /* Ugly as fuck */
+ if((irc::string(redir->targetchan.c_str()) == irc::string(mask[CHAN].c_str())) && (irc::string(redir->banmask.c_str()) == irc::string(param.c_str())))
{
- /* But there were, so we need to remove the matching one if there is one */
+ redirects->erase(redir);
- for(BanRedirectList::iterator redir = redirects->begin(); redir != redirects->end(); redir++)
+ if(redirects->empty())
{
- /* Ugly as fuck */
- if((irc::string(redir->targetchan.c_str()) == irc::string(mask[CHAN].c_str())) && (irc::string(redir->banmask.c_str()) == irc::string(param.c_str())))
- {
- redirects->erase(redir);
-
- if(redirects->empty())
- {
- delete redirects;
- channel->Shrink("banredirects");
- }
-
- break;
- }
+ delete redirects;
+ channel->Shrink("banredirects");
}
- }
- /* Append the channel so the default +b handler can remove the entry too */
- param.append(mask[CHAN]);
+ break;
+ }
}
}
- }
- else
- {
- source->WriteNumeric(403, "%s %s :Invalid channel name in redirection (%s)", source->nick.c_str(), channel->name.c_str(), mask[CHAN].c_str());
- return false;
+
+ /* Append the channel so the default +b handler can remove the entry too */
+ param.append(mask[CHAN]);
}
}
}
class ModuleBanRedirect : public Module
{
- BanRedirect* re;
+ BanRedirect re;
bool nofollow;
Module* ExceptionModule;
public:
ModuleBanRedirect(InspIRCd* Me)
- : Module(Me)
+ : Module(Me), re(Me)
{
- re = new BanRedirect(Me);
nofollow = false;
- if(!ServerInstance->Modes->AddModeWatcher(re))
- {
- delete re;
+ if(!ServerInstance->Modes->AddModeWatcher(&re))
throw ModuleException("Could not add mode watcher");
- }
- OnRehash(NULL, "");
+ OnRehash(NULL);
Implementation list[] = { I_OnRehash, I_OnUserPreJoin, I_OnChannelDelete, I_OnCleanup };
Me->Modules->Attach(list, this, 4);
while(modestack.GetStackedLine(stackresult))
{
- for(StringDeque::size_type i = 0; i < stackresult.size(); i++)
- {
- mode_junk.push_back(stackresult[i]);
- }
-
+ mode_junk.insert(mode_junk.end(), stackresult.begin(), stackresult.end());
ServerInstance->SendMode(mode_junk, ServerInstance->FakeClient);
+ mode_junk.erase(mode_junk.begin() + 1, mode_junk.end());
}
delete redirects;
}
}
- virtual void OnRehash(User* user, const std::string ¶m)
+ virtual void OnRehash(User* user)
{
ExceptionModule = ServerInstance->Modules->Find("m_banexception.so");
}
else
{
user->WriteNumeric(474, "%s %s :Cannot join channel (You are banned)", user->nick.c_str(), chan->name.c_str());
- user->WriteNumeric(470, "%s :You are being automatically redirected to %s", user->nick.c_str(), redir->targetchan.c_str());
+ user->WriteNumeric(470, "%s %s %s :You are banned from this channel, so you are automatically transfered to the redirected channel.", user->nick.c_str(), chan->name.c_str(), redir->targetchan.c_str());
nofollow = true;
Channel::JoinUser(ServerInstance, user, redir->targetchan.c_str(), false, "", false, ServerInstance->Time());
nofollow = false;
virtual ~ModuleBanRedirect()
{
- ServerInstance->Modes->DelModeWatcher(re);
- delete re;
+ ServerInstance->Modes->DelModeWatcher(&re);
}
virtual Version GetVersion()
{
- return Version("$Id$", VF_COMMON | VF_VENDOR, API_VERSION);
+ return Version("$Id$", VF_COMMON|VF_VENDOR, API_VERSION);
}
void Prioritize()
{
Module* banex = ServerInstance->Modules->Find("m_banexception.so");
- ServerInstance->Modules->SetPriority(this, I_OnUserPreJoin, PRIO_BEFORE, &banex);
+ ServerInstance->Modules->SetPriority(this, I_OnUserPreJoin, PRIORITY_BEFORE, &banex);
}
};