unrealircd

- supernets unrealircd source & configuration
git clone git://git.acid.vegas/unrealircd.git
Log | Files | Refs | Archive | README | LICENSE

whowas.c (3510B)

      1 /* whowas.* RPC calls
      2  * (C) Copyright 2023-.. Bram Matthys (Syzop) and the UnrealIRCd team
      3  * License: GPLv2 or later
      4  */
      5 
      6 #include "unrealircd.h"
      7 
      8 ModuleHeader MOD_HEADER
      9 = {
     10 	"rpc/whowas",
     11 	"1.0.0",
     12 	"whowas.* RPC calls",
     13 	"UnrealIRCd Team",
     14 	"unrealircd-6",
     15 };
     16 
     17 /* Externals */
     18 extern WhoWas MODVAR WHOWAS[NICKNAMEHISTORYLENGTH];
     19 
     20 /* Forward declarations */
     21 RPC_CALL_FUNC(rpc_whowas_get);
     22 
     23 MOD_INIT()
     24 {
     25 	RPCHandlerInfo r;
     26 
     27 	MARK_AS_OFFICIAL_MODULE(modinfo);
     28 
     29 	memset(&r, 0, sizeof(r));
     30 	r.method = "whowas.get";
     31 	r.loglevel = ULOG_DEBUG;
     32 	r.call = rpc_whowas_get;
     33 	if (!RPCHandlerAdd(modinfo->handle, &r))
     34 	{
     35 		config_error("[rpc/whowas] Could not register RPC handler");
     36 		return MOD_FAILED;
     37 	}
     38 
     39 	return MOD_SUCCESS;
     40 }
     41 
     42 MOD_LOAD()
     43 {
     44 	return MOD_SUCCESS;
     45 }
     46 
     47 MOD_UNLOAD()
     48 {
     49 	return MOD_SUCCESS;
     50 }
     51 
     52 const char *whowas_event_to_string(WhoWasEvent event)
     53 {
     54 	if (event == WHOWAS_EVENT_QUIT)
     55 		return "quit";
     56 	if (event == WHOWAS_EVENT_NICK_CHANGE)
     57 		return "nick-change";
     58 	if (event == WHOWAS_EVENT_SERVER_TERMINATING)
     59 		return "server-terminating";
     60 	return "unknown";
     61 }
     62 
     63 void json_expand_whowas(json_t *j, const char *key, WhoWas *e, int detail)
     64 {
     65 	json_t *child;
     66 	json_t *user = NULL;
     67 	char buf[BUFSIZE+1];
     68 
     69 	if (key)
     70 	{
     71 		child = json_object();
     72 		json_object_set_new(j, key, child);
     73 	} else {
     74 		child = j;
     75 	}
     76 
     77 	json_object_set_new(child, "name", json_string_unreal(e->name));
     78 	json_object_set_new(child, "event", json_string_unreal(whowas_event_to_string(e->event)));
     79 	json_object_set_new(child, "logon_time", json_timestamp(e->logon));
     80 	json_object_set_new(child, "logoff_time", json_timestamp(e->logoff));
     81 
     82 	if (detail == 0)
     83 		return;
     84 
     85 	json_object_set_new(child, "hostname", json_string_unreal(e->hostname));
     86 	json_object_set_new(child, "ip", json_string_unreal(e->ip));
     87 
     88 	snprintf(buf, sizeof(buf), "%s!%s@%s", e->name, e->username, e->hostname);
     89 	json_object_set_new(child, "details", json_string_unreal(buf));
     90 
     91 	if (detail < 2)
     92 		return;
     93 
     94 	if (e->connected_since)
     95 		json_object_set_new(child, "connected_since", json_timestamp(e->connected_since));
     96 
     97 	/* client.user */
     98 	user = json_object();
     99 	json_object_set_new(child, "user", user);
    100 
    101 	json_object_set_new(user, "username", json_string_unreal(e->username));
    102 	if (!BadPtr(e->realname))
    103 		json_object_set_new(user, "realname", json_string_unreal(e->realname));
    104 	if (!BadPtr(e->virthost))
    105 		json_object_set_new(user, "vhost", json_string_unreal(e->virthost));
    106 	json_object_set_new(user, "servername", json_string_unreal(e->servername));
    107 	if (!BadPtr(e->account))
    108 		json_object_set_new(user, "account", json_string_unreal(e->account));
    109 }
    110 
    111 RPC_CALL_FUNC(rpc_whowas_get)
    112 {
    113 	json_t *result, *list, *item;
    114 	int details;
    115 	int i;
    116 	const char *nick;
    117 	const char *ip;
    118 
    119 	OPTIONAL_PARAM_STRING("nick", nick);
    120 	OPTIONAL_PARAM_STRING("ip", ip);
    121 	OPTIONAL_PARAM_INTEGER("object_detail_level", details, 2);
    122 	if (details == 3)
    123 	{
    124 		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.");
    125 		return;
    126 	}
    127 
    128 	result = json_object();
    129 	list = json_array();
    130 	json_object_set_new(result, "list", list);
    131 
    132 	for (i=0; i < NICKNAMEHISTORYLENGTH; i++)
    133 	{
    134 		WhoWas *e = &WHOWAS[i];
    135 		if (!e->name)
    136 			continue;
    137 		if (nick && !match_simple(nick, e->name))
    138 			continue;
    139 		if (ip && !match_simple(ip, e->ip))
    140 			continue;
    141 		item = json_object();
    142 		json_expand_whowas(item, NULL, e, details);
    143 		json_array_append_new(list, item);
    144 	}
    145 
    146 	rpc_response(client, request, result);
    147 	json_decref(result);
    148 }