#include "client.h"
#include "hash.h"
#include "ircd.h"
+#include "ircd_features.h"
#include "ircd_log.h"
-#include "ircd_policy.h"
#include "ircd_reply.h"
#include "ircd_snprintf.h"
#include "ircd_string.h"
#include "send.h"
#include "whowas.h"
-#include <assert.h>
+/* #include <assert.h> -- Now using assert in ircd_log.h */
#include <string.h>
/*
- * ms_kill - server message handler template
+ * do_kill - Performs the generic work involved in killing a client
+ *
+ */
+static int do_kill(struct Client* cptr, struct Client* sptr,
+ struct Client* victim, char* inpath, char* path, char* msg)
+{
+ assert(0 != cptr);
+ assert(0 != sptr);
+ assert(!IsServer(victim));
+
+ /*
+ * Notify all *local* opers about the KILL (this includes the one
+ * originating the kill, if from this server--the special numeric
+ * reply message is not generated anymore).
+ *
+ * Note: "victim->name" is used instead of "user" because we may
+ * have changed the target because of the nickname change.
+ */
+ sendto_opmask_butone(0, IsServer(sptr) ? SNO_SERVKILL : SNO_OPERKILL,
+ "Received KILL message for %s from %s Path: %s!%s %s",
+ get_client_name(victim, SHOW_IP), cli_name(sptr),
+ inpath, path, msg);
+ log_write_kill(victim, sptr, inpath, path, msg);
+
+ /*
+ * And pass on the message to other servers. Note, that if KILL
+ * was changed, the message has to be sent to all links, also
+ * back.
+ * Client suicide kills are NOT passed on --SRB
+ */
+ if (IsServer(cptr) || !MyConnect(victim)) {
+ sendcmdto_serv_butone(sptr, CMD_KILL, cptr, "%C :%s!%s %s", victim,
+ inpath, path, msg);
+
+ /*
+ * Set FLAG_KILLED. This prevents exit_one_client from sending
+ * the unnecessary QUIT for this. (This flag should never be
+ * set in any other place)
+ */
+ SetFlag(victim, FLAG_KILLED);
+ }
+
+ /*
+ * Tell the victim she/he has been zapped, but *only* if
+ * the victim is on current server--no sense in sending the
+ * notification chasing the above kill, it won't get far
+ * anyway (as this user don't exist there any more either)
+ * In accordance with the new hiding rules, the victim
+ * always sees the kill as coming from me.
+ */
+ if (MyConnect(victim))
+ sendcmdto_one(feature_bool(FEAT_HIS_KILLWHO) ? &his : sptr, CMD_KILL,
+ victim, "%C :%s %s", victim, feature_bool(FEAT_HIS_KILLWHO)
+ ? feature_str(FEAT_HIS_SERVERNAME) : cli_name(sptr), msg);
+ return exit_client_msg(cptr, victim, feature_bool(FEAT_HIS_KILLWHO)
+ ? &me : sptr, "Killed (%s %s)",
+ feature_bool(FEAT_HIS_KILLWHO) ?
+ feature_str(FEAT_HIS_SERVERNAME) : cli_name(sptr),
+ msg);
+}
+
+/*
+ * ms_kill - server message handler
*
* NOTE: IsServer(cptr) == true;
*
int ms_kill(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
{
struct Client* victim;
- const char* inpath;
- char* user;
char* path;
- char* comment;
- char buf[BUFSIZE];
+ char* msg;
assert(0 != cptr);
assert(0 != sptr);
return need_more_params(sptr, "KILL");
}
- user = parv[1];
path = parv[parc - 1]; /* Either defined or NULL (parc >= 3) */
+ if (!(msg = strchr(path, ' '))) /* Extract out the message */
+ msg = "(No reason supplied)";
+ else
+ *(msg++) = '\0'; /* Remove first character (space) and terminate path */
+
if (!(victim = findNUser(parv[1]))) {
if (IsUser(sptr))
sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :KILL target disconnected "
return 0;
}
- /*
- * Notify all *local* opers about the KILL (this includes the one
- * originating the kill, if from this server--the special numeric
- * reply message is not generated anymore).
- *
- * Note: "victim->name" is used instead of "user" because we may
- * have changed the target because of the nickname change.
- */
- inpath = cli_name(cptr);
-
- sendto_opmask_butone(0, IsServer(sptr) ? SNO_SERVKILL : SNO_OPERKILL,
- "Received KILL message for %s. From %s Path: %C!%s",
- get_client_name(victim,SHOW_IP), parv[0], cptr, path);
-
- log_write_kill(victim, sptr, cli_name(cptr), path);
- /*
- * And pass on the message to other servers. Note, that if KILL
- * was changed, the message has to be sent to all links, also
- * back.
- */
- sendcmdto_serv_butone(sptr, CMD_KILL, cptr, "%C :%s!%s", victim, cli_name(cptr),
- path);
/*
* We *can* have crossed a NICK with this numeric... --Run
*
* Bounce the kill back to the originator, if the client can't be found
* by the next hop (short lag) the bounce won't propagate further.
*/
- if (MyConnect(victim))
- sendcmdto_one(&me, CMD_KILL, cptr, "%C :%s!%s (Ghost 5 Numeric Collided)",
- victim, cli_name(cptr), path);
- /*
- * Set FLAGS_KILLED. This prevents exit_one_client from sending
- * the unnecessary QUIT for this. (This flag should never be
- * set in any other place)
- */
- cli_flags(victim) |= FLAGS_KILLED;
-
- /*
- * the first space in path will be at the end of the
- * opers name:
- * bla.bla.bla!host.net.dom!opername (comment)
- */
- if (!(comment = strchr(path, ' ')))
- comment = " (No reason given)";
- /*
- * Tell the victim she/he has been zapped, but *only* if
- * the victim is on current server--no sense in sending the
- * notification chasing the above kill, it won't get far
- * anyway (as this user don't exist there any more either)
- */
- if (MyConnect(victim))
- sendcmdto_one(IsServer(sptr) ? &me : sptr, CMD_KILL, victim,
- "%C :%s%s", victim, IsServer(sptr) ? HEAD_IN_SAND_SERVERNAME :
- cli_name(sptr), comment);
-
- ircd_snprintf(0, buf, sizeof(buf), "Killed (%s%s)", IsServer(sptr) ?
- HEAD_IN_SAND_SERVERNAME : cli_name(sptr), comment);
-
- return exit_client(cptr, victim, sptr, buf);
+ if (MyConnect(victim)) {
+ sendcmdto_one(&me, CMD_KILL, cptr, "%C :%s (Ghost 5 Numeric Collided)",
+ victim, path);
+ }
+ return do_kill(cptr, sptr, victim, cli_name(cptr), path, msg);
}
/*
- * mo_kill - oper message handler template
+ * mo_kill - oper message handler
*
* NOTE: IsPrivileged(sptr), IsAnOper(sptr) == true
* IsServer(cptr), IsServer(sptr) == false
int mo_kill(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
{
struct Client* victim;
- const char* inpath;
char* user;
- char* path;
- char* comment;
- char buf[BUFSIZE];
+ char msg[TOPICLEN + 3]; /* (, ), and \0 */
assert(0 != cptr);
assert(0 != sptr);
return need_more_params(sptr, "KILL");
user = parv[1];
+ ircd_snprintf(0, msg, sizeof(msg), "(%.*s)", TOPICLEN, parv[parc - 1]);
+
if (!(victim = FindClient(user))) {
/*
- * If the user has recently changed nick, we automaticly
+ * If the user has recently changed nick, we automatically
* rewrite the KILL for this new nickname--this keeps
* servers in synch when nick change and kill collide
*/
if (!MyConnect(victim) && !HasPriv(sptr, PRIV_KILL)) {
- sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :Nick %s isnt on your server",
+ sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :Nick %s isn't on your server",
sptr, cli_name(victim));
return 0;
}
-
- /*
- * The kill originates from this server, initialize path.
- * (In which case the 'path' may contain user suplied
- * explanation ...or some nasty comment, sigh... >;-)
- *
- * ...!operhost!oper
- * ...!operhost!oper (comment)
- */
-
- comment = parv[parc - 1]; /* Either defined or NULL (parc >= 3) */
-
- if (strlen(comment) > TOPICLEN)
- comment[TOPICLEN] = '\0';
-
- inpath = cli_user(sptr)->host;
-
- ircd_snprintf(0, buf, sizeof(buf), "%s (%s)", cli_name(cptr), comment);
- path = buf;
-
- /*
- * Notify all *local* opers about the KILL (this includes the one
- * originating the kill, if from this server--the special numeric
- * reply message is not generated anymore).
- *
- * Note: "victim->name" is used instead of "user" because we may
- * have changed the target because of the nickname change.
- */
- sendto_opmask_butone(0, SNO_OPERKILL,
- "Received KILL message for %s. From %s Path: %s!%s",
- get_client_name(victim,SHOW_IP), parv[0], inpath, path);
-
- log_write_kill(victim, sptr, inpath, path);
- /*
- * And pass on the message to other servers. Note, that if KILL
- * was changed, the message has to be sent to all links, also
- * back.
- * Suicide kills are NOT passed on --SRB
- */
- if (!MyConnect(victim)) {
- sendcmdto_serv_butone(sptr, CMD_KILL, cptr, "%C :%s!%s", victim, inpath,
- path);
-
- /*
- * Set FLAGS_KILLED. This prevents exit_one_client from sending
- * the unnecessary QUIT for this. (This flag should never be
- * set in any other place)
- */
- cli_flags(victim) |= FLAGS_KILLED;
-
- }
- else {
- /*
- * Tell the victim she/he has been zapped, but *only* if
- * the victim is on current server--no sense in sending the
- * notification chasing the above kill, it won't get far
- * anyway (as this user don't exist there any more either)
- */
- sendcmdto_one(sptr, CMD_KILL, victim, "%C :%s", victim, path);
- }
-
- ircd_snprintf(0, buf, sizeof(buf), "Killed (%s (%s))", cli_name(sptr),
- comment);
-
- return exit_client(cptr, victim, sptr, buf);
+ return do_kill(cptr, sptr, victim, cli_user(sptr)->host, cli_name(sptr),
+ msg);
}