]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/cmd_stats.cpp
Remove references to inspircd_io from these, stop configure making all the modules...
[user/henk/code/inspircd.git] / src / cmd_stats.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 #include "inspircd_config.h"
18 #include "inspircd.h"
19 #include "configreader.h"
20 #include "hash_map.h"
21 #include <sys/types.h>
22 #include <sys/time.h>
23 #include <sys/resource.h>
24 #ifdef THREADED_DNS
25 #include <pthread.h>
26 #endif
27 #ifndef RUSAGE_SELF
28 #define   RUSAGE_SELF     0
29 #define   RUSAGE_CHILDREN     -1
30 #endif
31
32 #include "users.h"
33 #include "ctables.h"
34 #include "globals.h"
35 #include "modules.h"
36 #include "dynamic.h"
37 #include "wildcard.h"
38 #include "message.h"
39 #include "commands.h"
40 #include "mode.h"
41 #include "xline.h"
42 #include "inspstring.h"
43 #include "dnsqueue.h"
44 #include "helperfuncs.h"
45 #include "hashcomp.h"
46 #include "socketengine.h"
47 #include "command_parse.h"
48 #include "cmd_stats.h"
49
50 extern ServerConfig* Config;
51 extern InspIRCd* ServerInstance;
52 extern int MODCOUNT;
53 extern ModuleList modules;
54 extern FactoryList factory;
55 extern time_t TIME;
56 extern user_hash clientlist;
57 extern chan_hash chanlist;
58
59 void cmd_stats::Handle (char **parameters, int pcnt, userrec *user)
60 {
61         if (pcnt != 1)
62         {
63                 return;
64         }
65         if (parameters[0][1])
66         {
67                 /* make the stats query 1 character long */
68                 parameters[0][1] = 0;
69         }
70
71         if ((*Config->OperOnlyStats) && (strchr(Config->OperOnlyStats,*parameters[0])) && (!*user->oper))
72         {
73                 WriteServ(user->fd,"481 %s :Permission denied - STATS %c is oper-only",user->nick,*parameters[0]);
74                 return;
75         }
76
77
78         int MOD_RESULT = 0;
79         FOREACH_RESULT(I_OnStats,OnStats(*parameters[0],user));
80         if (MOD_RESULT)
81                 return;
82
83         if (*parameters[0] == 'c')
84         {
85                 /* This stats symbol must be handled by a linking module */
86         }
87         
88         if (*parameters[0] == 'i')
89         {
90                 int idx = 0;
91                 for (ClassVector::iterator i = Config->Classes.begin(); i != Config->Classes.end(); i++)
92                 {
93                         WriteServ(user->fd,"215 %s I * * * %d %d %s *",user->nick,MAXCLIENTS,idx,Config->ServerName);
94                         idx++;
95                 }
96         }
97         
98         if (*parameters[0] == 'y')
99         {
100                 int idx = 0;
101                 for (ClassVector::iterator i = Config->Classes.begin(); i != Config->Classes.end(); i++)
102                 {
103                         WriteServ(user->fd,"218 %s Y %d %d 0 %d %d",user->nick,idx,120,i->flood,i->registration_timeout);
104                         idx++;
105                 }
106         }
107
108         if (*parameters[0] == 'U')
109         {
110                 char ulined[MAXBUF];
111                 for (int i = 0; i < Config->ConfValueEnum(Config->config_data, "uline"); i++)
112                 {
113                         Config->ConfValue(Config->config_data, "uline","server", i, ulined, MAXBUF);
114                         WriteServ(user->fd,"248 %s U %s",user->nick,ulined);
115                 }
116         }
117         
118         if (*parameters[0] == 'P')
119         {
120                 int idx = 0;
121                 for (user_hash::iterator i = clientlist.begin(); i != clientlist.end(); i++)
122                 {
123                         if (*i->second->oper)
124                         {
125                                 WriteServ(user->fd,"249 %s :%s (%s@%s) Idle: %d",user->nick,i->second->nick,i->second->ident,i->second->dhost,(TIME - i->second->idle_lastmsg));
126                                 idx++;
127                         }
128                 }
129                 WriteServ(user->fd,"249 %s :%d OPER(s)",user->nick,idx);
130         }
131         
132         if (*parameters[0] == 'k')
133         {
134                 stats_k(user);
135         }
136
137         if (*parameters[0] == 'g')
138         {
139                 stats_g(user);
140         }
141
142         if (*parameters[0] == 'q')
143         {
144                 stats_q(user);
145         }
146
147         if (*parameters[0] == 'Z')
148         {
149                 stats_z(user);
150         }
151
152         if (*parameters[0] == 'e')
153         {
154                 stats_e(user);
155         }
156
157         /* stats m (list number of times each command has been used, plus bytecount) */
158         if (*parameters[0] == 'm')
159         {
160                 for (nspace::hash_map<std::string,command_t*>::iterator i = ServerInstance->Parser->cmdlist.begin(); i != ServerInstance->Parser->cmdlist.end(); i++)
161                 {
162                         if (i->second->use_count)
163                         {
164                                 /* RPL_STATSCOMMANDS */
165                                 WriteServ(user->fd,"212 %s %s %d %d",user->nick,i->second->command.c_str(),i->second->use_count,i->second->total_bytes);
166                         }
167                 }
168                         
169         }
170
171         /* stats z (debug and memory info) */
172         if (*parameters[0] == 'z')
173         {
174                 rusage R;
175                 WriteServ(user->fd,"249 %s :Users(HASH_MAP) %d (%d bytes, %d buckets)",user->nick,clientlist.size(),clientlist.size()*sizeof(userrec),clientlist.bucket_count());
176                 WriteServ(user->fd,"249 %s :Channels(HASH_MAP) %d (%d bytes, %d buckets)",user->nick,chanlist.size(),chanlist.size()*sizeof(chanrec),chanlist.bucket_count());
177                 WriteServ(user->fd,"249 %s :Commands(VECTOR) %d (%d bytes)",user->nick,ServerInstance->Parser->cmdlist.size(),ServerInstance->Parser->cmdlist.size()*sizeof(command_t));
178                 WriteServ(user->fd,"249 %s :MOTD(VECTOR) %d, RULES(VECTOR) %d",user->nick,Config->MOTD.size(),Config->RULES.size());
179                 WriteServ(user->fd,"249 %s :Modules(VECTOR) %d (%d)",user->nick,modules.size(),modules.size()*sizeof(Module));
180                 WriteServ(user->fd,"249 %s :ClassFactories(VECTOR) %d (%d)",user->nick,factory.size(),factory.size()*sizeof(ircd_module));
181                 if (!getrusage(RUSAGE_SELF,&R))
182                 {
183                         WriteServ(user->fd,"249 %s :Total allocation: %luK (0x%lx)",user->nick,R.ru_maxrss,R.ru_maxrss);
184                         WriteServ(user->fd,"249 %s :Signals:          %lu  (0x%lx)",user->nick,R.ru_nsignals,R.ru_nsignals);
185                         WriteServ(user->fd,"249 %s :Page faults:      %lu  (0x%lx)",user->nick,R.ru_majflt,R.ru_majflt);
186                         WriteServ(user->fd,"249 %s :Swaps:            %lu  (0x%lx)",user->nick,R.ru_nswap,R.ru_nswap);
187                         WriteServ(user->fd,"249 %s :Context Switches: %lu  (0x%lx)",user->nick,R.ru_nvcsw+R.ru_nivcsw,R.ru_nvcsw+R.ru_nivcsw);
188                 }
189         }
190
191         if (*parameters[0] == 'T')
192         {
193                 WriteServ(user->fd,"249 %s :accepts %d refused %d",user->nick,ServerInstance->stats->statsAccept,ServerInstance->stats->statsRefused);
194                 WriteServ(user->fd,"249 %s :unknown commands %d",user->nick,ServerInstance->stats->statsUnknown);
195                 WriteServ(user->fd,"249 %s :nick collisions %d",user->nick,ServerInstance->stats->statsCollisions);
196                 WriteServ(user->fd,"249 %s :dns requests %d succeeded %d failed %d",user->nick,ServerInstance->stats->statsDns,ServerInstance->stats->statsDnsGood,ServerInstance->stats->statsDnsBad);
197                 WriteServ(user->fd,"249 %s :connections %d",user->nick,ServerInstance->stats->statsConnects);
198                 WriteServ(user->fd,"249 %s :bytes sent %dK recv %dK",user->nick,(ServerInstance->stats->statsSent / 1024),(ServerInstance->stats->statsRecv / 1024));
199         }
200         
201         /* stats o */
202         if (*parameters[0] == 'o')
203         {
204                 for (int i = 0; i < Config->ConfValueEnum(Config->config_data, "oper"); i++)
205                 {
206                         char LoginName[MAXBUF];
207                         char HostName[MAXBUF];
208                         char OperType[MAXBUF];
209                         Config->ConfValue(Config->config_data, "oper","name", i, LoginName, MAXBUF);
210                         Config->ConfValue(Config->config_data, "oper","host", i, HostName, MAXBUF);
211                         Config->ConfValue(Config->config_data, "oper","type", i, OperType, MAXBUF);
212                         WriteServ(user->fd,"243 %s O %s * %s %s 0",user->nick,HostName,LoginName,OperType);
213                 }
214         }
215         
216         /* stats l (show user I/O stats) */
217         if (*parameters[0] == 'l')
218         {
219                 WriteServ(user->fd,"211 %s :server:port nick bytes_in cmds_in bytes_out cmds_out",user->nick);
220                 for (user_hash::iterator i = clientlist.begin(); i != clientlist.end(); i++)
221                 {
222                         if (isnick(i->second->nick))
223                         {
224                                 WriteServ(user->fd,"211 %s :%s:%d %s %d %d %d %d",user->nick,i->second->server,i->second->port,i->second->nick,i->second->bytes_in,i->second->cmds_in,i->second->bytes_out,i->second->cmds_out);
225                         }
226                         else
227                         {
228                                 WriteServ(user->fd,"211 %s :%s:%d (unknown@%d) %d %d %d %d",user->nick,i->second->server,i->second->port,i->second->fd,i->second->bytes_in,i->second->cmds_in,i->second->bytes_out,i->second->cmds_out);
229                         }
230                         
231                 }
232         }
233         
234         /* stats u (show server uptime) */
235         if (*parameters[0] == 'u')
236         {
237                 time_t current_time = 0;
238                 current_time = TIME;
239                 time_t server_uptime = current_time - ServerInstance->startup_time;
240                 struct tm* stime;
241                 stime = gmtime(&server_uptime);
242                 /* i dont know who the hell would have an ircd running for over a year nonstop, but
243                  * Craig suggested this, and it seemed a good idea so in it went */
244                 if (stime->tm_year > 70)
245                 {
246                         WriteServ(user->fd,"242 %s :Server up %d years, %d days, %.2d:%.2d:%.2d",user->nick,(stime->tm_year-70),stime->tm_yday,stime->tm_hour,stime->tm_min,stime->tm_sec);
247                 }
248                 else
249                 {
250                         WriteServ(user->fd,"242 %s :Server up %d days, %.2d:%.2d:%.2d",user->nick,stime->tm_yday,stime->tm_hour,stime->tm_min,stime->tm_sec);
251                 }
252         }
253
254         WriteServ(user->fd,"219 %s %s :End of /STATS report",user->nick,parameters[0]);
255         WriteOpers("*** Notice: Stats '%s' requested by %s (%s@%s)",parameters[0],user->nick,user->ident,user->host);
256         
257 }