summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/command_parse.h29
-rw-r--r--include/commands/cmd_mode.h31
-rw-r--r--include/mode.h14
-rw-r--r--src/cmd_mode.cpp35
-rw-r--r--src/command_parse.cpp65
-rw-r--r--src/mode.cpp11
6 files changed, 156 insertions, 29 deletions
diff --git a/include/command_parse.h b/include/command_parse.h
index d4c64dab4..a9c1e26c8 100644
--- a/include/command_parse.h
+++ b/include/command_parse.h
@@ -24,6 +24,8 @@
class InspIRCd;
+typedef std::map<std::string, void*> SharedObjectList;
+
/** This class handles command management and parsing.
* It allows you to add and remove commands from the map,
* call command handlers by name, and chop up comma seperated
@@ -55,12 +57,16 @@ class CommandParser : public classbase
void FindSym(void** v, void* h);
+ SharedObjectList RFCCommands;
+
+ void LoadCommand(const char* name);
+
public:
/** Command list, a hash_map of command names to command_t*
*/
command_table cmdlist;
- void LoadCommand(const char* name);
+ bool ReloadCommand(const char* cmd);
/** Default constructor.
* @param Instance The creator of this class
@@ -146,9 +152,28 @@ class CommandParser : public classbase
/** Add a new command to the commands hash
* @param f The new command_t to add to the list
+ * @param so_handle The handle to the shared object where the command can be found.
+ * Only core commands loaded via cmd_*.so files should set this parameter to anything
+ * meaningful. Module authors should leave this parameter at its default of NULL.
* @return True if the command was added
*/
- bool CreateCommand(command_t *f);
+ bool CreateCommand(command_t *f, void* so_handle = NULL);
+};
+
+/** Command handler class for the RELOAD command.
+ * A command cant really reload itself, so this has to be in here.
+ */
+class cmd_reload : public command_t
+{
+ public:
+ /** Standard constructor
+ */
+ cmd_reload (InspIRCd* Instance) : command_t(Instance,"RELOAD",'o',1) { syntax = "<core-command>"; }
+ /** Handle RELOAD
+ */
+ void Handle(const char** parameters, int pcnt, userrec *user);
};
+
+
#endif
diff --git a/include/commands/cmd_mode.h b/include/commands/cmd_mode.h
new file mode 100644
index 000000000..e52042f6a
--- /dev/null
+++ b/include/commands/cmd_mode.h
@@ -0,0 +1,31 @@
+/* +------------------------------------+
+ * | Inspire Internet Relay Chat Daemon |
+ * +------------------------------------+
+ *
+ * InspIRCd is copyright (C) 2002-2006 ChatSpike-Dev.
+ * E-mail:
+ * <brain@chatspike.net>
+ * <Craig@chatspike.net>
+ *
+ * Written by Craig Edwards, Craig McLure, and others.
+ * This program is free but copyrighted software; see
+ * the file COPYING for details.
+ *
+ * ---------------------------------------------------
+ */
+
+#ifndef __CMD_ADMIN_H__
+#define __CMD_ADMIN_H__
+
+#include "users.h"
+#include "channels.h"
+#include "ctables.h"
+
+class cmd_mode : public command_t
+{
+ public:
+ cmd_mode (InspIRCd* Instance) : command_t(Instance,"MODE",0,1) { syntax = "<target> <modes> {<mode-parameters>}"; }
+ void Handle(const char** parameters, int pcnt, userrec *user);
+};
+
+#endif
diff --git a/include/mode.h b/include/mode.h
index 27cdd890f..fe646c9b3 100644
--- a/include/mode.h
+++ b/include/mode.h
@@ -483,18 +483,4 @@ class ModeParser : public classbase
std::string ModeString(userrec* user, chanrec* channel);
};
-/** Command handler class for the MODE command.
- * put here for completeness.
- */
-class cmd_mode : public command_t
-{
- public:
- /** Standard constructor
- */
- cmd_mode (InspIRCd* Instance) : command_t(Instance,"MODE",0,1) { syntax = "<target> <modes> {<mode-parameters>}"; }
- /** Handle MODE
- */
- void Handle(const char** parameters, int pcnt, userrec *user);
-};
-
#endif
diff --git a/src/cmd_mode.cpp b/src/cmd_mode.cpp
new file mode 100644
index 000000000..c1d128bf9
--- /dev/null
+++ b/src/cmd_mode.cpp
@@ -0,0 +1,35 @@
+/* +------------------------------------+
+ * | Inspire Internet Relay Chat Daemon |
+ * +------------------------------------+
+ *
+ * InspIRCd is copyright (C) 2002-2006 ChatSpike-Dev.
+ * E-mail:
+ * <brain@chatspike.net>
+ * <Craig@chatspike.net>
+ *
+ * Written by Craig Edwards, Craig McLure, and others.
+ * This program is free but copyrighted software; see
+ * the file COPYING for details.
+ *
+ * ---------------------------------------------------
+ */
+
+#include "configreader.h"
+#include "users.h"
+#include "commands/cmd_mode.h"
+
+extern "C" command_t* init_command(InspIRCd* Instance)
+{
+ return new cmd_mode(Instance);
+}
+
+void cmd_mode::Handle (const char** parameters, int pcnt, userrec *user)
+{
+ if (!user)
+ return;
+
+ ServerInstance->Modes->Process(parameters, pcnt, user, false);
+
+ return;
+}
+
diff --git a/src/command_parse.cpp b/src/command_parse.cpp
index 13ba64169..600ce2e61 100644
--- a/src/command_parse.cpp
+++ b/src/command_parse.cpp
@@ -444,8 +444,22 @@ void CommandParser::ProcessBuffer(std::string &buffer,userrec *user)
}
}
-bool CommandParser::CreateCommand(command_t *f)
+bool CommandParser::CreateCommand(command_t *f, void* so_handle)
{
+ if (so_handle)
+ {
+ if (RFCCommands.find(f->command) == RFCCommands.end())
+ {
+ RFCCommands[f->command] = so_handle;
+ ServerInstance->Log(DEFAULT,"Monitoring RFC-specified reloadable command at %8x",so_handle);
+ }
+ else
+ {
+ ServerInstance->Log(DEFAULT,"ERK! Somehow, we loaded a cmd_*.so file twice! Only the first instance is being recorded.");
+ return false;
+ }
+ }
+
/* create the command and push it onto the table */
if (cmdlist.find(f->command) == cmdlist.end())
{
@@ -472,6 +486,49 @@ void CommandParser::FindSym(void** v, void* h)
}
}
+bool CommandParser::ReloadCommand(const char* cmd)
+{
+ char filename[MAXBUF];
+ char commandname[MAXBUF];
+ int y = 0;
+
+ for (const char* x = cmd; *x; x++, y++)
+ commandname[y] = toupper(*x);
+
+ commandname[y] = 0;
+
+ SharedObjectList::iterator command = RFCCommands.find(commandname);
+
+ if (command != RFCCommands.end())
+ {
+ command_t* cmdptr = cmdlist.find(commandname)->second;
+ cmdlist.erase(cmdlist.find(commandname));
+
+ for (char* x = commandname; *x; x++)
+ *x = tolower(*x);
+
+
+ delete cmdptr;
+ dlclose(command->second);
+
+ sprintf(filename, "cmd_%s.so", commandname);
+ this->LoadCommand(filename);
+
+ return true;
+ }
+
+ return false;
+}
+
+void cmd_reload::Handle(const char** parameters, int pcnt, userrec *user)
+{
+ user->WriteServ("NOTICE %s :*** Reloading command '%s'",user->nick, parameters[0]);
+ if (ServerInstance->Parser->ReloadCommand(parameters[0]))
+ user->WriteServ("NOTICE %s :*** Successfully reloaded command '%s'", user->nick, parameters[0]);
+ else
+ user->WriteServ("NOTICE %s :*** Could not reload command '%s'", user->nick, parameters[0]);
+}
+
void CommandParser::LoadCommand(const char* name)
{
char filename[MAXBUF];
@@ -490,11 +547,13 @@ void CommandParser::LoadCommand(const char* name)
command_t* newcommand = cmd_factory_func(ServerInstance);
- this->CreateCommand(newcommand);
+ this->CreateCommand(newcommand, h);
}
void CommandParser::SetupCommandTable()
{
+ RFCCommands.clear();
+
DIR* library = opendir(LIBRARYDIR);
if (library)
{
@@ -508,5 +567,7 @@ void CommandParser::SetupCommandTable()
}
closedir(library);
}
+
+ this->CreateCommand(new cmd_reload(ServerInstance));
}
diff --git a/src/mode.cpp b/src/mode.cpp
index 5da96249f..3bdcb1a30 100644
--- a/src/mode.cpp
+++ b/src/mode.cpp
@@ -515,17 +515,6 @@ void ModeParser::Process(const char** parameters, int pcnt, userrec *user, bool
}
}
-
-void cmd_mode::Handle (const char** parameters, int pcnt, userrec *user)
-{
- if (!user)
- return;
-
- ServerInstance->Modes->Process(parameters, pcnt, user, false);
-
- return;
-}
-
void ModeParser::CleanMask(std::string &mask)
{
std::string::size_type pos_of_pling = mask.find_first_of('!');