CmdResult Handle (const std::vector<std::string>& parameters, User *user) { User* dest = ServerInstance->FindNick(parameters[1]); Channel* channel = ServerInstance->FindChan(parameters[0]); const char* reason = ""; if ((dest) && (dest->registered == REG_ALL) && (channel)) { if (parameters.size() > 2) { reason = parameters[2].c_str(); } else { reason = dest->nick.c_str(); } 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 kick them. For remote clients, * just return CMD_SUCCESS knowing the protocol module will route the SAKICK to the user's * local server and that will kick them instead. */ if (IS_LOCAL(dest)) { channel->KickUser(ServerInstance->FakeClient, dest, reason); Channel *n = ServerInstance->FindChan(parameters[1]); if (n && n->HasUser(dest)) { /* Sort-of-bug: If the command was issued remotely, this message won't be sent */ user->WriteNotice("*** Unable to kick " + dest->nick + " from " + parameters[0]); return CMD_FAILURE; } } if (IS_LOCAL(user)) { /* Locally issued command; send the snomasks */ ServerInstance->SNO->WriteGlobalSno('a', user->nick + " SAKICKed " + dest->nick + " on " + parameters[0]); } return CMD_SUCCESS; } else { user->WriteNotice("*** Invalid nickname or channel"); } return CMD_FAILURE; }
/** Handle /KICK */ CmdResult CommandKick::Handle (const std::vector<std::string>& parameters, User *user) { std::string reason; Channel* c = ServerInstance->FindChan(parameters[0]); User* u; if (CommandParser::LoopCall(user, this, parameters, 1)) return CMD_SUCCESS; if (IS_LOCAL(user)) u = ServerInstance->FindNickOnly(parameters[1]); else u = ServerInstance->FindNick(parameters[1]); if ((!u) || (!c) || (u->registered != REG_ALL)) { user->WriteNumeric(ERR_NOSUCHNICK, "%s :No such nick/channel", c ? parameters[1].c_str() : parameters[0].c_str()); return CMD_FAILURE; } Membership* srcmemb = NULL; if (IS_LOCAL(user)) { srcmemb = c->GetUser(user); if (!srcmemb) { user->WriteNumeric(ERR_NOTONCHANNEL, "%s :You're not on that channel!", parameters[0].c_str()); return CMD_FAILURE; } if (u->server->IsULine()) { user->WriteNumeric(ERR_CHANOPRIVSNEEDED, "%s :You may not kick a u-lined client", c->name.c_str()); return CMD_FAILURE; } } if (parameters.size() > 2) { reason.assign(parameters[2], 0, ServerInstance->Config->Limits.MaxKick); } else { reason.assign(user->nick, 0, ServerInstance->Config->Limits.MaxKick); } c->KickUser(user, u, reason, srcmemb); return CMD_SUCCESS; }
CmdResult Handle(User* user, const Params& parameters) override { User* dest = ServerInstance->FindNick(parameters[1]); Channel* channel = ServerInstance->FindChan(parameters[0]); if ((dest) && (dest->registered == REG_ALL) && (channel)) { const std::string& reason = (parameters.size() > 2) ? parameters[2] : dest->nick; 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 kick them. For remote clients, * just return CMD_SUCCESS knowing the protocol module will route the SAKICK to the user's * local server and that will kick them instead. */ if (IS_LOCAL(dest)) { // Target is on this server, kick them and send the snotice channel->KickUser(ServerInstance->FakeClient, dest, reason); ServerInstance->SNO.WriteGlobalSno('a', user->nick + " SAKICKed " + dest->nick + " on " + channel->name); } return CMD_SUCCESS; } else { user->WriteNotice("*** Invalid nickname or channel"); } return CMD_FAILURE; }
/** Handle /KICK */ CmdResult CommandKick::Handle (const std::vector<std::string>& parameters, User *user) { std::string reason; Channel* c = ServerInstance->FindChan(parameters[0]); User* u; if (ServerInstance->Parser->LoopCall(user, this, parameters, 1)) return CMD_SUCCESS; if (IS_LOCAL(user)) u = ServerInstance->FindNickOnly(parameters[1]); else u = ServerInstance->FindNick(parameters[1]); if (!u || !c) { user->WriteServ( "401 %s %s :No such nick/channel", user->nick.c_str(), u ? parameters[0].c_str() : parameters[1].c_str()); return CMD_FAILURE; } if ((IS_LOCAL(user)) && (!c->HasUser(user)) && (!ServerInstance->ULine(user->server))) { user->WriteServ( "442 %s %s :You're not on that channel!", user->nick.c_str(), parameters[0].c_str()); return CMD_FAILURE; } if (parameters.size() > 2) { reason.assign(parameters[2], 0, ServerInstance->Config->Limits.MaxKick); } else { reason.assign(user->nick, 0, ServerInstance->Config->Limits.MaxKick); } c->KickUser(user, u, reason); return CMD_SUCCESS; }
void ValidateChans() { badchan = true; std::vector<Channel*> chanvec; for (chan_hash::const_iterator i = ServerInstance->chanlist->begin(); i != ServerInstance->chanlist->end(); ++i) { if (!ServerInstance->IsChannel(i->second->name)) chanvec.push_back(i->second); } std::vector<Channel*>::reverse_iterator c2 = chanvec.rbegin(); while (c2 != chanvec.rend()) { Channel* c = *c2++; if (c->IsModeSet(permchannelmode) && c->GetUserCounter()) { std::vector<std::string> modes; modes.push_back(c->name); modes.push_back(std::string("-") + permchannelmode->GetModeChar()); ServerInstance->Modes->Process(modes, ServerInstance->FakeClient); } const UserMembList* users = c->GetUsers(); for(UserMembCIter j = users->begin(); j != users->end(); ) { if (IS_LOCAL(j->first)) { // KickUser invalidates the iterator UserMembCIter it = j++; c->KickUser(ServerInstance->FakeClient, it->first, "Channel name no longer valid"); } else ++j; } } badchan = false; }
void ValidateChans() { Modes::ChangeList removepermchan; badchan = true; const chan_hash& chans = ServerInstance->GetChans(); for (chan_hash::const_iterator i = chans.begin(); i != chans.end(); ) { Channel* c = i->second; // Move iterator before we begin kicking ++i; if (ServerInstance->IsChannel(c->name)) continue; // The name of this channel is still valid if (c->IsModeSet(permchannelmode) && c->GetUserCounter()) { removepermchan.clear(); removepermchan.push_remove(*permchannelmode); ServerInstance->Modes.Process(ServerInstance->FakeClient, c, NULL, removepermchan); } Channel::MemberMap& users = c->userlist; for (Channel::MemberMap::iterator j = users.begin(); j != users.end(); ) { if (IS_LOCAL(j->first)) { // KickUser invalidates the iterator Channel::MemberMap::iterator it = j++; c->KickUser(ServerInstance->FakeClient, it, "Channel name no longer valid"); } else ++j; } } badchan = false; }