diff options
Diffstat (limited to 'src/smtp.rs')
| -rw-r--r-- | src/smtp.rs | 71 |
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!() + } +} |
