/** * fflags.C: This file contains code for the ChanServ FFLAGS functions. * * 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: fflags.C,v 1.10 2007/09/22 14:27:27 pippijn Exp $ */ #include "atheme.h" #include #include #include #include #include "template.h" static char const rcsid[] = "$Id: fflags.C,v 1.10 2007/09/22 14:27:27 pippijn Exp $"; REGISTER_MODULE ("chanserv/fflags", false, "The Ermyth Team "); static void cs_cmd_fflags (sourceinfo_t *si, int parc, char *parv[]); command_t const cs_fflags = { "FFLAGS", N_("Forces a flags change on a channel."), PRIV_CHAN_ADMIN, 3, cs_cmd_fflags }; E cmdvec cs_cmdtree; E helpvec cs_helptree; bool _modinit (module *m) { cs_cmdtree << cs_fflags; help_addentry (cs_helptree, "FFLAGS", "help/chanserv/fflags", NULL); return true; } void _moddeinit () { cs_cmdtree >> cs_fflags; help_delentry (cs_helptree, "FFLAGS"); } /* FFLAGS */ static void cs_cmd_fflags (sourceinfo_t *si, int parc, char *parv[]) { chanacs_t *ca; char *channel = parv[0]; char *target = parv[1]; char *flagstr = parv[2]; mychan_t *mc = mychan_t::find (channel); myuser_t *tmu; unsigned int addflags, removeflags; if (parc < 3) { command_fail (si, fault::needmoreparams, STR_INSUFFICIENT_PARAMS, "FFLAGS"); command_fail (si, fault::needmoreparams, _("Syntax: FFLAGS ")); return; } if (!mc) { command_fail (si, fault::nosuch_target, _("\2%s\2 is not registered."), channel); return; } if (*flagstr == '+' || *flagstr == '-' || *flagstr == '=') { flags_make_bitmasks (flagstr, chanacs_flags, &addflags, &removeflags); if (addflags == 0 && removeflags == 0) { command_fail (si, fault::badparams, _("No valid flags given, use /%s%s HELP FLAGS for a list"), ircd->uses_rcommand ? "" : "msg ", chansvs.disp); return; } } else { addflags = get_template_flags (mc, flagstr); if (addflags == 0) { /* Hack -- jilles */ if (*target == '+' || *target == '-' || *target == '=') command_fail (si, fault::badparams, _("Usage: FFLAGS %s "), mc->name); else command_fail (si, fault::badparams, _("Invalid template name given, use /%s%s TEMPLATE %s for a list"), ircd->uses_rcommand ? "" : "msg ", chansvs.disp, mc->name); return; } removeflags = ca_all & ~addflags; } if (!validhostmask (target)) { if (!(tmu = myuser_t::find_ext (target))) { command_fail (si, fault::nosuch_target, _("\2%s\2 is not registered."), target); return; } target = tmu->name; /* XXX this should be more like flags.c */ if (removeflags & CA_FLAGS) removeflags |= CA_FOUNDER, addflags &= ~CA_FOUNDER; else if (addflags & CA_FOUNDER) addflags |= CA_FLAGS, removeflags &= ~CA_FLAGS; if (tmu->is_founder (mc) && removeflags & CA_FOUNDER && mc->num_founders () == 1) { command_fail (si, fault::noprivs, _("You may not remove the last founder.")); return; } /* If NEVEROP is set, don't allow adding new entries * except sole +b. Adding flags if the current level * is +b counts as adding an entry. * -- jilles */ if (tmu->flags & MU_NEVEROP && addflags != CA_AKICK && addflags != 0 && ((ca = chanacs_find (mc, tmu, 0)) == NULL || ca->level == CA_AKICK)) { command_fail (si, fault::noprivs, _("\2%s\2 does not wish to be added to access lists (NEVEROP set)."), tmu->name); return; } if (!chanacs_change (mc, tmu, NULL, &addflags, &removeflags, ca_all)) { /* this shouldn't happen */ command_fail (si, fault::noprivs, _("You are not allowed to set \2%s\2 on \2%s\2 in \2%s\2."), bitmask_to_flags2 (addflags, removeflags, chanacs_flags), tmu->name, mc->name); return; } } else { if (addflags & CA_FOUNDER) { command_fail (si, fault::badparams, _("You may not set founder status on a hostmask.")); return; } if (!chanacs_change (mc, NULL, target, &addflags, &removeflags, ca_all)) { /* this shouldn't happen */ command_fail (si, fault::noprivs, _("You are not allowed to set \2%s\2 on \2%s\2 in \2%s\2."), bitmask_to_flags2 (addflags, removeflags, chanacs_flags), target, mc->name); return; } } if ((addflags | removeflags) == 0) { command_fail (si, fault::nochange, _("Channel access to \2%s\2 for \2%s\2 unchanged."), channel, target); return; } flagstr = bitmask_to_flags2 (addflags, removeflags, chanacs_flags); wallops ("\2%s\2 is forcing flags change \2%s\2 on \2%s\2 in \2%s\2.", get_oper_name (si), flagstr, target, mc->name); snoop ("FFLAGS: \2%s\2 \2%s\2 \2%s\2 by \2%s\2", channel, target, flagstr, get_oper_name (si)); command_success_nodata (si, _("Flags \2%s\2 were set on \2%s\2 in \2%s\2."), flagstr, target, channel); logcommand (si, CMDLOG_ADMIN, "%s FFLAGS %s %s", mc->name, target, flagstr); verbose (mc, "\2%s\2 forced flags change \2%s\2 on \2%s\2.", get_source_name (si), flagstr, target); }