]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/modules/extra/m_filter_pcre.cpp
Whoops, properly handle rehash now that new filters might be added by /FILTER
[user/henk/code/inspircd.git] / src / modules / extra / m_filter_pcre.cpp
index 5df48cb05f427deb2264a9fed44c11d2e4c60e31..a7829871f18569416a587c36cb733dce6de2d1ae 100644 (file)
 /* $ModDesc: m_filter with regexps */
 /* $CompileFlags: `pcre-config --cflags` */
 /* $LinkerFlags: `pcre-config --libs` `perl extra/pcre_rpath.pl` -lpcre */
-/* $ModDep: ../m_filter.h */
+/* $ModDep: m_filter.h */
 
 class PCREFilter : public FilterResult
 {
  public:
         pcre* regexp;
 
-        PCREFilter(pcre* r, const std::string &rea, const std::string &act)
-                : FilterResult::FilterResult(rea, act), regexp(r)
+        PCREFilter(pcre* r, const std::string &rea, const std::string &act, long gline_time, const std::string &pat)
+                : FilterResult::FilterResult(pat, rea, act, gline_time), regexp(r)
         {
         }
 };
@@ -52,7 +52,7 @@ class ModuleFilterPCRE : public FilterBase
 
  public:
        ModuleFilterPCRE(InspIRCd* Me)
-       : FilterBase::FilterBase(Me)
+       : FilterBase::FilterBase(Me, "m_filter_pcre.so")
        {
                OnRehash("");
        }
@@ -74,24 +74,69 @@ class ModuleFilterPCRE : public FilterBase
                }
                return NULL;
        }
-       
-       virtual void OnRehash(const std::string &parameter)
-       {               
-               ConfigReader MyConf(ServerInstance);
 
+       virtual bool DeleteFilter(const std::string &freeform)
+       {
+               for (std::vector<PCREFilter>::iterator i = filters.begin(); i != filters.end(); i++)
+               {
+                       if (i->freeform == freeform)
+                       {
+                               pcre_free((*i).regexp);
+                               filters.erase(i);
+                               return true;
+                       }
+               }
+               return false;
+       }
+
+       virtual void SyncFilters(Module* proto, void* opaque)
+       {
+               for (std::vector<PCREFilter>::iterator i = filters.begin(); i != filters.end(); i++)
+               {
+                       this->SendFilter(proto, opaque, &(*i));
+               }
+       }
+
+       virtual std::pair<bool, std::string> AddFilter(const std::string &freeform, const std::string &type, const std::string &reason, long duration)
+       {
                for (std::vector<PCREFilter>::iterator i = filters.begin(); i != filters.end(); i++)
-                       pcre_free((*i).regexp);
+               {
+                       if (i->freeform == freeform)
+                       {
+                               return std::make_pair(false, "Filter already exists");
+                       }
+               }
+
+               re = pcre_compile(freeform.c_str(),0,&error,&erroffset,NULL);
 
-               filters.clear();
+               if (!re)
+               {
+                       ServerInstance->Log(DEFAULT,"Error in regular expression: %s at offset %d: %s\n", freeform.c_str(), erroffset, error);
+                       ServerInstance->Log(DEFAULT,"Regular expression %s not loaded.", freeform.c_str());
+                       return std::make_pair(false, "Error in regular expression at offset " + ConvToStr(erroffset) + ": "+error);
+               }
+               else
+               {
+                       filters.push_back(PCREFilter(re, reason, type, duration, freeform));
+                       return std::make_pair(true, "");
+               }
+       }
+
+       virtual void OnRehash(const std::string &parameter)
+       {               
+               ConfigReader MyConf(ServerInstance);
 
                for (int index = 0; index < MyConf.Enumerate("keyword"); 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);
-                       
+                       this->DeleteFilter(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);
+                       long gline_time = ServerInstance->Duration(MyConf.ReadValue("keyword", "duration", index).c_str());
+
                        re = pcre_compile(pattern.c_str(),0,&error,&erroffset,NULL);
-                       
+
                        if (!re)
                        {
                                ServerInstance->Log(DEFAULT,"Error in regular expression: %s at offset %d: %s\n", pattern.c_str(), erroffset, error);
@@ -99,7 +144,7 @@ class ModuleFilterPCRE : public FilterBase
                        }
                        else
                        {
-                               filters.push_back(PCREFilter(re, reason, action));
+                               filters.push_back(PCREFilter(re, reason, action, gline_time, pattern));
                                ServerInstance->Log(DEFAULT,"Regular expression %s loaded.", pattern.c_str());
                        }
                }