00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include "inspircd.h"
00015 #include "m_regex.h"
00016 #include "xline.h"
00017
00018 static Module* rxengine = NULL;
00019 static Module* mymodule = NULL;
00020
00021
00022
00023 class RLine : public XLine
00024 {
00025 public:
00026
00035 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, "R")
00036 {
00037 matchtext = regexs;
00038
00039 if (!rxengine)
00040 {
00041 ServerInstance->SNO->WriteToSnoMask('x', "Cannot create regexes until engine is set to a loaded provider!");
00042 throw ModuleException("Regex engine not set or loaded!");
00043 }
00044
00045
00046
00047
00048 regex = RegexFactoryRequest(mymodule, rxengine, regexs).Create();
00049 }
00050
00053 ~RLine()
00054 {
00055 delete regex;
00056 }
00057
00058 bool Matches(User *u)
00059 {
00060 std::string compare = u->nick + "!" + u->ident + "@" + u->host + " " + u->fullname;
00061 return regex->Matches(compare);
00062 }
00063
00064 bool Matches(const std::string &compare)
00065 {
00066 return regex->Matches(compare);
00067 }
00068
00069 void Apply(User* u)
00070 {
00071 DefaultApply(u, "R", true);
00072 }
00073
00074 void DisplayExpiry()
00075 {
00076 ServerInstance->SNO->WriteToSnoMask('x',"Expiring timed R-Line %s (set by %s %ld seconds ago)", this->matchtext.c_str(), this->source, this->duration);
00077 }
00078
00079 const char* Displayable()
00080 {
00081 return matchtext.c_str();
00082 }
00083
00084 std::string matchtext;
00085
00086 Regex *regex;
00087 };
00088
00089
00092 class RLineFactory : public XLineFactory
00093 {
00094 public:
00095 RLineFactory(InspIRCd* Instance) : XLineFactory(Instance, "R")
00096 {
00097 }
00098
00101 XLine* Generate(time_t set_time, long duration, const char* source, const char* reason, const char* xline_specific_mask)
00102 {
00103 return new RLine(ServerInstance, set_time, duration, source, reason, xline_specific_mask);
00104 }
00105
00106 ~RLineFactory()
00107 {
00108 }
00109 };
00110
00114 class CommandRLine : public Command
00115 {
00116 std::string rxengine;
00117
00118 public:
00119 CommandRLine (InspIRCd* Instance) : Command(Instance,"RLINE", "o", 1, 3)
00120 {
00121 this->source = "m_rline.so";
00122 this->syntax = "<regex> [<rline-duration>] :<reason>";
00123 }
00124
00125 CmdResult Handle (const std::vector<std::string>& parameters, User *user)
00126 {
00127
00128 if (parameters.size() >= 3)
00129 {
00130
00131
00132 long duration = ServerInstance->Duration(parameters[1]);
00133 RLine *r = NULL;
00134
00135 try
00136 {
00137 r = new RLine(ServerInstance, ServerInstance->Time(), duration, user->nick.c_str(), parameters[2].c_str(), parameters[0].c_str());
00138 }
00139 catch (ModuleException &e)
00140 {
00141 ServerInstance->SNO->WriteToSnoMask('x',"Could not add RLINE: %s", e.GetReason());
00142 }
00143
00144 if (r)
00145 {
00146 if (ServerInstance->XLines->AddLine(r, user))
00147 {
00148 if (!duration)
00149 {
00150 ServerInstance->SNO->WriteToSnoMask('x',"%s added permanent R-Line for %s: %s", user->nick.c_str(), parameters[0].c_str(), parameters[2].c_str());
00151 }
00152 else
00153 {
00154 time_t c_requires_crap = duration + ServerInstance->Time();
00155 ServerInstance->SNO->WriteToSnoMask('x', "%s added timed R-Line for %s, expires on %s: %s", user->nick.c_str(), parameters[0].c_str(), ServerInstance->TimeString(c_requires_crap).c_str(), parameters[2].c_str());
00156 }
00157
00158 ServerInstance->XLines->ApplyLines();
00159 }
00160 else
00161 {
00162 delete r;
00163 user->WriteServ("NOTICE %s :*** R-Line for %s already exists", user->nick.c_str(), parameters[0].c_str());
00164 }
00165 }
00166 }
00167 else
00168 {
00169 if (ServerInstance->XLines->DelLine(parameters[0].c_str(), "R", user))
00170 {
00171 ServerInstance->SNO->WriteToSnoMask('x',"%s Removed R-Line on %s.",user->nick.c_str(),parameters[0].c_str());
00172 }
00173 else
00174 {
00175 user->WriteServ("NOTICE %s :*** R-Line %s not found in list, try /stats R.",user->nick.c_str(),parameters[0].c_str());
00176 }
00177 }
00178
00179 return CMD_SUCCESS;
00180 }
00181 };
00182
00183 class ModuleRLine : public Module
00184 {
00185 private:
00186 CommandRLine *r;
00187 RLineFactory *f;
00188 bool MatchOnNickChange;
00189 std::string RegexEngine;
00190
00191 public:
00192 ModuleRLine(InspIRCd* Me) : Module(Me)
00193 {
00194 mymodule = this;
00195 OnRehash(NULL, "");
00196
00197 Me->Modules->UseInterface("RegularExpression");
00198
00199
00200 r = new CommandRLine(ServerInstance);
00201 ServerInstance->AddCommand(r);
00202
00203 f = new RLineFactory(ServerInstance);
00204 ServerInstance->XLines->RegisterFactory(f);
00205
00206 Implementation eventlist[] = { I_OnUserConnect, I_OnRehash, I_OnUserPostNick, I_OnLoadModule, I_OnStats };
00207 ServerInstance->Modules->Attach(eventlist, this, 5);
00208
00209 }
00210
00211 virtual ~ModuleRLine()
00212 {
00213 ServerInstance->Modules->DoneWithInterface("RegularExpression");
00214 ServerInstance->XLines->DelAll("R");
00215 ServerInstance->XLines->UnregisterFactory(f);
00216 }
00217
00218 virtual Version GetVersion()
00219 {
00220 return Version("$Id: m_rline.cpp 10741 2008-10-28 16:11:20Z w00t $", VF_COMMON | VF_VENDOR, API_VERSION);
00221 }
00222
00223 virtual void OnUserConnect(User* user)
00224 {
00225
00226 XLine *rl = ServerInstance->XLines->MatchesLine("R", user);
00227
00228 if (rl)
00229 {
00230
00231 rl->Apply(user);
00232 }
00233 }
00234
00235 virtual void OnRehash(User *user, const std::string ¶meter)
00236 {
00237 ConfigReader Conf(ServerInstance);
00238
00239 MatchOnNickChange = Conf.ReadFlag("rline", "matchonnickchange", 0);
00240 std::string newrxengine = Conf.ReadValue("rline", "engine", 0);
00241
00242 if (!RegexEngine.empty())
00243 {
00244 if (RegexEngine == newrxengine)
00245 return;
00246
00247 ServerInstance->SNO->WriteToSnoMask('x', "Dumping all R-Lines due to regex engine change (was '%s', now '%s')", RegexEngine.c_str(), newrxengine.c_str());
00248 ServerInstance->XLines->DelAll("R");
00249 }
00250 rxengine = 0;
00251 RegexEngine = newrxengine;
00252 modulelist* ml = ServerInstance->Modules->FindInterface("RegularExpression");
00253 if (ml)
00254 {
00255 for (modulelist::iterator i = ml->begin(); i != ml->end(); ++i)
00256 {
00257 if (RegexNameRequest(this, *i).Send() == newrxengine)
00258 {
00259 ServerInstance->SNO->WriteToSnoMask('x', "R-Line now using engine '%s'", RegexEngine.c_str());
00260 rxengine = *i;
00261 }
00262 }
00263 }
00264 if (!rxengine)
00265 {
00266 ServerInstance->SNO->WriteToSnoMask('x', "WARNING: Regex engine '%s' is not loaded - R-Line functionality disabled until this is corrected.", RegexEngine.c_str());
00267 }
00268 }
00269
00270 virtual int OnStats(char symbol, User* user, string_list &results)
00271 {
00272 if (symbol != 'R')
00273 return 0;
00274
00275 ServerInstance->XLines->InvokeStats("R", 223, user, results);
00276 return 1;
00277 }
00278
00279 virtual void OnLoadModule(Module* mod, const std::string& name)
00280 {
00281 if (ServerInstance->Modules->ModuleHasInterface(mod, "RegularExpression"))
00282 {
00283 std::string rxname = RegexNameRequest(this, mod).Send();
00284 if (rxname == RegexEngine)
00285 {
00286 ServerInstance->SNO->WriteToSnoMask('x', "R-Line now using engine '%s'", RegexEngine.c_str());
00287 rxengine = mod;
00288 }
00289 }
00290 }
00291
00292 virtual void OnUserPostNick(User *user, const std::string &oldnick)
00293 {
00294 if (!IS_LOCAL(user))
00295 return;
00296
00297 if (!MatchOnNickChange)
00298 return;
00299
00300 XLine *rl = ServerInstance->XLines->MatchesLine("R", user);
00301
00302 if (rl)
00303 {
00304
00305 rl->Apply(user);
00306 }
00307 }
00308
00309 };
00310
00311 MODULE_INIT(ModuleRLine)
00312