diff --git a/extensions/Makefile.in b/extensions/Makefile.in index 7606d1f5..2609f59d 100644 --- a/extensions/Makefile.in +++ b/extensions/Makefile.in @@ -69,6 +69,7 @@ SRCS = \ m_findforwards.c \ m_identify.c \ m_mkpasswd.c \ + m_nokillservices.c \ m_ojoin.c \ m_olist.c \ m_okick.c \ diff --git a/extensions/m_nokillservices.c b/extensions/m_nokillservices.c new file mode 100644 index 00000000..3446ec83 --- /dev/null +++ b/extensions/m_nokillservices.c @@ -0,0 +1,50 @@ +/* + * Stop services kills + * Well, it won't stop them all, unless this is loaded on all servers. + * + * Copyright (C) 2013 Elizabeth Myers. All rights reserved. + * Licensed under the WTFPLv2 + */ + +#include "stdinc.h" +#include "modules.h" +#include "hook.h" +#include "client.h" +#include "ircd.h" +#include "send.h" +#include "hash.h" +#include "s_conf.h" +#include "s_user.h" +#include "s_serv.h" +#include "numeric.h" +#include "privilege.h" +#include "s_newconf.h" + +static void block_services_kill(void *data); + +mapi_hfn_list_av1 m_nokillservices_hfnlist[] = { + { "can_kill", (hookfn) block_services_kill }, + { NULL, NULL } +}; + +static void +block_services_kill(void *vdata) +{ + hook_data_client_approval *data = (hook_data_client_approval *) vdata; + + if (!MyClient(data->client)) + return; + + if (!data->approved) + return; + + if (IsService(data->target)) + { + sendto_one_notice(data->client, ":You may not kill network service %s", + data->target->name); + data->approved = 0; + } +} + +DECLARE_MODULE_AV1(m_nokillservices, NULL, NULL, NULL, NULL, + m_nokillservices_hfnlist, "Charybdis 3.4+"); diff --git a/include/hook.h b/include/hook.h index 08ec5380..88f6cc73 100644 --- a/include/hook.h +++ b/include/hook.h @@ -87,6 +87,7 @@ typedef struct typedef struct { struct Client *client; + struct Client *target; int approved; } hook_data_client_approval; diff --git a/modules/core/m_kill.c b/modules/core/m_kill.c index 17042fcc..a058ce82 100644 --- a/modules/core/m_kill.c +++ b/modules/core/m_kill.c @@ -40,6 +40,7 @@ #include "modules.h" #include "s_newconf.h" +static int h_can_kill; static char buf[BUFSIZE]; static int ms_kill(struct Client *, struct Client *, int, const char **); @@ -54,7 +55,12 @@ struct Message kill_msgtab = { 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_AV1(kill, NULL, NULL, kill_clist, kill_hlist, NULL, "$Revision: 3408 $"); /* ** mo_kill @@ -68,6 +74,7 @@ mo_kill(struct Client *client_p, struct Client *source_p, int parc, const char * const char *inpath = client_p->name; const char *user; const char *reason; + hook_data_client_approval moduledata; user = parv[1]; @@ -115,6 +122,16 @@ mo_kill(struct Client *client_p, struct Client *source_p, int parc, const char * 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) + /* Let the calleee send a message */ + return 0; + if(MyConnect(target_p)) sendto_one(target_p, ":%s!%s@%s KILL %s :%s", source_p->name, source_p->username, source_p->host,