summaryrefslogtreecommitdiff
path: root/src/config.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/config.cpp')
-rw-r--r--src/config.cpp326
1 files changed, 192 insertions, 134 deletions
diff --git a/src/config.cpp b/src/config.cpp
index 7d3efcb91..0d9341424 100644
--- a/src/config.cpp
+++ b/src/config.cpp
@@ -11,18 +11,17 @@
#include "services.h"
#include "config.h"
+#include "module.h"
/*************************************************************************/
ConfigurationFile services_conf("services.conf", false); // Services configuration file name
ServerConfig *Config = NULL;
-static Anope::string Modules;
static Anope::string UlineServers;
static Anope::string OSNotifications;
static Anope::string BSDefaults;
static Anope::string CSDefaults;
-static Anope::string temp_nsuserhost;
static Anope::string NSDefaults;
/*************************************************************************/
@@ -31,21 +30,6 @@ ServerConfig::ServerConfig() : config_data(), NSDefFlags(NickCoreFlagStrings), C
{
this->Read();
- if (!temp_nsuserhost.empty())
- {
- size_t at = temp_nsuserhost.find('@');
- if (at == Anope::string::npos)
- {
- this->NSEnforcerUser = temp_nsuserhost;
- this->NSEnforcerHost = this->ServiceHost;
- }
- else
- {
- this->NSEnforcerUser = temp_nsuserhost.substr(0, at);
- this->NSEnforcerHost = temp_nsuserhost.substr(at + 1);
- }
- }
-
if (NSDefaults.empty())
{
this->NSDefFlags.SetFlag(NI_SECURE);
@@ -155,8 +139,6 @@ ServerConfig::ServerConfig() : config_data(), NSDefFlags(NickCoreFlagStrings), C
this->BSDefFlags.SetFlag(BS_GREET);
else if (option.equals_ci("fantasy"))
this->BSDefFlags.SetFlag(BS_FANTASY);
- else if (option.equals_ci("symbiosis"))
- this->BSDefFlags.SetFlag(BS_SYMBIOSIS);
}
}
@@ -196,23 +178,12 @@ ServerConfig::ServerConfig() : config_data(), NSDefFlags(NickCoreFlagStrings), C
this->Ulines.push_back(uline);
}
- /* Modules Autoload building... :P */
- this->ModulesAutoLoad = BuildStringList(Modules);
-
if (this->LimitSessions)
{
if (this->MaxSessionKill && !this->SessionAutoKillExpiry)
this->SessionAutoKillExpiry = 1800; /* 30 minutes */
}
- if (!this->s_BotServ.empty())
- {
- if (this->BSFantasyCharacter.empty())
- this->BSFantasyCharacter = "!";
- if (this->BSFantasyCharacter.length() > 1)
- Log() << "*** " << this->BSFantasyCharacter << " is more than 1 character long. Only the first character will be used. The others will be ignored.";
- }
-
/* Check the user keys */
if (this->UserKey1 == this->UserKey2 || this->UserKey1 == this->UserKey3 || this->UserKey3 == this->UserKey2)
Log() << "Every UserKey must be different. It's for YOUR safety! Remember that!";
@@ -421,7 +392,7 @@ bool ValidateBantype(ServerConfig *, const Anope::string &, const Anope::string
bool ValidateChanServ(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data)
{
- if (!config->s_ChanServ.empty())
+ if (!config->ChanServ.empty())
{
if ((value.equals_ci("decription") || value.equals_ci("autokickreason")) && data.GetValue().empty())
throw ConfigException("The value for <" + tag + ":" + value + "> cannot be empty when ChanServ is enabled!");
@@ -435,7 +406,7 @@ bool ValidateChanServ(ServerConfig *config, const Anope::string &tag, const Anop
bool ValidateMemoServ(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data)
{
- if (!config->s_MemoServ.empty())
+ if (!config->MemoServ.empty())
{
if (value.equals_ci("description"))
{
@@ -448,7 +419,7 @@ bool ValidateMemoServ(ServerConfig *config, const Anope::string &tag, const Anop
bool ValidateBotServ(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data)
{
- if (!config->s_BotServ.empty())
+ if (!config->BotServ.empty())
{
if (value.equals_ci("description"))
{
@@ -471,7 +442,7 @@ bool ValidateBotServ(ServerConfig *config, const Anope::string &tag, const Anope
bool ValidateHostServ(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data)
{
- if (!config->s_HostServ.empty())
+ if (!config->HostServ.empty())
{
if (value.equals_ci("description") && data.GetValue().empty())
throw ConfigException("The value for <" + tag + ":" + value + "> cannot be empty when HostServ is enabled!");
@@ -494,7 +465,7 @@ bool ValidateLimitSessions(ServerConfig *config, const Anope::string &tag, const
bool ValidateOperServ(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data)
{
- if (!config->s_OperServ.empty())
+ if (!config->OperServ.empty())
{
if (value.equals_ci("description") && data.GetValue().empty())
throw ConfigException("The value for <" + tag + ":" + value + "> cannot be empty when OperServ is enabled!");
@@ -508,7 +479,7 @@ bool ValidateOperServ(ServerConfig *config, const Anope::string &tag, const Anop
bool ValidateGlobal(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data)
{
- if (!config->s_Global.empty())
+ if (!config->Global.empty())
{
if (value.equals_ci("description") && data.GetValue().empty())
throw ConfigException("The value for <" + tag + ":" + value + "> cannot be empty when Global is enabled!");
@@ -571,7 +542,7 @@ bool InitUplinks(ServerConfig *config, const Anope::string &)
return true;
}
-bool DoUplink(ServerConfig *config, const Anope::string &, const Anope::string *, ValueList &values, int *)
+static bool DoUplink(ServerConfig *config, const Anope::string &, const Anope::string *, ValueList &values, int *)
{
// Validation variables
Anope::string host = values[0].GetValue(), password = values[3].GetValue();
@@ -592,7 +563,7 @@ bool DoUplink(ServerConfig *config, const Anope::string &, const Anope::string *
return true;
}
-bool DoneUplinks(ServerConfig *config, const Anope::string &)
+static bool DoneUplinks(ServerConfig *config, const Anope::string &)
{
if (config->Uplinks.empty())
throw ConfigException("You must define at least one uplink block!");
@@ -746,27 +717,31 @@ static bool DoneInclude(ServerConfig *config, const Anope::string &)
bool InitModules(ServerConfig *, const Anope::string &)
{
- Modules.clear();
return true;
}
-bool DoModule(ServerConfig *conf, const Anope::string &, const Anope::string *, ValueList &values, int *)
+static bool DoModule(ServerConfig *conf, const Anope::string &, const Anope::string *, ValueList &values, int *)
{
// First we validate that there was a name in the module block
Anope::string module = values[0].GetValue();
ValueItem vi(module);
if (!ValidateNotEmpty(conf, "module", "name", vi))
throw ConfigException("One or more values in your configuration file failed to validate. Please see your log for more information.");
- // If the string isn't empty, add a space before we add the module name
- if (!Modules.empty())
- Modules += " ";
- // Add the module name to the string
- Modules += values[0].GetValue();
+ conf->ModulesAutoLoad.push_back(module);
return true;
}
-bool DoneModules(ServerConfig *, const Anope::string &)
+static bool DoneModules(ServerConfig *config, const Anope::string &)
{
+ if (Config)
+ {
+ for (std::list<Anope::string>::iterator it = Config->ModulesAutoLoad.begin(); it != Config->ModulesAutoLoad.end(); ++it)
+ if (std::find(config->ModulesAutoLoad.begin(), config->ModulesAutoLoad.end(), *it) == config->ModulesAutoLoad.end())
+ ModuleManager::UnloadModule(ModuleManager::FindModule(*it), NULL);
+ for (std::list<Anope::string>::iterator it = config->ModulesAutoLoad.begin(); it != config->ModulesAutoLoad.end(); ++it)
+ if (std::find(Config->ModulesAutoLoad.begin(), Config->ModulesAutoLoad.end(), *it) == Config->ModulesAutoLoad.end())
+ ModuleManager::LoadModule(*it, NULL);
+ }
return true;
}
@@ -809,7 +784,7 @@ bool InitLogs(ServerConfig *config, const Anope::string &)
return true;
}
-bool DoLogs(ServerConfig *config, const Anope::string &, const Anope::string *, ValueList &values, int *)
+static bool DoLogs(ServerConfig *config, const Anope::string &, const Anope::string *, ValueList &values, int *)
{
//{"target", "source", "logage", "inhabit", "admin", "override", "commands", "servers", "channels", "users", "other", "rawio", "debug"},
Anope::string targets = values[0].GetValue();
@@ -846,7 +821,7 @@ bool DoLogs(ServerConfig *config, const Anope::string &, const Anope::string *,
return true;
}
-bool DoneLogs(ServerConfig *config, const Anope::string &)
+static bool DoneLogs(ServerConfig *config, const Anope::string &)
{
Log() << "Loaded " << config->LogInfos.size() << " log blocks";
@@ -873,7 +848,7 @@ bool DoneLogs(ServerConfig *config, const Anope::string &)
{
BotInfo *bi = it->second;
if (!c->FindUser(bi))
- bi->Join(c, &config->BotModeList);
+ bi->Join(c, NULL);
}
}
}
@@ -882,6 +857,106 @@ bool DoneLogs(ServerConfig *config, const Anope::string &)
return true;
}
+/*************************************************************************/
+
+static bool InitCommands(ServerConfig *config, const Anope::string &)
+{
+ for (botinfo_map::iterator it = BotListByNick.begin(), it_end = BotListByNick.end(); it != it_end; ++it)
+ it->second->commands.clear();
+ return true;
+}
+
+static bool DoCommands(ServerConfig *config, const Anope::string &, const Anope::string *, ValueList &values, int *)
+{
+ Anope::string service = values[0].GetValue();
+ Anope::string name = values[1].GetValue();
+ Anope::string command = values[2].GetValue();
+
+ ValueItem vi(service);
+ if (!ValidateNotEmpty(config, "command", "service", vi))
+ throw ConfigException("One or more values in your configuration file failed to validate. Please see your log for more information.");
+
+ vi = ValueItem(name);
+ if (!ValidateNotEmpty(config, "command", "name", vi))
+ throw ConfigException("One or more values in your configuration file failed to validate. Please see your log for more information.");
+
+ vi = ValueItem(command);
+ if (!ValidateNotEmpty(config, "command", "command", vi))
+ throw ConfigException("One or more values in your configuration file failed to validate. Please see your log for more information.");
+
+ BotInfo *bi = findbot(service);
+ if (bi == NULL)
+ throw ConfigException("Command " + name + " exists for nonexistant service " + service);
+
+ if (bi->commands.count(name))
+ throw ConfigException("Command name " + name + " already exists on " + bi->nick);
+
+ bi->commands[name] = command;
+ return true;
+}
+
+static bool DoneCommands(ServerConfig *config, const Anope::string &)
+{
+ return true;
+}
+
+/*************************************************************************/
+
+static std::set<Anope::string> services;
+static bool InitServices(ServerConfig *config, const Anope::string &)
+{
+ services.clear();
+ return true;
+}
+
+static bool DoServices(ServerConfig *config, const Anope::string &, const Anope::string *, ValueList &values, int *)
+{
+ Anope::string nick = values[0].GetValue();
+ Anope::string user = values[1].GetValue();
+ Anope::string host = values[2].GetValue();
+ Anope::string gecos = values[3].GetValue();
+
+ ValueItem vi(nick);
+ if (!ValidateNotEmpty(config, "service", "nick", vi))
+ throw ConfigException("One or more values in your configuration file failed to validate. Please see your log for more information.");
+
+ vi = ValueItem(user);
+ if (!ValidateNotEmpty(config, "service", "user", vi))
+ throw ConfigException("One or more values in your configuration file failed to validate. Please see your log for more information.");
+
+ vi = ValueItem(host);
+ if (!ValidateNotEmpty(config, "service", "host", vi))
+ throw ConfigException("One or more values in your configuration file failed to validate. Please see your log for more information.");
+
+ vi = ValueItem(gecos);
+ if (!ValidateNotEmpty(config, "service", "gecos", vi))
+ throw ConfigException("One or more values in your configuration file failed to validate. Please see your log for more information.");
+
+ services.insert(nick);
+ BotInfo *bi = findbot(nick);
+ if (bi != NULL)
+ return true;
+ bi = new BotInfo(nick, user, host, gecos);
+ bi->SetFlag(BI_CONF);
+ return true;
+}
+
+static bool DoneServices(ServerConfig *config, const Anope::string &)
+{
+ for (botinfo_map::iterator it = BotListByNick.begin(), it_end = BotListByNick.end(); it != it_end;)
+ {
+ BotInfo *bi = it->second;
+ ++it;
+
+ if (bi->HasFlag(BI_CONF) && services.count(bi->nick) == 0)
+ delete bi;
+ }
+ services.clear();
+ return true;
+}
+
+/*************************************************************************/
+
ConfigurationFile::ConfigurationFile(const Anope::string &n, bool e) : name(n), executable(e), fp(NULL)
{
}
@@ -1000,8 +1075,6 @@ ConfigItems::ConfigItems(ServerConfig *conf)
{"serverinfo", "description", "", new ValueContainerString(&conf->ServerDesc), DT_STRING | DT_NORELOAD, ValidateNotEmpty},
{"serverinfo", "localhost", "", new ValueContainerString(&conf->LocalHost), DT_HOSTNAME | DT_NORELOAD, NoValidation},
{"serverinfo", "id", "", new ValueContainerString(&conf->Numeric), DT_NOSPACES | DT_NORELOAD, NoValidation},
- {"serverinfo", "ident", "", new ValueContainerString(&conf->ServiceUser), DT_STRING | DT_NORELOAD, ValidateNotEmpty},
- {"serverinfo", "hostname", "", new ValueContainerString(&conf->ServiceHost), DT_STRING | DT_NORELOAD, ValidateNotEmpty},
{"serverinfo", "pid", "services.pid", new ValueContainerString(&conf->PIDFilename), DT_STRING | DT_NORELOAD, ValidateNotEmpty},
{"serverinfo", "motd", "services.motd", new ValueContainerString(&conf->MOTDFilename), DT_STRING, ValidateNotEmpty},
{"networkinfo", "networkname", "", new ValueContainerString(&conf->NetworkName), DT_STRING, ValidateNotEmpty},
@@ -1035,10 +1108,8 @@ ConfigItems::ConfigItems(ServerConfig *conf)
{"options", "botmodes", "", new ValueContainerString(&conf->BotModes), DT_STRING, NoValidation},
{"options", "retrywait", "60", new ValueContainerInt(&conf->RetryWait), DT_INTEGER, ValidateNotZero},
{"options", "hideprivilegedcommands", "no", new ValueContainerBool(&conf->HidePrivilegedCommands), DT_BOOLEAN, NoValidation},
- {"nickserv", "nick", "NickServ", new ValueContainerString(&conf->s_NickServ), DT_STRING | DT_NORELOAD, ValidateNotEmpty},
- {"nickserv", "description", "Nickname Registration Service", new ValueContainerString(&conf->desc_NickServ), DT_STRING | DT_NORELOAD, ValidateNotEmpty},
+ {"nickserv", "name", "NickServ", new ValueContainerString(&conf->NickServ), DT_STRING, NoValidation},
{"nickserv", "emailregistration", "no", new ValueContainerBool(&conf->NSEmailReg), DT_BOOLEAN, NoValidation},
- {"nickserv", "modules", "", new ValueContainerString(&conf->NickCoreModules), DT_STRING, NoValidation},
{"nickserv", "forceemail", "no", new ValueContainerBool(&conf->NSForceEmail), DT_BOOLEAN, ValidateEmailReg},
{"nickserv", "confirmemailchanges", "no", new ValueContainerBool(&conf->NSConfirmEmailChanges), DT_BOOLEAN, NoValidation},
{"nickserv", "defaults", "secure memosignon memoreceive", new ValueContainerString(&NSDefaults), DT_STRING, NoValidation},
@@ -1051,7 +1122,8 @@ ConfigItems::ConfigItems(ServerConfig *conf)
{"nickserv", "unconfirmedexpire", "0", new ValueContainerTime(&conf->NSUnconfirmedExpire), DT_TIME, ValidateEmailReg},
{"nickserv", "maxaliases", "0", new ValueContainerUInt(&conf->NSMaxAliases), DT_UINTEGER, NoValidation},
{"nickserv", "accessmax", "0", new ValueContainerUInt(&conf->NSAccessMax), DT_UINTEGER, ValidateNotZero},
- {"nickserv", "enforceruser", "", new ValueContainerString(&temp_nsuserhost), DT_STRING, ValidateNotEmpty},
+ {"nickserv", "enforceruser", "", new ValueContainerString(&conf->NSEnforcerUser), DT_STRING, ValidateNotEmpty},
+ {"nickserv", "enforcerhost", "", new ValueContainerString(&conf->NSEnforcerHost), DT_STRING, ValidateNotEmpty},
{"nickserv", "releasetimeout", "0", new ValueContainerTime(&conf->NSReleaseTimeout), DT_TIME, ValidateNotZero},
{"nickserv", "allowkillimmed", "no", new ValueContainerBool(&conf->NSAllowKillImmed), DT_BOOLEAN | DT_NORELOAD, NoValidation},
{"nickserv", "nogroupchange", "no", new ValueContainerBool(&conf->NSNoGroupChange), DT_BOOLEAN, NoValidation},
@@ -1071,9 +1143,7 @@ ConfigItems::ConfigItems(ServerConfig *conf)
{"mail", "dontquoteaddresses", "no", new ValueContainerBool(&conf->DontQuoteAddresses), DT_BOOLEAN, NoValidation},
{"dns", "nameserver", "127.0.0.1", new ValueContainerString(&conf->NameServer), DT_STRING, NoValidation},
{"dns", "timeout", "5", new ValueContainerTime(&conf->DNSTimeout), DT_TIME, NoValidation},
- {"chanserv", "nick", "", new ValueContainerString(&conf->s_ChanServ), DT_STRING | DT_NORELOAD, NoValidation},
- {"chanserv", "description", "Channel Registration Service", new ValueContainerString(&conf->desc_ChanServ), DT_STRING | DT_NORELOAD, ValidateChanServ},
- {"chanserv", "modules", "", new ValueContainerString(&conf->ChanCoreModules), DT_STRING, ValidateChanServ},
+ {"chanserv", "name", "ChanServ", new ValueContainerString(&conf->ChanServ), DT_STRING, NoValidation},
{"chanserv", "defaults", "keeptopic secure securefounder signkick", new ValueContainerString(&CSDefaults), DT_STRING, ValidateChanServ},
{"chanserv", "maxregistered", "0", new ValueContainerUInt(&conf->CSMaxReg), DT_UINTEGER, ValidateChanServ},
{"chanserv", "expire", "14d", new ValueContainerTime(&conf->CSExpire), DT_TIME, ValidateChanServ},
@@ -1087,16 +1157,13 @@ ConfigItems::ConfigItems(ServerConfig *conf)
{"chanserv", "listopersonly", "no", new ValueContainerBool(&conf->CSListOpersOnly), DT_BOOLEAN, ValidateChanServ},
{"chanserv", "listmax", "0", new ValueContainerUInt(&conf->CSListMax), DT_UINTEGER, ValidateChanServ},
{"chanserv", "opersonly", "no", new ValueContainerBool(&conf->CSOpersOnly), DT_BOOLEAN, ValidateChanServ},
- {"memoserv", "nick", "", new ValueContainerString(&conf->s_MemoServ), DT_STRING | DT_NORELOAD, NoValidation},
- {"memoserv", "description", "Memo Service", new ValueContainerString(&conf->desc_MemoServ), DT_STRING | DT_NORELOAD, ValidateMemoServ},
- {"memoserv", "modules", "", new ValueContainerString(&conf->MemoCoreModules), DT_STRING, NoValidation},
+ {"memoserv", "name", "MemoServ", new ValueContainerString(&conf->MemoServ), DT_STRING, NoValidation},
{"memoserv", "maxmemos", "0", new ValueContainerUInt(&conf->MSMaxMemos), DT_UINTEGER, NoValidation},
{"memoserv", "senddelay", "0", new ValueContainerTime(&conf->MSSendDelay), DT_TIME, NoValidation},
{"memoserv", "notifyall", "no", new ValueContainerBool(&conf->MSNotifyAll), DT_BOOLEAN, NoValidation},
{"memoserv", "memoreceipt", "0", new ValueContainerUInt(&conf->MSMemoReceipt), DT_UINTEGER, NoValidation},
- {"botserv", "nick", "", new ValueContainerString(&conf->s_BotServ), DT_STRING | DT_NORELOAD, NoValidation},
- {"botserv", "description", "Bot Service", new ValueContainerString(&conf->desc_BotServ), DT_STRING | DT_NORELOAD, ValidateBotServ},
- {"botserv", "modules", "", new ValueContainerString(&conf->BotCoreModules), DT_STRING, NoValidation},
+ {"hostserv", "name", "HostServ", new ValueContainerString(&conf->HostServ), DT_STRING, NoValidation},
+ {"botserv", "name", "BotServ", new ValueContainerString(&conf->BotServ), DT_STRING, NoValidation},
{"botserv", "defaults", "", new ValueContainerString(&BSDefaults), DT_STRING, NoValidation},
{"botserv", "minusers", "0", new ValueContainerUInt(&conf->BSMinUsers), DT_UINTEGER, ValidateBotServ},
{"botserv", "badwordsmax", "0", new ValueContainerUInt(&conf->BSBadWordsMax), DT_UINTEGER, ValidateBotServ},
@@ -1105,12 +1172,7 @@ ConfigItems::ConfigItems(ServerConfig *conf)
{"botserv", "gentlebadwordreason", "no", new ValueContainerBool(&conf->BSGentleBWReason), DT_BOOLEAN, NoValidation},
{"botserv", "casesensitive", "no", new ValueContainerBool(&conf->BSCaseSensitive), DT_BOOLEAN, NoValidation},
{"botserv", "fantasycharacter", "!", new ValueContainerString(&conf->BSFantasyCharacter), DT_STRING, NoValidation},
- {"hostserv", "nick", "", new ValueContainerString(&conf->s_HostServ), DT_STRING | DT_NORELOAD, NoValidation},
- {"hostserv", "description", "vHost Service", new ValueContainerString(&conf->desc_HostServ), DT_STRING | DT_NORELOAD, ValidateHostServ},
- {"hostserv", "modules", "", new ValueContainerString(&conf->HostCoreModules), DT_STRING, NoValidation},
- {"operserv", "nick", "", new ValueContainerString(&conf->s_OperServ), DT_STRING | DT_NORELOAD, NoValidation},
- {"operserv", "description", "Operator Service", new ValueContainerString(&conf->desc_OperServ), DT_STRING | DT_NORELOAD, ValidateOperServ},
- {"operserv", "modules", "", new ValueContainerString(&conf->OperCoreModules), DT_STRING, NoValidation},
+ {"operserv", "name", "OperServ", new ValueContainerString(&conf->OperServ), DT_STRING, NoValidation},
{"operserv", "superadmin", "no", new ValueContainerBool(&conf->SuperAdmin), DT_BOOLEAN, NoValidation},
{"operserv", "autokillexpiry", "0", new ValueContainerTime(&conf->AutokillExpiry), DT_TIME, ValidateOperServ},
{"operserv", "chankillexpiry", "0", new ValueContainerTime(&conf->ChankillExpiry), DT_TIME, ValidateOperServ},
@@ -1131,9 +1193,7 @@ ConfigItems::ConfigItems(ServerConfig *conf)
{"operserv", "sessionautokillexpiry", "0", new ValueContainerTime(&conf->SessionAutoKillExpiry), DT_TIME, NoValidation},
{"operserv", "addakiller", "no", new ValueContainerBool(&conf->AddAkiller), DT_BOOLEAN, NoValidation},
{"operserv", "opersonly", "no", new ValueContainerBool(&conf->OSOpersOnly), DT_BOOLEAN, NoValidation},
- {"global", "nick", "", new ValueContainerString(&conf->s_Global), DT_STRING | DT_NORELOAD, NoValidation},
- {"global", "description", "Global Noticer", new ValueContainerString(&conf->desc_Global), DT_STRING | DT_NORELOAD, ValidateGlobal},
- {"global", "modules", "", new ValueContainerString(&conf->GlobalCoreModules), DT_STRING, NoValidation},
+ {"global", "name", "Global", new ValueContainerString(&conf->Global), DT_STRING, NoValidation},
{"global", "globaloncycle", "no", new ValueContainerBool(&conf->GlobalOnCycle), DT_BOOLEAN, NoValidation},
{"global", "globaloncycledown", "", new ValueContainerString(&conf->GlobalOnCycleMessage), DT_STRING, ValidateGlobalOnCycle},
{"global", "globaloncycleup", "", new ValueContainerString(&conf->GlobalOnCycleUP), DT_STRING, ValidateGlobalOnCycle},
@@ -1161,11 +1221,6 @@ ConfigItems::ConfigItems(ServerConfig *conf)
{"", ""},
{DT_STRING},
InitModules, DoModule, DoneModules},
- {"log",
- {"target", "source", "logage", "inhabitlogchannel", "admin", "override", "commands", "servers", "channels", "users", "other", "rawio", "debug", ""},
- {"", "", "7", "yes", "", "", "", "", "", "", "no", "no", ""},
- {DT_STRING, DT_STRING, DT_INTEGER, DT_BOOLEAN, DT_STRING, DT_STRING, DT_STRING, DT_STRING, DT_STRING, DT_STRING, DT_STRING, DT_BOOLEAN, DT_BOOLEAN},
- InitLogs, DoLogs, DoneLogs},
{"opertype",
{"name", "inherits", "commands", "privs", ""},
{"", "", "", "", ""},
@@ -1176,6 +1231,21 @@ ConfigItems::ConfigItems(ServerConfig *conf)
{"", "", "", "", ""},
{DT_STRING, DT_STRING, DT_STRING, DT_STRING},
InitOpers, DoOper, DoneOpers},
+ {"service",
+ {"nick", "user", "host", "gecos", ""},
+ {"", "", "", "", ""},
+ {DT_STRING, DT_STRING, DT_STRING, DT_STRING},
+ InitServices, DoServices, DoneServices},
+ {"log",
+ {"target", "source", "logage", "inhabitlogchannel", "admin", "override", "commands", "servers", "channels", "users", "other", "rawio", "debug", ""},
+ {"", "", "7", "yes", "", "", "", "", "", "", "no", "no", ""},
+ {DT_STRING, DT_STRING, DT_INTEGER, DT_BOOLEAN, DT_STRING, DT_STRING, DT_STRING, DT_STRING, DT_STRING, DT_STRING, DT_STRING, DT_BOOLEAN, DT_BOOLEAN},
+ InitLogs, DoLogs, DoneLogs},
+ {"command",
+ {"service", "name", "command", ""},
+ {"", "", "", ""},
+ {DT_STRING, DT_STRING, DT_STRING},
+ InitCommands, DoCommands, DoneCommands},
{"",
{""},
{""},
@@ -1424,14 +1494,11 @@ void ServerConfig::LoadConf(ConfigurationFile &file)
if (in_quote)
{
if (ch == '"')
- {
in_quote = in_word = false;
- continue;
- }
- wordbuffer += ch;
- continue;
+ else
+ wordbuffer += ch;
}
- if (in_ml_comment)
+ else if (in_ml_comment)
{
if (ch == '*' && c + 1 < len && line[c + 1] == '/')
{
@@ -1440,8 +1507,8 @@ void ServerConfig::LoadConf(ConfigurationFile &file)
}
continue;
}
- if (ch == '#' || (ch == '/' && c + 1 < len && line[c + 1] == '/'))
- break; // Line comment, ignore the rest of the line (much like this one!)
+ else if (ch == '#' || (ch == '/' && c + 1 < len && line[c + 1] == '/'))
+ c = len - 1; // Line comment, ignore the rest of the line (much like this one!)
else if (ch == '/' && c + 1 < len && line[c + 1] == '*')
{
// Multiline (or less than one line) comment
@@ -1463,7 +1530,6 @@ void ServerConfig::LoadConf(ConfigurationFile &file)
throw ConfigException("Unexpected quoted string (prior unhandled words): " + file.GetName() + ":" + stringify(linenumber));
}
in_quote = in_word = true;
- continue;
}
else if (ch == '=')
{
@@ -1498,70 +1564,62 @@ void ServerConfig::LoadConf(ConfigurationFile &file)
in_word = false;
section = wordbuffer;
wordbuffer.clear();
+ continue;
+ }
+ else if (ch == ' ' || ch == '\r' || ch == '\t')
+ {
+ // Terminate word
+ in_word = false;
}
+ else if (!in_word && ch == ';')
+ ;
else if (ch == '}')
+ ;
+ else
{
- if (section.empty())
+ if (!in_word && !wordbuffer.empty())
{
file.Close();
- throw ConfigException("Stray '}': " + file.GetName() + ":" + stringify(linenumber));
+ throw ConfigException("Unexpected word: " + file.GetName() + ":" + stringify(linenumber));
}
- if (!wordbuffer.empty() || !itemname.empty())
+ wordbuffer += ch;
+ in_word = true;
+ }
+
+ if (ch == ';' || ch == '}' || c + 1 == len)
+ {
+ if (in_quote)
+ {
+ // Quotes can span multiple lines; all we need to do is go to the next line without clearing things
+ wordbuffer += "\n";
+ continue;
+ }
+ in_word = false;
+ if (!itemname.empty())
{
- // this will allow for the construct: section { key = value }
- // but will not allow for anything else, such as: section { key = value; key = value }
- if (!sectiondata.empty())
+ if (wordbuffer.empty())
{
file.Close();
- throw ConfigException("Unexpected end of section: " + file.GetName() + ":" + stringify(linenumber));
+ throw ConfigException("Item without value: " + file.GetName() + ":" + stringify(linenumber));
}
- // this is the same as the below section for testing if itemname is non-empty after the loop, but done inside it to allow the above construct
- Log(LOG_DEBUG) << "ln "<< linenumber << " EOL: s='" << section << "' '" << itemname << "' set to '" << wordbuffer << "'";
+ Log(LOG_DEBUG) << "ln " << linenumber << " EOL: s='" << section << "' '" << itemname << "' set to '" << wordbuffer << "'";
sectiondata.push_back(KeyVal(itemname, wordbuffer));
wordbuffer.clear();
itemname.clear();
}
- this->config_data.insert(std::pair<Anope::string, KeyValList>(section, sectiondata));
- section.clear();
- sectiondata.clear();
- }
- else if (ch == ';' || ch == '\r')
- continue; // Ignore
- else if (ch == ' ' || ch == '\t')
- {
- // Terminate word
- if (in_word)
- in_word = false;
- }
- else
- {
- if (!in_word && !wordbuffer.empty())
+
+ if (ch == '}')
{
- file.Close();
- throw ConfigException("Unexpected word: " + file.GetName() + ":" + stringify(linenumber));
+ if (section.empty())
+ {
+ file.Close();
+ throw ConfigException("Stray '}': " + file.GetName() + ":" + stringify(linenumber));
+ }
+ this->config_data.insert(std::pair<Anope::string, KeyValList>(section, sectiondata));
+ section.clear();
+ sectiondata.clear();
}
- wordbuffer += ch;
- in_word = true;
- }
- }
- if (in_quote)
- {
- // Quotes can span multiple lines; all we need to do is go to the next line without clearing things
- wordbuffer += "\n";
- continue;
- }
- in_word = false;
- if (!itemname.empty())
- {
- if (wordbuffer.empty())
- {
- file.Close();
- throw ConfigException("Item without value: " + file.GetName() + ":" + stringify(linenumber));
}
- Log(LOG_DEBUG) << "ln " << linenumber << " EOL: s='" << section << "' '" << itemname << "' set to '" << wordbuffer << "'";
- sectiondata.push_back(KeyVal(itemname, wordbuffer));
- wordbuffer.clear();
- itemname.clear();
}
}
if (in_ml_comment)