diff options
-rw-r--r-- | include/ctables.h | 6 | ||||
-rw-r--r-- | src/modules/m_sasl.cpp | 2 | ||||
-rw-r--r-- | src/modules/m_showwhois.cpp | 1 | ||||
-rw-r--r-- | src/modules/m_spanningtree/commands.h | 95 | ||||
-rw-r--r-- | src/modules/m_spanningtree/fhost.cpp | 37 | ||||
-rw-r--r-- | src/modules/m_spanningtree/fident.cpp | 37 | ||||
-rw-r--r-- | src/modules/m_spanningtree/fjoin.cpp | 31 | ||||
-rw-r--r-- | src/modules/m_spanningtree/fmode.cpp | 26 | ||||
-rw-r--r-- | src/modules/m_spanningtree/fname.cpp | 37 | ||||
-rw-r--r-- | src/modules/m_spanningtree/ftopic.cpp | 27 | ||||
-rw-r--r-- | src/modules/m_spanningtree/main.cpp | 43 | ||||
-rw-r--r-- | src/modules/m_spanningtree/main.h | 17 | ||||
-rw-r--r-- | src/modules/m_spanningtree/metadata.cpp | 53 | ||||
-rw-r--r-- | src/modules/m_spanningtree/opertype.cpp | 65 | ||||
-rw-r--r-- | src/modules/m_spanningtree/treeserver.h | 2 | ||||
-rw-r--r-- | src/modules/m_spanningtree/treesocket.h | 37 | ||||
-rw-r--r-- | src/modules/m_spanningtree/treesocket2.cpp | 38 | ||||
-rw-r--r-- | src/modules/m_spanningtree/uid.cpp | 121 |
18 files changed, 270 insertions, 405 deletions
diff --git a/include/ctables.h b/include/ctables.h index badcd1fde..9c2a6181c 100644 --- a/include/ctables.h +++ b/include/ctables.h @@ -20,9 +20,13 @@ enum CmdResult { CMD_FAILURE = 0, /* Command exists, but failed */ CMD_SUCCESS = 1, /* Command exists, and succeeded */ - CMD_INVALID = 2 /* Command doesnt exist at all! */ + CMD_INVALID = 2, /* Command doesnt exist at all! */ + CMD_EPERM = 3 /* Command failed because of a permission check */ }; +/** Flag for commands that are only allowed from servers */ +const char FLAG_SERVERONLY = 7; // technically anything nonzero below 'A' works + /** Translation types for translation of parameters to UIDs. * This allows the core commands to not have to be aware of how UIDs * work (making it still possible to write other linking modules which diff --git a/src/modules/m_sasl.cpp b/src/modules/m_sasl.cpp index c35c38d2d..28a583c80 100644 --- a/src/modules/m_sasl.cpp +++ b/src/modules/m_sasl.cpp @@ -185,7 +185,7 @@ class CommandSASL : public Command SimpleExtItem<SaslAuthenticator>& authExt; CommandSASL(Module* Creator, SimpleExtItem<SaslAuthenticator>& ext) : Command(Creator, "SASL", 2), authExt(ext) { - this->disabled = true; // should not be called by users + this->flags_needed = FLAG_SERVERONLY; // should not be called by users } CmdResult Handle(const std::vector<std::string>& parameters, User *user) diff --git a/src/modules/m_showwhois.cpp b/src/modules/m_showwhois.cpp index 2b27de388..2d65d1669 100644 --- a/src/modules/m_showwhois.cpp +++ b/src/modules/m_showwhois.cpp @@ -53,6 +53,7 @@ class WhoisNoticeCmd : public Command public: WhoisNoticeCmd(Module* Creator) : Command(Creator,"WHOISNOTICE", 1) { + flags_needed = FLAG_SERVERONLY; } void HandleFast(User* dest, User* src) diff --git a/src/modules/m_spanningtree/commands.h b/src/modules/m_spanningtree/commands.h index 0eb90efb8..eebfd88d3 100644 --- a/src/modules/m_spanningtree/commands.h +++ b/src/modules/m_spanningtree/commands.h @@ -14,6 +14,8 @@ #ifndef __COMMANDS_H__ #define __COMMANDS_H__ +#include "main.h" + /** Handle /RCONNECT */ class CommandRConnect : public Command @@ -38,23 +40,110 @@ class CommandRSQuit : public Command class CommandSVSJoin : public Command { public: - CommandSVSJoin(Module* Creator) : Command(Creator, "SVSJOIN", 2) { flags_needed = 'o'; } + CommandSVSJoin(Module* Creator) : Command(Creator, "SVSJOIN", 2) { flags_needed = FLAG_SERVERONLY; } CmdResult Handle (const std::vector<std::string>& parameters, User *user); RouteDescriptor GetRouting(User* user, const std::vector<std::string>& parameters); }; class CommandSVSPart : public Command { public: - CommandSVSPart(Module* Creator) : Command(Creator, "SVSPART", 2) { flags_needed = 'o'; } + CommandSVSPart(Module* Creator) : Command(Creator, "SVSPART", 2) { flags_needed = FLAG_SERVERONLY; } CmdResult Handle (const std::vector<std::string>& parameters, User *user); RouteDescriptor GetRouting(User* user, const std::vector<std::string>& parameters); }; class CommandSVSNick : public Command { public: - CommandSVSNick(Module* Creator) : Command(Creator, "SVSNICK", 2) { flags_needed = 'o'; } + CommandSVSNick(Module* Creator) : Command(Creator, "SVSNICK", 2) { flags_needed = FLAG_SERVERONLY; } + CmdResult Handle (const std::vector<std::string>& parameters, User *user); + RouteDescriptor GetRouting(User* user, const std::vector<std::string>& parameters); +}; +class CommandMetadata : public Command +{ + public: + CommandMetadata(Module* Creator) : Command(Creator, "METADATA", 2) { flags_needed = FLAG_SERVERONLY; } + CmdResult Handle (const std::vector<std::string>& parameters, User *user); + RouteDescriptor GetRouting(User* user, const std::vector<std::string>& parameters); +}; +class CommandUID : public Command +{ + public: + CommandUID(Module* Creator) : Command(Creator, "UID", 10) { flags_needed = FLAG_SERVERONLY; } + CmdResult Handle (const std::vector<std::string>& parameters, User *user); + RouteDescriptor GetRouting(User* user, const std::vector<std::string>& parameters); +}; +class CommandOpertype : public Command +{ + public: + CommandOpertype(Module* Creator) : Command(Creator, "OPERTYPE", 1) { flags_needed = FLAG_SERVERONLY; } + CmdResult Handle (const std::vector<std::string>& parameters, User *user); + RouteDescriptor GetRouting(User* user, const std::vector<std::string>& parameters); +}; +class CommandFJoin : public Command +{ + public: + CommandFJoin(Module* Creator) : Command(Creator, "FJOIN", 3) { flags_needed = FLAG_SERVERONLY; } + CmdResult Handle (const std::vector<std::string>& parameters, User *user); + RouteDescriptor GetRouting(User* user, const std::vector<std::string>& parameters); + /** Remove all modes from a channel, including statusmodes (+qaovh etc), simplemodes, parameter modes. + * This does not update the timestamp of the target channel, this must be done seperately. + */ + void RemoveStatus(User* source, parameterlist ¶ms); +}; +class CommandFMode : public Command +{ + public: + CommandFMode(Module* Creator) : Command(Creator, "FMODE", 3) { flags_needed = FLAG_SERVERONLY; } CmdResult Handle (const std::vector<std::string>& parameters, User *user); RouteDescriptor GetRouting(User* user, const std::vector<std::string>& parameters); }; +class CommandFTopic : public Command +{ + public: + CommandFTopic(Module* Creator) : Command(Creator, "FTOPIC", 4) { flags_needed = FLAG_SERVERONLY; } + CmdResult Handle (const std::vector<std::string>& parameters, User *user); + RouteDescriptor GetRouting(User* user, const std::vector<std::string>& parameters); +}; +class CommandFHost : public Command +{ + public: + CommandFHost(Module* Creator) : Command(Creator, "FHOST", 1) { flags_needed = FLAG_SERVERONLY; } + CmdResult Handle (const std::vector<std::string>& parameters, User *user); + RouteDescriptor GetRouting(User* user, const std::vector<std::string>& parameters); +}; +class CommandFIdent : public Command +{ + public: + CommandFIdent(Module* Creator) : Command(Creator, "FIDENT", 1) { flags_needed = FLAG_SERVERONLY; } + CmdResult Handle (const std::vector<std::string>& parameters, User *user); + RouteDescriptor GetRouting(User* user, const std::vector<std::string>& parameters); +}; +class CommandFName : public Command +{ + public: + CommandFName(Module* Creator) : Command(Creator, "FNAME", 1) { flags_needed = FLAG_SERVERONLY; } + CmdResult Handle (const std::vector<std::string>& parameters, User *user); + RouteDescriptor GetRouting(User* user, const std::vector<std::string>& parameters); +}; + +class SpanningTreeCommands +{ + public: + CommandRConnect rconnect; + CommandRSQuit rsquit; + CommandSVSJoin svsjoin; + CommandSVSPart svspart; + CommandSVSNick svsnick; + CommandMetadata metadata; + CommandUID uid; + CommandOpertype opertype; + CommandFJoin fjoin; + CommandFMode fmode; + CommandFTopic ftopic; + CommandFHost fhost; + CommandFIdent fident; + CommandFName fname; + SpanningTreeCommands(ModuleSpanningTree* module); +}; #endif diff --git a/src/modules/m_spanningtree/fhost.cpp b/src/modules/m_spanningtree/fhost.cpp deleted file mode 100644 index 20e6ebfc4..000000000 --- a/src/modules/m_spanningtree/fhost.cpp +++ /dev/null @@ -1,37 +0,0 @@ -/* +------------------------------------+ - * | Inspire Internet Relay Chat Daemon | - * +------------------------------------+ - * - * InspIRCd: (C) 2002-2010 InspIRCd Development Team - * See: http://wiki.inspircd.org/Credits - * - * This program is free but copyrighted software; see - * the file COPYING for details. - * - * --------------------------------------------------- - */ - -#include "inspircd.h" -#include "xline.h" - -#include "treesocket.h" -#include "treeserver.h" -#include "utils.h" - -/* $ModDep: m_spanningtree/utils.h m_spanningtree/treeserver.h m_spanningtree/treesocket.h */ - - -bool TreeSocket::ChangeHost(const std::string &prefix, parameterlist ¶ms) -{ - if (params.size() < 1) - return true; - User* u = ServerInstance->FindNick(prefix); - - if (u) - { - u->ChangeDisplayedHost(params[0].c_str()); - Utils->DoOneToAllButSender(prefix,"FHOST",params,u->server); - } - return true; -} - diff --git a/src/modules/m_spanningtree/fident.cpp b/src/modules/m_spanningtree/fident.cpp deleted file mode 100644 index ddf4a99c5..000000000 --- a/src/modules/m_spanningtree/fident.cpp +++ /dev/null @@ -1,37 +0,0 @@ -/* +------------------------------------+ - * | Inspire Internet Relay Chat Daemon | - * +------------------------------------+ - * - * InspIRCd: (C) 2002-2010 InspIRCd Development Team - * See: http://wiki.inspircd.org/Credits - * - * This program is free but copyrighted software; see - * the file COPYING for details. - * - * --------------------------------------------------- - */ - -#include "inspircd.h" -#include "xline.h" - -#include "treesocket.h" -#include "treeserver.h" -#include "utils.h" - -/* $ModDep: m_spanningtree/utils.h m_spanningtree/treeserver.h m_spanningtree/treesocket.h */ - - -bool TreeSocket::ChangeIdent(const std::string &prefix, parameterlist ¶ms) -{ - if (params.size() < 1) - return true; - User* u = ServerInstance->FindNick(prefix); - if (u) - { - u->ChangeIdent(params[0].c_str()); - params[0] = ":" + params[0]; - Utils->DoOneToAllButSender(prefix,"FIDENT",params,u->server); - } - return true; -} - diff --git a/src/modules/m_spanningtree/fjoin.cpp b/src/modules/m_spanningtree/fjoin.cpp index f0606e3b2..be32410ef 100644 --- a/src/modules/m_spanningtree/fjoin.cpp +++ b/src/modules/m_spanningtree/fjoin.cpp @@ -12,18 +12,14 @@ */ #include "inspircd.h" -#include "xline.h" - -#include "treesocket.h" +#include "commands.h" #include "treeserver.h" -#include "utils.h" - -/* $ModDep: m_spanningtree/utils.h m_spanningtree/treeserver.h m_spanningtree/treesocket.h */ - +#include "treesocket.h" /** FJOIN, almost identical to TS6 SJOIN, except for nicklist handling. */ -void TreeSocket::ForceJoin(User* srcuser, parameterlist ¶ms) +CmdResult CommandFJoin::Handle(const std::vector<std::string>& params, User *srcuser) { + SpanningTreeUtilities* Utils = ((ModuleSpanningTree*)(Module*)creator)->Utils; /* 1.1 FJOIN works as follows: * * Each FJOIN is sent along with a timestamp, and the side with the lowest @@ -51,7 +47,7 @@ void TreeSocket::ForceJoin(User* srcuser, parameterlist ¶ms) * who succeed at internets. :-) */ if (params.size() < 3) - return; + return CMD_INVALID; irc::modestacker modestack(true); /* Modes to apply from the users in the user list */ User* who = NULL; /* User we are currently checking */ @@ -63,16 +59,13 @@ void TreeSocket::ForceJoin(User* srcuser, parameterlist ¶ms) bool created = !chan; /* True if the channel doesnt exist here yet */ std::string item; /* One item in the list of nicks */ - if (params.size() > 3) - params[params.size() - 1] = ":" + params[params.size() - 1]; - - Utils->DoOneToAllButSender(srcuser->server,"FJOIN",params,srcuser->server); + TreeSocket* src_socket = Utils->FindServer(srcuser->server)->GetRoute()->GetSocket(); if (!TS) { ServerInstance->Logs->Log("m_spanningtree",DEFAULT,"*** BUG? *** TS of 0 sent to FJOIN. Are some services authors smoking craq, or is it 1970 again?. Dropped."); ServerInstance->SNO->WriteToSnoMask('d', "WARNING: The server %s is sending FJOIN with a TS of zero. Total craq. Command was dropped.", srcuser->server.c_str()); - return; + return CMD_INVALID; } if (created) @@ -143,10 +136,7 @@ void TreeSocket::ForceJoin(User* srcuser, parameterlist ¶ms) if (mh) modes += *unparsedmodes; else - { - this->SendError(std::string("Unknown status mode '")+(*unparsedmodes)+"' in FJOIN"); - return; - } + return CMD_INVALID; usr++; unparsedmodes++; @@ -161,7 +151,7 @@ void TreeSocket::ForceJoin(User* srcuser, parameterlist ¶ms) { /* Check that the user's 'direction' is correct */ TreeServer* route_back_again = Utils->BestRouteTo(who->server); - if ((!route_back_again) || (route_back_again->GetSocket() != this)) + if ((!route_back_again) || (route_back_again->GetSocket() != src_socket)) continue; /* Add any modes this user had to the mode stack */ @@ -190,9 +180,10 @@ void TreeSocket::ForceJoin(User* srcuser, parameterlist ¶ms) stackresult.erase(stackresult.begin() + 1, stackresult.end()); } } + return CMD_SUCCESS; } -void TreeSocket::RemoveStatus(User* srcuser, parameterlist ¶ms) +void CommandFJoin::RemoveStatus(User* srcuser, parameterlist ¶ms) { if (params.size() < 1) return; diff --git a/src/modules/m_spanningtree/fmode.cpp b/src/modules/m_spanningtree/fmode.cpp index 598c9ab9c..de7631c83 100644 --- a/src/modules/m_spanningtree/fmode.cpp +++ b/src/modules/m_spanningtree/fmode.cpp @@ -12,25 +12,15 @@ */ #include "inspircd.h" -#include "xline.h" +#include "commands.h" #include "treesocket.h" #include "treeserver.h" #include "utils.h" -/* $ModDep: m_spanningtree/utils.h m_spanningtree/treeserver.h m_spanningtree/treesocket.h */ - - /** FMODE command - server mode with timestamp checks */ -void TreeSocket::ForceMode(User* who, parameterlist ¶ms) +CmdResult CommandFMode::Handle(const std::vector<std::string>& params, User *who) { - /* Chances are this is a 1.0 FMODE without TS */ - if (params.size() < 3) - { - /* No modes were in the command, probably a channel with no modes set on it */ - return; - } - std::string sourceserv = who->server; std::vector<std::string> modelist; @@ -70,27 +60,27 @@ void TreeSocket::ForceMode(User* who, parameterlist ¶ms) } else /* Oops, channel doesnt exist! */ - return; + return CMD_FAILURE; } if (!TS) { ServerInstance->Logs->Log("m_spanningtree",DEFAULT,"*** BUG? *** TS of 0 sent to FMODE. Are some services authors smoking craq, or is it 1970 again?. Dropped."); ServerInstance->SNO->WriteToSnoMask('d', "WARNING: The server %s is sending FMODE with a TS of zero. Total craq. Mode was dropped.", sourceserv.c_str()); - return; + return CMD_INVALID; } /* TS is equal or less: Merge the mode changes into ours and pass on. */ if (TS <= ourTS) { - ServerInstance->Modes->Process(modelist, who, IS_SERVER(who)); - - /* HOT POTATO! PASS IT ON! */ - Utils->DoOneToAllButSender(sourceserv,"FMODE",params,sourceserv); + bool merge = (TS == ourTS) && IS_SERVER(who); + ServerInstance->Modes->Process(modelist, who, merge); + return CMD_SUCCESS; } /* If the TS is greater than ours, we drop the mode and dont pass it anywhere. */ + return CMD_FAILURE; } diff --git a/src/modules/m_spanningtree/fname.cpp b/src/modules/m_spanningtree/fname.cpp deleted file mode 100644 index fddd3dec1..000000000 --- a/src/modules/m_spanningtree/fname.cpp +++ /dev/null @@ -1,37 +0,0 @@ -/* +------------------------------------+ - * | Inspire Internet Relay Chat Daemon | - * +------------------------------------+ - * - * InspIRCd: (C) 2002-2010 InspIRCd Development Team - * See: http://wiki.inspircd.org/Credits - * - * This program is free but copyrighted software; see - * the file COPYING for details. - * - * --------------------------------------------------- - */ - -#include "inspircd.h" -#include "xline.h" - -#include "treesocket.h" -#include "treeserver.h" -#include "utils.h" - -/* $ModDep: m_spanningtree/utils.h m_spanningtree/treeserver.h m_spanningtree/treesocket.h */ - - -bool TreeSocket::ChangeName(const std::string &prefix, parameterlist ¶ms) -{ - if (params.size() < 1) - return true; - User* u = ServerInstance->FindNick(prefix); - if (u) - { - u->ChangeName(params[0].c_str()); - params[0] = ":" + params[0]; - Utils->DoOneToAllButSender(prefix,"FNAME",params,u->server); - } - return true; -} - diff --git a/src/modules/m_spanningtree/ftopic.cpp b/src/modules/m_spanningtree/ftopic.cpp index 0753fa17b..2413a67d3 100644 --- a/src/modules/m_spanningtree/ftopic.cpp +++ b/src/modules/m_spanningtree/ftopic.cpp @@ -12,20 +12,15 @@ */ #include "inspircd.h" -#include "xline.h" +#include "commands.h" #include "treesocket.h" #include "treeserver.h" #include "utils.h" -/* $ModDep: m_spanningtree/utils.h m_spanningtree/treeserver.h m_spanningtree/treesocket.h */ - - /** FTOPIC command */ -bool TreeSocket::ForceTopic(const std::string &source, parameterlist ¶ms) +CmdResult CommandFTopic::Handle(const std::vector<std::string>& params, User *user) { - if (params.size() != 4) - return true; time_t ts = atoi(params[1].c_str()); Channel* c = ServerInstance->FindChan(params[0]); if (c) @@ -34,30 +29,16 @@ bool TreeSocket::ForceTopic(const std::string &source, parameterlist ¶ms) { if (c->topic != params[3]) { - User* user = ServerInstance->FindNick(source); // Update topic only when it differs from current topic c->topic.assign(params[3], 0, ServerInstance->Config->Limits.MaxTopic); - if (!user) - { - std::string sourceserv = Utils->FindServer(source)->GetName(); - c->WriteChannelWithServ(sourceserv.c_str(), "TOPIC %s :%s", c->name.c_str(), c->topic.c_str()); - } - else - { - c->WriteChannel(user, "TOPIC %s :%s", c->name.c_str(), c->topic.c_str()); - } + c->WriteChannel(user, "TOPIC %s :%s", c->name.c_str(), c->topic.c_str()); } // Always update setter and settime. c->setby.assign(params[2], 0, 127); c->topicset = ts; - - /* all done, send it on its way */ - params[3] = ":" + params[3]; - Utils->DoOneToAllButSender(source,"FTOPIC",params,source); } - } - return true; + return CMD_SUCCESS; } diff --git a/src/modules/m_spanningtree/main.cpp b/src/modules/m_spanningtree/main.cpp index 18f399bbf..7ac67221b 100644 --- a/src/modules/m_spanningtree/main.cpp +++ b/src/modules/m_spanningtree/main.cpp @@ -30,17 +30,34 @@ ModuleSpanningTree::ModuleSpanningTree() { Utils = new SpanningTreeUtilities(this); - command_rconnect = new CommandRConnect(this, Utils); - command_rsquit = new CommandRSQuit(this, Utils); - command_svsjoin = new CommandSVSJoin(this); - command_svspart = new CommandSVSPart(this); - command_svsnick = new CommandSVSNick(this); + commands = new SpanningTreeCommands(this); +} + +SpanningTreeCommands::SpanningTreeCommands(ModuleSpanningTree* module) + : rconnect(module, module->Utils), rsquit(module, module->Utils), + svsjoin(module), svspart(module), svsnick(module), metadata(module), + uid(module), opertype(module), fjoin(module), fmode(module), ftopic(module), + fhost(module), fident(module), fname(module) +{ +} + +void ModuleSpanningTree::init() +{ RefreshTimer = new CacheRefreshTimer(Utils); - ServerInstance->AddCommand(command_rconnect); - ServerInstance->AddCommand(command_rsquit); - ServerInstance->AddCommand(command_svsjoin); - ServerInstance->AddCommand(command_svspart); - ServerInstance->AddCommand(command_svsnick); + ServerInstance->Modules->AddService(commands->rconnect); + ServerInstance->Modules->AddService(commands->rsquit); + ServerInstance->Modules->AddService(commands->svsjoin); + ServerInstance->Modules->AddService(commands->svspart); + ServerInstance->Modules->AddService(commands->svsnick); + ServerInstance->Modules->AddService(commands->metadata); + ServerInstance->Modules->AddService(commands->uid); + ServerInstance->Modules->AddService(commands->opertype); + ServerInstance->Modules->AddService(commands->fjoin); + ServerInstance->Modules->AddService(commands->fmode); + ServerInstance->Modules->AddService(commands->ftopic); + ServerInstance->Modules->AddService(commands->fhost); + ServerInstance->Modules->AddService(commands->fident); + ServerInstance->Modules->AddService(commands->fname); ServerInstance->Timers->AddTimer(RefreshTimer); Implementation eventlist[] = @@ -898,11 +915,7 @@ ModuleSpanningTree::~ModuleSpanningTree() /* This will also free the listeners */ delete Utils; - delete command_rconnect; - delete command_rsquit; - delete command_svsjoin; - delete command_svspart; - delete command_svsnick; + delete commands; } Version ModuleSpanningTree::GetVersion() diff --git a/src/modules/m_spanningtree/main.h b/src/modules/m_spanningtree/main.h index 3997c148c..b2bff960a 100644 --- a/src/modules/m_spanningtree/main.h +++ b/src/modules/m_spanningtree/main.h @@ -31,11 +31,7 @@ const long MinCompatProtocol = 1201; /** Forward declarations */ -class CommandRConnect; -class CommandRSQuit; -class CommandSVSJoin; -class CommandSVSPart; -class CommandSVSNick; +class SpanningTreeCommands; class SpanningTreeUtilities; class CacheRefreshTimer; class TreeServer; @@ -46,16 +42,12 @@ class Autoconnect; */ class ModuleSpanningTree : public Module { - CommandRConnect* command_rconnect; - CommandRSQuit* command_rsquit; - CommandSVSJoin* command_svsjoin; - CommandSVSPart* command_svspart; - CommandSVSNick* command_svsnick; - SpanningTreeUtilities* Utils; - + SpanningTreeCommands* commands; void RedoConfig(Module* mod); public: + SpanningTreeUtilities* Utils; + CacheRefreshTimer *RefreshTimer; /** Set to true if inside a spanningtree call, to prevent sending * xlines and other things back to their source @@ -65,6 +57,7 @@ class ModuleSpanningTree : public Module /** Constructor */ ModuleSpanningTree(); + void init(); /** Shows /LINKS */ diff --git a/src/modules/m_spanningtree/metadata.cpp b/src/modules/m_spanningtree/metadata.cpp index 70bd0539b..4760793cb 100644 --- a/src/modules/m_spanningtree/metadata.cpp +++ b/src/modules/m_spanningtree/metadata.cpp @@ -12,50 +12,41 @@ */ #include "inspircd.h" -#include "xline.h" +#include "commands.h" #include "treesocket.h" #include "treeserver.h" #include "utils.h" -bool TreeSocket::MetaData(const std::string &prefix, parameterlist ¶ms) +CmdResult CommandMetadata::Handle(const std::vector<std::string>& params, User *srcuser) { - if (params.size() < 2) - return true; - else if (params.size() < 3) - params.push_back(""); - TreeServer* ServerSource = Utils->FindServer(prefix); + std::string value = params.size() < 3 ? "" : params[2]; ExtensionItem* item = ServerInstance->Extensions.GetItem(params[1]); - if (ServerSource) + if (params[0] == "*") { - if (params[0] == "*") - { - FOREACH_MOD(I_OnDecodeMetaData,OnDecodeMetaData(NULL,params[1],params[2])); - } - else if (*(params[0].c_str()) == '#') + FOREACH_MOD(I_OnDecodeMetaData,OnDecodeMetaData(NULL,params[1],value)); + } + else if (*(params[0].c_str()) == '#') + { + Channel* c = ServerInstance->FindChan(params[0]); + if (c) { - Channel* c = ServerInstance->FindChan(params[0]); - if (c) - { - if (item) - item->unserialize(FORMAT_NETWORK, c, params[2]); - FOREACH_MOD(I_OnDecodeMetaData,OnDecodeMetaData(c,params[1],params[2])); - } + if (item) + item->unserialize(FORMAT_NETWORK, c, value); + FOREACH_MOD(I_OnDecodeMetaData,OnDecodeMetaData(c,params[1],value)); } - else if (*(params[0].c_str()) != '#') + } + else if (*(params[0].c_str()) != '#') + { + User* u = ServerInstance->FindNick(params[0]); + if (u) { - User* u = ServerInstance->FindNick(params[0]); - if (u) - { - if (item) - item->unserialize(FORMAT_NETWORK, u, params[2]); - FOREACH_MOD(I_OnDecodeMetaData,OnDecodeMetaData(u,params[1],params[2])); - } + if (item) + item->unserialize(FORMAT_NETWORK, u, value); + FOREACH_MOD(I_OnDecodeMetaData,OnDecodeMetaData(u,params[1],value)); } } - params[2] = ":" + params[2]; - Utils->DoOneToAllButSender(prefix,"METADATA",params,prefix); - return true; + return CMD_SUCCESS; } diff --git a/src/modules/m_spanningtree/opertype.cpp b/src/modules/m_spanningtree/opertype.cpp index cdc47861a..807a76d39 100644 --- a/src/modules/m_spanningtree/opertype.cpp +++ b/src/modules/m_spanningtree/opertype.cpp @@ -12,57 +12,46 @@ */ #include "inspircd.h" -#include "xline.h" - -#include "treesocket.h" +#include "commands.h" #include "treeserver.h" #include "utils.h" -/* $ModDep: m_spanningtree/utils.h m_spanningtree/treeserver.h m_spanningtree/treesocket.h */ - - /** Because the core won't let users or even SERVERS set +o, * we use the OPERTYPE command to do this. */ -bool TreeSocket::OperType(const std::string &prefix, parameterlist ¶ms) +CmdResult CommandOpertype::Handle(const std::vector<std::string>& params, User *u) { - if (params.size() != 1) - return true; + SpanningTreeUtilities* Utils = ((ModuleSpanningTree*)(Module*)creator)->Utils; std::string opertype = params[0]; - User* u = ServerInstance->FindNick(prefix); - if (u) + if (!IS_OPER(u)) + ServerInstance->Users->all_opers.push_back(u); + u->modes[UM_OPERATOR] = 1; + OperIndex::iterator iter = ServerInstance->Config->oper_blocks.find(" " + opertype); + if (iter != ServerInstance->Config->oper_blocks.end()) + u->oper = iter->second; + else { - if (!IS_OPER(u)) - ServerInstance->Users->all_opers.push_back(u); - u->modes[UM_OPERATOR] = 1; - OperIndex::iterator iter = ServerInstance->Config->oper_blocks.find(" " + opertype); - if (iter != ServerInstance->Config->oper_blocks.end()) - u->oper = iter->second; - else - { - u->oper = new OperInfo; - u->oper->name = opertype; - } - Utils->DoOneToAllButSender(u->uuid, "OPERTYPE", params, u->server); + u->oper = new OperInfo; + u->oper->name = opertype; + } - TreeServer* remoteserver = Utils->FindServer(u->server); - bool dosend = true; + TreeServer* remoteserver = Utils->FindServer(u->server); + bool dosend = true; - if (this->Utils->quiet_bursts) + if (Utils->quiet_bursts) + { + /* + * If quiet bursts are enabled, and server is bursting or silent uline (i.e. services), + * then do nothing. -- w00t + */ + if (remoteserver->bursting || ServerInstance->SilentULine(u->server)) { - /* - * If quiet bursts are enabled, and server is bursting or silent uline (i.e. services), - * then do nothing. -- w00t - */ - if (remoteserver->bursting || ServerInstance->SilentULine(u->server)) - { - dosend = false; - } + dosend = false; } - - if (dosend) - ServerInstance->SNO->WriteToSnoMask('O',"From %s: User %s (%s@%s) is now an IRC operator of type %s",u->server.c_str(), u->nick.c_str(),u->ident.c_str(), u->host.c_str(), irc::Spacify(opertype.c_str())); } - return true; + + if (dosend) + ServerInstance->SNO->WriteToSnoMask('O',"From %s: User %s (%s@%s) is now an IRC operator of type %s",u->server.c_str(), u->nick.c_str(),u->ident.c_str(), u->host.c_str(), irc::Spacify(opertype.c_str())); + return CMD_SUCCESS; } diff --git a/src/modules/m_spanningtree/treeserver.h b/src/modules/m_spanningtree/treeserver.h index 079b6535e..7eb19d9a1 100644 --- a/src/modules/m_spanningtree/treeserver.h +++ b/src/modules/m_spanningtree/treeserver.h @@ -14,6 +14,8 @@ #ifndef __TREESERVER_H__ #define __TREESERVER_H__ +#include "treesocket.h" + /** Each server in the tree is represented by one class of * type TreeServer. A locally connected TreeServer can * have a class of type TreeSocket associated with it, for diff --git a/src/modules/m_spanningtree/treesocket.h b/src/modules/m_spanningtree/treesocket.h index bc51f3277..c1678ea5e 100644 --- a/src/modules/m_spanningtree/treesocket.h +++ b/src/modules/m_spanningtree/treesocket.h @@ -214,21 +214,9 @@ class TreeSocket : public BufferedSocket */ void Squit(TreeServer* Current, const std::string &reason); - /** FMODE command - server mode with timestamp checks */ - void ForceMode(User* who, parameterlist ¶ms); - - /** FTOPIC command */ - bool ForceTopic(const std::string &source, parameterlist ¶ms); - - /** FJOIN, similar to TS6 SJOIN, but not quite. */ - void ForceJoin(User* who, parameterlist ¶ms); - /* Used on nick collision ... XXX ugly function HACK */ int DoCollision(User *u, time_t remotets, const std::string &remoteident, const std::string &remoteip, const std::string &remoteuid); - /** UID command */ - bool ParseUID(const std::string &source, parameterlist ¶ms); - /** Send one or more FJOINs for a channel of users. * If the length of a single line is more than 480-NICKMAX * in length, it is split over multiple lines. @@ -271,11 +259,6 @@ class TreeSocket : public BufferedSocket bool Stats(const std::string &prefix, parameterlist ¶ms); - /** Because the core won't let users or even SERVERS set +o, - * we use the OPERTYPE command to do this. - */ - bool OperType(const std::string &prefix, parameterlist ¶ms); - /** Remote AWAY */ bool Away(const std::string &prefix, parameterlist ¶ms); @@ -298,18 +281,10 @@ class TreeSocket : public BufferedSocket */ bool LocalPong(const std::string &prefix, parameterlist ¶ms); - /** METADATA - */ - bool MetaData(const std::string &prefix, parameterlist ¶ms); - /** VERSION */ bool ServerVersion(const std::string &prefix, parameterlist ¶ms); - /** CHGHOST - */ - bool ChangeHost(const std::string &prefix, parameterlist ¶ms); - /** ADDLINE */ bool AddLine(const std::string &prefix, parameterlist ¶ms); @@ -318,13 +293,6 @@ class TreeSocket : public BufferedSocket */ bool DelLine(const std::string &prefix, parameterlist ¶ms); - /** CHGNAME - */ - bool ChangeName(const std::string &prefix, parameterlist ¶ms); - - /** FIDENT */ - bool ChangeIdent(const std::string &prefix, parameterlist ¶ms); - /** WHOIS */ bool Whois(const std::string &prefix, parameterlist ¶ms); @@ -341,11 +309,6 @@ class TreeSocket : public BufferedSocket */ bool LocalPing(const std::string &prefix, parameterlist ¶ms); - /** Remove all modes from a channel, including statusmodes (+qaovh etc), simplemodes, parameter modes. - * This does not update the timestamp of the target channel, this must be done seperately. - */ - void RemoveStatus(User* source, parameterlist ¶ms); - /** <- (remote) <- SERVER */ bool RemoteServer(const std::string &prefix, parameterlist ¶ms); diff --git a/src/modules/m_spanningtree/treesocket2.cpp b/src/modules/m_spanningtree/treesocket2.cpp index 00783bed3..fc58862d7 100644 --- a/src/modules/m_spanningtree/treesocket2.cpp +++ b/src/modules/m_spanningtree/treesocket2.cpp @@ -290,15 +290,7 @@ void TreeSocket::ProcessConnectedLine(std::string& prefix, std::string& command, command = "MODE"; // TODO move all this into Commands - if (command == "UID") - { - this->ParseUID(prefix, params); - } - else if (command == "FJOIN") - { - this->ForceJoin(who,params); - } - else if (command == "STATS") + if (command == "STATS") { this->Stats(prefix, params); } @@ -322,26 +314,10 @@ void TreeSocket::ProcessConnectedLine(std::string& prefix, std::string& command, { this->Error(params); } - else if (command == "OPERTYPE") - { - this->OperType(prefix,params); - } else if (command == "AWAY") { this->Away(prefix,params); } - else if (command == "FMODE") - { - this->ForceMode(who,params); - } - else if (command == "FTOPIC") - { - this->ForceTopic(prefix,params); - } - else if (command == "METADATA") - { - this->MetaData(prefix,params); - } else if (command == "PING") { this->LocalPing(prefix,params); @@ -360,18 +336,6 @@ void TreeSocket::ProcessConnectedLine(std::string& prefix, std::string& command, { this->ServerVersion(prefix,params); } - else if (command == "FHOST") - { - this->ChangeHost(prefix,params); - } - else if (command == "FNAME") - { - this->ChangeName(prefix,params); - } - else if (command == "FIDENT") - { - this->ChangeIdent(prefix,params); - } else if (command == "ADDLINE") { this->AddLine(prefix,params); diff --git a/src/modules/m_spanningtree/uid.cpp b/src/modules/m_spanningtree/uid.cpp index 5af3426c8..8fc423156 100644 --- a/src/modules/m_spanningtree/uid.cpp +++ b/src/modules/m_spanningtree/uid.cpp @@ -12,71 +12,58 @@ */ #include "inspircd.h" +#include "commands.h" -#include "main.h" #include "utils.h" -#include "treeserver.h" #include "link.h" #include "treesocket.h" +#include "treeserver.h" #include "resolvers.h" -/* $ModDep: m_spanningtree/resolvers.h m_spanningtree/main.h m_spanningtree/utils.h m_spanningtree/treeserver.h m_spanningtree/link.h m_spanningtree/treesocket.h m_hash.h m_spanningtree/handshaketimer.h */ - -bool TreeSocket::ParseUID(const std::string &source, parameterlist ¶ms) +CmdResult CommandUID::Handle(const parameterlist ¶ms, User* serversrc) { + SpanningTreeUtilities* Utils = ((ModuleSpanningTree*)(Module*)creator)->Utils; /** Do we have enough parameters: * 0 1 2 3 4 5 6 7 8 9 (n-1) * UID uuid age nick host dhost ident ip.string signon +modes (modepara) :gecos */ if (params.size() < 10) - { - this->SendError("Invalid client introduction (wanted 10 or more parameters, got " + (params.empty() ? "0" : ConvToStr(params.size())) + "!)"); - return false; - } + return CMD_INVALID; time_t age_t = ConvToInt(params[1]); time_t signon = ConvToInt(params[7]); std::string empty; + std::string nick(params[2]); + std::string modestr(params[8]); - TreeServer* remoteserver = Utils->FindServer(source); + TreeServer* remoteserver = Utils->FindServer(serversrc->server); if (!remoteserver) - { - this->SendError("Invalid client introduction (Unknown server "+source+")"); - return false; - } + return CMD_INVALID; /* Check parameters for validity before introducing the client, discovered by dmb */ - else if (!age_t) - { - this->SendError("Invalid client introduction (Invalid TS?)"); - return false; - } - else if (!signon) - { - this->SendError("Invalid client introduction (Invalid signon?)"); - return false; - } - else if (params[8][0] != '+') - { - this->SendError("Invalid client introduction (Malformed MODE sequence?)"); - return false; - } + if (!age_t) + return CMD_INVALID; + if (!signon) + return CMD_INVALID; + if (modestr[0] != '+') + return CMD_INVALID; + TreeSocket* sock = remoteserver->GetRoute()->GetSocket(); /* check for collision */ - user_hash::iterator iter = ServerInstance->Users->clientlist->find(params[2]); + user_hash::iterator iter = ServerInstance->Users->clientlist->find(nick); if (iter != ServerInstance->Users->clientlist->end()) { /* * Nick collision. */ - int collide = this->DoCollision(iter->second, age_t, params[5], params[8], params[0]); + int collide = sock->DoCollision(iter->second, age_t, params[5], modestr, params[0]); ServerInstance->Logs->Log("m_spanningtree",DEBUG,"*** Collision on %s, collide=%d", params[2].c_str(), collide); if (collide != 1) { /* remote client changed, make sure we change their nick for the hash too */ - params[2] = params[0]; + nick = params[0]; } } @@ -90,11 +77,10 @@ bool TreeSocket::ParseUID(const std::string &source, parameterlist ¶ms) } catch (...) { - this->SendError("Protocol violation - Duplicate UUID '" + params[0] + "' on introduction of new user"); - return false; + return CMD_INVALID; } - (*(ServerInstance->Users->clientlist))[params[2]] = _new; - _new->nick.assign(params[2], 0, MAXBUF); + (*(ServerInstance->Users->clientlist))[nick] = _new; + _new->nick.assign(nick, 0, MAXBUF); _new->host.assign(params[3], 0, 64); _new->dhost.assign(params[4], 0, 64); _new->ident.assign(params[5], 0, MAXBUF); @@ -104,12 +90,12 @@ bool TreeSocket::ParseUID(const std::string &source, parameterlist ¶ms) _new->age = age_t; /* we need to remove the + from the modestring, so we can do our stuff */ - std::string::size_type pos_after_plus = params[8].find_first_not_of('+'); + std::string::size_type pos_after_plus = modestr.find_first_not_of('+'); if (pos_after_plus != std::string::npos) - params[8] = params[8].substr(pos_after_plus); + modestr = modestr.substr(pos_after_plus); unsigned int paramptr = 9; - for (std::string::iterator v = params[8].begin(); v != params[8].end(); v++) + for (std::string::iterator v = modestr.begin(); v != modestr.end(); v++) { if (*v == '+') continue; @@ -121,6 +107,9 @@ bool TreeSocket::ParseUID(const std::string &source, parameterlist ¶ms) { if (mh->GetNumParams(true)) { + if (paramptr >= params.size() - 1) + return CMD_INVALID; + std::string mp = params[paramptr++]; /* IMPORTANT NOTE: * All modes are assumed to succeed here as they are being set by a remote server. * Modes CANNOT FAIL here. If they DO fail, then the failure is ignored. This is important @@ -130,28 +119,17 @@ bool TreeSocket::ParseUID(const std::string &source, parameterlist ¶ms) * will not change in future versions if you want to make use of this protective behaviour * yourself. */ - if (paramptr < params.size() - 1) - mh->OnModeChange(_new, _new, NULL, params[paramptr++], true); - else - { - this->SendError(std::string("Broken UID command, expected a parameter for user mode '")+(*v)+"' but there aren't enough parameters in the command!"); - return false; - } + mh->OnModeChange(_new, _new, NULL, mp, true); } else mh->OnModeChange(_new, _new, NULL, empty, true); _new->SetMode(*v, true); } - else - { - this->SendError(std::string("Warning: Broken UID command, unknown user mode '")+(*v)+"' in the mode string! (mismatched module?)"); - return false; - } } /* now we've done with modes processing, put the + back for remote servers */ - if (params[8][0] != '+') - params[8] = "+" + params[8]; + if (modestr[0] != '+') + modestr = "+" + modestr; _new->SetClientIP(params[6].c_str()); @@ -160,17 +138,44 @@ bool TreeSocket::ParseUID(const std::string &source, parameterlist ¶ms) bool dosend = true; - if ((this->Utils->quiet_bursts && remoteserver->bursting) || ServerInstance->SilentULine(_new->server)) + if ((Utils->quiet_bursts && remoteserver->bursting) || ServerInstance->SilentULine(_new->server)) dosend = false; if (dosend) ServerInstance->SNO->WriteToSnoMask('C',"Client connecting at %s: %s!%s@%s [%s] [%s]", _new->server.c_str(), _new->nick.c_str(), _new->ident.c_str(), _new->host.c_str(), _new->GetIPString(), _new->fullname.c_str()); - params[params.size() - 1] = ":" + params[params.size() - 1]; - Utils->DoOneToAllButSender(source, "UID", params, source); - FOREACH_MOD(I_OnPostConnect,OnPostConnect(_new)); - return true; + return CMD_SUCCESS; +} + +CmdResult CommandFHost::Handle(const parameterlist ¶ms, User* src) +{ + if (params.size() < 1) + return CMD_INVALID; + if (IS_SERVER(src)) + return CMD_FAILURE; + src->ChangeDisplayedHost(params[0].c_str()); + return CMD_SUCCESS; +} + +CmdResult CommandFIdent::Handle(const parameterlist ¶ms, User* src) +{ + if (params.size() < 1) + return CMD_INVALID; + if (IS_SERVER(src)) + return CMD_FAILURE; + src->ChangeIdent(params[0].c_str()); + return CMD_SUCCESS; +} + +CmdResult CommandFName::Handle(const parameterlist ¶ms, User* src) +{ + if (params.size() < 1) + return CMD_INVALID; + if (IS_SERVER(src)) + return CMD_FAILURE; + src->ChangeName(params[0].c_str()); + return CMD_SUCCESS; } |