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

Contents of /ircd-hybrid/modules/core/m_kill.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: 9482 byte(s)
- move ircd-hybrid-7.2 to trunk

1 /*
2 * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
3 * m_kill.c: Kills a user.
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 "client.h"
29 #include "hash.h" /* for find_client() */
30 #include "ircd.h"
31 #include "numeric.h"
32 #include "s_log.h"
33 #include "s_serv.h"
34 #include "s_conf.h"
35 #include "send.h"
36 #include "whowas.h"
37 #include "irc_string.h"
38 #include "sprintf_irc.h"
39 #include "msg.h"
40 #include "parse.h"
41 #include "modules.h"
42
43
44 static char buf[IRCD_BUFSIZE];
45
46 static void ms_kill(struct Client *, struct Client *, int, char *[]);
47 static void mo_kill(struct Client *, struct Client *, int, char *[]);
48 static void relay_kill(struct Client *, struct Client *, struct Client *,
49 const char *, const char *);
50
51 struct Message kill_msgtab = {
52 "KILL", 0, 0, 2, 0, MFLG_SLOW, 0,
53 {m_unregistered, m_not_oper, ms_kill, m_ignore, mo_kill, m_ignore}
54 };
55
56 #ifndef STATIC_MODULES
57 void
58 _modinit(void)
59 {
60 mod_add_cmd(&kill_msgtab);
61 }
62
63 void
64 _moddeinit(void)
65 {
66 mod_del_cmd(&kill_msgtab);
67 }
68
69 const char *_version = "$Revision$";
70 #endif
71
72 /* mo_kill()
73 * parv[0] = sender prefix
74 * parv[1] = kill victim
75 * parv[2] = kill path
76 */
77 static void
78 mo_kill(struct Client *client_p, struct Client *source_p,
79 int parc, char *parv[])
80 {
81 struct Client *target_p;
82 const char *inpath = client_p->name;
83 char *user;
84 char *reason;
85 char def_reason[] = "No reason";
86
87 user = parv[1];
88 reason = parv[2]; /* Either defined or NULL (parc >= 2!!) */
89
90 if (*user == '\0')
91 {
92 sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS),
93 me.name, source_p->name, "KILL");
94 return;
95 }
96
97 if (IsDigit(*user)) /* opers shouldn't be trying uids anyway ;-) */
98 return;
99
100 if (!IsOperK(source_p) && !IsOperGlobalKill(source_p))
101 {
102 sendto_one(source_p, form_str(ERR_NOPRIVILEGES),
103 me.name, source_p->name);
104 return;
105 }
106
107 if (!EmptyString(reason))
108 {
109 if (strlen(reason) > (size_t)KILLLEN)
110 reason[KILLLEN] = '\0';
111 }
112 else
113 reason = def_reason;
114
115 if ((target_p = find_client(user)) == NULL)
116 {
117 /* If the user has recently changed nick, automatically
118 * rewrite the KILL for this new nickname--this keeps
119 * servers in synch when nick change and kill collide
120 */
121 if ((target_p = get_history(user,
122 (time_t)ConfigFileEntry.kill_chase_time_limit))
123 == NULL)
124 {
125 sendto_one(source_p, form_str(ERR_NOSUCHNICK),
126 me.name, source_p->name, user);
127 return;
128 }
129
130 sendto_one(source_p, ":%s NOTICE %s :KILL changed from %s to %s",
131 me.name, source_p->name, user, target_p->name);
132 }
133
134 if (IsServer(target_p) || IsMe(target_p))
135 {
136 sendto_one(source_p, form_str(ERR_CANTKILLSERVER),
137 me.name, source_p->name);
138 return;
139 }
140
141 if (!MyConnect(target_p) && (!IsOperGlobalKill(source_p)))
142 {
143 sendto_one(source_p, ":%s NOTICE %s :Nick %s isnt on your server",
144 me.name, source_p->name, target_p->name);
145 return;
146 }
147
148 if (MyConnect(target_p))
149 sendto_one(target_p, ":%s!%s@%s KILL %s :%s",
150 source_p->name, source_p->username, source_p->host,
151 target_p->name, reason);
152
153 /* Do not change the format of this message. There's no point in changing messages
154 * that have been around for ever, for no reason.. */
155 sendto_realops_flags(UMODE_ALL, L_ALL,
156 "Received KILL message for %s. From %s Path: %s (%s)",
157 target_p->name, source_p->name, me.name, reason);
158
159 ilog(L_INFO, "KILL From %s For %s Path %s (%s)",
160 source_p->name, target_p->name, me.name, reason);
161 log_oper_action(LOG_KILL_TYPE, source_p, "%s %s\n",
162 me.name, reason);
163
164 /*
165 ** And pass on the message to other servers. Note, that if KILL
166 ** was changed, the message has to be sent to all links, also
167 ** back.
168 ** Suicide kills are NOT passed on --SRB
169 */
170 if (!MyConnect(target_p))
171 {
172 relay_kill(client_p, source_p, target_p, inpath, reason);
173 /*
174 ** Set FLAGS_KILLED. This prevents exit_one_client from sending
175 ** the unnecessary QUIT for this. (This flag should never be
176 ** set in any other place)
177 */
178 SetKilled(target_p);
179 }
180
181 ircsprintf(buf, "Killed (%s (%s))", source_p->name, reason);
182 exit_client(target_p, source_p, buf);
183 }
184
185 /* ms_kill()
186 * parv[0] = sender prefix
187 * parv[1] = kill victim
188 * parv[2] = kill path and reason
189 */
190 static void
191 ms_kill(struct Client *client_p, struct Client *source_p,
192 int parc, char *parv[])
193 {
194 struct Client *target_p;
195 char *user;
196 char *reason;
197 const char *path;
198 char def_reason[] = "No reason";
199
200 if (*parv[1] == '\0')
201 {
202 sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS),
203 me.name, source_p->name, "KILL");
204 return;
205 }
206
207 user = parv[1];
208
209 if (EmptyString(parv[2]))
210 {
211 reason = def_reason;
212
213 /* hyb6 takes the nick of the killer from the path *sigh* --fl_ */
214 path = source_p->name;
215 }
216 else
217 {
218 reason = strchr(parv[2], ' ');
219
220 if (reason != NULL)
221 *reason++ = '\0';
222 else
223 reason = def_reason;
224
225 path = parv[2];
226 }
227
228 if ((target_p = find_person(client_p, user)) == NULL)
229 {
230 /* If the user has recently changed nick, but only if its
231 * not an uid, automatically rewrite the KILL for this new nickname.
232 * --this keeps servers in synch when nick change and kill collide
233 */
234 if(IsDigit(*user)) /* Somehow an uid was not found in the hash ! */
235 return;
236 if((target_p = get_history(user,
237 (time_t)ConfigFileEntry.kill_chase_time_limit))
238 == NULL)
239 {
240 sendto_one(source_p, form_str(ERR_NOSUCHNICK),
241 me.name, source_p->name, user);
242 return;
243 }
244 sendto_one(source_p,":%s NOTICE %s :KILL changed from %s to %s",
245 me.name, source_p->name, user, target_p->name);
246 }
247
248 if (IsServer(target_p) || IsMe(target_p))
249 {
250 sendto_one(source_p, form_str(ERR_CANTKILLSERVER),
251 me.name, source_p->name);
252 return;
253 }
254
255 if (MyConnect(target_p))
256 {
257 if (IsServer(source_p))
258 {
259 /* dont send clients kills from a hidden server */
260 if ((IsHidden(source_p) || ConfigServerHide.hide_servers) && !IsOper(target_p))
261 sendto_one(target_p, ":%s KILL %s :%s",
262 me.name, target_p->name, reason);
263 else
264 sendto_one(target_p, ":%s KILL %s :%s",
265 source_p->name, target_p->name, reason);
266 }
267 else
268 sendto_one(target_p, ":%s!%s@%s KILL %s :%s",
269 source_p->name, source_p->username, source_p->host,
270 target_p->name, reason);
271 }
272
273 /* Be warned, this message must be From %s, or it confuses clients
274 * so dont change it to From: or the case or anything! -- fl -- db */
275 /* path must contain at least 2 !'s, or bitchx falsely declares it
276 * local --fl
277 */
278 if (IsOper(source_p)) /* send it normally */
279 {
280 sendto_realops_flags(UMODE_ALL, L_ALL,
281 "Received KILL message for %s. From %s Path: %s!%s!%s!%s %s",
282 target_p->name, source_p->name, source_p->servptr->name,
283 source_p->host, source_p->username, source_p->name, reason);
284 }
285 else
286 {
287 sendto_realops_flags(UMODE_SKILL, L_ALL,
288 "Received KILL message for %s. From %s %s",
289 target_p->name, source_p->name, reason);
290 }
291
292 ilog(L_INFO,"KILL From %s For %s Path %s %s",
293 source_p->name, target_p->name, source_p->name, reason);
294
295 relay_kill(client_p, source_p, target_p, path, reason);
296 SetKilled(target_p);
297
298 /* reason comes supplied with its own ()'s */
299 if (IsServer(source_p) && (IsHidden(source_p) || ConfigServerHide.hide_servers))
300 ircsprintf(buf, "Killed (%s %s)", me.name, reason);
301 else
302 ircsprintf(buf, "Killed (%s %s)", source_p->name, reason);
303
304 exit_client(target_p, source_p, buf);
305 }
306
307 static void
308 relay_kill(struct Client *one, struct Client *source_p,
309 struct Client *target_p, const char *inpath, const char *reason)
310 {
311 dlink_node *ptr;
312 struct Client *client_p;
313 const char *from, *to;
314
315 DLINK_FOREACH(ptr, serv_list.head)
316 {
317 client_p = ptr->data;
318
319 if (client_p == NULL || client_p == one)
320 continue;
321
322 /* use UID if possible */
323 from = ID_or_name(source_p, client_p);
324 to = ID_or_name(target_p, client_p);
325
326 if (MyClient(source_p))
327 {
328 sendto_one(client_p, ":%s KILL %s :%s!%s!%s!%s (%s)",
329 from, to,
330 me.name, source_p->host, source_p->username,
331 source_p->name, reason);
332 }
333 else
334 {
335 sendto_one(client_p, ":%s KILL %s :%s %s",
336 from, to, inpath, reason);
337 }
338 }
339 }
340

Properties

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

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