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