X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fusers.cpp;h=0dc9cea573ced77a3893978e7e66986058b6dbb8;hb=3ae91bafe711b26ffae1aa27cfd4f5fe7bfc2347;hp=fb7c46d6b0e615bb5495ecc52725cb0f2be93235;hpb=a5fe50aca04ca554d313e7361c571c6a497a9c4e;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/users.cpp b/src/users.cpp index fb7c46d6b..0dc9cea57 100644 --- a/src/users.cpp +++ b/src/users.cpp @@ -108,26 +108,6 @@ std::string User::ProcessNoticeMasks(const char *sm) return output; } -void LocalUser::StartDNSLookup() -{ - try - { - bool cached = false; - UserResolver *res_reverse; - - QueryType resolvtype = this->client_sa.sa.sa_family == AF_INET6 ? DNS_QUERY_PTR6 : DNS_QUERY_PTR4; - res_reverse = new UserResolver(this, this->GetIPString(), resolvtype, cached); - - ServerInstance->AddResolver(res_reverse, cached); - } - catch (CoreException& e) - { - ServerInstance->Logs->Log("USERS", LOG_DEBUG,"Error in resolver: %s",e.GetReason()); - dns_done = true; - ServerInstance->stats->statsDnsBad++; - } -} - bool User::IsNoticeMaskSet(unsigned char sm) { if (!isalpha(sm)) @@ -142,18 +122,16 @@ void User::SetNoticeMask(unsigned char sm, bool value) snomasks[sm-65] = value; } -const char* User::FormatNoticeMasks() +std::string User::FormatNoticeMasks() { - static char data[MAXBUF]; - int offset = 0; + std::string data; - for (int n = 0; n < 64; n++) + for (unsigned char n = 0; n < 64; n++) { if (snomasks[n]) - data[offset++] = n+65; + data.push_back(n + 65); } - data[offset] = 0; return data; } @@ -173,15 +151,15 @@ void User::SetMode(unsigned char m, bool value) const char* User::FormatModes(bool showparameters) { - static char data[MAXBUF]; + static std::string data; std::string params; - int offset = 0; + data.clear(); for (unsigned char n = 0; n < 64; n++) { if (modes[n]) { - data[offset++] = n + 65; + data.push_back(n + 65); ModeHandler* mh = ServerInstance->Modes->FindMode(n + 65, MODETYPE_USER); if (showparameters && mh && mh->GetNumParams(true)) { @@ -191,9 +169,8 @@ const char* User::FormatModes(bool showparameters) } } } - data[offset] = 0; - strlcat(data, params.c_str(), MAXBUF); - return data; + data += params; + return data.c_str(); } User::User(const std::string &uid, const std::string& sid, int type) @@ -215,12 +192,12 @@ User::User(const std::string &uid, const std::string& sid, int type) } LocalUser::LocalUser(int myfd, irc::sockets::sockaddrs* client, irc::sockets::sockaddrs* servaddr) - : User(ServerInstance->GetUID(), ServerInstance->Config->ServerName, USERTYPE_LOCAL), eh(this), + : User(ServerInstance->UIDGen.GetUID(), ServerInstance->Config->ServerName, USERTYPE_LOCAL), eh(this), localuseriter(ServerInstance->Users->local_users.end()), bytes_in(0), bytes_out(0), cmds_in(0), cmds_out(0), nping(0), CommandFloodPenalty(0), already_sent(0) { - exempt = quitting_sendq = dns_done = false; + exempt = quitting_sendq = false; idle_lastmsg = 0; ident = "unknown"; lastping = 0; @@ -241,18 +218,8 @@ const std::string& User::MakeHost() if (!this->cached_makehost.empty()) return this->cached_makehost; - char nhost[MAXBUF]; - /* This is much faster than snprintf */ - char* t = nhost; - for(const char* n = ident.c_str(); *n; n++) - *t++ = *n; - *t++ = '@'; - for(const char* n = host.c_str(); *n; n++) - *t++ = *n; - *t = 0; - - this->cached_makehost.assign(nhost); - + // XXX: Is there really a need to cache this? + this->cached_makehost = ident + "@" + host; return this->cached_makehost; } @@ -261,18 +228,8 @@ const std::string& User::MakeHostIP() if (!this->cached_hostip.empty()) return this->cached_hostip; - char ihost[MAXBUF]; - /* This is much faster than snprintf */ - char* t = ihost; - for(const char* n = ident.c_str(); *n; n++) - *t++ = *n; - *t++ = '@'; - for(const char* n = this->GetIPString().c_str(); *n; n++) - *t++ = *n; - *t = 0; - - this->cached_hostip = ihost; - + // XXX: Is there really a need to cache this? + this->cached_hostip = ident + "@" + this->GetIPString(); return this->cached_hostip; } @@ -281,91 +238,37 @@ const std::string& User::GetFullHost() if (!this->cached_fullhost.empty()) return this->cached_fullhost; - char result[MAXBUF]; - char* t = result; - for(const char* n = nick.c_str(); *n; n++) - *t++ = *n; - *t++ = '!'; - for(const char* n = ident.c_str(); *n; n++) - *t++ = *n; - *t++ = '@'; - for(const char* n = dhost.c_str(); *n; n++) - *t++ = *n; - *t = 0; - - this->cached_fullhost = result; - + // XXX: Is there really a need to cache this? + this->cached_fullhost = nick + "!" + ident + "@" + dhost; return this->cached_fullhost; } -char* User::MakeWildHost() -{ - static char nresult[MAXBUF]; - char* t = nresult; - *t++ = '*'; *t++ = '!'; - *t++ = '*'; *t++ = '@'; - for(const char* n = dhost.c_str(); *n; n++) - *t++ = *n; - *t = 0; - return nresult; -} - const std::string& User::GetFullRealHost() { if (!this->cached_fullrealhost.empty()) return this->cached_fullrealhost; - char fresult[MAXBUF]; - char* t = fresult; - for(const char* n = nick.c_str(); *n; n++) - *t++ = *n; - *t++ = '!'; - for(const char* n = ident.c_str(); *n; n++) - *t++ = *n; - *t++ = '@'; - for(const char* n = host.c_str(); *n; n++) - *t++ = *n; - *t = 0; - - this->cached_fullrealhost = fresult; - + // XXX: Is there really a need to cache this? + this->cached_fullrealhost = nick + "!" + ident + "@" + host; return this->cached_fullrealhost; } -bool LocalUser::IsInvited(const irc::string &channel) -{ - Channel* chan = ServerInstance->FindChan(channel.c_str()); - if (!chan) - return false; - - return (Invitation::Find(chan, this) != NULL); -} - InviteList& LocalUser::GetInviteList() { RemoveExpiredInvites(); return invites; } -void LocalUser::InviteTo(const irc::string &channel, time_t invtimeout) -{ - Channel* chan = ServerInstance->FindChan(channel.c_str()); - if (chan) - Invitation::Create(chan, this, invtimeout); -} - -void LocalUser::RemoveInvite(const irc::string &channel) +bool LocalUser::RemoveInvite(Channel* chan) { - Channel* chan = ServerInstance->FindChan(channel.c_str()); - if (chan) + Invitation* inv = Invitation::Find(chan, this); + if (inv) { - Invitation* inv = Invitation::Find(chan, this); - if (inv) - { - inv->cull(); - delete inv; - } + inv->cull(); + delete inv; + return true; } + return false; } void LocalUser::RemoveExpiredInvites() @@ -426,7 +329,7 @@ bool LocalUser::HasPrivPermission(const std::string &privstr, bool noisy) if (!this->IsOper()) { if (noisy) - this->WriteServ("NOTICE %s :You are not an oper", this->nick.c_str()); + this->WriteNotice("You are not an oper"); return false; } @@ -440,7 +343,8 @@ bool LocalUser::HasPrivPermission(const std::string &privstr, bool noisy) } if (noisy) - this->WriteServ("NOTICE %s :Oper type %s does not have access to priv %s", this->nick.c_str(), oper->NameStr(), privstr.c_str()); + this->WriteNotice("Oper type " + oper->name + " does not have access to priv " + privstr); + return false; } @@ -454,6 +358,7 @@ void UserIOHandler::OnDataReady() ServerInstance->Users->QuitUser(user, "RecvQ exceeded"); ServerInstance->SNO->WriteToSnoMask('a', "User %s RecvQ of %lu exceeds connect class maximum of %lu", user->nick.c_str(), (unsigned long)recvq.length(), user->MyClass->GetRecvqMax()); + return; } unsigned long sendqmax = ULONG_MAX; if (!user->HasPrivPermission("users/flood/increased-buffers")) @@ -465,7 +370,7 @@ void UserIOHandler::OnDataReady() while (user->CommandFloodPenalty < penaltymax && getSendQSize() < sendqmax) { std::string line; - line.reserve(MAXBUF); + line.reserve(ServerInstance->Config->Limits.MaxLine); std::string::size_type qpos = 0; while (qpos < recvq.length()) { @@ -480,7 +385,7 @@ void UserIOHandler::OnDataReady() case '\n': goto eol_found; } - if (line.length() < MAXBUF - 2) + if (line.length() < ServerInstance->Config->Limits.MaxLine - 2) line.push_back(c); } // if we got here, the recvq ran out before we found a newline @@ -543,7 +448,12 @@ CullResult LocalUser::cull() // overwritten in UserManager::AddUser() with the real iterator so this check // is only a precaution currently. if (localuseriter != ServerInstance->Users->local_users.end()) + { + ServerInstance->Users->local_count--; ServerInstance->Users->local_users.erase(localuseriter); + } + else + ServerInstance->Logs->Log("USERS", LOG_DEFAULT, "ERROR: LocalUserIter does not point to a valid entry for " + this->nick); ClearInvites(); eh.cull(); @@ -585,10 +495,10 @@ void User::Oper(OperInfo* info) } ServerInstance->SNO->WriteToSnoMask('o',"%s (%s@%s) is now an IRC operator of type %s (using oper '%s')", - nick.c_str(), ident.c_str(), host.c_str(), oper->NameStr(), opername.c_str()); - this->WriteNumeric(381, "%s :You are now %s %s", nick.c_str(), strchr("aeiouAEIOU", oper->name[0]) ? "an" : "a", oper->NameStr()); + nick.c_str(), ident.c_str(), host.c_str(), oper->name.c_str(), opername.c_str()); + this->WriteNumeric(381, "%s :You are now %s %s", nick.c_str(), strchr("aeiouAEIOU", oper->name[0]) ? "an" : "a", oper->name.c_str()); - ServerInstance->Logs->Log("OPER", LOG_DEFAULT, "%s opered as type: %s", GetFullRealHost().c_str(), oper->NameStr()); + ServerInstance->Logs->Log("OPER", LOG_DEFAULT, "%s opered as type: %s", GetFullRealHost().c_str(), oper->name.c_str()); ServerInstance->Users->all_opers.push_back(this); // Expand permissions from config for faster lookup @@ -690,7 +600,7 @@ void User::UnOper() /* * Check class restrictions */ -void LocalUser::CheckClass() +void LocalUser::CheckClass(bool clone_count) { ConnectClass* a = this->MyClass; @@ -704,19 +614,22 @@ void LocalUser::CheckClass() ServerInstance->Users->QuitUser(this, a->config->getString("reason", "Unauthorised connection")); return; } - else if ((a->GetMaxLocal()) && (ServerInstance->Users->LocalCloneCount(this) > a->GetMaxLocal())) + else if (clone_count) { - ServerInstance->Users->QuitUser(this, "No more connections allowed from your host via this connect class (local)"); - if (a->maxconnwarn) - ServerInstance->SNO->WriteToSnoMask('a', "WARNING: maximum LOCAL connections (%ld) exceeded for IP %s", a->GetMaxLocal(), this->GetIPString().c_str()); - return; - } - else if ((a->GetMaxGlobal()) && (ServerInstance->Users->GlobalCloneCount(this) > a->GetMaxGlobal())) - { - ServerInstance->Users->QuitUser(this, "No more connections allowed from your host via this connect class (global)"); - if (a->maxconnwarn) - ServerInstance->SNO->WriteToSnoMask('a', "WARNING: maximum GLOBAL connections (%ld) exceeded for IP %s", a->GetMaxGlobal(), this->GetIPString().c_str()); - return; + if ((a->GetMaxLocal()) && (ServerInstance->Users->LocalCloneCount(this) > a->GetMaxLocal())) + { + ServerInstance->Users->QuitUser(this, "No more connections allowed from your host via this connect class (local)"); + if (a->maxconnwarn) + ServerInstance->SNO->WriteToSnoMask('a', "WARNING: maximum LOCAL connections (%ld) exceeded for IP %s", a->GetMaxLocal(), this->GetIPString().c_str()); + return; + } + else if ((a->GetMaxGlobal()) && (ServerInstance->Users->GlobalCloneCount(this) > a->GetMaxGlobal())) + { + ServerInstance->Users->QuitUser(this, "No more connections allowed from your host via this connect class (global)"); + if (a->maxconnwarn) + ServerInstance->SNO->WriteToSnoMask('a', "WARNING: maximum GLOBAL connections (%ld) exceeded for IP %s", a->GetMaxGlobal(), this->GetIPString().c_str()); + return; + } } this->nping = ServerInstance->Time() + a->GetPingTime() + ServerInstance->Config->dns_timeout; @@ -766,10 +679,8 @@ void LocalUser::FullConnect() this->WriteNumeric(RPL_YOURHOSTIS, "%s :Your host is %s, running version %s",this->nick.c_str(),ServerInstance->Config->ServerName.c_str(),BRANCH); this->WriteNumeric(RPL_SERVERCREATED, "%s :This server was created %s %s", this->nick.c_str(), __TIME__, __DATE__); - std::string umlist = ServerInstance->Modes->UserModeList(); - std::string cmlist = ServerInstance->Modes->ChannelModeList(); - std::string pmlist = ServerInstance->Modes->ParaModeList(); - this->WriteNumeric(RPL_SERVERVERSION, "%s %s %s %s %s %s", this->nick.c_str(), ServerInstance->Config->ServerName.c_str(), BRANCH, umlist.c_str(), cmlist.c_str(), pmlist.c_str()); + const std::string& modelist = ServerInstance->Modes->GetModeListFor004Numeric(); + this->WriteNumeric(RPL_SERVERVERSION, "%s %s %s %s", this->nick.c_str(), ServerInstance->Config->ServerName.c_str(), BRANCH, modelist.c_str()); ServerInstance->ISupport.SendTo(this); this->WriteNumeric(RPL_YOURUUID, "%s %s :your unique ID", this->nick.c_str(), this->uuid.c_str()); @@ -824,19 +735,24 @@ void User::InvalidateCache() bool User::ChangeNick(const std::string& newnick, bool force) { - ModResult MOD_RESULT; - - if (force) - ServerInstance->NICKForced.set(this, 1); - FIRST_MOD_RESULT(OnUserPreNick, MOD_RESULT, (this, newnick)); - ServerInstance->NICKForced.set(this, 0); - - if (MOD_RESULT == MOD_RES_DENY) + if (quitting) { - ServerInstance->stats->statsCollisions++; + ServerInstance->Logs->Log("USERS", LOG_DEFAULT, "ERROR: Attempted to change nick of a quitting user: " + this->nick); return false; } + if (!force) + { + ModResult MOD_RESULT; + FIRST_MOD_RESULT(OnUserPreNick, MOD_RESULT, (this, newnick)); + + if (MOD_RESULT == MOD_RES_DENY) + { + ServerInstance->stats->statsCollisions++; + return false; + } + } + if (assign(newnick) == assign(nick)) { // case change, don't need to check Q:lines and such @@ -1024,10 +940,10 @@ void LocalUser::Write(const std::string& text) if (!ServerInstance->SE->BoundsCheckFd(&eh)) return; - if (text.length() > MAXBUF - 2) + if (text.length() > ServerInstance->Config->Limits.MaxLine - 2) { // this should happen rarely or never. Crop the string at 512 and try again. - std::string try_again = text.substr(0, MAXBUF - 2); + std::string try_again = text.substr(0, ServerInstance->Config->Limits.MaxLine - 2); Write(try_again); return; } @@ -1046,14 +962,9 @@ void LocalUser::Write(const std::string& text) */ void LocalUser::Write(const char *text, ...) { - va_list argsPtr; - char textbuffer[MAXBUF]; - - va_start(argsPtr, text); - vsnprintf(textbuffer, MAXBUF, text, argsPtr); - va_end(argsPtr); - - this->Write(std::string(textbuffer)); + std::string textbuffer; + VAFORMAT(textbuffer, text, text); + this->Write(textbuffer); } void User::WriteServ(const std::string& text) @@ -1066,50 +977,41 @@ void User::WriteServ(const std::string& text) */ void User::WriteServ(const char* text, ...) { - va_list argsPtr; - char textbuffer[MAXBUF]; - - va_start(argsPtr, text); - vsnprintf(textbuffer, MAXBUF, text, argsPtr); - va_end(argsPtr); - - this->WriteServ(std::string(textbuffer)); + std::string textbuffer; + VAFORMAT(textbuffer, text, text); + this->WriteServ(textbuffer); } +void User::WriteNotice(const std::string& text) +{ + this->WriteServ("NOTICE " + (this->registered == REG_ALL ? this->nick : "*") + " :" + text); +} void User::WriteNumeric(unsigned int numeric, const char* text, ...) { - va_list argsPtr; - char textbuffer[MAXBUF]; - - va_start(argsPtr, text); - vsnprintf(textbuffer, MAXBUF, text, argsPtr); - va_end(argsPtr); - - this->WriteNumeric(numeric, std::string(textbuffer)); + std::string textbuffer; + VAFORMAT(textbuffer, text, text); + this->WriteNumeric(numeric, textbuffer); } void User::WriteNumeric(unsigned int numeric, const std::string &text) { - char textbuffer[MAXBUF]; ModResult MOD_RESULT; FIRST_MOD_RESULT(OnNumeric, MOD_RESULT, (this, numeric, text)); if (MOD_RESULT == MOD_RES_DENY) return; - - snprintf(textbuffer,MAXBUF,":%s %03u %s",ServerInstance->Config->ServerName.c_str(), numeric, text.c_str()); - this->Write(std::string(textbuffer)); + + const std::string message = InspIRCd::Format(":%s %03u %s", ServerInstance->Config->ServerName.c_str(), + numeric, text.c_str()); + this->Write(message); } void User::WriteFrom(User *user, const std::string &text) { - char tb[MAXBUF]; - - snprintf(tb,MAXBUF,":%s %s",user->GetFullHost().c_str(),text.c_str()); - - this->Write(std::string(tb)); + const std::string message = ":" + user->GetFullHost() + " " + text; + this->Write(message); } @@ -1117,14 +1019,9 @@ void User::WriteFrom(User *user, const std::string &text) void User::WriteFrom(User *user, const char* text, ...) { - va_list argsPtr; - char textbuffer[MAXBUF]; - - va_start(argsPtr, text); - vsnprintf(textbuffer, MAXBUF, text, argsPtr); - va_end(argsPtr); - - this->WriteFrom(user, std::string(textbuffer)); + std::string textbuffer; + VAFORMAT(textbuffer, text, text); + this->WriteFrom(user, textbuffer); } @@ -1132,14 +1029,9 @@ void User::WriteFrom(User *user, const char* text, ...) void User::WriteTo(User *dest, const char *data, ...) { - char textbuffer[MAXBUF]; - va_list argsPtr; - - va_start(argsPtr, data); - vsnprintf(textbuffer, MAXBUF, data, argsPtr); - va_end(argsPtr); - - this->WriteTo(dest, std::string(textbuffer)); + std::string textbuffer; + VAFORMAT(textbuffer, data, data); + this->WriteTo(dest, textbuffer); } void User::WriteTo(User *dest, const std::string &data) @@ -1149,36 +1041,24 @@ void User::WriteTo(User *dest, const std::string &data) void User::WriteCommon(const char* text, ...) { - char textbuffer[MAXBUF]; - va_list argsPtr; - if (this->registered != REG_ALL || quitting) return; - int len = snprintf(textbuffer,MAXBUF,":%s ",this->GetFullHost().c_str()); - - va_start(argsPtr, text); - vsnprintf(textbuffer + len, MAXBUF - len, text, argsPtr); - va_end(argsPtr); - - this->WriteCommonRaw(std::string(textbuffer), true); + std::string textbuffer; + VAFORMAT(textbuffer, text, text); + textbuffer = ":" + this->GetFullHost() + " " + textbuffer; + this->WriteCommonRaw(textbuffer, true); } void User::WriteCommonExcept(const char* text, ...) { - char textbuffer[MAXBUF]; - va_list argsPtr; - if (this->registered != REG_ALL || quitting) return; - int len = snprintf(textbuffer,MAXBUF,":%s ",this->GetFullHost().c_str()); - - va_start(argsPtr, text); - vsnprintf(textbuffer + len, MAXBUF - len, text, argsPtr); - va_end(argsPtr); - - this->WriteCommonRaw(std::string(textbuffer), false); + std::string textbuffer; + VAFORMAT(textbuffer, text, text); + textbuffer = ":" + this->GetFullHost() + " " + textbuffer; + this->WriteCommonRaw(textbuffer, false); } void User::WriteCommonRaw(const std::string &line, bool include_self) @@ -1223,18 +1103,13 @@ void User::WriteCommonRaw(const std::string &line, bool include_self) void User::WriteCommonQuit(const std::string &normal_text, const std::string &oper_text) { - char tb1[MAXBUF]; - char tb2[MAXBUF]; - if (this->registered != REG_ALL) return; already_sent_t uniq_id = ++LocalUser::already_sent_id; - snprintf(tb1,MAXBUF,":%s QUIT :%s",this->GetFullHost().c_str(),normal_text.c_str()); - snprintf(tb2,MAXBUF,":%s QUIT :%s",this->GetFullHost().c_str(),oper_text.c_str()); - std::string out1 = tb1; - std::string out2 = tb2; + const std::string normalMessage = ":" + this->GetFullHost() + " QUIT :" + normal_text; + const std::string operMessage = ":" + this->GetFullHost() + " QUIT :" + oper_text; UserChanList include_c(chans); std::map exceptions; @@ -1248,7 +1123,7 @@ void User::WriteCommonQuit(const std::string &normal_text, const std::string &op { u->already_sent = uniq_id; if (i->second) - u->Write(u->IsOper() ? out2 : out1); + u->Write(u->IsOper() ? operMessage : normalMessage); } } for (UCListIter v = include_c.begin(); v != include_c.end(); ++v) @@ -1260,7 +1135,7 @@ void User::WriteCommonQuit(const std::string &normal_text, const std::string &op if (u && !u->quitting && (u->already_sent != uniq_id)) { u->already_sent = uniq_id; - u->Write(u->IsOper() ? out2 : out1); + u->Write(u->IsOper() ? operMessage : normalMessage); } } } @@ -1282,38 +1157,26 @@ void FakeUser::SendText(const std::string& line) void User::SendText(const char *text, ...) { - va_list argsPtr; - char line[MAXBUF]; - - va_start(argsPtr, text); - vsnprintf(line, MAXBUF, text, argsPtr); - va_end(argsPtr); - - SendText(std::string(line)); + std::string line; + VAFORMAT(line, text, text); + SendText(line); } -void User::SendText(const std::string &LinePrefix, std::stringstream &TextStream) +void User::SendText(const std::string& linePrefix, std::stringstream& textStream) { - char line[MAXBUF]; - int start_pos = LinePrefix.length(); - int pos = start_pos; - memcpy(line, LinePrefix.data(), pos); - std::string Word; - while (TextStream >> Word) + std::string line; + std::string word; + while (textStream >> word) { - int len = Word.length(); - if (pos + len + 12 > MAXBUF) + size_t lineLength = linePrefix.length() + line.length() + word.length() + 3; // "\s\n\r" + if (lineLength > ServerInstance->Config->Limits.MaxLine) { - line[pos] = '\0'; - SendText(std::string(line)); - pos = start_pos; + SendText(linePrefix + line); + line.clear(); } - line[pos] = ' '; - memcpy(line + pos + 1, Word.data(), len); - pos += len + 1; + line += " " + word; } - line[pos] = '\0'; - SendText(std::string(line)); + SendText(linePrefix + line); } /* return 0 or 1 depending if users u and u2 share one or more common channels @@ -1365,8 +1228,6 @@ bool User::ChangeName(const char* gecos) void User::DoHostCycle(const std::string &quitline) { - char buffer[MAXBUF]; - if (!ServerInstance->Config->CycleHosts) return; @@ -1397,18 +1258,17 @@ void User::DoHostCycle(const std::string &quitline) for (UCListIter v = include_c.begin(); v != include_c.end(); ++v) { Channel* c = *v; - snprintf(buffer, MAXBUF, ":%s JOIN %s", GetFullHost().c_str(), c->name.c_str()); - std::string joinline(buffer); Membership* memb = c->GetUser(this); - std::string modeline = memb->modes; - if (modeline.length() > 0) + const std::string joinline = ":" + GetFullHost() + " JOIN " + c->name; + std::string modeline; + + if (!memb->modes.empty()) { - for(unsigned int i=0; i < memb->modes.length(); i++) + modeline = ":" + (ServerInstance->Config->CycleHostsFromUser ? GetFullHost() : ServerInstance->Config->ServerName) + + " MODE " + c->name + " +" + memb->modes; + + for (size_t i = 0; i < memb->modes.length(); i++) modeline.append(" ").append(nick); - snprintf(buffer, MAXBUF, ":%s MODE %s +%s", - ServerInstance->Config->CycleHostsFromUser ? GetFullHost().c_str() : ServerInstance->Config->ServerName.c_str(), - c->name.c_str(), modeline.c_str()); - modeline = buffer; } const UserMembList *ulist = c->GetUsers(); @@ -1426,7 +1286,7 @@ void User::DoHostCycle(const std::string &quitline) u->already_sent = seen_id; } u->Write(joinline); - if (modeline.length() > 0) + if (!memb->modes.empty()) u->Write(modeline); } } @@ -1482,21 +1342,14 @@ bool User::ChangeIdent(const char* newident) void User::SendAll(const char* command, const char* text, ...) { - char textbuffer[MAXBUF]; - char formatbuffer[MAXBUF]; - va_list argsPtr; - - va_start(argsPtr, text); - vsnprintf(textbuffer, MAXBUF, text, argsPtr); - va_end(argsPtr); - - snprintf(formatbuffer,MAXBUF,":%s %s $* :%s", this->GetFullHost().c_str(), command, textbuffer); - std::string fmt = formatbuffer; + std::string textbuffer; + VAFORMAT(textbuffer, text, text); + const std::string message = ":" + this->GetFullHost() + " " + command + " $* :" + textbuffer; for (LocalUserList::const_iterator i = ServerInstance->Users->local_users.begin(); i != ServerInstance->Users->local_users.end(); i++) { if ((*i)->registered == REG_ALL) - (*i)->Write(fmt); + (*i)->Write(message); } } @@ -1648,7 +1501,8 @@ const std::string& FakeUser::GetFullRealHost() ConnectClass::ConnectClass(ConfigTag* tag, char t, const std::string& mask) : config(tag), type(t), fakelag(true), name("unnamed"), registration_timeout(0), host(mask), pingtime(0), softsendqmax(0), hardsendqmax(0), recvqmax(0), - penaltythreshold(0), commandrate(0), maxlocal(0), maxglobal(0), maxconnwarn(true), maxchans(0), limit(0) + penaltythreshold(0), commandrate(0), maxlocal(0), maxglobal(0), maxconnwarn(true), maxchans(0), + limit(0), nouserdns(false) { } @@ -1658,7 +1512,7 @@ ConnectClass::ConnectClass(ConfigTag* tag, char t, const std::string& mask, cons softsendqmax(parent.softsendqmax), hardsendqmax(parent.hardsendqmax), recvqmax(parent.recvqmax), penaltythreshold(parent.penaltythreshold), commandrate(parent.commandrate), maxlocal(parent.maxlocal), maxglobal(parent.maxglobal), maxconnwarn(parent.maxconnwarn), maxchans(parent.maxchans), - limit(parent.limit) + limit(parent.limit), nouserdns(parent.nouserdns) { } @@ -1681,4 +1535,5 @@ void ConnectClass::Update(const ConnectClass* src) maxconnwarn = src->maxconnwarn; maxchans = src->maxchans; limit = src->limit; + nouserdns = src->nouserdns; }