]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/modules/m_spanningtree/main.cpp
Use loopCall to protect OnUserKick rather than the triggerevents hack
[user/henk/code/inspircd.git] / src / modules / m_spanningtree / main.cpp
index b391df971ee5c17b2a11266fe640abae81108485..b38929ad00b2b6a935aa5f80c36964cf7c0fdf0e 100644 (file)
@@ -3,7 +3,7 @@
  *       +------------------------------------+
  *
  *  InspIRCd: (C) 2002-2009 InspIRCd Development Team
- * See: http://www.inspircd.org/wiki/index.php/Credits
+ * See: http://wiki.inspircd.org/Credits
  *
  * This program is free but copyrighted software; see
  *         the file COPYING for details.
@@ -49,15 +49,16 @@ ModuleSpanningTree::ModuleSpanningTree(InspIRCd* Me)
        {
                I_OnPreCommand, I_OnGetServerDescription, I_OnUserInvite, I_OnPostLocalTopicChange,
                I_OnWallops, I_OnUserNotice, I_OnUserMessage, I_OnBackgroundTimer,
-               I_OnUserJoin, I_OnChangeLocalUserHost, I_OnChangeName, I_OnUserPart,
+               I_OnUserJoin, I_OnChangeLocalUserHost, I_OnChangeName, I_OnUserPart, I_OnUnloadModule,
                I_OnUserQuit, I_OnUserPostNick, I_OnUserKick, I_OnRemoteKill, I_OnRehash,
-               I_OnOper, I_OnAddLine, I_OnDelLine, I_ProtoSendMode, I_OnMode,
+               I_OnOper, I_OnAddLine, I_OnDelLine, I_ProtoSendMode, I_OnMode, I_OnLoadModule,
                I_OnStats, I_ProtoSendMetaData, I_OnEvent, I_OnSetAway, I_OnPostCommand
        };
-       ServerInstance->Modules->Attach(eventlist, this, 27);
+       ServerInstance->Modules->Attach(eventlist, this, 29);
 
        delete ServerInstance->PI;
        ServerInstance->PI = new SpanningTreeProtocolInterface(this, Utils, ServerInstance);
