/** * clear_users.C: This file contains code for the ChanServ CLEAR USERS 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: clear_users.C,v 1.8 2007/09/22 14:27:27 pippijn Exp $ */ #include "atheme.h" #include #include #include static char const rcsid[] = "$Id: clear_users.C,v 1.8 2007/09/22 14:27:27 pippijn Exp $"; REGISTER_MODULE ("chanserv/clear_users", false, "The Ermyth Team "); static void cs_cmd_clear_users (sourceinfo_t *si, int parc, char *parv[]); command_t const cs_clear_users = { "USERS", N_("Kicks all users from a channel."), AC_NONE, 2, cs_cmd_clear_users }; E cmdvec cs_clear_cmds; E helpvec cs_helptree; bool _modinit (module *m) { cs_clear_cmds << cs_clear_users; help_addentry (cs_helptree, "CLEAR USERS", "help/chanserv/clear_users", NULL); return true; } void _moddeinit () { cs_clear_cmds >> cs_clear_users; help_delentry (cs_helptree, "CLEAR USERS"); } static void cs_cmd_clear_users (sourceinfo_t *si, int parc, char *parv[]) { char fullreason[200]; channel_t *c; char *channel = parv[0]; mychan_t *mc = mychan_t::find (channel); chanuser_t *cu; node_t *n, *tn; int oldlimit; if (parc >= 2) snprintf (fullreason, sizeof fullreason, "CLEAR USERS used by %s: %s", get_source_name (si), parv[1]); else snprintf (fullreason, sizeof fullreason, "CLEAR USERS used by %s", get_source_name (si)); if (!mc) { command_fail (si, fault::nosuch_target, _("\2%s\2 is not registered."), channel); return; } if (!(c = channel_find (channel))) { command_fail (si, fault::nosuch_target, _("\2%s\2 is currently empty."), channel); return; } if (!chanacs_source_has_flag (mc, si, CA_RECOVER)) { 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; } /* stop a race condition where users can rejoin */ oldlimit = c->limit; if (oldlimit != 1) modestack_mode_limit (chansvs.nick, c, MTYPE_ADD, 1); modestack_flush_channel (c); LIST_FOREACH_SAFE (n, tn, c->members.head) { cu = static_cast (n->data); /* don't kick the user who requested the masskick */ if (cu->user == si->su || is_internal_client (cu->user)) continue; phandler->kick (chansvs.nick, c->name, cu->user->nick, fullreason); } /* the channel may be empty now, so our pointer may be bogus! */ c = channel_find (channel); if (c != NULL) { if ((mc->flags & MC_GUARD) && !config_options.leave_chans && c != NULL && !chanuser_find (c, si->su)) { /* Always cycle it if the requester is not on channel * -- jilles */ part (channel, chansvs.nick); } /* could be permanent channel, blah */ c = channel_find (channel); if (c != NULL) { if (oldlimit == 0) modestack_mode_limit (chansvs.nick, c, MTYPE_DEL, 0); else if (oldlimit != 1) modestack_mode_limit (chansvs.nick, c, MTYPE_ADD, oldlimit); } } logcommand (si, CMDLOG_DO, "%s CLEAR USERS", mc->name); command_success_nodata (si, _("Cleared users from \2%s\2."), channel); }