]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/modules/m_spanningtree.cpp
Added the send_push event to m_spanningtree (send raw text to a remote user)
[user/henk/code/inspircd.git] / src / modules / m_spanningtree.cpp
index 155ad70993095e6df845a6b4059f24036471ec6c..7d034c17ce263f7986cb93d57f17af56223949c7 100644 (file)
@@ -100,6 +100,7 @@ class Link : public classbase
        std::string EncryptionKey;
        bool HiddenFromStats;
        std::string FailOver;
+       int Timeout;
 };
 
 /** Contains helper functions and variables for this module,
@@ -1057,6 +1058,9 @@ class TreeSocket : public InspSocket
        {
                if ((Current) && (Current != Utils->TreeRoot))
                {
+                       Event rmode((char*)Current->GetName().c_str(), (Module*)Utils->Creator, "lost_server");
+                       rmode.Send(Instance);
+
                        std::deque<std::string> params;
                        params.push_back(Current->GetName());
                        params.push_back(":"+reason);
@@ -1610,7 +1614,7 @@ class TreeSocket : public InspSocket
                        /* Lower the TS here */
                        if (Utils->AnnounceTSChange && chan)
                                chan->WriteChannelWithServ(Instance->Config->ServerName,
-                               "TS for %s changed from %lu to %lu", chan->name, ourTS, TS);
+                               "NOTICE %s :TS for %s changed from %lu to %lu", chan->name, chan->name, ourTS, TS);
                        ourTS = TS;
 
                        param_list.push_back(channel);
