Follow master
This commit is contained in:
@@ -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<SmtpResponse,SmtpResponse> {
|
||||
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<S> {
|
||||
/// TCP stream between client and server
|
||||
@@ -87,10 +95,8 @@ pub struct SmtpClient<S> {
|
||||
port: Port,
|
||||
/// Our hostname for HELO/EHLO commands
|
||||
my_hostname: ~str,
|
||||
/// Does the server supports ESMTP
|
||||
does_esmtp: Option<bool>,
|
||||
/// ESMTP features supported by the server
|
||||
esmtp_features: Option<~[~str]>
|
||||
/// Information about the server
|
||||
server_info: Option<SmtpServerInfo>
|
||||
}
|
||||
|
||||
impl<S> SmtpClient<S> {
|
||||
@@ -101,14 +107,31 @@ impl<S> SmtpClient<S> {
|
||||
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<TcpStream> {
|
||||
@@ -191,11 +214,11 @@ impl SmtpClient<TcpStream> {
|
||||
// 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),
|
||||
|
||||
@@ -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<Command> {
|
||||
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()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user