From 3e8375efef2886d527fe7200cae8ca479ec731bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20B=C3=BCrgin?= Date: Tue, 1 Mar 2022 09:08:50 +0100 Subject: [PATCH] Helper traits in callbacks --- CHANGELOG.md | 2 +- Cargo.lock | 4 ++-- src/callbacks.rs | 42 +++++++++++++++++++++++++----------------- src/client.rs | 2 +- src/main.rs | 4 +--- tests/common/mod.rs | 9 ++------- 6 files changed, 32 insertions(+), 31 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6da0c83..cdcfa2a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,7 +15,7 @@ The minimum supported Rust version is now 1.56.1. - Use inet:host:port for a TCP socket. - Use unix:path for a UNIX domain socket. * The command-line help information has changed its appearance slightly with the - update of the underlying Clap CLI library. + update of the underlying clap CLI library. * The changelog is now maintained in a more structured format, similar to https://keepachangelog.com. diff --git a/Cargo.lock b/Cargo.lock index dbd7308..aa28bc3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -83,9 +83,9 @@ dependencies = [ [[package]] name = "clap" -version = "3.1.0" +version = "3.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5f1fea81f183005ced9e59cdb01737ef2423956dac5a6d731b06b2ecfaa3467" +checksum = "5177fac1ab67102d8989464efd043c6ff44191b1557ec1ddd489b4f7e1447e77" dependencies = [ "atty", "bitflags", diff --git a/src/callbacks.rs b/src/callbacks.rs index 83f6e4b..8704b8c 100644 --- a/src/callbacks.rs +++ b/src/callbacks.rs @@ -54,6 +54,22 @@ impl ConnectionMut for Option { } } +trait MacrosExt { + fn get_string(&self, name: &CStr) -> Option>; + fn queue_id(&self) -> Cow<'_, str>; +} + +impl MacrosExt for Macros { + fn get_string(&self, name: &CStr) -> Option> { + self.get(name).map(|v| v.to_string_lossy()) + } + + fn queue_id(&self) -> Cow<'_, str> { + self.get_string(c_str!("i")) + .unwrap_or_else(|| "NONE".into()) + } +} + pub fn make_callbacks(config: Config) -> Callbacks { let config = Arc::new(config); let config_connect = config.clone(); @@ -148,7 +164,7 @@ async fn handle_mail( smtp_args: Vec, ) -> Status { if !config.auth_untrusted() { - if let Some(login) = lookup(&context.macros, c_str!("{auth_authen}")) { + if let Some(login) = context.macros.get_string(c_str!("{auth_authen}")) { verbose!(config, "accepted message from sender authenticated as \"{}\"", login); return Status::Accept; } @@ -179,7 +195,7 @@ async fn handle_data(context: &mut Context) -> Status { let conn = context.data.connection(); let client = conn.client.as_mut().unwrap(); - let id = queue_id(&context.macros); + let id = context.macros.queue_id(); if let Err(e) = client.connect() { eprintln!("{}: failed to start spamc: {}", id, e); @@ -196,11 +212,11 @@ async fn handle_data(context: &mut Context) -> Status { let info = ReceivedInfo { client_ip: conn.client_ip, helo_host: conn.helo_host.as_deref(), - client_name_addr: lookup(&context.macros, c_str!("_")), - my_hostname: lookup(&context.macros, c_str!("j")), - mta: lookup(&context.macros, c_str!("v")), - tls: lookup(&context.macros, c_str!("{tls_version}")), - auth: lookup(&context.macros, c_str!("{auth_authen}")), + client_name_addr: context.macros.get_string(c_str!("_")), + my_hostname: context.macros.get_string(c_str!("j")), + mta: context.macros.get_string(c_str!("v")), + tls: context.macros.get_string(c_str!("{tls_version}")), + auth: context.macros.get_string(c_str!("{auth_authen}")), queue_id: &id, date_time: Local::now().to_rfc2822(), }; @@ -243,7 +259,7 @@ async fn handle_body( let max = config.max_message_size(); if client.bytes_written() > max { - let id = queue_id(&context.macros); + let id = context.macros.queue_id(); verbose!(config, "{}: skipping rest of message larger than {} bytes", id, max); client.skip_body(); Status::Skip @@ -256,7 +272,7 @@ async fn handle_eom(config: Arc, context: &mut EomContext) - let conn = context.data.connection(); let client = conn.client.take().unwrap(); - let id = queue_id(&context.macros); + let id = context.macros.queue_id(); match client.process(&id, &mut context.reply, &context.actions, &config).await { Ok(status) => status, @@ -280,11 +296,3 @@ async fn handle_close(context: &mut Context) -> Status { Status::Continue } - -fn queue_id(macros: &Macros) -> Cow<'_, str> { - lookup(macros, c_str!("i")).unwrap_or_else(|| "NONE".into()) -} - -fn lookup<'a>(macros: &'a Macros, name: &CStr) -> Option> { - macros.get(name).map(|v| v.to_string_lossy()) -} diff --git a/src/client.rs b/src/client.rs index 6ce7ee6..a75d3ef 100644 --- a/src/client.rs +++ b/src/client.rs @@ -500,7 +500,7 @@ mod tests { async fn quarantine<'cx, 'a>( &'cx self, - _reason: impl IntoCString + Send + 'a, + _: impl IntoCString + Send + 'a, ) -> result::Result<(), ActionError> { unimplemented!() } diff --git a/src/main.rs b/src/main.rs index 807d86d..5630824 100644 --- a/src/main.rs +++ b/src/main.rs @@ -95,8 +95,6 @@ async fn main() { } }; - // Install a signal handler for the `TERM` and `INT` (Control-C) signals. - let (shutdown_tx, shutdown) = oneshot::channel(); let signals = Signals::new(&[SIGTERM, SIGINT]).expect("failed to install signal handler"); @@ -301,7 +299,7 @@ async fn handle_signals(mut signals: Signals, shutdown_milter: oneshot::Sender<( let _ = shutdown_milter.send(()); break; } - _ => unreachable!(), + _ => panic!("unexpected signal"), } } } diff --git a/tests/common/mod.rs b/tests/common/mod.rs index 3206f91..fdc6d64 100644 --- a/tests/common/mod.rs +++ b/tests/common/mod.rs @@ -12,7 +12,7 @@ use tokio::{ net::{TcpListener, ToSocketAddrs}, process::Command, sync::oneshot, - task::{self, JoinHandle}, + task::JoinHandle, time::timeout, }; @@ -46,8 +46,7 @@ where Ok(tokio::spawn(async move { // This server expects and handles only a single connection, so that we - // can `join` this thread in the tests and detect panics. A panic can be - // triggered both in the handling code as well as due to the timeout. + // can `join` this task in the tests and detect errors and panics. let (mut stream, _) = timeout(Duration::from_secs(10), listener.accept()) .await .map_err(|e| io::Error::new(ErrorKind::Other, e))??; @@ -129,10 +128,6 @@ impl SpamAssassinMilter { } pub async fn shutdown(self) -> io::Result<()> { - for _ in 0..10 { - task::yield_now().await; - } - let _ = self.shutdown.send(()); self.milter_handle.await?