ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/branches/8.2.x/modules/core/m_kick.c
Revision: 1167
Committed: Thu Aug 11 20:13:38 2011 UTC (12 years, 7 months ago) by michael
Content type: text/x-csrc
Original Path: ircd-hybrid-8/modules/core/m_kick.c
File size: 6771 byte(s)
Log Message:
- Improve services support
- Add channelmode +r

File Contents

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

Properties

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