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 }