Skip to content

Commit

Permalink
Make rehash generate a new ServerInstance->Config object
Browse files Browse the repository at this point in the history
This makes it possible to cancel a pending rehash, and fixes possible
threading issues with rehash and other events.

git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@11424 e03df62e-2008-0410-955e-edbf42e46eb7
  • Loading branch information
danieldg committed Jul 1, 2009
1 parent 50eebfe commit c384697
Show file tree
Hide file tree
Showing 12 changed files with 273 additions and 414 deletions.
72 changes: 32 additions & 40 deletions include/configreader.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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?
*/
Expand Down Expand Up @@ -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
*/
Expand All @@ -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
*/
Expand Down
16 changes: 8 additions & 8 deletions include/inspircd.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
}

Expand All @@ -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; }
};

Expand Down Expand Up @@ -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
Expand Down
31 changes: 0 additions & 31 deletions include/modules.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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.
*/
Expand Down Expand Up @@ -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
Expand Down
12 changes: 6 additions & 6 deletions src/commands.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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++)
Expand Down Expand Up @@ -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++)
Expand All @@ -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++)
Expand Down
20 changes: 10 additions & 10 deletions src/commands/cmd_oper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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))
{
Expand All @@ -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)
Expand Down
4 changes: 1 addition & 3 deletions src/commands/cmd_rehash.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
12 changes: 6 additions & 6 deletions src/commands/cmd_stats.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}
}
Expand Down Expand Up @@ -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;
Expand Down
Loading

0 comments on commit c384697

Please sign in to comment.