/[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 1028 - (show annotations)
Sun Nov 8 13:03:38 2009 UTC (11 years, 5 months ago) by michael
File MIME type: text/x-chdr
File size: 6777 byte(s)
- move ircd-hybrid-7.2 to trunk

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 "list.h"
27 #include "handlers.h"
28 #include "channel.h"
29 #include "channel_mode.h"
30 #include "client.h"
31 #include "irc_string.h"
32 #include "ircd.h"
33 #include "numeric.h"
34 #include "send.h"
35 #include "msg.h"
36 #include "modules.h"
37 #include "parse.h"
38 #include "hash.h"
39 #include "packet.h"
40 #include "s_serv.h"
41
42
43 static void m_kick(struct Client *, struct Client *, int, char *[]);
44
45 struct Message kick_msgtab = {
46 "KICK", 0, 0, 3, 0, MFLG_SLOW, 0,
47 {m_unregistered, m_kick, m_kick, m_ignore, m_kick, m_ignore}
48 };
49
50 #ifndef STATIC_MODULES
51 void
52 _modinit(void)
53 {
54 mod_add_cmd(&kick_msgtab);
55 }
56
57 void
58 _moddeinit(void)
59 {
60 mod_del_cmd(&kick_msgtab);
61 }
62
63 const char *_version = "$Revision$";
64 #endif
65
66 /* m_kick()
67 * parv[0] = sender prefix
68 * parv[1] = channel
69 * parv[2] = client to kick
70 * parv[3] = kick comment
71 */
72 static void
73 m_kick(struct Client *client_p, struct Client *source_p,
74 int parc, char *parv[])
75 {
76 struct Client *who;
77 struct Channel *chptr;
78 int chasing = 0;
79 char *comment;
80 char *name;
81 char *p = NULL;
82 char *user;
83 const char *from, *to;
84 struct Membership *ms = NULL;
85 struct Membership *ms_target;
86
87 if (!MyConnect(source_p) && IsCapable(source_p->from, CAP_TS6) && HasID(source_p))
88 {
89 from = me.id;
90 to = source_p->id;
91 }
92 else
93 {
94 from = me.name;
95 to = source_p->name;
96 }
97
98 if (EmptyString(parv[2]))
99 {
100 sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS),
101 from, to, "KICK");
102 return;
103 }
104
105 if (MyClient(source_p) && !IsFloodDone(source_p))
106 flood_endgrace(source_p);
107
108 comment = (EmptyString(parv[3])) ? parv[2] : parv[3];
109 if (strlen(comment) > (size_t)KICKLEN)
110 comment[KICKLEN] = '\0';
111
112 name = parv[1];
113 while (*name == ',')
114 name++;
115
116 if ((p = strchr(name,',')) != NULL)
117 *p = '\0';
118 if (*name == '\0')
119 return;
120
121 if ((chptr = hash_find_channel(name)) == NULL)
122 {
123 sendto_one(source_p, form_str(ERR_NOSUCHCHANNEL),
124 from, to, name);
125 return;
126 }
127
128 if (!IsServer(source_p))
129 {
130 if ((ms = find_channel_link(source_p, chptr)) == NULL)
131 {
132 if (MyConnect(source_p))
133 {
134 sendto_one(source_p, form_str(ERR_NOTONCHANNEL),
135 me.name, source_p->name, name);
136 return;
137 }
138 }
139
140 if (!has_member_flags(ms, CHFL_CHANOP|CHFL_HALFOP))
141 {
142 /* was a user, not a server, and user isn't seen as a chanop here */
143 if (MyConnect(source_p))
144 {
145 /* user on _my_ server, with no chanops.. so go away */
146 sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
147 me.name, source_p->name, name);
148 return;
149 }
150
151 if (chptr->channelts == 0)
152 {
153 /* If its a TS 0 channel, do it the old way */
154 sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
155 from, to, name);
156 return;
157 }
158
159 /* Its a user doing a kick, but is not showing as chanop locally
160 * its also not a user ON -my- server, and the channel has a TS.
161 * There are two cases we can get to this point then...
162 *
163 * 1) connect burst is happening, and for some reason a legit
164 * op has sent a KICK, but the SJOIN hasn't happened yet or
165 * been seen. (who knows.. due to lag...)
166 *
167 * 2) The channel is desynced. That can STILL happen with TS
168 *
169 * Now, the old code roger wrote, would allow the KICK to
170 * go through. Thats quite legit, but lets weird things like
171 * KICKS by users who appear not to be chanopped happen,
172 * or even neater, they appear not to be on the channel.
173 * This fits every definition of a desync, doesn't it? ;-)
174 * So I will allow the KICK, otherwise, things are MUCH worse.
175 * But I will warn it as a possible desync.
176 *
177 * -Dianora
178 */
179 }
180 }
181
182 user = parv[2];
183
184 while (*user == ',')
185 user++;
186
187 if ((p = strchr(user, ',')) != NULL)
188 *p = '\0';
189
190 if (*user == '\0')
191 return;
192
193 if ((who = find_chasing(client_p, source_p, user, &chasing)) == NULL)
194 return;
195
196 if ((ms_target = find_channel_link(who, chptr)) != NULL)
197 {
198 #ifdef HALFOPS
199 /* half ops cannot kick other halfops on private channels */
200 if (has_member_flags(ms, CHFL_HALFOP) && !has_member_flags(ms, CHFL_CHANOP))
201 {
202 if (((chptr->mode.mode & MODE_PRIVATE) && has_member_flags(ms_target,
203 CHFL_CHANOP|CHFL_HALFOP)) || has_member_flags(ms_target, CHFL_CHANOP))
204 {
205 sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
206 me.name, source_p->name, name);
207 return;
208 }
209 }
210 #endif
211
212 /* jdc
213 * - In the case of a server kicking a user (i.e. CLEARCHAN),
214 * the kick should show up as coming from the server which did
215 * the kick.
216 * - Personally, flame and I believe that server kicks shouldn't
217 * be sent anyways. Just waiting for some oper to abuse it...
218 */
219 if (IsServer(source_p))
220 sendto_channel_local(ALL_MEMBERS, 0, chptr, ":%s KICK %s %s :%s",
221 source_p->name, name, who->name, comment);
222 else
223 sendto_channel_local(ALL_MEMBERS, 0, chptr, ":%s!%s@%s KICK %s %s :%s",
224 source_p->name, source_p->username,
225 source_p->host, name, who->name, comment);
226
227 sendto_server(client_p, chptr, CAP_TS6, NOCAPS,
228 ":%s KICK %s %s :%s",
229 ID(source_p), chptr->chname, ID(who), comment);
230 sendto_server(client_p, chptr, NOCAPS, CAP_TS6,
231 ":%s KICK %s %s :%s", source_p->name, chptr->chname,
232 who->name, comment);
233
234 remove_user_from_channel(ms_target);
235 }
236 else
237 sendto_one(source_p, form_str(ERR_USERNOTINCHANNEL),
238 from, to, user, name);
239 }

Properties

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

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