1#![warn(missing_docs)]
2#![cfg_attr(docsrs, feature(doc_cfg))]
3#![doc(
4 html_logo_url = "https://raw.githubusercontent.com/surban/aggligator/master/.misc/aggligator.png",
5 html_favicon_url = "https://raw.githubusercontent.com/surban/aggligator/master/.misc/aggligator.png",
6 issue_tracker_base_url = "https://github.com/surban/aggligator/issues/"
7)]
8
9use anyhow::{bail, Context};
12use std::path::PathBuf;
13use tracing_subscriber::{fmt, prelude::*, EnvFilter};
14
15use aggligator::cfg::Cfg;
16use aggligator_transport_tcp::TcpLinkFilter;
17
18pub fn init_log() {
20 tracing_subscriber::registry().with(fmt::layer()).with(EnvFilter::from_default_env()).init();
21 tracing_log::LogTracer::init().unwrap();
22}
23
24pub fn print_default_cfg() {
26 println!("{}", serde_json::to_string_pretty(&Cfg::default()).unwrap());
27}
28
29pub fn load_cfg(path: &Option<PathBuf>) -> anyhow::Result<Cfg> {
32 match path {
33 Some(path) => {
34 let file = std::fs::File::open(path).context("cannot open configuration file")?;
35 serde_json::from_reader(file).context("cannot parse configuration file")
36 }
37 None => Ok(Cfg::default()),
38 }
39}
40
41pub fn parse_tcp_link_filter(s: &str) -> anyhow::Result<TcpLinkFilter> {
43 match s {
44 "none" => Ok(TcpLinkFilter::None),
45 "interface-interface" => Ok(TcpLinkFilter::InterfaceInterface),
46 "interface-ip" => Ok(TcpLinkFilter::InterfaceIp),
47 other => bail!("unknown TCP link filter: {other}"),
48 }
49}
50
51pub async fn wait_sigterm() {
53 #[cfg(unix)]
54 {
55 use tokio::signal::unix::{signal, SignalKind};
56
57 let mut sigterm = signal(SignalKind::terminate()).unwrap();
58 let mut sigint = signal(SignalKind::interrupt()).unwrap();
59 let mut sighup = signal(SignalKind::hangup()).unwrap();
60
61 tokio::select! {
62 _ = sigterm.recv() => {},
63 _ = sigint.recv() => {},
64 _ = sighup.recv() => {},
65 }
66 }
67
68 #[cfg(windows)]
69 {
70 use tokio::signal::windows;
71
72 let mut ctrl_c = windows::ctrl_c().unwrap();
73 let mut ctrl_break = windows::ctrl_break().unwrap();
74 let mut ctrl_close = windows::ctrl_close().unwrap();
75 let mut ctrl_logoff = windows::ctrl_logoff().unwrap();
76 let mut ctrl_shutdown = windows::ctrl_shutdown().unwrap();
77
78 tokio::select! {
79 _ = ctrl_c.recv() => {},
80 _ = ctrl_break.recv() => {},
81 _ = ctrl_close.recv() => {},
82 _ = ctrl_logoff.recv() => {},
83 _ = ctrl_shutdown.recv() => {},
84 }
85 }
86
87 #[cfg(not(any(unix, windows)))]
88 {
89 std::future::pending::<()>().await;
90 }
91
92 tracing::info!("received termination signal");
93}