/** * compare.C: This file contains functionality implementing OperServ COMPARE. * * 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 documented in doc/LICENCE. * * $Id: compare.C,v 1.6 2007/09/16 18:54:43 pippijn Exp $ */ #include "atheme.h" #include static char const rcsid[] = "$Id: compare.C,v 1.6 2007/09/16 18:54:43 pippijn Exp $"; REGISTER_MODULE ("operserv/compare", false, "Robin Burchell "); static void os_cmd_compare (sourceinfo_t *si, int parc, char *parv[]); command_t const os_compare = { "COMPARE", N_("Compares two users or channels."), PRIV_CHAN_AUSPEX, 2, os_cmd_compare }; E cmdvec os_cmdtree; E helpvec os_helptree; bool _modinit (module *m) { os_cmdtree << os_compare; help_addentry (os_helptree, "COMPARE", "help/operserv/compare", NULL); return true; } void _moddeinit (void) { os_cmdtree >> os_compare; help_delentry (os_helptree, "COMPARE"); } static void os_cmd_compare (sourceinfo_t *si, int parc, char *parv[]) { char *object1 = parv[0]; char *object2 = parv[1]; channel_t *c1, *c2; user_t *u1, *u2; node_t *n1, *n2; chanuser_t *cu1, *cu2; int matches = 0; int temp = 0; char buf[512]; char tmpbuf[100]; bzero (buf, 512); bzero (tmpbuf, 100); if (!object1 || !object2) { command_fail (si, fault::needmoreparams, STR_INSUFFICIENT_PARAMS, "COMPARE"); command_fail (si, fault::needmoreparams, _("Syntax: COMPARE ")); return; } if (*object1 == '#') { if (*object2 == '#') { /* compare on two channels */ c1 = channel_find (object1); c2 = channel_find (object2); if (!c1 || !c2) { command_fail (si, fault::nosuch_target, _("Both channels must exist for @compare")); return; } command_success_nodata (si, _("Common users in \2%s\2 and \2%s\2"), object1, object2); /* iterate over the users in channel 1 */ LIST_FOREACH (n1, c1->members.head) { cu1 = static_cast < chanuser_t *>(n1->data); /* now iterate over each of channel 2's members, and compare them to the current user from ch1 */ LIST_FOREACH (n2, c2->members.head) { cu2 = static_cast < chanuser_t *>(n2->data); /* match! */ if (cu1->user == cu2->user) { /* common user! */ snprintf (tmpbuf, 99, "%s, ", cu1->user->nick); strcat ((char *) buf, tmpbuf); bzero (tmpbuf, 100); /* if too many, output to user */ if (temp >= 5 || strlen (buf) > 300) { command_success_nodata (si, "%s", buf); bzero (buf, 512); temp = 0; } temp++; matches++; } } } } else { /* bad syntax */ command_fail (si, fault::badparams, _("Bad syntax for @compare. Use @compare on two channels, or two users.")); return; } } else { if (*object2 == '#') { /* bad syntax */ command_fail (si, fault::badparams, _("Bad syntax for @compare. Use @compare on two channels, or two users.")); return; } else { /* compare on two users */ u1 = user_find_named (object1); u2 = user_find_named (object2); if (!u1 || !u2) { command_fail (si, fault::nosuch_target, _("Both users must exist for @compare")); return; } command_success_nodata (si, _("Common channels for \2%s\2 and \2%s\2"), object1, object2); /* iterate over the channels of user 1 */ LIST_FOREACH (n1, u1->channels.head) { cu1 = static_cast < chanuser_t *>(n1->data); /* now iterate over each of user 2's channels to the current channel from user 1 */ LIST_FOREACH (n2, u2->channels.head) { cu2 = static_cast < chanuser_t *>(n2->data); /* match! */ if (cu1->chan == cu2->chan) { /* common channel! */ snprintf (tmpbuf, 99, "%s, ", cu1->chan->name); strcat ((char *) buf, tmpbuf); bzero (tmpbuf, 100); /* if too many, output to user */ if (temp >= 5 || strlen (buf) > 300) { command_success_nodata (si, "%s", buf); bzero (buf, 512); temp = 0; } temp++; matches++; } } } } } if (buf[0] != 0) command_success_nodata (si, "%s", buf); command_success_nodata (si, _("\2%d\2 matches comparing %s and %s"), matches, object1, object2); logcommand (si, CMDLOG_ADMIN, "COMPARE %s to %s (%d matches)", object1, object2, matches); snoop ("COMPARE: \2%s\2 to \2%s\2 by \2%s\2", object1, object2, get_oper_name (si)); } /* vim:cinoptions=>s,e0,n0,f0,{0,}0,^0,=s,ps,t0,c3,+s,(2s,us,)20,*30,gs,hs * vim:ts=8 * vim:sw=8 * vim:noexpandtab */