/** * why.C: This file contains code for the ChanServ WHY function. * * Copyright © 2007 Pippijn van Steenhoven / The Ermyth Team * Rights to this code are as documented in COPYING. * * * Portions of this file were derived from sources bearing the following license: * Copyright © 2005-2006 William Pitcock, et al. * Rights to this code are as documented in doc/pod/license.pod. * * $Id: why.C,v 1.9 2007/09/22 14:27:27 pippijn Exp $ */ #include "atheme.h" #include #include #include #include static char const rcsid[] = "$Id: why.C,v 1.9 2007/09/22 14:27:27 pippijn Exp $"; REGISTER_MODULE ("chanserv/why", false, "The Ermyth Team "); static void cs_cmd_why (sourceinfo_t *si, int parc, char *parv[]); command_t const cs_why = { "WHY", N_("Explains channel access logic."), AC_NONE, 2, cs_cmd_why }; E cmdvec cs_cmdtree; E helpvec cs_helptree; bool _modinit (module *m) { cs_cmdtree << cs_why; help_addentry (cs_helptree, "WHY", "help/chanserv/why", NULL); return true; } void _moddeinit () { cs_cmdtree >> cs_why; help_delentry (cs_helptree, "WHY"); } static void cs_cmd_why (sourceinfo_t *si, int parc, char *parv[]) { char *chan = parv[0]; char *targ = parv[1]; char host[BUFSIZE]; mychan_t *mc; user_t *u; myuser_t *mu; node_t *n; chanacs_t *ca; metadata *md; int operoverride = 0; int fl = 0; if (!chan || !targ) { command_fail (si, fault::needmoreparams, STR_INSUFFICIENT_PARAMS, "WHY"); command_fail (si, fault::needmoreparams, _("Syntax: WHY ")); return; } mc = mychan_t::find (chan); u = user_find_named (targ); if (u == NULL) { command_fail (si, fault::nosuch_target, _("\2%s\2 is not online."), targ); return; } mu = u->myuser; if (mc == NULL) { command_fail (si, fault::nosuch_target, _("\2%s\2 is not registered."), chan); return; } if (!chanacs_source_has_flag (mc, si, CA_ACLVIEW)) { if (has_priv (si, PRIV_CHAN_AUSPEX)) operoverride = 1; else { command_fail (si, fault::noprivs, _("You are not authorized to perform this operation.")); return; } } if (mc->find_metadata ("private:close:closer")) { command_fail (si, fault::noprivs, _("\2%s\2 is closed."), chan); return; } if (operoverride) logcommand (si, CMDLOG_ADMIN, "%s WHY %s!%s@%s (oper override)", mc->name, u->nick, u->user, u->vhost); else logcommand (si, CMDLOG_GET, "%s WHY %s!%s@%s", mc->name, u->nick, u->user, u->vhost); snprintf (host, BUFSIZE, "%s!%s@%s", u->nick, u->user, u->vhost); LIST_FOREACH (n, mc->chanacs.head) { ca = (chanacs_t *) n->data; if (ca->myuser != NULL && ca->myuser == mu) { fl |= ca->level; command_success_nodata (si, "\2%s\2 has flags \2%s\2 in \2%s\2 because they are logged in as \2%s\2.", u->nick, bitmask_to_flags2 (ca->level, 0, chanacs_flags), mc->name, mu->name); if (ca->level & CA_AKICK) { md = ca->find_metadata ("reason"); if (md != NULL) command_success_nodata (si, "Ban reason: %s", md->value); } } } for (n = phandler->next_matching_host_chanacs (mc, u, mc->chanacs.head); n != NULL; n = phandler->next_matching_host_chanacs (mc, u, n->next)) { ca = static_cast (n->data); fl |= ca->level; command_success_nodata (si, "\2%s\2 has flags \2%s\2 in \2%s\2 because they match the mask \2%s\2.", u->nick, bitmask_to_flags2 (ca->level, 0, chanacs_flags), mc->name, ca->host); if (ca->level & CA_AKICK) { md = ca->find_metadata ("reason"); if (md != NULL) command_success_nodata (si, "Ban reason: %s", md->value); } } if ((fl & (CA_AKICK | CA_REMOVE)) == (CA_AKICK | CA_REMOVE)) command_success_nodata (si, _("+r exempts from +b.")); else if (fl == 0) command_success_nodata (si, _("\2%s\2 has no special access to \2%s\2."), u->nick, mc->name); }