use std::{ error::Error, fs::File, sync::Arc, }; use tokio::sync::oneshot; use ptth::relay; use ptth::relay::RelayState; #[tokio::main] async fn main () -> Result <(), Box > { use std::io::Read; let config_file = { let config_file_path = "config/ptth_relay.toml"; let mut f = File::open (config_file_path).unwrap_or_else (|_| panic! ("Can't open {:?}", config_file_path)); let mut buffer = vec! [0u8; 4096]; let bytes_read = f.read (&mut buffer).unwrap_or_else (|_| panic! ("Can't read {:?}", config_file_path)); buffer.truncate (bytes_read); let config_s = String::from_utf8 (buffer).unwrap_or_else (|_| panic! ("Can't parse {:?} as UTF-8", config_file_path)); toml::from_str (&config_s).unwrap_or_else (|_| panic! ("Can't parse {:?} as TOML", config_file_path)) }; eprintln! ("ptth_relay Git version: {:?}", ptth::git_version::GIT_VERSION); let rx = { let (tx, rx) = oneshot::channel::<()> (); // I have to put the tx into a Cell here so that if Ctrl-C gets // called multiple times, we won't send multiple shutdowns to the // oneshot channel. (Which would be a compile error) let tx = Some (tx); let tx = std::cell::Cell::new (tx); ctrlc::set_handler (move ||{ let tx = tx.replace (None); if let Some (tx) = tx { tx.send (()).unwrap (); } }).expect ("Error setting Ctrl-C handler"); rx }; relay::run_relay ( Arc::new (RelayState::from (&config_file)), Some (rx) ).await }