Restore <options:exemptchanops> with long names

git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@12502 e03df62e-2008-0410-955e-edbf42e46eb7
This commit is contained in:
danieldg 2010-02-20 09:15:55 +00:00
parent a5263a8ada
commit 4d46f5f9ef
21 changed files with 102 additions and 89 deletions

View File

@ -580,6 +580,9 @@
# moronbanner: This is the text that is sent to a user when they are
# banned from the server.
moronbanner="You're banned! Email haha@abuse.com with the ERROR line below for help."
# exemptchanops: exemptions for channel access restrictions based on prefix.
exemptchanops="nonick:v flood:o"
# invitebypassmodes: This allows /invite to bypass other channel modes.
# (Such as +k, +j, +l, etc)

View File

@ -735,15 +735,6 @@
# modes are blockcaps, noctcp, blockcolor, nickflood, flood, censor, #
# filter, regmoderated, nonick, nonotice, and stripcolor. #
#<module name="m_exemptchanops.so"> #
# #
#-#-#-#-#-#-#-#-#-#- EXEMPTCHANOPS CONFIGURATION -#-#-#-#-#-#-#-#-#-#
# defaults - default exemptions. These can be added to or overridden #
# by the channel mode +X. Each item is of the form #
# [mode]:[minstatus] where you must have [minstatus] in #
# order to be able to bypass [mode]. #
# Use "blockcolor:*" to override a default exemption #
#<exemptchanops defaults="nonick:v flood:o">
#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#
# Filter module: Provides message filtering, similar to SPAMFILTER.

View File

@ -77,7 +77,6 @@ CoreExport extern InspIRCd* ServerInstance;
#include "socketengine.h"
#include "snomasks.h"
#include "filelogger.h"
#include "caller.h"
#include "modules.h"
#include "threadengine.h"
#include "configreader.h"
@ -240,6 +239,7 @@ DEFINE_HANDLER1(FloodQuitUserHandler, void, User*);
DEFINE_HANDLER2(IsChannelHandler, bool, const char*, size_t);
DEFINE_HANDLER1(IsSIDHandler, bool, const std::string&);
DEFINE_HANDLER1(RehashHandler, void, const std::string&);
DEFINE_HANDLER3(OnCheckExemptionHandler, ModResult, User*, Channel*, const std::string&);
/** The main class of the irc server.
* This class contains instances of all the other classes in this software.
@ -308,6 +308,7 @@ class CoreExport InspIRCd
IsNickHandler HandleIsNick;
IsIdentHandler HandleIsIdent;
FloodQuitUserHandler HandleFloodQuitUser;
OnCheckExemptionHandler HandleOnCheckExemption;
IsChannelHandler HandleIsChannel;
IsSIDHandler HandleIsSID;
RehashHandler HandleRehash;
@ -782,6 +783,13 @@ class CoreExport InspIRCd
*/
caller1<void, User*> FloodQuitUser;
/** Called to check whether a channel restriction mode applies to a user
* @param User that is attempting some action
* @param Channel that the action is being performed on
* @param Action name
*/
caller3<ModResult, User*, Channel*, const std::string&> OnCheckExemption;
/** Restart the server.
* This function will not return. If an error occurs,
* it will throw an instance of CoreException.

View File

@ -327,7 +327,7 @@ enum Implementation
I_OnPostOper, I_OnSyncNetwork, I_OnSetAway, I_OnPostCommand, I_OnPostJoin,
I_OnWhoisLine, I_OnBuildNeighborList, I_OnGarbageCollect, I_OnSetConnectClass,
I_OnText, I_OnPassCompare, I_OnRunTestSuite, I_OnNamesListItem, I_OnNumeric, I_OnHookIO,
I_OnPreRehash, I_OnModuleRehash, I_OnSendWhoLine, I_OnChangeIdent, I_OnChannelRestrictionApply,
I_OnPreRehash, I_OnModuleRehash, I_OnSendWhoLine, I_OnChangeIdent,
I_END
};
@ -1278,12 +1278,6 @@ class CoreExport Module : public classbase, public usecountbase
* @param line The raw line to send; modifiable, if empty no line will be returned.
*/
virtual void OnSendWhoLine(User* source, const std::vector<std::string>& params, User* user, Channel* channel, std::string& line);
/** Called to check whether a channel restriction mode applies to a user on it
* @return MOD_RES_DENY to apply the restriction, MOD_RES_ALLOW to bypass
* the restriction, or MOD_RES_PASSTHRU to check restriction status normally
*/
virtual ModResult OnChannelRestrictionApply(User* user, Channel* chan, const char* restriction);
};

