diff --git a/README.rst b/README.rst index 81d0f73..7ce7f3d 100644 --- a/README.rst +++ b/README.rst @@ -18,13 +18,13 @@ Build the library: make -To build the example client code: +To build the example command-line client code: make examples -To run the example: +To run the example's help: - ./build/client src_addr dest_addr message_of_one_word server port + ./build/client -h Todo ---- diff --git a/src/examples/client.rs b/src/examples/client.rs index b852366..a67d108 100644 --- a/src/examples/client.rs +++ b/src/examples/client.rs @@ -10,32 +10,98 @@ #![crate_id = "client"] extern crate smtp; +extern crate getopts; +use std::io::stdin; use std::io::net::tcp::TcpStream; use std::strbuf::StrBuf; use std::io::net::ip::Port; use std::os; use smtp::client::SmtpClient; +use getopts::{optopt,optflag,getopts,OptGroup,usage}; -fn main() { - //! For now, only one word messages - //! - //! TODO: use parameters, flexible syntax - let args = os::args(); - match args.len() { - 6 => sendmail(args.get(1), args.get(2), args.get(3), args.get(4), args.get(5)), - _ => { - println!("Usage: {} source_address recipient_address message server port", args.get(0)); - return; - }, - }; -} - -fn sendmail(source_address: &~str, recipient_address: &~str, message: &~str, server: &~str, port: &~str) { - let mut email_client: SmtpClient = - SmtpClient::new(StrBuf::from_str(*server), from_str::(*port), None); +fn sendmail(source_address: StrBuf, recipient_addresses: Vec, message: StrBuf, server: StrBuf, port: Option, my_hostname: Option) { + let mut email_client: SmtpClient = + SmtpClient::new( + server, + port, + my_hostname); email_client.send_mail( - StrBuf::from_str(*source_address), - vec!(StrBuf::from_str(*recipient_address)), - StrBuf::from_str(*message) + source_address, + recipient_addresses, + message ); } + +fn print_usage(description: &str, _opts: &[OptGroup]) { + println!("{}", usage(description, _opts)); +} + +fn main() { + let args = os::args(); + + let program = args.get(0).clone(); + let description = format!("Usage: {0} [options...] recipients\n\n\ + This program reads a message on standard input until it reaches EOF,\ + then tries to send it using the given paramters.\n\n\ + Example: {0} -r user@example.org user@example.com < message.txt", program); + + let opts = [ + optopt("r", "reverse-path", "set the sender address", "FROM_ADDRESS"), + optopt("p", "port", "set the port to use, default is 25", "PORT"), + optopt("s", "server", "set the server to use, default is localhost", "SERVER"), + optopt("m", "my-hostname", "set the hostname used by the client", "MY_HOSTNAME"), + optflag("h", "help", "print this help menu"), + optflag("v", "verbose", "display the transaction details"), + ]; + let matches = match getopts(args.tail(), opts) { + Ok(m) => { m } + Err(f) => { fail!(f.to_err_msg()) } + }; + if matches.opt_present("h") { + print_usage(description, opts); + return; + } + + let sender = match matches.opt_str("r") { + Some(sender) => StrBuf::from_str(sender), + None => { + println!("The sender option is required"); + print_usage(program, opts); + return; + } + }; + + let server = match matches.opt_str("s") { + Some(server) => StrBuf::from_str(server), + None => StrBuf::from_str("localhost") + }; + + let my_hostname = match matches.opt_str("m") { + Some(my_hostname) => Some(StrBuf::from_str(my_hostname)), + None => None + }; + + let port = match matches.opt_str("p") { + Some(port) => from_str::(port), + None => None + + }; + + let recipients_str: &str = if !matches.free.is_empty() { + (*matches.free.get(0)).clone() + } else { + print_usage(description, opts); + return; + }; + let mut recipients = Vec::new(); + for recipient in recipients_str.split(' ') { + recipients.push(StrBuf::from_str(recipient)) + } + + let mut message = StrBuf::new(); + for line in stdin().lines() { + message = message.append(line.unwrap().to_str()); + } + + sendmail(sender, recipients, message, server, port, my_hostname); +} diff --git a/src/smtp/commands.rs b/src/smtp/commands.rs index da36e0a..5fd380b 100644 --- a/src/smtp/commands.rs +++ b/src/smtp/commands.rs @@ -143,7 +143,7 @@ mod test { let noop: SmtpCommand = super::Noop; assert_eq!(format!("{}", noop), "NOOP".to_owned()); assert_eq!(format!("{}", super::ExtendedHello("me")), "EHLO me".to_owned()); - assert_eq!(format!("{}", + assert_eq!(format!("{}", super::Mail("test", Some(vec!("option")))), "MAIL FROM: option".to_owned() ); }