diff options
author | brain <brain@e03df62e-2008-0410-955e-edbf42e46eb7> | 2006-07-16 13:02:38 +0000 |
---|---|---|
committer | brain <brain@e03df62e-2008-0410-955e-edbf42e46eb7> | 2006-07-16 13:02:38 +0000 |
commit | 5d18f26b6bfb7a575b50dc2e3ad909131b9f75da (patch) | |
tree | 661cc9bedf6c71c6e232d1cb6e18a4a43bfbc606 | |
parent | 0757a4a495daabf661ac3b7ab79f0a5ee423abe8 (diff) |
Fix case sensitive commands issue due to new std::string based parser, improve the craq disabled commands check that was potentially O(n) where n is the number of disabled commands (erk)
git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@4404 e03df62e-2008-0410-955e-edbf42e46eb7
-rw-r--r-- | include/configreader.h | 2 | ||||
-rw-r--r-- | include/ctables.h | 15 | ||||
-rw-r--r-- | src/command_parse.cpp | 57 | ||||
-rw-r--r-- | src/configreader.cpp | 22 | ||||
-rw-r--r-- | src/inspircd.cpp | 3 |
5 files changed, 59 insertions, 40 deletions
diff --git a/include/configreader.h b/include/configreader.h index b37838cf1..c6775bc29 100644 --- a/include/configreader.h +++ b/include/configreader.h @@ -394,4 +394,6 @@ class ServerConfig : public Extensible bool DelIOHook(int port); }; +bool InitializeDisabledCommands(const char* data, InspIRCd* ServerInstance); + #endif diff --git a/include/ctables.h b/include/ctables.h index e6ae76015..828fafd00 100644 --- a/include/ctables.h +++ b/include/ctables.h @@ -48,8 +48,11 @@ class command_t : public Extensible /** used for resource tracking between modules */ std::string source; + /** True if the command is disabled to non-opers + */ + bool disabled; - command_t(const std::string &cmd, char flags, int minpara) : command(cmd), flags_needed(flags), min_params(minpara) + command_t(const std::string &cmd, char flags, int minpara) : command(cmd), flags_needed(flags), min_params(minpara), disabled(false) { use_count = total_bytes = 0; source = "<core>"; @@ -57,6 +60,16 @@ class command_t : public Extensible virtual void Handle(const char** parameters, int pcnt, userrec* user) = 0; + void Disable(bool setting) + { + disabled = setting; + } + + bool IsDisabled() + { + return disabled; + } + virtual ~command_t() {} }; diff --git a/src/command_parse.cpp b/src/command_parse.cpp index f27467f34..9170e3941 100644 --- a/src/command_parse.cpp +++ b/src/command_parse.cpp @@ -351,18 +351,21 @@ void CommandParser::ProcessCommand(userrec *user, std::string &cmd) int items = 0; std::string para[127]; irc::tokenstream tokens(cmd); - std::string xcommand = tokens.GetToken(); + std::string command = tokens.GetToken(); while (((para[items] = tokens.GetToken()) != "") && (items < 127)) command_p[items] = para[items++].c_str(); + + for (std::string::iterator makeupper = command.begin(); makeupper != command.end(); makeupper++) + *makeupper = toupper(*makeupper); int MOD_RESULT = 0; - FOREACH_RESULT(I_OnPreCommand,OnPreCommand(xcommand,command_p,items,user,false)); + FOREACH_RESULT(I_OnPreCommand,OnPreCommand(command,command_p,items,user,false)); if (MOD_RESULT == 1) { return; } - nspace::hash_map<std::string,command_t*>::iterator cm = cmdlist.find(xcommand); + nspace::hash_map<std::string,command_t*>::iterator cm = cmdlist.find(command); if (cm != cmdlist.end()) { @@ -372,52 +375,30 @@ void CommandParser::ProcessCommand(userrec *user, std::string &cmd) user->nping = TIME + user->pingmax; if (items < cm->second->min_params) { - log(DEBUG,"not enough parameters: %s %s",user->nick,xcommand.c_str()); - WriteServ(user->fd,"461 %s %s :Not enough parameters",user->nick,xcommand.c_str()); + log(DEBUG,"not enough parameters: %s %s",user->nick,command.c_str()); + WriteServ(user->fd,"461 %s %s :Not enough parameters",user->nick,command.c_str()); return; } if (cm->second->flags_needed) { if (!user->IsModeSet(cm->second->flags_needed)) { - log(DEBUG,"permission denied: %s %s",user->nick,xcommand.c_str()); + log(DEBUG,"permission denied: %s %s",user->nick,command.c_str()); WriteServ(user->fd,"481 %s :Permission Denied- You do not have the required operator privilages",user->nick); return; } } - if ((cm->second->flags_needed) && (!user->HasPermission(xcommand))) + if ((cm->second->flags_needed) && (!user->HasPermission(command))) { - log(DEBUG,"permission denied: %s %s",user->nick,xcommand.c_str()); - WriteServ(user->fd,"481 %s :Permission Denied- Oper type %s does not have access to command %s",user->nick,user->oper,xcommand.c_str()); + log(DEBUG,"permission denied: %s %s",user->nick,command.c_str()); + WriteServ(user->fd,"481 %s :Permission Denied- Oper type %s does not have access to command %s",user->nick,user->oper,command.c_str()); return; } - /* if the command isnt USER, PASS, or NICK, and nick is empty, - * deny command! */ - if ((cm->second != command_user) && (cm->second != command_nick) && (cm->second != command_pass)) - { - if ((!isnick(user->nick)) || (user->registered != 7)) - { - log(DEBUG,"not registered: %s %s",user->nick,xcommand.c_str()); - WriteServ(user->fd,"451 %s :You have not registered",xcommand.c_str()); - return; - } - } - if ((user->registered == 7) && (!*user->oper) && (*Config->DisabledCommands)) + if ((user->registered == 7) && (!*user->oper) && (cm->second->IsDisabled())) { - /* XXX: We should have a disabled setting in the command object, and on rehash set the disabled flag - * in the ones which are disabled, rather than this craq - */ - std::stringstream dcmds(Config->DisabledCommands); - std::string thiscmd; - while (dcmds >> thiscmd) - { - if (!strcasecmp(thiscmd.c_str(),xcommand.c_str())) - { - // command is disabled! - WriteServ(user->fd,"421 %s %s :This command has been disabled.",user->nick,xcommand.c_str()); - return; - } - } + /* command is disabled! */ + WriteServ(user->fd,"421 %s %s :This command has been disabled.",user->nick,command.c_str()); + return; } if ((user->registered == 7) || (cm->second == command_user) || (cm->second == command_nick) || (cm->second == command_pass)) { @@ -426,7 +407,7 @@ void CommandParser::ProcessCommand(userrec *user, std::string &cmd) cm->second->total_bytes += cmd.length(); int MOD_RESULT = 0; - FOREACH_RESULT(I_OnPreCommand,OnPreCommand(xcommand,command_p,items,user,true)); + FOREACH_RESULT(I_OnPreCommand,OnPreCommand(command,command_p,items,user,true)); if (MOD_RESULT == 1) return; @@ -441,7 +422,7 @@ void CommandParser::ProcessCommand(userrec *user, std::string &cmd) } else { - WriteServ(user->fd,"451 %s :You have not registered",xcommand.c_str()); + WriteServ(user->fd,"451 %s :You have not registered",command.c_str()); return; } } @@ -449,7 +430,7 @@ void CommandParser::ProcessCommand(userrec *user, std::string &cmd) else if (user) { ServerInstance->stats->statsUnknown++; - WriteServ(user->fd,"421 %s %s :Unknown command",user->nick,xcommand.c_str()); + WriteServ(user->fd,"421 %s %s :Unknown command",user->nick,command.c_str()); } } diff --git a/src/configreader.cpp b/src/configreader.cpp index 04918e7cf..b5ea8a815 100644 --- a/src/configreader.cpp +++ b/src/configreader.cpp @@ -200,6 +200,28 @@ bool ValidateDnsTimeout(const char* tag, const char* value, void* data) return true; } +bool InitializeDisabledCommands(const char* data, InspIRCd* ServerInstance) +{ + std::stringstream dcmds(data); + std::string thiscmd; + + /* Enable everything first */ + for (nspace::hash_map<std::string,command_t*>::iterator x = ServerInstance->Parser->cmdlist.begin(); x != ServerInstance->Parser->cmdlist.end(); x++) + x->second->Disable(false); + + /* Now disable all the ones which the user wants disabled */ + while (dcmds >> thiscmd) + { + nspace::hash_map<std::string,command_t*>::iterator cm = ServerInstance->Parser->cmdlist.find(thiscmd); + if (cm != ServerInstance->Parser->cmdlist.end()) + { + log(DEBUG,"Disabling command '%s'",cm->second->command.c_str()); + cm->second->Disable(true); + } + } + return true; +} + bool ValidateDnsServer(const char* tag, const char* value, void* data) { char* x = (char*)data; diff --git a/src/inspircd.cpp b/src/inspircd.cpp index 4333511bf..a6106a787 100644 --- a/src/inspircd.cpp +++ b/src/inspircd.cpp @@ -294,13 +294,14 @@ InspIRCd::InspIRCd(int argc, char** argv) OpenLog(argv, argc); this->stats = new serverstats(); + this->Parser = new CommandParser(); Config->ClearStack(); Config->Read(true,NULL); CheckRoot(); this->ModeGrok = new ModeParser(); - this->Parser = new CommandParser(); AddServerName(Config->ServerName); CheckDie(); + InitializeDisabledCommands(Config->DisabledCommands, this); stats->BoundPortCount = BindPorts(true); for(int t = 0; t < 255; t++) |