aboutsummaryrefslogtreecommitdiff
path: root/src/smtp.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/smtp.rs')
-rw-r--r--src/smtp.rs71
1 files changed, 71 insertions, 0 deletions
diff --git a/src/smtp.rs b/src/smtp.rs
new file mode 100644
index 0000000..affac8b
--- /dev/null
+++ b/src/smtp.rs
@@ -0,0 +1,71 @@
+use std::{
+ io::{BufRead, BufReader},
+ net::{IpAddr, SocketAddr, TcpListener, TcpStream},
+};
+
+use anyhow::Result;
+use tokio::spawn;
+
+pub struct SmtpServer {
+ listener: TcpListener,
+ running: bool,
+}
+
+impl SmtpServer {
+ pub fn new(ip: [u8; 4], port: u16) -> Result<Self> {
+ Ok(Self {
+ listener: TcpListener::bind((IpAddr::from(ip), port))?,
+ running: false,
+ })
+ }
+
+ // TODO: trap SIGINT to stop server?
+ pub async fn run(&mut self) -> Result<()> {
+ self.running = true;
+ while self.running {
+ let (stream, addr) = self.listener.accept()?;
+ let session = SessionHandler {
+ stream,
+ addr,
+ state: SessionState::default(),
+ };
+ spawn(session.run());
+ }
+ Ok(())
+ }
+}
+
+struct SessionHandler {
+ stream: TcpStream,
+ addr: SocketAddr,
+ state: SessionState,
+}
+
+impl SessionHandler {
+ async fn run(mut self) -> Result<()> {
+ let mut r = BufReader::new(&self.stream);
+ let mut buffer = String::new();
+
+ loop {
+ if r.read_line(&mut buffer)? == 0 {
+ break;
+ }
+
+ log::debug!("Received '{}' from '{}'", buffer.trim(), self.addr);
+ self.state.apply().await;
+ buffer.clear();
+ }
+
+ log::info!("Connection closed by {}", self.addr);
+ Ok(())
+ }
+}
+
+#[derive(Default)]
+struct SessionState {}
+
+impl SessionState {
+ async fn apply(&mut self) {
+ todo!()
+ }
+}
XMR address: 854DmXNrxULU3ZFJVs4Wc8PFhbq29RhqHhY8W6cdWrtFN3qmooKyyeYPcDzZTNRxphhJ5UzASQfAdEMwSteVqymk28aLhqj