#include "inspircd.h"
-#include <fstream>
#include "xline.h"
#include "listmode.h"
#include "exitcodes.h"
ServerConfig::ServerConfig()
{
RawLog = HideBans = HideSplits = UndernetMsgPrefix = false;
- WildcardIPv6 = CycleHosts = InvBypassModes = true;
+ WildcardIPv6 = InvBypassModes = true;
dns_timeout = 5;
MaxTargets = 20;
NetBufferSize = 10240;
c_ipv6_range = 128;
}
-template<typename T, typename V>
-static void range(T& value, V min, V max, V def, const char* msg)
-{
- if (value >= (T)min && value <= (T)max)
- return;
- ServerInstance->Logs->Log("CONFIG", LOG_DEFAULT, "WARNING: %s value of %ld is not between %ld and %ld; set to %ld.",
- msg, (long)value, (long)min, (long)max, (long)def);
- value = def;
-}
-
static void ValidHost(const std::string& p, const std::string& msg)
{
int num_dots = 0;
std::string name = tag->getString("name");
if (name.empty())
throw CoreException("<type:name> is missing from tag at " + tag->getTagLocation());
- if (oper_blocks.find(" " + name) != oper_blocks.end())
+ if (OperTypes.find(name) != OperTypes.end())
throw CoreException("Duplicate type block with name " + name + " at " + tag->getTagLocation());
OperInfo* ifo = new OperInfo;
- oper_blocks[" " + name] = ifo;
+ OperTypes[name] = ifo;
ifo->name = name;
ifo->type_block = tag;
throw CoreException("<oper:name> missing from tag at " + tag->getTagLocation());
std::string type = tag->getString("type");
- OperIndex::iterator tblk = oper_blocks.find(" " + type);
- if (tblk == oper_blocks.end())
+ OperIndex::iterator tblk = OperTypes.find(type);
+ if (tblk == OperTypes.end())
throw CoreException("Oper block " + name + " has missing type " + type);
if (oper_blocks.find(name) != oper_blocks.end())
throw CoreException("Duplicate oper block with name " + name + " at " + tag->getTagLocation());
me->maxchans = tag->getInt("maxchans", me->maxchans);
me->maxconnwarn = tag->getBool("maxconnwarn", me->maxconnwarn);
me->limit = tag->getInt("limit", me->limit);
- me->nouserdns = tag->getBool("nouserdns", me->nouserdns);
+ me->resolvehostnames = tag->getBool("resolvehostnames", me->resolvehostnames);
ClassMap::iterator oldMask = oldBlocksByMask.find(typeMask);
if (oldMask != oldBlocksByMask.end())
{ "link", "transport", "", "has been moved to <link:ssl> as of 2.0" },
{ "module", "name", "m_chanprotect.so", "has been replaced with m_customprefix as of 2.2" },
{ "module", "name", "m_halfop.so", "has been replaced with m_customprefix as of 2.2" },
- { "performance", "nouserdns", "", "has been moved to <connect:nouserdns> as of 2.2" }
+ { "options", "cyclehosts", "", "has been replaced with m_hostcycle as of 2.2" },
+ { "performance", "nouserdns", "", "has been moved to <connect:resolvehostnames> as of 2.2" }
};
void ServerConfig::Fill()
ConfigTag* security = ConfValue("security");
if (sid.empty())
{
- ServerName = ConfValue("server")->getString("name");
- sid = ConfValue("server")->getString("id");
+ ServerName = ConfValue("server")->getString("name", "irc.example.com");
ValidHost(ServerName, "<server:name>");
+
+ sid = ConfValue("server")->getString("id");
if (!sid.empty() && !InspIRCd::IsSID(sid))
throw CoreException(sid + " is not a valid server ID. A server ID must be 3 characters long, with the first character a digit and the next two characters a digit or letter.");
}
else
{
if (ServerName != ConfValue("server")->getString("name"))
- throw CoreException("You must restart to change the server name or SID");
+ throw CoreException("You must restart to change the server name");
+
std::string nsid = ConfValue("server")->getString("id");
if (!nsid.empty() && nsid != sid)
- throw CoreException("You must restart to change the server name or SID");
+ throw CoreException("You must restart to change the server id");
}
diepass = ConfValue("power")->getString("diepass");
restartpass = ConfValue("power")->getString("restartpass");
PrefixPart = options->getString("prefixpart");
SuffixPart = options->getString("suffixpart");
FixedPart = options->getString("fixedpart");
- SoftLimit = ConfValue("performance")->getInt("softlimit", ServerInstance->SE->GetMaxFds());
+ SoftLimit = ConfValue("performance")->getInt("softlimit", ServerInstance->SE->GetMaxFds(), 10, ServerInstance->SE->GetMaxFds());
+ CCOnConnect = ConfValue("performance")->getBool("clonesonconnect", true);
MaxConn = ConfValue("performance")->getInt("somaxconn", SOMAXCONN);
- MoronBanner = options->getString("moronbanner", "You're banned!");
+ XLineMessage = options->getString("xlinemessage", options->getString("moronbanner", "You're banned!"));
ServerDesc = ConfValue("server")->getString("description", "Configure Me");
Network = ConfValue("server")->getString("network", "Network");
AdminName = ConfValue("admin")->getString("name", "");
AdminEmail = ConfValue("admin")->getString("email", "null@example.com");
AdminNick = ConfValue("admin")->getString("nick", "admin");
- ModPath = ConfValue("path")->getString("moduledir", MOD_PATH);
- NetBufferSize = ConfValue("performance")->getInt("netbuffersize", 10240);
+ NetBufferSize = ConfValue("performance")->getInt("netbuffersize", 10240, 1024, 65534);
dns_timeout = ConfValue("dns")->getInt("timeout", 5);
DisabledCommands = ConfValue("disabled")->getString("commands", "");
DisabledDontExist = ConfValue("disabled")->getBool("fakenonexistant");
UserStats = security->getString("userstats");
- CustomVersion = security->getString("customversion", Network + " IRCd");
+ CustomVersion = security->getString("customversion");
HideSplits = security->getBool("hidesplits");
HideBans = security->getBool("hidebans");
HideWhoisServer = security->getString("hidewhois");
RestrictBannedUsers = security->getBool("restrictbannedusers", true);
GenericOper = security->getBool("genericoper");
SyntaxHints = options->getBool("syntaxhints");
- CycleHosts = options->getBool("cyclehosts");
CycleHostsFromUser = options->getBool("cyclehostsfromuser");
UndernetMsgPrefix = options->getBool("ircumsgprefix");
FullHostInTopic = options->getBool("hostintopic");
- MaxTargets = security->getInt("maxtargets", 20);
- DefaultModes = options->getString("defaultmodes", "nt");
+ MaxTargets = security->getInt("maxtargets", 20, 1, 31);
+ DefaultModes = options->getString("defaultmodes", "not");
PID = ConfValue("pid")->getString("file");
MaxChans = ConfValue("channels")->getInt("users", 20);
OperMaxChans = ConfValue("channels")->getInt("opers", 60);
Limits.MaxKick = ConfValue("limits")->getInt("maxkick", 255);
Limits.MaxGecos = ConfValue("limits")->getInt("maxgecos", 128);
Limits.MaxAway = ConfValue("limits")->getInt("maxaway", 200);
+ Limits.MaxLine = ConfValue("limits")->getInt("maxline", 512);
+ Paths.Config = ConfValue("path")->getString("configdir", CONFIG_PATH);
+ Paths.Data = ConfValue("path")->getString("datadir", DATA_PATH);
+ Paths.Log = ConfValue("path")->getString("logdir", LOG_PATH);
+ Paths.Module = ConfValue("path")->getString("moduledir", MOD_PATH);
InvBypassModes = options->getBool("invitebypassmodes", true);
NoSnoticeStack = options->getBool("nosnoticestack", false);
- range(SoftLimit, 10, ServerInstance->SE->GetMaxFds(), ServerInstance->SE->GetMaxFds(), "<performance:softlimit>");
- if (ConfValue("performance")->getBool("limitsomaxconn", true))
- range(MaxConn, 0, SOMAXCONN, SOMAXCONN, "<performance:somaxconn>");
- range(MaxTargets, 1, 31, 20, "<security:maxtargets>");
- range(NetBufferSize, 1024, 65534, 10240, "<performance:netbuffersize>");
+ if (Network.find(' ') != std::string::npos)
+ throw CoreException(Network + " is not a valid network name. A network name must not contain spaces.");
std::string defbind = options->getString("defaultbind");
if (assign(defbind) == "ipv4")
std::string server;
if (!tag->readString("server", server))
throw CoreException("<uline> tag missing server at " + tag->getTagLocation());
+
+ if (ServerName == server)
+ throw CoreException("Servers should not uline themselves (at " + tag->getTagLocation() + ")");
+
ulines[assign(server)] = tag->getBool("silent");
}
{
errstr << ' ' << ChangedConfig[index].key << "=\"" << ChangedConfig[index].value << "\"";
}
- errstr << "> - " << ChangedConfig[index].reason << " (at " << i->second->getTagLocation() << ")\n";
+ errstr << "> - " << ChangedConfig[index].reason << " (at " << i->second->getTagLocation() << ")" << std::endl;
}
}
}
if (valid)
ServerInstance->WritePID(this->PID);
+ ConfigTagList binds = ConfTags("bind");
+ if (binds.first == binds.second)
+ errstr << "Possible configuration error: you have not defined any <bind> blocks." << std::endl
+ << "You will need to do this if you want clients to be able to connect!" << std::endl;
+
if (old)
{
// On first run, ports are bound later on
}
}
- if (ConfValue("options")->getBool("allowhalfop") && removed_modules.erase("m_halfop.so") == 0)
- added_modules.push_back("m_halfop.so");
-
for (std::set<std::string>::iterator removing = removed_modules.begin(); removing != removed_modules.end(); removing++)
{
// Don't remove cmd_*.so, just remove m_*.so
if ((sb.st_mode & S_IFDIR) > 0)
return false;
- FILE *input = fopen(file, "r");
- if (input == NULL)
- return false;
- else
+ return !access(file, F_OK);
+}
+
+std::string ServerConfig::Escape(const std::string& str, bool xml)
+{
+ std::string escaped;
+ for (std::string::const_iterator it = str.begin(); it != str.end(); ++it)
{
- fclose(input);
- return true;
+ switch (*it)
+ {
+ case '"':
+ escaped += xml ? """ : "\"";
+ break;
+ case '&':
+ escaped += xml ? "&" : "&";
+ break;
+ case '\\':
+ escaped += xml ? "\\" : "\\\\";
+ break;
+ default:
+ escaped += *it;
+ break;
+ }
}
+ return escaped;
+}
+
+std::string ServerConfig::ExpandPath(const std::string& base, const std::string& fragment)
+{
+ // The fragment is an absolute path, don't modify it.
+ if (fragment[0] == '/' || ServerConfig::StartsWithWindowsDriveLetter(fragment))
+ return fragment;
+
+ return base + '/' + fragment;
}
const char* ServerConfig::CleanFilename(const char* name)
return (p != name ? ++p : p);
}
-const std::string& ServerConfig::GetSID()
-{
- return sid;
-}
-
void ConfigReaderThread::Run()
{
Config->Read();
*/
ServerInstance->XLines->CheckELines();
ServerInstance->XLines->ApplyLines();
- ModeReference ban(NULL, "ban");
+ ChanModeReference ban(NULL, "ban");
static_cast<ListModeBase*>(*ban)->DoRehash();
Config->ApplyDisabledCommands(Config->DisabledCommands);
User* user = ServerInstance->FindNick(TheUserUID);
- FOREACH_MOD(I_OnRehash, OnRehash(user));
+
+ ConfigStatus status(user);
+ const ModuleManager::ModuleMap& mods = ServerInstance->Modules->GetModules();
+ for (ModuleManager::ModuleMap::const_iterator i = mods.begin(); i != mods.end(); ++i)
+ i->second->ReadConfig(status);
+
ServerInstance->ISupport.Build();
ServerInstance->Logs->CloseLogs();