]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/cmd_kill.cpp
Patch fixing (almost) remote kill server notices, by just passing KILL onto cmd_kill...
[user/henk/code/inspircd.git] / src / cmd_kill.cpp
1 /*       +------------------------------------+
2  *       | Inspire Internet Relay Chat Daemon |
3  *       +------------------------------------+
4  *
5  *  InspIRCd: (C) 2002-2007 InspIRCd Development Team
6  * See: http://www.inspircd.org/wiki/index.php/Credits
7  *
8  * This program is free but copyrighted software; see
9  *            the file COPYING for details.
10  *
11  * ---------------------------------------------------
12  */
13
14 #include "inspircd.h"
15 #include "configreader.h"
16 #include "users.h"
17 #include "modules.h"
18 #include "wildcard.h"
19 #include "commands/cmd_kill.h"
20
21 extern "C" DllExport command_t* init_command(InspIRCd* Instance)
22 {
23         return new cmd_kill(Instance);
24 }
25
26 /** Handle /KILL
27  */
28 CmdResult cmd_kill::Handle (const char** parameters, int pcnt, userrec *user)
29 {
30         /* Allow comma seperated lists of users for /KILL (thanks w00t) */
31         if (ServerInstance->Parser->LoopCall(user, this, parameters, pcnt, 0))
32                 return CMD_SUCCESS;
33
34         userrec *u = ServerInstance->FindNick(parameters[0]);
35         char killreason[MAXBUF];
36         char killoperreason[MAXBUF];
37         int MOD_RESULT = 0;
38
39         if (u)
40         {
41                 /*
42                  * Here, we need to decide how to munge kill messages. Whether to hide killer, what to show opers, etc.
43                  * We only do this when the command is being issued LOCALLY, for remote KILL, we just copy the message we got.
44                  *
45                  * This conditional is so that we only append the "Killed (" prefix ONCE. If killer is remote, then the kill
46                  * just gets processed and passed on, otherwise, if they are local, it gets prefixed. Makes sense :-) -- w00t
47                  */
48                 if (IS_LOCAL(user))
49                 {
50                         /*
51                          * Moved this event inside the IS_LOCAL check also, we don't want half the network killing a user
52                          * and the other half not. This would be a bad thing. ;p -- w00t
53                          */
54                         FOREACH_RESULT(I_OnKill, OnKill(user, u, parameters[1]));
55
56                         if (MOD_RESULT)
57                                 return CMD_FAILURE;
58
59                         if (*ServerInstance->Config->HideKillsServer)
60                         {
61                                 // hidekills is on, use it
62                                 snprintf(killreason, MAXQUIT, "Killed (%s (%s))", ServerInstance->Config->HideKillsServer, parameters[1]);
63                         }
64                         else
65                         {
66                                 // hidekills is off, do nothing
67                                 snprintf(killreason, MAXQUIT, "Killed (%s (%s))", user->nick, parameters[1]);
68                         }
69
70                         // opers are lucky ducks, they always see the real reason
71                         snprintf(killoperreason, MAXQUIT, "Killed (%s (%s))", user->nick, parameters[1]);
72                 }
73                 else
74                 {
75                         snprintf(killreason, MAXQUIT, "%s", parameters[1]);
76                         /*
77                          * XXX - yes, this means opers will probably see a censored kill remotely. this needs fixing.
78                          * maybe a version of QuitUser that doesn't take nor propegate an oper reason? -- w00t
79                          */
80                         snprintf(killoperreason, MAXQUIT, "%s", parameters[1]);
81                 }
82
83                 /*
84                  * Now we need to decide whether or not to send a local or remote snotice. Currently this checking is a little flawed.
85                  * No time to fix it right now, so left a note. -- w00t
86                  */
87                 if (!IS_LOCAL(u))
88                 {
89                         // remote kill
90                         ServerInstance->SNO->WriteToSnoMask('k',"Remote kill by %s: %s!%s@%s (%s)", user->nick, u->nick, u->ident, u->host, parameters[1]);
91                         FOREACH_MOD(I_OnRemoteKill, OnRemoteKill(user, u, killreason));
92                 }
93                 else
94                 {
95                         // local kill
96                         /*
97                          * XXX - this isn't entirely correct, servers A - B - C, oper on A, client on C. Oper kills client, A and B will get remote kill
98                          * snotices, C will get a local kill snotice. this isn't accurate, and needs fixing at some stage. -- w00t
99                          */
100                         ServerInstance->SNO->WriteToSnoMask('k',"Local Kill by %s: %s!%s@%s (%s)", user->nick, u->nick, u->ident, u->host, parameters[1]);
101                         ServerInstance->Log(DEFAULT,"LOCAL KILL: %s :%s!%s!%s (%s)", u->nick, ServerInstance->Config->ServerName, user->dhost, user->nick, parameters[1]);
102                         user->WriteTo(u, "KILL %s :%s!%s!%s (%s)", *ServerInstance->Config->HideKillsServer ? ServerInstance->Config->HideKillsServer : u->nick,
103                                         ServerInstance->Config->ServerName, user->dhost, user->nick, parameters[1]);
104                 }
105
106                 // send the quit out
107                 userrec::QuitUser(ServerInstance, u, killreason, killoperreason);
108         }
109         else
110         {
111                 user->WriteServ( "401 %s %s :No such nick/channel", user->nick, parameters[0]);
112                 return CMD_FAILURE;
113         }
114
115         return CMD_SUCCESS;
116 }
117