]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/modules/m_rline.cpp
5036423a114b86eb32abdd4ff1c8e82e135d4889
[user/henk/code/inspircd.git] / src / modules / m_rline.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 "inspircd.h"
15 #include <pcre.h>
16 #include "xline.h"
17
18 /* $ModDesc: RLINE: Regexp user banning. */
19 /* $CompileFlags: exec("pcre-config --cflags") */
20 /* $LinkerFlags: exec("pcre-config --libs") rpath("pcre-config --libs") -lpcre */
21
22 #ifdef WINDOWS
23 #pragma comment(lib, "pcre.lib")
24 #endif
25
26 class CoreExport RLine : public XLine
27 {
28   public:
29
30         /** Create a R-Line.
31          * @param s_time The set time
32          * @param d The duration of the xline
33          * @param src The sender of the xline
34          * @param re The reason of the xline
35          * @param regex Pattern to match with
36          * @
37          */
38         RLine(InspIRCd* Instance, time_t s_time, long d, const char* src, const char* re, const char* regexs) : XLine(Instance, s_time, d, src, re, "K")
39         {
40                 const char *error;
41                 int erroffset;
42
43                 matchtext = regexs;
44
45                 regex = pcre_compile(regexs, 0, &error, &erroffset, NULL);
46
47                 if (!regex)
48                 {
49                         ServerInstance->SNO->WriteToSnoMask('x',"Error in regular expression: %s at offset %d: %s\n", regexs, erroffset, error);
50                         throw CoreException("Bad regex pattern.");
51                 }
52         }
53
54         /** Destructor
55          */
56         ~RLine()
57         {
58                 pcre_free(regex);
59         }
60
61         virtual bool Matches(User *u)
62         {
63                 std::string compare = compare.assign(u->nick) + "!" + u->ident + "@" + u->host + " " + u->fullname;
64
65                 ServerInstance->Log(DEBUG, "Matching " + matchtext + " against string " + compare);
66
67                 if (pcre_exec(regex, NULL, compare.c_str(), compare.length(), 0, 0, NULL, 0) > -1)
68                 {
69                         // Bang. :D
70                         return true;
71                 }
72
73                 return false;
74         }
75
76         virtual bool Matches(const std::string&); // Ignored for us
77
78         virtual void Apply(User* u)
79         {
80                 DefaultApply(u, "R", true);
81         }
82
83         virtual void DisplayExpiry()
84         {
85                 ServerInstance->SNO->WriteToSnoMask('x',"Expiring timed R-Line %s (set by %s %d seconds ago)", this->matchtext.c_str(), this->source, this->duration);
86         }
87
88         virtual const char* Displayable()
89         {
90                 return matchtext.c_str();
91         }
92
93         std::string matchtext;
94
95         pcre *regex;
96 };
97
98
99 /** An XLineFactory specialized to generate RLine* pointers
100  */
101 class CoreExport RLineFactory : public XLineFactory
102 {
103  public:
104         RLineFactory(InspIRCd* Instance) : XLineFactory(Instance, "R") { }
105
106         /** Generate a RLine
107          */
108         XLine* Generate(time_t set_time, long duration, const char* source, const char* reason, const char* xline_specific_mask)
109         {
110                 return new RLine(ServerInstance, set_time, duration, source, reason, xline_specific_mask);
111         }
112 };
113
114 /** Handle /RLINE
115  * Syntax is same as other lines: RLINE regex_goes_here 1d :reason
116  */
117 class CommandRLine : public Command
118 {
119  public:
120         CommandRLine (InspIRCd* Instance) : Command(Instance,"DALINFO", 1, 'o')
121         {
122                 this->source = "m_rline.so";
123         }
124
125         CmdResult Handle (const char** parameters, int pcnt, User *user)
126         {
127                 if (pcnt >= 3)
128                 {
129                         // Adding - XXX todo make this respect <insane> tag perhaps..
130
131                         long duration = ServerInstance->Duration(parameters[1]);
132                         RLine *r = NULL;
133
134                         try
135                         {
136                                 r = new RLine(ServerInstance, ServerInstance->Time(), duration, user->nick, parameters[2], parameters[0]);
137                         }
138                         catch (...)
139                         {
140                                 ; // Do nothing. If we get here, the regex was fucked up, and they already got told it fucked up.
141                         }
142
143                         if (r)
144                         {
145                                 if (ServerInstance->XLines->AddLine(r, user))
146                                 {
147                                         if (!duration)
148                                         {
149                                                 ServerInstance->SNO->WriteToSnoMask('x',"%s added permanent R-Line for %s.", user->nick, parameters[0]);
150                                         }
151                                         else
152                                         {
153                                                 time_t c_requires_crap = duration + ServerInstance->Time();
154                                                 ServerInstance->SNO->WriteToSnoMask('x', "%s added timed R-Line for %s, expires on %s", user->nick, parameters[0],
155                                                                 ServerInstance->TimeString(c_requires_crap).c_str());
156                                         }
157
158                                         ServerInstance->XLines->ApplyLines();
159                                 }
160                                 else
161                                 {
162                                         delete r;
163                                         user->WriteServ("NOTICE %s :*** R-Line for %s already exists", user->nick, parameters[0]);
164                                 }
165                         }
166                 }
167                 else
168                 {
169                         if (ServerInstance->XLines->DelLine(parameters[0],"G",user))
170                         {
171                                 ServerInstance->SNO->WriteToSnoMask('x',"%s Removed G-line on %s.",user->nick,parameters[0]);
172                         }
173                         else
174                         {
175                                 user->WriteServ("NOTICE %s :*** G-line %s not found in list, try /stats g.",user->nick,parameters[0]);
176                         }
177                 }
178
179                 return CMD_SUCCESS;
180         }
181 };
182
183 class ModuleRLine : public Module
184 {
185  private:
186         CommandRLine *r;
187  public:
188         ModuleRLine(InspIRCd* Me) : Module(Me)
189         {
190                 // Create a new command
191                 r = new CommandRLine(ServerInstance);
192                 ServerInstance->AddCommand(r);
193         }
194
195         virtual ~ModuleRLine()
196         {
197         }
198 };
199
200 MODULE_INIT(ModuleRLine)
201