summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/ctables.h12
-rw-r--r--include/modules.h2
-rw-r--r--src/command_parse.cpp7
-rw-r--r--src/modules/m_callerid.cpp1
-rw-r--r--src/modules/m_chghost.cpp1
-rw-r--r--src/modules/m_chgident.cpp1
-rw-r--r--src/modules/m_chgname.cpp1
-rw-r--r--src/modules/m_sajoin.cpp1
-rw-r--r--src/modules/m_samode.cpp1
-rw-r--r--src/modules/m_sanick.cpp1
-rw-r--r--src/modules/m_sethost.cpp7
-rw-r--r--src/modules/m_setident.cpp7
-rw-r--r--src/modules/m_setname.cpp7
-rw-r--r--src/modules/m_silence.cpp1
-rw-r--r--src/modules/m_spanningtree/treesocket2.cpp8
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)