diff options
-rw-r--r-- | include/command_parse.h | 29 | ||||
-rw-r--r-- | include/commands/cmd_mode.h | 31 | ||||
-rw-r--r-- | include/mode.h | 14 | ||||
-rw-r--r-- | src/cmd_mode.cpp | 35 | ||||
-rw-r--r-- | src/command_parse.cpp | 65 | ||||
-rw-r--r-- | src/mode.cpp | 11 |
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('!'); |