]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/modules/extra/m_filter_pcre.cpp
Change the SQLutils and SQL providers to also use interfaces for proper unload order...
[user/henk/code/inspircd.git] / src / modules / extra / m_filter_pcre.cpp
1 /*       +------------------------------------+
2  *       | Inspire Internet Relay Chat Daemon |
3  *       +------------------------------------+
4  *
5  *  InspIRCd: (C) 2002-2007 InspIRCd Development Team
6  * See: http://www.inspircd.org/wiki/index.php/Credits
7  *
8  * This program is free but copyrighted software; see
9  *            the file COPYING for details.
10  *
11  * ---------------------------------------------------
12  */
13
14 #include <stdio.h>
15 #include <string>
16 #include <pcre.h>
17 #include "users.h"
18 #include "channels.h"
19 #include "modules.h"
20 #include "inspircd.h"
21 #include "m_filter.h"
22
23 /* $ModDesc: m_filter with regexps */
24 /* $CompileFlags: `pcre-config --cflags` */
25 /* $LinkerFlags: `pcre-config --libs` `perl extra/pcre_rpath.pl` -lpcre */
26 /* $ModDep: m_filter.h */
27
28 class PCREFilter : public FilterResult
29 {
30  public:
31          pcre* regexp;
32
33          PCREFilter(pcre* r, const std::string &rea, const std::string &act, long gline_time, const std::string &pat)
34                  : FilterResult::FilterResult(pat, rea, act, gline_time), regexp(r)
35          {
36          }
37 };
38
39 class ModuleFilterPCRE : public FilterBase
40 {
41         std::vector<PCREFilter> filters;
42         pcre *re;
43         const char *error;
44         int erroffset;
45
46  public:
47         ModuleFilterPCRE(InspIRCd* Me)
48         : FilterBase::FilterBase(Me, "m_filter_pcre.so")
49         {
50                 OnRehash("");
51         }
52
53         virtual ~ModuleFilterPCRE()
54         {
55         }
56
57         virtual FilterResult* FilterMatch(const std::string &text)
58         {
59                 for (unsigned int index = 0; index < filters.size(); index++)
60                 {
61                         PCREFilter& filt = filters[index];
62                         
63                         if (pcre_exec(filt.regexp,NULL,text.c_str(),text.length(),0,0,NULL,0) > -1)
64                         {
65                                 return &filt;
66                         }
67                 }
68                 return NULL;
69         }
70
71         virtual bool DeleteFilter(const std::string &freeform)
72         {
73                 for (std::vector<PCREFilter>::iterator i = filters.begin(); i != filters.end(); i++)
74                 {
75                         if (i->freeform == freeform)
76                         {
77                                 pcre_free((*i).regexp);
78                                 filters.erase(i);
79                                 return true;
80                         }
81                 }
82                 return false;
83         }
84
85         virtual void SyncFilters(Module* proto, void* opaque)
86         {
87                 for (std::vector<PCREFilter>::iterator i = filters.begin(); i != filters.end(); i++)
88                 {
89                         this->SendFilter(proto, opaque, &(*i));
90                 }
91         }
92
93         virtual std::pair<bool, std::string> AddFilter(const std::string &freeform, const std::string &type, const std::string &reason, long duration)
94         {
95                 for (std::vector<PCREFilter>::iterator i = filters.begin(); i != filters.end(); i++)
96                 {
97                         if (i->freeform == freeform)
98                         {
99                                 return std::make_pair(false, "Filter already exists");
100                         }
101                 }
102
103                 re = pcre_compile(freeform.c_str(),0,&error,&erroffset,NULL);
104
105                 if (!re)
106                 {
107                         ServerInstance->Log(DEFAULT,"Error in regular expression: %s at offset %d: %s\n", freeform.c_str(), erroffset, error);
108                         ServerInstance->Log(DEFAULT,"Regular expression %s not loaded.", freeform.c_str());
109                         return std::make_pair(false, "Error in regular expression at offset " + ConvToStr(erroffset) + ": "+error);
110                 }
111                 else
112                 {
113                         filters.push_back(PCREFilter(re, reason, type, duration, freeform));
114                         return std::make_pair(true, "");
115                 }
116         }
117
118         virtual void OnRehash(const std::string &parameter)
119         {               
120                 ConfigReader MyConf(ServerInstance);
121
122                 for (int index = 0; index < MyConf.Enumerate("keyword"); index++)
123                 {
124                         this->DeleteFilter(MyConf.ReadValue("keyword", "pattern", index));
125
126                         std::string pattern = MyConf.ReadValue("keyword", "pattern", index);
127                         std::string reason = MyConf.ReadValue("keyword", "reason", index);
128                         std::string action = MyConf.ReadValue("keyword", "action", index);
129                         long gline_time = ServerInstance->Duration(MyConf.ReadValue("keyword", "duration", index).c_str());
130
131                         re = pcre_compile(pattern.c_str(),0,&error,&erroffset,NULL);
132
133                         if (!re)
134                         {
135                                 ServerInstance->Log(DEFAULT,"Error in regular expression: %s at offset %d: %s\n", pattern.c_str(), erroffset, error);
136                                 ServerInstance->Log(DEFAULT,"Regular expression %s not loaded.", pattern.c_str());
137                         }
138                         else
139                         {
140                                 filters.push_back(PCREFilter(re, reason, action, gline_time, pattern));
141                                 ServerInstance->Log(DEFAULT,"Regular expression %s loaded.", pattern.c_str());
142                         }
143                 }
144         }
145
146         virtual int OnStats(char symbol, userrec* user, string_list &results)
147         {
148                 if (symbol == 's')
149                 {
150                         std::string sn = ServerInstance->Config->ServerName;
151                         for (std::vector<PCREFilter>::iterator i = filters.begin(); i != filters.end(); i++)
152                         {
153                                 results.push_back(sn+" 223 "+user->nick+" :REGEXP:"+i->freeform+" "+i->action+" "+ConvToStr(i->gline_time)+" :"+i->reason);
154                         }
155                 }
156                 return 0;
157         }
158 };
159         
160
161 class ModuleFilterPCREFactory : public ModuleFactory
162 {
163  public:
164         ModuleFilterPCREFactory()
165         {
166         }
167         
168         ~ModuleFilterPCREFactory()
169         {
170         }
171         
172         virtual Module * CreateModule(InspIRCd* Me)
173         {
174                 return new ModuleFilterPCRE(Me);
175         }
176         
177 };
178
179
180 extern "C" void * init_module( void )
181 {
182         return new ModuleFilterPCREFactory;
183 }