From a1e1a0df5f36877bc29f10a1d4d107eccb4d89b2 Mon Sep 17 00:00:00 2001 From: Thelie Date: Wed, 9 Jun 2021 18:45:44 +0200 Subject: [PATCH] Changed email transport from sendmail to smtp. --- src/main.rs | 48 ++++++++++++++++++++++++++++++++++++------------ src/servers.rs | 43 +++++++++++++++++++++++-------------------- 2 files changed, 59 insertions(+), 32 deletions(-) diff --git a/src/main.rs b/src/main.rs index 22e1871..54bdb2d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -27,8 +27,12 @@ use std::{ thread, }; use lettre::{ - SendmailTransport, - Transport + SmtpClient, + smtp::authentication::{ + Credentials, + Mechanism, + }, + Transport, }; fn main() { @@ -57,17 +61,19 @@ fn main() { None => config = config::get_main_config(PathBuf::from("/etc/Mention2Mail/config.toml")) .expect("Could not get default config in /etc/Mention2Mail/default.toml"), } + + let mail_config = &config.get("email").expect("No email config found."); let server_configs; match server_conf_path { - Some(p) => server_configs = config::get_server_configs(config, PathBuf::from(p)) + Some(p) => server_configs = config::get_server_configs(config.clone(), PathBuf::from(p)) .expect("Could not get server config."), - None => server_configs = vec![config], + None => server_configs = vec![config.clone()], } // TODO: This line has many problems… - let (tx,rx): (std::sync::mpsc::Sender<(String, String, String, [Option<[String; 2]>; 5])>, std::sync::mpsc::Receiver<(String, String, String, [Option<[String; 2]>; 5])>)= channel(); + let (tx,rx): (std::sync::mpsc::Sender<(String, String, String, Vec>)>, std::sync::mpsc::Receiver<(String, String, String, Vec>)>)= channel(); let mut server_threads = vec![]; for s_conf in server_configs { @@ -75,12 +81,30 @@ fn main() { server_threads.push(thread::Builder::new() .name("server name here".to_string()) .spawn(move || { - servers::handle_server(s_conf, t).unwrap(); + servers::handle_server(s_conf, t, 5).unwrap(); }) ); } - - let mut mailer = SendmailTransport::new(); + + let smtp_address = mail_config.get("address") + .expect("No SMTP server address found.") + .as_str() + .unwrap(); + let smpt_user = mail_config.get("user") + .expect("No SMTP user name found.") + .as_str() + .unwrap(); + let smtp_pass = mail_config.get("pass") + .expect("No SMTP password found.") + .as_str() + .unwrap(); + + let mail_client = SmtpClient::new_simple(smtp_address).unwrap(); + let mail_client = mail_client.credentials( + Credentials::new(smpt_user.to_owned(), smtp_pass.to_owned()) + ); + let mail_client = mail_client.authentication_mechanism(Mechanism::Plain); + let mut mailer = mail_client.transport(); loop { match rx.recv() { @@ -92,9 +116,9 @@ fn main() { channel, server); for opt in context.iter() { match opt{ - Some([sender, msg]) => body.push_str( - &format!("{} wrote: {}", sender, msg) - ), + Some([sender, msg]) => { + body.push_str(&format!("{} wrote: {}\n", sender, msg)) + }, None => (), } } @@ -115,7 +139,7 @@ fn main() { match mailer.send(mail) { Ok(_) => println!("Email sent successfully!"), - Err(e) => panic!("Could not send email: {:?}", e), + Err(e) => println!("Could not send email: {:?}", e), } } Err(_e) => (), diff --git a/src/servers.rs b/src/servers.rs index 1dd1393..cdc86f0 100644 --- a/src/servers.rs +++ b/src/servers.rs @@ -34,43 +34,46 @@ use toml::value::Value; /// A static implementation of a ringbuffer. /// It holds arrays of three strings each, /// which are meant to represent the author and message respectively. -struct MessageRingBuf { - buf: [Option<[String; 2]>; SIZE], +pub struct MessageRingBuf { + buf: Vec>, ptr: usize, } -impl MessageRingBuf { - pub fn new() -> Self { +impl MessageRingBuf { + pub fn new(size: usize) -> Self { + Self{ - buf: [None; SIZE], + buf: vec!(None; size), ptr: 0 } } /// Adds a message to the end of the buffer, /// overwriting the first value if the buffer is full. - pub fn push(&mut self, val: [String; 2]) { - self.ptr = (self.ptr + 1) % SIZE; + pub fn push(&mut self, val: T) { + self.ptr = (self.ptr + 1) % self.buf.len(); self.buf[self.ptr] = Some(val); } /// Returns the last element of the buffer, /// replacing it with none. - pub fn pop(&mut self) -> Option<[String; 2]> { - self.ptr = (self.ptr + SIZE - 1) % SIZE; - self.buf[self.ptr].take() + pub fn pop(&mut self) -> Option { + let l = self.buf.len(); + self.ptr = (self.ptr + l - 1) % l; + self.buf[self.ptr].take() } /// Returns the contained buffer in the correct order. - pub fn get_queue(& self) -> [Option<[String; 2]>; SIZE] { + pub fn get_queue(& self) -> Vec> { + let l = self.buf.len(); let mut queue = self.buf.clone(); - for i in self.ptr .. SIZE { + for i in self.ptr .. l { queue[i - self.ptr] = self.buf[i].clone(); } for i in 0 .. self.ptr { - queue[SIZE - self.ptr + i] = self.buf[i].clone(); + queue[l - self.ptr + i] = self.buf[i].clone(); } return queue @@ -151,9 +154,9 @@ fn get_irc_join_messages(channels: &Vec, queue: VecDeque) /// - None and None in the case no mention or command is recognized /// - The appropriate answer as Message and None for a command /// - None and the mentioned user and channel as String and the context as a MessageRingBuf for mentions. -fn handle_message (message: Message, nick: &String, - client_names: Keys, contexts: &mut HashMap>) - -> (Option, Option<(String, String, [Option<[String; 2]>; SIZE])>) { +fn handle_message (message: Message, nick: &String, + client_names: Keys, contexts: &mut HashMap>) + -> (Option, Option<(String, String, Vec>)>) { let sender = match message.clone().source_nickname() { Some(s) => String::from(s), @@ -183,7 +186,7 @@ fn handle_message (message: Message, nick: &String, ) } else { match contexts.get_mut(&rec.clone()) { - Some(ref buf) => { + Some(ref mut buf) => { buf.push([sender.clone(), msg.clone()]); for c_name in client_names { if msg.contains(c_name) { @@ -210,8 +213,8 @@ fn handle_message (message: Message, nick: &String, /// Calls handle_message on each one and pushes /// email, server, channel as Strings /// and the context as MessageRingBuf to the given stream. -pub fn handle_server - (config: Value, tx: Sender<(String, String, String, [Option<[String; 2]>; SIZE])>) +pub fn handle_server + (config: Value, tx: Sender<(String, String, String, Vec>)>,context_size: usize) -> Result<(), Box> { let server_name = config.get("server").unwrap().as_str() @@ -233,7 +236,7 @@ pub fn handle_server channel.as_str() .ok_or("Could not parse one of the channels")? .to_owned(), - MessageRingBuf::new(), + MessageRingBuf::new(context_size), ); }