summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/configreader.h72
-rw-r--r--include/inspircd.h16
-rw-r--r--include/modules.h31
-rw-r--r--src/commands.cpp12
-rw-r--r--src/commands/cmd_oper.cpp20
-rw-r--r--src/commands/cmd_rehash.cpp4
-rw-r--r--src/commands/cmd_stats.cpp12
-rw-r--r--src/configreader.cpp433
-rw-r--r--src/inspircd.cpp22
-rw-r--r--src/modules.cpp50
-rw-r--r--src/server.cpp4
-rw-r--r--src/socket.cpp11
12 files changed, 273 insertions, 414 deletions
diff --git a/include/configreader.h b/include/configreader.h
index 60adbf868..36e5badfd 100644
--- a/include/configreader.h
+++ b/include/configreader.h
@@ -48,8 +48,7 @@ enum ConfigDataType
DT_IPADDRESS = 6, /* IP address (v4, v6) */
DT_CHANNEL = 7, /* Channel name */
DT_ALLOW_WILD = 64, /* Allow wildcards/CIDR in DT_IPADDRESS */
- DT_ALLOW_NEWLINE = 128, /* New line characters allowed in DT_CHARPTR */
- DT_BOOTONLY = 256 /* Can only be set on startup, not on rehash */
+ DT_ALLOW_NEWLINE = 128 /* New line characters allowed in DT_CHARPTR */
};
/** The maximum number of values in a core configuration tag. Can be increased if needed.
@@ -323,34 +322,27 @@ class CoreExport ServerConfig : public Extensible
* configutation, appending errors to errorstream
* and setting error if an error has occured.
*/
- bool ParseLine(ConfigDataHash &target, const std::string &filename, std::string &line, long &linenumber, std::ostringstream &errorstream);
+ bool ParseLine(const std::string &filename, std::string &line, long &linenumber);
/** Check that there is only one of each configuration item
*/
- bool CheckOnce(const char* tag, ConfigDataHash &newconf);
+ bool CheckOnce(const char* tag);
public:
/** Process an include executable directive
*/
- bool DoPipe(ConfigDataHash &target, const std::string &file, std::ostringstream &errorstream);
+ bool DoPipe(const std::string &file);
/** Process an include file directive
*/
- bool DoInclude(ConfigDataHash &target, const std::string &file, std::ostringstream &errorstream);
-
- /** User that is currently performing a rehash, needed because the
- * rehash code is now threaded and needs to know who to give errors and feedback to.
- */
- std::string RehashUserUID;
+ bool DoInclude(const std::string &file);
/** Error stream, contains error output from any failed configuration parsing.
*/
- std::ostringstream* errstr;
+ std::ostringstream errstr;
- /** Holds the new configuration when a rehash occurs so we dont overwrite the existing
- * working config with a broken one without checking it first and swapping pointers.
- */
- ConfigDataHash newconfig;
+ /** True if this configuration is valid enough to run with */
+ bool valid;
/** Set of included files. Do we use this any more?
*/
@@ -794,7 +786,11 @@ class CoreExport ServerConfig : public Extensible
* and initialize this class. All other methods
* should be used only by the core.
*/
- void Read(bool bail, const std::string &useruid);
+ void Read();
+
+ /** Apply configuration changes from the old configuration.
+ */
+ void Apply(ServerConfig* old, const std::string &useruid);
/** Read a file into a file_cache object
*/
@@ -805,84 +801,80 @@ class CoreExport ServerConfig : public Extensible
bool StartsWithWindowsDriveLetter(const std::string &path);
/** Report a configuration error given in errormessage.
- * @param bail If this is set to true, the error is sent to the console, and the program exits
- * @param useruid If this is set to a non-empty value which is a valid UID, and bail is false,
- * the errors are spooled to this user as SNOTICEs.
- * If the parameter is not a valid UID, the messages are spooled to all opers.
*/
- void ReportConfigError(const std::string &errormessage, bool bail, const std::string &useruid);
+ void ReportConfigError(const std::string &errormessage);
/** Load 'filename' into 'target', with the new config parser everything is parsed into
* tag/key/value at load-time rather than at read-value time.
*/
- bool LoadConf(ConfigDataHash &target, FILE* &conf, const char* filename, std::ostringstream &errorstream);
+ bool LoadConf(FILE* &conf, const char* filename);
/** Load 'filename' into 'target', with the new config parser everything is parsed into
* tag/key/value at load-time rather than at read-value time.
*/
- bool LoadConf(ConfigDataHash &target, FILE* &conf, const std::string &filename, std::ostringstream &errorstream);
+ bool LoadConf(FILE* &conf, const std::string &filename);
/** Writes 'length' chars into 'result' as a string
*/
- bool ConfValue(ConfigDataHash &target, const char* tag, const char* var, int index, char* result, int length, bool allow_linefeeds = false);
+ bool ConfValue(const char* tag, const char* var, int index, char* result, int length, bool allow_linefeeds = false);
/** Writes 'length' chars into 'result' as a string
*/
- bool ConfValue(ConfigDataHash &target, const char* tag, const char* var, const char* default_value, int index, char* result, int length, bool allow_linefeeds = false);
+ bool ConfValue(const char* tag, const char* var, const char* default_value, int index, char* result, int length, bool allow_linefeeds = false);
/** Writes 'length' chars into 'result' as a string
*/
- bool ConfValue(ConfigDataHash &target, const std::string &tag, const std::string &var, int index, std::string &result, bool allow_linefeeds = false);
+ bool ConfValue(const std::string &tag, const std::string &var, int index, std::string &result, bool allow_linefeeds = false);
/** Writes 'length' chars into 'result' as a string
*/
- bool ConfValue(ConfigDataHash &target, const std::string &tag, const std::string &var, const std::string &default_value, int index, std::string &result, bool allow_linefeeds = false);
+ bool ConfValue(const std::string &tag, const std::string &var, const std::string &default_value, int index, std::string &result, bool allow_linefeeds = false);
/** Tries to convert the value to an integer and write it to 'result'
*/
- bool ConfValueInteger(ConfigDataHash &target, const char* tag, const char* var, int index, int &result);
+ bool ConfValueInteger(const char* tag, const char* var, int index, int &result);
/** Tries to convert the value to an integer and write it to 'result'
*/
- bool ConfValueInteger(ConfigDataHash &target, const char* tag, const char* var, const char* default_value, int index, int &result);
+ bool ConfValueInteger(const char* tag, const char* var, const char* default_value, int index, int &result);
/** Tries to convert the value to an integer and write it to 'result'
*/
- bool ConfValueInteger(ConfigDataHash &target, const std::string &tag, const std::string &var, int index, int &result);
+ bool ConfValueInteger(const std::string &tag, const std::string &var, int index, int &result);
/** Tries to convert the value to an integer and write it to 'result'
*/
- bool ConfValueInteger(ConfigDataHash &target, const std::string &tag, const std::string &var, const std::string &default_value, int index, int &result);
+ bool ConfValueInteger(const std::string &tag, const std::string &var, const std::string &default_value, int index, int &result);
/** Returns true if the value exists and has a true value, false otherwise
*/
- bool ConfValueBool(ConfigDataHash &target, const char* tag, const char* var, int index);
+ bool ConfValueBool(const char* tag, const char* var, int index);
/** Returns true if the value exists and has a true value, false otherwise
*/
- bool ConfValueBool(ConfigDataHash &target, const char* tag, const char* var, const char* default_value, int index);
+ bool ConfValueBool(const char* tag, const char* var, const char* default_value, int index);
/** Returns true if the value exists and has a true value, false otherwise
*/
- bool ConfValueBool(ConfigDataHash &target, const std::string &tag, const std::string &var, int index);
+ bool ConfValueBool(const std::string &tag, const std::string &var, int index);
/** Returns true if the value exists and has a true value, false otherwise
*/
- bool ConfValueBool(ConfigDataHash &target, const std::string &tag, const std::string &var, const std::string &default_value, int index);
+ bool ConfValueBool(const std::string &tag, const std::string &var, const std::string &default_value, int index);
/** Returns the number of occurences of tag in the config file
*/
- int ConfValueEnum(ConfigDataHash &target, const char* tag);
+ int ConfValueEnum(const char* tag);
/** Returns the number of occurences of tag in the config file
*/
- int ConfValueEnum(ConfigDataHash &target, const std::string &tag);
+ int ConfValueEnum(const std::string &tag);
/** Returns the numbers of vars inside the index'th 'tag in the config file
*/
- int ConfVarEnum(ConfigDataHash &target, const char* tag, int index);
+ int ConfVarEnum(const char* tag, int index);
/** Returns the numbers of vars inside the index'th 'tag in the config file
*/
- int ConfVarEnum(ConfigDataHash &target, const std::string &tag, int index);
+ int ConfVarEnum(const std::string &tag, int index);
/** Validates a hostname value, throwing ConfigException if it is not valid
*/
diff --git a/include/inspircd.h b/include/inspircd.h
index afe4dcd7c..ef6c86f28 100644
--- a/include/inspircd.h
+++ b/include/inspircd.h
@@ -290,12 +290,12 @@ class BanCacheManager;
class CoreExport ConfigReaderThread : public Thread
{
InspIRCd* ServerInstance;
- bool do_bail;
+ ServerConfig* Config;
bool done;
- std::string TheUserUID;
public:
- ConfigReaderThread(InspIRCd* Instance, bool bail, const std::string &useruid)
- : Thread(), ServerInstance(Instance), do_bail(bail), done(false), TheUserUID(useruid)
+ std::string TheUserUID;
+ ConfigReaderThread(InspIRCd* Instance, const std::string &useruid)
+ : Thread(), ServerInstance(Instance), done(false), TheUserUID(useruid)
{
}
@@ -304,6 +304,8 @@ class CoreExport ConfigReaderThread : public Thread
}
void Run();
+ /** Run in the main thread to apply the configuration */
+ void Finish();
bool IsDone() { return done; }
};
@@ -536,11 +538,9 @@ class CoreExport InspIRCd : public classbase
caller1<void, User*> ProcessUser;
/** Bind all ports specified in the configuration file.
- * @param bail True if the function should bail back to the shell on failure
- * @param found_ports The actual number of ports found in the config, as opposed to the number actually bound
- * @return The number of ports actually bound without error
+ * @return The number of ports bound without error
*/
- int BindPorts(bool bail, int &found_ports, FailedPortList &failed_ports);
+ int BindPorts(FailedPortList &failed_ports);
/** Binds a socket on an already open file descriptor
* @param sockfd A valid file descriptor of an open socket
diff --git a/include/modules.h b/include/modules.h
index 31ed6ec8c..1761b1b54 100644
--- a/include/modules.h
+++ b/include/modules.h
@@ -1447,21 +1447,6 @@ class CoreExport ConfigReader : public classbase
{
protected:
InspIRCd* ServerInstance;
- /** The contents of the configuration file
- * This protected member should never be accessed by a module (and cannot be accessed unless the
- * core is changed). It will contain a pointer to the configuration file data with unneeded data
- * (such as comments) stripped from it.
- */
- ConfigDataHash* data;
- /** Used to store errors
- */
- std::ostringstream* errorlog;
- /** If we're using our own config data hash or not
- */
- bool privatehash;
- /** True if an error occured reading the config file
- */
- bool readerror;
/** Error code
*/
long error;
@@ -1472,10 +1457,6 @@ class CoreExport ConfigReader : public classbase
* as specified when running ./configure.
*/
ConfigReader(InspIRCd* Instance);
- /** Overloaded constructor.
- * This constructor initialises the ConfigReader class to read a user-specified config file
- */
- ConfigReader(InspIRCd* Instance, const std::string &filename);
/** Default destructor.
* This method destroys the ConfigReader class.
*/
@@ -1539,18 +1520,6 @@ class CoreExport ConfigReader : public classbase
* multiple instance tag.
*/
int Enumerate(const std::string &tag);
- /** Returns true if a config file is valid.
- * This method is partially implemented and will only return false if the config
- * file does not exist or could not be opened.
- */
- bool Verify();
- /** Dumps the list of errors in a config file to an output location. If bail is true,
- * then the program will abort. If bail is false and user points to a valid user
- * record, the error report will be spooled to the given user by means of NOTICE.
- * if bool is false AND user is false, the error report will be spooled to all opers
- * by means of a NOTICE to all opers.
- */
- void DumpErrors(bool bail,User* user);
/** Returns the number of items within a tag.
* For example if the tag was &lt;test tag="blah" data="foo"&gt; then this
diff --git a/src/commands.cpp b/src/commands.cpp
index 6c390b8bf..db2074d87 100644
--- a/src/commands.cpp
+++ b/src/commands.cpp
@@ -24,10 +24,10 @@ bool InspIRCd::HostMatchesEveryone(const std::string &mask, User* user)
char itrigger[MAXBUF];
long matches = 0;
- if (!Config->ConfValue(Config->config_data, "insane","trigger", 0, itrigger, MAXBUF))
+ if (!Config->ConfValue("insane","trigger", 0, itrigger, MAXBUF))
strlcpy(itrigger,"95.5",MAXBUF);
- if (Config->ConfValueBool(Config->config_data, "insane","hostmasks", 0))
+ if (Config->ConfValueBool("insane","hostmasks", 0))
return false;
for (user_hash::iterator u = this->Users->clientlist->begin(); u != this->Users->clientlist->end(); u++)
@@ -56,10 +56,10 @@ bool InspIRCd::IPMatchesEveryone(const std::string &ip, User* user)
char itrigger[MAXBUF];
long matches = 0;
- if (!Config->ConfValue(Config->config_data, "insane","trigger",0,itrigger,MAXBUF))
+ if (!Config->ConfValue("insane","trigger",0,itrigger,MAXBUF))
strlcpy(itrigger,"95.5",MAXBUF);
- if (Config->ConfValueBool(Config->config_data, "insane","ipmasks",0))
+ if (Config->ConfValueBool("insane","ipmasks",0))
return false;
for (user_hash::iterator u = this->Users->clientlist->begin(); u != this->Users->clientlist->end(); u++)
@@ -85,10 +85,10 @@ bool InspIRCd::NickMatchesEveryone(const std::string &nick, User* user)
char itrigger[MAXBUF];
long matches = 0;
- if (!Config->ConfValue(Config->config_data, "insane","trigger",0,itrigger,MAXBUF))
+ if (!Config->ConfValue("insane","trigger",0,itrigger,MAXBUF))
strlcpy(itrigger,"95.5",MAXBUF);
- if (Config->ConfValueBool(Config->config_data, "insane","nickmasks",0))
+ if (Config->ConfValueBool("insane","nickmasks",0))
return false;
for (user_hash::iterator u = this->Users->clientlist->begin(); u != this->Users->clientlist->end(); u++)
diff --git a/src/commands/cmd_oper.cpp b/src/commands/cmd_oper.cpp
index a98db6ca4..85af2da18 100644
--- a/src/commands/cmd_oper.cpp
+++ b/src/commands/cmd_oper.cpp
@@ -56,13 +56,13 @@ CmdResult CommandOper::Handle (const std::vector<std::string>& parameters, User
snprintf(TheHost,MAXBUF,"%s@%s",user->ident.c_str(),user->host.c_str());
snprintf(TheIP, MAXBUF,"%s@%s",user->ident.c_str(),user->GetIPString());
- for (int i = 0; i < ServerInstance->Config->ConfValueEnum(ServerInstance->Config->config_data, "oper"); i++)
+ for (int i = 0; i < ServerInstance->Config->ConfValueEnum("oper"); i++)
{
- ServerInstance->Config->ConfValue(ServerInstance->Config->config_data, "oper", "name", i, LoginName, MAXBUF);
- ServerInstance->Config->ConfValue(ServerInstance->Config->config_data, "oper", "password", i, Password, MAXBUF);
- ServerInstance->Config->ConfValue(ServerInstance->Config->config_data, "oper", "type", i, OperType, MAXBUF);
- ServerInstance->Config->ConfValue(ServerInstance->Config->config_data, "oper", "host", i, HostName, MAXBUF);
- ServerInstance->Config->ConfValue(ServerInstance->Config->config_data, "oper", "hash", i, HashType, MAXBUF);
+ ServerInstance->Config->ConfValue("oper", "name", i, LoginName, MAXBUF);
+ ServerInstance->Config->ConfValue("oper", "password", i, Password, MAXBUF);
+ ServerInstance->Config->ConfValue("oper", "type", i, OperType, MAXBUF);
+ ServerInstance->Config->ConfValue("oper", "host", i, HostName, MAXBUF);
+ ServerInstance->Config->ConfValue("oper", "hash", i, HashType, MAXBUF);
match_login = (LoginName == parameters[0]);
match_pass = !ServerInstance->PassCompare(user, Password, parameters[1], HashType);
@@ -71,10 +71,10 @@ CmdResult CommandOper::Handle (const std::vector<std::string>& parameters, User
if (match_login && match_pass && match_hosts)
{
type_invalid = true;
- for (j =0; j < ServerInstance->Config->ConfValueEnum(ServerInstance->Config->config_data, "type"); j++)
+ for (j =0; j < ServerInstance->Config->ConfValueEnum("type"); j++)
{
- ServerInstance->Config->ConfValue(ServerInstance->Config->config_data, "type", "name", j, TypeName, MAXBUF);
- ServerInstance->Config->ConfValue(ServerInstance->Config->config_data, "type", "class", j, ClassName, MAXBUF);
+ ServerInstance->Config->ConfValue("type", "name", j, TypeName, MAXBUF);
+ ServerInstance->Config->ConfValue("type", "class", j, ClassName, MAXBUF);
if (!strcmp(TypeName,OperType))
{
@@ -86,7 +86,7 @@ CmdResult CommandOper::Handle (const std::vector<std::string>& parameters, User
ServerInstance->Logs->Log("OPER",DEFAULT,"OPER: Failed oper attempt by %s!%s@%s: credentials valid, but oper type erroneous.", user->nick.c_str(), user->ident.c_str(), user->host.c_str());
return CMD_FAILURE;
}
- ServerInstance->Config->ConfValue(ServerInstance->Config->config_data, "type","host", j, HostName, MAXBUF);
+ ServerInstance->Config->ConfValue("type","host", j, HostName, MAXBUF);
if (*HostName)
user->ChangeDisplayedHost(HostName);
if (*ClassName)
diff --git a/src/commands/cmd_rehash.cpp b/src/commands/cmd_rehash.cpp
index 9ee71838b..96313829f 100644
--- a/src/commands/cmd_rehash.cpp
+++ b/src/commands/cmd_rehash.cpp
@@ -73,9 +73,7 @@ CmdResult CommandRehash::Handle (const std::vector<std::string>& parameters, Use
FOREACH_MOD(I_OnGarbageCollect, OnGarbageCollect());
- ServerInstance->Config->RehashUserUID = user->uuid;
-
- ServerInstance->ConfigThread = new ConfigReaderThread(ServerInstance, false, ServerInstance->Config->RehashUserUID);
+ ServerInstance->ConfigThread = new ConfigReaderThread(ServerInstance, user->uuid);
ServerInstance->Threads->Start(ServerInstance->ConfigThread);
return CMD_SUCCESS;
diff --git a/src/commands/cmd_stats.cpp b/src/commands/cmd_stats.cpp
index 4af8dcb91..f09fcf84f 100644
--- a/src/commands/cmd_stats.cpp
+++ b/src/commands/cmd_stats.cpp
@@ -127,9 +127,9 @@ DllExport void DoStats(InspIRCd* ServerInstance, char statschar, User* user, str
case 'U':
{
char ulined[MAXBUF];
- for (int i = 0; i < ServerInstance->Config->ConfValueEnum(ServerInstance->Config->config_data, "uline"); i++)
+ for (int i = 0; i < ServerInstance->Config->ConfValueEnum("uline"); i++)
{
- ServerInstance->Config->ConfValue(ServerInstance->Config->config_data, "uline","server", i, ulined, MAXBUF);
+ ServerInstance->Config->ConfValue("uline","server", i, ulined, MAXBUF);
results.push_back(sn+" 248 "+user->nick+" U "+std::string(ulined));
}
}
@@ -280,14 +280,14 @@ DllExport void DoStats(InspIRCd* ServerInstance, char statschar, User* user, str
/* stats o */
case 'o':
- for (int i = 0; i < ServerInstance->Config->ConfValueEnum(ServerInstance->Config->config_data, "oper"); i++)
+ for (int i = 0; i < ServerInstance->Config->ConfValueEnum("oper"); i++)
{
char LoginName[MAXBUF];
char HostName[MAXBUF];
char OperType[MAXBUF];
- ServerInstance->Config->ConfValue(ServerInstance->Config->config_data, "oper","name", i, LoginName, MAXBUF);
- ServerInstance->Config->ConfValue(ServerInstance->Config->config_data, "oper","host", i, HostName, MAXBUF);
- ServerInstance->Config->ConfValue(ServerInstance->Config->config_data, "oper","type", i, OperType, MAXBUF);
+ ServerInstance->Config->ConfValue("oper","name", i, LoginName, MAXBUF);
+ ServerInstance->Config->ConfValue("oper","host", i, HostName, MAXBUF);
+ ServerInstance->Config->ConfValue("oper","type", i, OperType, MAXBUF);
results.push_back(sn+" 243 "+user->nick+" O "+HostName+" * "+LoginName+" "+OperType+" 0");
}
break;
diff --git a/src/configreader.cpp b/src/configreader.cpp
index 51045ef58..4c7b96900 100644
--- a/src/configreader.cpp
+++ b/src/configreader.cpp
@@ -103,9 +103,9 @@ void ServerConfig::Send005(User* user)
user->WriteNumeric(RPL_ISUPPORT, "%s %s", user->nick.c_str(), line->c_str());
}
-bool ServerConfig::CheckOnce(const char* tag, ConfigDataHash &newconf)
+bool ServerConfig::CheckOnce(const char* tag)
{
- int count = ConfValueEnum(newconf, tag);
+ int count = ConfValueEnum(tag);
if (count > 1)
throw CoreException("You have more than one <"+std::string(tag)+"> tag, this is not permitted.");
@@ -707,53 +707,14 @@ bool DoneMaxBans(ServerConfig*, const char*)
return true;
}
-void ServerConfig::ReportConfigError(const std::string &errormessage, bool bail, const std::string &useruid)
+void ServerConfig::ReportConfigError(const std::string &errormessage)
{
ServerInstance->Logs->Log("CONFIG",DEFAULT, "There were errors in your configuration file: %s", errormessage.c_str());
- if (bail)
- {
- /* Unneeded because of the ServerInstance->Log() aboive? */
- printf("There were errors in your configuration:\n%s\n\n",errormessage.c_str());
- ServerInstance->Exit(EXIT_STATUS_CONFIG);
- }
- else
- {
- std::string errors = errormessage;
- std::string::size_type start;
- unsigned int prefixlen;
- start = 0;
- /* ":ServerInstance->Config->ServerName NOTICE user->nick :" */
- if (!useruid.empty())
- {
- User* user = ServerInstance->FindNick(useruid);
- if (user)
- {
- prefixlen = strlen(this->ServerName) + user->nick.length() + 11;
- user->WriteServ("NOTICE %s :There were errors in the configuration file:",user->nick.c_str());
- while (start < errors.length())
- {
- user->WriteServ("NOTICE %s :%s",user->nick.c_str(), errors.substr(start, 510 - prefixlen).c_str());
- start += 510 - prefixlen;
- }
- }
- }
- else
- {
- ServerInstance->SNO->WriteToSnoMask('a', "There were errors in the configuration file:");
- while (start < errors.length())
- {
- ServerInstance->SNO->WriteToSnoMask('a', errors.substr(start, 360));
- start += 360;
- }
- }
- return;
- }
+ errstr << errormessage << std::endl;
}
-void ServerConfig::Read(bool bail, const std::string &useruid)
+void ServerConfig::Read()
{
- int rem = 0, add = 0; /* Number of modules added, number of modules removed */
-
static char maxkeep[MAXBUF]; /* Temporary buffer for WhoWasMaxKeep value */
static char hidemodes[MAXBUF]; /* Modes to not allow listing from users below halfop */
static char exemptchanops[MAXBUF]; /* Exempt channel ops from these modes */
@@ -761,8 +722,8 @@ void ServerConfig::Read(bool bail, const std::string &useruid)
static char disabledumodes[MAXBUF]; /* Disabled usermodes */
static char disabledcmodes[MAXBUF]; /* Disabled chanmodes */
/* std::ostringstream::clear() does not clear the string itself, only the error flags. */
- this->errstr = new std::ostringstream(std::stringstream::in | std::stringstream::out);
-
+ valid = true;
+ errstr.str().clear();
include_stack.clear();
/* These tags MUST occur and must ONLY occur once in the config file */
@@ -795,10 +756,10 @@ void ServerConfig::Read(bool bail, const std::string &useruid)
{"performance", "softlimit", "0", new ValueContainerUInt (&this->SoftLimit), DT_INTEGER, ValidateSoftLimit},
{"performance", "somaxconn", SOMAXCONN_S, new ValueContainerInt (&this->MaxConn), DT_INTEGER, ValidateMaxConn},
{"options", "moronbanner", "Youre banned!", new ValueContainerChar (this->MoronBanner), DT_CHARPTR, NoValidation},
- {"server", "name", "", new ValueContainerChar (this->ServerName), DT_HOSTNAME|DT_BOOTONLY, ValidateServerName},
+ {"server", "name", "", new ValueContainerChar (this->ServerName), DT_HOSTNAME, ValidateServerName},
{"server", "description", "Configure Me", new ValueContainerChar (this->ServerDesc), DT_CHARPTR, NoValidation},
{"server", "network", "Network", new ValueContainerChar (this->Network), DT_NOSPACES, NoValidation},
- {"server", "id", "", new ValueContainerChar (this->sid), DT_CHARPTR|DT_BOOTONLY, ValidateSID},
+ {"server", "id", "", new ValueContainerChar (this->sid), DT_CHARPTR, ValidateSID},
{"admin", "name", "", new ValueContainerChar (this->AdminName), DT_CHARPTR, NoValidation},
{"admin", "email", "Mis@configu.red", new ValueContainerChar (this->AdminEmail), DT_CHARPTR, NoValidation},
{"admin", "nick", "Misconfigured", new ValueContainerChar (this->AdminNick), DT_CHARPTR, NoValidation},
@@ -951,32 +912,26 @@ void ServerConfig::Read(bool bail, const std::string &useruid)
/* Load and parse the config file, if there are any errors then explode */
- /* Make a copy here so if it fails then we can carry on running with an unaffected config */
- newconfig.clear();
-
- if (!this->DoInclude(newconfig, ServerInstance->ConfigFileName, *errstr))
+ if (!this->DoInclude(ServerInstance->ConfigFileName))
{
- ReportConfigError(errstr->str(), bail, useruid);
- delete errstr;
+ valid = false;
return;
}
- delete errstr;
-
/* The stuff in here may throw CoreException, be sure we're in a position to catch it. */
try
{
/* Check we dont have more than one of singular tags, or any of them missing
*/
for (int Index = 0; Once[Index]; Index++)
- if (!CheckOnce(Once[Index], newconfig))
+ if (!CheckOnce(Once[Index]))
return;
for (int Index = 0; ChangedConfig[Index].tag; Index++)
{
char item[MAXBUF];
*item = 0;
- if (ConfValue(newconfig, ChangedConfig[Index].tag, ChangedConfig[Index].value, "", 0, item, MAXBUF, true) || *item)
+ if (ConfValue(ChangedConfig[Index].tag, ChangedConfig[Index].value, "", 0, item, MAXBUF, true) || *item)
throw CoreException(std::string("Your configuration contains a deprecated value: <") + ChangedConfig[Index].tag + ":" + ChangedConfig[Index].value + "> - " + ChangedConfig[Index].reason);
}
@@ -988,19 +943,10 @@ void ServerConfig::Read(bool bail, const std::string &useruid)
int dt = Values[Index].datatype;
bool allow_newlines = ((dt & DT_ALLOW_NEWLINE) > 0);
bool allow_wild = ((dt & DT_ALLOW_WILD) > 0);
- bool bootonly = ((dt & DT_BOOTONLY) > 0);
dt &= ~DT_ALLOW_NEWLINE;
dt &= ~DT_ALLOW_WILD;
- dt &= ~DT_BOOTONLY;
-
- /* Silently ignore boot only values */
- if (bootonly && !bail)
- {
- delete Values[Index].val;
- continue;
- }
- ConfValue(newconfig, Values[Index].tag, Values[Index].value, Values[Index].default_value, 0, item, MAXBUF, allow_newlines);
+ ConfValue(Values[Index].tag, Values[Index].value, Values[Index].default_value, 0, item, MAXBUF, allow_newlines);
ValueItem vi(item);
if (!Values[Index].validation_function(this, Values[Index].tag, Values[Index].value, vi))
@@ -1081,7 +1027,7 @@ void ServerConfig::Read(bool bail, const std::string &useruid)
MultiValues[Index].init_function(this, MultiValues[Index].tag);
// XXX: ServerInstance->Threads->Unlock();
- int number_of_tags = ConfValueEnum(newconfig, MultiValues[Index].tag);
+ int number_of_tags = ConfValueEnum(MultiValues[Index].tag);
for (int tagnum = 0; tagnum < number_of_tags; ++tagnum)
{
@@ -1104,7 +1050,7 @@ void ServerConfig::Read(bool bail, const std::string &useruid)
case DT_NOSPACES:
{
char item[MAXBUF];
- if (ConfValue(newconfig, MultiValues[Index].tag, MultiValues[Index].items[valuenum], MultiValues[Index].items_default[valuenum], tagnum, item, MAXBUF, allow_newlines))
+ if (ConfValue(MultiValues[Index].tag, MultiValues[Index].items[valuenum], MultiValues[Index].items_default[valuenum], tagnum, item, MAXBUF, allow_newlines))
vl.push_back(ValueItem(item));
else
vl.push_back(ValueItem(""));
@@ -1114,7 +1060,7 @@ void ServerConfig::Read(bool bail, const std::string &useruid)
case DT_HOSTNAME:
{
char item[MAXBUF];
- if (ConfValue(newconfig, MultiValues[Index].tag, MultiValues[Index].items[valuenum], MultiValues[Index].items_default[valuenum], tagnum, item, MAXBUF, allow_newlines))
+ if (ConfValue(MultiValues[Index].tag, MultiValues[Index].items[valuenum], MultiValues[Index].items_default[valuenum], tagnum, item, MAXBUF, allow_newlines))
vl.push_back(ValueItem(item));
else
vl.push_back(ValueItem(""));
@@ -1124,7 +1070,7 @@ void ServerConfig::Read(bool bail, const std::string &useruid)
case DT_IPADDRESS:
{
char item[MAXBUF];
- if (ConfValue(newconfig, MultiValues[Index].tag, MultiValues[Index].items[valuenum], MultiValues[Index].items_default[valuenum], tagnum, item, MAXBUF, allow_newlines))
+ if (ConfValue(MultiValues[Index].tag, MultiValues[Index].items[valuenum], MultiValues[Index].items_default[valuenum], tagnum, item, MAXBUF, allow_newlines))
vl.push_back(ValueItem(item));
else
vl.push_back(ValueItem(""));
@@ -1134,7 +1080,7 @@ void ServerConfig::Read(bool bail, const std::string &useruid)
case DT_CHANNEL:
{
char item[MAXBUF];
- if (ConfValue(newconfig, MultiValues[Index].tag, MultiValues[Index].items[valuenum], MultiValues[Index].items_default[valuenum], tagnum, item, MAXBUF, allow_newlines))
+ if (ConfValue(MultiValues[Index].tag, MultiValues[Index].items[valuenum], MultiValues[Index].items_default[valuenum], tagnum, item, MAXBUF, allow_newlines))
vl.push_back(ValueItem(item));
else
vl.push_back(ValueItem(""));
@@ -1145,7 +1091,7 @@ void ServerConfig::Read(bool bail, const std::string &useruid)
case DT_CHARPTR:
{
char item[MAXBUF];
- if (ConfValue(newconfig, MultiValues[Index].tag, MultiValues[Index].items[valuenum], MultiValues[Index].items_default[valuenum], tagnum, item, MAXBUF, allow_newlines))
+ if (ConfValue(MultiValues[Index].tag, MultiValues[Index].items[valuenum], MultiValues[Index].items_default[valuenum], tagnum, item, MAXBUF, allow_newlines))
vl.push_back(ValueItem(item));
else
vl.push_back(ValueItem(""));
@@ -1154,7 +1100,7 @@ void ServerConfig::Read(bool bail, const std::string &useruid)
case DT_INTEGER:
{
int item = 0;
- if (ConfValueInteger(newconfig, MultiValues[Index].tag, MultiValues[Index].items[valuenum], MultiValues[Index].items_default[valuenum], tagnum, item))
+ if (ConfValueInteger(MultiValues[Index].tag, MultiValues[Index].items[valuenum], MultiValues[Index].items_default[valuenum], tagnum, item))
vl.push_back(ValueItem(item));
else
vl.push_back(ValueItem(0));
@@ -1162,7 +1108,7 @@ void ServerConfig::Read(bool bail, const std::string &useruid)
break;
case DT_BOOLEAN:
{
- bool item = ConfValueBool(newconfig, MultiValues[Index].tag, MultiValues[Index].items[valuenum], MultiValues[Index].items_default[valuenum], tagnum);
+ bool item = ConfValueBool(MultiValues[Index].tag, MultiValues[Index].items[valuenum], MultiValues[Index].items_default[valuenum], tagnum);
vl.push_back(ValueItem(item));
}
break;
@@ -1192,25 +1138,26 @@ void ServerConfig::Read(bool bail, const std::string &useruid)
catch (CoreException &ce)
{
- ReportConfigError(ce.GetReason(), bail, useruid);
+ errstr << ce.GetReason();
+ valid = false;
return;
}
// XXX: ServerInstance->Threads->Lock();
- for (int i = 0; i < ConfValueEnum(newconfig, "type"); ++i)
+ for (int i = 0; i < ConfValueEnum("type"); ++i)
{
char item[MAXBUF], classn[MAXBUF], classes[MAXBUF];
std::string classname;
- ConfValue(newconfig, "type", "classes", "", i, classes, MAXBUF, false);
+ ConfValue("type", "classes", "", i, classes, MAXBUF, false);
irc::spacesepstream str(classes);
- ConfValue(newconfig, "type", "name", "", i, item, MAXBUF, false);
+ ConfValue("type", "name", "", i, item, MAXBUF, false);
while (str.GetToken(classname))
{
std::string lost;
bool foundclass = false;
- for (int j = 0; j < ConfValueEnum(newconfig, "class"); ++j)
+ for (int j = 0; j < ConfValueEnum("class"); ++j)
{
- ConfValue(newconfig, "class", "name", "", j, classn, MAXBUF, false);
+ ConfValue("class", "name", "", j, classn, MAXBUF, false);
if (!strcmp(classn, classname.c_str()))
{
foundclass = true;
@@ -1219,141 +1166,126 @@ void ServerConfig::Read(bool bail, const std::string &useruid)
}
if (!foundclass)
{
- if (!useruid.empty())
- {
- User* user = ServerInstance->FindNick(useruid);
- if (user)
- user->WriteServ("NOTICE %s :*** Warning: Oper type '%s' has a missing class named '%s', this does nothing!", user->nick.c_str(), item, classname.c_str());
- }
- else
- {
- if (bail)
- printf("Warning: Oper type '%s' has a missing class named '%s', this does nothing!\n", item, classname.c_str());
- else
- ServerInstance->SNO->WriteToSnoMask('a', "Warning: Oper type '%s' has a missing class named '%s', this does nothing!", item, classname.c_str());
- }
+ char msg[MAXBUF];
+ snprintf(msg, MAXBUF, " Warning: Oper type '%s' has a missing class named '%s', this does nothing!\n",
+ item, classname.c_str());
+ errstr << msg;
}
}
}
- /* If we succeeded, set the ircd config to the new one */
- this->config_data = newconfig;
-
- // XXX: ServerInstance->Threads->Unlock();
+}
+void ServerConfig::Apply(ServerConfig* old, const std::string &useruid)
+{
+ int rem = 0, add = 0;
// write once here, to try it out and make sure its ok
ServerInstance->WritePID(this->PID);
- /* If we're rehashing, let's load any new modules, and unload old ones
- */
- if (!bail)
+ FailedPortList pl;
+ ServerInstance->BindPorts(pl);
+
+ if (pl.size())
{
- int found_ports = 0;
- FailedPortList pl;
- ServerInstance->BindPorts(false, found_ports, pl);
+ errstr << "Not all your client ports could be bound.\nThe following port(s) failed to bind:\n";
- if (pl.size() && !useruid.empty())
+ int j = 1;
+ for (FailedPortList::iterator i = pl.begin(); i != pl.end(); i++, j++)
{
- // XXX: ServerInstance->Threads->Lock();
- User* user = ServerInstance->FindNick(useruid);
- if (user)
- {
- user->WriteServ("NOTICE %s :*** Not all your client ports could be bound.", user->nick.c_str());
- user->WriteServ("NOTICE %s :*** The following port(s) failed to bind:", user->nick.c_str());
- int j = 1;
- for (FailedPortList::iterator i = pl.begin(); i != pl.end(); i++, j++)
- {
- user->WriteServ("NOTICE %s :*** %d. Address: %s Reason: %s", user->nick.c_str(), j, i->first.empty() ? "<all>" : i->first.c_str(), i->second.c_str());
- }
- }
- // XXX: ServerInstance->Threads->Unlock();
+ char buf[MAXBUF];
+ snprintf(buf, MAXBUF, "%d. Address: %s Reason: %s\n", j, i->first.empty() ? "<all>" : i->first.c_str(), i->second.c_str());
+ errstr << buf;
}
+ }
+
+
+ /* No old configuration -> initial boot, nothing more to do here */
+ if (!old)
+ return;
+
+ /*
+ * These values can only be set on boot. Keep their old values.
+ */
+ memcpy(this->ServerName, old->ServerName, sizeof(this->ServerName));
+ memcpy(this->sid, old->sid, sizeof(this->sid));
- // XXX: ServerInstance->Threads->Lock();
- if (!removed_modules.empty())
+ if (!removed_modules.empty())
+ {
+ for (std::vector<std::string>::iterator removing = removed_modules.begin(); removing != removed_modules.end(); removing++)
{
- for (std::vector<std::string>::iterator removing = removed_modules.begin(); removing != removed_modules.end(); removing++)
+ if (ServerInstance->Modules->Unload(removing->c_str()))
{
- if (ServerInstance->Modules->Unload(removing->c_str()))
- {
- ServerInstance->SNO->WriteToSnoMask('a', "*** REHASH UNLOADED MODULE: %s",removing->c_str());
+ ServerInstance->SNO->WriteToSnoMask('a', "*** REHASH UNLOADED MODULE: %s",removing->c_str());
- if (!useruid.empty())
- {
- User* user = ServerInstance->FindNick(useruid);
- if (user)
- user->WriteNumeric(RPL_UNLOADEDMODULE, "%s %s :Module %s successfully unloaded.",user->nick.c_str(), removing->c_str(), removing->c_str());
- }
- else
- ServerInstance->SNO->WriteToSnoMask('a', "Module %s successfully unloaded.", removing->c_str());
-
- rem++;
+ if (!useruid.empty())
+ {
+ User* user = ServerInstance->FindNick(useruid);
+ if (user)
+ user->WriteNumeric(RPL_UNLOADEDMODULE, "%s %s :Module %s successfully unloaded.",user->nick.c_str(), removing->c_str(), removing->c_str());
}
else
+ ServerInstance->SNO->WriteToSnoMask('a', "Module %s successfully unloaded.", removing->c_str());
+
+ rem++;
+ }
+ else
+ {
+ if (!useruid.empty())
{
- if (!useruid.empty())
- {
- User* user = ServerInstance->FindNick(useruid);
- if (user)
- user->WriteNumeric(ERR_CANTUNLOADMODULE, "%s %s :Failed to unload module %s: %s",user->nick.c_str(), removing->c_str(), removing->c_str(), ServerInstance->Modules->LastError().c_str());
- }
- else
- ServerInstance->SNO->WriteToSnoMask('a', "Failed to unload module %s: %s", removing->c_str(), ServerInstance->Modules->LastError().c_str());
+ User* user = ServerInstance->FindNick(useruid);
+ if (user)
+ user->WriteNumeric(ERR_CANTUNLOADMODULE, "%s %s :Failed to unload module %s: %s",user->nick.c_str(), removing->c_str(), removing->c_str(), ServerInstance->Modules->LastError().c_str());
}
+ else
+ ServerInstance->SNO->WriteToSnoMask('a', "Failed to unload module %s: %s", removing->c_str(), ServerInstance->Modules->LastError().c_str());
}
}
+ }
- if (!added_modules.empty())
+ if (!added_modules.empty())
+ {
+ for (std::vector<std::string>::iterator adding = added_modules.begin(); adding != added_modules.end(); adding++)
{
- for (std::vector<std::string>::iterator adding = added_modules.begin(); adding != added_modules.end(); adding++)
+ if (ServerInstance->Modules->Load(adding->c_str()))
{
- if (ServerInstance->Modules->Load(adding->c_str()))
+ ServerInstance->SNO->WriteToSnoMask('a', "*** REHASH LOADED MODULE: %s",adding->c_str());
+ if (!useruid.empty())
{
- ServerInstance->SNO->WriteToSnoMask('a', "*** REHASH LOADED MODULE: %s",adding->c_str());
- if (!useruid.empty())
- {
- User* user = ServerInstance->FindNick(useruid);
- if (user)
- user->WriteNumeric(RPL_LOADEDMODULE, "%s %s :Module %s successfully loaded.",user->nick.c_str(), adding->c_str(), adding->c_str());
- }
- else
- ServerInstance->SNO->WriteToSnoMask('a', "Module %s successfully loaded.", adding->c_str());
-
- add++;
+ User* user = ServerInstance->FindNick(useruid);
+ if (user)
+ user->WriteNumeric(RPL_LOADEDMODULE, "%s %s :Module %s successfully loaded.",user->nick.c_str(), adding->c_str(), adding->c_str());
}
else
+ ServerInstance->SNO->WriteToSnoMask('a', "Module %s successfully loaded.", adding->c_str());
+
+ add++;
+ }
+ else
+ {
+ if (!useruid.empty())
{
- if (!useruid.empty())
- {
- User* user = ServerInstance->FindNick(useruid);
- if (user)
- user->WriteNumeric(ERR_CANTLOADMODULE, "%s %s :Failed to load module %s: %s",user->nick.c_str(), adding->c_str(), adding->c_str(), ServerInstance->Modules->LastError().c_str());
- }
- else
- ServerInstance->SNO->WriteToSnoMask('a', "Failed to load module %s: %s", adding->c_str(), ServerInstance->Modules->LastError().c_str());
+ User* user = ServerInstance->FindNick(useruid);
+ if (user)
+ user->WriteNumeric(ERR_CANTLOADMODULE, "%s %s :Failed to load module %s: %s",user->nick.c_str(), adding->c_str(), adding->c_str(), ServerInstance->Modules->LastError().c_str());
}
+ else
+ ServerInstance->SNO->WriteToSnoMask('a', "Failed to load module %s: %s", adding->c_str(), ServerInstance->Modules->LastError().c_str());
}
}
- // XXX: ServerInstance->Threads->Unlock();
-
}
+ // XXX: ServerInstance->Threads->Unlock();
- if (!bail)
+ if (!useruid.empty())
{
- if (!useruid.empty())
- {
- User* user = ServerInstance->FindNick(useruid);
- if (user)
- user->WriteServ("NOTICE %s :*** Successfully rehashed server.", user->nick.c_str());
- }
- else
- ServerInstance->SNO->WriteToSnoMask('a', "*** Successfully rehashed server.");
+ User* user = ServerInstance->FindNick(useruid);
+ if (user)
+ user->WriteServ("NOTICE %s :*** Successfully rehashed server.", user->nick.c_str());
}
-
+ else
+ ServerInstance->SNO->WriteToSnoMask('a', "*** Successfully rehashed server.");
}
-
-bool ServerConfig::LoadConf(ConfigDataHash &target, FILE* &conf, const char* filename, std::ostringstream &errorstream)
+bool ServerConfig::LoadConf(FILE* &conf, const char* filename)
{
std::string line;
char ch;
@@ -1373,7 +1305,7 @@ bool ServerConfig::LoadConf(ConfigDataHash &target, FILE* &conf, const char* fil
/* Check if the file open failed first */
if (!conf)
{
- errorstream << "LoadConf: Couldn't open config file: " << filename << std::endl;
+ errstr << "LoadConf: Couldn't open config file: " << filename << std::endl;
return false;
}
@@ -1381,7 +1313,7 @@ bool ServerConfig::LoadConf(ConfigDataHash &target, FILE* &conf, const char* fil
{
if (std::string(filename) == include_stack[t])
{
- errorstream << "File " << filename << " is included recursively (looped inclusion)." << std::endl;
+ errstr << "File " << filename << " is included recursively (looped inclusion)." << std::endl;
return false;
}
}
@@ -1402,7 +1334,7 @@ bool ServerConfig::LoadConf(ConfigDataHash &target, FILE* &conf, const char* fil
*/
if ((character_count++ < 2) && (ch == '\xFF' || ch == '\xFE'))
{
- errorstream << "File " << filename << " cannot be read, as it is encoded in braindead UTF-16. Save your file as plain ASCII!" << std::endl;
+ errstr << "File " << filename << " cannot be read, as it is encoded in braindead UTF-16. Save your file as plain ASCII!" << std::endl;
return false;
}
@@ -1458,7 +1390,7 @@ bool ServerConfig::LoadConf(ConfigDataHash &target, FILE* &conf, const char* fil
}
else
{
- errorstream << "End of file after a \\, what did you want to escape?: " << filename << ":" << linenumber << std::endl;
+ errstr << "End of file after a \\, what did you want to escape?: " << filename << ":" << linenumber << std::endl;
return false;
}
}
@@ -1468,7 +1400,7 @@ bool ServerConfig::LoadConf(ConfigDataHash &target, FILE* &conf, const char* fil
if ((ch != '<') && (!in_tag) && (!in_comment) && (ch > ' ') && (ch != 9))
{
- errorstream << "You have stray characters beyond the tag which starts at " << filename << ":" << last_successful_parse << std::endl;
+ errstr << "You have stray characters beyond the tag which starts at " << filename << ":" << last_successful_parse << std::endl;
return false;
}
@@ -1478,7 +1410,7 @@ bool ServerConfig::LoadConf(ConfigDataHash &target, FILE* &conf, const char* fil
{
if (!in_quote)
{
- errorstream << "The tag at location " << filename << ":" << last_successful_parse << " was valid, but there is an error in the tag which comes after it. You are possibly missing a \" or >. Please check this." << std::endl;
+ errstr << "The tag at location " << filename << ":" << last_successful_parse << " was valid, but there is an error in the tag which comes after it. You are possibly missing a \" or >. Please check this." << std::endl;
return false;
}
}
@@ -1486,12 +1418,12 @@ bool ServerConfig::LoadConf(ConfigDataHash &target, FILE* &conf, const char* fil
{
if (in_quote)
{
- errorstream << "Parser error: Inside a quote but not within the last valid tag, which was opened at: " << filename << ":" << last_successful_parse << std::endl;
+ errstr << "Parser error: Inside a quote but not within the last valid tag, which was opened at: " << filename << ":" << last_successful_parse << std::endl;
return false;
}
else
{
- // errorstream << "Opening new config tag on line " << linenumber << std::endl;
+ // errstr << "Opening new config tag on line " << linenumber << std::endl;
in_tag = true;
}
}
@@ -1502,12 +1434,12 @@ bool ServerConfig::LoadConf(ConfigDataHash &target, FILE* &conf, const char* fil
{
if (in_quote)
{
- // errorstream << "Closing quote in config tag on line " << linenumber << std::endl;
+ // errstr << "Closing quote in config tag on line " << linenumber << std::endl;
in_quote = false;
}
else
{
- // errorstream << "Opening quote in config tag on line " << linenumber << std::endl;
+ // errstr << "Opening quote in config tag on line " << linenumber << std::endl;
in_quote = true;
}
}
@@ -1515,11 +1447,11 @@ bool ServerConfig::LoadConf(ConfigDataHash &target, FILE* &conf, const char* fil
{
if (in_quote)
{
- errorstream << "The tag immediately after the one at " << filename << ":" << last_successful_parse << " has a missing closing \" symbol. Please check this." << std::endl;
+ errstr << "The tag immediately after the one at " << filename << ":" << last_successful_parse << " has a missing closing \" symbol. Please check this." << std::endl;
}
else
{
- errorstream << "You have opened a quote (\") beyond the tag at " << filename << ":" << last_successful_parse << " without opening a new tag. Please check this." << std::endl;
+ errstr << "You have opened a quote (\") beyond the tag at " << filename << ":" << last_successful_parse << " without opening a new tag. Please check this." << std::endl;
}
}
}
@@ -1529,7 +1461,7 @@ bool ServerConfig::LoadConf(ConfigDataHash &target, FILE* &conf, const char* fil
{
if (in_tag)
{
- // errorstream << "Closing config tag on line " << linenumber << std::endl;
+ // errstr << "Closing config tag on line " << linenumber << std::endl;
in_tag = false;
/*
@@ -1537,7 +1469,7 @@ bool ServerConfig::LoadConf(ConfigDataHash &target, FILE* &conf, const char* fil
* LoadConf() and load the included config into the same ConfigDataHash
*/
long bl = linenumber;
- if (!this->ParseLine(target, filename, line, linenumber, errorstream))
+ if (!this->ParseLine(filename, line, linenumber))
return false;
last_successful_parse = linenumber;
@@ -1547,7 +1479,7 @@ bool ServerConfig::LoadConf(ConfigDataHash &target, FILE* &conf, const char* fil
}
else
{
- errorstream << "You forgot to close the tag which comes immediately after the one at " << filename << ":" << last_successful_parse << std::endl;
+ errstr << "You forgot to close the tag which comes immediately after the one at " << filename << ":" << last_successful_parse << std::endl;
return false;
}
}
@@ -1557,7 +1489,7 @@ bool ServerConfig::LoadConf(ConfigDataHash &target, FILE* &conf, const char* fil
/* Fix for bug #392 - if we reach the end of a file and we are still in a quote or comment, most likely the user fucked up */
if (in_comment || in_quote)
{
- errorstream << "Reached end of file whilst still inside a quoted section or tag. This is most likely an error or there \
+ errstr << "Reached end of file whilst still inside a quoted section or tag. This is most likely an error or there \
is a newline missing from the end of the file: " << filename << ":" << linenumber << std::endl;
}
@@ -1565,12 +1497,12 @@ bool ServerConfig::LoadConf(ConfigDataHash &target, FILE* &conf, const char* fil
}
-bool ServerConfig::LoadConf(ConfigDataHash &target, FILE* &conf, const std::string &filename, std::ostringstream &errorstream)
+bool ServerConfig::LoadConf(FILE* &conf, const std::string &filename)
{
- return this->LoadConf(target, conf, filename.c_str(), errorstream);
+ return this->LoadConf(conf, filename.c_str());
}
-bool ServerConfig::ParseLine(ConfigDataHash &target, const std::string &filename, std::string &line, long &linenumber, std::ostringstream &errorstream)
+bool ServerConfig::ParseLine(const std::string &filename, std::string &line, long &linenumber)
{
std::string tagname;
std::string current_key;
@@ -1597,7 +1529,7 @@ bool ServerConfig::ParseLine(ConfigDataHash &target, const std::string &filename
tagname += *c;
else
{
- errorstream << "Invalid character in value name of tag: '" << *c << "' in value '" << tagname << "' in filename: " << filename << ":" << linenumber << std::endl;
+ errstr << "Invalid character in value name of tag: '" << *c << "' in value '" << tagname << "' in filename: " << filename << ":" << linenumber << std::endl;
return false;
}
}
@@ -1625,7 +1557,7 @@ bool ServerConfig::ParseLine(ConfigDataHash &target, const std::string &filename
current_key += *c;
else
{
- errorstream << "Invalid character in key: '" << *c << "' in key '" << current_key << "' in filename: " << filename << ":" << linenumber << std::endl;
+ errstr << "Invalid character in key: '" << *c << "' in key '" << current_key << "' in filename: " << filename << ":" << linenumber << std::endl;
return false;
}
}
@@ -1654,7 +1586,7 @@ bool ServerConfig::ParseLine(ConfigDataHash &target, const std::string &filename
}
else if ((*c == '\\') && (!in_quote))
{
- errorstream << "You can't have an escape sequence outside of a quoted section: " << filename << ":" << linenumber << std::endl;
+ errstr << "You can't have an escape sequence outside of a quoted section: " << filename << ":" << linenumber << std::endl;
return false;
}
else if ((*c == '\n') && (in_quote))
@@ -1688,13 +1620,13 @@ bool ServerConfig::ParseLine(ConfigDataHash &target, const std::string &filename
if ((tagname == "include") && (current_key == "file"))
{
- if (!this->DoInclude(target, current_value, errorstream))
+ if (!this->DoInclude(current_value))
return false;
}
else if ((tagname == "include") && (current_key == "executable"))
{
/* Pipe an executable and use its stdout as config data */
- if (!this->DoPipe(target, current_value, errorstream))
+ if (!this->DoPipe(current_value))
return false;
}
@@ -1715,23 +1647,23 @@ bool ServerConfig::ParseLine(ConfigDataHash &target, const std::string &filename
}
/* Finished parsing the tag, add it to the config hash */
- target.insert(std::pair<std::string, KeyValList > (tagname, results));
+ config_data.insert(std::pair<std::string, KeyValList > (tagname, results));
return true;
}
-bool ServerConfig::DoPipe(ConfigDataHash &target, const std::string &file, std::ostringstream &errorstream)
+bool ServerConfig::DoPipe(const std::string &file)
{
FILE* conf = popen(file.c_str(), "r");
bool ret = false;
if (conf)
{
- ret = LoadConf(target, conf, file.c_str(), errorstream);
+ ret = LoadConf(conf, file.c_str());
pclose(conf);
}
else
- errorstream << "Couldn't execute: " << file << std::endl;
+ errstr << "Couldn't execute: " << file << std::endl;
return ret;
}
@@ -1741,7 +1673,7 @@ bool ServerConfig::StartsWithWindowsDriveLetter(const std::string &path)
return (path.length() > 2 && isalpha(path[0]) && path[1] == ':');
}
-bool ServerConfig::DoInclude(ConfigDataHash &target, const std::string &file, std::ostringstream &errorstream)
+bool ServerConfig::DoInclude(const std::string &file)
{
std::string confpath;
std::string newfile;
@@ -1762,7 +1694,7 @@ bool ServerConfig::DoInclude(ConfigDataHash &target, const std::string &file, st
}
else
{
- errorstream << "Couldn't get config path from: " << ServerInstance->ConfigFileName << std::endl;
+ errstr << "Couldn't get config path from: " << ServerInstance->ConfigFileName << std::endl;
return false;
}
}
@@ -1772,39 +1704,39 @@ bool ServerConfig::DoInclude(ConfigDataHash &target, const std::string &file, st
if (conf)
{
- ret = LoadConf(target, conf, newfile, errorstream);
+ ret = LoadConf(conf, newfile);
fclose(conf);
}
else
- errorstream << "Couldn't open config file: " << file << std::endl;
+ errstr << "Couldn't open config file: " << file << std::endl;
return ret;
}
-bool ServerConfig::ConfValue(ConfigDataHash &target, const char* tag, const char* var, int index, char* result, int length, bool allow_linefeeds)
+bool ServerConfig::ConfValue(const char* tag, const char* var, int index, char* result, int length, bool allow_linefeeds)
{
- return ConfValue(target, tag, var, "", index, result, length, allow_linefeeds);
+ return ConfValue(tag, var, "", index, result, length, allow_linefeeds);
}
-bool ServerConfig::ConfValue(ConfigDataHash &target, const char* tag, const char* var, const char* default_value, int index, char* result, int length, bool allow_linefeeds)
+bool ServerConfig::ConfValue(const char* tag, const char* var, const char* default_value, int index, char* result, int length, bool allow_linefeeds)
{
std::string value;
- bool r = ConfValue(target, std::string(tag), std::string(var), std::string(default_value), index, value, allow_linefeeds);
+ bool r = ConfValue(std::string(tag), std::string(var), std::string(default_value), index, value, allow_linefeeds);
strlcpy(result, value.c_str(), length);
return r;
}
-bool ServerConfig::ConfValue(ConfigDataHash &target, const std::string &tag, const std::string &var, int index, std::string &result, bool allow_linefeeds)
+bool ServerConfig::ConfValue(const std::string &tag, const std::string &var, int index, std::string &result, bool allow_linefeeds)
{
- return ConfValue(target, tag, var, "", index, result, allow_linefeeds);
+ return ConfValue(tag, var, "", index, result, allow_linefeeds);
}
-bool ServerConfig::ConfValue(ConfigDataHash &target, const std::string &tag, const std::string &var, const std::string &default_value, int index, std::string &result, bool allow_linefeeds)
+bool ServerConfig::ConfValue(const std::string &tag, const std::string &var, const std::string &default_value, int index, std::string &result, bool allow_linefeeds)
{
ConfigDataHash::size_type pos = index;
- if (pos < target.count(tag))
+ if (pos < config_data.count(tag))
{
- ConfigDataHash::iterator iter = target.find(tag);
+ ConfigDataHash::iterator iter = config_data.find(tag);
for(int i = 0; i < index; i++)
iter++;
@@ -1844,26 +1776,26 @@ bool ServerConfig::ConfValue(ConfigDataHash &target, const std::string &tag, con
return false;
}
-bool ServerConfig::ConfValueInteger(ConfigDataHash &target, const char* tag, const char* var, int index, int &result)
+bool ServerConfig::ConfValueInteger(const char* tag, const char* var, int index, int &result)
{
- return ConfValueInteger(target, std::string(tag), std::string(var), "", index, result);
+ return ConfValueInteger(std::string(tag), std::string(var), "", index, result);
}
-bool ServerConfig::ConfValueInteger(ConfigDataHash &target, const char* tag, const char* var, const char* default_value, int index, int &result)
+bool ServerConfig::ConfValueInteger(const char* tag, const char* var, const char* default_value, int index, int &result)
{
- return ConfValueInteger(target, std::string(tag), std::string(var), std::string(default_value), index, result);
+ return ConfValueInteger(std::string(tag), std::string(var), std::string(default_value), index, result);
}
-bool ServerConfig::ConfValueInteger(ConfigDataHash &target, const std::string &tag, const std::string &var, int index, int &result)
+bool ServerConfig::ConfValueInteger(const std::string &tag, const std::string &var, int index, int &result)
{
- return ConfValueInteger(target, tag, var, "", index, result);
+ return ConfValueInteger(tag, var, "", index, result);
}
-bool ServerConfig::ConfValueInteger(ConfigDataHash &target, const std::string &tag, const std::string &var, const std::string &default_value, int index, int &result)
+bool ServerConfig::ConfValueInteger(const std::string &tag, const std::string &var, const std::string &default_value, int index, int &result)
{
std::string value;
std::istringstream stream;
- bool r = ConfValue(target, tag, var, default_value, index, value);
+ bool r = ConfValue(tag, var, default_value, index, value);
stream.str(value);
if(!(stream >> result))
return false;
@@ -1907,52 +1839,52 @@ bool ServerConfig::ConfValueInteger(ConfigDataHash &target, const std::string &t
}
-bool ServerConfig::ConfValueBool(ConfigDataHash &target, const char* tag, const char* var, int index)
+bool ServerConfig::ConfValueBool(const char* tag, const char* var, int index)
{
- return ConfValueBool(target, std::string(tag), std::string(var), "", index);
+ return ConfValueBool(std::string(tag), std::string(var), "", index);
}
-bool ServerConfig::ConfValueBool(ConfigDataHash &target, const char* tag, const char* var, const char* default_value, int index)
+bool ServerConfig::ConfValueBool(const char* tag, const char* var, const char* default_value, int index)
{
- return ConfValueBool(target, std::string(tag), std::string(var), std::string(default_value), index);
+ return ConfValueBool(std::string(tag), std::string(var), std::string(default_value), index);
}
-bool ServerConfig::ConfValueBool(ConfigDataHash &target, const std::string &tag, const std::string &var, int index)
+bool ServerConfig::ConfValueBool(const std::string &tag, const std::string &var, int index)
{
- return ConfValueBool(target, tag, var, "", index);
+ return ConfValueBool(tag, var, "", index);
}
-bool ServerConfig::ConfValueBool(ConfigDataHash &target, const std::string &tag, const std::string &var, const std::string &default_value, int index)
+bool ServerConfig::ConfValueBool(const std::string &tag, const std::string &var, const std::string &default_value, int index)
{
std::string result;
- if(!ConfValue(target, tag, var, default_value, index, result))
+ if(!ConfValue(tag, var, default_value, index, result))
return false;
return ((result == "yes") || (result == "true") || (result == "1"));
}
-int ServerConfig::ConfValueEnum(ConfigDataHash &target, const char* tag)
+int ServerConfig::ConfValueEnum(const char* tag)
{
- return target.count(tag);
+ return config_data.count(tag);
}
-int ServerConfig::ConfValueEnum(ConfigDataHash &target, const std::string &tag)
+int ServerConfig::ConfValueEnum(const std::string &tag)
{
- return target.count(tag);
+ return config_data.count(tag);
}
-int ServerConfig::ConfVarEnum(ConfigDataHash &target, const char* tag, int index)
+int ServerConfig::ConfVarEnum(const char* tag, int index)
{
- return ConfVarEnum(target, std::string(tag), index);
+ return ConfVarEnum(std::string(tag), index);
}
-int ServerConfig::ConfVarEnum(ConfigDataHash &target, const std::string &tag, int index)
+int ServerConfig::ConfVarEnum(const std::string &tag, int index)
{
ConfigDataHash::size_type pos = index;
- if (pos < target.count(tag))
+ if (pos < config_data.count(tag))
{
- ConfigDataHash::const_iterator iter = target.find(tag);
+ ConfigDataHash::const_iterator iter = config_data.find(tag);
for(int i = 0; i < index; i++)
iter++;
@@ -2304,6 +2236,15 @@ bool DoneELine(ServerConfig* conf, const char* tag)
void ConfigReaderThread::Run()
{
- ServerInstance->Config->Read(do_bail, TheUserUID);
+ Config = new ServerConfig(ServerInstance);
+ Config->Read();
done = true;
}
+
+void ConfigReaderThread::Finish()
+{
+ ServerConfig* old = ServerInstance->Config;
+ ServerInstance->Config = this->Config;
+ Config->Apply(old, TheUserUID);
+ delete old;
+}
diff --git a/src/inspircd.cpp b/src/inspircd.cpp
index 630216d6e..ca89e0ef3 100644
--- a/src/inspircd.cpp
+++ b/src/inspircd.cpp
@@ -352,7 +352,6 @@ InspIRCd::InspIRCd(int argc, char** argv)
// Avoid erroneous frees on early exit
WindowsIPC = 0;
#endif
- int found_ports = 0;
FailedPortList pl;
int do_version = 0, do_nofork = 0, do_debug = 0,
do_nolog = 0, do_root = 0, do_testsuite = 0; /* flag variables */
@@ -374,6 +373,7 @@ InspIRCd::InspIRCd(int argc, char** argv)
this->XLines = 0;
this->Modes = 0;
this->Res = 0;
+ this->ConfigThread = NULL;
// Initialise TIME
this->TIME = time(NULL);
@@ -573,11 +573,8 @@ InspIRCd::InspIRCd(int argc, char** argv)
/* During startup we don't actually initialize this
* in the thread engine.
*/
- this->ConfigThread = new ConfigReaderThread(this, true, "");
- ConfigThread->Run();
- delete ConfigThread;
- this->ConfigThread = NULL;
- /* Switch over logfiles */
+ this->Config->Read();
+ this->Config->Apply(NULL, "");
Logs->OpenFileLogs();
/** Note: This is safe, the method checks for user == NULL */
@@ -618,7 +615,7 @@ InspIRCd::InspIRCd(int argc, char** argv)
this->XLines->ApplyLines();
CheckDie();
- int bounditems = BindPorts(true, found_ports, pl);
+ int bounditems = BindPorts(pl);
printf("\n");
@@ -628,9 +625,10 @@ InspIRCd::InspIRCd(int argc, char** argv)
this->BuildISupport();
InitializeDisabledCommands(Config->DisabledCommands, this);
- if (ports.size() != (unsigned int)found_ports)
+ if (!pl.empty())
{
- printf("\nWARNING: Not all your client ports could be bound --\nstarting anyway with %d of %d client ports bound.\n\n", bounditems, found_ports);
+ printf("\nWARNING: Not all your client ports could be bound --\nstarting anyway with %d of %d client ports bound.\n\n",
+ bounditems, bounditems + (int)pl.size());
printf("The following port(s) failed to bind:\n");
printf("Hint: Try using a public IP instead of blank or *\n\n");
int j = 1;
@@ -768,13 +766,12 @@ int InspIRCd::Run()
if (this->ConfigThread && this->ConfigThread->IsDone())
{
/* Rehash has completed */
+ this->Logs->Log("CONFIG",DEBUG,"Detected ConfigThread exiting, tidying up...");
/* Switch over logfiles */
Logs->CloseLogs();
Logs->OpenFileLogs();
- this->Logs->Log("CONFIG",DEBUG,"Detected ConfigThread exiting, tidying up...");
-
/*
* Apply the changed configuration from the rehash. This is not done within the
* configuration thread becasuse they may invoke functions that are not threadsafe.
@@ -782,12 +779,13 @@ int InspIRCd::Run()
* XXX: The order of these is IMPORTANT, do not reorder them without testing
* thoroughly!!!
*/
+ this->ConfigThread->Finish();
this->XLines->CheckELines();
this->XLines->ApplyLines();
this->Res->Rehash();
this->ResetMaxBans();
InitializeDisabledCommands(Config->DisabledCommands, this);
- User* user = !Config->RehashUserUID.empty() ? FindNick(Config->RehashUserUID) : NULL;
+ User* user = ConfigThread->TheUserUID.empty() ? FindNick(ConfigThread->TheUserUID) : NULL;
FOREACH_MOD_I(this, I_OnRehash, OnRehash(user));
this->BuildISupport();
diff --git a/src/modules.cpp b/src/modules.cpp
index 71f4d7524..87e2de705 100644
--- a/src/modules.cpp
+++ b/src/modules.cpp
@@ -561,9 +561,9 @@ void ModuleManager::LoadAll()
char configToken[MAXBUF];
ModCount = -1;
- for(int count = 0; count < Instance->Config->ConfValueEnum(Instance->Config->config_data, "module"); count++)
+ for(int count = 0; count < Instance->Config->ConfValueEnum("module"); count++)
{
- Instance->Config->ConfValue(Instance->Config->config_data, "module", "name", count, configToken, MAXBUF);
+ Instance->Config->ConfValue("module", "name", count, configToken, MAXBUF);
printf_c("[\033[1;32m*\033[0m] Loading module:\t\033[1;32m%s\033[0m\n",configToken);
if (!this->Load(configToken))
@@ -799,36 +799,12 @@ const std::vector<std::string> ModuleManager::GetAllModuleNames(int filter)
ConfigReader::ConfigReader(InspIRCd* Instance) : ServerInstance(Instance)
{
- this->errorlog = new std::ostringstream(std::stringstream::in | std::stringstream::out);
- this->error = CONF_NO_ERROR;
- this->data = &ServerInstance->Config->config_data;
- this->privatehash = false;
this->error = 0;
}
ConfigReader::~ConfigReader()
{
- if (this->errorlog)
- delete this->errorlog;
- if(this->privatehash)
- delete this->data;
-}
-
-
-ConfigReader::ConfigReader(InspIRCd* Instance, const std::string &filename) : ServerInstance(Instance)
-{
- ServerInstance->Config->ClearStack();
-
- this->error = CONF_NO_ERROR;
- this->data = new ConfigDataHash;
- this->privatehash = true;
- this->errorlog = new std::ostringstream(std::stringstream::in | std::stringstream::out);
- /*** XXX: This might block! */
- this->readerror = ServerInstance->Config->DoInclude(*this->data, filename, *this->errorlog);
- if (!this->readerror)
- this->error = CONF_FILE_NOT_FOUND;
- this->error = 0;
}
@@ -837,7 +813,7 @@ std::string ConfigReader::ReadValue(const std::string &tag, const std::string &n
/* Don't need to strlcpy() tag and name anymore, ReadConf() takes const char* */
std::string result;
- if (!ServerInstance->Config->ConfValue(*this->data, tag, name, default_value, index, result, allow_linefeeds))
+ if (!ServerInstance->Config->ConfValue(tag, name, default_value, index, result, allow_linefeeds))
{
this->error = CONF_VALUE_NOT_FOUND;
}
@@ -851,7 +827,7 @@ std::string ConfigReader::ReadValue(const std::string &tag, const std::string &n
bool ConfigReader::ReadFlag(const std::string &tag, const std::string &name, const std::string &default_value, int index)
{
- return ServerInstance->Config->ConfValueBool(*this->data, tag, name, default_value, index);
+ return ServerInstance->Config->ConfValueBool(tag, name, default_value, index);
}
bool ConfigReader::ReadFlag(const std::string &tag, const std::string &name, int index)
@@ -864,7 +840,7 @@ int ConfigReader::ReadInteger(const std::string &tag, const std::string &name, c
{
int result;
- if(!ServerInstance->Config->ConfValueInteger(*this->data, tag, name, default_value, index, result))
+ if(!ServerInstance->Config->ConfValueInteger(tag, name, default_value, index, result))
{
this->error = CONF_VALUE_NOT_FOUND;
return 0;
@@ -891,28 +867,16 @@ long ConfigReader::GetError()
return olderr;
}
-void ConfigReader::DumpErrors(bool bail, User* user)
-{
- ServerInstance->Config->ReportConfigError(this->errorlog->str(), bail, user->uuid);
-}
-
-
int ConfigReader::Enumerate(const std::string &tag)
{
- return ServerInstance->Config->ConfValueEnum(*this->data, tag);
+ return ServerInstance->Config->ConfValueEnum(tag);
}
int ConfigReader::EnumerateValues(const std::string &tag, int index)
{
- return ServerInstance->Config->ConfVarEnum(*this->data, tag, index);
+ return ServerInstance->Config->ConfVarEnum(tag, index);
}
-bool ConfigReader::Verify()
-{
- return this->readerror;
-}
-
-
FileReader::FileReader(InspIRCd* Instance, const std::string &filename) : ServerInstance(Instance)
{
LoadFile(filename);
diff --git a/src/server.cpp b/src/server.cpp
index 1c73067b7..01f523e47 100644
--- a/src/server.cpp
+++ b/src/server.cpp
@@ -53,9 +53,7 @@ void RehashHandler::Call(const std::string &reason)
FOREACH_MOD_I(Server, I_OnGarbageCollect, OnGarbageCollect());
if (!Server->ConfigThread)
{
- Server->Config->RehashUserUID = "";
-
- Server->ConfigThread = new ConfigReaderThread(Server, false, "");
+ Server->ConfigThread = new ConfigReaderThread(Server, "");
Server->Threads->Start(Server->ConfigThread);
}
}
diff --git a/src/socket.cpp b/src/socket.cpp
index 35feda01f..d18a8f5bc 100644
--- a/src/socket.cpp
+++ b/src/socket.cpp
@@ -179,7 +179,7 @@ int irc::sockets::OpenTCPSocket(const char* addr, int socktype)
}
// XXX: it would be VERY nice to genericize this so all listen stuff (server/client) could use the one function. -- w00t
-int InspIRCd::BindPorts(bool, int &ports_found, FailedPortList &failed_ports)
+int InspIRCd::BindPorts(FailedPortList &failed_ports)
{
char configToken[MAXBUF], Addr[MAXBUF], Type[MAXBUF];
int bound = 0;
@@ -190,11 +190,11 @@ int InspIRCd::BindPorts(bool, int &ports_found, FailedPortList &failed_ports)
for (std::vector<ListenSocketBase *>::iterator o = ports.begin(); o != ports.end(); ++o)
old_ports.push_back(make_pair((*o)->GetIP(), (*o)->GetPort()));
- for (int count = 0; count < Config->ConfValueEnum(Config->config_data, "bind"); count++)
+ for (int count = 0; count < Config->ConfValueEnum("bind"); count++)
{
- Config->ConfValue(Config->config_data, "bind", "port", count, configToken, MAXBUF);
- Config->ConfValue(Config->config_data, "bind", "address", count, Addr, MAXBUF);
- Config->ConfValue(Config->config_data, "bind", "type", count, Type, MAXBUF);
+ Config->ConfValue("bind", "port", count, configToken, MAXBUF);
+ Config->ConfValue("bind", "address", count, Addr, MAXBUF);
+ Config->ConfValue("bind", "type", count, Type, MAXBUF);
if (strncmp(Addr, "::ffff:", 7) == 0)
this->Logs->Log("SOCKET",DEFAULT, "Using 4in6 (::ffff:) isn't recommended. You should bind IPv4 addresses directly instead.");
@@ -237,7 +237,6 @@ int InspIRCd::BindPorts(bool, int &ports_found, FailedPortList &failed_ports)
{
failed_ports.push_back(std::make_pair((*Addr ? Addr : "*") + std::string(":") + ConvToStr(portno), strerror(errno)));
}
- ports_found++;
}
}
}