/* Halfop (+h) related functions. * * IRC Services is copyright (c) 1996-2007 Andrew Church. * E-mail: * Parts written by Andrew Kempe and others. * This program is free but copyrighted software; see the file COPYING for * details. */ #include "services.h" #include "modules.h" #include "language.h" #include "modules/chanserv/chanserv.h" #include "halfop.h" /*************************************************************************/ static Module *module; static Module *module_chanserv; static int old_XOP_REACHED_LIMIT = -1; static int old_XOP_NICKS_ONLY = -1; static int old_HELP_SOP_MID2 = -1; static int old_HELP_AOP_MID = -1; static const char **p_s_ChanServ = NULL; #define s_ChanServ (*p_s_ChanServ) /*************************************************************************/ /*************************************************************************/ /* Callback to handle ChanServ CLEAR HALFOPS. */ static void clear_halfops(Channel *chan); static int do_cs_clear(User *u, Channel *c, const char *what) { if (stricmp(what, "HALFOPS") == 0) { clear_halfops(c); set_cmode(NULL, c); notice_lang(s_ChanServ, u, CHAN_CLEARED_HALFOPS, c->name); return 1; } return 0; } static void clear_halfops(Channel *chan) { struct c_userlist *cu; static int32 mode_h = -1; if (mode_h < 0) mode_h = mode_char_to_flag('h', MODE_CHANUSER); LIST_FOREACH (cu, chan->users) { if (cu->mode & mode_h) set_cmode(s_ChanServ, chan, "-h", cu->user->nick); } } /*************************************************************************/ /*************************************************************************/ /* Callback to watch for modules being loaded. */ static int do_load_module(Module *mod, const char *name) { if (strcmp(name, "chanserv/main") == 0) { module_chanserv = mod; p_s_ChanServ = get_module_symbol(mod, "s_ChanServ"); if (p_s_ChanServ) { if (!(add_callback(mod, "CLEAR", do_cs_clear))) module_log("halfop: Unable to add ChanServ CLEAR callback"); } else { module_log("halfop: Unable to resolve symbol `s_ChanServ' in" " module `chanserv/main', CLEAR HALFOPS will not" " be available"); } } return 0; } /*************************************************************************/ /* Callback to watch for modules being unloaded. */ static int do_unload_module(Module *mod) { if (mod == module_chanserv) { p_s_ChanServ = NULL; module_chanserv = NULL; } return 0; } /*************************************************************************/ int init_halfop(Module *module_) { module = module_; if (!add_callback(NULL, "load module", do_load_module) || !add_callback(NULL, "unload module", do_unload_module) ) { module_log("halfop: Unable to add callbacks"); exit_halfop(); return 0; } protocol_features |= PF_HALFOP; old_XOP_REACHED_LIMIT = setstring(CHAN_XOP_REACHED_LIMIT, CHAN_XOP_REACHED_LIMIT_HOP); old_XOP_NICKS_ONLY = setstring(CHAN_XOP_NICKS_ONLY, CHAN_XOP_NICKS_ONLY_HOP); old_HELP_SOP_MID2 = setstring(CHAN_HELP_SOP_MID2, CHAN_HELP_SOP_MID2_HALFOP); old_HELP_AOP_MID = setstring(CHAN_HELP_AOP_MID, CHAN_HELP_AOP_MID_HALFOP); return 1; } /*************************************************************************/ void exit_halfop(void) { if (module_chanserv) do_unload_module(module_chanserv); if (old_HELP_AOP_MID >= 0) setstring(CHAN_HELP_AOP_MID, old_HELP_AOP_MID); if (old_HELP_SOP_MID2 >= 0) setstring(CHAN_HELP_SOP_MID2, old_HELP_SOP_MID2); if (old_XOP_NICKS_ONLY >= 0) setstring(CHAN_XOP_NICKS_ONLY, old_XOP_NICKS_ONLY); if (old_XOP_REACHED_LIMIT >= 0) setstring(CHAN_XOP_REACHED_LIMIT, old_XOP_REACHED_LIMIT); old_HELP_AOP_MID = -1; old_HELP_SOP_MID2 = -1; old_XOP_NICKS_ONLY = -1; old_XOP_REACHED_LIMIT = -1; remove_callback(NULL, "unload module", do_unload_module); remove_callback(NULL, "load module", do_load_module); } /*************************************************************************/