1 /* +------------------------------------+
\r * | Inspire Internet Relay Chat Daemon |
\r * +------------------------------------+
\r *
\r * InspIRCd: (C) 2002-2007 InspIRCd Development Team
\r * See: http://www.inspircd.org/wiki/index.php/Credits
\r *
\r * This program is free but copyrighted software; see
\r * the file COPYING for details.
\r *
\r * ---------------------------------------------------
\r */
\r\r/* NO, THIS MODULE DOES NOT SPY ON CHANNELS OR USERS.
\r * IT JUST ALLOWS OPERS TO SEE +s CHANNELS IN LIST AND
\r * WHOIS, WHICH IS SUPPORTED BY MOST IRCDS IN CORE.
\r */
\r\r/* $ModDesc: Provides SPYLIST and SPYNAMES capability, allowing opers to see who's in +s channels */
\r\r#include "inspircd.h"
\r#include "users.h"
\r#include "channels.h"
\r#include "modules.h"
\r#include "wildcard.h"
\r\rvoid spy_userlist(userrec *user, chanrec *c)
\r{
\r char list[MAXBUF];
\r size_t dlen, curlen;
\r\r dlen = curlen = snprintf(list,MAXBUF,"353 %s = %s :", user->nick, c->name);
\r\r int numusers = 0;
\r char* ptr = list + dlen;
\r\r CUList *ulist= c->GetUsers();
\r\r for (CUList::iterator i = ulist->begin(); i != ulist->end(); i++)
\r {
\r size_t ptrlen = snprintf(ptr, MAXBUF, "%s%s ", c->GetPrefixChar(i->first), i->first->nick);
\r\r curlen += ptrlen;
\r ptr += ptrlen;
\r\r numusers++;
\r\r if (curlen > (480-NICKMAX))
\r {
\r /* list overflowed into multiple numerics */
\r user->WriteServ(std::string(list));
\r\r /* reset our lengths */
\r dlen = curlen = snprintf(list,MAXBUF,"353 %s = %s :", user->nick, c->name);
\r ptr = list + dlen;
\r\r ptrlen = 0;
\r numusers = 0;
\r }
\r }
\r\r /* if whats left in the list isnt empty, send it */
\r if (numusers)
\r {
\r user->WriteServ(std::string(list));
\r }
\r\r user->WriteServ("366 %s %s :End of /NAMES list.", user->nick, c->name);
\r\r}
\r\r/** Handle /SPYLIST
\r */
\rclass cmd_spylist : public command_t
\r{
\r public:
\r cmd_spylist (InspIRCd* Instance) : command_t(Instance,"SPYLIST", 'o', 0)
\r {
\r this->source = "m_spy.so";
\r syntax.clear();
\r }
\r\r CmdResult Handle (const char** parameters, int pcnt, userrec *user)
\r {
\r ServerInstance->WriteOpers("*** Oper %s used SPYLIST to list +s/+p channels and keys.",user->nick);
\r user->WriteServ("321 %s Channel :Users Name",user->nick);
\r for (chan_hash::const_iterator i = ServerInstance->chanlist->begin(); i != ServerInstance->chanlist->end(); i++)
\r {
\r if (pcnt && !match(i->second->name, parameters[0]))
\r continue;
\r user->WriteServ("322 %s %s %d :[+%s] %s",user->nick,i->second->name,i->second->GetUserCounter(),i->second->ChanModes(true),i->second->topic);
\r }
\r user->WriteServ("323 %s :End of channel list.",user->nick);
\r\r /* Dont send out across the network */
\r return CMD_FAILURE;
\r }
\r};
\r\r/** Handle /SPYNAMES
\r */
\rclass cmd_spynames : public command_t
\r{
\r public:
\r cmd_spynames (InspIRCd* Instance) : command_t(Instance,"SPYNAMES", 'o', 0)
\r {
\r this->source = "m_spy.so";
\r syntax = "{<channel>{,<channel>}}";
\r }
\r\r CmdResult Handle (const char** parameters, int pcnt, userrec *user)
\r {
\r chanrec* c = NULL;
\r\r if (!pcnt)
\r {
\r user->WriteServ("366 %s * :End of /NAMES list.",user->nick);
\r return CMD_FAILURE;
\r }
\r\r if (ServerInstance->Parser->LoopCall(user, this, parameters, pcnt, 0))
\r return CMD_FAILURE;
\r\r c = ServerInstance->FindChan(parameters[0]);
\r if (c)
\r {
\r ServerInstance->WriteOpers("*** Oper %s used SPYNAMES to view the users on %s", user->nick, parameters[0]);
\r spy_userlist(user,c);
\r }
\r else
\r {
\r user->WriteServ("401 %s %s :No such nick/channel",user->nick, parameters[0]);
\r }
\r\r return CMD_FAILURE;
\r }
\r};
\r\rclass ModuleSpy : public Module
\r{
\r cmd_spylist *mycommand;
\r cmd_spynames *mycommand2;
\r public:
\r ModuleSpy(InspIRCd* Me) : Module(Me)
\r {
\r \r mycommand = new cmd_spylist(ServerInstance);
\r mycommand2 = new cmd_spynames(ServerInstance);
\r ServerInstance->AddCommand(mycommand);
\r ServerInstance->AddCommand(mycommand2);
\r }
\r \r virtual ~ModuleSpy()
\r {
\r }
\r \r virtual Version GetVersion()
\r {
\r return Version(1, 1, 0, 0, VF_VENDOR, API_VERSION);
\r }
\r};
\r\rMODULE_INIT(ModuleSpy)
\r