Fix bugs spotted in beta testing: Quarantine blocks not working or
[ircu2.10.12-pk.git] / ircd / s_stats.c
index a60cb3d90c837048eb128afbd02bd3665fea325e..355537626a86747736a0b452614908310f6c0828 100644 (file)
@@ -24,6 +24,7 @@
 #include "class.h"
 #include "client.h"
 #include "gline.h"
+#include "hash.h"
 #include "ircd.h"
 #include "ircd_chattr.h"
 #include "ircd_events.h"
@@ -40,6 +41,7 @@
 #include "msgq.h"
 #include "numeric.h"
 #include "numnicks.h"
+#include "querycmds.h"
 #include "res.h"
 #include "s_bsd.h"
 #include "s_conf.h"
  *       it--not reversed as in ircd.conf!
  */
 
-/** Stats response to use for various ConfItem types. */
-static unsigned int report_array[][3] = {
-  {CONF_SERVER, RPL_STATSCLINE, 'C'},
-  {CONF_CLIENT, RPL_STATSILINE, 'I'},
-  {CONF_LEAF, RPL_STATSLLINE, 'L'},
-  {CONF_OPERATOR, RPL_STATSOLINE, 'O'},
-  {CONF_HUB, RPL_STATSHLINE, 'H'},
-  {CONF_UWORLD, RPL_STATSULINE, 'U'},
-  {0, 0}
-};
-
 /* The statsinfo array should only be used in this file, but just TRY
  * telling the compiler that you want to forward declare a static
  * array without specifying a length, and see how it responds.  So we
@@ -96,46 +87,33 @@ stats_configured_links(struct Client *sptr, const struct StatDesc* sd,
 {
   static char null[] = "<NULL>";
   struct ConfItem *tmp;
-  int mask;
-  unsigned int *p;
   unsigned short int port;
-  char c, *host, *pass, *name;
-
-  mask = sd->sd_funcdata;
+  int maximum;
+  char *host, *pass, *name, *username, *hub_limit;
 
-  for (tmp = GlobalConfList; tmp; tmp = tmp->next) 
+  for (tmp = GlobalConfList; tmp; tmp = tmp->next)
   {
-    if ((tmp->status & mask))
+    if ((tmp->status & sd->sd_funcdata))
     {
-      for (p = &report_array[0][0]; *p; p += 3)
-        if (*p == tmp->status)
-          break;
-      if (!*p)
-        continue;
-      c = (char)*(p + 2);
       host = BadPtr(tmp->host) ? null : tmp->host;
       pass = BadPtr(tmp->passwd) ? null : tmp->passwd;
       name = BadPtr(tmp->name) ? null : tmp->name;
+      username = BadPtr(tmp->username) ? null : tmp->username;
+      hub_limit = BadPtr(tmp->hub_limit) ? null : tmp->hub_limit;
+      maximum = tmp->maximum;
       port = tmp->address.port;
-      /*
-       * On K line the passwd contents can be
-       * displayed on STATS reply.    -Vesa
-       */
-      /* Special-case 'k' or 'K' lines as appropriate... -Kev */
-      if ((tmp->status & CONF_UWORLD))
-       send_reply(sptr, p[1], c, host, pass, name, port, get_conf_class(tmp));
-      else if ((tmp->status & (CONF_SERVER | CONF_HUB)))
-       send_reply(sptr, p[1], c, "*", name, port, get_conf_class(tmp));
-      else if ((tmp->status & CONF_CLIENT))
-      {
-       if(tmp->passwd && IsDigit(*tmp->passwd) && (!tmp->passwd[1] ||
-           (IsDigit(tmp->passwd[1]) && !tmp->passwd[2])))
-         send_reply(sptr, p[1], c, host, pass, name, port, get_conf_class(tmp));
-       else
-         send_reply(sptr, p[1], c, host, "*", name, port, get_conf_class(tmp));
-      }
-      else
-       send_reply(sptr, p[1], c, host, name, port, get_conf_class(tmp));
+
+      if (tmp->status & CONF_UWORLD)
+       send_reply(sptr, RPL_STATSULINE, host);
+      else if (tmp->status & CONF_SERVER)
+       send_reply(sptr, RPL_STATSCLINE, name, "", "*", port, maximum, hub_limit, get_conf_class(tmp));
+      else if (tmp->status & CONF_CLIENT)
+        send_reply(sptr, RPL_STATSILINE,
+                   (tmp->host ? tmp->host : "*"), maximum,
+                   (name[0] == ':' ? "0" : ""), (tmp->name ? tmp->name : "*"),
+                   port, get_conf_class(tmp));
+      else if (tmp->status & CONF_OPERATOR)
+       send_reply(sptr, RPL_STATSOLINE, username, host, name, get_conf_class(tmp));
     }
   }
 }
