]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/xline.cpp
Rewrite of XLineManager::ApplyLines to only apply pending lines. This ..doesn't seem...
[user/henk/code/inspircd.git] / src / xline.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 /* $Core: libIRCDxline */
15
16 #include "inspircd.h"
17 #include "wildcard.h"
18 #include "xline.h"
19
20 /*
21  * This is now version 3 of the XLine subsystem, let's see if we can get it as nice and 
22  * efficient as we can this time so we can close this file and never ever touch it again ..
23  *
24  * Background:
25  *  Version 1 stored all line types in one list (one for g, one for z, etc). This was fine,
26  *  but both version 1 and 2 suck at applying lines efficiently. That is, every time a new line
27  *  was added, it iterated every existing line for every existing user. Ow. Expiry was also
28  *  expensive, as the lists were NOT sorted.
29  *
30  *  Version 2 moved permanent lines into a seperate list from non-permanent to help optimize
31  *  matching speed, but matched in the same way.
32  *  Expiry was also sped up by sorting the list by expiry (meaning just remove the items at the
33  *  head of the list that are outdated.)
34  *
35  * This was fine and good, but it looked less than ideal in code, and matching was still slower
36  * than it could have been, something which we address here.
37  *
38  * VERSION 3:
39  *  All lines are (as in v1) stored together -- no seperation of perm and non-perm. Expiry will
40  *  still use a sorted list, and we'll just ignore anything permanent.
41  *
42  *  Application will be by a list of lines 'pending' application, meaning only the newly added lines
43  *  will be gone over. Much faster.
44  *
45  * More of course is to come.
46  */
47
48 /* Version two, now with optimized expiry!
49  *
50  * Because the old way was horrendously slow, the new way of expiring xlines is very
51  * very efficient. I have improved the efficiency of the algorithm in two ways:
52  *
53  * (1) There are now two lists of items for each linetype. One list holds temporary
54  *     items, and the other list holds permanent items (ones which will expire).
55  *     Items which are on the permanent list are NEVER checked at all by the
56  *     expire_lines() function.
57  * (2) The temporary xline lists are always kept in strict numerical order, keyed by
58  *     current time + duration. This means that the line which is due to expire the
59  *     soonest is always pointed at by vector::begin(), so a simple while loop can
60  *     very efficiently, very quickly and above all SAFELY pick off the first few
61  *     items in the vector which need zapping.
62  *
63  *     -- Brain
64  */
65
66 bool InitXLine(ServerConfig* conf, const char* tag)
67 {
68         return true;
69 }
70
71 bool DoneZLine(ServerConfig* conf, const char* tag)
72 {
73         // XXX we should really only call this once - after we've finished processing configuration all together
74         conf->GetInstance()->XLines->ApplyLines();
75         return true;
76 }
77
78 bool DoneQLine(ServerConfig* conf, const char* tag)
79 {
80         // XXX we should really only call this once - after we've finished processing configuration all together
81         conf->GetInstance()->XLines->ApplyLines();
82         return true;
83 }
84
85 bool DoneKLine(ServerConfig* conf, const char* tag)
86 {
87         // XXX we should really only call this once - after we've finished processing configuration all together
88         conf->GetInstance()->XLines->ApplyLines();
89         return true;
90 }
91
92 bool DoneELine(ServerConfig* conf, const char* tag)
93 {
94         // XXX we should really only call this once - after we've finished processing configuration all together
95         conf->GetInstance()->XLines->ApplyLines();
96         return true;
97 }
98
99 bool DoZLine(ServerConfig* conf, const char* tag, char** entries, ValueList &values, int* types)
100 {
101         const char* reason = values[0].GetString();
102         const char* ipmask = values[1].GetString();
103
104         conf->GetInstance()->XLines->AddZLine(0,"<Config>",reason,ipmask);
105         return true;
106 }
107
108 bool DoQLine(ServerConfig* conf, const char* tag, char** entries, ValueList &values, int* types)
109 {
110         const char* reason = values[0].GetString();
111         const char* nick = values[1].GetString();
112
113         conf->GetInstance()->XLines->AddQLine(0,"<Config>",reason,nick);
114         return true;
115 }
116
117 bool DoKLine(ServerConfig* conf, const char* tag, char** entries, ValueList &values, int* types)
118 {
119         const char* reason = values[0].GetString();
120         const char* host = values[1].GetString();
121
122         conf->GetInstance()->XLines->AddKLine(0,"<Config>",reason,host);
123         return true;
124 }
125
126 bool DoELine(ServerConfig* conf, const char* tag, char** entries, ValueList &values, int* types)
127 {
128         const char* reason = values[0].GetString();
129         const char* host = values[1].GetString();
130
131         conf->GetInstance()->XLines->AddELine(0,"<Config>",reason,host);
132         return true;
133 }
134
135 bool XLine::Matches(User *u)
136 {
137         return false;
138 }
139
140 IdentHostPair XLineManager::IdentSplit(const std::string &ident_and_host)
141 {
142         IdentHostPair n = std::make_pair<std::string,std::string>("*","*");
143         std::string::size_type x = ident_and_host.find('@');
144         if (x != std::string::npos)
145         {
146                 n.second = ident_and_host.substr(x + 1,ident_and_host.length());
147                 n.first = ident_and_host.substr(0, x);
148                 if (!n.first.length())
149                         n.first.assign("*");
150                 if (!n.second.length())
151                         n.second.assign("*");
152         }
153         else
154         {
155                 n.second = ident_and_host;
156         }
157
158         return n;
159 }
160
161 // adds a g:line
162
163 bool XLineManager::AddGLine(long duration, const char* source,const char* reason,const char* hostmask)
164 {
165         IdentHostPair ih = IdentSplit(hostmask);
166
167         if (DelGLine(hostmask, true))
168                 return false;
169
170         GLine* item = new GLine(ServerInstance->Time(), duration, source, reason, ih.first.c_str(), ih.second.c_str());
171
172         glines.push_back(item);
173         sort(glines.begin(), glines.end(),XLineManager::XSortComparison);
174         pending_lines.push_back(item);
175
176         return true;
177 }
178
179 // adds an e:line (exception to bans)
180
181 bool XLineManager::AddELine(long duration, const char* source, const char* reason, const char* hostmask)
182 {
183         IdentHostPair ih = IdentSplit(hostmask);
184
185         if (DelELine(hostmask, true))
186                 return false;
187
188         ELine* item = new ELine(ServerInstance->Time(), duration, source, reason, ih.first.c_str(), ih.second.c_str());
189
190         elines.push_back(item);
191         sort(elines.begin(), elines.end(),XLineManager::XSortComparison);
192         pending_lines.push_back(item);
193
194         return true;
195 }
196
197 // adds a q:line
198
199 bool XLineManager::AddQLine(long duration, const char* source, const char* reason, const char* nickname)
200 {
201         if (DelQLine(nickname, true))
202                 return false;
203
204         QLine* item = new QLine(ServerInstance->Time(), duration, source, reason, nickname);
205
206         qlines.push_back(item);
207         sort(qlines.begin(), qlines.end(),XLineManager::XSortComparison);
208         pending_lines.push_back(item);
209
210         return true;
211 }
212
213 // adds a z:line
214
215 bool XLineManager::AddZLine(long duration, const char* source, const char* reason, const char* ipaddr)
216 {
217         if (strchr(ipaddr,'@'))
218         {
219                 while (*ipaddr != '@')
220                         ipaddr++;
221                 ipaddr++;
222         }
223
224         if (DelZLine(ipaddr, true))
225                 return false;
226
227         ZLine* item = new ZLine(ServerInstance->Time(), duration, source, reason, ipaddr);
228
229         zlines.push_back(item);
230         sort(zlines.begin(), zlines.end(),XLineManager::XSortComparison);
231         pending_lines.push_back(item);
232
233         return true;
234 }
235
236 // adds a k:line
237
238 bool XLineManager::AddKLine(long duration, const char* source, const char* reason, const char* hostmask)
239 {
240         IdentHostPair ih = IdentSplit(hostmask);
241
242         if (DelKLine(hostmask, true))
243                 return false;
244
245         KLine* item = new KLine(ServerInstance->Time(), duration, source, reason, ih.first.c_str(), ih.second.c_str());
246
247         klines.push_back(item);
248         sort(klines.begin(), klines.end(),XLineManager::XSortComparison);
249         pending_lines.push_back(item);
250
251         return true;
252 }
253
254 // deletes a g:line, returns true if the line existed and was removed
255
256 bool XLineManager::DelGLine(const char* hostmask, bool simulate)
257 {
258         IdentHostPair ih = IdentSplit(hostmask);
259         for (std::vector<GLine*>::iterator i = glines.begin(); i != glines.end(); i++)
260         {
261                 if (!strcasecmp(ih.first.c_str(),(*i)->identmask) && !strcasecmp(ih.second.c_str(),(*i)->hostmask))
262                 {
263                         if (!simulate)
264                         {
265                                 delete *i;
266                                 glines.erase(i);
267                         }
268                         return true;
269                 }
270         }
271
272         return false;
273 }
274
275 // deletes a e:line, returns true if the line existed and was removed
276
277 bool XLineManager::DelELine(const char* hostmask, bool simulate)
278 {
279         IdentHostPair ih = IdentSplit(hostmask);
280         for (std::vector<ELine*>::iterator i = elines.begin(); i != elines.end(); i++)
281         {
282                 if (!strcasecmp(ih.first.c_str(),(*i)->identmask) && !strcasecmp(ih.second.c_str(),(*i)->hostmask))
283                 {
284                         if (!simulate)
285                         {
286                                 delete *i;
287                                 elines.erase(i);
288                         }
289                         return true;
290                 }
291         }
292
293         return false;
294 }
295
296 // deletes a q:line, returns true if the line existed and was removed
297
298 bool XLineManager::DelQLine(const char* nickname, bool simulate)
299 {
300         for (std::vector<QLine*>::iterator i = qlines.begin(); i != qlines.end(); i++)
301         {
302                 if (!strcasecmp(nickname,(*i)->nick))
303                 {
304                         if (!simulate)
305                         {
306                                 delete *i;
307                                 qlines.erase(i);
308                         }
309                         return true;
310                 }
311         }
312
313         return false;
314 }
315
316 // deletes a z:line, returns true if the line existed and was removed
317
318 bool XLineManager::DelZLine(const char* ipaddr, bool simulate)
319 {
320         for (std::vector<ZLine*>::iterator i = zlines.begin(); i != zlines.end(); i++)
321         {
322                 if (!strcasecmp(ipaddr,(*i)->ipaddr))
323                 {
324                         if (!simulate)
325                         {
326                                 delete *i;
327                                 zlines.erase(i);
328                         }
329                         return true;
330                 }
331         }
332
333         return false;
334 }
335
336 // deletes a k:line, returns true if the line existed and was removed
337
338 bool XLineManager::DelKLine(const char* hostmask, bool simulate)
339 {
340         IdentHostPair ih = IdentSplit(hostmask);
341         for (std::vector<KLine*>::iterator i = klines.begin(); i != klines.end(); i++)
342         {
343                 if (!strcasecmp(ih.first.c_str(),(*i)->identmask) && !strcasecmp(ih.second.c_str(),(*i)->hostmask))
344                 {
345                         if (!simulate)
346                         {
347                                 delete *i;
348                                 klines.erase(i);
349                         }
350                         return true;
351                 }
352         }
353
354         return false;
355 }
356
357 // returns a pointer to the reason if a nickname matches a qline, NULL if it didnt match
358
359 QLine* XLineManager::matches_qline(const char* nick)
360 {
361         if (qlines.empty())
362                 return NULL;
363
364         for (std::vector<QLine*>::iterator i = qlines.begin(); i != qlines.end(); i++)
365                 if ((*i)->Matches(nick))
366                         return (*i);
367         return NULL;
368 }
369
370 // returns a pointer to the reason if a host matches a gline, NULL if it didnt match
371
372 GLine* XLineManager::matches_gline(User* user)
373 {
374         if (glines.empty())
375                 return NULL;
376
377         for (std::vector<GLine*>::iterator i = glines.begin(); i != glines.end(); i++)
378         {
379                 if ((*i)->Matches(user))
380                         return (*i);
381         }
382
383         return NULL;
384 }
385
386 ELine* XLineManager::matches_exception(User* user)
387 {
388         if (elines.empty())
389                 return NULL;
390
391         for (std::vector<ELine*>::iterator i = elines.begin(); i != elines.end(); i++)
392         {
393                 if ((*i)->Matches(user))
394                         return (*i);
395         }
396         return NULL;
397 }
398
399
400 void XLineManager::gline_set_creation_time(const char* host, time_t create_time)
401 {
402         for (std::vector<GLine*>::iterator i = glines.begin(); i != glines.end(); i++)
403         {
404                 if (!strcasecmp(host,(*i)->hostmask))
405                 {
406                         (*i)->set_time = create_time;
407                         (*i)->expiry = create_time + (*i)->duration;
408                         return;
409                 }
410         }
411
412         return ;
413 }
414
415 void XLineManager::eline_set_creation_time(const char* host, time_t create_time)
416 {
417         for (std::vector<ELine*>::iterator i = elines.begin(); i != elines.end(); i++)
418         {
419                 if (!strcasecmp(host,(*i)->hostmask))
420                 {
421                         (*i)->set_time = create_time;
422                         (*i)->expiry = create_time + (*i)->duration;
423                         return;
424                 }
425         }
426
427         return;
428 }
429
430 void XLineManager::qline_set_creation_time(const char* nick, time_t create_time)
431 {
432         for (std::vector<QLine*>::iterator i = qlines.begin(); i != qlines.end(); i++)
433         {
434                 if (!strcasecmp(nick,(*i)->nick))
435                 {
436                         (*i)->set_time = create_time;
437                         (*i)->expiry = create_time + (*i)->duration;
438                         return;
439                 }
440         }
441
442         return;
443 }
444
445 void XLineManager::zline_set_creation_time(const char* ip, time_t create_time)
446 {
447         for (std::vector<ZLine*>::iterator i = zlines.begin(); i != zlines.end(); i++)
448         {
449                 if (!strcasecmp(ip,(*i)->ipaddr))
450                 {
451                         (*i)->set_time = create_time;
452                         (*i)->expiry = create_time + (*i)->duration;
453                         return;
454                 }
455         }
456
457         return;
458 }
459
460 // returns a pointer to the reason if an ip address matches a zline, NULL if it didnt match
461
462 ZLine* XLineManager::matches_zline(User *u)
463 {
464         if (zlines.empty())
465                 return NULL;
466
467         for (std::vector<ZLine*>::iterator i = zlines.begin(); i != zlines.end(); i++)
468                 if ((*i)->Matches(u))
469                         return (*i);
470         return NULL;
471 }
472
473 // returns a pointer to the reason if a host matches a kline, NULL if it didnt match
474
475 KLine* XLineManager::matches_kline(User* user)
476 {
477         if (klines.empty())
478                 return NULL;
479
480         for (std::vector<KLine*>::iterator i = klines.begin(); i != klines.end(); i++)
481         {
482                 if ((*i)->Matches(user))
483                         return (*i);
484         }
485
486         return NULL;
487 }
488
489 bool XLineManager::XSortComparison(const XLine *one, const XLine *two)
490 {
491         // account for permanent lines
492         if (one->expiry == 0)
493         {
494                 return false;
495         }
496         return (one->expiry) < (two->expiry);
497 }
498
499 // removes lines that have expired
500 void XLineManager::expire_lines()
501 {
502         time_t current = ServerInstance->Time();
503
504         /* Because we now store all our XLines in sorted order using ((*i)->duration + (*i)->set_time) as a key, this
505          * means that to expire the XLines we just need to do a while, picking off the top few until there are
506          * none left at the head of the queue that are after the current time.
507          */
508
509         while ((glines.size()) && (current > (*glines.begin())->expiry) && ((*glines.begin())->duration != 0))
510         {
511                 std::vector<GLine*>::iterator i = glines.begin();
512                 ServerInstance->SNO->WriteToSnoMask('x',"Expiring timed G-Line %s@%s (set by %s %d seconds ago)",(*i)->identmask,(*i)->hostmask,(*i)->source,(*i)->duration);
513                 glines.erase(i);
514         }
515
516         while ((elines.size()) && (current > (*elines.begin())->expiry) && ((*elines.begin())->duration != 0))
517         {
518                 std::vector<ELine*>::iterator i = elines.begin();
519                 ServerInstance->SNO->WriteToSnoMask('x',"Expiring timed E-Line %s@%s (set by %s %d seconds ago)",(*i)->identmask,(*i)->hostmask,(*i)->source,(*i)->duration);
520                 elines.erase(i);
521         }
522
523         while ((zlines.size()) && (current > (*zlines.begin())->expiry) && ((*zlines.begin())->duration != 0))
524         {
525                 std::vector<ZLine*>::iterator i = zlines.begin();
526                 ServerInstance->SNO->WriteToSnoMask('x',"Expiring timed Z-Line %s (set by %s %d seconds ago)",(*i)->ipaddr,(*i)->source,(*i)->duration);
527                 zlines.erase(i);
528         }
529
530         while ((klines.size()) && (current > (*klines.begin())->expiry) && ((*klines.begin())->duration != 0))
531         {
532                 std::vector<KLine*>::iterator i = klines.begin();
533                 ServerInstance->SNO->WriteToSnoMask('x',"Expiring timed K-Line %s@%s (set by %s %d seconds ago)",(*i)->identmask,(*i)->hostmask,(*i)->source,(*i)->duration);
534                 klines.erase(i);
535         }
536
537         while ((qlines.size()) && (current > (*qlines.begin())->expiry) && ((*qlines.begin())->duration != 0))
538         {
539                 std::vector<QLine*>::iterator i = qlines.begin();
540                 ServerInstance->SNO->WriteToSnoMask('x',"Expiring timed Q-Line %s (set by %s %d seconds ago)",(*i)->nick,(*i)->source,(*i)->duration);
541                 qlines.erase(i);
542         }
543
544 }
545
546 // applies lines, removing clients and changing nicks etc as applicable
547
548 void XLineManager::ApplyLines()
549 {
550         char reason[MAXBUF];
551
552         XLine* check = NULL;
553         for (std::vector<User*>::const_iterator u2 = ServerInstance->local_users.begin(); u2 != ServerInstance->local_users.end(); u2++)
554         {
555                 User* u = (User*)(*u2);
556
557                 if (elines.size())
558                 {
559                         // ignore people matching exempts -- XXX cache the exempt state in userrec permanently?
560                         // should be fairly easy to accomplish really, and might achieve some nice gains?
561                         if (matches_exception(u))
562                                 continue;
563                 }
564
565                 for (std::vector<XLine *>::iterator i = pending_lines.begin(); i != pending_lines.end(); i++)
566                 {
567                         XLine *x = (*i);
568
569                         switch (x->type)
570                         {
571                                 case 'Z':
572                                 {
573                                         ZLine *z = dynamic_cast<ZLine *>(x);
574
575                                         if (z->Matches(u))
576                                         {
577                                                 snprintf(reason,MAXBUF,"Z-Lined: %s", check->reason);
578                                                 if (*ServerInstance->Config->MoronBanner)
579                                                         u->WriteServ("NOTICE %s :*** %s", u->nick, ServerInstance->Config->MoronBanner);
580                                                 if (ServerInstance->Config->HideBans)
581                                                         User::QuitUser(ServerInstance, u, "Z-Lined", reason);
582                                                 else
583                                                         User::QuitUser(ServerInstance, u, reason);
584                                         }
585                                         break;
586                                 }
587                                 case 'G':
588                                 {
589                                         GLine *g = dynamic_cast<GLine *>(x);
590
591                                         if (g->Matches(u))
592                                         {
593                                                 snprintf(reason,MAXBUF,"G-Lined: %s",check->reason);
594                                                 if (*ServerInstance->Config->MoronBanner)
595                                                         u->WriteServ("NOTICE %s :*** %s", u->nick, ServerInstance->Config->MoronBanner);
596                                                 if (ServerInstance->Config->HideBans)
597                                                         User::QuitUser(ServerInstance, u, "G-Lined", reason);
598                                                 else
599                                                         User::QuitUser(ServerInstance, u, reason);
600                                         }
601                                         break;
602                                 }
603                                 case 'Q':
604                                 {
605                                         QLine *q = dynamic_cast<QLine *>(x);
606
607                                         if (q->Matches(u))
608                                         {
609                                                 snprintf(reason,MAXBUF,"Q-Lined: %s",check->reason);
610                                                 if (*ServerInstance->Config->MoronBanner)
611                                                         u->WriteServ("NOTICE %s :*** %s", u->nick, ServerInstance->Config->MoronBanner);
612                                                 if (ServerInstance->Config->HideBans)
613                                                         User::QuitUser(ServerInstance, u, "Q-Lined", reason);
614                                                 else
615                                                         User::QuitUser(ServerInstance, u, reason);
616                                         }
617                                         break;
618                                 }
619                                 case 'K':
620                                 {
621                                         KLine *k = dynamic_cast<KLine *>(x);
622
623                                         if (k->Matches(u))
624                                         {
625                                                 snprintf(reason,MAXBUF,"K-Lined: %s",check->reason);
626                                                 if (*ServerInstance->Config->MoronBanner)
627                                                         u->WriteServ("NOTICE %s :*** %s", u->nick, ServerInstance->Config->MoronBanner);
628                                                 if (ServerInstance->Config->HideBans)
629                                                         User::QuitUser(ServerInstance, u, "K-Lined", reason);
630                                                 else
631                                                         User::QuitUser(ServerInstance, u, reason);
632                                         }
633                                         break;
634                                 }
635                                 case 'E':
636                                 {
637 //                                      ELine *e = dynamic_cast<ELine *>(x);
638                                         break;
639                                 }
640                                 default:
641                                 {
642                                         ServerInstance->Log(DEBUG, "Unknown line type pending: %c", x->type);
643                                         break;
644                                 }
645                         }
646                 }
647         }
648
649         pending_lines.clear();
650 }
651
652 void XLineManager::stats_k(User* user, string_list &results)
653 {
654         std::string sn = ServerInstance->Config->ServerName;
655         for (std::vector<KLine*>::iterator i = klines.begin(); i != klines.end(); i++)
656                 results.push_back(sn+" 216 "+user->nick+" :"+(*i)->identmask+"@"+(*i)->hostmask+" "+ConvToStr((*i)->set_time)+" "+ConvToStr((*i)->duration)+" "+(*i)->source+" :"+(*i)->reason);
657 }
658
659 void XLineManager::stats_g(User* user, string_list &results)
660 {
661         std::string sn = ServerInstance->Config->ServerName;
662         for (std::vector<GLine*>::iterator i = glines.begin(); i != glines.end(); i++)
663                 results.push_back(sn+" 223 "+user->nick+" :"+(*i)->identmask+"@"+(*i)->hostmask+" "+ConvToStr((*i)->set_time)+" "+ConvToStr((*i)->duration)+" "+(*i)->source+" :"+(*i)->reason);
664 }
665
666 void XLineManager::stats_q(User* user, string_list &results)
667 {
668         std::string sn = ServerInstance->Config->ServerName;
669         for (std::vector<QLine*>::iterator i = qlines.begin(); i != qlines.end(); i++)
670                 results.push_back(sn+" 217 "+user->nick+" :"+(*i)->nick+" "+ConvToStr((*i)->set_time)+" "+ConvToStr((*i)->duration)+" "+(*i)->source+" :"+(*i)->reason);
671 }
672
673 void XLineManager::stats_z(User* user, string_list &results)
674 {
675         std::string sn = ServerInstance->Config->ServerName;
676         for (std::vector<ZLine*>::iterator i = zlines.begin(); i != zlines.end(); i++)
677                 results.push_back(sn+" 223 "+user->nick+" :"+(*i)->ipaddr+" "+ConvToStr((*i)->set_time)+" "+ConvToStr((*i)->duration)+" "+(*i)->source+" :"+(*i)->reason);
678 }
679
680 void XLineManager::stats_e(User* user, string_list &results)
681 {
682         std::string sn = ServerInstance->Config->ServerName;
683         for (std::vector<ELine*>::iterator i = elines.begin(); i != elines.end(); i++)
684                 results.push_back(sn+" 223 "+user->nick+" :"+(*i)->identmask+"@"+(*i)->hostmask+" "+ConvToStr((*i)->set_time)+" "+ConvToStr((*i)->duration)+" "+(*i)->source+" :"+(*i)->reason);
685 }
686
687 XLineManager::XLineManager(InspIRCd* Instance) : ServerInstance(Instance)
688 {
689 }
690
691 //irtual bool Matches(const std::string &str)
692 //{
693         //return false;
694 //}
695
696 bool KLine::Matches(User *u)
697 {
698         if ((match(u->ident, this->identmask)))
699         {
700                 if ((match(u->host, this->hostmask, true)) || (match(u->GetIPString(), this->hostmask, true)))
701                 {
702                         return true;
703                 }
704         }
705
706         return false;
707 }
708
709 bool GLine::Matches(User *u)
710 {
711         if ((match(u->ident, this->identmask)))
712         {
713                 if ((match(u->host, this->hostmask, true)) || (match(u->GetIPString(), this->hostmask, true)))
714                 {
715                         return true;
716                 }
717         }
718
719         return false;
720 }
721
722 bool ELine::Matches(User *u)
723 {
724         if ((match(u->ident, this->identmask)))
725         {
726                 if ((match(u->host, this->hostmask, true)) || (match(u->GetIPString(), this->hostmask, true)))
727                 {
728                         return true;
729                 }
730         }
731
732         return false;
733 }
734
735 bool ZLine::Matches(User *u)
736 {
737         if (match(u->GetIPString(), this->ipaddr, true))
738                 return true;
739         else
740                 return false;
741 }
742
743 bool QLine::Matches(User *u)
744 {
745         if (match(u->nick, this->nick))
746                 return true;
747
748         return false;
749 }
750
751 bool ZLine::Matches(const std::string &str)
752 {
753         if (match(str.c_str(), this->ipaddr, true))
754                 return true;
755         else
756                 return false;
757 }
758
759 bool QLine::Matches(const std::string &str)
760 {
761         if (match(str.c_str(), this->nick))
762                 return true;
763
764         return false;
765 }
766