summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbrain <brain@e03df62e-2008-0410-955e-edbf42e46eb7>2007-08-11 12:05:31 +0000
committerbrain <brain@e03df62e-2008-0410-955e-edbf42e46eb7>2007-08-11 12:05:31 +0000
commit9595db021dbfc77f0b0bd81ddc01b2578435aa22 (patch)
tree17aa8a4c5eb434a4a34971e65f41deb15396c8e9
parent0f4caa76984ab4f15f8e69b4a396eb38f3a7fd4d (diff)
Allow rehash to attempt to load missing (and new) lib/cmd_*.so files, to allow users to fix an emergency situation you can create by trying to reload a corrupt .so without needing a restart
git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@7712 e03df62e-2008-0410-955e-edbf42e46eb7
-rw-r--r--include/command_parse.h11
-rw-r--r--src/command_parse.cpp41
-rw-r--r--src/configreader.cpp3
3 files changed, 40 insertions, 15 deletions
diff --git a/include/command_parse.h b/include/command_parse.h
index 58f63a802..2c3605613 100644
--- a/include/command_parse.h
+++ b/include/command_parse.h
@@ -56,10 +56,6 @@ class CoreExport CommandParser : public classbase
*/
void ProcessCommand(userrec *user, std::string &cmd);
- /** Insert the default RFC1459 commands into the command hash.
- */
- void SetupCommandTable();
-
/** Finds the init_command symbol in a .so file
* @param v A function pointer to be initialized
* @param h A valid shared object handle
@@ -198,6 +194,13 @@ class CoreExport CommandParser : public classbase
* @return True if the command was added
*/
bool CreateCommand(command_t *f, void* so_handle = NULL);
+
+ /** Insert the default RFC1459 commands into the command hash.
+ * Ignore any already loaded commands.
+ * @param user User to spool errors to, or if NULL, when an error occurs spool the errors to
+ * stdout then exit with EXIT_STATUS_HANDLER.
+ */
+ void SetupCommandTable(userrec* user);
};
/** Command handler class for the RELOAD command.
diff --git a/src/command_parse.cpp b/src/command_parse.cpp
index 6be50dd96..4e374d622 100644
--- a/src/command_parse.cpp
+++ b/src/command_parse.cpp
@@ -445,7 +445,7 @@ bool CommandParser::CreateCommand(command_t *f, void* so_handle)
CommandParser::CommandParser(InspIRCd* Instance) : ServerInstance(Instance)
{
para.resize(128);
- this->SetupCommandTable();
+ this->SetupCommandTable(NULL);
}
bool CommandParser::FindSym(void** v, void* h)
@@ -512,7 +512,7 @@ CmdResult cmd_reload::Handle(const char** parameters, int pcnt, userrec *user)
}
else
{
- user->WriteServ("NOTICE %s :*** Could not reload command '%s'", user->nick, parameters[0]);
+ user->WriteServ("NOTICE %s :*** Could not reload command '%s' -- fix this problem, then /REHASH as soon as possible!", user->nick, parameters[0]);
return CMD_FAILURE;
}
}
@@ -523,6 +523,10 @@ const char* CommandParser::LoadCommand(const char* name)
void* h;
command_t* (*cmd_factory_func)(InspIRCd*);
+ /* Command already exists? Succeed silently - this is needed for REHASH */
+ if (RFCCommands.find(name) != RFCCommands.end())
+ return NULL;
+
snprintf(filename, MAXBUF, "%s/%s", LIBRARYDIR, name);
h = dlopen(filename, RTLD_NOW | RTLD_GLOBAL);
@@ -541,12 +545,15 @@ const char* CommandParser::LoadCommand(const char* name)
return NULL;
}
-void CommandParser::SetupCommandTable()
+void CommandParser::SetupCommandTable(userrec* user)
{
RFCCommands.clear();
- printf("\nLoading core commands");
- fflush(stdout);
+ if (!user)
+ {
+ printf("\nLoading core commands");
+ fflush(stdout);
+ }
DIR* library = opendir(LIBRARYDIR);
if (library)
@@ -556,20 +563,32 @@ void CommandParser::SetupCommandTable()
{
if (match(entry->d_name, "cmd_*.so"))
{
- printf(".");
- fflush(stdout);
+ if (!user)
+ {
+ printf(".");
+ fflush(stdout);
+ }
const char* err = this->LoadCommand(entry->d_name);
if (err)
{
- printf("Error loading %s: %s", entry->d_name, err);
- exit(EXIT_STATUS_BADHANDLER);
+ if (user)
+ {
+ user->WriteServ("NOTICE %s :*** Failed to load core command %s: %s", entry->d_name, err);
+ }
+ else
+ {
+ printf("Error loading %s: %s", entry->d_name, err);
+ exit(EXIT_STATUS_BADHANDLER);
+ }
}
}
}
closedir(library);
- printf("\n");
+ if (!user)
+ printf("\n");
}
- this->CreateCommand(new cmd_reload(ServerInstance));
+ if (cmdlist.find("RELOAD") == cmdlist.end())
+ this->CreateCommand(new cmd_reload(ServerInstance));
}
diff --git a/src/configreader.cpp b/src/configreader.cpp
index 46bb9231e..050276525 100644
--- a/src/configreader.cpp
+++ b/src/configreader.cpp
@@ -920,6 +920,9 @@ void ServerConfig::Read(bool bail, userrec* user)
ServerInstance->Log(DEFAULT,"Successfully unloaded %lu of %lu modules and loaded %lu of %lu modules.",(unsigned long)rem,(unsigned long)removed_modules.size(),(unsigned long)add,(unsigned long)added_modules.size());
}
+ /** Note: This is safe, the method checks for user == NULL */
+ ServerInstance->Parser->SetupCommandTable(user);
+
if (user)
user->WriteServ("NOTICE %s :*** Successfully rehashed server.", user->nick);
else