/[svn]/ircd-hybrid/modules/core/m_kick.c
ViewVC logotype

Contents of /ircd-hybrid/modules/core/m_kick.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 470 - (show annotations)
Fri Feb 17 05:07:43 2006 UTC (16 years, 6 months ago) by db
File MIME type: text/x-chdr
File size: 6712 byte(s)
- fix compile errors with moved modules.h
- fix a few missing includes, msg.h and parse.h


1 /*
2 * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
3 * m_kick.c: Kicks a user from a channel.
4 *
5 * Copyright (C) 2002 by the past and present ircd coders, and others.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20 * USA
21 *
22 * $Id$
23 */
24
25 #include "stdinc.h"
26 #include "handlers.h"
27 #include "channel.h"
28 #include "channel_mode.h"
29 #include "common.h"
30 #include "client.h"
31 #include "ircd.h"
32 #include "numeric.h"
33 #include "send.h"
34 #include "msg.h"
35 #include "conf/modules.h"
36 #include "parse.h"
37 #include "hash.h"
38 #include "packet.h"
39 #include "s_serv.h"
40
41
42 static void m_kick(struct Client *, struct Client *, int, char *[]);
43
44 struct Message kick_msgtab = {
45 "KICK", 0, 0, 3, 0, MFLG_SLOW, 0,
46 { m_unregistered, m_kick, m_kick, m_ignore, m_kick, m_ignore }
47 };
48
49 INIT_MODULE(m_kick, "$Revision$")
50 {
51 mod_add_cmd(&kick_msgtab);
52 }
53
54 CLEANUP_MODULE
55 {
56 mod_del_cmd(&kick_msgtab);
57 }
58
59 /* m_kick()
60 * parv[0] = sender prefix
61 * parv[1] = channel
62 * parv[2] = client to kick
63 * parv[3] = kick comment
64 */
65 static void
66 m_kick(struct Client *client_p, struct Client *source_p,
67 int parc, char *parv[])
68 {
69 struct Client *who;
70 struct Channel *chptr;
71 int chasing = 0;
72 char *comment;
73 char *name;
74 char *p = NULL;
75 char *user;
76 const char *from, *to;
77 struct Membership *ms = NULL;
78 struct Membership *ms_target;
79
80 if (!MyConnect(source_p) && IsCapable(source_p->from, CAP_TS6) && HasID(source_p))
81 {
82 from = me.id;
83 to = source_p->id;
84 }
85 else
86 {
87 from = me.name;
88 to = source_p->name;
89 }
90
91 if (*parv[2] == '\0')
92 {
93 sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS),
94 from, to, "KICK");
95 return;
96 }
97
98 if (MyClient(source_p) && !IsFloodDone(source_p))
99 flood_endgrace(source_p);
100
101 comment = (EmptyString(parv[3])) ? parv[2] : parv[3];
102 if (strlen(comment) > (size_t)KICKLEN)
103 comment[KICKLEN] = '\0';
104
105 name = parv[1];
106 while (*name == ',')
107 name++;
108
109 if ((p = strchr(name,',')) != NULL)
110 *p = '\0';
111 if (*name == '\0')
112 return;
113
114 if ((chptr = hash_find_channel(name)) == NULL)
115 {
116 sendto_one(source_p, form_str(ERR_NOSUCHCHANNEL),
117 from, to, name);
118 return;
119 }
120
121 if (!IsServer(source_p))
122 {
123 if ((ms = find_channel_link(source_p, chptr)) == NULL)
124 {
125 if (MyConnect(source_p))
126 {
127 sendto_one(source_p, form_str(ERR_NOTONCHANNEL),
128 me.name, source_p->name, name);
129 return;
130 }
131 }
132
133 if (!has_member_flags(ms, CHFL_CHANOP|CHFL_HALFOP))
134 {
135 /* was a user, not a server, and user isn't seen as a chanop here */
136 if (MyConnect(source_p))
137 {
138 /* user on _my_ server, with no chanops.. so go away */
139 sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
140 me.name, source_p->name, name);
141 return;
142 }
143
144 if (chptr->channelts == 0)
145 {
146 /* If its a TS 0 channel, do it the old way */
147 sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
148 from, to, name);
149 return;
150 }
151
152 /* Its a user doing a kick, but is not showing as chanop locally
153 * its also not a user ON -my- server, and the channel has a TS.
154 * There are two cases we can get to this point then...
155 *
156 * 1) connect burst is happening, and for some reason a legit
157 * op has sent a KICK, but the SJOIN hasn't happened yet or
158 * been seen. (who knows.. due to lag...)
159 *
160 * 2) The channel is desynced. That can STILL happen with TS
161 *
162 * Now, the old code roger wrote, would allow the KICK to
163 * go through. Thats quite legit, but lets weird things like
164 * KICKS by users who appear not to be chanopped happen,
165 * or even neater, they appear not to be on the channel.
166 * This fits every definition of a desync, doesn't it? ;-)
167 * So I will allow the KICK, otherwise, things are MUCH worse.
168 * But I will warn it as a possible desync.
169 *
170 * -Dianora
171 */
172 }
173 }
174
175 user = parv[2];
176
177 while (*user == ',')
178 user++;
179
180 if ((p = strchr(user, ',')) != NULL)
181 *p = '\0';
182
183 if (*user == '\0')
184 return;
185
186 if ((who = find_chasing(client_p, source_p, user, &chasing)) == NULL)
187 return;
188
189 if ((ms_target = find_channel_link(who, chptr)) != NULL)
190 {
191 #ifdef HALFOPS
192 /* half ops cannot kick other halfops on private channels */
193 if (has_member_flags(ms, CHFL_HALFOP) && !has_member_flags(ms, CHFL_CHANOP))
194 {
195 if (((chptr->mode.mode & MODE_PARANOID) && has_member_flags(ms_target,
196 CHFL_CHANOP|CHFL_HALFOP)) || has_member_flags(ms_target, CHFL_CHANOP))
197 {
198 sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
199 me.name, source_p->name, name);
200 return;
201 }
202 }
203 #endif
204
205 /* jdc
206 * - In the case of a server kicking a user (i.e. CLEARCHAN),
207 * the kick should show up as coming from the server which did
208 * the kick.
209 * - Personally, flame and I believe that server kicks shouldn't
210 * be sent anyways. Just waiting for some oper to abuse it...
211 */
212 if (IsServer(source_p))
213 sendto_channel_local(ALL_MEMBERS, NO, chptr, ":%s KICK %s %s :%s",
214 source_p->name, name, who->name, comment);
215 else
216 sendto_channel_local(ALL_MEMBERS, NO, chptr, ":%s!%s@%s KICK %s %s :%s",
217 source_p->name, source_p->username,
218 source_p->host, name, who->name, comment);
219
220 sendto_server(client_p, NULL, chptr, CAP_TS6, NOCAPS,
221 ":%s KICK %s %s :%s",
222 ID(source_p), chptr->chname, ID(who), comment);
223 sendto_server(client_p, NULL, chptr, NOCAPS, CAP_TS6,
224 ":%s KICK %s %s :%s", source_p->name, chptr->chname,
225 who->name, comment);
226
227 remove_user_from_channel(ms_target);
228 }
229 else
230 sendto_one(source_p, form_str(ERR_USERNOTINCHANNEL),
231 from, to, user, name);
232 }

Properties

Name Value
svn:eol-style native
svn:keywords Id Revision

svnadmin@ircd-hybrid.org
ViewVC Help
Powered by ViewVC 1.1.28