/** * quiet.C: This file contains code for the ChanServ QUIET/UNQUIET 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 William Pitcock, et al. * Rights to this code are as documented in doc/pod/license.pod. * * $Id: quiet.C,v 1.8 2007/09/22 14:27:27 pippijn Exp $ */ #include "atheme.h" #include #include #include static char const rcsid[] = "$Id: quiet.C,v 1.8 2007/09/22 14:27:27 pippijn Exp $"; REGISTER_MODULE ("chanserv/quiet", false, "The Ermyth Team "); static void cs_cmd_quiet (sourceinfo_t *si, int parc, char *parv[]); static void cs_cmd_unquiet (sourceinfo_t *si, int parc, char *parv[]); command_t const cs_quiet = { "QUIET", N_("Sets a quiet on a channel."), AC_NONE, 2, cs_cmd_quiet }; command_t const cs_unquiet = { "UNQUIET", N_("Removes a quiet on a channel."), AC_NONE, 2, cs_cmd_unquiet }; E cmdvec cs_cmdtree; E helpvec cs_helptree; bool _modinit (module *m) { if (ircd && !strchr (ircd->ban_like_modes, 'q')) { slog (LG_INFO, "Module %s requires a ban-like mode +q, refusing to load.", m->name); return false; } cs_cmdtree << cs_quiet; cs_cmdtree << cs_unquiet; help_addentry (cs_helptree, "QUIET", "help/chanserv/quiet", NULL); help_addentry (cs_helptree, "UNQUIET", "help/chanserv/unquiet", NULL); return true; } void _moddeinit () { cs_cmdtree >> cs_quiet; cs_cmdtree >> cs_unquiet; help_delentry (cs_helptree, "QUIET"); help_delentry (cs_helptree, "UNQUIET"); } static void cs_cmd_quiet (sourceinfo_t *si, int parc, char *parv[]) { char *channel = parv[0]; char *target = parv[1]; channel_t *c = channel_find (channel); mychan_t *mc = mychan_t::find (channel); user_t *tu; if (!channel || !target) { command_fail (si, fault::needmoreparams, STR_INSUFFICIENT_PARAMS, "QUIET"); command_fail (si, fault::needmoreparams, _("Syntax: QUIET <#channel> ")); return; } if (!mc) { command_fail (si, fault::nosuch_target, _("\2%s\2 is not registered."), channel); return; } if (!c) { command_fail (si, fault::nosuch_target, _("\2%s\2 is currently empty."), channel); return; } if (!si->smu) { command_fail (si, fault::noprivs, _("You are not logged in.")); return; } if (!chanacs_source_has_flag (mc, si, CA_REMOVE)) { 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."), channel); return; } if (validhostmask (target)) { modestack_mode_param (chansvs.nick, c, MTYPE_ADD, 'q', target); chanban_add (c, target, 'q'); logcommand (si, CMDLOG_DO, "%s QUIET %s", mc->name, target); if (!chanuser_find (mc->chan, si->su)) command_success_nodata (si, _("Quieted \2%s\2 on \2%s\2."), target, channel); return; } else if ((tu = user_find_named (target))) { char hostbuf[BUFSIZE]; hostbuf[0] = '\0'; strlcat (hostbuf, "*!*@", BUFSIZE); strlcat (hostbuf, tu->vhost, BUFSIZE); modestack_mode_param (chansvs.nick, c, MTYPE_ADD, 'q', hostbuf); chanban_add (c, hostbuf, 'q'); logcommand (si, CMDLOG_DO, "%s QUIET %s (for user %s!%s@%s)", mc->name, hostbuf, tu->nick, tu->user, tu->vhost); if (!chanuser_find (mc->chan, si->su)) command_success_nodata (si, _("Quieted \2%s\2 on \2%s\2."), target, channel); return; } else { command_fail (si, fault::badparams, _("Invalid nickname/hostmask provided: \2%s\2"), target); command_fail (si, fault::badparams, _("Syntax: QUIET <#channel> ")); return; } } static void cs_cmd_unquiet (sourceinfo_t *si, int parc, char *parv[]) { char *channel = parv[0]; char *target = parv[1]; channel_t *c = channel_find (channel); mychan_t *mc = mychan_t::find (channel); user_t *tu; chanban_t *cb; if (!channel) { command_fail (si, fault::needmoreparams, STR_INSUFFICIENT_PARAMS, "UNQUIET"); command_fail (si, fault::needmoreparams, _("Syntax: UNQUIET <#channel> ")); return; } if (!target) { if (si->su == NULL) { command_fail (si, fault::needmoreparams, STR_INSUFFICIENT_PARAMS, "UNQUIET"); command_fail (si, fault::needmoreparams, _("Syntax: UNQUIET <#channel> ")); return; } target = si->su->nick; } if (!mc) { command_fail (si, fault::nosuch_target, _("\2%s\2 is not registered."), channel); return; } if (!c) { command_fail (si, fault::nosuch_target, _("\2%s\2 is currently empty."), channel); return; } if (!si->smu) { command_fail (si, fault::noprivs, _("You are not logged in.")); return; } if (!chanacs_source_has_flag (mc, si, CA_REMOVE)) { command_fail (si, fault::noprivs, _("You are not authorized to perform this operation.")); return; } if ((tu = user_find_named (target))) { node_t *n, *tn; char hostbuf2[BUFSIZE]; int count = 0; snprintf (hostbuf2, BUFSIZE, "%s!%s@%s", tu->nick, tu->user, tu->vhost); for (n = phandler->next_matching_ban (c, tu, 'q', c->bans.head); n != NULL; n = phandler->next_matching_ban (c, tu, 'q', tn)) { tn = n->next; cb = static_cast (n->data); logcommand (si, CMDLOG_DO, "%s UNQUIET %s (for user %s)", mc->name, cb->mask, hostbuf2); modestack_mode_param (chansvs.nick, c, MTYPE_DEL, cb->type, cb->mask); chanban_delete (cb); count++; } if (count > 0) command_success_nodata (si, _("Unquieted \2%s\2 on \2%s\2 (%d ban%s removed)."), target, channel, count, (count != 1 ? "s" : "")); else command_success_nodata (si, _("No quiets found matching \2%s\2 on \2%s\2."), target, channel); return; } else if ((cb = chanban_find (c, target, 'q')) != NULL || validhostmask (target)) { if (cb) { modestack_mode_param (chansvs.nick, c, MTYPE_DEL, 'q', target); chanban_delete (cb); logcommand (si, CMDLOG_DO, "%s UNQUIET %s", mc->name, target); if (!chanuser_find (mc->chan, si->su)) command_success_nodata (si, _("Unquieted \2%s\2 on \2%s\2."), target, channel); } else command_fail (si, fault::nosuch_key, _("No such quiet \2%s\2 on \2%s\2."), target, channel); return; } else { command_fail (si, fault::badparams, _("Invalid nickname/hostmask provided: \2%s\2"), target); command_fail (si, fault::badparams, _("Syntax: UNQUIET <#channel> [nickname|hostmask]")); return; } }