CmdResult CommandPart::Handle (const std::vector<std::string>& parameters, User *user) { std::string reason; if (IS_LOCAL(user)) { if (!ServerInstance->Config->FixedPart.empty()) reason = ServerInstance->Config->FixedPart; else if (parameters.size() > 1) reason = ServerInstance->Config->PrefixPart + parameters[1] + ServerInstance->Config->SuffixPart; } else { if (parameters.size() > 1) reason = parameters[1]; } if (CommandParser::LoopCall(user, this, parameters, 0)) return CMD_SUCCESS; Channel* c = ServerInstance->FindChan(parameters[0]); if (c) { c->PartUser(user, reason); } else { user->WriteServ( "401 %s %s :No such channel", user->nick.c_str(), parameters[0].c_str()); return CMD_FAILURE; } return CMD_SUCCESS; }
CmdResult Handle (const std::vector<std::string>& parameters, User *user) { User* dest = ServerInstance->FindNick(parameters[0]); Channel* channel = ServerInstance->FindChan(parameters[1]); std::string reason; if ((dest) && (dest->registered == REG_ALL) && (channel)) { if (parameters.size() > 2) reason = parameters[2]; if (ServerInstance->ULine(dest->server)) { user->WriteNumeric(ERR_NOPRIVILEGES, "%s :Cannot use an SA command on a u-lined client",user->nick.c_str()); return CMD_FAILURE; } /* For local clients, directly part them generating a PART message. For remote clients, * just return CMD_SUCCESS knowing the protocol module will route the SAPART to the users * local server and that will generate the PART instead */ if (IS_LOCAL(dest)) { channel->PartUser(dest, reason); Channel* n = ServerInstance->FindChan(parameters[1]); if (!n) { ServerInstance->SNO->WriteGlobalSno('a', user->nick+" used SAPART to make "+dest->nick+" part "+parameters[1]); return CMD_SUCCESS; } else { if (!n->HasUser(dest)) { ServerInstance->SNO->WriteGlobalSno('a', user->nick+" used SAPART to make "+dest->nick+" part "+parameters[1]); return CMD_SUCCESS; } else { user->WriteServ("NOTICE %s :*** Unable to make %s part %s",user->nick.c_str(), dest->nick.c_str(), parameters[1].c_str()); return CMD_FAILURE; } } } return CMD_SUCCESS; } else { user->WriteServ("NOTICE %s :*** Invalid nickname or channel", user->nick.c_str()); } return CMD_FAILURE; }
CmdResult CommandSVSPart::Handle(User* user, std::vector<std::string>& parameters) { User* u = ServerInstance->FindUUID(parameters[0]); if (!u) return CMD_FAILURE; Channel* c = ServerInstance->FindChan(parameters[1]); if (!c) return CMD_FAILURE; if (IS_LOCAL(u)) { std::string reason = (parameters.size() == 3) ? parameters[2] : "Services forced part"; c->PartUser(u, reason); } return CMD_SUCCESS; }
CmdResult Handle (const std::vector<std::string>& parameters, User *user) { if (CommandParser::LoopCall(user, this, parameters, 1)) return CMD_FAILURE; User* dest = ServerInstance->FindNick(parameters[0]); Channel* channel = ServerInstance->FindChan(parameters[1]); std::string reason; if ((dest) && (dest->registered == REG_ALL) && (channel)) { if (parameters.size() > 2) reason = parameters[2]; if (dest->server->IsULine()) { user->WriteNumeric(ERR_NOPRIVILEGES, ":Cannot use an SA command on a u-lined client"); return CMD_FAILURE; } if (!channel->HasUser(dest)) { user->WriteNotice("*** " + dest->nick + " is not on " + channel->name); return CMD_FAILURE; } /* For local clients, directly part them generating a PART message. For remote clients, * just return CMD_SUCCESS knowing the protocol module will route the SAPART to the users * local server and that will generate the PART instead */ if (IS_LOCAL(dest)) { channel->PartUser(dest, reason); ServerInstance->SNO->WriteGlobalSno('a', user->nick+" used SAPART to make "+dest->nick+" part "+channel->name); } return CMD_SUCCESS; } else { user->WriteNotice("*** Invalid nickname or channel"); } return CMD_FAILURE; }
CmdResult Handle (const std::vector<std::string> ¶meters, User *user) { Channel* channel = ServerInstance->FindChan(parameters[0]); std::string reason = ConvToStr("Cycling"); if (parameters.size() > 1) { /* reason provided, use it */ reason = reason + ": " + parameters[1]; } if (!channel) { user->WriteNumeric(403, "%s %s :No such channel", user->nick.c_str(), parameters[0].c_str()); return CMD_FAILURE; } if (channel->HasUser(user)) { /* * technically, this is only ever sent locally, but pays to be safe ;p */ if (IS_LOCAL(user)) { if (channel->GetPrefixValue(user) < VOICE_VALUE && channel->IsBanned(user)) { /* banned, boned. drop the message. */ user->WriteServ("NOTICE "+user->nick+" :*** You may not cycle, as you are banned on channel " + channel->name); return CMD_FAILURE; } channel->PartUser(user, reason); Channel::JoinUser(user, parameters[0], true, "", false, ServerInstance->Time()); } return CMD_SUCCESS; } else { user->WriteNumeric(442, "%s %s :You're not on that channel", user->nick.c_str(), channel->name.c_str()); } return CMD_FAILURE; }
CmdResult CommandPart::Handle (const std::vector<std::string>& parameters, User *user) { std::string reason; if (IS_LOCAL(user)) { if (*ServerInstance->Config->FixedPart) reason = ServerInstance->Config->FixedPart; else { if (parameters.size() > 1) reason = ServerInstance->Config->PrefixPart + std::string(parameters[1]) + ServerInstance->Config->SuffixPart; else reason = ""; } } else { reason = parameters.size() > 1 ? parameters[1] : ""; } if (ServerInstance->Parser->LoopCall(user, this, parameters, 0)) return CMD_SUCCESS; Channel* c = ServerInstance->FindChan(parameters[0]); if (c) { if (!c->PartUser(user, reason)) /* Arse, who stole our channel! :/ */ delete c; } else { user->WriteServ( "401 %s %s :No such channel", user->nick.c_str(), parameters[0].c_str()); return CMD_FAILURE; } return CMD_SUCCESS; }
bool TreeSocket::ServicePart(const std::string &prefix, std::deque<std::string> ¶ms) { if (params.size() < 2) return true; std::string reason = "Services forced part"; if (params.size() == 3) reason = params[2]; User* u = this->ServerInstance->FindNick(params[0]); Channel* c = this->ServerInstance->FindChan(params[1]); if (u) { /* only part if it's local, otherwise just pass it on! */ if (IS_LOCAL(u)) if (!c->PartUser(u, reason)) delete c; Utils->DoOneToAllButSender(prefix,"SVSPART",params,prefix); } return true; }
CmdResult HandleRMB(const std::vector<std::string>& parameters, User *user, bool neworder) { User* target; Channel* channel; std::string reason; std::string protectkey; std::string founderkey; bool hasnokicks; /* Set these to the parameters needed, the new version of this module switches it's parameters around * supplying a new command with the new order while keeping the old /remove with the older order. * /remove <nick> <channel> [reason ...] * /fpart <channel> <nick> [reason ...] */ const std::string& channame = parameters[neworder ? 0 : 1]; const std::string& username = parameters[neworder ? 1 : 0]; /* Look up the user we're meant to be removing from the channel */ target = ServerInstance->FindNick(username); /* And the channel we're meant to be removing them from */ channel = ServerInstance->FindChan(channame); /* Fix by brain - someone needs to learn to validate their input! */ if ((!target) || (target->registered != REG_ALL) || (!channel)) { user->WriteNumeric(ERR_NOSUCHNICK, "%s %s :No such nick/channel", user->nick.c_str(), !channel ? channame.c_str() : username.c_str()); return CMD_FAILURE; } if (!channel->HasUser(target)) { user->WriteServ( "NOTICE %s :*** The user %s is not on channel %s", user->nick.c_str(), target->nick.c_str(), channel->name.c_str()); return CMD_FAILURE; } int ulevel = channel->GetPrefixValue(user); int tlevel = channel->GetPrefixValue(target); hasnokicks = (ServerInstance->Modules->Find("m_nokicks.so") && channel->IsModeSet('Q')); if (ServerInstance->ULine(target->server)) { user->WriteNumeric(482, "%s %s :Only a u-line may remove a u-line from a channel.", user->nick.c_str(), channame.c_str()); return CMD_FAILURE; } /* We support the +Q channel mode via. the m_nokicks module, if the module is loaded and the mode is set then disallow the /remove */ if ((!IS_LOCAL(user)) || (!supportnokicks || !hasnokicks)) { /* We'll let everyone remove their level and below, eg: * ops can remove ops, halfops, voices, and those with no mode (no moders actually are set to 1) * a ulined target will get a higher level than it's possible for a /remover to get..so they're safe. * Nobody may remove a founder. */ if ((!IS_LOCAL(user)) || ((ulevel > VOICE_VALUE) && (ulevel >= tlevel) && (tlevel != 50000))) { // REMOVE/FPART will be sent to the target's server and it will reply with a PART (or do nothing if it doesn't understand the command) if (!IS_LOCAL(target)) return CMD_SUCCESS; std::string reasonparam; /* If a reason is given, use it */ if(parameters.size() > 2) reasonparam = parameters[2]; else reasonparam = "No reason given"; /* Build up the part reason string. */ reason = "Removed by " + user->nick + ": " + reasonparam; channel->WriteChannelWithServ(ServerInstance->Config->ServerName, "NOTICE %s :%s removed %s from the channel", channel->name.c_str(), user->nick.c_str(), target->nick.c_str()); target->WriteServ("NOTICE %s :*** %s removed you from %s with the message: %s", target->nick.c_str(), user->nick.c_str(), channel->name.c_str(), reasonparam.c_str()); channel->PartUser(target, reason); } else { user->WriteServ( "NOTICE %s :*** You do not have access to /remove %s from %s", user->nick.c_str(), target->nick.c_str(), channel->name.c_str()); return CMD_FAILURE; } } else { /* m_nokicks.so was loaded and +Q was set, block! */ user->WriteServ( "484 %s %s :Can't remove user %s from channel (+Q set)", user->nick.c_str(), channel->name.c_str(), target->nick.c_str()); return CMD_FAILURE; } return CMD_SUCCESS; }
CmdResult HandleRMB(User* user, const CommandBase::Params& parameters, bool fpart) { User* target; Channel* channel; std::string reason; // If the command is a /REMOVE then detect the parameter order bool neworder = ((fpart) || (parameters[0][0] == '#')); /* Set these to the parameters needed, the new version of this module switches it's parameters around * supplying a new command with the new order while keeping the old /remove with the older order. * /remove <nick> <channel> [reason ...] * /fpart <channel> <nick> [reason ...] */ const std::string& channame = parameters[neworder ? 0 : 1]; const std::string& username = parameters[neworder ? 1 : 0]; /* Look up the user we're meant to be removing from the channel */ if (IS_LOCAL(user)) target = ServerInstance->FindNickOnly(username); else target = ServerInstance->FindNick(username); /* And the channel we're meant to be removing them from */ channel = ServerInstance->FindChan(channame); /* Fix by brain - someone needs to learn to validate their input! */ if (!channel) { user->WriteNumeric(Numerics::NoSuchChannel(channame)); return CMD_FAILURE; } if ((!target) || (target->registered != REG_ALL)) { user->WriteNumeric(Numerics::NoSuchNick(username)); return CMD_FAILURE; } if (!channel->HasUser(target)) { user->WriteNotice(InspIRCd::Format("*** The user %s is not on channel %s", target->nick.c_str(), channel->name.c_str())); return CMD_FAILURE; } if (target->server->IsULine()) { user->WriteNumeric(ERR_CHANOPRIVSNEEDED, channame, "Only a u-line may remove a u-line from a channel."); return CMD_FAILURE; } /* We support the +Q channel mode via. the m_nokicks module, if the module is loaded and the mode is set then disallow the /remove */ if ((!IS_LOCAL(user)) || (!supportnokicks) || (!channel->IsModeSet(nokicksmode))) { /* We'll let everyone remove their level and below, eg: * ops can remove ops, halfops, voices, and those with no mode (no moders actually are set to 1) a ulined target will get a higher level than it's possible for a /remover to get..so they're safe. * Nobody may remove people with >= protectedrank rank. */ unsigned int ulevel = channel->GetPrefixValue(user); unsigned int tlevel = channel->GetPrefixValue(target); if ((!IS_LOCAL(user)) || ((ulevel > VOICE_VALUE) && (ulevel >= tlevel) && ((protectedrank == 0) || (tlevel < protectedrank)))) { // REMOVE will be sent to the target's server and it will reply with a PART (or do nothing if it doesn't understand the command) if (!IS_LOCAL(target)) { // Send an ENCAP REMOVE with parameters being in the old <user> <chan> order which is // compatible with both 2.0 and 3.0. This also turns FPART into REMOVE. CommandBase::Params p; p.push_back(target->uuid); p.push_back(channel->name); if (parameters.size() > 2) p.push_back(":" + parameters[2]); ServerInstance->PI->SendEncapsulatedData(target->server->GetName(), "REMOVE", p, user); return CMD_SUCCESS; } std::string reasonparam; /* If a reason is given, use it */ if(parameters.size() > 2) reasonparam = parameters[2]; else reasonparam = "No reason given"; /* Build up the part reason string. */ reason = "Removed by " + user->nick + ": " + reasonparam; channel->WriteNotice(InspIRCd::Format("%s removed %s from the channel", user->nick.c_str(), target->nick.c_str())); target->WriteNotice("*** " + user->nick + " removed you from " + channel->name + " with the message: " + reasonparam); channel->PartUser(target, reason); } else { user->WriteNotice(InspIRCd::Format("*** You do not have access to /remove %s from %s", target->nick.c_str(), channel->name.c_str())); return CMD_FAILURE; } } else { /* m_nokicks.so was loaded and +Q was set, block! */ user->WriteNumeric(ERR_RESTRICTED, channel->name, InspIRCd::Format("Can't remove user %s from channel (nokicks mode is set)", target->nick.c_str())); return CMD_FAILURE; } return CMD_SUCCESS; }