#include "wildcard.h"
#include "xline.h"
#include "socketengine.h"
-#include "userprocess.h"
#include "socket.h"
#include "command_parse.h"
if (!strchr(parameters[splithere],','))
return 0;
+ /** Some lame ircds will weed out dupes using some shitty O(n^2) algorithm.
+ * By using std::map (thanks for the idea w00t) we can cut this down a ton.
+ * ...VOOODOOOO!
+ */
+ std::map<irc::string, bool> dupes;
+
/* Create two lists, one for channel names, one for keys
*/
irc::commasepstream items1(parameters[splithere]);
irc::commasepstream items2(parameters[extra]);
- std::string item = "";
+ std::string item = "*";
unsigned int max = 0;
/* Attempt to iterate these lists and call the command objech
*/
while (((item = items1.GetToken()) != "") && (max++ < ServerInstance->Config->MaxTargets))
{
- std::string extrastuff = items2.GetToken();
- parameters[splithere] = item.c_str();
- parameters[extra] = extrastuff.c_str();
- CommandObj->Handle(parameters,pcnt,user);
+ if (dupes.find(item.c_str()) == dupes.end())
+ {
+ const char* new_parameters[127];
+
+ for (int t = 0; (t < pcnt) && (t < 127); t++)
+ new_parameters[t] = parameters[t];
+
+ std::string extrastuff = items2.GetToken();
+
+ new_parameters[splithere] = item.c_str();
+ new_parameters[extra] = extrastuff.c_str();
+
+ if (CommandObj->Handle(new_parameters,pcnt,user) == CMD_USER_DELETED)
+ return 1;
+
+ dupes[item.c_str()] = true;
+ }
}
return 1;
}
if (!strchr(parameters[splithere],','))
return 0;
+ std::map<irc::string, bool> dupes;
+
/* Only one commasepstream here */
+ ServerInstance->Log(DEBUG,"Splitting '%s'",parameters[splithere]);
irc::commasepstream items1(parameters[splithere]);
- std::string item = "";
+ std::string item = "*";
unsigned int max = 0;
/* Parse the commasepstream until there are no tokens remaining.
*/
while (((item = items1.GetToken()) != "") && (max++ < ServerInstance->Config->MaxTargets))
{
- parameters[splithere] = item.c_str();
- CommandObj->Handle(parameters,pcnt,user);
+ if (dupes.find(item.c_str()) == dupes.end())
+ {
+ const char* new_parameters[127];
+
+ for (int t = 0; (t < pcnt) && (t < 127); t++)
+ new_parameters[t] = parameters[t];
+
+ new_parameters[splithere] = item.c_str();
+
+ parameters[splithere] = item.c_str();
+
+ /* Execute the command handler over and over. If someone pulls our user
+ * record out from under us (e.g. if we /kill a comma sep list, and we're
+ * in that list ourselves) abort if we're gone.
+ */
+ if (CommandObj->Handle(new_parameters,pcnt,user) == CMD_USER_DELETED)
+ return 1;
+
+ dupes[item.c_str()] = true;
+ }
}
/* 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 false;
}
+command_t* CommandParser::GetHandler(const std::string &commandname)
+{
+ nspace::hash_map<std::string,command_t*>::iterator n = cmdlist.find(commandname);
+ if (n != cmdlist.end())
+ return n->second;
+
+ return NULL;
+}
+
// calls a handler function for a command
CmdResult CommandParser::CallHandler(const std::string &commandname,const char** parameters, int pcnt, userrec *user)
{
if (!user->IsModeSet(cm->second->flags_needed))
{
- user->WriteServ("481 %s :Permission Denied- You do not have the required operator privilages",user->nick);
+ user->WriteServ("481 %s :Permission Denied- You do not have the required operator privileges",user->nick);
return;
}
if (!user->HasPermission(command))
dlclose(command->second);
RFCCommands.erase(command);
- sprintf(filename, "cmd_%s.so", commandname);
+ snprintf(filename, MAXBUF, "cmd_%s.so", commandname);
this->LoadCommand(filename);
return true;