+       loopCall = false;
 
        for (std::vector<User*>::const_iterator i = ServerInstance->Users->local_users.begin(); i != ServerInstance->Users->local_users.end(); i++)
        {
@@ -192,6 +193,12 @@ void ModuleSpanningTree::DoPingChecks(time_t curtime)
        {
                TreeServer *s = i->second;
 
+               // Fix for bug #792, do not ping servers that are not connected yet!
+               // Remote servers have Socket == NULL and local connected servers have
+               // Socket->LinkState == CONNECTED
+               if (s->GetSocket() && s->GetSocket()->GetLinkState() != CONNECTED)
+                       continue;
+
                // Now do PING checks on all servers
                TreeServer *mts = Utils->BestRouteTo(s->GetID());
 
@@ -595,6 +602,9 @@ void ModuleSpanningTree::OnUserJoin(User* user, Channel* channel, bool sync, boo
 
 int ModuleSpanningTree::OnChangeLocalUserHost(User* user, const std::string &newhost)
 {
+       if (user->registered != REG_ALL)
+               return 0;
+
        std::deque<std::string> params;
        params.push_back(newhost);
        Utils->DoOneToMany(user->uuid,"FHOST",params);
@@ -606,6 +616,7 @@ void ModuleSpanningTree::OnChangeName(User* user, const std::string &gecos)
        // only occurs for local clients
        if (user->registered != REG_ALL)
                return;
+
        std::deque<std::string> params;
        params.push_back(gecos);
        Utils->DoOneToMany(user->uuid,"FNAME",params);
@@ -666,6 +677,8 @@ void ModuleSpanningTree::OnUserPostNick(User* user, const std::string &oldnick)
 
 void ModuleSpanningTree::OnUserKick(User* source, User* user, Channel* chan, const std::string &reason, bool &silent)
 {
+       if (loopCall)
+               return;
        if ((source) && (IS_LOCAL(source)))
        {
                std::deque<std::string> params;
@@ -686,7 +699,9 @@ void ModuleSpanningTree::OnUserKick(User* source, User* user, Channel* chan, con
 
 void ModuleSpanningTree::OnRemoteKill(User* source, User* dest, const std::string &reason, const std::string &operreason)
 {
-       if (!IS_LOCAL(source)) return; // Only start routing if we're origin.
+       if (!IS_LOCAL(source))
+               return; // Only start routing if we're origin.
+
        std::deque<std::string> params;
        params.push_back(":"+reason);
        Utils->DoOneToMany(dest->uuid,"OPERQUIT",params);
@@ -714,6 +729,34 @@ void ModuleSpanningTree::OnRehash(User* user, const std::string &parameter)
        Utils->ReadConfiguration(true);
 }
 
+void ModuleSpanningTree::OnLoadModule(Module* mod, const std::string &name)
+{
+       this->RedoConfig(mod, name);
+}
+
+void ModuleSpanningTree::OnUnloadModule(Module* mod, const std::string &name)
+{
+       this->RedoConfig(mod, name);
+}
+
+void ModuleSpanningTree::RedoConfig(Module* mod, const std::string &name)
+{
+       /* If m_sha256.so is loaded (we use this for HMAC) or any module implementing a BufferedSocket interface is loaded,
+        * then we need to re-read our config again taking this into account.
+        */
+       modulelist* ml = ServerInstance->Modules->FindInterface("BufferedSocketHook");
+       bool IsBufferSocketModule = false;
+
+       /* Did we find any modules? */
+       if (ml && std::find(ml->begin(), ml->end(), mod) != ml->end())
+               IsBufferSocketModule = true;
+
+       if (name == "m_sha256.so" || IsBufferSocketModule)
+       {
+               Utils->ReadConfiguration(true);
+       }
+}
+
 // note: the protocol does not allow direct umode +o except
 // via NICK with 8 params. sending OPERTYPE infers +o modechange
 // locally.
@@ -729,7 +772,7 @@ void ModuleSpanningTree::OnOper(User* user, const std::string &opertype)
 
 void ModuleSpanningTree::OnAddLine(User* user, XLine *x)
 {
-       if (!x->IsBurstable())
+       if (!x->IsBurstable() || loopCall)
                return;
 
        char data[MAXBUF];
@@ -772,7 +815,7 @@ void ModuleSpanningTree::OnDelLine(User* user, XLine *x)
        }
 }
 
-void ModuleSpanningTree::OnMode(User* user, void* dest, int target_type, const std::string &text)
+void ModuleSpanningTree::OnMode(User* user, void* dest, int target_type, const std::deque<std::string> &text, const std::deque<TranslateType> &translate)
 {
        if ((IS_LOCAL(user)) && (user->registered == REG_ALL))
        {
@@ -780,7 +823,7 @@ void ModuleSpanningTree::OnMode(User* user, void* dest, int target_type, const s
                std::string command;
                std::string output_text;
 
-               ServerInstance->Parser->TranslateUIDs(TR_SPACENICKLIST, text, output_text);
+               ServerInstance->Parser->TranslateUIDs(translate, text, output_text);
 
                if (target_type == TYPE_USER)
                {
@@ -823,19 +866,19 @@ int ModuleSpanningTree::OnSetAway(User* user, const std::string &awaymsg)
        return 0;
 }
 
-void ModuleSpanningTree::ProtoSendMode(void* opaque, TargetTypeFlags target_type, void* target, const std::string &modeline)
+void ModuleSpanningTree::ProtoSendMode(void* opaque, TargetTypeFlags target_type, void* target, const std::deque<std::string> &modeline, const std::deque<TranslateType> &translate)
 {
        TreeSocket* s = (TreeSocket*)opaque;
        std::string output_text;
 
-       ServerInstance->Parser->TranslateUIDs(TR_SPACENICKLIST, modeline, output_text);
+       ServerInstance->Parser->TranslateUIDs(translate, modeline, output_text);
 
        if (target)
        {
                if (target_type == TYPE_USER)
                {
                        User* u = (User*)target;
-                       s->WriteLine(std::string(":")+ServerInstance->Config->GetSID()+" FMODE "+u->uuid+" "+ConvToStr(u->age)+" "+output_text);
+                       s->WriteLine(std::string(":")+ServerInstance->Config->GetSID()+" MODE "+u->uuid+" "+output_text);
                }
                else if (target_type == TYPE_CHANNEL)
                {
@@ -903,7 +946,7 @@ Version ModuleSpanningTree::GetVersion()
  */
 void ModuleSpanningTree::Prioritize()
 {
-       ServerInstance->Modules->SetPriority(this, PRIO_LAST);
+       ServerInstance->Modules->SetPriority(this, PRIORITY_LAST);
 }
 
 MODULE_INIT(ModuleSpanningTree)