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-8/modules/m_stats.c (file contents), Revision 1483 by michael, Wed Jul 25 19:15:48 2012 UTC vs.
ircd-hybrid/trunk/modules/m_stats.c (file contents), Revision 2116 by michael, Sun May 26 11:44:01 2013 UTC

# Line 24 | Line 24
24  
25   #include "stdinc.h"
26   #include "list.h"        /* dlink_node/dlink_list */
27 – #include "balloc.h"
27   #include "client.h"      /* Client */
28   #include "irc_string.h"  
29   #include "ircd.h"        /* me */
30   #include "listener.h"    /* show_ports */
31   #include "s_gline.h"
32 + #include "conf.h"
33 + #include "conf_class.h"
34   #include "hostmask.h"
35   #include "numeric.h"     /* ERR_xxx */
36   #include "send.h"        /* sendto_one */
37   #include "fdlist.h"      /* PF and friends */
38   #include "s_bsd.h"       /* highest_fd */
38 – #include "conf.h"      /* AccessItem, report_configured_links */
39   #include "s_misc.h"      /* serv_info */
40   #include "s_serv.h"      /* hunt_server */
41   #include "s_user.h"      /* show_opers */
# Line 52 | Line 52
52  
53   const char *from, *to;
54  
55 + static const struct shared_flags
56 + {
57 +  const unsigned int type;
58 +  const unsigned char letter;
59 + } flag_table[] = {
60 +  { SHARED_KLINE,   'K' },
61 +  { SHARED_UNKLINE, 'U' },
62 +  { SHARED_XLINE,   'X' },
63 +  { SHARED_UNXLINE, 'Y' },
64 +  { SHARED_RESV,    'Q' },
65 +  { SHARED_UNRESV,  'R' },
66 +  { SHARED_LOCOPS,  'L' },
67 +  { SHARED_DLINE,   'D' },
68 +  { SHARED_UNDLINE, 'E' },
69 +  { 0, '\0' }
70 + };
71 +
72 + /*
73 + * inputs       - pointer to client requesting confitem report
74 + *              - ConfType to report
75 + * output       - none
76 + * side effects -
77 + */
78 + static void
79 + report_confitem_types(struct Client *source_p, enum maskitem_type type)
80 + {
81 +  dlink_node *ptr = NULL, *dptr = NULL;
82 +  struct MaskItem *conf = NULL;
83 +  const struct shared_flags *shared = NULL;
84 +  char buf[12];
85 +  char *p = NULL;
86 +
87 +  switch (type)
88 +  {
89 +  case CONF_XLINE:
90 +    DLINK_FOREACH(ptr, xconf_items.head)
91 +    {
92 +      conf = ptr->data;
93 +
94 +      sendto_one(source_p, form_str(RPL_STATSXLINE),
95 +                 me.name, source_p->name,
96 +                 conf->until ? 'x': 'X', conf->count,
97 +                 conf->name, conf->reason);
98 +    }
99 +    break;
100 +
101 +  case CONF_ULINE:
102 +    shared = flag_table;
103 +    DLINK_FOREACH(ptr, uconf_items.head)
104 +    {
105 +      conf = ptr->data;
106 +
107 +      p = buf;
108 +
109 +      *p++ = 'c';
110 +      for (; shared->type; ++shared)
111 +        if (shared->type & conf->flags)
112 +          *p++ = shared->letter;
113 +        else
114 +          *p++ = ToLower(shared->letter);
115 +
116 +      sendto_one(source_p, form_str(RPL_STATSULINE),
117 +                 me.name, source_p->name, conf->name,
118 +                 conf->user?conf->user: "*",
119 +                 conf->host?conf->host: "*", buf);
120 +    }
121 +
122 +    shared = flag_table;
123 +    DLINK_FOREACH(ptr, cluster_items.head)
124 +    {
125 +      conf = ptr->data;
126 +
127 +      p = buf;
128 +
129 +      *p++ = 'C';
130 +      for (; shared->type; ++shared)
131 +        if (shared->type & conf->flags)
132 +          *p++ = shared->letter;
133 +        else
134 +          *p++ = ToLower(shared->letter);
135 +
136 +      sendto_one(source_p, form_str(RPL_STATSULINE),
137 +                 me.name, source_p->name, conf->name,
138 +                 "*", "*", buf);
139 +    }
140 +
141 +    break;
142 +
143 +  case CONF_OPER:
144 +    DLINK_FOREACH(ptr, oconf_items.head)
145 +    {
146 +      conf = ptr->data;
147 +
148 +      /* Don't allow non opers to see oper privs */
149 +      if (HasUMode(source_p, UMODE_OPER))
150 +        sendto_one(source_p, form_str(RPL_STATSOLINE),
151 +                   me.name, source_p->name, 'O', conf->count, conf->user, conf->host,
152 +                   conf->name, oper_privs_as_string(conf->port),
153 +                   conf->class ? conf->class->name : "<default>");
154 +      else
155 +        sendto_one(source_p, form_str(RPL_STATSOLINE),
156 +                   me.name, source_p->name, 'O', conf->count, conf->user, conf->host,
157 +                   conf->name, "0",
158 +                   conf->class ? conf->class->name : "<default>");
159 +    }
160 +    break;
161 +
162 +  case CONF_SERVICE:
163 +    DLINK_FOREACH(ptr, service_items.head)
164 +    {
165 +      conf = ptr->data;
166 +      sendto_one(source_p, form_str(RPL_STATSSERVICE),
167 +                 me.name, source_p->name, 'S', "*", conf->name, 0, 0);
168 +    }
169 +    break;
170 +
171 +  case CONF_SERVER:
172 +    DLINK_FOREACH(ptr, server_items.head)
173 +    {
174 +      p = buf;
175 +      conf = ptr->data;
176 +
177 +      buf[0] = '\0';
178 +
179 +      if (IsConfAllowAutoConn(conf))
180 +        *p++ = 'A';
181 +      if (IsConfSSL(conf))
182 +        *p++ = 'S';
183 +      if (buf[0] == '\0')
184 +        *p++ = '*';
185 +
186 +      *p = '\0';
187 +
188 +      /*
189 +       * Allow admins to see actual ips unless hide_server_ips is enabled
190 +       */
191 +      if (!ConfigServerHide.hide_server_ips && HasUMode(source_p, UMODE_ADMIN))
192 +        sendto_one(source_p, form_str(RPL_STATSCLINE),
193 +                   me.name, source_p->name, 'C', conf->host,
194 +                   buf, conf->name, conf->port,
195 +                   conf->class ? conf->class->name : "<default>");
196 +        else
197 +          sendto_one(source_p, form_str(RPL_STATSCLINE),
198 +                     me.name, source_p->name, 'C',
199 +                     "*@127.0.0.1", buf, conf->name, conf->port,
200 +                     conf->class ? conf->class->name : "<default>");
201 +    }
202 +    break;
203 +
204 +  case CONF_HUB:
205 +    DLINK_FOREACH(ptr, server_items.head)
206 +    {
207 +      conf = ptr->data;
208 +
209 +      DLINK_FOREACH(dptr, conf->hub_list.head)
210 +        sendto_one(source_p, form_str(RPL_STATSHLINE), me.name,
211 +                   source_p->name, 'H', dptr->data, conf->name, 0, "*");
212 +    }
213 +
214 +    DLINK_FOREACH(ptr, server_items.head)
215 +    {
216 +      conf = ptr->data;
217 +
218 +      DLINK_FOREACH(dptr, conf->leaf_list.head)
219 +        sendto_one(source_p, form_str(RPL_STATSLLINE), me.name,
220 +                   source_p->name, 'L', dptr->data, conf->name, 0, "*");
221 +    }
222 +
223 +    break;
224 +
225 +  default:
226 +    break;
227 +  }
228 + }
229 +
230 + /* report_resv()
231 + *
232 + * inputs       - pointer to client pointer to report to.
233 + * output       - NONE
234 + * side effects - report all resvs to client.
235 + */
236 + static void
237 + report_resv(struct Client *source_p)
238 + {
239 +  dlink_node *ptr = NULL;
240 +  struct MaskItem *conf = NULL;
241 +
242 +  DLINK_FOREACH(ptr, resv_channel_list.head)
243 +  {
244 +    conf = ptr->data;
245 +    sendto_one(source_p, form_str(RPL_STATSQLINE),
246 +               me.name, source_p->name,
247 +               conf->until ? 'q' : 'Q', conf->count,
248 +               conf->name, conf->reason);
249 +  }
250 +
251 +  DLINK_FOREACH(ptr, nresv_items.head)
252 +  {
253 +    conf = ptr->data;
254 +    sendto_one(source_p, form_str(RPL_STATSQLINE),
255 +               me.name, source_p->name,
256 +               conf->until ? 'q' : 'Q', conf->count,
257 +               conf->name, conf->reason);
258 +  }
259 + }
260 +
261   /*
262   * This is part of the STATS replies. There is no offical numeric for this
263   * since this isnt an official command, in much the same way as HASH isnt.
# Line 93 | Line 299 | stats_usage(struct Client *source_p, int
299      rup = 1;
300  
301    sendto_one(source_p,
302 <             ":%s %d %s R :CPU Secs %d:%d User %d:%d System %d:%d",
302 >             ":%s %d %s R :CPU Secs %d:%02d User %d:%02d System %d:%02d",
303               me.name, RPL_STATSDEBUG, source_p->name, (int)(secs/60), (int)(secs%60),
304               (int)(rus.ru_utime.tv_sec/60), (int)(rus.ru_utime.tv_sec%60),
305               (int)(rus.ru_stime.tv_sec/60), (int)(rus.ru_stime.tv_sec%60));
# Line 265 | Line 471 | stats_memory(struct Client *source_p, in
471    }
472   #endif
473    /* count up all classes */
474 <  class_count = dlink_list_length(&class_items);
474 >  class_count = dlink_list_length(class_get_list());
475  
476    count_whowas_memory(&wwu, &wwm);
477    watch_count_memory(&watch_list_headers, &watch_list_memory);
478  
479 <  sendto_one(source_p, ":%s %d %s z :WATCH headers %u(%u) entries %d(%u)",
479 >  sendto_one(source_p, ":%s %d %s z :WATCH headers %u(%llu) entries %d(%u)",
480               me.name, RPL_STATSDEBUG, source_p->name, watch_list_headers,
481               watch_list_memory, watch_list_entries,
482               watch_list_entries * sizeof(dlink_node) * 2);
# Line 291 | Line 497 | stats_memory(struct Client *source_p, in
497    sendto_one(source_p, ":%s %d %s z :Resv channels %u(%lu) nicks %u(%lu)",
498               me.name, RPL_STATSDEBUG, source_p->name,
499               dlink_list_length(&resv_channel_list),
500 <             dlink_list_length(&resv_channel_list) * sizeof(struct ResvChannel),
500 >             dlink_list_length(&resv_channel_list) * sizeof(struct MaskItem),
501               dlink_list_length(&nresv_items),
502 <             dlink_list_length(&nresv_items) * sizeof(struct MatchItem));
502 >             dlink_list_length(&nresv_items) * sizeof(struct MaskItem));
503  
504    sendto_one(source_p, ":%s %d %s z :Classes %u(%llu)",
505               me.name, RPL_STATSDEBUG, source_p->name,
506               class_count, (unsigned long long)(class_count * sizeof(struct ClassItem)));
507  
508 <  sendto_one(source_p, ":%s %d %s z :Channels %uu(%llu) Topics %u(%u)",
508 >  sendto_one(source_p, ":%s %d %s z :Channels %u(%llu) Topics %u(%u)",
509               me.name, RPL_STATSDEBUG, source_p->name,
510               dlink_list_length(&global_channel_list),
511               channel_memory, topic_count, topic_count *
# Line 364 | Line 570 | stats_memory(struct Client *source_p, in
570               me.name, RPL_STATSDEBUG, source_p->name, remote_client_count,
571               remote_client_memory_used);
572  
367 –  block_heap_report_stats(source_p);
368 –
573    sendto_one(source_p,
574               ":%s %d %s z :TOTAL: %llu",
575               me.name, RPL_STATSDEBUG, source_p->name,
# Line 381 | Line 585 | stats_dns_servers(struct Client *source_
585   static void
586   stats_connect(struct Client *source_p, int parc, char *parv[])
587   {
588 <  report_confitem_types(source_p, SERVER_TYPE);
588 >  report_confitem_types(source_p, CONF_SERVER);
589   }
590  
591   /* stats_deny()
# Line 393 | Line 597 | stats_connect(struct Client *source_p, i
597   static void
598   stats_deny(struct Client *source_p, int parc, char *parv[])
599   {
600 <  struct ConfItem *conf;
397 <  struct AccessItem *aconf;
600 >  struct MaskItem *conf;
601    dlink_node *ptr = NULL;
602    unsigned int i = 0;
603  
# Line 405 | Line 608 | stats_deny(struct Client *source_p, int
608      {
609        struct AddressRec *arec = ptr->data;
610  
611 <      if (arec->type == CONF_DLINE)
612 <      {
410 <        aconf = arec->aconf;
611 >      if (arec->type != CONF_DLINE)
612 >        continue;
613  
614 <        /* dont report a tdline as a dline */
413 <        if (aconf->flags & CONF_FLAGS_TEMPORARY)
414 <          continue;
614 >      conf = arec->conf;
615  
616 <        conf = unmap_conf_item(aconf);
616 >      /* dont report a tdline as a dline */
617 >      if (conf->until)
618 >        continue;
619  
620 <        sendto_one(source_p, form_str(RPL_STATSDLINE),
621 <                   from, to, 'D', aconf->host, aconf->reason,
420 <                   aconf->oper_reason);
421 <      }
620 >      sendto_one(source_p, form_str(RPL_STATSDLINE),
621 >                 from, to, 'D', conf->host, conf->reason);
622      }
623    }
624   }
# Line 432 | Line 632 | stats_deny(struct Client *source_p, int
632   static void
633   stats_tdeny(struct Client *source_p, int parc, char *parv[])
634   {
635 <  struct ConfItem *conf;
436 <  struct AccessItem *aconf;
635 >  struct MaskItem *conf = NULL;
636    dlink_node *ptr = NULL;
637    unsigned int i = 0;
638  
# Line 444 | Line 643 | stats_tdeny(struct Client *source_p, int
643      {
644        struct AddressRec *arec = ptr->data;
645  
646 <      if (arec->type == CONF_DLINE)
647 <      {
449 <        aconf = arec->aconf;
646 >      if (arec->type != CONF_DLINE)
647 >        continue;
648  
649 <        /* dont report a permanent dline as a tdline */
452 <        if (!(aconf->flags & CONF_FLAGS_TEMPORARY))
453 <          continue;
649 >      conf = arec->conf;
650  
651 <        conf = unmap_conf_item(aconf);
651 >      /* dont report a permanent dline as a tdline */
652 >      if (!conf->until)
653 >        continue;
654  
655 <        sendto_one(source_p, form_str(RPL_STATSDLINE),
656 <                   from, to, 'd', aconf->host, aconf->reason,
459 <                   aconf->oper_reason);
460 <      }
655 >      sendto_one(source_p, form_str(RPL_STATSDLINE),
656 >                 from, to, 'd', conf->host, conf->reason);
657      }
658    }
659   }
# Line 471 | Line 667 | stats_tdeny(struct Client *source_p, int
667   static void
668   stats_exempt(struct Client *source_p, int parc, char *parv[])
669   {
670 <  struct ConfItem *conf;
475 <  struct AccessItem *aconf;
670 >  struct MaskItem *conf;
671    dlink_node *ptr = NULL;
672    unsigned int i = 0;
673  
# Line 490 | Line 685 | stats_exempt(struct Client *source_p, in
685      {
686        struct AddressRec *arec = ptr->data;
687  
688 <      if (arec->type == CONF_EXEMPTDLINE)
689 <      {
495 <        aconf = arec->aconf;
688 >      if (arec->type != CONF_EXEMPT)
689 >        continue;
690  
691 <        conf = unmap_conf_item(aconf);
691 >      conf = arec->conf;
692  
693 <        sendto_one(source_p, form_str(RPL_STATSDLINE),
694 <                   from, to, 'e', aconf->host,
501 <                   aconf->reason, aconf->oper_reason);
502 <      }
693 >      sendto_one(source_p, form_str(RPL_STATSDLINE), from, to, 'e',
694 >                 conf->host, "");
695      }
696    }
697   }
# Line 626 | Line 818 | stats_glines(struct Client *source_p, in
818  
819        if (arec->type == CONF_GLINE)
820        {
821 <        const struct AccessItem *aconf = arec->aconf;
821 >        const struct MaskItem *conf = arec->conf;
822  
823          sendto_one(source_p, form_str(RPL_STATSKLINE),
824 <                   from, to, "G",
825 <                   aconf->host ? aconf->host : "*",
826 <                   aconf->user ? aconf->user : "*",
827 <                   aconf->reason ? aconf->reason : "No reason", "" );
824 >                   from, to, 'G',
825 >                   conf->host ? conf->host : "*",
826 >                   conf->user ? conf->user : "*",
827 >                   conf->reason ? conf->reason : CONF_NOREASON);
828        }
829      }
830    }
# Line 641 | Line 833 | stats_glines(struct Client *source_p, in
833   static void
834   stats_hubleaf(struct Client *source_p, int parc, char *parv[])
835   {
836 <  report_confitem_types(source_p, HUB_TYPE);
645 <  report_confitem_types(source_p, LEAF_TYPE);
836 >  report_confitem_types(source_p, CONF_HUB);
837   }
838  
839   /*
840   * show_iline_prefix()
841   *
842   * inputs       - pointer to struct Client requesting output
843 < *              - pointer to struct AccessItem
843 > *              - pointer to struct MaskItem
844   *              - name to which iline prefix will be prefixed to
845   * output       - pointer to static string with prefixes listed in ascii form
846   * side effects - NONE
847   */
848   static const char *
849 < show_iline_prefix(struct Client *sptr, struct AccessItem *aconf, const char *name)
849 > show_iline_prefix(const struct Client *sptr, const struct MaskItem *conf)
850   {
851 <  static char prefix_of_host[USERLEN + 14];
851 >  static char prefix_of_host[USERLEN + 15];
852    char *prefix_ptr = prefix_of_host;
853  
854 <  if (IsNoTilde(aconf))
854 >  if (IsConfWebIRC(conf))
855 >    *prefix_ptr++ = '<';
856 >  if (IsNoTilde(conf))
857      *prefix_ptr++ = '-';
858 <  if (IsLimitIp(aconf))
858 >  if (IsLimitIp(conf))
859      *prefix_ptr++ = '!';
860 <  if (IsNeedIdentd(aconf))
860 >  if (IsNeedIdentd(conf))
861      *prefix_ptr++ = '+';
862 <  if (!IsNeedPassword(aconf))
862 >  if (!IsNeedPassword(conf))
863      *prefix_ptr++ = '&';
864 <  if (IsConfExemptResv(aconf))
864 >  if (IsConfExemptResv(conf))
865      *prefix_ptr++ = '$';
866 <  if (IsNoMatchIp(aconf))
866 >  if (IsNoMatchIp(conf))
867      *prefix_ptr++ = '%';
868 <  if (IsConfDoSpoofIp(aconf))
868 >  if (IsConfDoSpoofIp(conf))
869      *prefix_ptr++ = '=';
870 <  if (MyOper(sptr) && IsConfExemptKline(aconf))
870 >  if (MyOper(sptr) && IsConfExemptKline(conf))
871      *prefix_ptr++ = '^';
872 <  if (MyOper(sptr) && IsConfExemptGline(aconf))
872 >  if (MyOper(sptr) && IsConfExemptGline(conf))
873      *prefix_ptr++ = '_';
874 <  if (MyOper(sptr) && IsConfExemptLimits(aconf))
874 >  if (MyOper(sptr) && IsConfExemptLimits(conf))
875      *prefix_ptr++ = '>';
876 <  if (IsConfCanFlood(aconf))
876 >  if (IsConfCanFlood(conf))
877      *prefix_ptr++ = '|';
878  
879 <  strlcpy(prefix_ptr, name, USERLEN+1);
879 >  strlcpy(prefix_ptr, conf->user, USERLEN+1);
880  
881    return prefix_of_host;
882   }
# Line 691 | Line 884 | show_iline_prefix(struct Client *sptr, s
884   static void
885   report_auth(struct Client *client_p, int parc, char *parv[])
886   {
887 <  struct ConfItem *conf;
695 <  struct AccessItem *aconf;
887 >  struct MaskItem *conf = NULL;
888    dlink_node *ptr = NULL;
889    unsigned int i;
890  
# Line 703 | Line 895 | report_auth(struct Client *client_p, int
895      {
896        struct AddressRec *arec = ptr->data;
897  
898 <      if (arec->type == CONF_CLIENT)
899 <      {
708 <        aconf = arec->aconf;
709 <
710 <        if (!MyOper(client_p) && IsConfDoSpoofIp(aconf))
711 <          continue;
898 >      if (arec->type != CONF_CLIENT)
899 >        continue;
900  
901 <        conf = unmap_conf_item(aconf);
901 >      conf = arec->conf;
902  
903 <        /* We are doing a partial list, based on what matches the u@h of the
904 <         * sender, so prepare the strings for comparing --fl_
717 <         */
718 <        if (ConfigFileEntry.hide_spoof_ips)
719 <          sendto_one(client_p, form_str(RPL_STATSILINE), me.name,
720 <                     client_p->name, 'I',
721 <                     conf->name == NULL ? "*" : conf->name,
722 <                     show_iline_prefix(client_p, aconf, aconf->user),
723 <                     IsConfDoSpoofIp(aconf) ? "255.255.255.255" :
724 <                     aconf->host, aconf->port,
725 <                     aconf->class_ptr ? aconf->class_ptr->name : "<default>");
903 >      if (!MyOper(client_p) && IsConfDoSpoofIp(conf))
904 >        continue;
905  
906 <        else
907 <          sendto_one(client_p, form_str(RPL_STATSILINE), me.name,
908 <                     client_p->name, 'I',
909 <                     conf->name == NULL ? "*" : conf->name,
910 <                     show_iline_prefix(client_p, aconf, aconf->user),
911 <                     aconf->host, aconf->port,
912 <                     aconf->class_ptr ? aconf->class_ptr->name : "<default>");
913 <      }
906 >      /* We are doing a partial list, based on what matches the u@h of the
907 >       * sender, so prepare the strings for comparing --fl_
908 >       */
909 >      if (ConfigFileEntry.hide_spoof_ips)
910 >        sendto_one(client_p, form_str(RPL_STATSILINE), me.name,
911 >                   client_p->name, 'I',
912 >                   conf->name == NULL ? "*" : conf->name,
913 >                   show_iline_prefix(client_p, conf),
914 >                   IsConfDoSpoofIp(conf) ? "255.255.255.255" :
915 >                   conf->host, conf->port,
916 >                   conf->class ? conf->class->name : "<default>");
917 >
918 >      else
919 >        sendto_one(client_p, form_str(RPL_STATSILINE), me.name,
920 >                   client_p->name, 'I',
921 >                   conf->name == NULL ? "*" : conf->name,
922 >                   show_iline_prefix(client_p, conf),
923 >                   conf->host, conf->port,
924 >                   conf->class ? conf->class->name : "<default>");
925      }
926    }
927   }
# Line 747 | Line 937 | stats_auth(struct Client *source_p, int
937    /* If unopered, Only return matching auth blocks */
938    else if ((ConfigFileEntry.stats_i_oper_only == 1) && !HasUMode(source_p, UMODE_OPER))
939    {
940 <    struct ConfItem *conf;
751 <    struct AccessItem *aconf;
940 >    struct MaskItem *conf;
941  
942      if (MyConnect(source_p))
943 <      aconf = find_conf_by_address(source_p->host,
943 >      conf = find_conf_by_address(source_p->host,
944                                     &source_p->localClient->ip,
945                                     CONF_CLIENT,
946                                     source_p->localClient->aftype,
947                                     source_p->username,
948                                     source_p->localClient->passwd, 1);
949      else
950 <      aconf = find_conf_by_address(source_p->host, NULL, CONF_CLIENT,
950 >      conf = find_conf_by_address(source_p->host, NULL, CONF_CLIENT,
951                                     0, source_p->username, NULL, 1);
952  
953 <    if (aconf == NULL)
953 >    if (conf == NULL)
954        return;
955  
767 –    conf = unmap_conf_item(aconf);
768 –
956      sendto_one(source_p, form_str(RPL_STATSILINE), from,
957                 to, 'I',
958 <               "*", show_iline_prefix(source_p, aconf, aconf->user),
959 <               aconf->host, aconf->port,
960 <               aconf->class_ptr ? aconf->class_ptr->name : "<default>");
958 >               "*", show_iline_prefix(source_p, conf),
959 >               conf->host, conf->port,
960 >               conf->class ? conf->class->name : "<default>");
961    }
962    /* They are opered, or allowed to see all auth blocks */
963    else
# Line 787 | Line 974 | stats_auth(struct Client *source_p, int
974   static void
975   report_Klines(struct Client *client_p, int tkline)
976   {
977 <  struct AccessItem *aconf = NULL;
977 >  struct MaskItem *conf = NULL;
978    unsigned int i = 0;
979 <  const char *p = NULL;
979 >  char c = '\0';
980    dlink_node *ptr = NULL;
981  
982    if (tkline)
983 <    p = "k";
983 >    c = 'k';
984    else
985 <    p = "K";
985 >    c = 'K';
986  
987    for (i = 0; i < ATABLE_SIZE; ++i)
988    {
# Line 803 | Line 990 | report_Klines(struct Client *client_p, i
990      {
991        struct AddressRec *arec = ptr->data;
992  
993 <      if (arec->type == CONF_KLINE)
994 <      {
995 <        if ((tkline && !((aconf = arec->aconf)->flags & CONF_FLAGS_TEMPORARY)) ||
996 <            (!tkline && ((aconf = arec->aconf)->flags & CONF_FLAGS_TEMPORARY)))
997 <          continue;
998 <
999 <        if (HasUMode(client_p, UMODE_OPER))
1000 <          sendto_one(client_p, form_str(RPL_STATSKLINE), me.name,
1001 <                     client_p->name, p, aconf->host, aconf->user,
1002 <                     aconf->reason, aconf->oper_reason ? aconf->oper_reason : "");
1003 <        else
1004 <          sendto_one(client_p, form_str(RPL_STATSKLINE), me.name,
1005 <                     client_p->name, p, aconf->host, aconf->user,
1006 <                     aconf->reason, "");
1007 <      }
993 >      if (arec->type != CONF_KLINE)
994 >        continue;
995 >
996 >      conf = arec->conf;
997 >
998 >      if ((!tkline && conf->until) ||
999 >          (tkline && !conf->until))
1000 >        continue;
1001 >
1002 >      if (HasUMode(client_p, UMODE_OPER))
1003 >        sendto_one(client_p, form_str(RPL_STATSKLINE), me.name,
1004 >                   client_p->name, c, conf->host, conf->user,
1005 >                   conf->reason);
1006 >      else
1007 >        sendto_one(client_p, form_str(RPL_STATSKLINE), me.name,
1008 >                   client_p->name, c, conf->host, conf->user,
1009 >                   conf->reason);
1010      }
1011    }
1012   }
# Line 825 | Line 1014 | report_Klines(struct Client *client_p, i
1014   static void
1015   stats_tklines(struct Client *source_p, int parc, char *parv[])
1016   {
828 –  struct ConfItem *conf;
1017    /* Oper only, if unopered, return ERR_NOPRIVILEGES */
1018    if ((ConfigFileEntry.stats_k_oper_only == 2) && !HasUMode(source_p, UMODE_OPER))
1019      sendto_one(source_p, form_str(ERR_NOPRIVILEGES),
# Line 834 | Line 1022 | stats_tklines(struct Client *source_p, i
1022    /* If unopered, Only return matching klines */
1023    else if ((ConfigFileEntry.stats_k_oper_only == 1) && !HasUMode(source_p, UMODE_OPER))
1024    {
1025 <    struct AccessItem *aconf;
1025 >    struct MaskItem *conf = NULL;
1026  
1027      if (MyConnect(source_p))
1028 <      aconf = find_conf_by_address(source_p->host,
1029 <                                   &source_p->localClient->ip,
1028 >      conf = find_conf_by_address(source_p->host,
1029 >                                  &source_p->localClient->ip,
1030                                     CONF_KLINE,
1031                                     source_p->localClient->aftype,
1032                                     source_p->username, NULL, 1);
1033      else
1034 <      aconf = find_conf_by_address(source_p->host, NULL, CONF_KLINE,
1034 >      conf = find_conf_by_address(source_p->host, NULL, CONF_KLINE,
1035                                     0, source_p->username, NULL, 1);
1036  
1037 <    if (aconf == NULL)
1037 >    if (!conf)
1038        return;
1039  
1040      /* dont report a permanent kline as a tkline */
1041 <    if (!(aconf->flags & CONF_FLAGS_TEMPORARY))
1041 >    if (!conf->until)
1042        return;
1043  
856 –    conf = unmap_conf_item(aconf);
857 –
1044      sendto_one(source_p, form_str(RPL_STATSKLINE), from,
1045 <               to, "k", aconf->host, aconf->user, aconf->reason, "");
1045 >               to, 'k', conf->host, conf->user, conf->reason);
1046    }
1047    /* Theyre opered, or allowed to see all klines */
1048    else {
# Line 875 | Line 1061 | stats_klines(struct Client *source_p, in
1061    /* If unopered, Only return matching klines */
1062    else if ((ConfigFileEntry.stats_k_oper_only == 1) && !HasUMode(source_p, UMODE_OPER))
1063    {
1064 <    struct AccessItem *aconf;
1064 >    struct MaskItem *conf = NULL;
1065  
1066      /* search for a kline */
1067      if (MyConnect(source_p))
1068 <      aconf = find_conf_by_address(source_p->host,
1068 >      conf = find_conf_by_address(source_p->host,
1069                                     &source_p->localClient->ip,
1070                                     CONF_KLINE,
1071                                     source_p->localClient->aftype,
1072                                     source_p->username, NULL, 0);
1073      else
1074 <      aconf = find_conf_by_address(source_p->host, NULL, CONF_KLINE,
1074 >      conf = find_conf_by_address(source_p->host, NULL, CONF_KLINE,
1075                                     0, source_p->username, NULL, 0);
1076  
1077 <    if (aconf == NULL)
1077 >    if (!conf)
1078        return;
1079  
1080      /* dont report a tkline as a kline */
1081 <    if (aconf->flags & CONF_FLAGS_TEMPORARY)
1081 >    if (conf->until)
1082        return;
1083        
1084      sendto_one(source_p, form_str(RPL_STATSKLINE), from,
1085 <               to, "K", aconf->host, aconf->user, aconf->reason,
900 <               aconf->oper_reason);
1085 >               to, 'K', conf->host, conf->user, conf->reason);
1086    }
1087    /* Theyre opered, or allowed to see all klines */
1088 <  else {
1088 >  else
1089      report_Klines(source_p, 0);
905 –    report_confitem_types(source_p, RKLINE_TYPE);
906 –  }
1090   }
1091  
1092   static void
# Line 919 | Line 1102 | stats_oper(struct Client *source_p, int
1102      sendto_one(source_p, form_str(ERR_NOPRIVILEGES),
1103                 from, to);
1104    else
1105 <    report_confitem_types(source_p, OPER_TYPE);
1105 >    report_confitem_types(source_p, CONF_OPER);
1106   }
1107  
1108   /* stats_operedup()
# Line 941 | Line 1124 | stats_operedup(struct Client *source_p,
1124        continue;
1125  
1126      if (MyClient(source_p) && HasUMode(source_p, UMODE_OPER))
1127 <      sendto_one(source_p, ":%s %d %s p :[%c][%s] %s (%s@%s) Idle: %d",
1127 >      sendto_one(source_p, ":%s %d %s p :[%c][%s] %s (%s@%s) Idle: %u",
1128                   from, RPL_STATSDEBUG, to,
1129                   HasUMode(target_p, UMODE_ADMIN) ? 'A' : 'O',
1130                   oper_privs_as_string(target_p->localClient->operflags),
1131                   target_p->name, target_p->username, target_p->host,
1132 <                 (int)(CurrentTime - target_p->localClient->last_privmsg));
1132 >                 idle_time_get(source_p, target_p));
1133      else
1134 <      sendto_one(source_p, ":%s %d %s p :[%c] %s (%s@%s) Idle: %d",
1134 >      sendto_one(source_p, ":%s %d %s p :[%c] %s (%s@%s) Idle: %u",
1135                   from, RPL_STATSDEBUG, to,
1136                   HasUMode(target_p, UMODE_ADMIN) ? 'A' : 'O',
1137                   target_p->name, target_p->username, target_p->host,
1138 <                 (int)(CurrentTime - target_p->localClient->last_privmsg));
1138 >                 idle_time_get(source_p, target_p));
1139    }
1140  
1141 <  sendto_one(source_p, ":%s %d %s p :%lu OPER(s)",
1141 >  sendto_one(source_p, ":%s %d %s p :%u OPER(s)",
1142               from, RPL_STATSDEBUG, to, dlink_list_length(&oper_list));
1143   }
1144  
# Line 978 | Line 1161 | stats_resv(struct Client *source_p, int
1161   static void
1162   stats_service(struct Client *source_p, int parc, char *parv[])
1163   {
1164 <  report_confitem_types(source_p, SERVICE_TYPE);
1164 >  report_confitem_types(source_p, CONF_SERVICE);
1165   }
1166  
1167   static void
# Line 986 | Line 1169 | stats_tstats(struct Client *source_p, in
1169   {
1170    const struct Client *target_p = NULL;
1171    const dlink_node *ptr = NULL;
989 –  struct ServerStatistics *sp;
1172    struct ServerStatistics tmp;
1173 +  struct ServerStatistics *sp = &tmp;
1174  
992 –  sp = &tmp;
1175    memcpy(sp, &ServerStats, sizeof(struct ServerStatistics));
1176  
1177    /*
# Line 1068 | Line 1250 | stats_uptime(struct Client *source_p, in
1250   static void
1251   stats_shared(struct Client *source_p, int parc, char *parv[])
1252   {
1253 <  report_confitem_types(source_p, ULINE_TYPE);
1253 >  report_confitem_types(source_p, CONF_ULINE);
1254   }
1255  
1256   /* stats_servers()
# Line 1099 | Line 1281 | stats_servers(struct Client *source_p, i
1281   static void
1282   stats_gecos(struct Client *source_p, int parc, char *parv[])
1283   {
1284 <  report_confitem_types(source_p, XLINE_TYPE);
1103 <  report_confitem_types(source_p, RXLINE_TYPE);
1284 >  report_confitem_types(source_p, CONF_XLINE);
1285   }
1286  
1287   static void
1288   stats_class(struct Client *source_p, int parc, char *parv[])
1289   {
1290 <  report_confitem_types(source_p, CLASS_TYPE);
1290 >  const dlink_node *ptr = NULL;
1291 >
1292 >  DLINK_FOREACH(ptr, class_get_list()->head)
1293 >  {
1294 >    const struct ClassItem *class = ptr->data;
1295 >
1296 >    sendto_one(source_p, form_str(RPL_STATSYLINE),
1297 >               me.name, source_p->name, 'Y',
1298 >               class->name, class->ping_freq,
1299 >               class->con_freq,
1300 >               class->max_total, class->max_sendq,
1301 >               class->max_recvq,
1302 >               class->ref_count,
1303 >               class->number_per_cidr, class->cidr_bitlen_ipv4,
1304 >               class->number_per_cidr, class->cidr_bitlen_ipv6,
1305 >               class->active ? "active" : "disabled");
1306 >  }
1307   }
1308  
1309   static void
# Line 1127 | Line 1324 | stats_servlinks(struct Client *source_p,
1324    {
1325      struct Client *target_p = ptr->data;
1326  
1327 +    if (HasFlag(target_p, FLAGS_SERVICE) && ConfigServerHide.hide_services)
1328 +      if (!HasUMode(source_p, UMODE_OPER))
1329 +        continue;
1330 +
1331      sendB += target_p->localClient->send.bytes;
1332      recvB += target_p->localClient->recv.bytes;
1333  
# Line 1194 | Line 1395 | parse_stats_args(int parc, char *parv[],
1395  
1396      if (!irccmp(name, from))
1397        *doall = 2;
1398 <    else if (match(name, from))
1398 >    else if (!match(name, from))
1399        *doall = 1;
1400  
1401      *wilds = has_wildcards(name);
# Line 1226 | Line 1427 | stats_L_list(struct Client *source_p,cha
1427          !(MyConnect(source_p) && HasUMode(source_p, UMODE_OPER)) &&
1428          !HasUMode(target_p, UMODE_OPER) && (target_p != source_p))
1429        continue;
1430 <    if (!doall && wilds && !match(name, target_p->name))
1430 >    if (!doall && wilds && match(name, target_p->name))
1431        continue;
1432      if (!(doall || wilds) && irccmp(name, target_p->name))
1433        continue;
# Line 1361 | Line 1562 | static const struct StatsStruct
1562    { 'Q',        stats_resv,             1,      0       },
1563    { 'r',        stats_usage,            1,      0       },
1564    { 'R',        stats_usage,            1,      0       },
1565 +  { 's',        stats_service,          1,      0       },
1566    { 'S',        stats_service,          1,      0       },
1567    { 't',        stats_tstats,           1,      0       },
1568    { 'T',        stats_tstats,           1,      0       },
# Line 1402 | Line 1604 | do_stats(struct Client *source_p, int pa
1604          break;
1605        }
1606  
1607 <      sendto_realops_flags(UMODE_SPY, L_ALL,
1608 <                           "STATS %c requested by %s (%s@%s) [%s] on %s",
1607 >      sendto_realops_flags(UMODE_SPY, L_ALL, SEND_NOTICE,
1608 >                           "STATS %c requested by %s (%s@%s) [%s]",
1609                             statchar, source_p->name, source_p->username,
1610                             source_p->host, source_p->servptr->name);
1611        tab->handler(source_p, parc, parv);

Diff Legend

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