* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*
- * $Id: m_kick.c 3317 2007-03-28 23:17:06Z jilles $
*/
#include "stdinc.h"
-#include "tools.h"
#include "channel.h"
#include "client.h"
-#include "irc_string.h"
+#include "match.h"
#include "ircd.h"
#include "numeric.h"
#include "send.h"
#include "hash.h"
#include "packet.h"
#include "s_serv.h"
+#include "s_conf.h"
+#include "hook.h"
static int m_kick(struct Client *, struct Client *, int, const char **);
#define mg_kick { m_kick, 3 }
/*
** m_kick
-** parv[0] = sender prefix
** parv[1] = channel
** parv[2] = client to kick
** parv[3] = kick comment
char *comment;
const char *name;
char *p = NULL;
+ char text[10];
const char *user;
static char buf[BUFSIZE];
+ int is_override = 0;
if(MyClient(source_p) && !IsFloodDone(source_p))
flood_endgrace(source_p);
return 0;
}
+ user = parv[2]; /* strtoken(&p2, parv[2], ","); */
+
+ if(!(who = find_chasing(source_p, user, &chasing)))
+ {
+ return 0;
+ }
+
if(!IsServer(source_p))
{
msptr = find_channel_membership(chptr, source_p);
return 0;
}
- if(!is_chanop(msptr))
+ if(!can_kick_deop(msptr, find_channel_membership(chptr, who)))
{
if(MyConnect(source_p))
{
- sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
- me.name, source_p->name, name);
- return 0;
+ if(IsOverride(source_p))
+ is_override = 1;
+ else
+ {
+ sendto_one(source_p, ":%s 482 %s %s :You do not have the proper privledges to kick this user",
+ me.name, source_p->name, name);
+ return 0;
+ }
}
/* If its a TS 0 channel, do it the old way */
- if(chptr->channelts == 0)
+ else if(chptr->channelts == 0)
{
sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
get_id(&me, source_p), get_id(source_p, source_p), name);
if((p = strchr(parv[2], ',')))
*p = '\0';
- user = parv[2]; /* strtoken(&p2, parv[2], ","); */
-
- if(!(who = find_chasing(source_p, user, &chasing)))
- {
- return 0;
- }
-
msptr = find_channel_membership(chptr, who);
if(msptr != NULL)
return 0;
}
+ if(MyClient(source_p) && chptr->mode.mode & MODE_NOKICK)
+ {
+ sendto_one_numeric(source_p, ERR_NOKICK,
+ form_str(ERR_NOKICK),
+ chptr->chname);
+ return 0;
+ }
+
+ if (MyClient(source_p) && chptr->mode.mode & MODE_NOOPERKICK && IsOper(who))
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
+ "Overriding KICK from %s on %s in %s (channel is +M)",
+ source_p->name, who->name, chptr->chname);
+ sendto_one_numeric(source_p, ERR_ISCHANSERVICE,
+ "%s %s :Cannot kick IRC operators from that channel.",
+ who->name, chptr->chname);
+ return 0;
+ }
+
+ if(MyClient(source_p))
+ {
+ hook_data_channel_approval hookdata;
+
+ hookdata.client = source_p;
+ hookdata.chptr = chptr;
+ hookdata.target = who;
+ hookdata.approved = 1;
+
+ call_hook(h_can_kick, &hookdata);
+
+ if (!hookdata.approved)
+ return 0;
+ }
+
comment = LOCAL_COPY((EmptyString(parv[3])) ? who->name : parv[3]);
if(strlen(comment) > (size_t) REASONLEN)
comment[REASONLEN] = '\0';
+ if(is_override)
+ {
+ sendto_wallops_flags(UMODE_WALLOP, &me,
+ "%s is overriding KICK [%s] on [%s] [%s]",
+ get_oper_name(source_p), who->name, chptr->chname, comment);
+ sendto_server(NULL, chptr, NOCAPS, NOCAPS,
+ ":%s WALLOPS :%s is overriding KICK [%s] on [%s] [%s]",
+ me.name, get_oper_name(source_p), who->name, chptr->chname, comment);
+ }
+
/* jdc
* - In the case of a server kicking a user (i.e. CLEARCHAN),
* the kick should show up as coming from the server which did
sendto_server(client_p, chptr, CAP_TS6, NOCAPS,
":%s KICK %s %s :%s",
use_id(source_p), chptr->chname, use_id(who), comment);
- sendto_server(client_p, chptr, NOCAPS, CAP_TS6,
- ":%s KICK %s %s :%s",
- source_p->name, chptr->chname, who->name, comment);
remove_user_from_channel(msptr);
+
+ rb_snprintf(text, sizeof(text), "K%s", who->id);
+
+ /* we don't need to track NOREJOIN stuff unless it's our client being kicked */
+ if(MyClient(who) && chptr->mode.mode & MODE_NOREJOIN)
+ channel_metadata_time_add(chptr, text, rb_current_time(), "KICKNOREJOIN");
}
else if (MyClient(source_p))
sendto_one_numeric(source_p, ERR_USERNOTINCHANNEL,