aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMroik <mroik@delayed.space>2026-04-07 10:35:35 +0200
committerMroik <mroik@delayed.space>2026-04-13 06:56:10 +0200
commitceaa25c8baf2294458c1560b3292c00c57b0fa1b (patch)
treeb8fc7d22e43f485d0ed5e3acad82f7bfd74e4d8d /src
parent53f9119edd29611bd947da1187619627b59146e6 (diff)
Add SMTP server scaffolding
Signed-off-by: Mroik <mroik@delayed.space>
Diffstat (limited to 'src')
-rw-r--r--src/main.rs1
-rw-r--r--src/smtp.rs71
2 files changed, 72 insertions, 0 deletions
diff --git a/src/main.rs b/src/main.rs
index 60b75af..075dc7d 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,5 +1,6 @@
mod database;
mod list;
+mod smtp;
fn main() {
println!("Hello, world!");
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