mirror of https://github.com/pissnet/pissircd.git
215 lines
4.7 KiB
C
215 lines
4.7 KiB
C
/* stats.* RPC calls
|
|
* (C) Copyright 2022-.. Bram Matthys (Syzop) and the UnrealIRCd team
|
|
* License: GPLv2 or later
|
|
*/
|
|
|
|
#include "unrealircd.h"
|
|
|
|
ModuleHeader MOD_HEADER
|
|
= {
|
|
"rpc/stats",
|
|
"1.0.2",
|
|
"stats.* RPC calls",
|
|
"UnrealIRCd Team",
|
|
"unrealircd-6",
|
|
};
|
|
|
|
/* Forward declarations */
|
|
void rpc_stats_get(Client *client, json_t *request, json_t *params);
|
|
|
|
MOD_INIT()
|
|
{
|
|
RPCHandlerInfo r;
|
|
|
|
MARK_AS_OFFICIAL_MODULE(modinfo);
|
|
|
|
memset(&r, 0, sizeof(r));
|
|
r.method = "stats.get";
|
|
r.loglevel = ULOG_DEBUG;
|
|
r.call = rpc_stats_get;
|
|
if (!RPCHandlerAdd(modinfo->handle, &r))
|
|
{
|
|
config_error("[rpc/stats] Could not register RPC handler");
|
|
return MOD_FAILED;
|
|
}
|
|
|
|
return MOD_SUCCESS;
|
|
}
|
|
|
|
MOD_LOAD()
|
|
{
|
|
return MOD_SUCCESS;
|
|
}
|
|
|
|
MOD_UNLOAD()
|
|
{
|
|
return MOD_SUCCESS;
|
|
}
|
|
|
|
void json_expand_countries(json_t *main, const char *name, NameValuePrioList *geo)
|
|
{
|
|
json_t *list = json_array();
|
|
json_t *item;
|
|
|
|
json_object_set_new(main, name, list);
|
|
|
|
for (; geo; geo = geo->next)
|
|
{
|
|
item = json_object();
|
|
json_object_set_new(item, "country", json_string_unreal(geo->name));
|
|
json_object_set_new(item, "count", json_integer(0 - geo->priority));
|
|
json_array_append_new(list, item);
|
|
}
|
|
}
|
|
|
|
void rpc_stats_user(json_t *main, int detail)
|
|
{
|
|
Client *client;
|
|
int total = 0, ulined = 0, oper = 0;
|
|
json_t *child;
|
|
GeoIPResult *geo;
|
|
NameValuePrioList *countries = NULL;
|
|
|
|
child = json_object();
|
|
json_object_set_new(main, "user", child);
|
|
|
|
list_for_each_entry(client, &client_list, client_node)
|
|
{
|
|
if (IsUser(client))
|
|
{
|
|
total++;
|
|
if (IsULine(client))
|
|
ulined++;
|
|
else if (IsOper(client))
|
|
oper++;
|
|
if (detail >= 1)
|
|
{
|
|
geo = geoip_client(client);
|
|
if (geo && geo->country_code)
|
|
{
|
|
NameValuePrioList *e = find_nvplist(countries, geo->country_code);
|
|
if (e)
|
|
{
|
|
DelListItem(e, countries);
|
|
e->priority--;
|
|
AddListItemPrio(e, countries, e->priority);
|
|
} else {
|
|
add_nvplist(&countries, -1, geo->country_code, NULL);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
json_object_set_new(child, "total", json_integer(total));
|
|
json_object_set_new(child, "ulined", json_integer(ulined));
|
|
json_object_set_new(child, "oper", json_integer(oper));
|
|
json_object_set_new(child, "record", json_integer(irccounts.global_max));
|
|
if (detail >= 1)
|
|
json_expand_countries(child, "countries", countries);
|
|
}
|
|
|
|
void rpc_stats_channel(json_t *main)
|
|
{
|
|
json_t *child = json_object();
|
|
json_object_set_new(main, "channel", child);
|
|
json_object_set_new(child, "total", json_integer(irccounts.channels));
|
|
}
|
|
|
|
void rpc_stats_server(json_t *main)
|
|
{
|
|
Client *client;
|
|
int total = 0, ulined = 0, oper = 0;
|
|
json_t *child = json_object();
|
|
json_object_set_new(main, "server", child);
|
|
|
|
total++; /* ourselves */
|
|
list_for_each_entry(client, &global_server_list, client_node)
|
|
{
|
|
if (IsServer(client))
|
|
{
|
|
total++;
|
|
if (IsULine(client))
|
|
ulined++;
|
|
}
|
|
}
|
|
|
|
json_object_set_new(child, "total", json_integer(total));
|
|
json_object_set_new(child, "ulined", json_integer(ulined));
|
|
}
|
|
|
|
void rpc_stats_server_ban(json_t *main)
|
|
{
|
|
Client *client;
|
|
int index, index2;
|
|
TKL *tkl;
|
|
int total = 0;
|
|
int server_ban = 0;
|
|
int server_ban_exception = 0;
|
|
int spamfilter = 0;
|
|
int name_ban = 0;
|
|
json_t *child = json_object();
|
|
json_object_set_new(main, "server_ban", child);
|
|
|
|
/* First, hashed entries.. */
|
|
for (index = 0; index < TKLIPHASHLEN1; index++)
|
|
{
|
|
for (index2 = 0; index2 < TKLIPHASHLEN2; index2++)
|
|
{
|
|
for (tkl = tklines_ip_hash[index][index2]; tkl; tkl = tkl->next)
|
|
{
|
|
total++;
|
|
if (TKLIsServerBan(tkl))
|
|
server_ban++;
|
|
else if (TKLIsBanException(tkl))
|
|
server_ban_exception++;
|
|
else if (TKLIsNameBan(tkl))
|
|
name_ban++;
|
|
else if (TKLIsSpamfilter(tkl))
|
|
spamfilter++;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Now normal entries.. */
|
|
for (index = 0; index < TKLISTLEN; index++)
|
|
{
|
|
for (tkl = tklines[index]; tkl; tkl = tkl->next)
|
|
{
|
|
total++;
|
|
if (TKLIsServerBan(tkl))
|
|
server_ban++;
|
|
else if (TKLIsBanException(tkl))
|
|
server_ban_exception++;
|
|
else if (TKLIsNameBan(tkl))
|
|
name_ban++;
|
|
else if (TKLIsSpamfilter(tkl))
|
|
spamfilter++;
|
|
}
|
|
}
|
|
|
|
json_object_set_new(child, "total", json_integer(total));
|
|
json_object_set_new(child, "server_ban", json_integer(server_ban));
|
|
json_object_set_new(child, "spamfilter", json_integer(spamfilter));
|
|
json_object_set_new(child, "name_ban", json_integer(name_ban));
|
|
json_object_set_new(child, "server_ban_exception", json_integer(server_ban_exception));
|
|
}
|
|
|
|
void rpc_stats_get(Client *client, json_t *request, json_t *params)
|
|
{
|
|
json_t *result, *item;
|
|
const char *statsname;
|
|
Channel *stats;
|
|
int details;
|
|
|
|
OPTIONAL_PARAM_INTEGER("object_detail_level", details, 1);
|
|
|
|
result = json_object();
|
|
rpc_stats_server(result);
|
|
rpc_stats_user(result, details);
|
|
rpc_stats_channel(result);
|
|
rpc_stats_server_ban(result);
|
|
rpc_response(client, request, result);
|
|
json_decref(result);
|
|
}
|