X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fcommand_parse.cpp;h=f4d8f377c57827729814e8739d8636900db427d2;hb=e2b0f3dc9ef4d56c71d7abda13e6139ca092e387;hp=503630d537eaa5f0b409fcd73c76922237a94587;hpb=58a0a7e01422e62de1565a8eb0a1febdc463d04d;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/command_parse.cpp b/src/command_parse.cpp index 503630d53..f4d8f377c 100644 --- a/src/command_parse.cpp +++ b/src/command_parse.cpp @@ -1,11 +1,13 @@ /* * InspIRCd -- Internet Relay Chat Daemon * + * Copyright (C) 2014, 2018-2020 Sadie Powell + * Copyright (C) 2012-2016, 2018 Attila Molnar + * Copyright (C) 2012 Robby * Copyright (C) 2009-2010 Daniel De Graaf - * Copyright (C) 2006-2008 Robin Burchell - * Copyright (C) 2008 Thomas Stagner - * Copyright (C) 2005-2008 Craig Edwards - * Copyright (C) 2006-2007 Dennis Friis + * Copyright (C) 2007-2009 Robin Burchell + * Copyright (C) 2007 Dennis Friis + * Copyright (C) 2005-2008, 2010 Craig Edwards * * This file is part of InspIRCd. InspIRCd is free software: you can * redistribute it and/or modify it under the terms of the GNU General Public @@ -37,7 +39,7 @@ bool InspIRCd::PassCompare(Extensible* ex, const std::string& data, const std::s return false; /* We dont handle any hash types except for plaintext - Thanks tra26 */ - if (!hashtype.empty() && hashtype != "plaintext") + if (!hashtype.empty() && !stdalgo::string::equalsci(hashtype, "plaintext")) return false; return TimingSafeCompare(data, input); @@ -78,29 +80,28 @@ bool CommandParser::LoopCall(User* user, Command* handler, const CommandBase::Pa * for every parameter or parameter pair until there are no more * left to parse. */ + CommandBase::Params splitparams(parameters); while (items1.GetToken(item) && (!usemax || max++ < ServerInstance->Config->MaxTargets)) { if ((!check_dupes) || (dupes.insert(item).second)) { - CommandBase::Params new_parameters(parameters); - new_parameters[splithere] = item; + splitparams[splithere] = item; if (extra >= 0) { // If we have two lists then get the next item from the second list. // In case it runs out of elements then 'item' will be an empty string. items2.GetToken(item); - new_parameters[extra] = item; + splitparams[extra] = item; } - CommandBase::Params params(new_parameters, parameters.GetTags()); - CmdResult result = handler->Handle(user, params); + CmdResult result = handler->Handle(user, splitparams); if (localuser) { - // Run the OnPostCommand hook with the last parameter (original line) being empty - // to indicate that the command had more targets in its original form. + // Run the OnPostCommand hook with the last parameter being true to indicate + // that the event is being called in a loop. item.clear(); - FOREACH_MOD(OnPostCommand, (handler, new_parameters, localuser, result)); + FOREACH_MOD(OnPostCommand, (handler, splitparams, localuser, result, true)); } } } @@ -139,7 +140,7 @@ CmdResult CommandParser::CallHandler(const std::string& commandname, const Comma if (user->IsModeSet(n->second->flags_needed)) { /* if user has the flags, and now has the permissions, go ahead */ - if (user->HasPermission(commandname)) + if (user->HasCommandPermission(commandname)) bOkay = true; } } @@ -189,7 +190,10 @@ void CommandParser::ProcessCommand(LocalUser* user, std::string& command, Comman ModResult MOD_RESULT; FIRST_MOD_RESULT(OnPreCommand, MOD_RESULT, (command, command_p, user, false)); if (MOD_RESULT == MOD_RES_DENY) + { + FOREACH_MOD(OnCommandBlocked, (command, command_p, user)); return; + } /* * This double lookup is in case a module (abbreviation) wishes to change a command. @@ -203,7 +207,9 @@ void CommandParser::ProcessCommand(LocalUser* user, std::string& command, Comman { if (user->registered == REG_ALL) user->WriteNumeric(ERR_UNKNOWNCOMMAND, command, "Unknown command"); + ServerInstance->stats.Unknown++; + FOREACH_MOD(OnCommandBlocked, (command, command_p, user)); return; } } @@ -225,7 +231,7 @@ void CommandParser::ProcessCommand(LocalUser* user, std::string& command, Comman // Iterator to the first excess parameter const CommandBase::Params::iterator firstexcess = lastkeep + 1; - // Append all excess parameter(s) to the last parameter, seperated by spaces + // Append all excess parameter(s) to the last parameter, separated by spaces for (CommandBase::Params::const_iterator i = firstexcess; i != command_p.end(); ++i) { lastkeep->push_back(' '); @@ -237,16 +243,19 @@ void CommandParser::ProcessCommand(LocalUser* user, std::string& command, Comman } /* - * We call OnPreCommand here seperately if the command exists, so the magic above can + * We call OnPreCommand here separately if the command exists, so the magic above can * truncate to max_params if necessary. -- w00t */ ModResult MOD_RESULT; FIRST_MOD_RESULT(OnPreCommand, MOD_RESULT, (command, command_p, user, false)); if (MOD_RESULT == MOD_RES_DENY) + { + FOREACH_MOD(OnCommandBlocked, (command, command_p, user)); return; + } /* activity resets the ping pending timer */ - user->nping = ServerInstance->Time() + user->MyClass->GetPingTime(); + user->nextping = ServerInstance->Time() + user->MyClass->GetPingTime(); if (handler->flags_needed) { @@ -254,52 +263,36 @@ void CommandParser::ProcessCommand(LocalUser* user, std::string& command, Comman { user->CommandFloodPenalty += failpenalty; user->WriteNumeric(ERR_NOPRIVILEGES, "Permission Denied - You do not have the required operator privileges"); + FOREACH_MOD(OnCommandBlocked, (command, command_p, user)); return; } - if (!user->HasPermission(command)) + if (!user->HasCommandPermission(command)) { user->CommandFloodPenalty += failpenalty; user->WriteNumeric(ERR_NOPRIVILEGES, InspIRCd::Format("Permission Denied - Oper type %s does not have access to command %s", user->oper->name.c_str(), command.c_str())); + FOREACH_MOD(OnCommandBlocked, (command, command_p, user)); return; } } - if ((user->registered == REG_ALL) && (!user->IsOper()) && (handler->IsDisabled())) - { - /* command is disabled! */ - user->CommandFloodPenalty += failpenalty; - if (ServerInstance->Config->DisabledDontExist) - { - user->WriteNumeric(ERR_UNKNOWNCOMMAND, command, "Unknown command"); - } - else - { - user->WriteNumeric(ERR_UNKNOWNCOMMAND, command, "This command has been disabled."); - } - - ServerInstance->SNO->WriteToSnoMask('a', "%s denied for %s (%s@%s)", - command.c_str(), user->nick.c_str(), user->ident.c_str(), user->GetRealHost().c_str()); - return; - } - if ((!command_p.empty()) && (command_p.back().empty()) && (!handler->allow_empty_last_param)) command_p.pop_back(); if (command_p.size() < handler->min_params) { user->CommandFloodPenalty += failpenalty; - user->WriteNumeric(ERR_NEEDMOREPARAMS, command, "Not enough parameters."); - if ((ServerInstance->Config->SyntaxHints) && (user->registered == REG_ALL) && (handler->syntax.length())) - user->WriteNumeric(RPL_SYNTAX, handler->name, handler->syntax); + handler->TellNotEnoughParameters(user, command_p); + FOREACH_MOD(OnCommandBlocked, (command, command_p, user)); return; } - if ((user->registered != REG_ALL) && (!handler->WorksBeforeReg())) + if ((user->registered != REG_ALL) && (!handler->works_before_reg)) { user->CommandFloodPenalty += failpenalty; - user->WriteNumeric(ERR_NOTREGISTERED, command, "You have not registered"); + handler->TellNotRegistered(user, command_p); + FOREACH_MOD(OnCommandBlocked, (command, command_p, user)); } else { @@ -309,14 +302,17 @@ void CommandParser::ProcessCommand(LocalUser* user, std::string& command, Comman /* module calls too */ FIRST_MOD_RESULT(OnPreCommand, MOD_RESULT, (command, command_p, user, true)); if (MOD_RESULT == MOD_RES_DENY) + { + FOREACH_MOD(OnCommandBlocked, (command, command_p, user)); return; + } /* * WARNING: be careful, the user may be deleted soon */ CmdResult result = handler->Handle(user, command_p); - FOREACH_MOD(OnPostCommand, (handler, command_p, user, result)); + FOREACH_MOD(OnPostCommand, (handler, command_p, user, result, false)); } } @@ -327,49 +323,6 @@ void CommandParser::RemoveCommand(Command* x) cmdlist.erase(n); } -CommandBase::CommandBase(Module* mod, const std::string& cmd, unsigned int minpara, unsigned int maxpara) - : ServiceProvider(mod, cmd, SERVICE_COMMAND) - , flags_needed(0) - , min_params(minpara) - , max_params(maxpara) - , use_count(0) - , disabled(false) - , works_before_reg(false) - , allow_empty_last_param(true) - , Penalty(1) -{ -} - -CommandBase::~CommandBase() -{ -} - -void CommandBase::EncodeParameter(std::string& parameter, unsigned int index) -{ -} - -RouteDescriptor CommandBase::GetRouting(User* user, const Params& parameters) -{ - return ROUTE_LOCALONLY; -} - -Command::Command(Module* mod, const std::string& cmd, unsigned int minpara, unsigned int maxpara) - : CommandBase(mod, cmd, minpara, maxpara) - , force_manual_route(false) -{ -} - -Command::~Command() -{ - ServerInstance->Parser.RemoveCommand(this); -} - -void Command::RegisterService() -{ - if (!ServerInstance->Parser.AddCommand(this)) - throw ModuleException("Command already exists: " + name); -} - void CommandParser::ProcessBuffer(LocalUser* user, const std::string& buffer) { ClientProtocol::ParseOutput parseoutput; @@ -452,7 +405,7 @@ void CommandParser::TranslateSingleParam(TranslateType to, const std::string& it } // If no custom translator was given, fall through } - case TR_TEXT: + /*@fallthrough@*/ default: /* Do nothing */ dest.append(item);