ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/modules/m_stats.c
(Generate patch)

Comparing:
ircd-hybrid-7.2/modules/m_stats.c (file contents), Revision 560 by michael, Sun Apr 23 06:38:25 2006 UTC vs.
ircd-hybrid-8/modules/m_stats.c (file contents), Revision 1369 by michael, Wed Apr 25 19:04:19 2012 UTC

# Line 23 | Line 23
23   */
24  
25   #include "stdinc.h"
26 < #include "tools.h"       /* dlink_node/dlink_list */
27 < #include "handlers.h"    /* m_pass prototype */
26 > #include "list.h"        /* dlink_node/dlink_list */
27 > #include "balloc.h"
28   #include "client.h"      /* Client */
29 #include "common.h"      /* TRUE/FALSE */
29   #include "irc_string.h"  
30   #include "ircd.h"        /* me */
31   #include "listener.h"    /* show_ports */
32   #include "s_gline.h"
34 #include "ircd_handler.h"
35 #include "msg.h"         /* Message */
33   #include "hostmask.h"
34   #include "numeric.h"     /* ERR_xxx */
35   #include "send.h"        /* sendto_one */
36   #include "fdlist.h"      /* PF and friends */
37   #include "s_bsd.h"       /* highest_fd */
38 < #include "s_conf.h"      /* AccessItem, report_configured_links */
38 > #include "conf.h"      /* AccessItem, report_configured_links */
39   #include "s_misc.h"      /* serv_info */
40   #include "s_serv.h"      /* hunt_server */
44 #include "s_stats.h"     /* tstats */
41   #include "s_user.h"      /* show_opers */
42   #include "event.h"       /* events */
43   #include "dbuf.h"
44 + #include "hook.h"
45   #include "parse.h"
46   #include "modules.h"
50 #include "hook.h"
47   #include "resv.h"  /* report_resv */
48   #include "whowas.h"
49 < #include "list.h"
50 <
55 < static void do_stats(struct Client *, int, char **);
56 < static void m_stats(struct Client *, struct Client *, int, char *[]);
57 < static void mo_stats(struct Client *, struct Client *, int, char *[]);
58 < static void ms_stats(struct Client *, struct Client *, int, char *[]);
59 <
60 < struct Message stats_msgtab = {
61 <  "STATS", 0, 0, 2, 0, MFLG_SLOW, 0,
62 <  { m_unregistered, m_stats, ms_stats, m_ignore, mo_stats, m_ignore }
63 < };
64 <
65 < #ifndef STATIC_MODULES
66 < const char *_version = "$Revision$";
67 < static struct Callback *stats_cb;
68 <
69 < static void *
70 < va_stats(va_list args)
71 < {
72 <  struct Client *source_p = va_arg(args, struct Client *);
73 <  int parc = va_arg(args, int);
74 <  char **parv = va_arg(args, char **);
75 <
76 <  do_stats(source_p, parc, parv);
77 <  return NULL;
78 < }
79 <
80 < void
81 < _modinit(void)
82 < {
83 <  stats_cb = register_callback("doing_stats", va_stats);
84 <  mod_add_cmd(&stats_msgtab);
85 < }
49 > #include "watch.h"
50 > #include "irc_res.h"
51  
87 void
88 _moddeinit(void)
89 {
90  mod_del_cmd(&stats_msgtab);
91  uninstall_hook(stats_cb, va_stats);
92 }
93 #endif
52  
53   static char *parse_stats_args(int, char **, int *, int *);
54   static void stats_L(struct Client *, char *, int, int, char);
55 < static void stats_L_list(struct Client *s, char *, int, int, dlink_list *, char);
98 <
55 > static void stats_L_list(struct Client *, char *, int, int, dlink_list *, char);
56   static void stats_dns_servers(struct Client *);
57   static void stats_connect(struct Client *);
58   static void stats_deny(struct Client *);
# Line 115 | Line 72 | static void stats_operedup(struct Client
72   static void stats_ports(struct Client *);
73   static void stats_resv(struct Client *);
74   static void stats_usage(struct Client *);
75 + static void stats_service(struct Client *);
76   static void stats_tstats(struct Client *);
77   static void stats_uptime(struct Client *);
78   static void stats_shared(struct Client *);
# Line 124 | Line 82 | static void stats_class(struct Client *)
82   static void stats_memory(struct Client *);
83   static void stats_servlinks(struct Client *);
84   static void stats_ltrace(struct Client *, int, char **);
127 static void stats_ziplinks(struct Client *);
85  
86   /* This table contains the possible stats items, in order:
87   * /stats name,  function to call, operonly? adminonly? /stats letter
# Line 137 | Line 94 | static const struct StatsStruct
94    const unsigned int need_admin;
95   } stats_cmd_table[] = {
96    /* letter     function            need_oper need_admin */
97 <  { 'a',        stats_dns_servers,      1,      1,      },
98 <  { 'A',        stats_dns_servers,      1,      1,      },
99 <  { 'c',        stats_connect,          1,      0,      },
100 <  { 'C',        stats_connect,          1,      0,      },
101 <  { 'd',        stats_tdeny,            1,      0,      },
102 <  { 'D',        stats_deny,             1,      0,      },
103 <  { 'e',        stats_exempt,           1,      0,      },
104 <  { 'E',        stats_events,           1,      1,      },
105 <  { 'f',        fd_dump,                1,      1,      },
106 <  { 'F',        fd_dump,                1,      1,      },
107 <  { 'g',        stats_pending_glines,   1,      0,      },
108 <  { 'G',        stats_glines,           1,      0,      },
109 <  { 'h',        stats_hooks,            1,      1,      },
110 <  { 'H',        stats_hubleaf,          1,      0,      },
111 <  { 'i',        stats_auth,             0,      0,      },
112 <  { 'I',        stats_auth,             0,      0,      },
113 <  { 'k',        stats_tklines,          0,      0,      },
114 <  { 'K',        stats_klines,           0,      0,      },
115 <  { 'l',        stats_ltrace,           1,      0,      },
116 <  { 'L',        stats_ltrace,           1,      0,      },
117 <  { 'm',        stats_messages,         0,      0,      },
118 <  { 'M',        stats_messages,         0,      0,      },
119 <  { 'o',        stats_oper,             0,      0,      },
120 <  { 'O',        stats_oper,             0,      0,      },
121 <  { 'p',        stats_operedup,         0,      0,      },
122 <  { 'P',        stats_ports,            0,      0,      },
123 <  { 'q',        stats_resv,             1,      0,      },
124 <  { 'Q',        stats_resv,             1,      0,      },
125 <  { 'r',        stats_usage,            1,      0,      },
126 <  { 'R',        stats_usage,            1,      0,      },
127 <  { 't',        stats_tstats,           1,      0,      },
128 <  { 'T',        stats_tstats,           1,      0,      },
129 <  { 'u',        stats_uptime,           0,      0,      },
130 <  { 'U',        stats_shared,           1,      0,      },
131 <  { 'v',        stats_servers,          1,      0,      },
132 <  { 'V',        stats_gdeny,            1,      0,      },
133 <  { 'x',        stats_gecos,            1,      0,      },
134 <  { 'X',        stats_gecos,            1,      0,      },
135 <  { 'y',        stats_class,            1,      0,      },
136 <  { 'Y',        stats_class,            1,      0,      },
137 <  { 'z',        stats_memory,           1,      0,      },
138 <  { 'Z',        stats_ziplinks,         1,      0,      },
139 <  { '?',        stats_servlinks,        0,      0,      },
140 <  { '\0',       (void(*)())0,           0,      0,      }
97 >  { 'a',        stats_dns_servers,      1,      1       },
98 >  { 'A',        stats_dns_servers,      1,      1       },
99 >  { 'c',        stats_connect,          1,      0       },
100 >  { 'C',        stats_connect,          1,      0       },
101 >  { 'd',        stats_tdeny,            1,      0       },
102 >  { 'D',        stats_deny,             1,      0       },
103 >  { 'e',        stats_exempt,           1,      0       },
104 >  { 'E',        stats_events,           1,      1       },
105 >  { 'f',        fd_dump,                1,      1       },
106 >  { 'F',        fd_dump,                1,      1       },
107 >  { 'g',        stats_pending_glines,   1,      0       },
108 >  { 'G',        stats_glines,           1,      0       },
109 >  { 'h',        stats_hooks,            1,      1       },
110 >  { 'H',        stats_hubleaf,          1,      0       },
111 >  { 'i',        stats_auth,             0,      0       },
112 >  { 'I',        stats_auth,             0,      0       },
113 >  { 'k',        stats_tklines,          0,      0       },
114 >  { 'K',        stats_klines,           0,      0       },
115 >  { 'l',        stats_ltrace,           1,      0       },
116 >  { 'L',        stats_ltrace,           1,      0       },
117 >  { 'm',        stats_messages,         0,      0       },
118 >  { 'M',        stats_messages,         0,      0       },
119 >  { 'o',        stats_oper,             0,      0       },
120 >  { 'O',        stats_oper,             0,      0       },
121 >  { 'p',        stats_operedup,         0,      0       },
122 >  { 'P',        stats_ports,            0,      0       },
123 >  { 'q',        stats_resv,             1,      0       },
124 >  { 'Q',        stats_resv,             1,      0       },
125 >  { 'r',        stats_usage,            1,      0       },
126 >  { 'R',        stats_usage,            1,      0       },
127 >  { 'S',        stats_service,          1,      0       },
128 >  { 't',        stats_tstats,           1,      0       },
129 >  { 'T',        stats_tstats,           1,      0       },
130 >  { 'u',        stats_uptime,           0,      0       },
131 >  { 'U',        stats_shared,           1,      0       },
132 >  { 'v',        stats_servers,          1,      0       },
133 >  { 'V',        stats_gdeny,            1,      0       },
134 >  { 'x',        stats_gecos,            1,      0       },
135 >  { 'X',        stats_gecos,            1,      0       },
136 >  { 'y',        stats_class,            1,      0       },
137 >  { 'Y',        stats_class,            1,      0       },
138 >  { 'z',        stats_memory,           1,      0       },
139 >  { '?',        stats_servlinks,        0,      0       },
140 >  { '\0',       NULL,                   0,      0       }
141   };
142  
143   const char *from, *to;
144  
145   static void
146 < do_stats(struct Client *source_p, int parc, char **parv)
146 > do_stats(struct Client *source_p, int parc, char *parv[])
147   {
148 +  const struct StatsStruct *tab = stats_cmd_table;
149    char statchar = *parv[1];
192  int i;
150  
151    if (statchar == '\0')
152    {
# Line 198 | Line 155 | do_stats(struct Client *source_p, int pa
155      return;
156    }
157  
158 <  for (i = 0; stats_cmd_table[i].handler; i++)
158 >  for (; tab->handler; ++tab)
159    {
160 <    if (stats_cmd_table[i].letter == statchar)
160 >    if (tab->letter == statchar)
161      {
162        /* The stats table says what privs are needed, so check --fl_ */
163 <      if ((stats_cmd_table[i].need_admin && !IsAdmin(source_p)) ||
164 <          (stats_cmd_table[i].need_oper && !IsOper(source_p)))
163 >      if ((tab->need_admin && !HasUMode(source_p, UMODE_ADMIN)) ||
164 >          (tab->need_oper && !HasUMode(source_p, UMODE_OPER)))
165        {
166          sendto_one(source_p, form_str(ERR_NOPRIVILEGES),
167                     from, to);
# Line 213 | Line 170 | do_stats(struct Client *source_p, int pa
170  
171        /* Blah, stats L needs the parameters, none of the others do.. */
172        if (statchar == 'L' || statchar == 'l')
173 <        stats_cmd_table[i].handler(source_p, parc, parv);
173 >      {
174 >        sendto_realops_flags(UMODE_SPY, L_ALL,
175 >                             "STATS %c requested by %s (%s@%s) [%s] on %s",
176 >                             statchar, source_p->name, source_p->username,
177 >                             source_p->host, source_p->servptr->name,
178 >                             parc > 2 ? parv[2] : "<no recipient>");
179 >        tab->handler(source_p, parc, parv);
180 >      }
181        else
182 <        stats_cmd_table[i].handler(source_p);
182 >      {
183 >        sendto_realops_flags(UMODE_SPY, L_ALL,
184 >                             "STATS %c requested by %s (%s@%s) [%s]",
185 >                             statchar, source_p->name, source_p->username,
186 >                             source_p->host, source_p->servptr->name);
187 >        tab->handler(source_p);
188 >      }
189  
190        break;
191      }
# Line 242 | Line 212 | m_stats(struct Client *client_p, struct
212  
213    /* Is the stats meant for us? */
214    if (!ConfigFileEntry.disable_remote)
215 <    if (hunt_server(client_p,source_p,":%s STATS %s :%s",2,parc,parv) != HUNTED_ISME)
215 >    if (hunt_server(client_p, source_p, ":%s STATS %s :%s", 2,
216 >                    parc, parv) != HUNTED_ISME)
217        return;
218  
219    if (!MyClient(source_p) && IsCapable(source_p->from, CAP_TS6) && HasID(source_p))
# Line 263 | Line 234 | m_stats(struct Client *client_p, struct
234                 from, to);
235      return;
236    }
266  else
267    last_used = CurrentTime;
237  
238 < #ifdef STATIC_MODULES
238 >  last_used = CurrentTime;
239 >
240    do_stats(source_p, parc, parv);
271 #else
272  execute_callback(stats_cb, source_p, parc, parv);
273 #endif
241   }
242  
243   /*
# Line 301 | Line 268 | mo_stats(struct Client *client_p, struct
268      to = source_p->name;
269    }
270  
304 #ifdef STATIC_MODULES
271    do_stats(source_p, parc, parv);
272 < #else
273 <  execute_callback(stats_cb, source_p, parc, parv);
274 < #endif
272 > }
273 >
274 > /*
275 > * ms_stats - STATS message handler
276 > *      parv[0] = sender prefix
277 > *      parv[1] = statistics selector (defaults to Message frequency)
278 > *      parv[2] = server name (current server defaulted, if omitted)
279 > */
280 > static void
281 > ms_stats(struct Client *client_p, struct Client *source_p,
282 >         int parc, char *parv[])
283 > {
284 >  if (hunt_server(client_p, source_p, ":%s STATS %s :%s", 2,
285 >                  parc, parv) != HUNTED_ISME)
286 >    return;
287 >
288 >  if (IsClient(source_p))
289 >    mo_stats(client_p, source_p, parc, parv);
290   }
291  
292   /*
# Line 318 | Line 299 | mo_stats(struct Client *client_p, struct
299   static void
300   send_usage(struct Client *source_p)
301   {
321 #ifndef _WIN32
302    struct rusage rus;
303    time_t secs;
304    time_t rup;
# Line 344 | Line 324 | send_usage(struct Client *source_p)
324    if (secs == 0)
325      secs = 1;
326  
327 <  rup = (CurrentTime - me.since) * hzz;
327 >  rup = (CurrentTime - me.localClient->since) * hzz;
328  
329    if (rup == 0)
330      rup = 1;
# Line 370 | Line 350 | send_usage(struct Client *source_p)
350    sendto_one(source_p, ":%s %d %s R :Signals %d Context Vol. %d Invol %d",
351               me.name, RPL_STATSDEBUG, source_p->name, (int)rus.ru_nsignals,
352               (int)rus.ru_nvcsw, (int)rus.ru_nivcsw);
373 #endif
353   }
354  
355   static void
# Line 379 | Line 358 | count_memory(struct Client *source_p)
358    const dlink_node *gptr = NULL;
359    const dlink_node *dlink = NULL;
360  
361 <  int local_client_conf_count = 0;      /* local client conf links */
362 <  int users_counted = 0;                /* user structs */
361 >  unsigned int local_client_conf_count = 0;      /* local client conf links */
362 >  unsigned int users_counted = 0;                /* user structs */
363  
364 <  int channel_users = 0; /* XXX */
365 <  int channel_invites = 0;
366 <  int channel_bans = 0;
367 <  int channel_except = 0;
368 <  int channel_invex = 0;
369 <
370 <  int wwu = 0;                  /* whowas users */
371 <  int class_count = 0;          /* classes */
372 <  int users_invited_count = 0;  /* users invited */
373 <  int aways_counted = 0;
374 <  int number_ips_stored;        /* number of ip addresses hashed */
375 <
376 <  unsigned long channel_memory = 0;
377 <  size_t channel_ban_memory = 0;
378 <  size_t channel_except_memory = 0;
400 <  size_t channel_invex_memory = 0;
364 >  unsigned int channel_members = 0;
365 >  unsigned int channel_invites = 0;
366 >  unsigned int channel_bans = 0;
367 >  unsigned int channel_except = 0;
368 >  unsigned int channel_invex = 0;
369 >
370 >  unsigned int wwu = 0;                  /* whowas users */
371 >  unsigned int class_count = 0;          /* classes */
372 >  unsigned int aways_counted = 0;
373 >  unsigned int number_ips_stored;        /* number of ip addresses hashed */
374 >
375 >  uint64_t channel_memory = 0;
376 >  uint64_t channel_ban_memory = 0;
377 >  uint64_t channel_except_memory = 0;
378 >  uint64_t channel_invex_memory = 0;
379  
380    unsigned int safelist_count = 0;
381 <  size_t safelist_memory = 0;
381 >  uint64_t safelist_memory = 0;
382 >
383 >  uint64_t away_memory = 0;       /* memory used by aways           */
384 >  uint64_t wwm = 0;               /* whowas array memory used       */
385 >  uint64_t conf_memory = 0;       /* memory used by conf lines      */
386 >  uint64_t mem_ips_stored;        /* memory used by ip address hash */
387  
388 <  unsigned long away_memory = 0;       /* memory used by aways           */
389 <  unsigned long wwm = 0;               /* whowas array memory used       */
407 <  unsigned long conf_memory = 0;       /* memory used by conf lines      */
408 <  unsigned long mem_ips_stored;        /* memory used by ip address hash */
409 <
410 <  unsigned long client_hash_table_size = 0;
411 <  unsigned long channel_hash_table_size = 0;
412 <  unsigned long resv_hash_table_size = 0;
413 <  unsigned long id_hash_table_size = 0;
414 <  unsigned long total_channel_memory = 0;
415 <  unsigned long totww = 0;
388 >  uint64_t total_channel_memory = 0;
389 >  uint64_t totww = 0;
390  
391    unsigned int local_client_count  = 0;
392    unsigned int remote_client_count = 0;
393  
394 <  unsigned int local_client_memory_used  = 0;
395 <  unsigned int remote_client_memory_used = 0;
394 >  uint64_t local_client_memory_used  = 0;
395 >  uint64_t remote_client_memory_used = 0;
396  
397 <  unsigned long total_memory = 0;
397 >  uint64_t total_memory = 0;
398    unsigned int topic_count = 0;
399  
400 <  count_whowas_memory(&wwu, &wwm);
400 >  unsigned int watch_list_headers = 0;   /* watchlist headers     */
401 >  unsigned int watch_list_entries = 0;   /* watchlist entries     */
402 >  uint64_t watch_list_memory = 0; /* watchlist memory used */
403 >
404  
405    DLINK_FOREACH(gptr, global_client_list.head)
406    {
# Line 433 | Line 410 | count_memory(struct Client *source_p)
410      {
411        ++local_client_count;
412        local_client_conf_count += dlink_list_length(&target_p->localClient->confs);
413 <      users_invited_count += dlink_list_length(&target_p->localClient->invited);
413 >      watch_list_entries += dlink_list_length(&target_p->localClient->watches);
414      }
415      else
416        ++remote_client_count;
# Line 455 | Line 432 | count_memory(struct Client *source_p)
432                     sizeof(struct Channel);
433    DLINK_FOREACH(gptr, global_channel_list.head)
434    {
435 <    struct Ban *actualBan;
436 <    struct Channel *chptr = gptr->data;
435 >    const struct Ban *actualBan;
436 >    const struct Channel *chptr = gptr->data;
437  
438 <    channel_users   += dlink_list_length(&chptr->members);
438 >    channel_members += dlink_list_length(&chptr->members);
439      channel_invites += dlink_list_length(&chptr->invites);
440  
441 <    if (chptr->topic != NULL)
441 >    if (chptr->topic[0])
442        ++topic_count;
443  
444 <    if ((channel_bans = dlink_list_length(&chptr->banlist)))
445 <    {
469 <      channel_ban_memory = channel_bans * sizeof(struct Ban);
444 >    channel_bans += dlink_list_length(&chptr->banlist);
445 >    channel_ban_memory += dlink_list_length(&chptr->banlist) * sizeof(struct Ban);
446  
447 <      DLINK_FOREACH(dlink, chptr->banlist.head)
448 <      {
449 <        actualBan = dlink->data;
450 <        assert(actualBan->who);
447 >    DLINK_FOREACH(dlink, chptr->banlist.head)
448 >    {
449 >      actualBan = dlink->data;
450 >      assert(actualBan->who);
451  
452 <        channel_ban_memory += actualBan->len + 3;
453 <        channel_ban_memory += strlen(actualBan->who) + 1;
478 <      }
452 >      channel_ban_memory += actualBan->len + 1;
453 >      channel_ban_memory += strlen(actualBan->who) + 1;
454      }
455  
456 <    if ((channel_except = dlink_list_length(&chptr->exceptlist)))
457 <    {
483 <      channel_except_memory = channel_except * sizeof(struct Ban);
456 >    channel_except += dlink_list_length(&chptr->exceptlist);
457 >    channel_except_memory += dlink_list_length(&chptr->exceptlist) * sizeof(struct Ban);
458  
459 <      DLINK_FOREACH(dlink, chptr->exceptlist.head)
460 <      {
461 <        actualBan = dlink->data;
462 <        assert(actualBan->who);
459 >    DLINK_FOREACH(dlink, chptr->exceptlist.head)
460 >    {
461 >      actualBan = dlink->data;
462 >      assert(actualBan->who);
463  
464 <        channel_except_memory += actualBan->len + 3;
465 <        channel_except_memory += strlen(actualBan->who) + 1;
492 <      }
464 >      channel_except_memory += actualBan->len + 1;
465 >      channel_except_memory += strlen(actualBan->who) + 1;
466      }
467  
468 <    if ((channel_invex = dlink_list_length(&chptr->invexlist)))
469 <    {
497 <      channel_invex_memory = channel_invex * sizeof(struct Ban);
468 >    channel_invex += dlink_list_length(&chptr->invexlist);
469 >    channel_invex_memory += dlink_list_length(&chptr->invexlist) * sizeof(struct Ban);
470  
471 <      DLINK_FOREACH(dlink, chptr->invexlist.head)
472 <      {
473 <        actualBan = dlink->data;
474 <        assert(actualBan->who);
471 >    DLINK_FOREACH(dlink, chptr->invexlist.head)
472 >    {
473 >      actualBan = dlink->data;
474 >      assert(actualBan->who);
475  
476 <        channel_invex_memory += actualBan->len + 3;
477 <        channel_invex_memory += strlen(actualBan->who) + 1;
506 <      }
476 >      channel_invex_memory += actualBan->len + 1;
477 >      channel_invex_memory += strlen(actualBan->who) + 1;
478      }
479    }
480  
# Line 512 | Line 483 | count_memory(struct Client *source_p)
483      safelist_memory = safelist_count * sizeof(struct ListTask);
484      DLINK_FOREACH(gptr, listing_client_list.head)
485      {
486 <      struct Client *acptr = gptr->data;
486 >      const struct Client *acptr = gptr->data;
487  
488        DLINK_FOREACH(dlink, acptr->localClient->list_task->show_mask.head)
489          safelist_memory += strlen(dlink->data);
# Line 537 | Line 508 | count_memory(struct Client *source_p)
508    /* count up all classes */
509    class_count = dlink_list_length(&class_items);
510  
511 <  sendto_one(source_p, ":%s %d %s z :Clients %u(%lu) Invites %u(%lu)",
511 >  count_whowas_memory(&wwu, &wwm);
512 >  watch_count_memory(&watch_list_headers, &watch_list_memory);
513 >
514 >  sendto_one(source_p, ":%s %d %s z :WATCH headers %u(%u) entries %d(%u)",
515 >             me.name, RPL_STATSDEBUG, source_p->name, watch_list_headers,
516 >             watch_list_memory, watch_list_entries,
517 >             watch_list_entries * sizeof(dlink_node) * 2);
518 >
519 >  sendto_one(source_p, ":%s %d %s z :Clients %u(%u)",
520               me.name, RPL_STATSDEBUG, source_p->name, users_counted,
521 <             (unsigned long)(users_counted * sizeof(struct Client)),
543 <             users_invited_count, (unsigned long)(users_invited_count * sizeof(dlink_node)));
521 >             (users_counted * sizeof(struct Client)));
522  
523 <  sendto_one(source_p, ":%s %d %s z :User aways %u(%d)",
523 >  sendto_one(source_p, ":%s %d %s z :User aways %u(%llu)",
524               me.name, RPL_STATSDEBUG, source_p->name,
525 <             aways_counted, (int)away_memory);
525 >             aways_counted, away_memory);
526  
527 <  sendto_one(source_p, ":%s %d %s z :Attached confs %u(%lu)",
527 >  sendto_one(source_p, ":%s %d %s z :Attached confs %u(%llu)",
528               me.name, RPL_STATSDEBUG, source_p->name,
529               local_client_conf_count,
530 <             (unsigned long)(local_client_conf_count * sizeof(dlink_node)));
553 <
554 <  /* XXX  ConfigItemList fix */
555 < #if 0
556 <  sendto_one(source_p, ":%s %d %s z :Conflines %lu(%d)",
557 <             me.name, RPL_STATSDEBUG, source_p->name,
558 <             dlink_list_length(&ConfigItemList), (int) conf_memory);
559 < #endif
530 >             (unsigned long long)(local_client_conf_count * sizeof(dlink_node)));
531  
532 <  sendto_one(source_p, ":%s %d %s z :Resv channels %lu(%lu) nicks %lu(%lu)",
532 >  sendto_one(source_p, ":%s %d %s z :Resv channels %u(%lu) nicks %u(%lu)",
533               me.name, RPL_STATSDEBUG, source_p->name,
534               dlink_list_length(&resv_channel_list),
535               dlink_list_length(&resv_channel_list) * sizeof(struct ResvChannel),
536               dlink_list_length(&nresv_items),
537               dlink_list_length(&nresv_items) * sizeof(struct MatchItem));
538  
539 <  sendto_one(source_p, ":%s %d %s z :Classes %u(%lu)",
539 >  sendto_one(source_p, ":%s %d %s z :Classes %u(%llu)",
540               me.name, RPL_STATSDEBUG, source_p->name,
541 <             class_count, (unsigned long)(class_count * sizeof(struct ClassItem)));
541 >             class_count, (unsigned long long)(class_count * sizeof(struct ClassItem)));
542  
543 <  sendto_one(source_p, ":%s %d %s z :Channels %lu(%lu) Topics %u(%d)",
543 >  sendto_one(source_p, ":%s %d %s z :Channels %uu(%llu) Topics %u(%u)",
544               me.name, RPL_STATSDEBUG, source_p->name,
545               dlink_list_length(&global_channel_list),
546               channel_memory, topic_count, topic_count *
547               (TOPICLEN + 1 + USERHOST_REPLYLEN));
548  
549 <  sendto_one(source_p, ":%s %d %s z :Bans %u(%u)",
549 >  sendto_one(source_p, ":%s %d %s z :Bans %u(%llu)",
550               me.name, RPL_STATSDEBUG, source_p->name,
551               channel_bans, channel_ban_memory);
552  
553 <  sendto_one(source_p, ":%s %d %s z :Exceptions %u(%u)",
553 >  sendto_one(source_p, ":%s %d %s z :Exceptions %u(%llu)",
554               me.name, RPL_STATSDEBUG, source_p->name,
555               channel_except, channel_except_memory);
556  
557 <  sendto_one(source_p, ":%s %d %s z :Invex %u(%u)",
557 >  sendto_one(source_p, ":%s %d %s z :Invex %u(%llu)",
558               me.name, RPL_STATSDEBUG, source_p->name,
559               channel_invex, channel_invex_memory);
560  
561 <  sendto_one(source_p, ":%s %d %s z :Channel members %u(%lu) invite %u(%lu)",
562 <             me.name, RPL_STATSDEBUG, source_p->name, channel_users,
563 <             (unsigned long)(channel_users * sizeof(struct Membership)),
564 <             channel_invites, (unsigned long)channel_invites *
565 <             sizeof(dlink_node));
561 >  sendto_one(source_p, ":%s %d %s z :Channel members %u(%llu) invites %u(%llu)",
562 >             me.name, RPL_STATSDEBUG, source_p->name, channel_members,
563 >             (unsigned long long)(channel_members * sizeof(struct Membership)),
564 >             channel_invites, (unsigned long long)channel_invites *
565 >             sizeof(dlink_node) * 2);
566  
567    total_channel_memory = channel_memory + channel_ban_memory +
568 <                         channel_users * sizeof(struct Membership) +
569 <                         channel_invites * sizeof(dlink_node);
568 >                         channel_members * sizeof(struct Membership) +
569 >                         (channel_invites * sizeof(dlink_node)*2);
570  
571 <  sendto_one(source_p, ":%s %d %s z :Safelist %u(%u)",
571 >  sendto_one(source_p, ":%s %d %s z :Safelist %u(%llu)",
572               me.name, RPL_STATSDEBUG, source_p->name,
573               safelist_count, safelist_memory);
574  
575 <  sendto_one(source_p, ":%s %d %s z :Whowas users %u(%lu)",
575 >  sendto_one(source_p, ":%s %d %s z :Whowas users %u(%llu)",
576               me.name, RPL_STATSDEBUG, source_p->name,
577 <             wwu, (unsigned long)(wwu * sizeof(struct Client)));
577 >             wwu, (unsigned long long)(wwu * sizeof(struct Client)));
578  
579 <  sendto_one(source_p, ":%s %d %s z :Whowas array %u(%d)",
579 >  sendto_one(source_p, ":%s %d %s z :Whowas array %u(%llu)",
580               me.name, RPL_STATSDEBUG, source_p->name,
581 <             NICKNAMEHISTORYLENGTH, (int)wwm);
581 >             NICKNAMEHISTORYLENGTH, wwm);
582  
583    totww = wwu * sizeof(struct Client) + wwm;
613 /****
614  client_hash_table_size  = hash_get_client_table_size();
615  channel_hash_table_size = hash_get_channel_table_size();
616  resv_hash_table_size    = hash_get_resv_table_size();
617  id_hash_table_size      = hash_get_id_table_size();
584  
619  sendto_one(source_p, ":%s %d %s z :Hash: client %u(%lu) chan %u(%lu) resv "
620             "%u(%lu) id %u(%lu)",
621             me.name, RPL_STATSDEBUG, source_p->name,
622             U_MAX, client_hash_table_size,
623             CH_MAX, channel_hash_table_size , R_MAX,
624             resv_hash_table_size, U_MAX, id_hash_table_size);
625 ****/
585    count_ip_hash(&number_ips_stored,&mem_ips_stored);
586 <  sendto_one(source_p, ":%s %d %s z :iphash %u(%d)",
586 >  sendto_one(source_p, ":%s %d %s z :iphash %u(%llu)",
587               me.name, RPL_STATSDEBUG, source_p->name,
588 <             number_ips_stored, (int)mem_ips_stored);
588 >             number_ips_stored, mem_ips_stored);
589  
590    total_memory = totww + total_channel_memory + conf_memory + class_count *
591                   sizeof(struct ClassItem);
592 <  total_memory += client_hash_table_size;
593 <  total_memory += channel_hash_table_size;
594 <  total_memory += resv_hash_table_size;
636 <  total_memory += id_hash_table_size;
637 <
638 <  sendto_one(source_p, ":%s %d %s z :Total: whowas %d channel %d conf %d",
639 <             me.name, RPL_STATSDEBUG, source_p->name, (int)totww,
640 <            (int)total_channel_memory, (int)conf_memory);
592 >  sendto_one(source_p, ":%s %d %s z :Total: whowas %llu channel %llu conf %llu",
593 >             me.name, RPL_STATSDEBUG, source_p->name, totww,
594 >             total_channel_memory, conf_memory);
595  
596    local_client_memory_used = local_client_count*(sizeof(struct Client) + sizeof(struct LocalUser));
597    total_memory += local_client_memory_used;
598 <  sendto_one(source_p, ":%s %d %s z :Local client Memory in use: %d(%d)",
598 >  sendto_one(source_p, ":%s %d %s z :Local client Memory in use: %u(%llu)",
599               me.name, RPL_STATSDEBUG, source_p->name, local_client_count,
600               local_client_memory_used);
601  
602    remote_client_memory_used = remote_client_count * sizeof(struct Client);
603    total_memory += remote_client_memory_used;
604 <  sendto_one(source_p, ":%s %d %s z :Remote client Memory in use: %d(%d)",
604 >  sendto_one(source_p, ":%s %d %s z :Remote client Memory in use: %u(%llu)",
605               me.name, RPL_STATSDEBUG, source_p->name, remote_client_count,
606               remote_client_memory_used);
607  
608    block_heap_report_stats(source_p);
609  
610    sendto_one(source_p,
611 <             ":%s %d %s z :TOTAL: %d Available:  Current max RSS: %lu",
611 >             ":%s %d %s z :TOTAL: %llu",
612               me.name, RPL_STATSDEBUG, source_p->name,
613 <             (int)total_memory, get_maxrss());
613 >             total_memory);
614   }
615  
616   static void
# Line 668 | Line 622 | stats_dns_servers(struct Client *source_
622   static void
623   stats_connect(struct Client *source_p)
624   {
625 <  report_confitem_types(source_p, SERVER_TYPE, 0);
625 >  report_confitem_types(source_p, SERVER_TYPE);
626   }
627  
628   /* stats_deny()
# Line 680 | Line 634 | stats_connect(struct Client *source_p)
634   static void
635   stats_deny(struct Client *source_p)
636   {
683  struct AddressRec *arec;
637    struct ConfItem *conf;
638    struct AccessItem *aconf;
639 <  int i;
639 >  dlink_node *ptr = NULL;
640 >  unsigned int i = 0;
641 >
642  
643 <  for (i = 0; i < ATABLE_SIZE; i++)
643 >  for (i = 0; i < ATABLE_SIZE; ++i)
644    {
645 <    for (arec = atable[i]; arec; arec=arec->next)
645 >    ptr = NULL;
646 >
647 >    DLINK_FOREACH(ptr, atable[i].head)
648      {
649 +      struct AddressRec *arec = ptr->data;
650 +
651        if (arec->type == CONF_DLINE)
652        {
653          aconf = arec->aconf;
# Line 716 | Line 675 | stats_deny(struct Client *source_p)
675   static void
676   stats_tdeny(struct Client *source_p)
677   {
719  struct AddressRec *arec;
678    struct ConfItem *conf;
679    struct AccessItem *aconf;
680 <  int i;
680 >  dlink_node *ptr = NULL;
681 >  unsigned int i = 0;
682 >
683  
684 <  for (i = 0; i < ATABLE_SIZE; i++)
684 >  for (i = 0; i < ATABLE_SIZE; ++i)
685    {
686 <    for (arec = atable[i]; arec; arec=arec->next)
686 >    ptr = NULL;
687 >
688 >    DLINK_FOREACH(ptr, atable[i].head)
689      {
690 +      struct AddressRec *arec = ptr->data;
691 +
692        if (arec->type == CONF_DLINE)
693        {
694          aconf = arec->aconf;
# Line 752 | Line 716 | stats_tdeny(struct Client *source_p)
716   static void
717   stats_exempt(struct Client *source_p)
718   {
755  struct AddressRec *arec;
719    struct ConfItem *conf;
720    struct AccessItem *aconf;
721 <  int i;
721 >  dlink_node *ptr = NULL;
722 >  unsigned int i = 0;
723  
724 <  for (i = 0; i < ATABLE_SIZE; i++)
724 >  if (ConfigFileEntry.stats_e_disabled)
725    {
726 <    for (arec = atable[i]; arec; arec=arec->next)
726 >    sendto_one(source_p, form_str(ERR_NOPRIVILEGES),
727 >               from, to);
728 >    return;
729 >  }
730 >
731 >
732 >  for (i = 0; i < ATABLE_SIZE; ++i)
733 >  {
734 >    ptr = NULL;
735 >
736 >    DLINK_FOREACH(ptr, atable[i].head)
737      {
738 +      struct AddressRec *arec = ptr->data;
739 +
740        if (arec->type == CONF_EXEMPTDLINE)
741        {
742          aconf = arec->aconf;
# Line 790 | Line 766 | stats_events(struct Client *source_p)
766   static void
767   stats_pending_glines(struct Client *source_p)
768   {
769 < #ifdef GLINE_VOTING
770 <  dlink_node *pending_node;
771 <  struct gline_pending *glp_ptr;
772 <  char timebuffer[MAX_DATE_STRING];
797 <  struct tm *tmptr;
769 >  const dlink_node *dn_ptr = NULL;
770 >  const struct gline_pending *glp_ptr = NULL;
771 >  char timebuffer[MAX_DATE_STRING] = { '\0' };
772 >  struct tm *tmptr = NULL;
773  
774    if (!ConfigFileEntry.glines)
775    {
# Line 803 | Line 778 | stats_pending_glines(struct Client *sour
778      return;
779    }
780  
781 <  if (dlink_list_length(&pending_glines) > 0)
781 >  if (dlink_list_length(&pending_glines[GLINE_PENDING_ADD_TYPE]) > 0)
782      sendto_one(source_p, ":%s NOTICE %s :Pending G-lines",
783                 from, to);
784  
785 <  DLINK_FOREACH(pending_node, pending_glines.head)
785 >  DLINK_FOREACH(dn_ptr, pending_glines[GLINE_PENDING_ADD_TYPE].head)
786    {
787 <    glp_ptr = pending_node->data;
788 <    tmptr   = localtime(&glp_ptr->time_request1);
787 >    glp_ptr = dn_ptr->data;
788 >    tmptr   = localtime(&glp_ptr->vote_1.time_request);
789      strftime(timebuffer, MAX_DATE_STRING, "%Y/%m/%d %H:%M:%S", tmptr);
790  
791      sendto_one(source_p,
792                 ":%s NOTICE %s :1) %s!%s@%s on %s requested gline at %s for %s@%s [%s]",
793 <               from, to, glp_ptr->oper_nick1,
794 <               glp_ptr->oper_user1, glp_ptr->oper_host1,
795 <               glp_ptr->oper_server1, timebuffer,
796 <               glp_ptr->user, glp_ptr->host, glp_ptr->reason1);
793 >               from, to, glp_ptr->vote_1.oper_nick,
794 >               glp_ptr->vote_1.oper_user, glp_ptr->vote_1.oper_host,
795 >               glp_ptr->vote_1.oper_server, timebuffer,
796 >               glp_ptr->user, glp_ptr->host, glp_ptr->vote_1.reason);
797  
798 <    if (glp_ptr->oper_nick2[0] != '\0')
798 >    if (glp_ptr->vote_2.oper_nick[0] != '\0')
799      {
800 <      tmptr = localtime(&glp_ptr->time_request2);
800 >      tmptr = localtime(&glp_ptr->vote_2.time_request);
801        strftime(timebuffer, MAX_DATE_STRING, "%Y/%m/%d %H:%M:%S", tmptr);
802        sendto_one(source_p,
803        ":%s NOTICE %s :2) %s!%s@%s on %s requested gline at %s for %s@%s [%s]",
804 <                 from, to, glp_ptr->oper_nick2,
805 <                 glp_ptr->oper_user2, glp_ptr->oper_host2,
806 <                 glp_ptr->oper_server2, timebuffer,
807 <                 glp_ptr->user, glp_ptr->host, glp_ptr->reason2);
804 >               from, to, glp_ptr->vote_2.oper_nick,
805 >               glp_ptr->vote_2.oper_user, glp_ptr->vote_2.oper_host,
806 >               glp_ptr->vote_2.oper_server, timebuffer,
807 >               glp_ptr->user, glp_ptr->host, glp_ptr->vote_2.reason);
808      }
809    }
810  
811    sendto_one(source_p, ":%s NOTICE %s :End of Pending G-lines",
812               from, to);
813 < #else
814 <  sendto_one(source_p, ":%s NOTICE %s :This server does not support G-Line voting",
813 >
814 >  if (dlink_list_length(&pending_glines[GLINE_PENDING_DEL_TYPE]) > 0)
815 >    sendto_one(source_p, ":%s NOTICE %s :Pending UNG-lines",
816 >               from, to);
817 >
818 >  DLINK_FOREACH(dn_ptr, pending_glines[GLINE_PENDING_DEL_TYPE].head)
819 >  {
820 >    glp_ptr = dn_ptr->data;
821 >    tmptr   = localtime(&glp_ptr->vote_1.time_request);
822 >    strftime(timebuffer, MAX_DATE_STRING, "%Y/%m/%d %H:%M:%S", tmptr);
823 >
824 >    sendto_one(source_p,
825 >               ":%s NOTICE %s :1) %s!%s@%s on %s requested ungline at %s for %s@%s [%s]",
826 >               from, to, glp_ptr->vote_1.oper_nick,
827 >               glp_ptr->vote_1.oper_user, glp_ptr->vote_1.oper_host,
828 >               glp_ptr->vote_1.oper_server, timebuffer,
829 >               glp_ptr->user, glp_ptr->host, glp_ptr->vote_1.reason);
830 >
831 >    if (glp_ptr->vote_2.oper_nick[0] != '\0')
832 >    {
833 >      tmptr = localtime(&glp_ptr->vote_2.time_request);
834 >      strftime(timebuffer, MAX_DATE_STRING, "%Y/%m/%d %H:%M:%S", tmptr);
835 >      sendto_one(source_p,
836 >      ":%s NOTICE %s :2) %s!%s@%s on %s requested ungline at %s for %s@%s [%s]",
837 >               from, to, glp_ptr->vote_2.oper_nick,
838 >               glp_ptr->vote_2.oper_user, glp_ptr->vote_2.oper_host,
839 >               glp_ptr->vote_2.oper_server, timebuffer,
840 >               glp_ptr->user, glp_ptr->host, glp_ptr->vote_2.reason);
841 >
842 >    }
843 >  }
844 >
845 >  sendto_one(source_p, ":%s NOTICE %s :End of Pending UNG-lines",
846               from, to);
841 #endif /* GLINE VOTING */
847   }
848  
849   /* stats_glines()
# Line 850 | Line 855 | stats_pending_glines(struct Client *sour
855   static void
856   stats_glines(struct Client *source_p)
857   {
858 <  struct AddressRec *arec = NULL;
859 <  int i = 0;
858 >  dlink_node *ptr = NULL;
859 >  unsigned int i = 0;
860  
861    if (!ConfigFileEntry.glines)
862    {
# Line 860 | Line 865 | stats_glines(struct Client *source_p)
865      return;
866    }
867  
868 <  for (; i < ATABLE_SIZE; ++i)
868 >  for (i = 0; i < ATABLE_SIZE; ++i)
869    {
870 <    for (arec = atable[i]; arec; arec=arec->next)
870 >    ptr = NULL;
871 >
872 >    DLINK_FOREACH(ptr, atable[i].head)
873      {
874 +      struct AddressRec *arec = ptr->data;
875 +
876        if (arec->type == CONF_GLINE)
877        {
878          const struct AccessItem *aconf = arec->aconf;
# Line 894 | Line 903 | stats_gdeny(struct Client *source_p)
903      return;
904    }
905  
906 <  report_confitem_types(source_p, GDENY_TYPE, 0);
906 >  report_confitem_types(source_p, GDENY_TYPE);
907   }
908  
909   static void
910   stats_hubleaf(struct Client *source_p)
911   {
912 <  report_confitem_types(source_p, HUB_TYPE, 0);
913 <  report_confitem_types(source_p, LEAF_TYPE, 0);
912 >  report_confitem_types(source_p, HUB_TYPE);
913 >  report_confitem_types(source_p, LEAF_TYPE);
914   }
915  
916   static void
917   stats_auth(struct Client *source_p)
918   {
919    /* Oper only, if unopered, return ERR_NOPRIVILEGES */
920 <  if ((ConfigFileEntry.stats_i_oper_only == 2) && !IsOper(source_p))
920 >  if ((ConfigFileEntry.stats_i_oper_only == 2) && !HasUMode(source_p, UMODE_OPER))
921      sendto_one(source_p, form_str(ERR_NOPRIVILEGES),
922                 from, to);
923  
924    /* If unopered, Only return matching auth blocks */
925 <  else if ((ConfigFileEntry.stats_i_oper_only == 1) && !IsOper(source_p))
925 >  else if ((ConfigFileEntry.stats_i_oper_only == 1) && !HasUMode(source_p, UMODE_OPER))
926    {
927      struct ConfItem *conf;
928      struct AccessItem *aconf;
# Line 950 | Line 959 | stats_tklines(struct Client *source_p)
959   {
960    struct ConfItem *conf;
961    /* Oper only, if unopered, return ERR_NOPRIVILEGES */
962 <  if ((ConfigFileEntry.stats_k_oper_only == 2) && !IsOper(source_p))
962 >  if ((ConfigFileEntry.stats_k_oper_only == 2) && !HasUMode(source_p, UMODE_OPER))
963      sendto_one(source_p, form_str(ERR_NOPRIVILEGES),
964                 from, to);
965  
966    /* If unopered, Only return matching klines */
967 <  else if ((ConfigFileEntry.stats_k_oper_only == 1) && !IsOper(source_p))
967 >  else if ((ConfigFileEntry.stats_k_oper_only == 1) && !HasUMode(source_p, UMODE_OPER))
968    {
969      struct AccessItem *aconf;
970  
971      if (MyConnect(source_p))
972        aconf = find_conf_by_address(source_p->host,
973                                     &source_p->localClient->ip,
974 <                                   CONF_KILL,
974 >                                   CONF_KLINE,
975                                     source_p->localClient->aftype,
976                                     source_p->username, NULL);
977      else
978 <      aconf = find_conf_by_address(source_p->host, NULL, CONF_KILL,
978 >      aconf = find_conf_by_address(source_p->host, NULL, CONF_KLINE,
979                                     0, source_p->username, NULL);
980  
981      if (aconf == NULL)
# Line 984 | Line 993 | stats_tklines(struct Client *source_p)
993    /* Theyre opered, or allowed to see all klines */
994    else {
995      report_Klines(source_p, 1);
987    report_confitem_types(source_p, RKLINE_TYPE, 1);
996    }
997   }
998  
# Line 992 | Line 1000 | static void
1000   stats_klines(struct Client *source_p)
1001   {
1002    /* Oper only, if unopered, return ERR_NOPRIVILEGES */
1003 <  if ((ConfigFileEntry.stats_k_oper_only == 2) && !IsOper(source_p))
1003 >  if ((ConfigFileEntry.stats_k_oper_only == 2) && !HasUMode(source_p, UMODE_OPER))
1004      sendto_one(source_p, form_str(ERR_NOPRIVILEGES),
1005                 from, to);
1006  
1007    /* If unopered, Only return matching klines */
1008 <  else if ((ConfigFileEntry.stats_k_oper_only == 1) && !IsOper(source_p))
1008 >  else if ((ConfigFileEntry.stats_k_oper_only == 1) && !HasUMode(source_p, UMODE_OPER))
1009    {
1010      struct AccessItem *aconf;
1011  
# Line 1005 | Line 1013 | stats_klines(struct Client *source_p)
1013      if (MyConnect(source_p))
1014        aconf = find_conf_by_address(source_p->host,
1015                                     &source_p->localClient->ip,
1016 <                                   CONF_KILL,
1016 >                                   CONF_KLINE,
1017                                     source_p->localClient->aftype,
1018                                     source_p->username, NULL);
1019      else
1020 <      aconf = find_conf_by_address(source_p->host, NULL, CONF_KILL,
1020 >      aconf = find_conf_by_address(source_p->host, NULL, CONF_KLINE,
1021                                     0, source_p->username, NULL);
1022  
1023      if (aconf == NULL)
# Line 1026 | Line 1034 | stats_klines(struct Client *source_p)
1034    /* Theyre opered, or allowed to see all klines */
1035    else {
1036      report_Klines(source_p, 0);
1037 <    report_confitem_types(source_p, RKLINE_TYPE, 0);
1037 >    report_confitem_types(source_p, RKLINE_TYPE);
1038    }
1039   }
1040  
# Line 1039 | Line 1047 | stats_messages(struct Client *source_p)
1047   static void
1048   stats_oper(struct Client *source_p)
1049   {
1050 <  if (!IsOper(source_p) && ConfigFileEntry.stats_o_oper_only)
1050 >  if (!HasUMode(source_p, UMODE_OPER) && ConfigFileEntry.stats_o_oper_only)
1051      sendto_one(source_p, form_str(ERR_NOPRIVILEGES),
1052                 from, to);
1053    else
1054 <    report_confitem_types(source_p, OPER_TYPE, 0);
1054 >    report_confitem_types(source_p, OPER_TYPE);
1055   }
1056  
1057   /* stats_operedup()
# Line 1061 | Line 1069 | stats_operedup(struct Client *source_p)
1069    {
1070      const struct Client *target_p = ptr->data;
1071  
1072 <    if (IsOperHidden(target_p) && !IsOper(source_p))
1072 >    if (HasUMode(target_p, UMODE_HIDDEN) && !HasUMode(source_p, UMODE_OPER))
1073        continue;
1074  
1075 <    if (MyClient(source_p) && IsOper(source_p))
1075 >    if (MyClient(source_p) && HasUMode(source_p, UMODE_OPER))
1076        sendto_one(source_p, ":%s %d %s p :[%c][%s] %s (%s@%s) Idle: %d",
1077                   from, RPL_STATSDEBUG, to,
1078 <                 IsAdmin(target_p) ?
1071 <                 (IsOperHiddenAdmin(target_p) ? 'O' : 'A') : 'O',
1078 >                 HasUMode(target_p, UMODE_ADMIN) ? 'A' : 'O',
1079                   oper_privs_as_string(target_p->localClient->operflags),
1080                   target_p->name, target_p->username, target_p->host,
1081 <                 (int)(CurrentTime - target_p->localClient->last));
1081 >                 (int)(CurrentTime - target_p->localClient->last_privmsg));
1082      else
1083        sendto_one(source_p, ":%s %d %s p :[%c] %s (%s@%s) Idle: %d",
1084                   from, RPL_STATSDEBUG, to,
1085 <                 IsAdmin(target_p) ?
1079 <                 (IsOperHiddenAdmin(target_p) ? 'O' : 'A') : 'O',
1085 >                 HasUMode(target_p, UMODE_ADMIN) ? 'A' : 'O',
1086                   target_p->name, target_p->username, target_p->host,
1087 <                 (int)(CurrentTime - target_p->localClient->last));
1087 >                 (int)(CurrentTime - target_p->localClient->last_privmsg));
1088    }
1089  
1090    sendto_one(source_p, ":%s %d %s p :%lu OPER(s)",
# Line 1088 | Line 1094 | stats_operedup(struct Client *source_p)
1094   static void
1095   stats_ports(struct Client *source_p)
1096   {
1097 <  if (!IsOper(source_p) && ConfigFileEntry.stats_P_oper_only)
1097 >  if (!HasUMode(source_p, UMODE_OPER) && ConfigFileEntry.stats_P_oper_only)
1098      sendto_one(source_p, form_str(ERR_NOPRIVILEGES),
1099                 from, to);
1100    else
# Line 1108 | Line 1114 | stats_usage(struct Client *source_p)
1114   }
1115  
1116   static void
1117 + stats_service(struct Client *source_p)
1118 + {
1119 +  report_confitem_types(source_p, SERVICE_TYPE);
1120 + }
1121 +
1122 + static void
1123   stats_tstats(struct Client *source_p)
1124   {
1125 <  tstats(source_p);
1125 >  const struct Client *target_p = NULL;
1126 >  const dlink_node *ptr = NULL;
1127 >  struct ServerStatistics *sp;
1128 >  struct ServerStatistics tmp;
1129 >
1130 >  sp = &tmp;
1131 >  memcpy(sp, &ServerStats, sizeof(struct ServerStatistics));
1132 >
1133 >  /*
1134 >   * must use the += operator. is_sv is not the number of currently
1135 >   * active server connections. Note the incrementation in
1136 >   * s_bsd.c:close_connection.
1137 >   */
1138 >  sp->is_sv += dlink_list_length(&serv_list);
1139 >
1140 >  DLINK_FOREACH(ptr, serv_list.head)
1141 >  {
1142 >    target_p = ptr->data;
1143 >
1144 >    sp->is_sbs += target_p->localClient->send.bytes;
1145 >    sp->is_sbr += target_p->localClient->recv.bytes;
1146 >    sp->is_sti += CurrentTime - target_p->localClient->firsttime;
1147 >  }
1148 >
1149 >  sp->is_cl += dlink_list_length(&local_client_list);
1150 >
1151 >  DLINK_FOREACH(ptr, local_client_list.head)
1152 >  {
1153 >    target_p = ptr->data;
1154 >
1155 >    sp->is_cbs += target_p->localClient->send.bytes;
1156 >    sp->is_cbr += target_p->localClient->recv.bytes;
1157 >    sp->is_cti += CurrentTime - target_p->localClient->firsttime;
1158 >  }
1159 >
1160 >  sp->is_ni += dlink_list_length(&unknown_list);
1161 >
1162 >  sendto_one(source_p, ":%s %d %s T :accepts %u refused %u",
1163 >             me.name, RPL_STATSDEBUG, source_p->name, sp->is_ac, sp->is_ref);
1164 >  sendto_one(source_p, ":%s %d %s T :unknown commands %u prefixes %u",
1165 >             me.name, RPL_STATSDEBUG, source_p->name, sp->is_unco, sp->is_unpf);
1166 >  sendto_one(source_p, ":%s %d %s T :nick collisions %u unknown closes %u",
1167 >             me.name, RPL_STATSDEBUG, source_p->name, sp->is_kill, sp->is_ni);
1168 >  sendto_one(source_p, ":%s %d %s T :wrong direction %u empty %u",
1169 >             me.name, RPL_STATSDEBUG, source_p->name, sp->is_wrdi, sp->is_empt);
1170 >  sendto_one(source_p, ":%s %d %s T :numerics seen %u",
1171 >             me.name, RPL_STATSDEBUG, source_p->name, sp->is_num);
1172 >  sendto_one(source_p, ":%s %d %s T :auth successes %u fails %u",
1173 >             me.name, RPL_STATSDEBUG, source_p->name, sp->is_asuc, sp->is_abad);
1174 >  sendto_one(source_p, ":%s %d %s T :Client Server",
1175 >             me.name, RPL_STATSDEBUG, source_p->name);
1176 >
1177 >  sendto_one(source_p, ":%s %d %s T :connected %u %u",
1178 >             me.name, RPL_STATSDEBUG, source_p->name,
1179 >             (unsigned int)sp->is_cl,
1180 >             (unsigned int)sp->is_sv);
1181 >  sendto_one(source_p, ":%s %d %s T :bytes sent %llu %llu",
1182 >             me.name, RPL_STATSDEBUG, source_p->name,
1183 >             sp->is_cbs, sp->is_sbs);
1184 >  sendto_one(source_p, ":%s %d %s T :bytes recv %llu %llu",
1185 >             me.name, RPL_STATSDEBUG, source_p->name,
1186 >             sp->is_cbr, sp->is_sbr);
1187 >  sendto_one(source_p, ":%s %d %s T :time connected %u %u",
1188 >             me.name, RPL_STATSDEBUG, source_p->name,
1189 >             (unsigned int)sp->is_cti,
1190 >             (unsigned int)sp->is_sti);
1191   }
1192  
1193   static void
1194   stats_uptime(struct Client *source_p)
1195   {
1196 <  time_t now = CurrentTime - me.since;
1196 >  time_t now = CurrentTime - me.localClient->since;
1197 >
1198    sendto_one(source_p, form_str(RPL_STATSUPTIME), from, to,
1199 <             now/86400, (now/3600)%24, (now/60)%60, now%60);
1200 <  if (!ConfigFileEntry.disable_remote || IsOper(source_p))
1199 >             now / 86400, (now / 3600) % 24, (now / 60) % 60, now % 60);
1200 >
1201 >  if (!ConfigFileEntry.disable_remote || HasUMode(source_p, UMODE_OPER))
1202       sendto_one(source_p, form_str(RPL_STATSCONN), from, to,
1203 <                MaxConnectionCount, MaxClientCount, Count.totalrestartcount);
1203 >                Count.max_loc_con, Count.max_loc_cli, Count.totalrestartcount);
1204   }
1205  
1206   static void
1207   stats_shared(struct Client *source_p)
1208   {
1209 <  report_confitem_types(source_p, ULINE_TYPE, 0);
1209 >  report_confitem_types(source_p, ULINE_TYPE);
1210   }
1211  
1212   /* stats_servers()
# Line 1139 | Line 1218 | stats_shared(struct Client *source_p)
1218   static void
1219   stats_servers(struct Client *source_p)
1220   {
1221 <  struct Client *target_p;
1143 <  dlink_node *ptr;
1144 <  int j = 0;
1221 >  dlink_node *ptr = NULL;
1222  
1223    DLINK_FOREACH(ptr, serv_list.head)
1224    {
1225 <    target_p = ptr->data;
1149 <
1150 <    j++;
1225 >    const struct Client *target_p = ptr->data;
1226  
1227      sendto_one(source_p, ":%s %d %s v :%s (%s!%s@%s) Idle: %d",
1228 <               from, RPL_STATSDEBUG, to,
1229 <               target_p->name,
1230 <               (target_p->serv->by[0] ? target_p->serv->by : "Remote."),
1156 <               "*", "*", (int)(CurrentTime - target_p->lasttime));
1228 >               from, RPL_STATSDEBUG, to, target_p->name,
1229 >               (target_p->serv->by[0] ? target_p->serv->by : "Remote."),
1230 >               "*", "*", (int)(CurrentTime - target_p->localClient->lasttime));
1231    }
1232  
1233 <  sendto_one(source_p, ":%s %d %s v :%d Server(s)",
1234 <             from, RPL_STATSDEBUG, to, j);
1233 >  sendto_one(source_p, ":%s %d %s v :%u Server(s)",
1234 >             from, RPL_STATSDEBUG, to, dlink_list_length(&serv_list));
1235   }
1236  
1237   static void
1238   stats_gecos(struct Client *source_p)
1239   {
1240 <  report_confitem_types(source_p, XLINE_TYPE, 0);
1241 <  report_confitem_types(source_p, RXLINE_TYPE, 0);
1240 >  report_confitem_types(source_p, XLINE_TYPE);
1241 >  report_confitem_types(source_p, RXLINE_TYPE);
1242   }
1243  
1244   static void
1245   stats_class(struct Client *source_p)
1246   {
1247 <  report_confitem_types(source_p, CLASS_TYPE, 0);
1247 >  report_confitem_types(source_p, CLASS_TYPE);
1248   }
1249  
1250   static void
# Line 1180 | Line 1254 | stats_memory(struct Client *source_p)
1254   }
1255  
1256   static void
1183 stats_ziplinks(struct Client *source_p)
1184 {
1185  dlink_node *ptr;
1186  struct Client *target_p;
1187  unsigned int sent_data = 0;
1188
1189  DLINK_FOREACH(ptr, serv_list.head)
1190  {
1191    target_p = ptr->data;
1192
1193    if (IsCapable(target_p, CAP_ZIP))
1194    {
1195      /* we use memcpy(3) and a local copy of the structure to
1196       * work around a register use bug on GCC on the SPARC.
1197       * -jmallett, 04/27/2002
1198       */
1199      struct ZipStats zipstats;
1200      memcpy(&zipstats, &target_p->localClient->zipstats, sizeof (struct ZipStats));
1201
1202      sendto_one(source_p, ":%s %d %s Z :ZipLinks stats for %s send[%.2f%% "
1203                 "compression (%lu bytes data/%lu bytes wire)] recv[%.2f%% "
1204                 "compression (%lu bytes data/%lu bytes wire)]",
1205                 from, RPL_STATSDEBUG, to, target_p->name,
1206                 zipstats.out_ratio, zipstats.out, zipstats.out_wire,
1207                 zipstats.in_ratio,  zipstats.in,  zipstats.in_wire);
1208      ++sent_data;
1209    }
1210  }
1211
1212  sendto_one(source_p, ":%s %d %s Z :%u ziplink(s)",
1213             from, RPL_STATSDEBUG, to, sent_data);
1214 }
1215
1216 static void
1257   stats_servlinks(struct Client *source_p)
1258   {
1259    uint64_t sendB = 0, recvB = 0;
1260    time_t uptime = 0;
1261    dlink_node *ptr = NULL;
1262  
1263 <  if (ConfigServerHide.flatten_links && !IsOper(source_p))
1263 >  if (ConfigServerHide.flatten_links && !HasUMode(source_p, UMODE_OPER))
1264    {
1265      sendto_one(source_p, form_str(ERR_NOPRIVILEGES),
1266                 from, to);
# Line 1237 | Line 1277 | stats_servlinks(struct Client *source_p)
1277      /* ":%s 211 %s %s %u %u %llu %u %llu :%u %u %s" */
1278      sendto_one(source_p, form_str(RPL_STATSLINKINFO),
1279                 from, to,
1280 <               get_client_name(target_p, IsAdmin(source_p) ? SHOW_IP : MASK_IP),
1280 >               get_client_name(target_p, HasUMode(source_p, UMODE_ADMIN) ? SHOW_IP : MASK_IP),
1281                 dbuf_length(&target_p->localClient->buf_sendq),
1282                 target_p->localClient->send.messages,
1283                 target_p->localClient->send.bytes >> 10,
1284                 target_p->localClient->recv.messages,
1285                 target_p->localClient->recv.bytes >> 10,
1286 <               (unsigned)(CurrentTime - target_p->firsttime),
1287 <               (CurrentTime > target_p->since) ? (unsigned)(CurrentTime - target_p->since): 0,
1288 <               IsOper(source_p) ? show_capabilities(target_p) : "TS");
1286 >               (unsigned)(CurrentTime - target_p->localClient->firsttime),
1287 >               (CurrentTime > target_p->localClient->since) ? (unsigned)(CurrentTime - target_p->localClient->since): 0,
1288 >               HasUMode(source_p, UMODE_OPER) ? show_capabilities(target_p) : "TS");
1289    }
1290  
1291    sendB >>= 10;
# Line 1260 | Line 1300 | stats_servlinks(struct Client *source_p)
1300               from, RPL_STATSDEBUG, to,
1301               _GMKv(recvB), _GMKs(recvB));
1302  
1303 <  uptime = (CurrentTime - me.since);
1303 >  uptime = (CurrentTime - me.localClient->since);
1304  
1305    sendto_one(source_p, ":%s %d %s ? :Server send: %7.2f %s (%4.1f K/s)",
1306               from, RPL_STATSDEBUG, to,
# Line 1296 | Line 1336 | stats_ltrace(struct Client *source_p, in
1336   }
1337  
1338   /*
1299 * ms_stats - STATS message handler
1300 *      parv[0] = sender prefix
1301 *      parv[1] = statistics selector (defaults to Message frequency)
1302 *      parv[2] = server name (current server defaulted, if omitted)
1303 */
1304 static void
1305 ms_stats(struct Client *client_p, struct Client *source_p,
1306         int parc, char *parv[])
1307 {
1308  if (hunt_server(client_p,source_p,":%s STATS %s :%s",2,parc,parv)!=HUNTED_ISME)
1309    return;
1310
1311  if (IsClient(source_p))
1312    mo_stats(client_p, source_p, parc, parv);
1313 }
1314
1315 /*
1339   * stats_L
1340   *
1341   * inputs       - pointer to client to report to
# Line 1347 | Line 1370 | stats_L_list(struct Client *source_p,cha
1370    {
1371      target_p = ptr->data;
1372  
1373 <    if (IsInvisible(target_p) && (doall || wilds) &&
1374 <        !(MyConnect(source_p) && IsOper(source_p)) &&
1375 <        !IsOper(target_p) && (target_p != source_p))
1373 >    if (HasUMode(target_p, UMODE_INVISIBLE) && (doall || wilds) &&
1374 >        !(MyConnect(source_p) && HasUMode(source_p, UMODE_OPER)) &&
1375 >        !HasUMode(target_p, UMODE_OPER) && (target_p != source_p))
1376        continue;
1377      if (!doall && wilds && !match(name, target_p->name))
1378        continue;
# Line 1358 | Line 1381 | stats_L_list(struct Client *source_p,cha
1381  
1382      /* This basically shows ips for our opers if its not a server/admin, or
1383       * its one of our admins.  */
1384 <    if(MyClient(source_p) && IsOper(source_p) &&
1385 <       (IsAdmin(source_p) ||
1386 <       (!IsServer(target_p) && !IsAdmin(target_p) &&
1384 >    if(MyClient(source_p) && HasUMode(source_p, UMODE_OPER) &&
1385 >       (HasUMode(source_p, UMODE_ADMIN) ||
1386 >       (!IsServer(target_p) && !HasUMode(target_p, UMODE_ADMIN) &&
1387         !IsHandshake(target_p) && !IsConnecting(target_p))))
1388      {
1389        sendto_one(source_p, form_str(RPL_STATSLINKINFO),
# Line 1373 | Line 1396 | stats_L_list(struct Client *source_p,cha
1396                   target_p->localClient->send.bytes>>10,
1397                   target_p->localClient->recv.messages,
1398                   target_p->localClient->recv.bytes>>10,
1399 <                 (unsigned)(CurrentTime - target_p->firsttime),
1400 <                 (CurrentTime > target_p->since) ? (unsigned)(CurrentTime - target_p->since):0,
1399 >                 (unsigned)(CurrentTime - target_p->localClient->firsttime),
1400 >                 (CurrentTime > target_p->localClient->since) ? (unsigned)(CurrentTime - target_p->localClient->since):0,
1401                   IsServer(target_p) ? show_capabilities(target_p) : "-");
1402      }
1403      else
1404      {
1405        /* If its a hidden ip, an admin, or a server, mask the real IP */
1406 <      if(IsIPSpoof(target_p) || IsServer(target_p) || IsAdmin(target_p)
1406 >      if(IsIPSpoof(target_p) || IsServer(target_p) || HasUMode(target_p, UMODE_ADMIN)
1407           || IsHandshake(target_p) || IsConnecting(target_p))
1408          sendto_one(source_p, form_str(RPL_STATSLINKINFO),
1409                     from, to,
# Line 1390 | Line 1413 | stats_L_list(struct Client *source_p,cha
1413                     target_p->localClient->send.bytes>>10,
1414                     target_p->localClient->recv.messages,
1415                     target_p->localClient->recv.bytes>>10,
1416 <                   (unsigned)(CurrentTime - target_p->firsttime),
1417 <                   (CurrentTime > target_p->since) ? (unsigned)(CurrentTime - target_p->since):0,
1416 >                   (unsigned)(CurrentTime - target_p->localClient->firsttime),
1417 >                   (CurrentTime > target_p->localClient->since) ? (unsigned)(CurrentTime - target_p->localClient->since):0,
1418                     IsServer(target_p) ? show_capabilities(target_p) : "-");
1419        else /* show the real IP */
1420          sendto_one(source_p, form_str(RPL_STATSLINKINFO),
# Line 1404 | Line 1427 | stats_L_list(struct Client *source_p,cha
1427                     target_p->localClient->send.bytes>>10,
1428                     target_p->localClient->recv.messages,
1429                     target_p->localClient->recv.bytes>>10,
1430 <                   (unsigned)(CurrentTime - target_p->firsttime),
1431 <                   (CurrentTime > target_p->since) ? (unsigned)(CurrentTime - target_p->since):0,
1430 >                   (unsigned)(CurrentTime - target_p->localClient->firsttime),
1431 >                   (CurrentTime > target_p->localClient->since) ? (unsigned)(CurrentTime - target_p->localClient->since):0,
1432                     IsServer(target_p) ? show_capabilities(target_p) : "-");
1433      }
1434    }
# Line 1445 | Line 1468 | parse_stats_args(int parc, char *parv[],
1468    else
1469      return(NULL);
1470   }
1471 +
1472 + static struct Message stats_msgtab = {
1473 +  "STATS", 0, 0, 2, MAXPARA, MFLG_SLOW, 0,
1474 +  { m_unregistered, m_stats, ms_stats, m_ignore, mo_stats, m_ignore }
1475 + };
1476 +
1477 + static void
1478 + module_init(void)
1479 + {
1480 +  mod_add_cmd(&stats_msgtab);
1481 + }
1482 +
1483 + static void
1484 + module_exit(void)
1485 + {
1486 +  mod_del_cmd(&stats_msgtab);
1487 + }
1488 +
1489 + struct module module_entry = {
1490 +  .node    = { NULL, NULL, NULL },
1491 +  .name    = NULL,
1492 +  .version = "$Revision$",
1493 +  .handle  = NULL,
1494 +  .modinit = module_init,
1495 +  .modexit = module_exit,
1496 +  .flags   = 0
1497 + };

Diff Legend

Removed lines
+ Added lines
< Changed lines (old)
> Changed lines (new)