]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/modules/m_spy.cpp
53a7f0d7f960e9131a7e804c0d8311b401058153
[user/henk/code/inspircd.git] / src / modules / m_spy.cpp
1 /*       +------------------------------------+
2  *       | Inspire Internet Relay Chat Daemon |
3  *       +------------------------------------+
4  *
5  *  InspIRCd is copyright (C) 2002-2006 ChatSpike-Dev.
6  *                     E-mail:
7  *              <brain@chatspike.net>
8  *                <Craig@chatspike.net>
9  *     
10  * Written by Craig Edwards, Craig McLure, and others.
11  * This program is free but copyrighted software; see
12  *          the file COPYING for details.
13  *
14  * ---------------------------------------------------
15  */
16
17 /* NO, THIS MODULE DOES NOT SPY ON CHANNELS OR USERS.
18  * IT JUST ALLOWS OPERS TO SEE +s CHANNELS IN LIST AND
19  * WHOIS, WHICH IS SUPPORTED BY MOST IRCDS IN CORE.
20  */
21
22 using namespace std;
23
24 /* $ModDesc: Provides SPYLIST and SPYNAMES capability, allowing opers to see who's in +s channels */
25
26 #include "inspircd_config.h"
27 #include "users.h" 
28 #include "channels.h"
29 #include "modules.h"
30 #include "inspircd.h"
31 #include "wildcard.h"
32
33 void spy_userlist(userrec *user, chanrec *c)
34 {
35         char list[MAXBUF];
36         size_t dlen, curlen;
37
38         dlen = curlen = snprintf(list,MAXBUF,"353 %s = %s :", user->nick, c->name);
39
40         int numusers = 0;
41         char* ptr = list + dlen;
42
43         CUList *ulist= c->GetUsers();
44
45         /* Improvement by Brain - this doesnt change in value, so why was it inside
46          * the loop?
47          */
48         bool has_user = c->HasUser(user);
49
50         for (CUList::iterator i = ulist->begin(); i != ulist->end(); i++)
51         {
52                 if ((!has_user) && (i->second->modes[UM_INVISIBLE]))
53                 {
54                         /*
55                          * user is +i, and source not on the channel, does not show
56                          * nick in NAMES list
57                          */
58                         continue;
59                 }
60
61                 size_t ptrlen = snprintf(ptr, MAXBUF, "%s%s ", c->GetPrefixChar(i->second), i->second->nick);
62
63                 curlen += ptrlen;
64                 ptr += ptrlen;
65
66                 numusers++;
67
68                 if (curlen > (480-NICKMAX))
69                 {
70                         /* list overflowed into multiple numerics */
71                         user->WriteServ(std::string(list));
72
73                         /* reset our lengths */
74                         dlen = curlen = snprintf(list,MAXBUF,"353 %s = %s :", user->nick, c->name);
75                         ptr = list + dlen;
76
77                         ptrlen = 0;
78                         numusers = 0;
79                 }
80         }
81
82         /* if whats left in the list isnt empty, send it */
83         if (numusers)
84         {
85                 user->WriteServ(std::string(list));
86         }
87
88         user->WriteServ("366 %s %s :End of /NAMES list.", user->nick, c->name);
89
90 }
91
92
93 class cmd_spylist : public command_t
94 {
95   public:
96         cmd_spylist (InspIRCd* Instance) : command_t(Instance,"SPYLIST", 'o', 0)
97         {
98                 this->source = "m_spy.so";
99                 syntax = "";
100         }
101
102         CmdResult Handle (const char** parameters, int pcnt, userrec *user)
103         {
104                 ServerInstance->WriteOpers("*** Oper %s used SPYLIST to list +s/+p channels and keys.",user->nick);
105                 user->WriteServ("321 %s Channel :Users Name",user->nick);
106                 for (chan_hash::const_iterator i = ServerInstance->chanlist.begin(); i != ServerInstance->chanlist.end(); i++)
107                 {
108                         if (pcnt && !match(i->second->name, parameters[0]))
109                                 continue;
110                         user->WriteServ("322 %s %s %d :[+%s] %s",user->nick,i->second->name,i->second->GetUserCounter(),i->second->ChanModes(true),i->second->topic);
111                 }
112                 user->WriteServ("323 %s :End of channel list.",user->nick);
113
114                 /* Dont send out across the network */
115                 return CMD_FAILURE;
116         }
117 };
118
119 class cmd_spynames : public command_t
120 {
121   public:
122         cmd_spynames (InspIRCd* Instance) : command_t(Instance,"SPYNAMES", 'o', 0)
123         {
124                 this->source = "m_spy.so";
125                 syntax = "{<channel>{,<channel>}}";
126         }
127
128         CmdResult Handle (const char** parameters, int pcnt, userrec *user)
129         {
130                 chanrec* c = NULL;
131
132                 if (!pcnt)
133                 {
134                         user->WriteServ("366 %s * :End of /NAMES list.",user->nick);
135                         return CMD_FAILURE;
136                 }
137
138                 if (ServerInstance->Parser->LoopCall(user, this, parameters, pcnt, 0))
139                         return CMD_FAILURE;
140
141                 c = ServerInstance->FindChan(parameters[0]);
142                 if (c)
143                 {
144                         ServerInstance->WriteOpers("*** Oper %s used SPYNAMES to view the users on %s", user->nick, parameters[0]);
145                         spy_userlist(user,c);
146                         user->WriteServ("366 %s %s :End of /NAMES list.", user->nick, c->name);
147                 }
148                 else
149                 {
150                         user->WriteServ("401 %s %s :No such nick/channel",user->nick, parameters[0]);
151                 }
152
153                 return CMD_FAILURE;
154         }
155 };
156
157 class ModuleSpy : public Module
158 {
159         cmd_spylist *mycommand;
160         cmd_spynames *mycommand2;
161  public:
162         ModuleSpy(InspIRCd* Me) : Module::Module(Me)
163         {
164                 
165                 mycommand = new cmd_spylist(ServerInstance);
166                 mycommand2 = new cmd_spynames(ServerInstance);
167                 ServerInstance->AddCommand(mycommand);
168                 ServerInstance->AddCommand(mycommand2);
169         }
170         
171         virtual ~ModuleSpy()
172         {
173         }
174         
175         virtual Version GetVersion()
176         {
177                 return Version(1, 0, 0, 0, VF_VENDOR, API_VERSION);
178         }
179 };
180
181
182 class ModuleSpyFactory : public ModuleFactory
183 {
184  public:
185         ModuleSpyFactory()
186         {
187         }
188         
189         ~ModuleSpyFactory()
190         {
191         }
192         
193         virtual Module * CreateModule(InspIRCd* Me)
194         {
195                 return new ModuleSpy(Me);
196         }
197         
198 };
199
200
201 extern "C" void * init_module( void )
202 {
203         return new ModuleSpyFactory;
204 }