extern crate imap; extern crate native_tls; extern crate serde; extern crate fondant; use fondant::Configure; use serde::{Serialize, Deserialize}; #[derive(Configure, Serialize, Deserialize, Default)] #[config_file = "config.toml"] struct Config { host: String, user: String, pass: String, pass_eval: String, hook: String, } type Session = imap::Session>; fn connect(host: &str, user: &str, pass: &str) -> Result { let tls = native_tls::TlsConnector::builder().build().unwrap(); let client = imap::connect((host, 993), host, &tls).unwrap(); let mut imap_session = client .login(user, pass) .map_err(|e| e.0)?; imap_session.select("INBOX")?; Ok(imap_session) } fn get_pass(eval: &str) -> String { String::from(std::str::from_utf8( std::process::Command::new("sh") .args(&["-c", eval]) .output().unwrap().stdout.as_ref() ).unwrap()).split("\n").next().unwrap().to_string() } fn main() { let conf = Config::load().unwrap(); let pass = match (conf.pass.len(), conf.pass_eval.len()) { (0, 0) => { eprintln!("No password supplied"); return } ( 0, _e) => get_pass(&conf.pass_eval), (_p, 0) => conf.pass, (_p, _e) => get_pass(&conf.pass_eval), }; let mut sess = connect(&conf.host, &conf.user, &pass).unwrap(); println!("connected to {}", &conf.host); loop { match sess.idle().unwrap().wait_keepalive() { Ok(()) => { println!("got message!"); std::process::Command::new("sh") .args(&["-c", &conf.hook]) .status() .expect("failed to execute process"); }, _ => { eprintln!("Failed to wait on PUSH"); break; } } } }