X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fmodules%2Fm_spanningtree%2Fnetburst.cpp;h=8b873a3e7f29aa22b1a8ec2505df61b53c749557;hb=da28fe0b8c0bec9ab111044b1004f24cbf2d742e;hp=8cd0dccd9ae78b7591d487108b2475b60290fd02;hpb=02859be56d43bcece02aab350e02bc95ed1bf446;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/modules/m_spanningtree/netburst.cpp b/src/modules/m_spanningtree/netburst.cpp index 8cd0dccd9..8b873a3e7 100644 --- a/src/modules/m_spanningtree/netburst.cpp +++ b/src/modules/m_spanningtree/netburst.cpp @@ -21,6 +21,7 @@ #include "inspircd.h" #include "xline.h" +#include "listmode.h" #include "treesocket.h" #include "treeserver.h" @@ -34,27 +35,25 @@ */ void TreeSocket::DoBurst(TreeServer* s) { - std::string name = s->GetName(); - std::string burst = ":" + ServerInstance->Config->GetSID() + " BURST " +ConvToStr(ServerInstance->Time()); - std::string endburst = ":" + ServerInstance->Config->GetSID() + " ENDBURST"; + std::string servername = s->GetName(); ServerInstance->SNO->WriteToSnoMask('l',"Bursting to \2%s\2 (Authentication: %s%s).", - name.c_str(), + servername.c_str(), capab->auth_fingerprint ? "SSL Fingerprint and " : "", capab->auth_challenge ? "challenge-response" : "plaintext password"); this->CleanNegotiationInfo(); - this->WriteLine(burst); + this->WriteLine(":" + ServerInstance->Config->GetSID() + " BURST " + ConvToStr(ServerInstance->Time())); /* send our version string */ - this->WriteLine(std::string(":")+ServerInstance->Config->GetSID()+" VERSION :"+ServerInstance->GetVersionString()); + this->WriteLine(":" + ServerInstance->Config->GetSID() + " VERSION :"+ServerInstance->GetVersionString()); /* Send server tree */ this->SendServers(Utils->TreeRoot,s,1); /* Send users and their oper status */ - this->SendUsers(s); + this->SendUsers(); /* Send everything else (channel modes, xlines etc) */ - this->SendChannelModes(s); - this->SendXLines(s); + this->SendChannelModes(); + this->SendXLines(); FOREACH_MOD(I_OnSyncNetwork,OnSyncNetwork(Utils->Creator,(void*)this)); - this->WriteLine(endburst); - ServerInstance->SNO->WriteToSnoMask('l',"Finished bursting to \2"+name+"\2."); + this->WriteLine(":" + ServerInstance->Config->GetSID() + " ENDBURST"); + ServerInstance->SNO->WriteToSnoMask('l',"Finished bursting to \2"+ s->GetName()+"\2."); } /** Recursively send the server tree with distances as hops. @@ -68,19 +67,18 @@ void TreeSocket::DoBurst(TreeServer* s) */ void TreeSocket::SendServers(TreeServer* Current, TreeServer* s, int hops) { - char command[1024]; + char command[MAXBUF]; for (unsigned int q = 0; q < Current->ChildCount(); q++) { TreeServer* recursive_server = Current->GetChild(q); if (recursive_server != s) { - std::string servername = Current->GetName(); std::string recursive_servername = recursive_server->GetName(); - snprintf(command,1024,":%s SERVER %s * %d %s :%s", servername.c_str(), recursive_servername.c_str(), hops, + snprintf(command, MAXBUF, ":%s SERVER %s * %d %s :%s", Current->GetID().c_str(), recursive_servername.c_str(), hops, recursive_server->GetID().c_str(), recursive_server->GetDesc().c_str()); this->WriteLine(command); - this->WriteLine(":"+recursive_server->GetName()+" VERSION :"+recursive_server->GetVersion()); + this->WriteLine(":"+recursive_server->GetID()+" VERSION :"+recursive_server->GetVersion()); /* down to next level */ this->SendServers(recursive_server, s, hops+1); } @@ -90,101 +88,50 @@ void TreeSocket::SendServers(TreeServer* Current, TreeServer* s, int hops) /** 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. + * Send one or more FMODEs for a channel with the + * channel bans, if there's any. */ -void TreeSocket::SendFJoins(TreeServer* Current, Channel* c) +void TreeSocket::SendFJoins(Channel* c) { - std::string buffer; - char list[MAXBUF]; - - size_t curlen, headlen; - curlen = headlen = snprintf(list,MAXBUF,":%s FJOIN %s %lu +%s :", - ServerInstance->Config->GetSID().c_str(), c->name.c_str(), (unsigned long)c->age, c->ChanModes(true)); - int numusers = 0; - char* ptr = list + curlen; - bool looped_once = false; + std::string line(":"); + line.append(ServerInstance->Config->GetSID()).append(" FJOIN ").append(c->name).append(1, ' ').append(ConvToStr(c->age)).append(" +"); + std::string::size_type erase_from = line.length(); + line.append(c->ChanModes(true)).append(" :"); const UserMembList *ulist = c->GetUsers(); - std::string modes; - std::string params; - - for (UserMembCIter i = ulist->begin(); i != ulist->end(); i++) - { - size_t ptrlen = 0; - std::string modestr = i->second->modes; - - if ((curlen + modestr.length() + i->first->uuid.length() + 4) > 480) - { - // remove the final space - if (ptr[-1] == ' ') - ptr[-1] = '\0'; - buffer.append(list).append("\r\n"); - curlen = headlen; - ptr = list + headlen; - numusers = 0; - } - - ptrlen = snprintf(ptr, MAXBUF-curlen, "%s,%s ", modestr.c_str(), i->first->uuid.c_str()); - - looped_once = true; - - curlen += ptrlen; - ptr += ptrlen; - - numusers++; - } - // Okay, permanent channels will (of course) need this \r\n anyway, numusers check is if there - // actually were people in the channel (looped_once == true) - if (!looped_once || numusers > 0) + for (UserMembCIter i = ulist->begin(); i != ulist->end(); ++i) { - // remove the final space - if (ptr[-1] == ' ') - ptr[-1] = '\0'; - buffer.append(list).append("\r\n"); - } - - int linesize = 1; - for (BanList::iterator b = c->bans.begin(); b != c->bans.end(); b++) - { - int size = b->data.length() + 2; - int currsize = linesize + size; - if (currsize <= 350) - { - modes.append("b"); - params.append(" ").append(b->data); - linesize += size; - } - if ((modes.length() >= ServerInstance->Config->Limits.MaxModes) || (currsize > 350)) + const std::string& modestr = i->second->modes; + if ((line.length() + modestr.length() + (UUID_LENGTH-1) + 2) > 480) { - /* Wrap at MAXMODES */ - buffer.append(":").append(ServerInstance->Config->GetSID()).append(" FMODE ").append(c->name).append(" ").append(ConvToStr(c->age)).append(" +").append(modes).append(params).append("\r\n"); - modes.clear(); - params.clear(); - linesize = 1; + this->WriteLine(line); + line.erase(erase_from); + line.append(" :"); } + line.append(modestr).append(1, ',').append(i->first->uuid).push_back(' '); } + this->WriteLine(line); - /* Only send these if there are any */ - if (!modes.empty()) - buffer.append(":").append(ServerInstance->Config->GetSID()).append(" FMODE ").append(c->name).append(" ").append(ConvToStr(c->age)).append(" +").append(modes).append(params); - - this->WriteLine(buffer); + ModeReference ban(NULL, "ban"); + static_cast(*ban)->DoSyncChannel(c, Utils->Creator, this); } -/** Send G, Q, Z and E lines */ -void TreeSocket::SendXLines(TreeServer* Current) +/** Send all XLines we know about */ +void TreeSocket::SendXLines() { char data[MAXBUF]; std::string n = ServerInstance->Config->GetSID(); const char* sn = n.c_str(); std::vector types = ServerInstance->XLines->GetAllTypes(); - time_t current = ServerInstance->Time(); - for (std::vector::iterator it = types.begin(); it != types.end(); ++it) + for (std::vector::const_iterator it = types.begin(); it != types.end(); ++it) { + /* Expired lines are removed in XLineManager::GetAll() */ XLineLookup* lookup = ServerInstance->XLines->GetAll(*it); + /* lookup cannot be NULL in this case but a check won't hurt */ if (lookup) { for (LookupIter i = lookup->begin(); i != lookup->end(); ++i) @@ -195,11 +142,6 @@ void TreeSocket::SendXLines(TreeServer* Current) if (!i->second->IsBurstable()) break; - /* If it's expired, don't bother to burst it - */ - if (i->second->duration && current > i->second->expiry) - continue; - snprintf(data,MAXBUF,":%s ADDLINE %s %s %s %lu %lu :%s",sn, it->c_str(), i->second->Displayable(), i->second->source.c_str(), (unsigned long)i->second->set_time, @@ -211,16 +153,16 @@ void TreeSocket::SendXLines(TreeServer* Current) } } -/** Send channel modes and topics */ -void TreeSocket::SendChannelModes(TreeServer* Current) +/** Send channel topic, modes and metadata */ +void TreeSocket::SendChannelModes() { char data[MAXBUF]; - std::deque list; std::string n = ServerInstance->Config->GetSID(); const char* sn = n.c_str(); + for (chan_hash::iterator c = ServerInstance->chanlist->begin(); c != ServerInstance->chanlist->end(); c++) { - SendFJoins(Current, c->second); + SendFJoins(c->second); if (!c->second->topic.empty()) { snprintf(data,MAXBUF,":%s FTOPIC %s %lu %s :%s", sn, c->second->name.c_str(), (unsigned long)c->second->topicset, c->second->setby.c_str(), c->second->topic.c_str()); @@ -240,7 +182,7 @@ void TreeSocket::SendChannelModes(TreeServer* Current) } /** send all users and their oper state/modes */ -void TreeSocket::SendUsers(TreeServer* Current) +void TreeSocket::SendUsers() { char data[MAXBUF]; std::string dataline; @@ -259,17 +201,17 @@ void TreeSocket::SendUsers(TreeServer* Current) u->second->host.c_str(), /* 3: Displayed Host */ u->second->dhost.c_str(), /* 4: Real host */ u->second->ident.c_str(), /* 5: Ident */ - u->second->GetIPString(), /* 6: IP string */ + u->second->GetIPString().c_str(), /* 6: IP string */ (unsigned long)u->second->signon, /* 7: Signon time for WHOWAS */ u->second->FormatModes(true), /* 8...n: Modes and params */ u->second->fullname.c_str()); /* size-1: GECOS */ this->WriteLine(data); - if (IS_OPER(u->second)) + if (u->second->IsOper()) { snprintf(data,MAXBUF,":%s OPERTYPE %s", u->second->uuid.c_str(), u->second->oper->name.c_str()); this->WriteLine(data); } - if (IS_AWAY(u->second)) + if (u->second->IsAway()) { snprintf(data,MAXBUF,":%s AWAY %ld :%s", u->second->uuid.c_str(), (long)u->second->awaytime, u->second->awaymsg.c_str()); this->WriteLine(data);