]> jfr.im git - solanum.git/blobdiff - modules/core/m_kill.c
Unify oper:{global,local}_kill
[solanum.git] / modules / core / m_kill.c
index 5559dacbf2ca07a02b76d780ea859f8ef979c4fe..060310bc58ab5fbf9cd2a9dd62bcd8b051754ade 100644 (file)
@@ -20,8 +20,6 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
  *  USA
- *
- *  $Id: m_kill.c 3408 2007-04-14 20:58:56Z jilles $
  */
 
 #include "stdinc.h"
 #include "hash.h"              /* for find_client() */
 #include "ircd.h"
 #include "numeric.h"
-#include "sprintf_irc.h"
 #include "logger.h"
 #include "s_serv.h"
 #include "s_conf.h"
 #include "send.h"
 #include "whowas.h"
-#include "irc_string.h"
+#include "match.h"
 #include "msg.h"
 #include "parse.h"
 #include "modules.h"
 #include "s_newconf.h"
 
+static const char kill_desc[] = "Provides the KILL command to remove a user from the network";
+
+static int h_can_kill;
 static char buf[BUFSIZE];
 
-static int ms_kill(struct Client *, struct Client *, int, const char **);
-static int mo_kill(struct Client *, struct Client *, int, const char **);
+static void ms_kill(struct MsgBuf *, struct Client *, struct Client *, int, const char **);
+static void mo_kill(struct MsgBuf *, struct Client *, struct Client *, int, const char **);
 static void relay_kill(struct Client *, struct Client *, struct Client *,
                       const char *, const char *);
 
 struct Message kill_msgtab = {
-       "KILL", 0, 0, 0, MFLG_SLOW,
+       "KILL", 0, 0, 0, 0,
        {mg_unreg, mg_not_oper, {ms_kill, 2}, {ms_kill, 2}, mg_ignore, {mo_kill, 2}}
 };
 
 mapi_clist_av1 kill_clist[] = { &kill_msgtab, NULL };
 
-DECLARE_MODULE_AV1(kill, NULL, NULL, kill_clist, NULL, NULL, "$Revision: 3408 $");
+mapi_hlist_av1 kill_hlist[] = {
+       { "can_kill", &h_can_kill },
+       { NULL, NULL},
+};
+
+DECLARE_MODULE_AV2(kill, NULL, NULL, kill_clist, kill_hlist, NULL, NULL, NULL, kill_desc);
 
 /*
 ** mo_kill
-**      parv[0] = sender prefix
 **      parv[1] = kill victim
 **      parv[2] = kill path
 */
