Anope IRC Services  Version 1.8
os_stats.c
Go to the documentation of this file.
1 /* OperServ core functions
2  *
3  * (C) 2003-2014 Anope Team
4  * Contact us at team@anope.org
5  *
6  * Please read COPYING and README for further details.
7  *
8  * Based on the original code of Epona by Lara.
9  * Based on the original code of Services by Andy Church.
10  *
11  *
12  */
13 /*************************************************************************/
14 
15 #include "module.h"
16 
17 
18 
19 static int do_stats(User * u);
20 static void get_operserv_stats(long *nrec, long *memuse);
21 static void myOperServHelp(User * u);
22 
29 int AnopeInit(int argc, char **argv)
30 {
31  Command *c;
32 
33  moduleAddAuthor("Anope");
34  moduleAddVersion(VERSION_STRING);
36 
37  c = createCommand("STATS", do_stats, NULL, OPER_HELP_STATS,
38  -1, -1, -1, -1);
40  c = createCommand("UPTIME", do_stats, NULL,
41  OPER_HELP_STATS, -1, -1, -1, -1);
43 
45 
46  return MOD_CONT;
47 }
48 
52 void AnopeFini(void)
53 {
54 
55 }
56 
57 
62 static void myOperServHelp(User * u)
63 {
64  notice_lang(s_OperServ, u, OPER_HELP_CMD_STATS);
65 }
66 
72 static int stats_count_servers(Server * s)
73 {
74  int count = 0;
75 
76  while (s) {
77  count++;
78  if (s->links)
79  count += stats_count_servers(s->links);
80  s = s->next;
81  }
82 
83  return count;
84 }
85 
91 static int do_stats(User * u)
92 {
93  time_t uptime = time(NULL) - start_time;
94  char *extra = strtok(NULL, "");
95  int days = uptime / 86400, hours = (uptime / 3600) % 24,
96  mins = (uptime / 60) % 60, secs = uptime % 60;
97  struct tm *tm;
98  char timebuf[64];
99  char buf[512];
100  int buflen;
101  int i;
102 
103  if (extra && stricmp(extra, "ALL") != 0) {
104  if (stricmp(extra, "AKILL") == 0) {
105  int timeout;
106  /* AKILLs */
107  notice_lang(s_OperServ, u, OPER_STATS_AKILL_COUNT,
108  akills.count);
109  timeout = AutokillExpiry + 59;
110  if (timeout >= 172800)
111  notice_lang(s_OperServ, u, OPER_STATS_AKILL_EXPIRE_DAYS,
112  timeout / 86400);
113  else if (timeout >= 86400)
114  notice_lang(s_OperServ, u, OPER_STATS_AKILL_EXPIRE_DAY);
115  else if (timeout >= 7200)
116  notice_lang(s_OperServ, u, OPER_STATS_AKILL_EXPIRE_HOURS,
117  timeout / 3600);
118  else if (timeout >= 3600)
119  notice_lang(s_OperServ, u, OPER_STATS_AKILL_EXPIRE_HOUR);
120  else if (timeout >= 120)
121  notice_lang(s_OperServ, u, OPER_STATS_AKILL_EXPIRE_MINS,
122  timeout / 60);
123  else if (timeout >= 60)
124  notice_lang(s_OperServ, u, OPER_STATS_AKILL_EXPIRE_MIN);
125  else
126  notice_lang(s_OperServ, u, OPER_STATS_AKILL_EXPIRE_NONE);
127  if (ircd->sgline) {
128  /* SGLINEs */
129  notice_lang(s_OperServ, u, OPER_STATS_SGLINE_COUNT,
130  sglines.count);
131  timeout = SGLineExpiry + 59;
132  if (timeout >= 172800)
134  OPER_STATS_SGLINE_EXPIRE_DAYS,
135  timeout / 86400);
136  else if (timeout >= 86400)
138  OPER_STATS_SGLINE_EXPIRE_DAY);
139  else if (timeout >= 7200)
141  OPER_STATS_SGLINE_EXPIRE_HOURS,
142  timeout / 3600);
143  else if (timeout >= 3600)
145  OPER_STATS_SGLINE_EXPIRE_HOUR);
146  else if (timeout >= 120)
148  OPER_STATS_SGLINE_EXPIRE_MINS,
149  timeout / 60);
150  else if (timeout >= 60)
152  OPER_STATS_SGLINE_EXPIRE_MIN);
153  else
155  OPER_STATS_SGLINE_EXPIRE_NONE);
156  }
157  if (ircd->sqline) {
158  /* SQLINEs */
159  notice_lang(s_OperServ, u, OPER_STATS_SQLINE_COUNT,
160  sqlines.count);
161  timeout = SQLineExpiry + 59;
162  if (timeout >= 172800)
164  OPER_STATS_SQLINE_EXPIRE_DAYS,
165  timeout / 86400);
166  else if (timeout >= 86400)
168  OPER_STATS_SQLINE_EXPIRE_DAY);
169  else if (timeout >= 7200)
171  OPER_STATS_SQLINE_EXPIRE_HOURS,
172  timeout / 3600);
173  else if (timeout >= 3600)
175  OPER_STATS_SQLINE_EXPIRE_HOUR);
176  else if (timeout >= 120)
178  OPER_STATS_SQLINE_EXPIRE_MINS,
179  timeout / 60);
180  else if (timeout >= 60)
182  OPER_STATS_SQLINE_EXPIRE_MIN);
183  else
185  OPER_STATS_SQLINE_EXPIRE_NONE);
186  }
187  if (ircd->szline) {
188  /* SZLINEs */
189  notice_lang(s_OperServ, u, OPER_STATS_SZLINE_COUNT,
190  szlines.count);
191  timeout = SZLineExpiry + 59;
192  if (timeout >= 172800)
194  OPER_STATS_SZLINE_EXPIRE_DAYS,
195  timeout / 86400);
196  else if (timeout >= 86400)
198  OPER_STATS_SZLINE_EXPIRE_DAY);
199  else if (timeout >= 7200)
201  OPER_STATS_SZLINE_EXPIRE_HOURS,
202  timeout / 3600);
203  else if (timeout >= 3600)
205  OPER_STATS_SZLINE_EXPIRE_HOUR);
206  else if (timeout >= 120)
208  OPER_STATS_SZLINE_EXPIRE_MINS,
209  timeout / 60);
210  else if (timeout >= 60)
212  OPER_STATS_SZLINE_EXPIRE_MIN);
213  else
215  OPER_STATS_SZLINE_EXPIRE_NONE);
216  }
217  return MOD_CONT;
218  } else if (!stricmp(extra, "RESET")) {
219  if (is_services_admin(u)) {
221  notice_lang(s_OperServ, u, OPER_STATS_RESET);
222  } else {
223  notice_lang(s_OperServ, u, PERMISSION_DENIED);
224  }
225  return MOD_CONT;
226  } else if (stricmp(extra, "MEMORY") && stricmp(extra, "UPLINK")) {
227  notice_lang(s_OperServ, u, OPER_STATS_UNKNOWN_OPTION, extra);
228  }
229  }
230 
231  if (!extra || ((stricmp(extra, "MEMORY") != 0)
232  && (stricmp(extra, "UPLINK") != 0))) {
233  notice_lang(s_OperServ, u, OPER_STATS_CURRENT_USERS, usercnt,
234  opcnt);
235  tm = localtime(&maxusertime);
236  strftime_lang(timebuf, sizeof(timebuf), u,
237  STRFTIME_DATE_TIME_FORMAT, tm);
238  notice_lang(s_OperServ, u, OPER_STATS_MAX_USERS, maxusercnt,
239  timebuf);
240  if (days > 1) {
241  notice_lang(s_OperServ, u, OPER_STATS_UPTIME_DHMS,
242  days, hours, mins, secs);
243  } else if (days == 1) {
244  notice_lang(s_OperServ, u, OPER_STATS_UPTIME_1DHMS,
245  days, hours, mins, secs);
246  } else {
247  if (hours > 1) {
248  if (mins != 1) {
249  if (secs != 1) {
250  notice_lang(s_OperServ, u, OPER_STATS_UPTIME_HMS,
251  hours, mins, secs);
252  } else {
253  notice_lang(s_OperServ, u, OPER_STATS_UPTIME_HM1S,
254  hours, mins, secs);
255  }
256  } else {
257  if (secs != 1) {
258  notice_lang(s_OperServ, u, OPER_STATS_UPTIME_H1MS,
259  hours, mins, secs);
260  } else {
261  notice_lang(s_OperServ, u, OPER_STATS_UPTIME_H1M1S,
262  hours, mins, secs);
263  }
264  }
265  } else if (hours == 1) {
266  if (mins != 1) {
267  if (secs != 1) {
268  notice_lang(s_OperServ, u, OPER_STATS_UPTIME_1HMS,
269  hours, mins, secs);
270  } else {
271  notice_lang(s_OperServ, u, OPER_STATS_UPTIME_1HM1S,
272  hours, mins, secs);
273  }
274  } else {
275  if (secs != 1) {
276  notice_lang(s_OperServ, u, OPER_STATS_UPTIME_1H1MS,
277  hours, mins, secs);
278  } else {
280  OPER_STATS_UPTIME_1H1M1S, hours, mins,
281  secs);
282  }
283  }
284  } else {
285  if (mins != 1) {
286  if (secs != 1) {
287  notice_lang(s_OperServ, u, OPER_STATS_UPTIME_MS,
288  mins, secs);
289  } else {
290  notice_lang(s_OperServ, u, OPER_STATS_UPTIME_M1S,
291  mins, secs);
292  }
293  } else {
294  if (secs != 1) {
295  notice_lang(s_OperServ, u, OPER_STATS_UPTIME_1MS,
296  mins, secs);
297  } else {
298  notice_lang(s_OperServ, u, OPER_STATS_UPTIME_1M1S,
299  mins, secs);
300  }
301  }
302  }
303  }
304  }
305 
306  if (extra && ((stricmp(extra, "ALL") == 0)
307  || (stricmp(extra, "UPLINK") == 0))
308  && is_services_admin(u)) {
309  buf[0] = '\0';
310  buflen = 511; /* How confusing, this is the amount of space left! */
311  for (i = 0; capab_info[i].token; i++) {
312  if (uplink_capab & capab_info[i].flag) {
313  strncat(buf, " ", buflen);
314  buflen--;
315  strncat(buf, capab_info[i].token, buflen);
316  buflen -= strlen(capab_info[i].token);
317  /* Special cases */
318  if (capab_info[i].flag == CAPAB_CHANMODE) {
319  strncat(buf, "=", buflen);
320  buflen--;
321  strncat(buf, ircd->chanmodes, buflen);
322  buflen -= strlen(ircd->chanmodes);
323  }
324  if (capab_info[i].flag == CAPAB_NICKCHARS) {
325  strncat(buf, "=", buflen);
326  buflen--;
327  if (ircd->nickchars) {
328  strncat(buf, ircd->nickchars, buflen);
329  buflen -= strlen(ircd->nickchars);
330  } /* leave blank if it was null */
331  }
332  }
333  }
334  notice_lang(s_OperServ, u, OPER_STATS_UPLINK_SERVER,
335  serv_uplink->name);
336  notice_lang(s_OperServ, u, OPER_STATS_UPLINK_CAPAB, buf);
337  notice_lang(s_OperServ, u, OPER_STATS_UPLINK_SERVER_COUNT,
339  }
340 
341  if (extra && ((stricmp(extra, "ALL") == 0)
342  || (stricmp(extra, "MEMORY") == 0))
343  && is_services_admin(u)) {
344  long count, mem;
345 
346  notice_lang(s_OperServ, u, OPER_STATS_BYTES_READ,
347  total_read / 1024);
348  notice_lang(s_OperServ, u, OPER_STATS_BYTES_WRITTEN,
349  total_written / 1024);
350 
351  get_user_stats(&count, &mem);
352  notice_lang(s_OperServ, u, OPER_STATS_USER_MEM, count,
353  (mem + 512) / 1024);
354  get_channel_stats(&count, &mem);
355  notice_lang(s_OperServ, u, OPER_STATS_CHANNEL_MEM, count,
356  (mem + 512) / 1024);
357  get_core_stats(&count, &mem);
358  notice_lang(s_OperServ, u, OPER_STATS_GROUPS_MEM, count,
359  (mem + 512) / 1024);
360  get_aliases_stats(&count, &mem);
361  notice_lang(s_OperServ, u, OPER_STATS_ALIASES_MEM, count,
362  (mem + 512) / 1024);
363  get_chanserv_stats(&count, &mem);
364  notice_lang(s_OperServ, u, OPER_STATS_CHANSERV_MEM, count,
365  (mem + 512) / 1024);
366  if (s_BotServ) {
367  get_botserv_stats(&count, &mem);
368  notice_lang(s_OperServ, u, OPER_STATS_BOTSERV_MEM, count,
369  (mem + 512) / 1024);
370  }
371  if (s_HostServ) {
372  get_hostserv_stats(&count, &mem);
373  notice_lang(s_OperServ, u, OPER_STATS_HOSTSERV_MEM, count,
374  (mem + 512) / 1024);
375  }
376  get_operserv_stats(&count, &mem);
377  notice_lang(s_OperServ, u, OPER_STATS_OPERSERV_MEM, count,
378  (mem + 512) / 1024);
379  get_session_stats(&count, &mem);
380  notice_lang(s_OperServ, u, OPER_STATS_SESSIONS_MEM, count,
381  (mem + 512) / 1024);
382  }
383  return MOD_CONT;
384 }
385 
386 static void get_operserv_stats(long *nrec, long *memuse)
387 {
388  int i;
389  long mem = 0, count = 0, mem2 = 0, count2 = 0;
390  Akill *ak;
391  SXLine *sx;
392 
393  count += akills.count;
394  mem += akills.capacity;
395  mem += akills.count * sizeof(Akill);
396 
397  for (i = 0; i < akills.count; i++) {
398  ak = akills.list[i];
399  mem += strlen(ak->user) + 1;
400  mem += strlen(ak->host) + 1;
401  mem += strlen(ak->by) + 1;
402  mem += strlen(ak->reason) + 1;
403  }
404 
405  if (ircd->sgline) {
406  count += sglines.count;
407  mem += sglines.capacity;
408  mem += sglines.count * sizeof(SXLine);
409 
410  for (i = 0; i < sglines.count; i++) {
411  sx = sglines.list[i];
412  mem += strlen(sx->mask) + 1;
413  mem += strlen(sx->by) + 1;
414  mem += strlen(sx->reason) + 1;
415  }
416  }
417  if (ircd->sqline) {
418  count += sqlines.count;
419  mem += sqlines.capacity;
420  mem += sqlines.count * sizeof(SXLine);
421 
422  for (i = 0; i < sqlines.count; i++) {
423  sx = sqlines.list[i];
424  mem += strlen(sx->mask) + 1;
425  mem += strlen(sx->by) + 1;
426  mem += strlen(sx->reason) + 1;
427  }
428  }
429  if (ircd->szline) {
430  count += szlines.count;
431  mem += szlines.capacity;
432  mem += szlines.count * sizeof(SXLine);
433 
434  for (i = 0; i < szlines.count; i++) {
435  sx = szlines.list[i];
436  mem += strlen(sx->mask) + 1;
437  mem += strlen(sx->by) + 1;
438  mem += strlen(sx->reason) + 1;
439  }
440  }
441 
442 
443  get_news_stats(&count2, &mem2);
444  count += count2;
445  mem += mem2;
446  get_exception_stats(&count2, &mem2);
447  count += count2;
448  mem += mem2;
449 
450  *nrec = count;
451  *memuse = mem;
452 }
E int32 usercnt
Definition: extern.h:1140
E time_t maxusertime
Definition: extern.h:1142
E void get_channel_stats(long *nrec, long *memuse)
Definition: channels.c:459
E int32 opcnt
Definition: extern.h:1140
E void get_core_stats(long *nrec, long *memuse)
Definition: nickserv.c:183
struct akill_ Akill
Definition: services.h:234
char * chanmodes
Definition: services.h:355
char * nickchars
Definition: services.h:369
E int SQLineExpiry
Definition: extern.h:442
E int SZLineExpiry
Definition: extern.h:443
char * by
Definition: services.h:1096
#define CAPAB_NICKCHARS
Definition: services.h:1396
E CapabInfo capab_info[]
Definition: extern.h:1055
E char * s_BotServ
Definition: extern.h:287
E IRCDVar * ircd
Definition: extern.h:39
E void get_chanserv_stats(long *nrec, long *memuse)
Definition: chanserv.c:307
E uint32 maxusercnt
Definition: extern.h:1141
char * mask
Definition: services.h:1095
E void get_news_stats(long *nrec, long *memuse)
Definition: news.c:128
char * host
Definition: services.h:1081
E time_t start_time
Definition: extern.h:797
E int stricmp(const char *s1, const char *s2)
Definition: compat.c:58
char * reason
Definition: services.h:1084
E SList sglines
Definition: extern.h:970
int szline
Definition: services.h:315
Server * links
Definition: services.h:861
MDE void moduleAddAuthor(const char *author)
Definition: modules.c:1772
E void notice_lang(char *source, User *dest, int message,...)
Definition: send.c:169
MDE void moduleSetType(MODType type)
Definition: modules.c:818
char * user
Definition: services.h:1080
E void get_botserv_stats(long *nrec, long *memuse)
Definition: botserv.c:45
static int stats_count_servers(Server *s)
Definition: os_stats.c:72
#define OPERSERV
Definition: modules.h:62
void ** list
Definition: slist.h:21
E char * s_OperServ
Definition: extern.h:289
Server * next
Definition: services.h:852
static void myOperServHelp(User *u)
Definition: os_stats.c:62
int16 count
Definition: slist.h:23
void AnopeFini(void)
Definition: os_stats.c:52
E void get_hostserv_stats(long *nrec, long *memuse)
Definition: hostserv.c:45
MDE void moduleAddVersion(const char *version)
Definition: modules.c:1760
char * token
Definition: services.h:1362
char * name
Definition: services.h:854
Command * c
Definition: ns_recover.c:17
char * by
Definition: services.h:1083
E uint32 uplink_capab
Definition: extern.h:1054
int sqline
Definition: services.h:314
MDE void moduleSetOperHelp(void(*func)(User *u))
Definition: modules.c:2126
#define MOD_CONT
Definition: modules.h:54
E int32 total_written
Definition: extern.h:1123
#define CAPAB_CHANMODE
Definition: services.h:1394
E SList akills
Definition: extern.h:970
E int is_services_admin(User *u)
Definition: operserv.c:591
E void get_user_stats(long *nusers, long *memuse)
Definition: users.c:285
E char * s_HostServ
Definition: extern.h:303
E void get_session_stats(long *nrec, long *memuse)
Definition: sessions.c:69
E int AutokillExpiry
Definition: extern.h:439
E int32 total_read
Definition: extern.h:1123
E void get_aliases_stats(long *nrec, long *memuse)
Definition: nickserv.c:155
Definition: modules.h:99
E Server * serv_uplink
Definition: extern.h:1053
MDE Command * createCommand(const char *name, int(*func)(User *u), int(*has_priv)(User *u), int help_all, int help_reg, int help_oper, int help_admin, int help_root)
Definition: modules.c:987
struct sxline_ SXLine
Definition: services.h:235
E SList szlines
Definition: extern.h:970
E void get_exception_stats(long *nrec, long *memuse)
Definition: sessions.c:86
int16 capacity
Definition: slist.h:24
E int strftime_lang(char *buf, int size, User *u, int format, struct tm *tm)
Definition: language.c:240
int sgline
Definition: services.h:313
E SList sqlines
Definition: extern.h:970
MDE int moduleAddCommand(CommandHash *cmdTable[], Command *c, int pos)
Definition: modules.c:1082
char * reason
Definition: services.h:1097
E int SGLineExpiry
Definition: extern.h:441
static void get_operserv_stats(long *nrec, long *memuse)
Definition: os_stats.c:386
int AnopeInit(int argc, char **argv)
Definition: os_stats.c:29
#define MOD_UNIQUE
Definition: module.h:11
static int do_stats(User *u)
Definition: os_stats.c:91