X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fmodules%2Fextra%2Fm_filter_pcre.cpp;h=faf1718e458421c96ee0be68d92e2026b4e1b6e7;hb=b45e7cfebbeaad4ecc3c55bc3060140f50f710d3;hp=58ca77333d3dae0af2f8cd0078ef18bae6e89f61;hpb=5d407fb44c759524881712a80febb86b4506ddbf;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/modules/extra/m_filter_pcre.cpp b/src/modules/extra/m_filter_pcre.cpp index 58ca77333..faf1718e4 100644 --- a/src/modules/extra/m_filter_pcre.cpp +++ b/src/modules/extra/m_filter_pcre.cpp @@ -14,8 +14,6 @@ * --------------------------------------------------- */ -using namespace std; - // Message and notice filtering using regex patterns // a module based on the original work done by Craig Edwards in 2003 // for the chatspike network. @@ -26,8 +24,10 @@ using namespace std; #include "users.h" #include "channels.h" #include "modules.h" -#include "helperfuncs.h" +#include "inspircd.h" +/** Thrown by m_filter_pcre + */ class FilterPCREException : public ModuleException { public: @@ -38,61 +38,39 @@ class FilterPCREException : public ModuleException }; /* $ModDesc: m_filter with regexps */ -/* $CompileFlags: -I/usr/local/include */ -/* $LinkerFlags: -L/usr/local/lib -lpcre */ +/* $CompileFlags: -I`pcre-config --prefix`/include */ +/* $LinkerFlags: `pcre-config --libs` `perl extra/pcre_rpath.pl` -lpcre */ class ModuleFilterPCRE : public Module { - Server *Srv; - ConfigReader *Conf, *MyConf; - std::vector filters; + class Filter + { + public: + pcre* regexp; + std::string reason; + std::string action; + + Filter(pcre* r, const std::string &rea, const std::string &act) + : regexp(r), reason(rea), action(act) + { + } + }; + + InspIRCd* Srv; + std::vector filters; pcre *re; const char *error; int erroffset; public: - ModuleFilterPCRE(Server* Me) - : Module::Module(Me) + ModuleFilterPCRE(InspIRCd* Me) + : Module::Module(Me), Srv(Me) { - // read the configuration file on startup. - // it is perfectly valid to set to the value of the - // main config file, then append your tags to the bottom - // of the main config... but rather messy. That's why the capability - // of using a seperate config file is provided. - Srv = Me; - Conf = new ConfigReader; - std::string filterfile = Conf->ReadValue("filter","file",0); - MyConf = new ConfigReader(filterfile); - if ((filterfile == "") || (!MyConf->Verify())) - { - FilterPCREException e; - throw(e); - } - Srv->Log(DEFAULT,std::string("m_filter_pcre: read configuration from ")+filterfile); - - filters.clear(); - for (int index = 0; index < MyConf->Enumerate("keyword"); index++) - { - std::string pattern = MyConf->ReadValue("keyword","pattern",index); - re = pcre_compile(pattern.c_str(),0,&error,&erroffset,NULL); - if (!re) - { - log(DEFAULT,"Error in regular expression: %s at offset %d: %s\n", pattern.c_str(), erroffset, error); - log(DEFAULT,"Regular expression %s not loaded.", pattern.c_str()); - } - else - { - filters.push_back(re); - log(DEFAULT,"Regular expression %s loaded.", pattern.c_str()); - } - } - + OnRehash(""); } virtual ~ModuleFilterPCRE() { - DELETE(MyConf); - DELETE(Conf); } void Implements(char* List) @@ -111,41 +89,42 @@ class ModuleFilterPCRE : public Module { for (unsigned int index = 0; index < filters.size(); index++) { - if (pcre_exec(filters[index],NULL,text.c_str(),text.length(),0,0,NULL,0) > -1) + Filter& filt = filters[index]; + + if (pcre_exec(filt.regexp,NULL,text.c_str(),text.length(),0,0,NULL,0) > -1) { - std::string target = ""; - std::string reason = MyConf->ReadValue("keyword","reason",index); - std::string do_action = MyConf->ReadValue("keyword","action",index); - - if (do_action == "") - do_action = "none"; + const char* target; + + if(filt.action.empty()) + filt.action = "none"; if (target_type == TYPE_USER) { userrec* t = (userrec*)dest; - target = std::string(t->nick); + target = t->nick; } else if (target_type == TYPE_CHANNEL) { chanrec* t = (chanrec*)dest; - target = std::string(t->name); + target = t->name; } - if (do_action == "block") - { - Srv->SendOpers(std::string("Filter: ")+std::string(user->nick)+ - std::string(" had their notice filtered, target was ")+ - target+": "+reason); - Srv->SendTo(NULL,user,"NOTICE "+std::string(user->nick)+ - " :Your notice has been filtered and opers notified: "+reason); - } - Srv->Log(DEFAULT,std::string("Filter: ")+std::string(user->nick)+ - std::string(" had their notice filtered, target was ")+ - target+": "+reason+" Action: "+do_action); - - if (do_action == "kill") + else { - Srv->QuitUser(user,reason); + target = ""; } + + ServerInstance->Log(DEFAULT, "Filter: %s had their notice filtered, target was %s: %s Action: %s", user->nick, target, filt.reason.c_str(), filt.action.c_str()); + + if (filt.action == "block") + { + Srv->WriteOpers("Filter: %s had their notice filtered, target was %s: %s", user->nick, target, filt.reason.c_str()); + user->WriteServ("NOTICE "+std::string(user->nick)+" :Your notice has been filtered and opers notified: "+filt.reason); + } + else if (filt.action == "kill") + { + userrec::QuitUser(Srv, user, filt.reason); + } + return 1; } } @@ -154,45 +133,54 @@ class ModuleFilterPCRE : public Module virtual void OnRehash(const std::string ¶meter) { - // reload our config file on rehash - we must destroy and re-allocate the classes - // to call the constructor again and re-read our data. - DELETE(Conf); - DELETE(MyConf); - Conf = new ConfigReader; - std::string filterfile = Conf->ReadValue("filter","file",0); - // this automatically re-reads the configuration file into the class - MyConf = new ConfigReader(filterfile); - if ((filterfile == "") || (!MyConf->Verify())) + /* Read the configuration file on startup and rehash. + * It is perfectly valid to set to the value of the + * main config file, then append your tags to the bottom + * of the main config... but rather messy. That's why the capability + * of using a seperate config file is provided. + */ + + ConfigReader Conf(Srv); + + std::string filterfile = Conf.ReadValue("filter", "file", 0); + + ConfigReader MyConf(Srv, filterfile); + + if (filterfile.empty() || !MyConf.Verify()) { FilterPCREException e; - // bail if the user forgot to create a config file throw(e); } - Srv->Log(DEFAULT,std::string("m_filter_pcre: read configuration from ")+filterfile); + + ServerInstance->Log(DEFAULT,"m_filter_pcre: read configuration from "+filterfile); filters.clear(); - for (int index = 0; index < MyConf->Enumerate("keyword"); index++) + + for (int index = 0; index < MyConf.Enumerate("keyword"); index++) { - std::string pattern = MyConf->ReadValue("keyword","pattern",index); + std::string pattern = MyConf.ReadValue("keyword","pattern",index); + std::string reason = MyConf.ReadValue("keyword","reason",index); + std::string action = MyConf.ReadValue("keyword","action",index); + re = pcre_compile(pattern.c_str(),0,&error,&erroffset,NULL); + if (!re) { - log(DEFAULT,"Error in regular expression: %s at offset %d: %s\n", pattern.c_str(), erroffset, error); - log(DEFAULT,"Regular expression %s not loaded.", pattern.c_str()); + ServerInstance->Log(DEFAULT,"Error in regular expression: %s at offset %d: %s\n", pattern.c_str(), erroffset, error); + ServerInstance->Log(DEFAULT,"Regular expression %s not loaded.", pattern.c_str()); } else { - filters.push_back(re); - log(DEFAULT,"Regular expression %s loaded.", pattern.c_str()); + filters.push_back(Filter(re, reason, action)); + ServerInstance->Log(DEFAULT,"Regular expression %s loaded.", pattern.c_str()); } } - } virtual Version GetVersion() { - // This is version 2 because version 1.x is the unreleased unrealircd module - return Version(3,0,0,0,VF_VENDOR); + /* Version 1.x is the unreleased unrealircd module */ + return Version(3,2,0,0,VF_VENDOR); } }; @@ -210,7 +198,7 @@ class ModuleFilterPCREFactory : public ModuleFactory { } - virtual Module * CreateModule(Server* Me) + virtual Module * CreateModule(InspIRCd* Me) { return new ModuleFilterPCRE(Me); } @@ -222,4 +210,3 @@ extern "C" void * init_module( void ) { return new ModuleFilterPCREFactory; } -