mirror of
https://github.com/unrealircd/unrealircd.git
synced 2026-07-04 22:03:12 +02:00
JSON-RPC: WHOWAS fetching is now whowas.get, also expose not only
logon_time/logoff_time but also connected_since. This also fixes the Makefile for the Windows build (i hope)
This commit is contained in:
@@ -34,7 +34,7 @@ INCLUDES = ../../include/channel.h \
|
||||
R_MODULES= \
|
||||
rpc.so stats.so user.so server.so channel.so server_ban.so \
|
||||
server_ban_exception.so name_ban.so spamfilter.so \
|
||||
log.so
|
||||
log.so whowas.so
|
||||
|
||||
MODULES=$(R_MODULES)
|
||||
MODULEFLAGS=@MODULEFLAGS@
|
||||
|
||||
+1
-109
@@ -8,7 +8,7 @@
|
||||
ModuleHeader MOD_HEADER
|
||||
= {
|
||||
"rpc/user",
|
||||
"1.0.6",
|
||||
"1.0.7",
|
||||
"user.* RPC calls",
|
||||
"UnrealIRCd Team",
|
||||
"unrealircd-6",
|
||||
@@ -28,7 +28,6 @@ RPC_CALL_FUNC(rpc_user_kill);
|
||||
RPC_CALL_FUNC(rpc_user_quit);
|
||||
RPC_CALL_FUNC(rpc_user_join);
|
||||
RPC_CALL_FUNC(rpc_user_part);
|
||||
RPC_CALL_FUNC(rpc_user_get_whowas);
|
||||
|
||||
MOD_INIT()
|
||||
{
|
||||
@@ -142,15 +141,6 @@ MOD_INIT()
|
||||
config_error("[rpc/user] Could not register RPC handler");
|
||||
return MOD_FAILED;
|
||||
}
|
||||
memset(&r, 0, sizeof(r));
|
||||
r.method = "user.get_whowas";
|
||||
r.loglevel = ULOG_DEBUG;
|
||||
r.call = rpc_user_get_whowas;
|
||||
if (!RPCHandlerAdd(modinfo->handle, &r))
|
||||
{
|
||||
config_error("[rpc/user] Could not register RPC handler");
|
||||
return MOD_FAILED;
|
||||
}
|
||||
|
||||
return MOD_SUCCESS;
|
||||
}
|
||||
@@ -705,101 +695,3 @@ RPC_CALL_FUNC(rpc_user_part)
|
||||
rpc_response(client, request, result);
|
||||
json_decref(result);
|
||||
}
|
||||
|
||||
extern WhoWas MODVAR WHOWAS[NICKNAMEHISTORYLENGTH];
|
||||
|
||||
const char *whowas_event_to_string(WhoWasEvent event)
|
||||
{
|
||||
if (event == WHOWAS_EVENT_QUIT)
|
||||
return "quit";
|
||||
if (event == WHOWAS_EVENT_NICK_CHANGE)
|
||||
return "nick-change";
|
||||
if (event == WHOWAS_EVENT_SERVER_TERMINATING)
|
||||
return "server-terminating";
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
void json_expand_whowas(json_t *j, const char *key, WhoWas *e, int detail)
|
||||
{
|
||||
json_t *child;
|
||||
json_t *user = NULL;
|
||||
char buf[BUFSIZE+1];
|
||||
|
||||
if (key)
|
||||
{
|
||||
child = json_object();
|
||||
json_object_set_new(j, key, child);
|
||||
} else {
|
||||
child = j;
|
||||
}
|
||||
|
||||
json_object_set_new(child, "name", json_string_unreal(e->name));
|
||||
|
||||
if (detail == 0)
|
||||
return;
|
||||
|
||||
json_object_set_new(child, "hostname", json_string_unreal(e->hostname));
|
||||
json_object_set_new(child, "ip", json_string_unreal(e->ip));
|
||||
|
||||
snprintf(buf, sizeof(buf), "%s!%s@%s", e->name, e->username, e->hostname);
|
||||
json_object_set_new(child, "details", json_string_unreal(buf));
|
||||
|
||||
if (detail < 2)
|
||||
return;
|
||||
|
||||
json_object_set_new(child, "event", json_string_unreal(whowas_event_to_string(e->event)));
|
||||
json_object_set_new(child, "logon_time", json_timestamp(e->logon));
|
||||
json_object_set_new(child, "logoff_time", json_timestamp(e->logoff));
|
||||
|
||||
/* client.user */
|
||||
user = json_object();
|
||||
json_object_set_new(child, "user", user);
|
||||
|
||||
json_object_set_new(user, "username", json_string_unreal(e->username));
|
||||
if (!BadPtr(e->realname))
|
||||
json_object_set_new(user, "realname", json_string_unreal(e->realname));
|
||||
if (!BadPtr(e->virthost))
|
||||
json_object_set_new(user, "vhost", json_string_unreal(e->virthost));
|
||||
json_object_set_new(user, "servername", json_string_unreal(e->servername));
|
||||
if (!BadPtr(e->account))
|
||||
json_object_set_new(user, "account", json_string_unreal(e->account));
|
||||
}
|
||||
|
||||
RPC_CALL_FUNC(rpc_user_get_whowas)
|
||||
{
|
||||
json_t *result, *list, *item;
|
||||
int details;
|
||||
int i;
|
||||
const char *name;
|
||||
const char *ip;
|
||||
|
||||
OPTIONAL_PARAM_STRING("name", name);
|
||||
OPTIONAL_PARAM_STRING("ip", ip);
|
||||
OPTIONAL_PARAM_INTEGER("object_detail_level", details, 2);
|
||||
if (details == 3)
|
||||
{
|
||||
rpc_error(client, request, JSON_RPC_ERROR_INVALID_PARAMS, "Using an 'object_detail_level' of 3 is not allowed in user.* calls, use 0, 1, 2 or 4.");
|
||||
return;
|
||||
}
|
||||
|
||||
result = json_object();
|
||||
list = json_array();
|
||||
json_object_set_new(result, "list", list);
|
||||
|
||||
for (i=0; i < NICKNAMEHISTORYLENGTH; i++)
|
||||
{
|
||||
WhoWas *e = &WHOWAS[i];
|
||||
if (!e->name)
|
||||
continue;
|
||||
if (name && !match_simple(name, e->name))
|
||||
continue;
|
||||
if (ip && !match_simple(ip, e->ip))
|
||||
continue;
|
||||
item = json_object();
|
||||
json_expand_whowas(item, NULL, e, details);
|
||||
json_array_append_new(list, item);
|
||||
}
|
||||
|
||||
rpc_response(client, request, result);
|
||||
json_decref(result);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,148 @@
|
||||
/* whowas.* RPC calls
|
||||
* (C) Copyright 2023-.. Bram Matthys (Syzop) and the UnrealIRCd team
|
||||
* License: GPLv2 or later
|
||||
*/
|
||||
|
||||
#include "unrealircd.h"
|
||||
|
||||
ModuleHeader MOD_HEADER
|
||||
= {
|
||||
"rpc/whowas",
|
||||
"1.0.0",
|
||||
"whowas.* RPC calls",
|
||||
"UnrealIRCd Team",
|
||||
"unrealircd-6",
|
||||
};
|
||||
|
||||
/* Externals */
|
||||
extern WhoWas MODVAR WHOWAS[NICKNAMEHISTORYLENGTH];
|
||||
|
||||
/* Forward declarations */
|
||||
RPC_CALL_FUNC(rpc_whowas_get);
|
||||
|
||||
MOD_INIT()
|
||||
{
|
||||
RPCHandlerInfo r;
|
||||
|
||||
MARK_AS_OFFICIAL_MODULE(modinfo);
|
||||
|
||||
memset(&r, 0, sizeof(r));
|
||||
r.method = "whowas.get";
|
||||
r.loglevel = ULOG_DEBUG;
|
||||
r.call = rpc_whowas_get;
|
||||
if (!RPCHandlerAdd(modinfo->handle, &r))
|
||||
{
|
||||
config_error("[rpc/whowas] Could not register RPC handler");
|
||||
return MOD_FAILED;
|
||||
}
|
||||
|
||||
return MOD_SUCCESS;
|
||||
}
|
||||
|
||||
MOD_LOAD()
|
||||
{
|
||||
return MOD_SUCCESS;
|
||||
}
|
||||
|
||||
MOD_UNLOAD()
|
||||
{
|
||||
return MOD_SUCCESS;
|
||||
}
|
||||
|
||||
const char *whowas_event_to_string(WhoWasEvent event)
|
||||
{
|
||||
if (event == WHOWAS_EVENT_QUIT)
|
||||
return "quit";
|
||||
if (event == WHOWAS_EVENT_NICK_CHANGE)
|
||||
return "nick-change";
|
||||
if (event == WHOWAS_EVENT_SERVER_TERMINATING)
|
||||
return "server-terminating";
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
void json_expand_whowas(json_t *j, const char *key, WhoWas *e, int detail)
|
||||
{
|
||||
json_t *child;
|
||||
json_t *user = NULL;
|
||||
char buf[BUFSIZE+1];
|
||||
|
||||
if (key)
|
||||
{
|
||||
child = json_object();
|
||||
json_object_set_new(j, key, child);
|
||||
} else {
|
||||
child = j;
|
||||
}
|
||||
|
||||
json_object_set_new(child, "name", json_string_unreal(e->name));
|
||||
json_object_set_new(child, "event", json_string_unreal(whowas_event_to_string(e->event)));
|
||||
json_object_set_new(child, "logon_time", json_timestamp(e->logon));
|
||||
json_object_set_new(child, "logoff_time", json_timestamp(e->logoff));
|
||||
|
||||
if (detail == 0)
|
||||
return;
|
||||
|
||||
json_object_set_new(child, "hostname", json_string_unreal(e->hostname));
|
||||
json_object_set_new(child, "ip", json_string_unreal(e->ip));
|
||||
|
||||
snprintf(buf, sizeof(buf), "%s!%s@%s", e->name, e->username, e->hostname);
|
||||
json_object_set_new(child, "details", json_string_unreal(buf));
|
||||
|
||||
if (detail < 2)
|
||||
return;
|
||||
|
||||
if (e->connected_since)
|
||||
json_object_set_new(child, "connected_since", json_timestamp(e->connected_since));
|
||||
|
||||
/* client.user */
|
||||
user = json_object();
|
||||
json_object_set_new(child, "user", user);
|
||||
|
||||
json_object_set_new(user, "username", json_string_unreal(e->username));
|
||||
if (!BadPtr(e->realname))
|
||||
json_object_set_new(user, "realname", json_string_unreal(e->realname));
|
||||
if (!BadPtr(e->virthost))
|
||||
json_object_set_new(user, "vhost", json_string_unreal(e->virthost));
|
||||
json_object_set_new(user, "servername", json_string_unreal(e->servername));
|
||||
if (!BadPtr(e->account))
|
||||
json_object_set_new(user, "account", json_string_unreal(e->account));
|
||||
}
|
||||
|
||||
RPC_CALL_FUNC(rpc_whowas_get)
|
||||
{
|
||||
json_t *result, *list, *item;
|
||||
int details;
|
||||
int i;
|
||||
const char *name;
|
||||
const char *ip;
|
||||
|
||||
OPTIONAL_PARAM_STRING("name", name);
|
||||
OPTIONAL_PARAM_STRING("ip", ip);
|
||||
OPTIONAL_PARAM_INTEGER("object_detail_level", details, 2);
|
||||
if (details == 3)
|
||||
{
|
||||
rpc_error(client, request, JSON_RPC_ERROR_INVALID_PARAMS, "Using an 'object_detail_level' of 3 is not allowed in user.* calls, use 0, 1, 2 or 4.");
|
||||
return;
|
||||
}
|
||||
|
||||
result = json_object();
|
||||
list = json_array();
|
||||
json_object_set_new(result, "list", list);
|
||||
|
||||
for (i=0; i < NICKNAMEHISTORYLENGTH; i++)
|
||||
{
|
||||
WhoWas *e = &WHOWAS[i];
|
||||
if (!e->name)
|
||||
continue;
|
||||
if (name && !match_simple(name, e->name))
|
||||
continue;
|
||||
if (ip && !match_simple(ip, e->ip))
|
||||
continue;
|
||||
item = json_object();
|
||||
json_expand_whowas(item, NULL, e, details);
|
||||
json_array_append_new(list, item);
|
||||
}
|
||||
|
||||
rpc_response(client, request, result);
|
||||
json_decref(result);
|
||||
}
|
||||
+17
-7
@@ -364,19 +364,22 @@ int write_whowasdb(void)
|
||||
|
||||
int write_whowas_entry(UnrealDB *db, const char *tmpfname, WhoWas *e)
|
||||
{
|
||||
char connected_since[64];
|
||||
char logontime[64];
|
||||
char logofftime[64];
|
||||
char event[16];
|
||||
|
||||
snprintf(connected_since, sizeof(connected_since), "%lld", (long long)e->connected_since);
|
||||
snprintf(logontime, sizeof(logontime), "%lld", (long long)e->logon);
|
||||
snprintf(logofftime, sizeof(logofftime), "%lld", (long long)e->logoff);
|
||||
snprintf(event, sizeof(event), "%d", e->event);
|
||||
|
||||
W_SAFE(unrealdb_write_int32(db, MAGIC_WHOWASDB_START));
|
||||
W_SAFE_PROPERTY(db, "nick", e->name);
|
||||
W_SAFE_PROPERTY(db, "event", event);
|
||||
W_SAFE_PROPERTY(db, "connected_since", connected_since);
|
||||
W_SAFE_PROPERTY(db, "logontime", logontime);
|
||||
W_SAFE_PROPERTY(db, "logofftime", logofftime);
|
||||
W_SAFE_PROPERTY(db, "event", event);
|
||||
W_SAFE_PROPERTY(db, "username", e->username);
|
||||
W_SAFE_PROPERTY(db, "hostname", e->hostname);
|
||||
W_SAFE_PROPERTY(db, "ip", e->ip);
|
||||
@@ -399,7 +402,7 @@ int write_whowas_entry(UnrealDB *db, const char *tmpfname, WhoWas *e)
|
||||
safe_free(hostname); \
|
||||
safe_free(ip); \
|
||||
safe_free(realname); \
|
||||
logontime = logofftime = 0; \
|
||||
connected_since = logontime = logofftime = 0; \
|
||||
event = 0; \
|
||||
safe_free(server); \
|
||||
safe_free(virthost); \
|
||||
@@ -431,6 +434,7 @@ int read_whowasdb(void)
|
||||
char *hostname = NULL;
|
||||
char *ip = NULL;
|
||||
char *realname = NULL;
|
||||
long long connected_since = 0;
|
||||
long long logontime = 0;
|
||||
long long logofftime = 0;
|
||||
int event = 0;
|
||||
@@ -491,7 +495,7 @@ int read_whowasdb(void)
|
||||
// Variables
|
||||
key = value = NULL;
|
||||
nick = username = hostname = ip = realname = virthost = account = server = NULL;
|
||||
logontime = logofftime = 0;
|
||||
connected_since = logontime = logofftime = 0;
|
||||
event = 0;
|
||||
|
||||
R_SAFE(unrealdb_read_int32(db, &magic));
|
||||
@@ -524,6 +528,11 @@ int read_whowasdb(void)
|
||||
{
|
||||
realname = value;
|
||||
} else
|
||||
if (!strcmp(key, "connected_since"))
|
||||
{
|
||||
connected_since = atoll(value);
|
||||
safe_free(value);
|
||||
} else
|
||||
if (!strcmp(key, "logontime"))
|
||||
{
|
||||
logontime = atoll(value);
|
||||
@@ -581,13 +590,14 @@ int read_whowasdb(void)
|
||||
if (e->hashv != -1)
|
||||
free_whowas_fields(e);
|
||||
/* Set values */
|
||||
unreal_log(ULOG_DEBUG, "whowasdb", "WHOWASDB_READ_RECORD", NULL,
|
||||
"[whowasdb] Adding '$nick'...",
|
||||
log_data_string("nick", nick));
|
||||
//unreal_log(ULOG_DEBUG, "whowasdb", "WHOWASDB_READ_RECORD", NULL,
|
||||
// "[whowasdb] Adding '$nick'...",
|
||||
// log_data_string("nick", nick));
|
||||
e->hashv = hash_whowas_name(nick);
|
||||
e->event = event;
|
||||
e->connected_since = connected_since;
|
||||
e->logon = logontime;
|
||||
e->logoff = logofftime;
|
||||
e->event = event;
|
||||
safe_strdup(e->name, nick);
|
||||
safe_strdup(e->username, username);
|
||||
safe_strdup(e->hostname, hostname);
|
||||
|
||||
Reference in New Issue
Block a user