diff --git a/src/transport/mod.rs b/src/transport/mod.rs index e884bb8..bd575d2 100644 --- a/src/transport/mod.rs +++ b/src/transport/mod.rs @@ -1,5 +1,6 @@ //! Represents an Email transport pub mod smtp; +pub mod sendmail; pub mod stub; pub mod file; diff --git a/src/transport/sendmail/error.rs b/src/transport/sendmail/error.rs new file mode 100644 index 0000000..5db1cf7 --- /dev/null +++ b/src/transport/sendmail/error.rs @@ -0,0 +1,54 @@ +//! Error and result type for sendmail transport + + +use self::Error::*; +use std::error::Error as StdError; +use std::fmt; +use std::fmt::{Display, Formatter}; +use std::io; + +/// An enum of all error kinds. +#[derive(Debug)] +pub enum Error { + /// Internal client error + Client(&'static str), + /// IO error + Io(io::Error), +} + +impl Display for Error { + fn fmt(&self, fmt: &mut Formatter) -> Result<(), fmt::Error> { + fmt.write_str(self.description()) + } +} + +impl StdError for Error { + fn description(&self) -> &str { + match *self { + Client(_) => "an unknown error occured", + Io(_) => "an I/O error occured", + } + } + + fn cause(&self) -> Option<&StdError> { + match *self { + Io(ref err) => Some(&*err as &StdError), + _ => None, + } + } +} + +impl From for Error { + fn from(err: io::Error) -> Error { + Io(err) + } +} + +impl From<&'static str> for Error { + fn from(string: &'static str) -> Error { + Client(string) + } +} + +/// SendMail result type +pub type SendmailResult = Result<(), Error>; diff --git a/src/transport/sendmail/mod.rs b/src/transport/sendmail/mod.rs new file mode 100644 index 0000000..6d226d7 --- /dev/null +++ b/src/transport/sendmail/mod.rs @@ -0,0 +1,44 @@ +//! This transport uilizes the sendmail executable for each email. + +use email::SendableEmail; +use std::error::Error; +use std::io::prelude::*; +use std::process::{Command, Stdio}; + +use transport::EmailTransport; +use transport::sendmail::error::SendmailResult; + +pub mod error; + +/// Writes the content and the envelope information to a file +pub struct SendmailTransport; + +impl EmailTransport for SendmailTransport { + fn send(&mut self, email: T) -> SendmailResult { + // Spawn the `wc` command + let process = try!(Command::new("/usr/bin/sendmail") + .args(&email.to_addresses()) + .stdin(Stdio::piped()) + .stdout(Stdio::piped()) + .spawn()); + + match process.stdin.unwrap().write_all(email.message().clone().as_bytes()) { + Err(why) => error!("couldn't write to sendmail stdin: {}", + why.description()), + Ok(_) => info!("sent pangram to sendmail"), + } + + let mut s = String::new(); + match process.stdout.unwrap().read_to_string(&mut s) { + Err(why) => error!("couldn't read sendmail stdout: {}", + why.description()), + Ok(_) => info!("sendmail responded with:\n{}", s), + } + + Ok(()) + } + + fn close(&mut self) { + () + } +}