import java.io.*;
import java.net.Socket;

/**
 * Simple SMTP Client that allows your Java App send emails.
 * Uses Java Sockets to connect directly to an SMTP server.
 * It supports sending of plain text or HTML emails.
 * Bonus: Unlike many other Java SMTP Sockets examples, this one actually works.
 *
 * @author Olly Oechsle, www.intelligent-web.co.uk
 */
public class Emailer {

    public static void main(String[] args) throws Exception {
        String results = send("localhost",
                25,
                "sender@somewhere.com",
                "recipient@somewhere.com",
                "Test Email",
                "<b>You got mail!</b>");
        System.out.println(results);
    }

    /**
     * Sends an email.
     *
     * @return The full SMTP conversation as a string.
     */
    public static String send(
            String host,
            int port,
            String to,
            String from,
            String subject,
            String message) throws Exception {

        // Save the SMTP conversation into this buffer (for debugging if necessary)
        StringBuffer buffer = new StringBuffer();

        try {

            // Connect to the SMTP server running on the local machine. Usually this is SendMail
            Socket smtpSocket = new Socket(host, port);

            // We send commands TO the server with this
            DataOutputStream output = new DataOutputStream(smtpSocket.getOutputStream());

            // And recieve responses FROM the server with this
            BufferedReader input =
                    new BufferedReader(
                            new InputStreamReader(
                                    new DataInputStream(smtpSocket.getInputStream())));

            try {

                // Read the server's hello message
                read(input, buffer);

                // Say hello to the server
                send(output, "HELO localhost.localdomain\r\n", buffer);
                read(input, buffer);

                // Who is sending the email
                send(output, "MAIL FROM: " + from + "\r\n", buffer);
                read(input, buffer);

                // Where the mail is going
                send(output, "RCPT to: " + to + "\r\n", buffer);
                read(input, buffer);

                // Start the message
                send(output, "DATA\r\n", buffer);
                read(input, buffer);

                // Set the subject
                send(output, "Subject: " + subject + "\r\n", buffer);

                // If we detect HTML in the message, set the content type so it displays
                // properly in the recipient's email client.
                if (message.indexOf("<") == -1) {
                    send(output, "Content-type: text/plain; charset=\"us-ascii\"\r\n", buffer);
                } else {
                    send(output, "Content-type: text/html; charset=\"us-ascii\"\r\n", buffer);
                }

                // Send the message
                send(output, message, buffer);

                // Finish the message
                send(output, "\r\n.\r\n", buffer);
                read(input, buffer);

                // Close the socket
                smtpSocket.close();

            }
            catch (IOException e) {
                System.out.println("Cannot send email as an error occurred.");
            }
        }
        catch (Exception e) {
            System.out.println("Host unknown");
        }

        return buffer.toString();

    }

    /**
     * Sends a message to the server using the DataOutputStream's writeBytes() method.
     * Saves what was sent to the buffer so we can record the conversation.
     */
    private static void send(DataOutputStream output,
                             String data,
                             StringBuffer buffer)
            throws IOException {
        output.writeBytes(data);
        buffer.append(data);
    }

    /**
     * Reads a line from the server and adds it onto the conversation buffer.
     */
    private static void read(BufferedReader br, StringBuffer buffer) throws IOException {
        int c;
        while ((c = br.read()) != -1) {
            buffer.append((char) c);
            if (c == '\n') {
                break;
            }
        }
    }

}