@@ -1875,6 +1879,8 @@ class TreeSocket : public InspSocket
         */
        void SendFJoins(TreeServer* Current, chanrec* c)
        {
+               std::string buffer;
+
                Instance->Log(DEBUG,"Sending FJOINs to other server for %s",c->name);
                char list[MAXBUF];
                std::string individual_halfops = std::string(":")+this->Instance->Config->ServerName+" FMODE "+c->name+" "+ConvToStr(c->age);
@@ -1900,7 +1906,8 @@ class TreeSocket : public InspSocket
 
                        if (curlen > (480-NICKMAX))
                        {
-                               this->WriteLine(list);
+                               buffer.append(list).append("\r\n");
+
                                dlen = curlen = snprintf(list,MAXBUF,":%s FJOIN %s %lu",this->Instance->Config->ServerName,c->name,(unsigned long)c->age);
                                ptr = list + dlen;
                                ptrlen = 0;
@@ -1909,64 +1916,83 @@ class TreeSocket : public InspSocket
                }
 
                if (numusers)
-                       this->WriteLine(list);
+                       buffer.append(list).append("\r\n");
 
-                for (BanList::iterator b = c->bans.begin(); b != c->bans.end(); b++)
-                {
+               for (BanList::iterator b = c->bans.begin(); b != c->bans.end(); b++)
+               {
                        modes.append("b");
-                       params.append(b->data).append(" ");
-                }
-               this->WriteLine(std::string(":")+this->Instance->Config->ServerName+" FMODE "+c->name+" "+ConvToStr(c->age)+" +"+c->ChanModes(true)+modes+" "+params);
+                       params.append(" ").append(b->data);
+
+                       if (params.length() >= MAXMODES)
+                       {
+                               /* Wrap at MAXMODES */
+                               buffer.append(":").append(this->Instance->Config->ServerName).append(" FMODE ").append(c->name).append(" ").append(ConvToStr(c->age)).append(" +").append(modes).append(params).append("\r\n");
+                               modes = "";
+                               params = "";
+                       }
+               }
+
+               buffer.append(":").append(this->Instance->Config->ServerName).append(" FMODE ").append(c->name).append(" ").append(ConvToStr(c->age)).append(" +").append(c->ChanModes(true));
+
+               /* Only send these if there are any */
+               if (!modes.empty())
+                       buffer.append("\r\n").append(":").append(this->Instance->Config->ServerName).append(" FMODE ").append(c->name).append(" ").append(ConvToStr(c->age)).append(" +").append(modes).append(params);
+
+               this->WriteLine(buffer);
        }
 
        /** Send G, Q, Z and E lines */
        void SendXLines(TreeServer* Current)
        {
                char data[MAXBUF];
+               std::string buffer;
                std::string n = this->Instance->Config->ServerName;
                const char* sn = n.c_str();
                int iterations = 0;
                /* Yes, these arent too nice looking, but they get the job done */
                for (std::vector<ZLine*>::iterator i = Instance->XLines->zlines.begin(); i != Instance->XLines->zlines.end(); i++, iterations++)
                {
-                       snprintf(data,MAXBUF,":%s ADDLINE Z %s %s %lu %lu :%s",sn,(*i)->ipaddr,(*i)->source,(unsigned long)(*i)->set_time,(unsigned long)(*i)->duration,(*i)->reason);
-                       this->WriteLine(data);
+                       snprintf(data,MAXBUF,":%s ADDLINE Z %s %s %lu %lu :%s\r\n",sn,(*i)->ipaddr,(*i)->source,(unsigned long)(*i)->set_time,(unsigned long)(*i)->duration,(*i)->reason);
+                       buffer.append(data);
                }
                for (std::vector<QLine*>::iterator i = Instance->XLines->qlines.begin(); i != Instance->XLines->qlines.end(); i++, iterations++)
                {
-                       snprintf(data,MAXBUF,":%s ADDLINE Q %s %s %lu %lu :%s",sn,(*i)->nick,(*i)->source,(unsigned long)(*i)->set_time,(unsigned long)(*i)->duration,(*i)->reason);
-                       this->WriteLine(data);
+                       snprintf(data,MAXBUF,":%s ADDLINE Q %s %s %lu %lu :%s\r\n",sn,(*i)->nick,(*i)->source,(unsigned long)(*i)->set_time,(unsigned long)(*i)->duration,(*i)->reason);
+                       buffer.append(data);
                }
                for (std::vector<GLine*>::iterator i = Instance->XLines->glines.begin(); i != Instance->XLines->glines.end(); i++, iterations++)
                {
-                       snprintf(data,MAXBUF,":%s ADDLINE G %s %s %lu %lu :%s",sn,(*i)->hostmask,(*i)->source,(unsigned long)(*i)->set_time,(unsigned long)(*i)->duration,(*i)->reason);
-                       this->WriteLine(data);
+                       snprintf(data,MAXBUF,":%s ADDLINE G %s %s %lu %lu :%s\r\n",sn,(*i)->hostmask,(*i)->source,(unsigned long)(*i)->set_time,(unsigned long)(*i)->duration,(*i)->reason);
+                       buffer.append(data);
                }
                for (std::vector<ELine*>::iterator i = Instance->XLines->elines.begin(); i != Instance->XLines->elines.end(); i++, iterations++)
                {
-                       snprintf(data,MAXBUF,":%s ADDLINE E %s %s %lu %lu :%s",sn,(*i)->hostmask,(*i)->source,(unsigned long)(*i)->set_time,(unsigned long)(*i)->duration,(*i)->reason);
-                       this->WriteLine(data);
+                       snprintf(data,MAXBUF,":%s ADDLINE E %s %s %lu %lu :%s\r\n",sn,(*i)->hostmask,(*i)->source,(unsigned long)(*i)->set_time,(unsigned long)(*i)->duration,(*i)->reason);
+                       buffer.append(data);
                }
                for (std::vector<ZLine*>::iterator i = Instance->XLines->pzlines.begin(); i != Instance->XLines->pzlines.end(); i++, iterations++)
                {
-                       snprintf(data,MAXBUF,":%s ADDLINE Z %s %s %lu %lu :%s",sn,(*i)->ipaddr,(*i)->source,(unsigned long)(*i)->set_time,(unsigned long)(*i)->duration,(*i)->reason);
-                       this->WriteLine(data);
+                       snprintf(data,MAXBUF,":%s ADDLINE Z %s %s %lu %lu :%s\r\n",sn,(*i)->ipaddr,(*i)->source,(unsigned long)(*i)->set_time,(unsigned long)(*i)->duration,(*i)->reason);
+                       buffer.append(data);
                }
                for (std::vector<QLine*>::iterator i = Instance->XLines->pqlines.begin(); i != Instance->XLines->pqlines.end(); i++, iterations++)
                {
-                       snprintf(data,MAXBUF,":%s ADDLINE Q %s %s %lu %lu :%s",sn,(*i)->nick,(*i)->source,(unsigned long)(*i)->set_time,(unsigned long)(*i)->duration,(*i)->reason);
-                       this->WriteLine(data);
+                       snprintf(data,MAXBUF,":%s ADDLINE Q %s %s %lu %lu :%s\r\n",sn,(*i)->nick,(*i)->source,(unsigned long)(*i)->set_time,(unsigned long)(*i)->duration,(*i)->reason);
+                       buffer.append(data);
                }
                for (std::vector<GLine*>::iterator i = Instance->XLines->pglines.begin(); i != Instance->XLines->pglines.end(); i++, iterations++)
                {
-                       snprintf(data,MAXBUF,":%s ADDLINE G %s %s %lu %lu :%s",sn,(*i)->hostmask,(*i)->source,(unsigned long)(*i)->set_time,(unsigned long)(*i)->duration,(*i)->reason);
-                       this->WriteLine(data);
+                       snprintf(data,MAXBUF,":%s ADDLINE G %s %s %lu %lu :%s\r\n",sn,(*i)->hostmask,(*i)->source,(unsigned long)(*i)->set_time,(unsigned long)(*i)->duration,(*i)->reason);
+                       buffer.append(data);
                }
                for (std::vector<ELine*>::iterator i = Instance->XLines->pelines.begin(); i != Instance->XLines->pelines.end(); i++, iterations++)
                {
-                       snprintf(data,MAXBUF,":%s ADDLINE E %s %s %lu %lu :%s",sn,(*i)->hostmask,(*i)->source,(unsigned long)(*i)->set_time,(unsigned long)(*i)->duration,(*i)->reason);
-                       this->WriteLine(data);
+                       snprintf(data,MAXBUF,":%s ADDLINE E %s %s %lu %lu :%s\r\n",sn,(*i)->hostmask,(*i)->source,(unsigned long)(*i)->set_time,(unsigned long)(*i)->duration,(*i)->reason);
+                       buffer.append(data);
                }
+
+               if (!buffer.empty())
+                       this->WriteLine(buffer);
        }
 
        /** Send channel modes and topics */
