X-Git-Url: https://jfr.im/git/solanum.git/blobdiff_plain/4727c0f5868c0688c40d6edd19b3bf79e6d3d12a..7baa37a9ef4c66708d7505dfda182339461232cf:/modules/m_stats.c diff --git a/modules/m_stats.c b/modules/m_stats.c index a37cdd82..1bdeb244 100644 --- a/modules/m_stats.c +++ b/modules/m_stats.c @@ -48,11 +48,13 @@ #include "hash.h" #include "reject.h" #include "whowas.h" +#include "irc_radixtree.h" +#include "sslproc.h" -static int m_stats (struct Client *, struct Client *, int, const char **); +static int m_stats (struct MsgBuf *, struct Client *, struct Client *, int, const char **); struct Message stats_msgtab = { - "STATS", 0, 0, 0, MFLG_SLOW, + "STATS", 0, 0, 0, 0, {mg_unreg, {m_stats, 2}, {m_stats, 3}, mg_ignore, mg_ignore, {m_stats, 2}} }; @@ -75,7 +77,7 @@ static void stats_l_list(struct Client *s, const char *, int, int, rb_dlink_list static void stats_l_client(struct Client *source_p, struct Client *target_p, char statchar); -static void stats_spy(struct Client *, char, const char *); +static int stats_spy(struct Client *, char, const char *); static void stats_p_spy(struct Client *); /* Heres our struct for the stats table */ @@ -108,6 +110,7 @@ static void stats_operedup(struct Client *); static void stats_ports(struct Client *); static void stats_tresv(struct Client *); static void stats_resv(struct Client *); +static void stats_ssld(struct Client *); static void stats_usage(struct Client *); static void stats_tstats(struct Client *); static void stats_uptime(struct Client *); @@ -161,6 +164,8 @@ static struct StatsStruct stats_cmd_table[] = { {'Q', stats_resv, 1, 0, }, {'r', stats_usage, 1, 0, }, {'R', stats_usage, 1, 0, }, + {'s', stats_ssld, 1, 1, }, + {'S', stats_ssld, 1, 1, }, {'t', stats_tstats, 1, 0, }, {'T', stats_tstats, 1, 0, }, {'u', stats_uptime, 0, 0, }, @@ -183,14 +188,15 @@ static struct StatsStruct stats_cmd_table[] = { * parv[2] = (if present) server/mask in stats L, or target * * This will search the tables for the appropriate stats letter, - * if found execute it. + * if found execute it. */ static int -m_stats(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]) +m_stats(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char *parv[]) { static time_t last_used = 0; int i; char statchar; + int did_stats = 0; statchar = parv[1][0]; @@ -202,7 +208,7 @@ m_stats(struct Client *client_p, struct Client *source_p, int parc, const char * /* safe enough to give this on a local connect only */ sendto_one(source_p, form_str(RPL_LOAD2HI), me.name, source_p->name, "STATS"); - sendto_one_numeric(source_p, RPL_ENDOFSTATS, + sendto_one_numeric(source_p, RPL_ENDOFSTATS, form_str(RPL_ENDOFSTATS), statchar); return 0; } @@ -214,7 +220,11 @@ m_stats(struct Client *client_p, struct Client *source_p, int parc, const char * return 0; if((statchar != 'L') && (statchar != 'l')) - stats_spy(source_p, statchar, NULL); + did_stats = stats_spy(source_p, statchar, NULL); + + /* if did_stats is true, a module grabbed this STATS request */ + if (did_stats) + goto stats_out; for (i = 0; stats_cmd_table[i].letter; i++) { @@ -245,8 +255,9 @@ m_stats(struct Client *client_p, struct Client *source_p, int parc, const char * } } +stats_out: /* Send the end of stats notice, and the stats_spy */ - sendto_one_numeric(source_p, RPL_ENDOFSTATS, + sendto_one_numeric(source_p, RPL_ENDOFSTATS, form_str(RPL_ENDOFSTATS), statchar); return 0; @@ -271,10 +282,20 @@ stats_delay(struct Client *source_p) } } +static void +stats_hash_cb(const char *buf, void *client_p) +{ + sendto_one_numeric(client_p, RPL_STATSDEBUG, "B :%s", buf); +} + static void stats_hash(struct Client *source_p) { - hash_stats(source_p); + sendto_one_numeric(source_p, RPL_STATSDEBUG, "B :%-30s %-15s %-10s %-10s %-10s %-10s", + "NAME", "TYPE", "OBJECTS", "DEPTH SUM", "AVG DEPTH", "MAX DEPTH"); + + irc_dictionary_stats_walk(stats_hash_cb, source_p); + irc_radixtree_stats_walk(stats_hash_cb, source_p); } static void @@ -285,7 +306,7 @@ stats_connect(struct Client *source_p) char *s; rb_dlink_node *ptr; - if((ConfigFileEntry.stats_c_oper_only || + if((ConfigFileEntry.stats_c_oper_only || (ConfigServerHide.flatten_links && !IsExemptShide(source_p))) && !IsOper(source_p)) { @@ -301,7 +322,6 @@ stats_connect(struct Client *source_p) if(ServerConfIllegal(server_p)) continue; - buf[0] = '\0'; s = buf; if(IsOper(source_p)) @@ -316,14 +336,14 @@ stats_connect(struct Client *source_p) *s++ = 'Z'; } - if(!buf[0]) + if(s == buf) *s++ = '*'; *s = '\0'; - sendto_one_numeric(source_p, RPL_STATSCLINE, + sendto_one_numeric(source_p, RPL_STATSCLINE, form_str(RPL_STATSCLINE), - "*@127.0.0.1", + "*@127.0.0.1", buf, server_p->name, server_p->port, server_p->class_name); } @@ -356,7 +376,7 @@ stats_tdeny (struct Client *source_p) get_printable_kline(source_p, aconf, &host, &pass, &user, &oper_reason); - sendto_one_numeric(source_p, RPL_STATSDLINE, + sendto_one_numeric(source_p, RPL_STATSDLINE, form_str (RPL_STATSDLINE), 'd', host, pass, oper_reason ? "|" : "", @@ -393,7 +413,7 @@ stats_deny (struct Client *source_p) get_printable_kline(source_p, aconf, &host, &pass, &user, &oper_reason); - sendto_one_numeric(source_p, RPL_STATSDLINE, + sendto_one_numeric(source_p, RPL_STATSDLINE, form_str (RPL_STATSDLINE), 'D', host, pass, oper_reason ? "|" : "", @@ -413,7 +433,8 @@ stats_deny (struct Client *source_p) static void stats_exempt(struct Client *source_p) { - char *name, *host, *pass, *user, *classname; + char *name, *host, *user, *classname; + const char *pass; struct AddressRec *arec; struct ConfItem *aconf; int i, port; @@ -435,7 +456,7 @@ stats_exempt(struct Client *source_p) get_printable_conf (aconf, &name, &host, &pass, &user, &port, &classname); - sendto_one_numeric(source_p, RPL_STATSDLINE, + sendto_one_numeric(source_p, RPL_STATSDLINE, form_str(RPL_STATSDLINE), 'e', host, pass, "", ""); } @@ -470,7 +491,7 @@ stats_prop_klines(struct Client *source_p) if(aconf->status != CONF_KILL) continue; - get_printable_kline(source_p, aconf, &host, &pass, + get_printable_kline(source_p, aconf, &host, &pass, &user, &oper_reason); sendto_one_numeric(source_p, RPL_STATSKLINE, @@ -487,7 +508,7 @@ stats_hubleaf(struct Client *source_p) struct remote_conf *hub_p; rb_dlink_node *ptr; - if((ConfigFileEntry.stats_h_oper_only || + if((ConfigFileEntry.stats_h_oper_only || (ConfigServerHide.flatten_links && !IsExemptShide(source_p))) && !IsOper(source_p)) { @@ -524,7 +545,8 @@ stats_auth (struct Client *source_p) else if((ConfigFileEntry.stats_i_oper_only == 1) && !IsOper (source_p)) { struct ConfItem *aconf; - char *name, *host, *pass = "*", *user, *classname; + char *name, *host, *user, *classname; + const char *pass = "*"; int port; if(MyConnect (source_p)) @@ -588,7 +610,7 @@ stats_tklines(struct Client *source_p) get_printable_kline(source_p, aconf, &host, &pass, &user, &oper_reason); - sendto_one_numeric(source_p, RPL_STATSKLINE, + sendto_one_numeric(source_p, RPL_STATSKLINE, form_str(RPL_STATSKLINE), aconf->flags & CONF_FLAGS_TEMPORARY ? 'k' : 'K', host, user, pass, oper_reason ? "|" : "", oper_reason ? oper_reason : ""); @@ -607,7 +629,7 @@ stats_tklines(struct Client *source_p) { aconf = ptr->data; - get_printable_kline(source_p, aconf, &host, &pass, + get_printable_kline(source_p, aconf, &host, &pass, &user, &oper_reason); sendto_one_numeric(source_p, RPL_STATSKLINE, @@ -620,6 +642,43 @@ stats_tklines(struct Client *source_p) } } +/* report_Klines() + * + * inputs - Client to report to, mask + * outputs - + * side effects - Reports configured K-lines to client_p. + */ +static void +report_Klines(struct Client *source_p) +{ + char *host, *pass, *user, *oper_reason; + struct AddressRec *arec; + struct ConfItem *aconf = NULL; + int i; + + for (i = 0; i < ATABLE_SIZE; i++) + { + for (arec = atable[i]; arec; arec = arec->next) + { + if(arec->type == CONF_KILL) + { + aconf = arec->aconf; + + /* its a tempkline, theyre reported elsewhere */ + if(aconf->flags & CONF_FLAGS_TEMPORARY) + continue; + + get_printable_kline(source_p, aconf, &host, &pass, &user, &oper_reason); + sendto_one_numeric(source_p, RPL_STATSKLINE, + form_str(RPL_STATSKLINE), + 'K', host, user, pass, + oper_reason ? "|" : "", + oper_reason ? oper_reason : ""); + } + } + } +} + static void stats_klines(struct Client *source_p) { @@ -701,8 +760,8 @@ stats_oper(struct Client *source_p) RB_DLINK_FOREACH(ptr, oper_conf_list.head) { oper_p = ptr->data; - - sendto_one_numeric(source_p, RPL_STATSOLINE, + + sendto_one_numeric(source_p, RPL_STATSOLINE, form_str(RPL_STATSOLINE), oper_p->username, oper_p->host, oper_p->name, IsOper(source_p) ? oper_p->privset->name : "0", "-1"); @@ -756,7 +815,7 @@ stats_operedup (struct Client *source_p) sendto_one_numeric(source_p, RPL_STATSDEBUG, "p :%s (%s@%s)", - target_p->name, target_p->username, + target_p->name, target_p->username, target_p->host); } @@ -780,6 +839,7 @@ static void stats_tresv(struct Client *source_p) { struct ConfItem *aconf; + struct irc_radixtree_iteration_state state; rb_dlink_node *ptr; int i; @@ -787,20 +847,18 @@ stats_tresv(struct Client *source_p) { aconf = ptr->data; if(aconf->hold) - sendto_one_numeric(source_p, RPL_STATSQLINE, + sendto_one_numeric(source_p, RPL_STATSQLINE, form_str(RPL_STATSQLINE), 'q', aconf->port, aconf->host, aconf->passwd); } - HASH_WALK(i, R_MAX, ptr, resvTable) + IRC_RADIXTREE_FOREACH(aconf, &state, resv_tree) { - aconf = ptr->data; if(aconf->hold) - sendto_one_numeric(source_p, RPL_STATSQLINE, + sendto_one_numeric(source_p, RPL_STATSQLINE, form_str(RPL_STATSQLINE), 'q', aconf->port, aconf->host, aconf->passwd); } - HASH_WALK_END } @@ -808,6 +866,7 @@ static void stats_resv(struct Client *source_p) { struct ConfItem *aconf; + struct irc_radixtree_iteration_state state; rb_dlink_node *ptr; int i; @@ -815,20 +874,38 @@ stats_resv(struct Client *source_p) { aconf = ptr->data; if(!aconf->hold) - sendto_one_numeric(source_p, RPL_STATSQLINE, + sendto_one_numeric(source_p, RPL_STATSQLINE, form_str(RPL_STATSQLINE), 'Q', aconf->port, aconf->host, aconf->passwd); } - HASH_WALK(i, R_MAX, ptr, resvTable) + IRC_RADIXTREE_FOREACH(aconf, &state, resv_tree) { - aconf = ptr->data; if(!aconf->hold) - sendto_one_numeric(source_p, RPL_STATSQLINE, + sendto_one_numeric(source_p, RPL_STATSQLINE, form_str(RPL_STATSQLINE), 'Q', aconf->port, aconf->host, aconf->passwd); } - HASH_WALK_END +} + +static void +stats_ssld_foreach(void *data, pid_t pid, int cli_count, enum ssld_status status) +{ + struct Client *source_p = data; + + sendto_one_numeric(source_p, RPL_STATSDEBUG, + "S :%u %c %u", + pid, + status == SSLD_DEAD ? 'D' : (status == SSLD_SHUTDOWN ? 'S' : 'A'), + cli_count); +} + +static void +stats_ssld(struct Client *source_p) +{ +#if 0 + ssld_foreach_info(stats_ssld_foreach, source_p); +#endif } static void @@ -860,17 +937,17 @@ stats_usage (struct Client *source_p) rup = (rb_current_time() - startup_time) * hzz; if(0 == rup) rup = 1; - + sendto_one_numeric(source_p, RPL_STATSDEBUG, "R :CPU Secs %d:%02d User %d:%02d System %d:%02d", (int) (secs / 60), (int) (secs % 60), (int) (rus.ru_utime.tv_sec / 60), (int) (rus.ru_utime.tv_sec % 60), - (int) (rus.ru_stime.tv_sec / 60), + (int) (rus.ru_stime.tv_sec / 60), (int) (rus.ru_stime.tv_sec % 60)); sendto_one_numeric(source_p, RPL_STATSDEBUG, "R :RSS %ld ShMem %ld Data %ld Stack %ld", - rus.ru_maxrss, (rus.ru_ixrss / rup), + rus.ru_maxrss, (rus.ru_ixrss / rup), (rus.ru_idrss / rup), (rus.ru_isrss / rup)); sendto_one_numeric(source_p, RPL_STATSDEBUG, "R :Swaps %d Reclaims %d Faults %d", @@ -883,7 +960,7 @@ stats_usage (struct Client *source_p) (int) rus.ru_msgrcv, (int) rus.ru_msgsnd); sendto_one_numeric(source_p, RPL_STATSDEBUG, "R :Signals %d Context Vol. %d Invol %d", - (int) rus.ru_nsignals, (int) rus.ru_nvcsw, + (int) rus.ru_nsignals, (int) rus.ru_nvcsw, (int) rus.ru_nivcsw); } @@ -924,7 +1001,7 @@ stats_tstats (struct Client *source_p) sendto_one_numeric(source_p, RPL_STATSDEBUG, "T :accepts %u refused %u", sp.is_ac, sp.is_ref); sendto_one_numeric(source_p, RPL_STATSDEBUG, - "T :rejected %u delaying %lu", + "T :rejected %u delaying %lu", sp.is_rej, delay_exit_length()); sendto_one_numeric(source_p, RPL_STATSDEBUG, "T :throttled refused %u throttle list size %lu", sp.is_thr, throttle_size()); @@ -938,7 +1015,7 @@ stats_tstats (struct Client *source_p) "T :nick collisions %u saves %u unknown closes %u", sp.is_kill, sp.is_save, sp.is_ni); sendto_one_numeric(source_p, RPL_STATSDEBUG, - "T :wrong direction %u empty %u", + "T :wrong direction %u empty %u", sp.is_wrdi, sp.is_empt); sendto_one_numeric(source_p, RPL_STATSDEBUG, "T :numerics seen %u", sp.is_num); @@ -958,11 +1035,11 @@ stats_tstats (struct Client *source_p) "T :connected %u %u", sp.is_cl, sp.is_sv); sendto_one_numeric(source_p, RPL_STATSDEBUG, "T :bytes sent %lluK %lluK", - sp.is_cbs / 1024, + sp.is_cbs / 1024, sp.is_sbs / 1024); sendto_one_numeric(source_p, RPL_STATSDEBUG, "T :bytes recv %lluK %lluK", - sp.is_cbr / 1024, + sp.is_cbr / 1024, sp.is_sbr / 1024); sendto_one_numeric(source_p, RPL_STATSDEBUG, "T :time connected %llu %llu", @@ -975,13 +1052,13 @@ stats_uptime (struct Client *source_p) time_t now; now = rb_current_time() - startup_time; - sendto_one_numeric(source_p, RPL_STATSUPTIME, + sendto_one_numeric(source_p, RPL_STATSUPTIME, form_str (RPL_STATSUPTIME), - now / 86400, (now / 3600) % 24, - (now / 60) % 60, now % 60); + (int)(now / 86400), (int)((now / 3600) % 24), + (int)((now / 60) % 60), (int)(now % 60)); sendto_one_numeric(source_p, RPL_STATSCONN, form_str (RPL_STATSCONN), - MaxConnectionCount, MaxClientCount, + MaxConnectionCount, MaxClientCount, Count.totalrestartcount); } @@ -1006,6 +1083,8 @@ static struct shared_flags shared_flagtable[] = { SHARED_TDLINE, 'd' }, { SHARED_PDLINE, 'D' }, { SHARED_UNDLINE, 'E' }, + { SHARED_GRANT, 'G' }, + { SHARED_DIE, 'I' }, { 0, '\0'} }; @@ -1035,7 +1114,7 @@ stats_shared (struct Client *source_p) *p = '\0'; - sendto_one_numeric(source_p, RPL_STATSULINE, + sendto_one_numeric(source_p, RPL_STATSULINE, form_str(RPL_STATSULINE), shared_p->server, shared_p->username, shared_p->host, buf); @@ -1057,7 +1136,7 @@ stats_shared (struct Client *source_p) *p = '\0'; - sendto_one_numeric(source_p, RPL_STATSULINE, + sendto_one_numeric(source_p, RPL_STATSULINE, form_str(RPL_STATSULINE), shared_p->server, "*", "*", buf); } @@ -1107,7 +1186,7 @@ stats_servers (struct Client *source_p) (target_p->serv->by[0] ? target_p->serv->by : "Remote."), (int) (rb_current_time() - target_p->localClient->lasttime), (int) rb_linebuf_len (&target_p->localClient->buf_sendq), - days, (days == 1) ? "" : "s", hours, minutes, + days, (days == 1) ? "" : "s", hours, minutes, (int) seconds); } @@ -1146,7 +1225,7 @@ stats_gecos(struct Client *source_p) if(!aconf->hold) sendto_one_numeric(source_p, RPL_STATSXLINE, form_str(RPL_STATSXLINE), - 'X', aconf->port, aconf->host, + 'X', aconf->port, aconf->host, aconf->passwd); } } @@ -1212,7 +1291,7 @@ stats_memory (struct Client *source_p) size_t total_memory = 0; - count_whowas_memory(&ww, &wwm); + whowas_memory_usage(&ww, &wwm); RB_DLINK_FOREACH(ptr, global_client_list.head) { @@ -1284,7 +1363,7 @@ stats_memory (struct Client *source_p) "z :Users %u(%lu) Invites %u(%lu)", users_counted, (unsigned long) users_counted * sizeof(struct User), - users_invited_count, + users_invited_count, (unsigned long) users_invited_count * sizeof(rb_dlink_node)); sendto_one_numeric(source_p, RPL_STATSDEBUG, @@ -1303,7 +1382,7 @@ stats_memory (struct Client *source_p) sendto_one_numeric(source_p, RPL_STATSDEBUG, "z :Classes %u(%lu)", - class_count, + class_count, (unsigned long) class_count * sizeof(struct Class)); sendto_one_numeric(source_p, RPL_STATSDEBUG, @@ -1321,7 +1400,7 @@ stats_memory (struct Client *source_p) "z :Channel members %u(%lu) invite %u(%lu)", channel_users, (unsigned long) channel_users * sizeof(rb_dlink_node), - channel_invites, + channel_invites, (unsigned long) channel_invites * sizeof(rb_dlink_node)); total_channel_memory = channel_memory + @@ -1336,7 +1415,7 @@ stats_memory (struct Client *source_p) sendto_one_numeric(source_p, RPL_STATSDEBUG, "z :Hash: client %u(%ld) chan %u(%ld)", - U_MAX, (long)(U_MAX * sizeof(rb_dlink_list)), + U_MAX, (long)(U_MAX * sizeof(rb_dlink_list)), CH_MAX, (long)(CH_MAX * sizeof(rb_dlink_list))); sendto_one_numeric(source_p, RPL_STATSDEBUG, @@ -1358,8 +1437,8 @@ stats_memory (struct Client *source_p) total_memory += mem_servers_cached; sendto_one_numeric(source_p, RPL_STATSDEBUG, - "z :Total: whowas %d channel %d conf %d", - (int) totww, (int) total_channel_memory, + "z :Total: whowas %d channel %d conf %d", + (int) totww, (int) total_channel_memory, (int) conf_memory); count_local_client_memory(&local_client_count, &local_client_memory_used); @@ -1392,7 +1471,7 @@ stats_ziplinks (struct Client *source_p) target_p = ptr->data; if(IsCapable (target_p, CAP_ZIP)) { - zipstats = target_p->localClient->zipstats; + zipstats = target_p->localClient->zipstats; sprintf(buf, "%.2f%%", zipstats->out_ratio); sprintf(buf1, "%.2f%%", zipstats->in_ratio); sendto_one_numeric(source_p, RPL_STATSDEBUG, @@ -1400,8 +1479,8 @@ stats_ziplinks (struct Client *source_p) "(%llu kB data/%llu kB wire)] recv[%s compression " "(%llu kB data/%llu kB wire)]", target_p->name, - buf, zipstats->out >> 10, - zipstats->out_wire >> 10, buf1, + buf, zipstats->out >> 10, + zipstats->out_wire >> 10, buf1, zipstats->in >> 10, zipstats->in_wire >> 10); sent_data++; } @@ -1448,7 +1527,7 @@ stats_servlinks (struct Client *source_p) (int) target_p->localClient->receiveM, (int) target_p->localClient->receiveK, rb_current_time() - target_p->localClient->firsttime, - (rb_current_time() > target_p->localClient->lasttime) ? + (rb_current_time() > target_p->localClient->lasttime) ? (rb_current_time() - target_p->localClient->lasttime) : 0, IsOper (source_p) ? show_capabilities (target_p) : "TS"); } @@ -1467,7 +1546,7 @@ stats_servlinks (struct Client *source_p) uptime = (rb_current_time() - startup_time); snprintf(buf, sizeof buf, "%7.2f %s (%4.1f K/s)", - _GMKv (me.localClient->sendK), + _GMKv (me.localClient->sendK), _GMKs (me.localClient->sendK), (float) ((float) me.localClient->sendK / (float) uptime)); sendto_one_numeric(source_p, RPL_STATSDEBUG, "? :Server send: %s", buf); @@ -1484,9 +1563,6 @@ stats_l_should_show_oper(struct Client *target_p) if (IsOperInvis(target_p)) return 0; - if(target_p->user->away) - return 0; - return 1; } @@ -1614,7 +1690,7 @@ stats_l_client(struct Client *source_p, struct Client *target_p, (int) target_p->localClient->receiveM, (int) target_p->localClient->receiveK, rb_current_time() - target_p->localClient->firsttime, - (rb_current_time() > target_p->localClient->lasttime) ? + (rb_current_time() > target_p->localClient->lasttime) ? (rb_current_time() - target_p->localClient->lasttime) : 0, IsOper(source_p) ? show_capabilities(target_p) : "-"); } @@ -1633,7 +1709,7 @@ stats_l_client(struct Client *source_p, struct Client *target_p, (int) target_p->localClient->receiveM, (int) target_p->localClient->receiveK, rb_current_time() - target_p->localClient->firsttime, - (rb_current_time() > target_p->localClient->lasttime) ? + (rb_current_time() > target_p->localClient->lasttime) ? (rb_current_time() - target_p->localClient->lasttime) : 0, "-"); } @@ -1665,7 +1741,7 @@ stats_comm(struct Client *source_p) * any damage with stats requests now anyway. So, why show them? * -Dianora */ -static void +static int stats_spy(struct Client *source_p, char statchar, const char *name) { hook_data_int data; @@ -1673,8 +1749,11 @@ stats_spy(struct Client *source_p, char statchar, const char *name) data.client = source_p; data.arg1 = name; data.arg2 = (int) statchar; + data.result = 0; call_hook(doing_stats_hook, &data); + + return data.result; } /* stats_p_spy()