Java tutorial
/* * Copyright (c) Ian F. Darwin, http://www.darwinsys.com/, 1996-2002. * All rights reserved. Software written by Ian F. Darwin and others. * $Id: LICENSE,v 1.8 2004/02/09 03:33:38 ian Exp $ * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * Java, the Duke mascot, and all variants of Sun's Java "steaming coffee * cup" logo are trademarks of Sun Microsystems. Sun's, and James Gosling's, * pioneering role in inventing and promulgating (and standardizing) the Java * language and environment is gratefully acknowledged. * * The pioneering role of Dennis Ritchie and Bjarne Stroustrup, of AT&T, for * inventing predecessor languages C and C++ is also gratefully acknowledged. */ /// import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintStream; import java.net.ConnectException; import java.net.NoRouteToHostException; import java.net.Socket; import java.net.UnknownHostException; import java.util.StringTokenizer; /** * SMTP talker class, usable standalone (as a SendMail(8) backend) or inside * applications such as JabaDex that need to send mail.. * * OBSOLETE!! Use javax.mail instead, now that it's available! * * Needs more parameterization - bit of a hack to start. Should use same * interface as Mailer (subclass, and override doSend()). * * @author Ian Darwin * @version $Id: SmtpTalk.java,v 1.10 2002/10/26 13:53:45 ian Exp $ */ public class SmtpTalk { BufferedReader is; PrintStream os; private boolean debug = true; private String host; /** * A simple main program showing the class in action. * * TODO generalize to accept From arg, read msg on stdin */ public static void main(String[] argv) { if (argv.length != 2) { System.err.println("Usage: java SmtpTalk host user"); System.exit(1); } try { SmtpTalk st = new SmtpTalk(argv[0]); System.out.println("SMTP Talker ready"); st.converse("MAILER-DAEMON@daroad.darwinsys.com", argv[1], "Test message", "Hello there"); } catch (Exception ig) { System.err.println(ig.getMessage()); System.exit(0); } } /** * Constructor taking a server hostname as argument. */ SmtpTalk(String server) throws Exception { host = server; try { Socket s = new Socket(host, 25); is = new BufferedReader(new InputStreamReader(s.getInputStream())); os = new PrintStream(s.getOutputStream()); } catch (NoRouteToHostException e) { die("No route to host " + host); } catch (ConnectException e) { die("Connection Refused by " + host); } catch (UnknownHostException e) { die("Unknown host " + host); } catch (IOException e) { die("I/O error setting up socket streams\n" + e); } } /** Send a command with an operand */ protected void send_cmd(String cmd, String oprnd) { send_cmd(cmd + " " + oprnd); } /* Send a command with no operand */ protected void send_cmd(String cmd) { if (debug) System.out.println(">>> " + cmd); os.print(cmd + "\r\n"); } /** Send_text sends the body of the message. */ public void send_text(String text) { os.print(text + "\r\n"); } /** Expect (read and check for) a given reply */ protected boolean expect_reply(String rspNum) throws Exception { String s = null; try { s = is.readLine(); } catch (IOException e) { die("I/O error reading from host " + host + " " + e); } if (debug) System.out.println("<<< " + s); return s.startsWith(rspNum + " "); } /** * Convenience routine to print message & exit, like K&P error(), perl * die(), ... * * @param ret * Numeric value to pass back * @param msg * Error message to be printed on stdout. */ protected void die(String msg) throws Exception { throw new Exception(msg); } /** * send one Mail message to one or more recipients via smtp to server * "host". */ public void converse(String sender, String recipients, String subject, String body) throws Exception { if (!expect_reply("220")) die("did not get SMTP greeting"); send_cmd("HELO", "darwinsys.com"); if (!expect_reply("250")) die("did not ack our HELO"); send_cmd("MAIL", "From:<" + sender + ">"); // no spaces! if (!expect_reply("250")) die("did not ack our MAIL command"); StringTokenizer st = new StringTokenizer(recipients); while (st.hasMoreTokens()) { String r = st.nextToken(); send_cmd("RCPT", "To:<" + r + ">"); if (!expect_reply("250")) die("didn't ack RCPT " + r); } send_cmd("DATA"); if (!expect_reply("354")) die("did not want our DATA!"); send_text("From: " + sender); send_text("To: " + recipients); send_text("Subject: " + subject); send_text(""); send_text(body + "\r"); send_cmd("."); if (!expect_reply("250")) die("Mail not accepted"); send_cmd("QUIT"); if (!expect_reply("221")) die("Other end not closing down"); } }