]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/modules/m_spanningtree.cpp
Forgot to change the prefix, whoops
[user/henk/code/inspircd.git] / src / modules / m_spanningtree.cpp
index 96eb2fc633257fce69c54d0cd50644b91978137a..1dbf54b59e2eeaebec146e8b67b0419f805b206f 100644 (file)
@@ -1058,6 +1058,11 @@ class TreeSocket : public InspSocket
        {
                if (params.size() < 8)
                        return true;
+               if (params.size() > 8)
+               {
+                       this->WriteLine(":"+Srv->GetServerName()+" KILL "+params[1]+" :Invalid client introduction ("+params[1]+"?)");
+                       return true;
+               }
                // NICK age nick host dhost ident +modes ip :gecos
                //       0   1    2    3      4     5    6   7
                time_t age = atoi(params[0].c_str());
@@ -1124,26 +1129,67 @@ class TreeSocket : public InspSocket
        {
                log(DEBUG,"Sending FJOINs to other server for %s",c->name);
                char list[MAXBUF];
+               std::string individual_halfops = ":"+Srv->GetServerName()+" FMODE "+c->name;
                snprintf(list,MAXBUF,":%s FJOIN %s %lu",Srv->GetServerName().c_str(),c->name,(unsigned long)c->age);
                std::map<char*,char*> *ulist = c->GetUsers();
+               std::vector<userrec*> specific_halfop;
+               std::vector<userrec*> specific_voice;
                for (std::map<char*,char*>::iterator i = ulist->begin(); i != ulist->end(); i++)
                {
                        char* o = i->second;
                        userrec* otheruser = (userrec*)o;
                        strlcat(list," ",MAXBUF);
-                       strlcat(list,cmode(otheruser,c),MAXBUF);
+                       int x = cflags(otheruser,c);
+                       if ((x & UCMODE_HOP) && (x & UCMODE_OP))
+                       {
+                               specific_halfop.push_back(otheruser);
+                       }
+                       if (((x & UCMODE_HOP) || (x & UCMODE_OP)) && (x & UCMODE_VOICE))
+                       {
+                               specific_voice.push_back(otheruser);
+                       }
+                       char* n = "";
+                       if (x & UCMODE_OP)
+                       {
+                               n = "@";
+                       }
+                       else if (x & UCMODE_HOP)
+                       {
+                               n = "%";
+                       }
+                       else if (x & UCMODE_VOICE)
+                       {
+                               n = "+";
+                       }
+                       strlcat(list,n,MAXBUF);
                        strlcat(list,otheruser->nick,MAXBUF);
                        if (strlen(list)>(480-NICKMAX))
                        {
                                log(DEBUG,"FJOIN line wrapped");
                                this->WriteLine(list);
                                snprintf(list,MAXBUF,":%s FJOIN %s %lu",Srv->GetServerName().c_str(),c->name,(unsigned long)c->age);
+                               for (unsigned int y = 0; y < specific_voice.size(); y++)
+                               {
+                                       this->WriteLine(":"+Srv->GetServerName()+" FMODE "+c->name+" +v "+specific_voice[y]->nick);
+                               }
+                               for (unsigned int y = 0; y < specific_halfop.size(); y++)
+                               {
+                                       this->WriteLine(":"+Srv->GetServerName()+" FMODE "+c->name+" +h "+specific_halfop[y]->nick);
+                               }
                        }
                }
                if (list[strlen(list)-1] != ':')
                {
                        log(DEBUG,"Final FJOIN line");
                        this->WriteLine(list);
+                       for (unsigned int y = 0; y < specific_voice.size(); y++)
+                       {
+                               this->WriteLine(":"+Srv->GetServerName()+" FMODE "+c->name+" +v "+specific_voice[y]->nick);
+                       }
+                       for (unsigned int y = 0; y < specific_halfop.size(); y++)
+                       {
+                               this->WriteLine(":"+Srv->GetServerName()+" FMODE "+c->name+" +h "+specific_halfop[y]->nick);
+                       }
                }
        }
 
@@ -1415,9 +1461,15 @@ class TreeSocket : public InspSocket
                userrec* u = Srv->FindNick(params[0]);
                if (u)
                {
-                       Srv->ChangeUserNick(u,params[1]);
-                       u->age = atoi(params[2].c_str());
                        DoOneToAllButSender(prefix,"SVSNICK",params,prefix);
+                       if (IS_LOCAL(u))
+                       {
+                               std::deque<std::string> par;
+                               par.push_back(params[1]);
+                               DoOneToMany(u->nick,"NICK",par);
+                               Srv->ChangeUserNick(u,params[1]);
+                               u->age = atoi(params[2].c_str());
+                       }
                }
                return true;
        }
@@ -1481,11 +1533,35 @@ class TreeSocket : public InspSocket
        {
                if (params.size() < 1)
                        return true;
-               TreeServer* ServerSource = FindServer(prefix);
-               if (ServerSource)
+               if (params.size() == 1)
                {
-                       ServerSource->SetPingFlag();
+                       TreeServer* ServerSource = FindServer(prefix);
+                       if (ServerSource)
+                       {
+                               ServerSource->SetPingFlag();
+                       }
                }
+                else
+                {       
+                        std::string forwardto = params[1];
+                        if (forwardto == Srv->GetServerName())
+                        {
+                                // this is a PONG for us
+                               // if the prefix is a user, check theyre local, and if they are,
+                               // dump the PONG reply back to their fd. If its a server, do nowt.
+                               // Services might want to send these s->s, but we dont need to yet.
+                               userrec* u = Srv->FindNick(prefix);
+                               if (u)
+                               {
+                                       WriteServ(u->fd,"PONG %s %s",params[0].c_str(),params[1].c_str());
+                               }
+                        }
+                        else
+                        {
+                                // not for us, pass it on :)
+                                DoOneToOne(prefix,"PONG",params,forwardto);
+                        }
+                }
                return true;
        }
        