-static int
-mo_kill(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+static void
+mo_kill(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
 {
        struct Client *target_p;
        const char *inpath = client_p->name;
        const char *user;
        const char *reason;
+       hook_data_client_approval moduledata;
 
        user = parv[1];
 
-       if(!IsOperLocalKill(source_p))
+       if(!IsOperKill(source_p))
        {
-               sendto_one(source_p, form_str(ERR_NOPRIVS), me.name, source_p->name, "local_kill");
-               return 0;
+               sendto_one(source_p, form_str(ERR_NOPRIVS), me.name, source_p->name, "kill");
+               return;
        }
 
        if(!EmptyString(parv[2]))
@@ -97,25 +102,27 @@ mo_kill(struct Client *client_p, struct Client *source_p, int parc, const char *
                 ** rewrite the KILL for this new nickname--this keeps
                 ** servers in synch when nick change and kill collide
                 */
-               if((target_p = get_history(user, (long) KILLCHASETIMELIMIT)) == NULL)
+               if((target_p = whowas_get_history(user, (long) KILLCHASETIMELIMIT)) == NULL)
                {
                        if (strchr(user, '.'))
                                sendto_one_numeric(source_p, ERR_CANTKILLSERVER, form_str(ERR_CANTKILLSERVER));
                        else
                                sendto_one_numeric(source_p, ERR_NOSUCHNICK,
                                                   form_str(ERR_NOSUCHNICK), user);
-                       return 0;
+                       return;
                }
                sendto_one_notice(source_p, ":KILL changed from %s to %s", user, target_p->name);
        }
 
-       if(!MyConnect(target_p) && (!IsOperGlobalKill(source_p)))
-       {
-               sendto_one_notice(source_p, ":Nick %s is not on your server "
-                                           "and you do not have the global_kill flag",
-                               target_p->name);
-               return 0;
-       }
+       /* Last chance to stop the kill */
+       moduledata.client = source_p;
+       moduledata.target = target_p;
+       moduledata.approved = 1;
+       call_hook(h_can_kill, &moduledata);
+
+       if (moduledata.approved == 0)
+               /* The callee should have sent a message. */
+               return;
 
        if(MyConnect(target_p))
                sendto_one(target_p, ":%s!%s@%s KILL %s :%s",
@@ -126,8 +133,8 @@ mo_kill(struct Client *client_p, struct Client *source_p, int parc, const char *
         * that have been around for ever, for no reason.. */
        sendto_realops_snomask(SNO_GENERAL, L_ALL,
                             "Received KILL message for %s!%s@%s. From %s Path: %s (%s)",
-                            target_p->name, target_p->username, target_p->orighost, 
-                            parv[0], me.name, reason);
+                            target_p->name, target_p->username, target_p->orighost,
+                            source_p->name, me.name, reason);
 
        ilog(L_KILL, "%c %s %s!%s@%s %s %s",
             MyConnect(target_p) ? 'L' : 'G', get_oper_name(source_p),
@@ -150,28 +157,24 @@ mo_kill(struct Client *client_p, struct Client *source_p, int parc, const char *
                target_p->flags |= FLAGS_KILLED;
        }
 
-       rb_sprintf(buf, "Killed (%s (%s))", source_p->name, reason);
+       sprintf(buf, "Killed (%s (%s))", source_p->name, reason);
 
        exit_client(client_p, target_p, source_p, buf);
-
-       return 0;
 }
 
 /*
  * ms_kill
- *      parv[0] = sender prefix
  *      parv[1] = kill victim
  *      parv[2] = kill path and reason
  */
-static int
-ms_kill(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+static void
+ms_kill(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
 {
        struct Client *target_p;
        const char *user;
        const char *reason;
        char default_reason[] = "<No reason given>";
        const char *path;
-       int chasing = 0;
 
        *buf = '\0';
 
@@ -204,24 +207,23 @@ ms_kill(struct Client *client_p, struct Client *source_p, int parc, const char *
        if((target_p = find_person(user)) == NULL)
        {
                /*
-                * If the user has recently changed nick, but only if its 
+                * If the user has recently changed nick, but only if its
                 * not an uid, automatically rewrite the KILL for this new nickname.
                 * --this keeps servers in synch when nick change and kill collide
                 */
-               if(IsDigit(*user) || (!(target_p = get_history(user, (long) KILLCHASETIMELIMIT))))
+               if(IsDigit(*user) || (!(target_p = whowas_get_history(user, (long) KILLCHASETIMELIMIT))))
                {
                        sendto_one_numeric(source_p, ERR_NOSUCHNICK,
                                           form_str(ERR_NOSUCHNICK), IsDigit(*user) ? "*" : user);
-                       return 0;
+                       return;
                }
                sendto_one_notice(source_p, ":KILL changed from %s to %s", user, target_p->name);
-               chasing = 1;
        }
 
        if(IsServer(target_p) || IsMe(target_p))
        {
                sendto_one_numeric(source_p, ERR_CANTKILLSERVER, form_str(ERR_CANTKILLSERVER));
-               return 0;
+               return;
        }
 
        if(MyConnect(target_p))
@@ -246,7 +248,7 @@ ms_kill(struct Client *client_p, struct Client *source_p, int parc, const char *
        {
                sendto_realops_snomask(IsService(source_p) ? SNO_SKILL : SNO_GENERAL, L_ALL,
                                     "Received KILL message for %s!%s@%s. From %s Path: %s!%s!%s!%s %s",
-                                    target_p->name, target_p->username, target_p->orighost, parv[0], 
+                                    target_p->name, target_p->username, target_p->orighost, source_p->name,
                                     source_p->servptr->name, source_p->host, source_p->username,
                                     source_p->name, reason);
 
@@ -260,7 +262,7 @@ ms_kill(struct Client *client_p, struct Client *source_p, int parc, const char *
                sendto_realops_snomask(SNO_SKILL, L_ALL,
                                     "Received KILL message for %s!%s@%s. From %s %s",
                                     target_p->name, target_p->username, target_p->orighost,
-                                    parv[0], reason);
+                                    source_p->name, reason);
 
                ilog(L_KILL, "S %s %s!%s@%s %s %s",
                     source_p->name, target_p->name, target_p->username,
@@ -272,11 +274,9 @@ ms_kill(struct Client *client_p, struct Client *source_p, int parc, const char *
        /* FLAGS_KILLED prevents a quit being sent out */
        target_p->flags |= FLAGS_KILLED;
 
-       rb_sprintf(buf, "Killed (%s %s)", source_p->name, reason);
+       sprintf(buf, "Killed (%s %s)", source_p->name, reason);
 
        exit_client(client_p, target_p, source_p, buf);
-
-       return 0;
 }
 
 static void
@@ -288,11 +288,11 @@ relay_kill(struct Client *one, struct Client *source_p,
        char buffer[BUFSIZE];
 
        if(MyClient(source_p))
-               rb_snprintf(buffer, sizeof(buffer),
+               snprintf(buffer, sizeof(buffer),
                            "%s!%s!%s!%s (%s)",
                            me.name, source_p->host, source_p->username, source_p->name, reason);
        else
-               rb_snprintf(buffer, sizeof(buffer), "%s %s", inpath, reason);
+               snprintf(buffer, sizeof(buffer), "%s %s", inpath, reason);
 
        RB_DLINK_FOREACH(ptr, serv_list.head)
        {