ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/branches/8.2.x/modules/core/m_kill.c
Revision: 3171
Committed: Sun Mar 16 11:51:48 2014 UTC (10 years, 1 month ago) by michael
Content type: text/x-csrc
Original Path: ircd-hybrid/trunk/modules/core/m_kill.c
File size: 9685 byte(s)
Log Message:
- Incorporate Adam's exit_client/quit storm cleanups
  Note: QS is mandatory now

File Contents

# Content
1 /*
2 * ircd-hybrid: an advanced, lightweight Internet Relay Chat Daemon (ircd)
3 *
4 * Copyright (c) 1997-2014 ircd-hybrid development team
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19 * USA
20 */
21
22 /*! \file m_kill.c
23 * \brief Includes required functions for processing the KILL command.
24 * \version $Id$
25 */
26
27 #include "stdinc.h"
28 #include "list.h"
29 #include "client.h"
30 #include "hash.h"
31 #include "ircd.h"
32 #include "numeric.h"
33 #include "log.h"
34 #include "s_serv.h"
35 #include "conf.h"
36 #include "send.h"
37 #include "whowas.h"
38 #include "irc_string.h"
39 #include "parse.h"
40 #include "modules.h"
41
42
43 static char buf[IRCD_BUFSIZE];
44
45 static void
46 relay_kill(struct Client *source_p,
47 struct Client *target_p, const char *inpath,
48 const char *reason)
49 {
50 dlink_node *ptr = NULL;
51
52 DLINK_FOREACH(ptr, serv_list.head)
53 {
54 struct Client *client_p = ptr->data;
55
56 if (client_p == source_p->from)
57 continue;
58
59 if (MyClient(source_p))
60 sendto_one(client_p, ":%s KILL %s :%s!%s!%s!%s (%s)",
61 ID_or_name(source_p, client_p),
62 ID_or_name(target_p, client_p),
63 me.name, source_p->host, source_p->username,
64 source_p->name, reason);
65 else
66 sendto_one(client_p, ":%s KILL %s :%s %s",
67 ID_or_name(source_p, client_p),
68 ID_or_name(target_p, client_p), inpath, reason);
69 }
70 }
71
72 /* mo_kill()
73 * parv[0] = command
74 * parv[1] = kill victim
75 * parv[2] = kill path
76 */
77 static int
78 mo_kill(struct Client *source_p, int parc, char *parv[])
79 {
80 struct Client *target_p;
81 char *user;
82 char *reason;
83 char def_reason[] = CONF_NOREASON;
84
85 user = parv[1];
86 reason = parv[2]; /* Either defined or NULL (parc >= 2!!) */
87
88 if (*user == '\0')
89 {
90 sendto_one_numeric(source_p, &me, ERR_NEEDMOREPARAMS, "KILL");
91 return 0;
92 }
93
94 if (!EmptyString(reason))
95 {
96 if (strlen(reason) > (size_t)KILLLEN)
97 reason[KILLLEN] = '\0';
98 }
99 else
100 reason = def_reason;
101
102 if ((target_p = hash_find_client(user)) == NULL)
103 {
104 /*
105 * If the user has recently changed nick, automatically
106 * rewrite the KILL for this new nickname--this keeps
107 * servers in synch when nick change and kill collide
108 */
109 if ((target_p = whowas_get_history(user,
110 (time_t)ConfigFileEntry.kill_chase_time_limit))
111 == NULL)
112 {
113 sendto_one_numeric(source_p, &me, ERR_NOSUCHNICK, user);
114 return 0;
115 }
116
117 sendto_one_notice(source_p, &me, ":KILL changed from %s to %s",
118 user, target_p->name);
119 }
120
121 if (!MyConnect(target_p) && !HasOFlag(source_p, OPER_FLAG_KILL_REMOTE))
122 {
123 sendto_one_numeric(source_p, &me, ERR_NOPRIVS, "kill:remote");
124 return 0;
125 }
126
127 if (MyConnect(target_p) && !HasOFlag(source_p, OPER_FLAG_KILL))
128 {
129 sendto_one_numeric(source_p, &me, ERR_NOPRIVS, "kill");
130 return 0;
131 }
132
133 if (IsServer(target_p) || IsMe(target_p))
134 {
135 sendto_one_numeric(source_p, &me, ERR_CANTKILLSERVER);
136 return 0;
137 }
138
139 if (MyConnect(target_p))
140 sendto_one(target_p, ":%s!%s@%s KILL %s :%s",
141 source_p->name, source_p->username, source_p->host,
142 target_p->name, reason);
143
144 /*
145 * Do not change the format of this message. There's no point in changing messages
146 * that have been around for ever, for no reason..
147 */
148 sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
149 "Received KILL message for %s!%s@%s[%s/%s]. From %s Path: %s (%s)",
150 target_p->name, target_p->username, target_p->host,
151 target_p->servptr->name,
152 target_p->servptr->id[0] ? target_p->servptr->id : "<>",
153 source_p->name, me.name, reason);
154
155 ilog(LOG_TYPE_KILL, "KILL From %s For %s Path %s (%s)",
156 source_p->name, target_p->name, me.name, reason);
157
158 /*
159 * And pass on the message to other servers. Note, that if KILL
160 * was changed, the message has to be sent to all links, also
161 * back.
162 * Suicide kills are NOT passed on --SRB
163 */
164 if (!MyConnect(target_p))
165 {
166 relay_kill(source_p, target_p, source_p->from->name, reason);
167 /*
168 * Set FLAGS_KILLED. This prevents exit_one_client from sending
169 * the unnecessary QUIT for this. (This flag should never be
170 * set in any other place)
171 */
172 AddFlag(target_p, FLAGS_KILLED);
173 }
174
175 snprintf(buf, sizeof(buf), "Killed (%s (%s))", source_p->name, reason);
176 exit_client(target_p, buf);
177 return 0;
178 }
179
180 /* ms_kill()
181 * parv[0] = command
182 * parv[1] = kill victim
183 * parv[2] = kill path and reason
184 */
185 static int
186 ms_kill(struct Client *source_p, int parc, char *parv[])
187 {
188 struct Client *target_p;
189 char *user;
190 char *reason;
191 const char *path;
192 char def_reason[] = CONF_NOREASON;
193
194 if (EmptyString(parv[1]))
195 {
196 sendto_one_numeric(source_p, &me, ERR_NEEDMOREPARAMS, "KILL");
197 return 0;
198 }
199
200 user = parv[1];
201
202 if (EmptyString(parv[2]))
203 {
204 reason = def_reason;
205
206 /* hyb6 takes the nick of the killer from the path *sigh* --fl_ */
207 path = source_p->name;
208 }
209 else
210 {
211 reason = strchr(parv[2], ' ');
212
213 if (reason != NULL)
214 *reason++ = '\0';
215 else
216 reason = def_reason;
217
218 path = parv[2];
219 }
220
221 if ((target_p = find_person(source_p, user)) == NULL)
222 {
223 /*
224 * If the user has recently changed nick, but only if its
225 * not an uid, automatically rewrite the KILL for this new nickname.
226 * --this keeps servers in synch when nick change and kill collide
227 */
228 if (IsDigit(*user)) /* Somehow an uid was not found in the hash ! */
229 return 0;
230 if ((target_p = whowas_get_history(user,
231 (time_t)ConfigFileEntry.kill_chase_time_limit))
232 == NULL)
233 {
234 sendto_one_numeric(source_p, &me, ERR_NOSUCHNICK, user);
235 return 0;
236 }
237
238 sendto_one_notice(source_p, &me, ":KILL changed from %s to %s",
239 user, target_p->name);
240 }
241
242 if (IsServer(target_p) || IsMe(target_p))
243 {
244 sendto_one_numeric(source_p, &me, ERR_CANTKILLSERVER);
245 return 0;
246 }
247
248 if (MyConnect(target_p))
249 {
250 if (IsServer(source_p))
251 {
252 /* dont send clients kills from a hidden server */
253 if ((IsHidden(source_p) || ConfigServerHide.hide_servers) && !HasUMode(target_p, UMODE_OPER))
254 sendto_one(target_p, ":%s KILL %s :%s",
255 me.name, target_p->name, reason);
256 else
257 sendto_one(target_p, ":%s KILL %s :%s",
258 source_p->name, target_p->name, reason);
259 }
260 else
261 sendto_one(target_p, ":%s!%s@%s KILL %s :%s",
262 source_p->name, source_p->username, source_p->host,
263 target_p->name, reason);
264 }
265
266 /*
267 * Be warned, this message must be From %s, or it confuses clients
268 * so dont change it to From: or the case or anything! -- fl -- db
269 */
270 /*
271 * path must contain at least 2 !'s, or bitchx falsely declares it
272 * local --fl
273 */
274 if (HasUMode(source_p, UMODE_OPER)) /* send it normally */
275 sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
276 "Received KILL message for %s!%s@%s[%s/%s]. From %s Path: %s!%s!%s!%s %s",
277 target_p->name, target_p->username, target_p->host,
278 target_p->servptr->name,
279 target_p->servptr->id[0] ? target_p->servptr->id : "<>", source_p->name,
280 source_p->servptr->name, source_p->host, source_p->username,
281 source_p->name, reason);
282 else
283 sendto_realops_flags(UMODE_SKILL, L_ALL, SEND_NOTICE,
284 "Received KILL message for %s!%s@%s[%s/%s]. From %s %s",
285 target_p->name, target_p->username, target_p->host,
286 target_p->servptr->name,
287 target_p->servptr->id[0] ? target_p->servptr->id : "<>",
288 source_p->name, reason);
289
290 ilog(LOG_TYPE_KILL, "KILL From %s For %s Path %s %s",
291 source_p->name, target_p->name, source_p->name, reason);
292
293 relay_kill(source_p, target_p, path, reason);
294 AddFlag(target_p, FLAGS_KILLED);
295
296 /* reason comes supplied with its own ()'s */
297 if (IsServer(source_p) && (IsHidden(source_p) || ConfigServerHide.hide_servers))
298 snprintf(buf, sizeof(buf), "Killed (%s %s)", me.name, reason);
299 else
300 snprintf(buf, sizeof(buf), "Killed (%s %s)", source_p->name, reason);
301
302 exit_client(target_p, buf);
303 return 0;
304 }
305
306
307 static struct Message kill_msgtab =
308 {
309 "KILL", 0, 0, 2, MAXPARA, MFLG_SLOW, 0,
310 { m_unregistered, m_not_oper, ms_kill, m_ignore, mo_kill, m_ignore }
311 };
312
313 static void
314 module_init(void)
315 {
316 mod_add_cmd(&kill_msgtab);
317 }
318
319 static void
320 module_exit(void)
321 {
322 mod_del_cmd(&kill_msgtab);
323 }
324
325 struct module module_entry =
326 {
327 .node = { NULL, NULL, NULL },
328 .name = NULL,
329 .version = "$Revision$",
330 .handle = NULL,
331 .modinit = module_init,
332 .modexit = module_exit,
333 .flags = MODULE_FLAG_CORE
334 };

Properties

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