diff options
-rw-r--r-- | include/ctables.h | 12 | ||||
-rw-r--r-- | include/modules.h | 2 | ||||
-rw-r--r-- | src/command_parse.cpp | 7 | ||||
-rw-r--r-- | src/modules/m_callerid.cpp | 1 | ||||
-rw-r--r-- | src/modules/m_chghost.cpp | 1 | ||||
-rw-r--r-- | src/modules/m_chgident.cpp | 1 | ||||
-rw-r--r-- | src/modules/m_chgname.cpp | 1 | ||||
-rw-r--r-- | src/modules/m_sajoin.cpp | 1 | ||||
-rw-r--r-- | src/modules/m_samode.cpp | 1 | ||||
-rw-r--r-- | src/modules/m_sanick.cpp | 1 | ||||
-rw-r--r-- | src/modules/m_sethost.cpp | 7 | ||||
-rw-r--r-- | src/modules/m_setident.cpp | 7 | ||||
-rw-r--r-- | src/modules/m_setname.cpp | 7 | ||||
-rw-r--r-- | src/modules/m_silence.cpp | 1 | ||||
-rw-r--r-- | src/modules/m_spanningtree/treesocket2.cpp | 8 |
15 files changed, 39 insertions, 19 deletions
diff --git a/include/ctables.h b/include/ctables.h index 02bea198d..f9cd08cb3 100644 --- a/include/ctables.h +++ b/include/ctables.h @@ -132,6 +132,15 @@ class CoreExport Command : public ServiceProvider */ bool works_before_reg; + /** True if the command allows an empty last parameter. + * When false and the last parameter is empty, it's popped BEFORE + * checking there are enough params, etc. (i.e. the handler won't + * be called if there aren't enough params after popping the empty + * param). + * True by default + */ + bool allow_empty_last_param; + /** Syntax string for the command, displayed if non-empty string. * This takes place of the text in the 'not enough parameters' numeric. */ @@ -155,7 +164,8 @@ class CoreExport Command : public ServiceProvider */ Command(Module* me, const std::string &cmd, int minpara = 0, int maxpara = 0) : ServiceProvider(me, cmd, SERVICE_COMMAND), flags_needed(0), min_params(minpara), max_params(maxpara), - use_count(0), total_bytes(0), disabled(false), works_before_reg(false), Penalty(1) + use_count(0), total_bytes(0), disabled(false), works_before_reg(false), allow_empty_last_param(true), + Penalty(1) { } diff --git a/include/modules.h b/include/modules.h index 9c2ca1b27..2b9237a5d 100644 --- a/include/modules.h +++ b/include/modules.h @@ -116,7 +116,7 @@ struct ModResult { * and numerical comparisons in preprocessor macros if they wish to support * multiple versions of InspIRCd in one file. */ -#define INSPIRCD_VERSION_API 2 +#define INSPIRCD_VERSION_API 3 /** * This #define allows us to call a method in all diff --git a/src/command_parse.cpp b/src/command_parse.cpp index f05ffcd90..0bf8e0e0a 100644 --- a/src/command_parse.cpp +++ b/src/command_parse.cpp @@ -148,6 +148,9 @@ CmdResult CommandParser::CallHandler(const std::string &commandname, const std:: if (n != cmdlist.end()) { + if ((!parameters.empty()) && (parameters.back().empty()) && (!n->second->allow_empty_last_param)) + return CMD_INVALID; + if (parameters.size() >= n->second->min_params) { bool bOkay = false; @@ -314,6 +317,10 @@ bool CommandParser::ProcessCommand(LocalUser *user, std::string &cmd) command.c_str(), user->nick.c_str(), user->ident.c_str(), user->host.c_str()); return do_more; } + + if ((!command_p.empty()) && (command_p.back().empty()) && (!cm->second->allow_empty_last_param)) + command_p.pop_back(); + if (command_p.size() < cm->second->min_params) { user->WriteNumeric(ERR_NEEDMOREPARAMS, "%s %s :Not enough parameters.", user->nick.c_str(), command.c_str()); diff --git a/src/modules/m_callerid.cpp b/src/modules/m_callerid.cpp index 6ed1f957a..adf66b79a 100644 --- a/src/modules/m_callerid.cpp +++ b/src/modules/m_callerid.cpp @@ -136,6 +136,7 @@ public: CommandAccept(Module* Creator) : Command(Creator, "ACCEPT", 1), extInfo(Creator) { + allow_empty_last_param = false; syntax = "{[+|-]<nicks>}|*}"; TRANSLATE2(TR_CUSTOM, TR_END); } diff --git a/src/modules/m_chghost.cpp b/src/modules/m_chghost.cpp index ac318f9af..08f7f76fa 100644 --- a/src/modules/m_chghost.cpp +++ b/src/modules/m_chghost.cpp @@ -32,6 +32,7 @@ class CommandChghost : public Command public: CommandChghost(Module* Creator, char* hmap) : Command(Creator,"CHGHOST", 2), hostmap(hmap) { + allow_empty_last_param = false; flags_needed = 'o'; syntax = "<nick> <newhost>"; TRANSLATE3(TR_NICK, TR_TEXT, TR_END); diff --git a/src/modules/m_chgident.cpp b/src/modules/m_chgident.cpp index 7dfd71c97..2112e45a3 100644 --- a/src/modules/m_chgident.cpp +++ b/src/modules/m_chgident.cpp @@ -31,6 +31,7 @@ class CommandChgident : public Command public: CommandChgident(Module* Creator) : Command(Creator,"CHGIDENT", 2) { + allow_empty_last_param = false; flags_needed = 'o'; syntax = "<nick> <newident>"; TRANSLATE3(TR_NICK, TR_TEXT, TR_END); diff --git a/src/modules/m_chgname.cpp b/src/modules/m_chgname.cpp index 3ce1da5ec..73ae3d487 100644 --- a/src/modules/m_chgname.cpp +++ b/src/modules/m_chgname.cpp @@ -29,6 +29,7 @@ class CommandChgname : public Command public: CommandChgname(Module* Creator) : Command(Creator,"CHGNAME", 2, 2) { + allow_empty_last_param = false; flags_needed = 'o'; syntax = "<nick> <newname>"; TRANSLATE3(TR_NICK, TR_TEXT, TR_END); diff --git a/src/modules/m_sajoin.cpp b/src/modules/m_sajoin.cpp index 63d51f86d..932b564fa 100644 --- a/src/modules/m_sajoin.cpp +++ b/src/modules/m_sajoin.cpp @@ -30,6 +30,7 @@ class CommandSajoin : public Command public: CommandSajoin(Module* Creator) : Command(Creator,"SAJOIN", 2) { + allow_empty_last_param = false; flags_needed = 'o'; Penalty = 0; syntax = "<nick> <channel>"; TRANSLATE3(TR_NICK, TR_TEXT, TR_END); } diff --git a/src/modules/m_samode.cpp b/src/modules/m_samode.cpp index c0cf1b93d..9b71992a6 100644 --- a/src/modules/m_samode.cpp +++ b/src/modules/m_samode.cpp @@ -32,6 +32,7 @@ class CommandSamode : public Command bool active; CommandSamode(Module* Creator) : Command(Creator,"SAMODE", 2) { + allow_empty_last_param = false; flags_needed = 'o'; Penalty = 0; syntax = "<target> <modes> {<mode-parameters>}"; active = false; } diff --git a/src/modules/m_sanick.cpp b/src/modules/m_sanick.cpp index cf093d28a..4e4be77ae 100644 --- a/src/modules/m_sanick.cpp +++ b/src/modules/m_sanick.cpp @@ -30,6 +30,7 @@ class CommandSanick : public Command public: CommandSanick(Module* Creator) : Command(Creator,"SANICK", 2) { + allow_empty_last_param = false; flags_needed = 'o'; Penalty = 0; syntax = "<nick> <new-nick>"; TRANSLATE3(TR_NICK, TR_TEXT, TR_END); } diff --git a/src/modules/m_sethost.cpp b/src/modules/m_sethost.cpp index a036085ea..2ef0c0548 100644 --- a/src/modules/m_sethost.cpp +++ b/src/modules/m_sethost.cpp @@ -32,6 +32,7 @@ class CommandSethost : public Command public: CommandSethost(Module* Creator, char* hmap) : Command(Creator,"SETHOST", 1), hostmap(hmap) { + allow_empty_last_param = false; flags_needed = 'o'; syntax = "<new-hostname>"; TRANSLATE2(TR_TEXT, TR_END); } @@ -47,11 +48,7 @@ class CommandSethost : public Command return CMD_FAILURE; } } - if (len == 0) - { - user->WriteServ("NOTICE %s :*** SETHOST: Host must be specified", user->nick.c_str()); - return CMD_FAILURE; - } + if (len > 64) { user->WriteServ("NOTICE %s :*** SETHOST: Host too long",user->nick.c_str()); diff --git a/src/modules/m_setident.cpp b/src/modules/m_setident.cpp index 534742097..f63be1381 100644 --- a/src/modules/m_setident.cpp +++ b/src/modules/m_setident.cpp @@ -31,18 +31,13 @@ class CommandSetident : public Command public: CommandSetident(Module* Creator) : Command(Creator,"SETIDENT", 1) { + allow_empty_last_param = false; flags_needed = 'o'; syntax = "<new-ident>"; TRANSLATE2(TR_TEXT, TR_END); } CmdResult Handle(const std::vector<std::string>& parameters, User *user) { - if (parameters.size() == 0) - { - user->WriteServ("NOTICE %s :*** SETIDENT: Ident must be specified", user->nick.c_str()); - return CMD_FAILURE; - } - if (parameters[0].size() > ServerInstance->Config->Limits.IdentMax) { user->WriteServ("NOTICE %s :*** SETIDENT: Ident is too long", user->nick.c_str()); diff --git a/src/modules/m_setname.cpp b/src/modules/m_setname.cpp index f89c411b4..d0610853b 100644 --- a/src/modules/m_setname.cpp +++ b/src/modules/m_setname.cpp @@ -30,18 +30,13 @@ class CommandSetname : public Command public: CommandSetname(Module* Creator) : Command(Creator,"SETNAME", 1, 1) { + allow_empty_last_param = false; syntax = "<new-gecos>"; TRANSLATE2(TR_TEXT, TR_END); } CmdResult Handle (const std::vector<std::string>& parameters, User *user) { - if (parameters[0].empty()) - { - user->WriteServ("NOTICE %s :*** SETNAME: GECOS must be specified", user->nick.c_str()); - return CMD_FAILURE; - } - if (parameters[0].size() > ServerInstance->Config->Limits.MaxGecos) { user->WriteServ("NOTICE %s :*** SETNAME: GECOS too long", user->nick.c_str()); diff --git a/src/modules/m_silence.cpp b/src/modules/m_silence.cpp index ab2134e4c..817c8ffcf 100644 --- a/src/modules/m_silence.cpp +++ b/src/modules/m_silence.cpp @@ -110,6 +110,7 @@ class CommandSilence : public Command CommandSilence(Module* Creator, unsigned int &max) : Command(Creator, "SILENCE", 0), maxsilence(max), ext("silence_list", Creator) { + allow_empty_last_param = false; syntax = "{[+|-]<mask> <p|c|i|n|t|a|x>}"; TRANSLATE3(TR_TEXT, TR_TEXT, TR_END); } diff --git a/src/modules/m_spanningtree/treesocket2.cpp b/src/modules/m_spanningtree/treesocket2.cpp index e93dece5f..9c3fe9c36 100644 --- a/src/modules/m_spanningtree/treesocket2.cpp +++ b/src/modules/m_spanningtree/treesocket2.cpp @@ -458,6 +458,14 @@ void TreeSocket::ProcessConnectedLine(std::string& prefix, std::string& command, return; } + if ((!params.empty()) && (params.back().empty()) && (!cmd->allow_empty_last_param)) + { + // the last param is empty and the command handler doesn't allow that, check if there will be enough params if we drop the last + if (params.size()-1 < cmd->min_params) + return; + params.pop_back(); + } + CmdResult res = cmd->Handle(params, who); if (res == CMD_INVALID) |