diff --git a/doc/reference.conf b/doc/reference.conf index c4457a9d..2eb395fa 100755 --- a/doc/reference.conf +++ b/doc/reference.conf @@ -62,6 +62,7 @@ * Realname (gecos) bans (+b $r:mask) -- extb_realname.la * Server bans (+b $s:mask) -- extb_server.la * SSL bans (+b $z) -- extb_ssl.la + * Helpops system (umode +H) -- helpops.la * HURT system -- hurt.la * New host mangling (umode +x) -- ip_cloaking_4.0.la * Old host mangling (umode +h) -- ip_cloaking.la @@ -95,6 +96,7 @@ #loadmodule "extensions/extb_realname.la"; #loadmodule "extensions/extb_server.la"; #loadmodule "extensions/extb_ssl.la"; +#loadmodule "extensions/helpops.la"; #loadmodule "extensions/hurt.la"; #loadmodule "extensions/ip_cloaking_4.0.la"; #loadmodule "extensions/ip_cloaking.la"; diff --git a/extensions/Makefile.am b/extensions/Makefile.am index 20c12e61..a87c15dd 100644 --- a/extensions/Makefile.am +++ b/extensions/Makefile.am @@ -28,6 +28,7 @@ extension_LTLIBRARIES = \ extb_extgecos.la \ extb_combi.la \ force_user_invis.la \ + helpops.la \ hurt.la \ ip_cloaking.la \ ip_cloaking_old.la \ diff --git a/extensions/Makefile.in b/extensions/Makefile.in index 43929a35..baae5095 100644 --- a/extensions/Makefile.in +++ b/extensions/Makefile.in @@ -206,6 +206,9 @@ extb_usermode_la_OBJECTS = extb_usermode.lo force_user_invis_la_LIBADD = force_user_invis_la_SOURCES = force_user_invis.c force_user_invis_la_OBJECTS = force_user_invis.lo +helpops_la_LIBADD = +helpops_la_SOURCES = helpops.c +helpops_la_OBJECTS = helpops.lo hide_uncommon_channels_la_LIBADD = hide_uncommon_channels_la_SOURCES = hide_uncommon_channels.c hide_uncommon_channels_la_OBJECTS = hide_uncommon_channels.lo @@ -360,7 +363,7 @@ SOURCES = chm_adminonly.c chm_nonotice.c chm_operonly.c \ createoperonly.c example_module.c extb_account.c \ extb_canjoin.c extb_channel.c extb_combi.c extb_extgecos.c \ extb_hostmask.c extb_oper.c extb_realname.c extb_server.c \ - extb_ssl.c extb_usermode.c force_user_invis.c \ + extb_ssl.c extb_usermode.c force_user_invis.c helpops.c \ hide_uncommon_channels.c hurt.c ip_cloaking.c \ ip_cloaking_3.0.c ip_cloaking_4.0.c ip_cloaking_old.c m_42.c \ m_adminwall.c m_extendchans.c m_findforwards.c m_identify.c \ @@ -378,7 +381,7 @@ DIST_SOURCES = chm_adminonly.c chm_nonotice.c chm_operonly.c \ createoperonly.c example_module.c extb_account.c \ extb_canjoin.c extb_channel.c extb_combi.c extb_extgecos.c \ extb_hostmask.c extb_oper.c extb_realname.c extb_server.c \ - extb_ssl.c extb_usermode.c force_user_invis.c \ + extb_ssl.c extb_usermode.c force_user_invis.c helpops.c \ hide_uncommon_channels.c hurt.c ip_cloaking.c \ ip_cloaking_3.0.c ip_cloaking_4.0.c ip_cloaking_old.c m_42.c \ m_adminwall.c m_extendchans.c m_findforwards.c m_identify.c \ @@ -622,6 +625,7 @@ extension_LTLIBRARIES = \ extb_extgecos.la \ extb_combi.la \ force_user_invis.la \ + helpops.la \ hurt.la \ ip_cloaking.la \ ip_cloaking_old.la \ @@ -800,6 +804,9 @@ extb_usermode.la: $(extb_usermode_la_OBJECTS) $(extb_usermode_la_DEPENDENCIES) $ force_user_invis.la: $(force_user_invis_la_OBJECTS) $(force_user_invis_la_DEPENDENCIES) $(EXTRA_force_user_invis_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) -rpath $(extensiondir) $(force_user_invis_la_OBJECTS) $(force_user_invis_la_LIBADD) $(LIBS) +helpops.la: $(helpops_la_OBJECTS) $(helpops_la_DEPENDENCIES) $(EXTRA_helpops_la_DEPENDENCIES) + $(AM_V_CCLD)$(LINK) -rpath $(extensiondir) $(helpops_la_OBJECTS) $(helpops_la_LIBADD) $(LIBS) + hide_uncommon_channels.la: $(hide_uncommon_channels_la_OBJECTS) $(hide_uncommon_channels_la_DEPENDENCIES) $(EXTRA_hide_uncommon_channels_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) -rpath $(extensiondir) $(hide_uncommon_channels_la_OBJECTS) $(hide_uncommon_channels_la_LIBADD) $(LIBS) @@ -943,6 +950,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/extb_ssl.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/extb_usermode.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/force_user_invis.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/helpops.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hide_uncommon_channels.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hurt.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ip_cloaking.Plo@am__quote@ diff --git a/extensions/helpops.c b/extensions/helpops.c new file mode 100644 index 00000000..4bf86208 --- /dev/null +++ b/extensions/helpops.c @@ -0,0 +1,138 @@ +/* + * Helpops system. + * -- kaniini + */ + +#include "stdinc.h" +#include "modules.h" +#include "client.h" +#include "hook.h" +#include "ircd.h" +#include "send.h" +#include "s_conf.h" +#include "s_user.h" +#include "s_newconf.h" +#include "numeric.h" + +static rb_dlink_list helper_list = { NULL, NULL, 0 }; +static void h_hdl_stats_request(hook_data_int *hdata); +static void h_hdl_new_remote_user(struct Client *client_p); +static void h_hdl_client_exit(hook_data_client_exit *hdata); +static void h_hdl_umode_changed(hook_data_umode_changed *hdata); +static void h_hdl_whois(hook_data_client *hdata); + +mapi_hfn_list_av1 helpops_hfnlist[] = { + { "doing_stats", (hookfn) h_hdl_stats_request }, + { "new_remote_user", (hookfn) h_hdl_new_remote_user }, + { "client_exit", (hookfn) h_hdl_client_exit }, + { "umode_changed", (hookfn) h_hdl_umode_changed }, + { "doing_whois", (hookfn) h_hdl_whois }, + { "doing_whois_global", (hookfn) h_hdl_whois }, + { NULL, NULL } +}; + +static int UMODE_HELPOPS = 0; + +static int +_modinit(void) +{ + /* add the usermode to the available slot */ + user_modes['H'] = UMODE_HELPOPS = find_umode_slot(); + construct_umodebuf(); + + return 0; +} + +static void +_moddeinit(void) +{ + /* disable the umode and remove it from the available list */ + user_modes['H'] = UMODE_HELPOPS = 0; + construct_umodebuf(); +} + +static void +h_hdl_stats_request(hook_data_int *hdata) +{ + struct Client *target_p; + rb_dlink_node *helper_ptr; + unsigned int count = 0; + + if (hdata->arg2 != 'p') + return; + + RB_DLINK_FOREACH (helper_ptr, helper_list.head) + { + target_p = helper_ptr->data; + + if(IsOperInvis(target_p) && !IsOper(hdata->client)) + continue; + + if(target_p->user->away) + continue; + + count++; + + sendto_one_numeric(hdata->client, RPL_STATSDEBUG, + "p :%s (%s@%s)", + target_p->name, target_p->username, + target_p->host); + } + + sendto_one_numeric(hdata->client, RPL_STATSDEBUG, + "p :%u staff members", count); + + hdata->result = 1; +} + +static void +h_hdl_new_remote_user(struct Client *client_p) +{ + if (client_p->umodes & UMODE_HELPOPS) + rb_dlinkAddAlloc(client_p, &helper_list); +} + +static void +h_hdl_client_exit(hook_data_client_exit *hdata) +{ + if (hdata->target->umodes & UMODE_HELPOPS) + rb_dlinkFindDestroy(hdata->target, &helper_list); +} + +static void +h_hdl_umode_changed(hook_data_umode_changed *hdata) +{ + struct Client *source_p = hdata->client; + + /* didn't change +H umode, we don't need to do anything */ + if (!((hdata->oldumodes ^ source_p->umodes) & UMODE_HELPOPS)) + return; + + if (source_p->umodes & UMODE_HELPOPS) + { + if (MyClient(source_p) && !HasPrivilege(source_p, "usermode:helpops")) + { + source_p->umodes &= ~UMODE_HELPOPS; + sendto_one(source_p, form_str(ERR_NOPRIVS), me.name, source_p->name, "usermode:helpops"); + return; + } + + rb_dlinkAddAlloc(source_p, &helper_list); + } + else if (!(source_p->umodes & UMODE_HELPOPS)) + rb_dlinkFindDestroy(source_p, &helper_list); +} + +static void +h_hdl_whois(hook_data_client *hdata) +{ + struct Client *source_p = hdata->client; + struct Client *target_p = hdata->target; + + if ((target_p->umodes & UMODE_HELPOPS) && EmptyString(target_p->user->away)) + { + sendto_one_numeric(source_p, RPL_WHOISHELPOP, form_str(RPL_WHOISHELPOP), target_p->name); + } +} + +DECLARE_MODULE_AV1(helpops, _modinit, _moddeinit, NULL, NULL, helpops_hfnlist, ""); diff --git a/include/messages.h b/include/messages.h index 4f4455fa..8ae8ee87 100644 --- a/include/messages.h +++ b/include/messages.h @@ -89,6 +89,7 @@ #define NUMERIC_STR_303 ":%s 303 %s :" #define NUMERIC_STR_305 ":You are no longer marked as being away" #define NUMERIC_STR_306 ":You have been marked as being away" +#define NUMERIC_STR_310 "%s :is available for help." #define NUMERIC_STR_311 "%s %s %s * :%s" #define NUMERIC_STR_312 "%s %s :%s" #define NUMERIC_STR_313 "%s :%s" diff --git a/include/numeric.h b/include/numeric.h index 29ea398c..7f55249d 100644 --- a/include/numeric.h +++ b/include/numeric.h @@ -132,6 +132,7 @@ /* RPL_WHOISADMIN 308 -- hybrid */ +#define RPL_WHOISHELPOP 310 #define RPL_WHOISUSER 311 #define RPL_WHOISSERVER 312 #define RPL_WHOISOPERATOR 313