@@ -1589,6 +1665,10 @@ class TreeSocket : public InspSocket
                        params[5] = ":" + params[5];
                        DoOneToAllButSender(prefix,"ADDLINE",params,prefix);
                }
+               if (!this->bursting)
+               {
+                       apply_lines(APPLY_ZLINES|APPLY_GLINES|APPLY_QLINES);
+               }
                return true;
        }
 
@@ -1698,7 +1778,7 @@ class TreeSocket : public InspSocket
                if (params.size() == 2)
                {
                        // someone querying our time?
-                       if (Srv->MatchText(Srv->GetServerName(),params[0]))
+                       if (Srv->GetServerName() == params[0])
                        {
                                userrec* u = Srv->FindNick(params[1]);
                                if (u)
@@ -1707,9 +1787,16 @@ class TreeSocket : public InspSocket
                                        snprintf(curtime,256,"%lu",(unsigned long)time(NULL));
                                        params.push_back(curtime);
                                        params[0] = prefix;
-                                       DoOneToOne(Srv->GetServerName(),"TIME",params,u->server);
+                                       DoOneToOne(Srv->GetServerName(),"TIME",params,params[0]);
                                }
                        }
+                       else
+                       {
+                               // not us, pass it on
+                               userrec* u = Srv->FindNick(params[1]);
+                               if (u)
+                                       DoOneToOne(prefix,"TIME",params,params[0]);
+                       }
                }
                else if (params.size() == 3)
                {
@@ -1720,11 +1807,15 @@ class TreeSocket : public InspSocket
                                time_t rawtime = atol(params[2].c_str());
                                struct tm * timeinfo;
                                timeinfo = localtime(&rawtime);
-                               WriteServ(u->fd,"391 %s %s :%s",u->nick,prefix.c_str(),asctime(timeinfo));
+                               char tms[26];
+                               snprintf(tms,26,"%s",asctime(timeinfo));
+                               tms[24] = 0;
+                               WriteServ(u->fd,"391 %s %s :%s",u->nick,prefix.c_str(),tms);
                        }
                        else
                        {
-                               DoOneToOne(prefix,"TIME",params,u->server);
+                               if (u)
+                                       DoOneToOne(prefix,"TIME",params,u->server);
                        }
                }
                return true;
@@ -1734,9 +1825,29 @@ class TreeSocket : public InspSocket
        {
                if (params.size() < 1)
                        return true;
-               std::string stufftobounce = params[0];
-               this->WriteLine(":"+Srv->GetServerName()+" PONG "+stufftobounce);
-               return true;
+               if (params.size() == 1)
+               {
+                       std::string stufftobounce = params[0];
+                       this->WriteLine(":"+Srv->GetServerName()+" PONG "+stufftobounce);
+                       return true;
+               }
+               else
+               {
+                       std::string forwardto = params[1];
+                       if (forwardto == Srv->GetServerName())
+                       {
+                               // this is a ping for us, send back PONG to the requesting server
+                               params[1] = params[0];
+                               params[0] = forwardto;
+                               DoOneToOne(forwardto,"PONG",params,params[1]);
+                       }
+                       else
+                       {
+                               // not for us, pass it on :)
+                               DoOneToOne(prefix,"PING",params,forwardto);
+                       }
+                       return true;
+               }
        }
 
        bool RemoteServer(std::string prefix, std::deque<std::string> &params)
@@ -2206,6 +2317,7 @@ class TreeSocket : public InspSocket
                                else if (command == "ENDBURST")
                                {
                                        this->bursting = false;
+                                       apply_lines(APPLY_ZLINES|APPLY_GLINES|APPLY_QLINES);
                                        return true;
                                }
                                else
@@ -2793,6 +2905,30 @@ class ModuleSpanningTree : public Module
                return 1;
        }
 
+       int HandleTime(char** parameters, int pcnt, userrec* user)
+       {
+               if ((user->fd > -1) && (pcnt))
+               {
+                       TreeServer* found = FindServerMask(parameters[0]);
+                       if (found)
+                       {
+                               // we dont' override for local server
+                               if (found == TreeRoot)
+                                       return 0;
+                               
+                               std::deque<std::string> params;
+                               params.push_back(found->GetName());
+                               params.push_back(user->nick);
+                               DoOneToOne(Srv->GetServerName(),"TIME",params,found->GetName());
+                       }
+                       else
+                       {
+                               WriteServ(user->fd,"402 %s %s :No such server",user->nick,parameters[0]);
+                       }
+               }
+               return 1;
+       }
+
        int HandleRemoteWhois(char** parameters, int pcnt, userrec* user)
        {
                if ((user->fd > -1) && (pcnt > 1))
@@ -2975,6 +3111,10 @@ class ModuleSpanningTree : public Module
                        this->HandleMap(parameters,pcnt,user);
                        return 1;
                }
+               else if ((command == "TIME") && (pcnt > 0))
+               {
+                       return this->HandleTime(parameters,pcnt,user);
+               }
                else if (command == "LUSERS")
                {
                        this->HandleLusers(parameters,pcnt,user);