/** * Handler for the IRC command "KICK". * * @param Client The client from which this command has been received. * @param Req Request structure with prefix and all parameters. * @return CONNECTED or DISCONNECTED. */ GLOBAL bool IRC_KICK(CLIENT *Client, REQUEST *Req) { CLIENT *from; char *itemList = Req->argv[0]; const char* currentNick, *currentChannel, *reason; unsigned int channelCount = 1; unsigned int nickCount = 1; assert( Client != NULL ); assert( Req != NULL ); _IRC_ARGC_BETWEEN_OR_RETURN_(Client, Req, 2, 3) _IRC_GET_SENDER_OR_RETURN_(from, Req, Client) while (*itemList) { if (*itemList == ',') { *itemList = '\0'; channelCount++; } itemList++; } itemList = Req->argv[1]; while (*itemList) { if (*itemList == ',') { *itemList = '\0'; nickCount++; } itemList++; } reason = Req->argc == 3 ? Req->argv[2] : Client_ID(from); currentNick = Req->argv[1]; currentChannel = Req->argv[0]; if (channelCount == 1) { while (nickCount > 0) { if (!try_kick(Client, from, currentNick, currentChannel, reason)) return false; while (*currentNick) currentNick++; currentNick++; nickCount--; } } else if (channelCount == nickCount) { while (nickCount > 0) { if (!try_kick(Client, from, currentNick, currentChannel, reason)) return false; while (*currentNick) currentNick++; while (*currentChannel) currentChannel++; currentNick++; currentChannel++; nickCount--; } } else { return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG, Client_ID(Client), Req->command); } return true; } /* IRC_KICK */
static void cs_cmd_kick(sourceinfo_t *si, int parc, char *parv[]) { char *chan = parv[0]; char *nick = parv[1]; char *reason = parv[2]; mychan_t *mc; user_t *tu; chanuser_t *cu; char reasonbuf[BUFSIZE]; if (!chan || !nick) { command_fail(si, fault_needmoreparams, STR_INSUFFICIENT_PARAMS, "KICK"); command_fail(si, fault_needmoreparams, _("Syntax: KICK <#channel> <nickname> [reason]")); return; } mc = mychan_find(chan); if (!mc) { command_fail(si, fault_nosuch_target, _("Channel \2%s\2 is not registered."), chan); return; } if (!chanacs_source_has_flag(mc, si, CA_REMOVE)) { command_fail(si, fault_noprivs, _("You are not authorized to perform this operation.")); return; } if (metadata_find(mc, "private:close:closer")) { command_fail(si, fault_noprivs, _("\2%s\2 is closed."), chan); return; } /* figure out who we're going to kick */ if (!(tu = user_find_named(nick))) { command_fail(si, fault_nosuch_target, _("\2%s\2 is not online."), nick); return; } /* if target is a service, bail. --nenolod */ if (is_internal_client(tu)) return; cu = chanuser_find(mc->chan, tu); if (!cu) { command_fail(si, fault_nosuch_target, _("\2%s\2 is not on \2%s\2."), tu->nick, mc->name); return; } if (cu->modes & CSTATUS_OWNER || cu->modes & CSTATUS_PROTECT) { command_fail(si, fault_noprivs, _("\2%s\2 is protected from kicks; you cannot kick them."), tu->nick); return; } snprintf(reasonbuf, BUFSIZE, "(%s) %s", get_source_name(si), reason ? reason : "No reason given"); try_kick(chansvs.me->me, mc->chan, tu, reasonbuf); logcommand(si, CMDLOG_DO, "KICK: \2%s!%s@%s\2 from \2%s\2", tu->nick, tu->user, tu->vhost, mc->name); if (si->su != tu && !chanuser_find(mc->chan, si->su)) command_success_nodata(si, _("\2%s\2 has been kicked from \2%s\2."), tu->nick, mc->name); }
GLOBAL bool IRC_KICK(CLIENT *Client, REQUEST *Req) { CLIENT *from; char *itemList = Req->argv[0]; const char* currentNick, *currentChannel, *reason; unsigned int channelCount = 1; unsigned int nickCount = 1; assert( Client != NULL ); assert( Req != NULL ); if ((Req->argc < 2) || (Req->argc > 3)) return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG, Client_ID(Client), Req->command); while (*itemList) { if (*itemList == ',') { *itemList = '\0'; channelCount++; } itemList++; } itemList = Req->argv[1]; while (*itemList) { if (*itemList == ',') { *itemList = '\0'; nickCount++; } itemList++; } if (Client_Type(Client) == CLIENT_SERVER) from = Client_Search(Req->prefix); else from = Client; if (!from) return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG, Client_ID(Client), Req->prefix); reason = Req->argc == 3 ? Req->argv[2] : Client_ID(from); currentNick = Req->argv[1]; currentChannel = Req->argv[0]; if (channelCount == 1) { while (nickCount > 0) { if (!try_kick(Client, from, currentNick, currentChannel, reason)) return false; while (*currentNick) currentNick++; currentNick++; nickCount--; } } else if (channelCount == nickCount) { while (nickCount > 0) { if (!try_kick(Client, from, currentNick, currentChannel, reason)) return false; while (*currentNick) currentNick++; while (*currentChannel) currentChannel++; currentNick++; currentChannel++; nickCount--; } } else { return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG, Client_ID(Client), Req->command); } return true; } /* IRC_KICK */