X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fserver.cpp;h=dbc51e37c3ee971d5c502c58c4f98ced4e33618b;hb=6cfabb0064cab52bbbab59974e53dc0fa1954da7;hp=66b175a1ad5d9785aed9cab63d78b75f5aeb3a4f;hpb=ad0828aa6431021df45563d34de9976b2d303098;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/server.cpp b/src/server.cpp index 66b175a1a..dbc51e37c 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -1,8 +1,15 @@ /* * InspIRCd -- Internet Relay Chat Daemon * + * Copyright (C) 2019 nia + * Copyright (C) 2013-2014, 2016 Attila Molnar + * Copyright (C) 2013, 2016-2017, 2020 Sadie Powell + * Copyright (C) 2013 Adam + * Copyright (C) 2012 Robby + * Copyright (C) 2012 ChrisTX + * Copyright (C) 2009 Uli Schlachter * Copyright (C) 2009 Daniel De Graaf - * Copyright (C) 2008 Craig Edwards + * Copyright (C) 2008, 2010 Craig Edwards * Copyright (C) 2007-2008 Robin Burchell * Copyright (C) 2007 Dennis Friis * @@ -20,9 +27,9 @@ */ -#include -#include "exitcodes.h" #include "inspircd.h" +#include "exitcodes.h" +#include void InspIRCd::SignalHandler(int signal) { @@ -31,12 +38,13 @@ void InspIRCd::SignalHandler(int signal) #else if (signal == SIGHUP) { - Rehash("Caught SIGHUP"); + ServerInstance->SNO->WriteGlobalSno('a', "Rehashing due to SIGHUP"); + Rehash(); } else if (signal == SIGTERM) #endif { - Exit(signal); + Exit(EXIT_STATUS_SIGTERM); } } @@ -45,32 +53,26 @@ void InspIRCd::Exit(int status) #ifdef _WIN32 SetServiceStopped(status); #endif - if (this) - { - this->SendError("Exiting with status " + ConvToStr(status) + " (" + std::string(ExitCodes[status]) + ")"); - this->Cleanup(); - delete this; - ServerInstance = NULL; - } + this->Cleanup(); + ServerInstance = NULL; + delete this; exit (status); } -void RehashHandler::Call(const std::string &reason) +void InspIRCd::Rehash(const std::string& uuid) { - ServerInstance->SNO->WriteToSnoMask('a', "Rehashing config file %s %s",ServerConfig::CleanFilename(ServerInstance->ConfigFileName.c_str()), reason.c_str()); - FOREACH_MOD(I_OnGarbageCollect, OnGarbageCollect()); if (!ServerInstance->ConfigThread) { - ServerInstance->ConfigThread = new ConfigReaderThread(""); - ServerInstance->Threads->Start(ServerInstance->ConfigThread); + ServerInstance->ConfigThread = new ConfigReaderThread(uuid); + ServerInstance->Threads.Start(ServerInstance->ConfigThread); } } std::string InspIRCd::GetVersionString(bool getFullVersion) { if (getFullVersion) - return VERSION " " + Config->ServerName + " :" SYSTEM " [" REVISION "," + SE->GetName() + "," + Config->sid + "]"; - return BRANCH " " + Config->ServerName + " :" + Config->CustomVersion; + return INSPIRCD_VERSION ". " + Config->ServerName + " :[" + Config->sid + "] " + Config->CustomVersion; + return INSPIRCD_BRANCH ". " + Config->GetServerName() + " :" + Config->CustomVersion; } std::string UIDGenerator::GenerateSID(const std::string& servername, const std::string& serverdesc) @@ -160,6 +162,27 @@ std::string UIDGenerator::GetUID() return current_uid; } +void ISupportManager::AppendValue(std::string& buffer, const std::string& value) +{ + // If this token has no value then we have nothing to do. + if (value.empty()) + return; + + // This function implements value escaping according to the rules of the ISUPPORT draft: + // https://tools.ietf.org/html/draft-brocklesby-irc-isupport-03 + buffer.push_back('='); + for (std::string::const_iterator iter = value.begin(); iter != value.end(); ++iter) + { + // The value must be escaped if: + // (1) It is a banned character in an IRC parameter (NUL, LF, CR, SPACE). + // (2) It has special meaning within an ISUPPORT token (EQUALS, BACKSLASH). + if (*iter == '\0' || *iter == '\n' || *iter == '\r' || *iter == ' ' || *iter == '=' || *iter == '\\') + buffer.append(InspIRCd::Format("\\x%X", *iter)); + else + buffer.push_back(*iter); + } +} + void ISupportManager::Build() { /** @@ -167,60 +190,62 @@ void ISupportManager::Build() * the future we can use an initializer list here. */ std::map tokens; - std::vector lines; - int token_count = 0; - std::string line; tokens["AWAYLEN"] = ConvToStr(ServerInstance->Config->Limits.MaxAway); - tokens["CASEMAPPING"] = "rfc1459"; - tokens["CHANMODES"] = ConvToStr(ServerInstance->Modes->GiveModeList(MASK_CHANNEL)); + tokens["CASEMAPPING"] = ServerInstance->Config->CaseMapping; + tokens["CHANLIMIT"] = InspIRCd::Format("#:%u", ServerInstance->Config->MaxChans); tokens["CHANNELLEN"] = ConvToStr(ServerInstance->Config->Limits.ChanMax); tokens["CHANTYPES"] = "#"; - tokens["CHARSET"] = "ascii"; - tokens["ELIST"] = "MU"; + tokens["HOSTLEN"] = ConvToStr(ServerInstance->Config->Limits.MaxHost); tokens["KICKLEN"] = ConvToStr(ServerInstance->Config->Limits.MaxKick); - tokens["MAXBANS"] = "64"; // TODO: make this a config setting. - tokens["MAXCHANNELS"] = ConvToStr(ServerInstance->Config->MaxChans); - tokens["MAXPARA"] = ConvToStr(MAXPARAMETERS); + tokens["LINELEN"] = ConvToStr(ServerInstance->Config->Limits.MaxLine); tokens["MAXTARGETS"] = ConvToStr(ServerInstance->Config->MaxTargets); tokens["MODES"] = ConvToStr(ServerInstance->Config->Limits.MaxModes); - tokens["NETWORK"] = ConvToStr(ServerInstance->Config->Network); + tokens["NAMELEN"] = ConvToStr(ServerInstance->Config->Limits.MaxReal); + tokens["NETWORK"] = ServerInstance->Config->Network; tokens["NICKLEN"] = ConvToStr(ServerInstance->Config->Limits.NickMax); tokens["PREFIX"] = ServerInstance->Modes->BuildPrefixes(); tokens["STATUSMSG"] = ServerInstance->Modes->BuildPrefixes(false); tokens["TOPICLEN"] = ConvToStr(ServerInstance->Config->Limits.MaxTopic); + tokens["USERLEN"] = ConvToStr(ServerInstance->Config->Limits.IdentMax); - tokens["FNC"] = tokens["MAP"] = tokens["VBANLIST"] = - tokens["WALLCHOPS"] = tokens["WALLVOICES"]; - - FOREACH_MOD(I_On005Numeric, On005Numeric(tokens)); + // Modules can add new tokens and also edit or remove existing tokens + FOREACH_MOD(On005Numeric, (tokens)); // EXTBAN is a special case as we need to sort it and prepend a comma. std::map::iterator extban = tokens.find("EXTBAN"); if (extban != tokens.end()) { - sort(extban->second.begin(), extban->second.end()); + std::sort(extban->second.begin(), extban->second.end()); extban->second.insert(0, ","); } - for (std::map::iterator it = tokens.begin(); it != tokens.end(); it++) + // Transform the map into a list of lines, ready to be sent to clients + Numeric::Numeric numeric(RPL_ISUPPORT); + unsigned int token_count = 0; + cachedlines.clear(); + + for (std::map::const_iterator it = tokens.begin(); it != tokens.end(); ++it) { - line.append(it->first + (it->second.empty() ? " " : "=" + it->second + " ")); + numeric.push(it->first); + std::string& token = numeric.GetParams().back(); + AppendValue(token, it->second); + token_count++; if (token_count % 13 == 12 || it == --tokens.end()) { - line.append(":are supported by this server"); - lines.push_back(line); - line.clear(); + // Reached maximum number of tokens for this line or the current token + // is the last one; finalize the line and store it for later use + numeric.push("are supported by this server"); + cachedlines.push_back(numeric); + numeric.GetParams().clear(); } } - - this->Lines = lines; } void ISupportManager::SendTo(LocalUser* user) { - for (std::vector::iterator line = this->Lines.begin(); line != this->Lines.end(); line++) - user->WriteNumeric(RPL_ISUPPORT, "%s %s", user->nick.c_str(), line->c_str()); + for (std::vector::const_iterator i = cachedlines.begin(); i != cachedlines.end(); ++i) + user->WriteNumeric(*i); }