@@ -318,11 +296,11 @@ stats_links(struct Client* sptr, const struct StatDesc* sd, char* name)
       if (!(!name || wilds) && 0 != ircd_strcmp(name, cli_name(acptr)))
         continue;
       send_reply(sptr, SND_EXPLICIT | RPL_STATSLINKINFO,
-                 "%s %u %u %u %u %u :%Tu",
+                 "%s %u %u %Lu %u %Lu :%Tu",
                  (*(cli_name(acptr))) ? cli_name(acptr) : "<unregistered>",
                  (int)MsgQLength(&(cli_sendQ(acptr))), (int)cli_sendM(acptr),
-                 (int)cli_sendK(acptr), (int)cli_receiveM(acptr),
-                 (int)cli_receiveK(acptr), CurrentTime - cli_firsttime(acptr));
+                 (cli_sendB(acptr) >> 10), (int)cli_receiveM(acptr),
+                 (cli_receiveB(acptr) >> 10), CurrentTime - cli_firsttime(acptr));
     }
 }
 
@@ -480,7 +458,7 @@ stats_servers_verbose(struct Client* sptr, const struct StatDesc* sd,
                cli_serv(acptr)->asll_rtt,
                cli_serv(acptr)->asll_to,
                cli_serv(acptr)->asll_from,
-               cli_serv(acptr)->clients,
+               (acptr == &me ? UserStats.local_clients : cli_serv(acptr)->clients),
                cli_serv(acptr)->nn_mask,
                cli_serv(acptr)->prot,
                cli_serv(acptr)->timestamp,
@@ -544,15 +522,15 @@ struct StatDesc statsinfo[] = {
   { 'g', "glines", STAT_FLAG_OPERFEAT, FEAT_HIS_STATS_g,
     gline_stats, 0,
     "Global bans (G-lines)." },
-  { 'h', "hubs", STAT_FLAG_OPERFEAT, FEAT_HIS_STATS_h,
-    stats_configured_links, (CONF_HUB | CONF_LEAF),
-    "Hubs information." },
   { 'i', "access", (STAT_FLAG_OPERFEAT | STAT_FLAG_VARPARAM), FEAT_HIS_STATS_i,
     stats_access, CONF_CLIENT,
     "Connection authorization lines." },
-  { 'j', "histogram", STAT_FLAG_OPERFEAT, FEAT_HIS_STATS_j,
+  { 'j', "histogram", (STAT_FLAG_OPERFEAT | STAT_FLAG_CASESENS), FEAT_HIS_STATS_j,
     msgq_histogram, 0,
     "Message length histogram." },
+  { 'J', "jupes", (STAT_FLAG_OPERFEAT | STAT_FLAG_CASESENS), FEAT_HIS_STATS_J,
+    stats_nickjupes, 0,
+    "Nickname jupes." },
   { 'k', "klines", (STAT_FLAG_OPERFEAT | STAT_FLAG_VARPARAM), FEAT_HIS_STATS_k,
     stats_klines, 0,
     "Local bans (K-Lines)." },
@@ -592,7 +570,7 @@ struct StatDesc statsinfo[] = {
     "Local connection statistics (Total SND/RCV, etc)." },
   { 'U', "uworld", (STAT_FLAG_OPERFEAT | STAT_FLAG_CASESENS), FEAT_HIS_STATS_U,
     stats_configured_links, CONF_UWORLD,
-    "Service server & nick jupes information." },
+    "Service server information." },
   { 'u', "uptime", (STAT_FLAG_OPERFEAT | STAT_FLAG_CASESENS), FEAT_HIS_STATS_u,
     stats_uptime, 0,
     "Current uptime & highest connection count." },
@@ -646,7 +624,7 @@ stats_cmp(const void *a_, const void *b_)
 /** Compare a StatDesc's name against a string.
  * @param[in] key Pointer to a null-terminated string.
  * @param[in] sd_ Pointer to a StatDesc.
- * @return Less than,qual to, or greater than zero if \a key is
+ * @return Less than, equal to, or greater than zero if \a key is
  * lexicographically less than, equal to, or greater than \a
  * sd_->sd_name.
  */