@@ -2000,6 +2026,7 @@ class TreeSocket : public InspSocket
        {
                char data[MAXBUF];
                std::deque<std::string> list;
+               std::string dataline;
                int iterations = 0;
                for (user_hash::iterator u = this->Instance->clientlist.begin(); u != this->Instance->clientlist.end(); u++, iterations++)
                {
@@ -2009,11 +2036,13 @@ class TreeSocket : public InspSocket
                                this->WriteLine(data);
                                if (*u->second->oper)
                                {
-                                       this->WriteLine(":"+std::string(u->second->nick)+" OPERTYPE "+std::string(u->second->oper));
+                                       snprintf(data,MAXBUF,":%s OPERTYPE %s", u->second->nick, u->second->oper);
+                                       this->WriteLine(data);
                                }
                                if (*u->second->awaymsg)
                                {
-                                       this->WriteLine(":"+std::string(u->second->nick)+" AWAY :"+std::string(u->second->awaymsg));
+                                       snprintf(data,MAXBUF,":%s AWAY :%s", u->second->nick, u->second->awaymsg);
+                                       this->WriteLine(data);
                                }
                                FOREACH_MOD_I(this->Instance,I_OnSyncUser,OnSyncUser(u->second,(Module*)Utils->Creator,(void*)this));
                                list.clear();
@@ -3319,6 +3348,10 @@ class TreeSocket : public InspSocket
                                                sourceserv = this->InboundServerName;
                                        }
                                        this->Instance->SNO->WriteToSnoMask('l',"Received end of netburst from \2%s\2",sourceserv.c_str());
+
+                                       Event rmode((char*)sourceserv.c_str(), (Module*)Utils->Creator, "new_server");
+                                       rmode.Send(Instance);
+
                                        return true;
                                }
                                else
