/* Halfop (+h) related functions.
*
* IRC Services is copyright (c) 1996-2007 Andrew Church.
* E-mail: <achurch@achurch.org>
* 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);
}
/*************************************************************************/
syntax highlighted by Code2HTML, v. 0.9.1