From 559a102e4882b6a67dfc5742422616bca47f5aad Mon Sep 17 00:00:00 2001 From: reverse Date: Sun, 16 Aug 2026 19:10:29 +0000 Subject: [PATCH] add oper SQUIT command to disconnect a linked server by name --- src/coremods/core_oper.rs | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/coremods/core_oper.rs b/src/coremods/core_oper.rs index d197e83..177a2cb 100644 --- a/src/coremods/core_oper.rs +++ b/src/coremods/core_oper.rs @@ -37,6 +37,7 @@ pub fn commands() -> Vec> { Box::new(Cban), Box::new(Rline), Box::new(Connect), + Box::new(Squit), Box::new(ChgHost), Box::new(ChgIdent), Box::new(SetHost), @@ -968,6 +969,36 @@ impl Command for Connect { } } +/// SQUIT — disconnect a linked server (and everything behind it). +struct Squit; +impl Command for Squit { + fn name(&self) -> &'static str { + "SQUIT" + } + fn min_params(&self) -> usize { + 1 + } + fn handle(&self, s: &mut Server, uid: Uid, params: &[String]) -> CmdResult { + if !require_oper(s, uid) { + return CmdResult::Fail; + } + let name = ¶ms[0]; + let Some(via) = s + .servers + .values() + .find(|sv| sv.name.eq_ignore_ascii_case(name)) + .map(|sv| sv.via) + else { + s.numeric(uid, ERR_NOSUCHSERVER, &format!("{name} :No such server")); + return CmdResult::Fail; + }; + let by = oper_nick(s, uid); + s.snotice_c('l', &format!("{by} used SQUIT on {name}")); + s.close_link(via, &format!("SQUIT from {by}")); + CmdResult::Ok + } +} + /// Resolve a nick to a uid, sending ERR_NOSUCHNICK if it's unknown. fn oper_target(s: &mut Server, uid: Uid, nick: &str) -> Option { match s.find_nick(nick) {