@@ -3439,7 +3472,9 @@ class TreeSocket : public InspSocket
                {
                        Squit(s,"Remote host closed the connection");
                }
-               this->Instance->SNO->WriteToSnoMask('l',"Connection to '\2%s\2' failed.",quitserver.c_str());
+
+               if (quitserver != "")
+                       this->Instance->SNO->WriteToSnoMask('l',"Connection to '\2%s\2' failed.",quitserver.c_str());
        }
 
        virtual int OnIncomingConnection(int newsock, char* ip)
@@ -3500,7 +3535,7 @@ class ServernameResolver : public Resolver
                TreeServer* CheckDupe = Utils->FindServer(MyLink.Name.c_str());
                if (!CheckDupe) /* Check that nobody tried to connect it successfully while we were resolving */
                {
-                       TreeSocket* newsocket = new TreeSocket(this->Utils, ServerInstance, result,MyLink.Port,false,10,MyLink.Name.c_str());
+                       TreeSocket* newsocket = new TreeSocket(this->Utils, ServerInstance, result,MyLink.Port,false,MyLink.Timeout ? MyLink.Timeout : 10,MyLink.Name.c_str());
                        if (newsocket->GetFd() > -1)
                        {
                                /* We're all OK */
@@ -3814,6 +3849,7 @@ void SpanningTreeUtilities::ReadConfiguration(bool rebind)
                L.AutoConnect = Conf->ReadInteger("link","autoconnect",j,true);
                L.EncryptionKey =  Conf->ReadValue("link","encryptionkey",j);
                L.HiddenFromStats = Conf->ReadFlag("link","hidden",j);
+               L.Timeout = Conf->ReadInteger("link","timeout",j,true);
                L.NextConnectTime = time(NULL) + L.AutoConnect;
                /* Bugfix by brain, do not allow people to enter bad configurations */
                if (L.Name != ServerInstance->Config->ServerName)
@@ -4270,7 +4306,7 @@ class ModuleSpanningTree : public Module
                /* Do we already have an IP? If so, no need to resolve it. */
                if (insp_aton(x->IPAddr.c_str(), &binip) > 0)
                {
-                       TreeSocket* newsocket = new TreeSocket(Utils, ServerInstance, x->IPAddr,x->Port,false,10,x->Name.c_str());
+                       TreeSocket* newsocket = new TreeSocket(Utils, ServerInstance, x->IPAddr,x->Port,false,x->Timeout ? x->Timeout : 10,x->Name.c_str());
                        if (newsocket->GetFd() > -1)
                        {
                                /* Handled automatically on success */
@@ -4992,6 +5028,19 @@ class ModuleSpanningTree : public Module
                        params->insert(params->begin() + 1,ConvToStr(ourTS));
                        Utils->DoOneToMany(ServerInstance->Config->ServerName,"FMODE",*params);
                }
+               else if (event->GetEventID() == "send_push")
+               {
+                       if (params->size() < 2)
+                               return;
+                       
+                       userrec *a = ServerInstance->FindNick((*params)[0]);
+                       
+                       if (!a)
+                               return;
+                       
+                       (*params)[1] = ":" + (*params)[1];
+                       Utils->DoOneToOne(ServerInstance->Config->ServerName, "PUSH", *params, a->server);
+               }
        }
 
        virtual ~ModuleSpanningTree()