summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/command_parse.h26
-rw-r--r--src/command_parse.cpp65
-rw-r--r--src/commands/cmd_join.cpp4
3 files changed, 14 insertions, 81 deletions
diff --git a/include/command_parse.h b/include/command_parse.h
index f374673f2..ac401ff67 100644
--- a/include/command_parse.h
+++ b/include/command_parse.h
@@ -101,33 +101,11 @@ class CoreExport CommandParser
* @param The number of items in the parameters list
* @param splithere The first parameter index to split as a comma seperated list
* @param extra The second parameter index to split as a comma seperated list
+ * @param usemax Limit the command to MaxTargets targets
* @return This function will return 1 when there are no more parameters to process. When this occurs, its
* caller should return without doing anything, otherwise it should continue into its main section of code.
*/
- int LoopCall(User* user, Command* CommandObj, const std::vector<std::string>& parameters, unsigned int splithere, unsigned int extra);
-
- /** LoopCall is used to call a command classes handler repeatedly based on the contents of a comma seperated list.
- * There are two overriden versions of this method, one of which takes two potential lists and the other takes one.
- * We need a version which takes two potential lists for JOIN, because a JOIN may contain two lists of items at once,
- * the channel names and their keys as follows:
- *
- * JOIN #chan1,#chan2,#chan3 key1,,key3
- *
- * Therefore, we need to deal with both lists concurrently. The first instance of this method does that by creating
- * two instances of irc::commasepstream and reading them both together until the first runs out of tokens.
- * The second version is much simpler and just has the one stream to read, and is used in NAMES, WHOIS, PRIVMSG etc.
- * Both will only parse until they reach ServerInstance->Config->MaxTargets number of targets, to stop abuse via spam.
- *
- * @param user The user who sent the command
- * @param CommandObj the command object to call for each parameter in the list
- * @param parameters Parameter list as an array of array of char (that's not a typo).
- * @param The number of items in the parameters list
- * @param splithere The first parameter index to split as a comma seperated list
- * @param extra The second parameter index to split as a comma seperated list
- * @return This function will return 1 when there are no more parameters to process. When this occurs, its
- * caller should return without doing anything, otherwise it should continue into its main section of code.
- */
- int LoopCall(User* user, Command* CommandObj, const std::vector<std::string>& parameters, unsigned int splithere);
+ int LoopCall(User* user, Command* CommandObj, const std::vector<std::string>& parameters, unsigned int splithere, unsigned int extra = -1, bool usemax = true);
/** Take a raw input buffer from a recvq, and process it on behalf of a user.
* @param buffer The buffer line to process
diff --git a/src/command_parse.cpp b/src/command_parse.cpp
index 679f4e9ae..216981773 100644
--- a/src/command_parse.cpp
+++ b/src/command_parse.cpp
@@ -55,11 +55,14 @@ int InspIRCd::PassCompare(Extensible* ex, const std::string &data, const std::st
* The second version is much simpler and just has the one stream to read, and is used in NAMES, WHOIS, PRIVMSG etc.
* Both will only parse until they reach ServerInstance->Config->MaxTargets number of targets, to stop abuse via spam.
*/
-int CommandParser::LoopCall(User* user, Command* CommandObj, const std::vector<std::string>& parameters, unsigned int splithere, unsigned int extra)
+int CommandParser::LoopCall(User* user, Command* CommandObj, const std::vector<std::string>& parameters, unsigned int splithere, unsigned int extra, bool usemax)
{
if (splithere >= parameters.size())
return 0;
+ if (extra >= parameters.size())
+ extra = -1;
+
/* First check if we have more than one item in the list, if we don't we return zero here and the handler
* which called us just carries on as it was.
*/
@@ -75,7 +78,7 @@ int CommandParser::LoopCall(User* user, Command* CommandObj, const std::vector<s
/* Create two lists, one for channel names, one for keys
*/
irc::commasepstream items1(parameters[splithere]);
- irc::commasepstream items2(parameters[extra]);
+ irc::commasepstream items2(extra >= 0 ? parameters[extra] : "");
std::string extrastuff;
std::string item;
unsigned int max = 0;
@@ -84,72 +87,24 @@ int CommandParser::LoopCall(User* user, Command* CommandObj, const std::vector<s
* which called us, for every parameter pair until there are
* no more left to parse.
*/
- while (items1.GetToken(item) && (max++ < ServerInstance->Config->MaxTargets))
+ while (items1.GetToken(item) && (!usemax || max++ < ServerInstance->Config->MaxTargets))
{
if (dupes.find(item.c_str()) == dupes.end())
{
- std::vector<std::string> new_parameters;
-
- for (unsigned int t = 0; (t < parameters.size()) && (t < MAXPARAMETERS); t++)
- new_parameters.push_back(parameters[t]);
+ std::vector<std::string> new_parameters(parameters);
if (!items2.GetToken(extrastuff))
extrastuff = "";
- new_parameters[splithere] = item.c_str();
- new_parameters[extra] = extrastuff.c_str();
-
- CommandObj->Handle(new_parameters, user);
-
- dupes.insert(item.c_str());
- }
- }
- return 1;
-}
-
-int CommandParser::LoopCall(User* user, Command* CommandObj, const std::vector<std::string>& parameters, unsigned int splithere)
-{
- if (splithere >= parameters.size())
- return 0;
-
- /* First check if we have more than one item in the list, if we don't we return zero here and the handler
- * which called us just carries on as it was.
- */
- if (parameters[splithere].find(',') == std::string::npos)
- return 0;
-
- std::set<irc::string> dupes;
-
- /* Only one commasepstream here */
- irc::commasepstream items1(parameters[splithere]);
- std::string item;
- unsigned int max = 0;
+ new_parameters[splithere] = item;
+ if (extra >= 0)
+ new_parameters[extra] = extrastuff;
- /* Parse the commasepstream until there are no tokens remaining.
- * Each token we parse out, call the command handler that called us
- * with it
- */
- while (items1.GetToken(item) && (max++ < ServerInstance->Config->MaxTargets))
- {
- if (dupes.find(item.c_str()) == dupes.end())
- {
- std::vector<std::string> new_parameters;
-
- for (unsigned int t = 0; (t < parameters.size()) && (t < MAXPARAMETERS); t++)
- new_parameters.push_back(parameters[t]);
-
- new_parameters[splithere] = item.c_str();
-
- /* Execute the command handler. */
CommandObj->Handle(new_parameters, user);
dupes.insert(item.c_str());
}
}
- /* By returning 1 we tell our caller that nothing is to be done,
- * as all the previous calls handled the data. This makes the parent
- * return without doing any processing.
- */
return 1;
}
diff --git a/src/commands/cmd_join.cpp b/src/commands/cmd_join.cpp
index f3a97d31a..17a71688a 100644
--- a/src/commands/cmd_join.cpp
+++ b/src/commands/cmd_join.cpp
@@ -50,7 +50,7 @@ CmdResult CommandJoin::Handle (const std::vector<std::string>& parameters, User
{
if (parameters.size() > 1)
{
- if (ServerInstance->Parser->LoopCall(user, this, parameters, 0, 1))
+ if (ServerInstance->Parser->LoopCall(user, this, parameters, 0, 1, false))
return CMD_SUCCESS;
if (ServerInstance->IsChannel(parameters[0].c_str(), ServerInstance->Config->Limits.ChanMax))
@@ -61,7 +61,7 @@ CmdResult CommandJoin::Handle (const std::vector<std::string>& parameters, User
}
else
{
- if (ServerInstance->Parser->LoopCall(user, this, parameters, 0))
+ if (ServerInstance->Parser->LoopCall(user, this, parameters, 0, -1, false))
return CMD_SUCCESS;
if (ServerInstance->IsChannel(parameters[0].c_str(), ServerInstance->Config->Limits.ChanMax))