rpc: add server/stats/ban/message/whowas/spamfilter providers; fix REHASH to reload raw_config

This commit is contained in:
Jean Chevronnet 2026-08-09 16:07:53 +00:00
parent ee445396eb
commit 89f508aca9
10 changed files with 408 additions and 11 deletions

62
src/modules/rpc/server.rs Normal file
View file

@ -0,0 +1,62 @@
//! rpc server provider — `server.list`, `server.rehash`, `server.disconnect`.
//! InspIRCd's `m_rpc_server`. (`server.connect` needs the socketengine's dialer,
//! which isn't reachable from the core thread — use the `CONNECT` command instead.)
use super::json::{obj, qstr};
use super::RpcError;
use crate::config::Config;
use crate::server::Server;
pub fn handle(s: &mut Server, action: &str, params: &str) -> Result<String, RpcError> {
match action {
"list" => {
let mut servers = vec![obj(&[
("name", qstr(&s.name)),
("description", qstr(&s.server_desc)),
("uplink", qstr("")),
("usercount", s.users.len().to_string()),
])];
for rs in s.servers.values() {
let uplink = s
.servers
.values()
.find(|o| o.sid == rs.sid)
.map(|_| s.name.clone())
.unwrap_or_default();
servers.push(obj(&[
("name", qstr(&rs.name)),
("description", qstr(&rs.desc)),
("uplink", qstr(&uplink)),
("usercount", "0".to_string()),
]));
}
Ok(obj(&[("servers", format!("[{}]", servers.join(",")))]))
}
"rehash" => match Config::try_load(&s.conf_path) {
Some(fresh) => {
s.apply_config(fresh);
s.announce("Server configuration reloaded via RPC.");
Ok(obj(&[("result", "true".into())]))
}
None => Err(RpcError::internal("config file could not be read")),
},
"disconnect" => {
let name = json_name(params)?;
let via = s
.servers
.values()
.find(|rs| rs.name.eq_ignore_ascii_case(&name))
.map(|rs| rs.via)
.ok_or_else(|| RpcError::not_found("no such linked server"))?;
s.close_link(via, "Disconnected via RPC");
Ok(obj(&[("result", "true".into())]))
}
other => Err(RpcError::method_not_found(&format!("server.{other}"))),
}
}
fn json_name(params: &str) -> Result<String, RpcError> {
super::json::get_str(params, "name")
.or_else(|| super::json::get_str(params, "server"))
.ok_or_else(|| RpcError::invalid_params("missing 'name'"))
}