diff --git a/src/smtp/client.rs b/src/smtp/client.rs index fc199bf..f6421e1 100644 --- a/src/smtp/client.rs +++ b/src/smtp/client.rs @@ -51,32 +51,40 @@ pub struct SmtpResponse { message: ~str } -impl ToStr for SmtpResponse { - /// Get the server reply - fn to_str(&self) -> ~str { - return format!("{} {}", self.code.to_str(), self.message); - } -} - impl fmt::Show for SmtpResponse { /// Format SMTP response display fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), IoError> { - f.buf.write(self.to_str().as_bytes()) + f.buf.write( + format!("{} {}", self.code.to_str(), self.message).as_bytes() + ) } } impl SmtpResponse { /// Check the response code fn with_code(&self, expected_codes: &[uint]) -> Result { + let response = SmtpResponse{code: self.code, message: self.message.clone()}; for &code in expected_codes.iter() { if code == self.code { - return Ok(SmtpResponse{code: self.code, message: self.message.clone()}); + return Ok(response); } } - return Err(SmtpResponse{code: self.code, message: self.message.clone()}); + return Err(response); } } +/// Information about an SMTP server +#[deriving(Eq,Clone)] +pub struct SmtpServerInfo { + /// Server name + name: ~str, + /// Does the server supports ESMTP + does_esmtp: bool, + /// ESMTP features supported by the server + esmtp_features: Option<~[~str]> +} + + /// Structure that implements a simple SMTP client pub struct SmtpClient { /// TCP stream between client and server @@ -87,10 +95,8 @@ pub struct SmtpClient { port: Port, /// Our hostname for HELO/EHLO commands my_hostname: ~str, - /// Does the server supports ESMTP - does_esmtp: Option, - /// ESMTP features supported by the server - esmtp_features: Option<~[~str]> + /// Information about the server + server_info: Option } impl SmtpClient { @@ -101,14 +107,31 @@ impl SmtpClient { host: host.to_owned(), port: port.unwrap_or(SMTP_PORT), my_hostname: my_hostname.unwrap_or("localhost").to_owned(), - does_esmtp: None, - esmtp_features: None + server_info: None } } + + +// use std::io::{stdin, BufferedReader}; +// fn main() { +// let mut stdin = BufferedReader::new(stdin()); +// for line in stdin.lines() { +// println!("{}", line); +// } +// } + + // fn parse_ehello_or_hello_response(response: &str) { // // split // } +// pub fn parse_ehlo_features(response: &str) -> { +// +// +// // split \n +// // let b: ~[int] = a.iter().map(|&x| x).to_owned_vec(); +// } + } impl SmtpClient { @@ -191,11 +214,11 @@ impl SmtpClient { // Ehello or Hello match self.send_command(commands::Ehello, Some(my_hostname.clone())).with_code([250, 500]) { Ok(SmtpResponse{code: 250, message: message}) => { - self.does_esmtp = Some(true); + self.server_info = Some(SmtpServerInfo{name: message.clone(), does_esmtp: true, esmtp_features: None}); info!("{:u} {:s}", 250u, message); }, Ok(SmtpResponse{code: code, message: message}) => { - self.does_esmtp = Some(false); + self.server_info = Some(SmtpServerInfo{name: message.clone(), does_esmtp: false, esmtp_features: None}); info!("{:u} {:s}", code, message); match self.send_command(commands::Ehello, Some(my_hostname.clone())).with_code([250]) { Ok(response) => info!("{:u} {:s}", response.code, response.message), diff --git a/src/smtp/commands.rs b/src/smtp/commands.rs index 0751778..7ca4dce 100644 --- a/src/smtp/commands.rs +++ b/src/smtp/commands.rs @@ -5,6 +5,8 @@ */ use std::fmt; +// use std::from_str::FromStr; +// use std::to_str::ToStr; use std::io; /* @@ -53,7 +55,7 @@ pub enum Command { Help, /// Noop command Noop, - /// Quit command + /// Quit commandopenclassroom vim Quit, /// Turn command, deprecated in RFC 5321 Turn, @@ -103,56 +105,6 @@ impl Command { } } -impl ToStr for Command { - /// Get the name of a command. - fn to_str(&self) -> ~str { - match *self { - Hello => ~"HELO", - Ehello => ~"EHLO", - Mail => ~"MAIL", - Recipient => ~"RCPT", - Data => ~"DATA", - Reset => ~"RSET", - SendMail => ~"SEND", - SendOrMail => ~"SOML", - SendAndMail => ~"SAML", - Verify => ~"VRFY", - Expand => ~"EXPN", - Help => ~"HELP", - Noop => ~"NOOP", - Quit => ~"QUIT", - Turn => ~"TURN", - } - } -} - -impl FromStr for Command { - /// Get the Command from its name. - fn from_str(command: &str) -> Option { - if !command.is_ascii() { - return None; - } - match command { - "HELO" => Some(Hello), - "EHLO" => Some(Ehello), - "MAIL" => Some(Mail), - "RCPT" => Some(Recipient), - "DATA" => Some(Data), - "RSET" => Some(Reset), - "SEND" => Some(SendMail), - "SOML" => Some(SendOrMail), - "SAML" => Some(SendAndMail), - "VRFY" => Some(Verify), - "EXPN" => Some(Expand), - "HELP" => Some(Help), - "NOOP" => Some(Noop), - "QUIT" => Some(Quit), - "TURN" => Some(Turn), - _ => None, - } - } -} - impl fmt::Show for Command { /// Format SMTP command display fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), io::IoError> { @@ -195,22 +147,15 @@ impl SmtpCommand { } } -impl ToStr for SmtpCommand { - /// Return the formatted command, ready to be used in an SMTP session. - fn to_str(&self) -> ~str { - match (self.command.takes_argument(), self.command.needs_argument(), self.argument.clone()) { - (true, _, Some(argument)) => format!("{} {}", self.command, argument), - (_, false, None) => format!("{}", self.command), - _ => fail!("Wrong SMTP syntax") - } - } -} - impl fmt::Show for SmtpCommand { /// Return the formatted command, ready to be used in an SMTP session. fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), io::IoError> { f.buf.write( - self.to_str().as_bytes() + match (self.command.takes_argument(), self.command.needs_argument(), self.argument.clone()) { + (true, _, Some(argument)) => format!("{} {}", self.command, argument), + (_, false, None) => format!("{}", self.command), + _ => fail!("Wrong SMTP syntax") + }.as_bytes() ) } }