2 * IRC - Internet Relay Chat, ircd/m_kick.c
3 * Copyright (C) 1990 Jarkko Oikarinen and
4 * University of Oulu, Computing Center
6 * See file AUTHORS in IRC package for additional names of
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 1, or (at your option)
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 * m_functions execute protocol messages on this server:
29 * cptr is always NON-NULL, pointing to a *LOCAL* client
30 * structure (with an open socket connected!). This
31 * identifies the physical socket where the message
32 * originated (or which caused the m_function to be
33 * executed--some m_functions may call others...).
35 * sptr is the source of the message, defined by the
36 * prefix part of the message if present. If not
37 * or prefix not found, then sptr==cptr.
39 * (!IsServer(cptr)) => (cptr == sptr), because
40 * prefixes are taken *only* from servers...
43 * (sptr == cptr) => the message didn't
46 * (sptr != cptr && IsServer(sptr) means
47 * the prefix specified servername. (?)
49 * (sptr != cptr && !IsServer(sptr) means
50 * that message originated from a remote
55 * (!IsServer(sptr)) means that, sptr can safely
56 * taken as defining the target structure of the
57 * message in this server.
59 * *Always* true (if 'parse' and others are working correct):
61 * 1) sptr->from == cptr (note: cptr->from == cptr)
63 * 2) MyConnect(sptr) <=> sptr == cptr (e.g. sptr
64 * *cannot* be a local connection, unless it's
65 * actually cptr!). [MyConnect(x) should probably
66 * be defined as (x == x->from) --msa ]
68 * parc number of variable parameter strings (if zero,
69 * parv is allowed to be NULL)
71 * parv a NULL terminated list of parameter pointers,
73 * parv[0], sender (prefix string), if not present
74 * this points to an empty string.
75 * parv[1]...parv[parc-1]
76 * pointers to additional parameters
77 * parv[parc] == NULL, *always*
79 * note: it is guaranteed that parv[0]..parv[parc-1] are all
84 * No need to include handlers.h here the signatures must match
85 * and we don't need to force a rebuild of all the handlers everytime
86 * we add a new one to the list. --Bleep
94 #include "ircd_reply.h"
95 #include "ircd_string.h"
104 * m_kick - generic message handler
106 * parv[0] = sender prefix
108 * parv[2] = client to kick
109 * parv[parc-1] = kick comment
111 int m_kick(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
114 struct Channel* chptr;
115 struct Membership* member = 0;
118 sptr->flags &= ~FLAGS_TS8;
120 if (parc < 3 || *parv[1] == '\0')
121 return need_more_params(sptr, "KICK");
123 channel_name = parv[1];
125 if (IsLocalChannel(channel_name) && !MyUser(sptr))
128 if (IsModelessChannel(channel_name)) {
129 sendto_one(sptr, err_str(ERR_CHANOPRIVSNEEDED), me.name, parv[0],
134 chptr = get_channel(sptr, channel_name, CGT_NO_CREATE);
136 sendto_one(sptr, err_str(ERR_NOSUCHCHANNEL), me.name, parv[0], channel_name);
140 if (!IsServer(cptr) && !is_chan_op(sptr, chptr)) {
141 sendto_one(sptr, err_str(ERR_CHANOPRIVSNEEDED),
142 me.name, parv[0], chptr->chname);
147 if (!(who = find_chasing(sptr, parv[2], 0)))
148 return 0; /* No such user left! */
150 else if (!(who = findNUser(parv[2])))
151 return 0; /* No such user left! */
154 * if the user is +k, prevent a kick from local user
156 if (IsChannelService(who) && MyUser(sptr)) {
157 sendto_one(sptr, err_str(ERR_ISCHANSERVICE), me.name,
158 parv[0], who->name, chptr->chname);
162 #ifdef NO_OPER_DEOP_LCHAN
164 * Prevent kicking opers from local channels -DM-
166 if (IsOperOnLocalChannel(who, chptr->chname)) {
167 sendto_one(sptr, err_str(ERR_ISOPERLCHAN), me.name,
168 parv[0], who->name, chptr->chname);
174 * Servers can now send kicks without hacks during a netburst - they
175 * are kicking users from a +i channel.
176 * - Isomer 25-11-1999
179 #if defined(NO_INVITE_NETRIDE)
180 && !IsBurstOrBurstAck(sptr)
183 send_hack_notice(cptr, sptr, parc, parv, 1, 3);
186 if (IsServer(sptr) ||
187 ((member = find_member_link(chptr, who)) && !IsZombie(member)))
189 struct Membership* sptr_link = find_member_link(chptr, sptr);
190 if (who->from != cptr &&
191 ((sptr_link && IsDeopped(sptr_link)) || (!sptr_link && IsUser(sptr))))
195 * cptr must be a server (or cptr == sptr and
196 * sptr->flags can't have DEOPPED set
197 * when CHANOP is set).
199 sendto_one(cptr, "%s%s " TOK_JOIN " %s", NumNick(who), chptr->chname);
200 if (IsChanOp(member))
202 sendto_one(cptr, "%s " TOK_MODE " %s +o %s%s " TIME_T_FMT,
203 NumServ(&me), chptr->chname, NumNick(who), chptr->creationtime);
205 if (HasVoice(member))
207 sendto_one(cptr, "%s " TOK_MODE " %s +v %s%s " TIME_T_FMT,
208 NumServ(&me), chptr->chname, NumNick(who), chptr->creationtime);
213 char* comment = (EmptyString(parv[parc - 1])) ? parv[0] : parv[parc - 1];
214 if (strlen(comment) > TOPICLEN)
215 comment[TOPICLEN] = '\0';
217 if (!IsLocalChannel(channel_name))
219 sendto_highprot_butone(cptr, 10, "%s%s " TOK_KICK " %s %s%s :%s",
220 NumNick(sptr), chptr->chname, NumNick(who), comment);
223 sendto_channel_butserv(chptr, sptr,
224 ":%s KICK %s %s :%s", parv[0], chptr->chname, who->name, comment);
225 make_zombie(member, who, cptr, sptr, chptr);
229 else if (MyUser(sptr))
230 sendto_one(sptr, err_str(ERR_USERNOTINCHANNEL),
231 me.name, parv[0], who->name, chptr->chname);
237 * ms_kick - server message handler
239 * parv[0] = sender prefix
241 * parv[2] = client to kick
242 * parv[parc-1] = kick comment
244 int ms_kick(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
247 struct Channel* chptr;
248 struct Membership* member = 0;
251 sptr->flags &= ~FLAGS_TS8;
253 if (parc < 3 || *parv[1] == '\0')
254 return need_more_params(sptr, "KICK");
256 channel_name = parv[1];
258 if (IsLocalChannel(channel_name) && !MyUser(sptr))
261 if (IsModelessChannel(channel_name)) {
262 sendto_one(sptr, err_str(ERR_CHANOPRIVSNEEDED), me.name, parv[0],
267 chptr = get_channel(sptr, channel_name, CGT_NO_CREATE);
269 sendto_one(sptr, err_str(ERR_NOSUCHCHANNEL), me.name, parv[0], channel_name);
273 if (!IsServer(cptr) && !is_chan_op(sptr, chptr)) {
274 sendto_one(sptr, err_str(ERR_CHANOPRIVSNEEDED),
275 me.name, parv[0], chptr->chname);
280 if (!(who = find_chasing(sptr, parv[2], 0)))
281 return 0; /* No such user left! */
283 else if (!(who = findNUser(parv[2])))
284 return 0; /* No such user left! */
287 * if the user is +k, prevent a kick from local user
289 if (IsChannelService(who) && MyUser(sptr)) {
290 sendto_one(sptr, err_str(ERR_ISCHANSERVICE), me.name,
291 parv[0], who->name, chptr->chname);
295 #ifdef NO_OPER_DEOP_LCHAN
297 * Prevent kicking opers from local channels -DM-
299 if (IsOperOnLocalChannel(who, chptr->chname)) {
300 sendto_one(sptr, err_str(ERR_ISOPERLCHAN), me.name,
301 parv[0], who->name, chptr->chname);
306 #if defined(NO_INVITE_NETRIDE)
308 * Servers can now send kicks without hacks during a netburst - they
309 * are kicking users from a +i channel.
310 * - Isomer 25-11-1999
312 if (IsServer(sptr) && !IsBurstOrBurstAck(sptr)) {
314 if (IsServer(sptr)) {
316 send_hack_notice(cptr, sptr, parc, parv, 1, 3);
319 if (IsServer(sptr) ||
320 ((member = find_member_link(chptr, who)) && !IsZombie(member)))
322 struct Membership* sptr_link = find_member_link(chptr, sptr);
323 if (who->from != cptr &&
324 ((sptr_link && IsDeopped(sptr_link)) || (!sptr_link && IsUser(sptr))))
328 * cptr must be a server (or cptr == sptr and
329 * sptr->flags can't have DEOPPED set
330 * when CHANOP is set).
332 sendto_one(cptr, "%s%s " TOK_JOIN " %s", NumNick(who), chptr->chname);
333 if (IsChanOp(member))
335 sendto_one(cptr, "%s " TOK_MODE " %s +o %s%s " TIME_T_FMT,
336 NumServ(&me), chptr->chname, NumNick(who), chptr->creationtime);
338 if (HasVoice(member))
340 sendto_one(cptr, "%s " TOK_MODE " %s +v %s%s " TIME_T_FMT,
341 NumServ(&me), chptr->chname, NumNick(who), chptr->creationtime);
346 char* comment = (EmptyString(parv[parc - 1])) ? parv[0] : parv[parc - 1];
347 if (strlen(comment) > TOPICLEN)
348 comment[TOPICLEN] = '\0';
350 if (!IsLocalChannel(channel_name)) {
351 if (IsServer(sptr)) {
352 sendto_highprot_butone(cptr, 10, "%s " TOK_KICK " %s %s%s :%s",
353 NumServ(sptr), chptr->chname, NumNick(who),
357 sendto_highprot_butone(cptr, 10, "%s%s " TOK_KICK " %s %s%s :%s",
358 NumNick(sptr), chptr->chname, NumNick(who),
363 sendto_channel_butserv(chptr, sptr,
364 ":%s KICK %s %s :%s", parv[0], chptr->chname, who->name, comment);
365 make_zombie(member, who, cptr, sptr, chptr);
369 else if (MyUser(sptr))
370 sendto_one(sptr, err_str(ERR_USERNOTINCHANNEL),
371 me.name, parv[0], who->name, chptr->chname);
381 * parv[0] = sender prefix
383 * parv[2] = client to kick
384 * parv[parc-1] = kick comment
386 int m_kick(struct Client *cptr, struct Client *sptr, int parc, char *parv[])
389 struct Channel* chptr;
390 struct Membership* member = 0;
393 sptr->flags &= ~FLAGS_TS8;
395 if (parc < 3 || *parv[1] == '\0')
396 return need_more_params(sptr, "KICK");
398 channel_name = parv[1];
400 if (IsLocalChannel(channel_name) && !MyUser(sptr))
403 if (IsModelessChannel(channel_name)) {
404 sendto_one(sptr, err_str(ERR_CHANOPRIVSNEEDED), me.name, parv[0],
409 chptr = get_channel(sptr, channel_name, CGT_NO_CREATE);
411 sendto_one(sptr, err_str(ERR_NOSUCHCHANNEL), me.name, parv[0], channel_name);
415 if (!IsServer(cptr) && !is_chan_op(sptr, chptr)) {
416 sendto_one(sptr, err_str(ERR_CHANOPRIVSNEEDED),
417 me.name, parv[0], chptr->chname);
422 if (!(who = find_chasing(sptr, parv[2], 0)))
423 return 0; /* No such user left! */
425 else if (!(who = findNUser(parv[2])))
426 return 0; /* No such user left! */
429 * if the user is +k, prevent a kick from local user
431 if (IsChannelService(who) && MyUser(sptr)) {
432 sendto_one(sptr, err_str(ERR_ISCHANSERVICE), me.name,
433 parv[0], who->name, chptr->chname);
437 #ifdef NO_OPER_DEOP_LCHAN
439 * Prevent kicking opers from local channels -DM-
441 if (IsOperOnLocalChannel(who, chptr->chname)) {
442 sendto_one(sptr, err_str(ERR_ISOPERLCHAN), me.name,
443 parv[0], who->name, chptr->chname);
449 * Servers can now send kicks without hacks during a netburst - they
450 * are kicking users from a +i channel.
451 * - Isomer 25-11-1999
454 #if defined(NO_INVITE_NETRIDE)
455 && !IsBurstOrBurstAck(sptr)
458 send_hack_notice(cptr, sptr, parc, parv, 1, 3);
461 if (IsServer(sptr) ||
462 ((member = find_member_link(chptr, who)) && !IsZombie(member)))
464 struct Membership* sptr_link = find_member_link(chptr, sptr);
465 if (who->from != cptr &&
466 ((sptr_link && IsDeopped(sptr_link)) || (!sptr_link && IsUser(sptr))))
470 * cptr must be a server (or cptr == sptr and
471 * sptr->flags can't have DEOPPED set
472 * when CHANOP is set).
474 sendto_one(cptr, "%s%s " TOK_JOIN " %s", NumNick(who), chptr->chname);
475 if (IsChanOp(member))
477 sendto_one(cptr, "%s " TOK_MODE " %s +o %s%s " TIME_T_FMT,
478 NumServ(&me), chptr->chname, NumNick(who), chptr->creationtime);
480 if (HasVoice(member))
482 sendto_one(cptr, "%s " TOK_MODE " %s +v %s%s " TIME_T_FMT,
483 NumServ(&me), chptr->chname, NumNick(who), chptr->creationtime);
488 char* comment = (EmptyString(parv[parc - 1])) ? parv[0] : parv[parc - 1];
489 if (strlen(comment) > TOPICLEN)
490 comment[TOPICLEN] = '\0';
492 if (!IsLocalChannel(channel_name))
494 sendto_highprot_butone(cptr, 10, "%s%s " TOK_KICK " %s %s%s :%s",
495 NumNick(sptr), chptr->chname, NumNick(who), comment);
498 sendto_channel_butserv(chptr, sptr,
499 ":%s KICK %s %s :%s", parv[0], chptr->chname, who->name, comment);
500 make_zombie(member, who, cptr, sptr, chptr);
504 else if (MyUser(sptr))
505 sendto_one(sptr, err_str(ERR_USERNOTINCHANNEL),
506 me.name, parv[0], who->name, chptr->chname);