View File

@ -92,9 +92,8 @@ int Channel::SetTopic(User *u, std::string &ntopic, bool forceset)
return CMD_FAILURE;
if (res != MOD_RES_ALLOW)
{
FIRST_MOD_RESULT(OnChannelRestrictionApply, res, (u,this,"topiclock"));
bool defok = IsModeSet('t') ? GetPrefixValue(u) >= HALFOP_VALUE : HasUser(u);
if (!res.check(defok))
if (!ServerInstance->OnCheckExemption(u,this,"topiclock").check(defok))
{
if (!this->HasUser(u))
u->WriteNumeric(442, "%s %s :You're not on that channel!",u->nick.c_str(), this->name.c_str());

View File

@ -439,3 +439,28 @@ void GenRandomHandler::Call(char *output, size_t max)
for(unsigned int i=0; i < max; i++)
output[i] = random();
}
ModResult OnCheckExemptionHandler::Call(User* user, Channel* chan, const std::string& restriction)
{
unsigned int mypfx = chan->GetPrefixValue(user);
char minmode;
std::string current;
irc::spacesepstream defaultstream(ServerInstance->Config->ConfValue("options")->getString("exemptchanops"));
while (defaultstream.GetToken(current))
{
std::string::size_type pos = current.find(':');
if (pos == std::string::npos)
continue;
if (current.substr(0,pos) == restriction)
minmode = current[pos+1];
}
ModeHandler* mh = ServerInstance->Modes->FindMode(minmode, MODETYPE_CHANNEL);
if (mh && mypfx >= mh->GetPrefixRank())
return MOD_RES_ALLOW;
if (mh || minmode == '*')
return MOD_RES_DENY;
return MOD_RES_PASSTHRU;
}

View File

@ -305,7 +305,8 @@ InspIRCd::InspIRCd(int argc, char** argv) :
Rehash(&HandleRehash),
IsNick(&HandleIsNick),
IsIdent(&HandleIsIdent),
FloodQuitUser(&HandleFloodQuitUser)
FloodQuitUser(&HandleFloodQuitUser),
OnCheckExemption(&HandleOnCheckExemption)
{
#ifdef WIN32
// Strict, frequent checking of memory on debug builds

View File

@ -163,7 +163,6 @@ ModResult Module::OnNumeric(User*, unsigned int, const std::string&) { return MO
void Module::OnHookIO(StreamSocket*, ListenSocket*) { }
ModResult Module::OnAcceptConnection(int, ListenSocket*, irc::sockets::sockaddrs*, irc::sockets::sockaddrs*) { return MOD_RES_PASSTHRU; }
void Module::OnSendWhoLine(User*, const std::vector<std::string>&, User*, Channel*, std::string&) { }
ModResult Module::OnChannelRestrictionApply(User*, Channel*, const char*) { return MOD_RES_PASSTHRU; }
ModuleManager::ModuleManager() : ModCount(0)
{

View File

@ -59,8 +59,7 @@ public:
return MOD_RES_PASSTHRU;
Channel* c = (Channel*)dest;
ModResult res;
FIRST_MOD_RESULT(OnChannelRestrictionApply, res, (user,c,"blockcaps"));
ModResult res = ServerInstance->OnCheckExemption(user,c,"blockcaps");
if (res == MOD_RES_ALLOW)
return MOD_RES_PASSTHRU;

View File

@ -47,8 +47,7 @@ class ModuleBlockColour : public Module
if ((target_type == TYPE_CHANNEL) && (IS_LOCAL(user)))
{
Channel* c = (Channel*)dest;
ModResult res;
FIRST_MOD_RESULT(OnChannelRestrictionApply, res, (user,c,"blockcolor"));
ModResult res = ServerInstance->OnCheckExemption(user,c,"blockcolor");
if (res == MOD_RES_ALLOW)
return MOD_RES_PASSTHRU;

View File

@ -76,8 +76,7 @@ class ModuleCensor : public Module
{
active = ((Channel*)dest)->IsModeSet('G');
Channel* c = (Channel*)dest;
ModResult res;
FIRST_MOD_RESULT(OnChannelRestrictionApply, res, (user,c,"censor"));
ModResult res = ServerInstance->OnCheckExemption(user,c,"censor");
if (res == MOD_RES_ALLOW)
return MOD_RES_PASSTHRU;

View File

@ -83,8 +83,7 @@ class ModuleChanFilter : public Module
virtual ModResult ProcessMessages(User* user,Channel* chan,std::string &text)
{
ModResult res;
FIRST_MOD_RESULT(OnChannelRestrictionApply, res, (user,chan,"filter"));
ModResult res = ServerInstance->OnCheckExemption(user,chan,"filter");
if (!IS_LOCAL(user) || res == MOD_RES_ALLOW)
return MOD_RES_PASSTHRU;

View File

@ -52,42 +52,12 @@ class ExemptChanOps : public ListModeBase
}
};
class ModuleExemptChanOps : public Module
class ExemptHandler : public HandlerBase3<ModResult, User*, Channel*, const std::string&>
{
ExemptChanOps ec;
std::string defaults;
public:
ModuleExemptChanOps() : ec(this)
{
}
void init()
{
ServerInstance->Modules->AddService(ec);
Implementation eventlist[] = { I_OnChannelDelete, I_OnChannelRestrictionApply, I_OnRehash, I_OnSyncChannel };
ServerInstance->Modules->Attach(eventlist, this, 4);
OnRehash(NULL);
}
Version GetVersion()
{
return Version("Provides the ability to allow channel operators to be exempt from certain modes.",VF_VENDOR);
}
void OnRehash(User* user)
{
defaults = ServerInstance->Config->ConfValue("exemptchanops")->getString("defaults");
ec.DoRehash();
}
void OnSyncChannel(Channel* chan, Module* proto, void* opaque)
{
ec.DoSyncChannel(chan, proto, opaque);
}
ExemptChanOps ec;
ExemptHandler(Module* me) : ec(me) {}
ModeHandler* FindMode(const std::string& mid)
{
if (mid.length() == 1)
@ -101,21 +71,11 @@ class ModuleExemptChanOps : public Module
return NULL;
}
ModResult OnChannelRestrictionApply(User* user, Channel* chan, const char* restriction)
ModResult Call(User* user, Channel* chan, const std::string& restriction)
{
unsigned int mypfx = chan->GetPrefixValue(user);
irc::spacesepstream defaultstream(defaults);
std::string minmode;
std::string current;
while (defaultstream.GetToken(current))
{
std::string::size_type pos = current.find(':');
if (pos == std::string::npos)
continue;
if (current.substr(0,pos) == restriction)
minmode = current[pos+1];
}
modelist* list = ec.extItem.get(chan);
if (list)
@ -135,7 +95,50 @@ class ModuleExemptChanOps : public Module
return MOD_RES_ALLOW;
if (mh || minmode == "*")
return MOD_RES_DENY;
return MOD_RES_PASSTHRU;
return ServerInstance->HandleOnCheckExemption.Call(user, chan, restriction);
}
};
class ModuleExemptChanOps : public Module
{
std::string defaults;
ExemptHandler eh;
public:
ModuleExemptChanOps() : eh(this)
{
}
void init()
{
ServerInstance->Modules->AddService(eh.ec);
Implementation eventlist[] = { I_OnRehash, I_OnSyncChannel };
ServerInstance->Modules->Attach(eventlist, this, 2);
ServerInstance->OnCheckExemption = &eh;
OnRehash(NULL);
}
~ModuleExemptChanOps()
{
ServerInstance->OnCheckExemption = &ServerInstance->HandleOnCheckExemption;
}
Version GetVersion()
{
return Version("Provides the ability to allow channel operators to be exempt from certain modes.",VF_VENDOR);
}
void OnRehash(User* user)
{
eh.ec.DoRehash();
}
void OnSyncChannel(Channel* chan, Module* proto, void* opaque)
{
eh.ec.DoSyncChannel(chan, proto, opaque);
}
};

View File

@ -196,8 +196,7 @@ class ModuleMsgFlood : public Module
ModResult ProcessMessages(User* user,Channel* dest, const std::string &text)
{
ModResult res;
FIRST_MOD_RESULT(OnChannelRestrictionApply, res, (user,dest,"flood"));
ModResult res = ServerInstance->OnCheckExemption(user,dest,"flood");
if (!IS_LOCAL(user) || res == MOD_RES_ALLOW)
return MOD_RES_PASSTHRU;

View File

@ -209,7 +209,7 @@ class ModuleNickFlood : public Module
nickfloodsettings *f = nf.ext.get(channel);
if (f)
{
FIRST_MOD_RESULT(OnChannelRestrictionApply, res, (user,channel,"nickflood"));
res = ServerInstance->OnCheckExemption(user,channel,"nickflood");
if (res == MOD_RES_ALLOW)
continue;
@ -248,7 +248,7 @@ class ModuleNickFlood : public Module
nickfloodsettings *f = nf.ext.get(channel);
if (f)
{
FIRST_MOD_RESULT(OnChannelRestrictionApply, res, (user,channel,"nickflood"));
res = ServerInstance->OnCheckExemption(user,channel,"nickflood");
if (res == MOD_RES_ALLOW)
return;

View File

@ -78,8 +78,7 @@ class ModuleNoCTCP : public Module
if ((target_type == TYPE_CHANNEL) && (IS_LOCAL(user)))
{
Channel* c = (Channel*)dest;
ModResult res;
FIRST_MOD_RESULT(OnChannelRestrictionApply, res, (user,c,"noctcp"));
ModResult res = ServerInstance->OnCheckExemption(user,c,"noctcp");
if (res == MOD_RES_ALLOW)
return MOD_RES_PASSTHRU;

View File

@ -84,8 +84,7 @@ class ModuleNoNickChange : public Module
{
Channel* curr = *i;
ModResult res;
FIRST_MOD_RESULT(OnChannelRestrictionApply, res, (user,curr,"nonick"));
ModResult res = ServerInstance->OnCheckExemption(user,curr,"nonick");
if (res == MOD_RES_ALLOW)
continue;

View File

@ -53,7 +53,7 @@ class ModuleNoNotice : public Module
// ulines are exempt.
return MOD_RES_PASSTHRU;
}
FIRST_MOD_RESULT(OnChannelRestrictionApply, res, (user,c,"nonotice"));
res = ServerInstance->OnCheckExemption(user,c,"nonotice");
if (res == MOD_RES_ALLOW)
return MOD_RES_PASSTHRU;
else

View File

@ -175,8 +175,7 @@ class ModuleServicesAccount : public Module
if (target_type == TYPE_CHANNEL)
{
Channel* c = (Channel*)dest;
ModResult res;
FIRST_MOD_RESULT(OnChannelRestrictionApply, res, (user,c,"regmoderated"));
ModResult res = ServerInstance->OnCheckExemption(user,c,"regmoderated");
if (c->IsModeSet('M') && !is_registered && res != MOD_RES_ALLOW)
{

View File

@ -114,8 +114,7 @@ class ModuleStripColor : public Module
else if (target_type == TYPE_CHANNEL)
{
Channel* t = (Channel*)dest;
ModResult res;
FIRST_MOD_RESULT(OnChannelRestrictionApply, res, (user,t,"stripcolor"));
ModResult res = ServerInstance->OnCheckExemption(user,t,"stripcolor");
if (res == MOD_RES_ALLOW)
return MOD_RES_PASSTHRU;

View File

@ -169,7 +169,6 @@ static void checkall(Module* noimpl)
CHK(OnModuleRehash);
CHK(OnSendWhoLine);
CHK(OnChangeIdent);
CHK(OnChannelRestrictionApply);
}
class CommandTest : public Command