/** * rakill.C: Regexp-based AKILL implementation. * * 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 © 2006 Robin Burchell * Rights to this code are as defined in doc/pod/license.pod. * * $Id: rakill.C,v 1.8 2007/09/22 14:27:28 pippijn Exp $ */ /* * @makill regex!here.+ [akill reason] * Matches `nick!user@host realname here' for each client against a given regex, and places akills. * CHECK REGEX USING @RMATCH FIRST! */ #include #include "atheme.h" #include #include #include static char const rcsid[] = "$Id: rakill.C,v 1.8 2007/09/22 14:27:28 pippijn Exp $"; REGISTER_MODULE ("operserv/rakill", false, "The Ermyth Team "); E cmdvec os_cmdtree; E helpvec os_helptree; static void os_cmd_rakill (sourceinfo_t *si, int parc, char *parv[]); command_t const os_rakill = { "RAKILL", N_("Sets a group of AKILLs against users matching a specific regex pattern."), PRIV_MASS_AKILL, 1, os_cmd_rakill }; bool _modinit (module *m) { os_cmdtree << os_rakill; help_addentry (os_helptree, "RAKILL", "help/operserv/rakill", NULL); return true; } void _moddeinit (void) { os_cmdtree >> os_rakill; help_delentry (os_helptree, "RAKILL"); } static void os_cmd_rakill (sourceinfo_t *si, int parc, char *parv[]) { regex_t *regex; char usermask[512]; unsigned int matches = 0; user_t *u; char *args = parv[0]; char *pattern; char *reason; user_t *source; int flags = 0; /* make sure they could have done RMATCH */ if (!has_priv (si, PRIV_USER_AUSPEX)) { command_fail (si, fault::noprivs, _("You do not have %s privilege."), PRIV_USER_AUSPEX); return; } if (args == NULL) { command_fail (si, fault::needmoreparams, STR_INSUFFICIENT_PARAMS, "RAKILL"); command_fail (si, fault::needmoreparams, _("Syntax: RAKILL //[i] ")); return; } pattern = regex_extract (args, &args, &flags); if (pattern == NULL) { command_fail (si, fault::badparams, STR_INVALID_PARAMS, "RAKILL"); command_fail (si, fault::badparams, _("Syntax: RAKILL //[i] ")); return; } reason = args; while (*reason == ' ') reason++; if (*reason == '\0') { command_fail (si, fault::needmoreparams, STR_INSUFFICIENT_PARAMS, "RAKILL"); command_fail (si, fault::needmoreparams, _("Syntax: RAKILL //[i] ")); return; } regex = regex_create (pattern, flags); if (regex == NULL) { command_fail (si, fault::badparams, _("The provided regex \2%s\2 is invalid."), pattern); return; } source = si->su; /* try to find them on IRC, otherwise use operserv */ if (source == NULL) source = si->smu != NULL && !si->smu->logins.empty () ? si->smu->logins.back () : si->service->me; sprintf (usermask, "%s!%s@%s %s", source->nick, source->user, source->host, source->gecos); if (regex_match (regex, (char *) usermask)) { regex_destroy (regex); command_fail (si, fault::noprivs, _("The provided regex matches you, refusing RAKILL.")); snoop ("RAKILL:REFUSED: \2%s\2 by \2%s\2 (%s) (matches self)", pattern, get_oper_name (si), reason); wallops ("\2%s\2 attempted to do RAKILL on \2%s\2 matching self", get_oper_name (si), pattern); logcommand (si, CMDLOG_ADMIN, "RAKILL %s %s (refused, matches self)", pattern, reason); return; } snoop ("RAKILL: \2%s\2 by \2%s\2 (%s)", pattern, get_oper_name (si), reason); foreach (user_t::pair_type &up, user_t::map) { u = up.second; sprintf (usermask, "%s!%s@%s %s", u->nick, u->user, u->host, u->gecos); if (regex_match (regex, (char *) usermask)) { /* match */ command_success_nodata (si, _("\2Match:\2 %s!%s@%s %s - akilling"), u->nick, u->user, u->host, u->gecos); phandler->kline_sts ("*", "*", u->host, 604800, reason); matches++; } } regex_destroy (regex); command_success_nodata (si, _("\2%d\2 matches for %s akilled."), matches, pattern); logcommand (si, CMDLOG_ADMIN, "RAKILL %s %s (%d matches)", pattern, reason, matches); }