X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fmodules%2Fm_spanningtree.cpp;h=1dbf54b59e2eeaebec146e8b67b0419f805b206f;hb=2ea814385ef00a34f150e08c3dae14ef90978458;hp=96eb2fc633257fce69c54d0cd50644b91978137a;hpb=9a0c30d6b9cfbd0bc70918ef4c605a92d1dc6914;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/modules/m_spanningtree.cpp b/src/modules/m_spanningtree.cpp index 96eb2fc63..1dbf54b59 100644 --- a/src/modules/m_spanningtree.cpp +++ b/src/modules/m_spanningtree.cpp @@ -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 *ulist = c->GetUsers(); + std::vector specific_halfop; + std::vector specific_voice; for (std::map::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 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 ¶ms) @@ -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 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);