diff options
Diffstat (limited to 'src/modules/m_callerid.cpp')
-rw-r--r-- | src/modules/m_callerid.cpp | 185 |
1 files changed, 92 insertions, 93 deletions
diff --git a/src/modules/m_callerid.cpp b/src/modules/m_callerid.cpp index 37787b525..3d2394fb1 100644 --- a/src/modules/m_callerid.cpp +++ b/src/modules/m_callerid.cpp @@ -22,8 +22,6 @@ #include "inspircd.h" -/* $ModDesc: Implementation of callerid, usermode +g, /accept */ - class callerid_data { public: @@ -62,12 +60,20 @@ struct CallerIDExtInfo : public ExtensionItem std::string serialize(SerializeFormat format, const Extensible* container, void* item) const { - callerid_data* dat = static_cast<callerid_data*>(item); - return dat->ToString(format); + std::string ret; + if (format != FORMAT_NETWORK) + { + callerid_data* dat = static_cast<callerid_data*>(item); + ret = dat->ToString(format); + } + return ret; } void unserialize(SerializeFormat format, Extensible* container, const std::string& value) { + if (format == FORMAT_NETWORK) + return; + callerid_data* dat = new callerid_data; irc::commasepstream s(value); std::string tok; @@ -76,9 +82,6 @@ struct CallerIDExtInfo : public ExtensionItem while (s.GetToken(tok)) { - if (tok.empty()) - continue; - User *u = ServerInstance->FindNick(tok); if ((u) && (u->registered == REG_ALL) && (!u->quitting) && (!IS_SERVER(u))) { @@ -117,7 +120,7 @@ struct CallerIDExtInfo : public ExtensionItem if (!targ) { - ServerInstance->Logs->Log("m_callerid", DEFAULT, "ERROR: Inconsistency detected in callerid state, please report (1)"); + ServerInstance->Logs->Log(MODNAME, LOG_DEFAULT, "ERROR: Inconsistency detected in callerid state, please report (1)"); continue; // shouldn't happen, but oh well. } @@ -125,7 +128,7 @@ struct CallerIDExtInfo : public ExtensionItem if (it2 != targ->wholistsme.end()) targ->wholistsme.erase(it2); else - ServerInstance->Logs->Log("m_callerid", DEFAULT, "ERROR: Inconsistency detected in callerid state, please report (2)"); + ServerInstance->Logs->Log(MODNAME, LOG_DEFAULT, "ERROR: Inconsistency detected in callerid state, please report (2)"); } delete dat; } @@ -139,6 +142,23 @@ public: class CommandAccept : public Command { + /** Pair: first is the target, second is true to add, false to remove + */ + typedef std::pair<User*, bool> ACCEPTAction; + + ACCEPTAction GetTargetAndAction(std::string& tok) + { + bool remove = (tok[0] == '-'); + if ((remove) || (tok[0] == '+')) + tok.erase(tok.begin()); + + User* target = ServerInstance->FindNick(tok); + if ((!target) || (target->registered != REG_ALL) || (target->quitting) || (IS_SERVER(target))) + target = NULL; + + return std::make_pair(target, !remove); + } + public: CallerIDExtInfo extInfo; unsigned int maxaccepts; @@ -147,39 +167,21 @@ public: { allow_empty_last_param = false; syntax = "{[+|-]<nicks>}|*}"; - TRANSLATE2(TR_CUSTOM, TR_END); + TRANSLATE1(TR_CUSTOM); } - virtual void EncodeParameter(std::string& parameter, int index) + void EncodeParameter(std::string& parameter, int index) { - if (index != 0) + // Send lists as-is (part of 2.0 compat) + if (parameter.find(',') != std::string::npos) return; - std::string out; - irc::commasepstream nicks(parameter); - std::string tok; - while (nicks.GetToken(tok)) - { - if (tok == "*") - { - continue; // Drop list requests, since remote servers ignore them anyway. - } - if (!out.empty()) - out.append(","); - bool dash = false; - if (tok[0] == '-') - { - dash = true; - tok.erase(0, 1); // Remove the dash. - } - User* u = ServerInstance->FindNick(tok); - if ((!u) || (u->registered != REG_ALL) || (u->quitting) || (IS_SERVER(u))) - continue; - if (dash) - out.append("-"); - out.append(u->uuid); - } - parameter = out; + // Convert a [+|-]<nick> into a [-]<uuid> + ACCEPTAction action = GetTargetAndAction(parameter); + if (!action.first) + return; + + parameter = (action.second ? "" : "-") + action.first->uuid; } /** Will take any number of nicks (up to MaxTargets), which can be seperated by commas. @@ -189,43 +191,58 @@ public: */ CmdResult Handle(const std::vector<std::string> ¶meters, User* user) { - if (ServerInstance->Parser->LoopCall(user, this, parameters, 0)) + if (CommandParser::LoopCall(user, this, parameters, 0)) return CMD_SUCCESS; + /* Even if callerid mode is not set, we let them manage their ACCEPT list so that if they go +g they can * have a list already setup. */ - std::string tok = parameters[0]; - - if (tok == "*") + if (parameters[0] == "*") { - if (IS_LOCAL(user)) - ListAccept(user); + ListAccept(user); return CMD_SUCCESS; } - else if (tok[0] == '-') + + std::string tok = parameters[0]; + ACCEPTAction action = GetTargetAndAction(tok); + if (!action.first) { - User* whotoremove = ServerInstance->FindNick(tok.substr(1)); - if (whotoremove) - return (RemoveAccept(user, whotoremove) ? CMD_SUCCESS : CMD_FAILURE); - else - return CMD_FAILURE; + user->WriteNumeric(401, "%s %s :No such nick/channel", user->nick.c_str(), tok.c_str()); + return CMD_FAILURE; } + + if ((!IS_LOCAL(user)) && (!IS_LOCAL(action.first))) + // Neither source nor target is local, forward the command to the server of target + return CMD_SUCCESS; + + // The second item in the pair is true if the first char is a '+' (or nothing), false if it's a '-' + if (action.second) + return (AddAccept(user, action.first) ? CMD_SUCCESS : CMD_FAILURE); else - { - User* whotoadd = ServerInstance->FindNick(tok[0] == '+' ? tok.substr(1) : tok); - if ((whotoadd) && (whotoadd->registered == REG_ALL) && (!whotoadd->quitting) && (!IS_SERVER(whotoadd))) - return (AddAccept(user, whotoadd) ? CMD_SUCCESS : CMD_FAILURE); - else - { - user->WriteNumeric(401, "%s %s :No such nick/channel", user->nick.c_str(), tok.c_str()); - return CMD_FAILURE; - } - } + return (RemoveAccept(user, action.first) ? CMD_SUCCESS : CMD_FAILURE); } RouteDescriptor GetRouting(User* user, const std::vector<std::string>& parameters) { - return ROUTE_BROADCAST; + // There is a list in parameters[0] in two cases: + // Either when the source is remote, this happens because 2.0 servers send comma seperated uuid lists, + // we don't split those but broadcast them, as before. + // + // Or if the source is local then LoopCall() runs OnPostCommand() after each entry in the list, + // meaning the linking module has sent an ACCEPT already for each entry in the list to the + // appropiate server and the ACCEPT with the list of nicks (this) doesn't need to be sent anywhere. + if ((!IS_LOCAL(user)) && (parameters[0].find(',') != std::string::npos)) + return ROUTE_BROADCAST; + + // Find the target + std::string targetstring = parameters[0]; + ACCEPTAction action = GetTargetAndAction(targetstring); + if (!action.first) + // Target is a "*" or source is local and the target is a list of nicks + return ROUTE_LOCALONLY; + + // Route to the server of the target + return ROUTE_UNICAST(action.first->server); } void ListAccept(User* user) @@ -258,7 +275,7 @@ public: callerid_data *targ = extInfo.get(whotoadd, true); targ->wholistsme.push_back(dat); - user->WriteServ("NOTICE %s :%s is now on your accept list", user->nick.c_str(), whotoadd->nick.c_str()); + user->WriteNotice(whotoadd->nick + " is now on your accept list"); return true; } @@ -285,7 +302,7 @@ public: if (!dat2) { // How the fuck is this possible. - ServerInstance->Logs->Log("m_callerid", DEFAULT, "ERROR: Inconsistency detected in callerid state, please report (3)"); + ServerInstance->Logs->Log(MODNAME, LOG_DEFAULT, "ERROR: Inconsistency detected in callerid state, please report (3)"); return false; } @@ -294,17 +311,16 @@ public: // Found me! dat2->wholistsme.erase(it); else - ServerInstance->Logs->Log("m_callerid", DEFAULT, "ERROR: Inconsistency detected in callerid state, please report (4)"); + ServerInstance->Logs->Log(MODNAME, LOG_DEFAULT, "ERROR: Inconsistency detected in callerid state, please report (4)"); - user->WriteServ("NOTICE %s :%s is no longer on your accept list", user->nick.c_str(), whotoremove->nick.c_str()); + user->WriteNotice(whotoremove->nick + " is no longer on your accept list"); return true; } }; class ModuleCallerID : public Module { -private: CommandAccept cmd; User_g myumode; @@ -334,7 +350,7 @@ private: if (it2 != dat->accepting.end()) dat->accepting.erase(it2); else - ServerInstance->Logs->Log("m_callerid", DEFAULT, "ERROR: Inconsistency detected in callerid state, please report (5)"); + ServerInstance->Logs->Log(MODNAME, LOG_DEFAULT, "ERROR: Inconsistency detected in callerid state, please report (5)"); } userdata->wholistsme.clear(); @@ -345,38 +361,31 @@ public: { } - void init() + void init() CXX11_OVERRIDE { OnRehash(NULL); ServerInstance->Modules->AddService(myumode); ServerInstance->Modules->AddService(cmd); ServerInstance->Modules->AddService(cmd.extInfo); - - Implementation eventlist[] = { I_OnRehash, I_OnUserPostNick, I_OnUserQuit, I_On005Numeric, I_OnUserPreNotice, I_OnUserPreMessage }; - ServerInstance->Modules->Attach(eventlist, this, sizeof(eventlist)/sizeof(Implementation)); } - virtual ~ModuleCallerID() - { - } - - virtual Version GetVersion() + Version GetVersion() CXX11_OVERRIDE { return Version("Implementation of callerid, usermode +g, /accept", VF_COMMON | VF_VENDOR); } - virtual void On005Numeric(std::string& output) + void On005Numeric(std::map<std::string, std::string>& tokens) CXX11_OVERRIDE { - output += " CALLERID=g"; + tokens["CALLERID"] = "g"; } ModResult PreText(User* user, User* dest, std::string& text) { - if (!dest->IsModeSet('g') || (user == dest)) + if (!dest->IsModeSet(myumode) || (user == dest)) return MOD_RES_PASSTHRU; - if (operoverride && IS_OPER(user)) + if (operoverride && user->IsOper()) return MOD_RES_PASSTHRU; callerid_data* dat = cmd.extInfo.get(dest, true); @@ -399,15 +408,7 @@ public: return MOD_RES_PASSTHRU; } - virtual ModResult OnUserPreMessage(User* user, void* dest, int target_type, std::string& text, char status, CUList &exempt_list) - { - if (IS_LOCAL(user) && target_type == TYPE_USER) - return PreText(user, (User*)dest, text); - - return MOD_RES_PASSTHRU; - } - - virtual ModResult OnUserPreNotice(User* user, void* dest, int target_type, std::string& text, char status, CUList &exempt_list) + ModResult OnUserPreMessage(User* user, void* dest, int target_type, std::string& text, char status, CUList& exempt_list, MessageType msgtype) CXX11_OVERRIDE { if (IS_LOCAL(user) && target_type == TYPE_USER) return PreText(user, (User*)dest, text); @@ -415,18 +416,18 @@ public: return MOD_RES_PASSTHRU; } - void OnUserPostNick(User* user, const std::string& oldnick) + void OnUserPostNick(User* user, const std::string& oldnick) CXX11_OVERRIDE { if (!tracknick) RemoveFromAllAccepts(user); } - void OnUserQuit(User* user, const std::string& message, const std::string& oper_message) + void OnUserQuit(User* user, const std::string& message, const std::string& oper_message) CXX11_OVERRIDE { RemoveFromAllAccepts(user); } - virtual void OnRehash(User* user) + void OnRehash(User* user) CXX11_OVERRIDE { ConfigTag* tag = ServerInstance->Config->ConfValue("callerid"); cmd.maxaccepts = tag->getInt("maxaccepts", 16); @@ -437,5 +438,3 @@ public: }; MODULE_INIT(ModuleCallerID) - - |