diff options
| author | Joe Robinson <joe@lc8n.com> | 2010-10-27 14:21:09 +0100 | 
|---|---|---|
| committer | Joe Robinson <joe@lc8n.com> | 2010-10-27 14:21:09 +0100 | 
| commit | 063284837c8c366e5502b1b0264b8eb807b61732 (patch) | |
| tree | fff3a1e1e5afaa671485b9d990704658276627ac /org/apache/commons/net/smtp | |
Basic upload functionality to predifined location, with basic file browser
Diffstat (limited to 'org/apache/commons/net/smtp')
| -rw-r--r-- | org/apache/commons/net/smtp/RelayPath.java | 102 | ||||
| -rw-r--r-- | org/apache/commons/net/smtp/SMTP.java | 777 | ||||
| -rw-r--r-- | org/apache/commons/net/smtp/SMTPClient.java | 607 | ||||
| -rw-r--r-- | org/apache/commons/net/smtp/SMTPCommand.java | 91 | ||||
| -rw-r--r-- | org/apache/commons/net/smtp/SMTPConnectionClosedException.java | 56 | ||||
| -rw-r--r-- | org/apache/commons/net/smtp/SMTPReply.java | 167 | ||||
| -rw-r--r-- | org/apache/commons/net/smtp/SimpleSMTPHeader.java | 153 | 
7 files changed, 1953 insertions, 0 deletions
| diff --git a/org/apache/commons/net/smtp/RelayPath.java b/org/apache/commons/net/smtp/RelayPath.java new file mode 100644 index 0000000..62d1098 --- /dev/null +++ b/org/apache/commons/net/smtp/RelayPath.java @@ -0,0 +1,102 @@ +/*
 + * Licensed to the Apache Software Foundation (ASF) under one or more
 + * contributor license agreements.  See the NOTICE file distributed with
 + * this work for additional information regarding copyright ownership.
 + * The ASF licenses this file to You under the Apache License, Version 2.0
 + * (the "License"); you may not use this file except in compliance with
 + * the License.  You may obtain a copy of the License at
 + *
 + *      http://www.apache.org/licenses/LICENSE-2.0
 + *
 + * Unless required by applicable law or agreed to in writing, software
 + * distributed under the License is distributed on an "AS IS" BASIS,
 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 + * See the License for the specific language governing permissions and
 + * limitations under the License.
 + */
 +
 +package org.apache.commons.net.smtp;
 +
 +import java.util.Enumeration;
 +import java.util.Vector;
 +
 +/***
 + * A class used to represent forward and reverse relay paths.  The
 + * SMTP MAIL command requires a reverse relay path while the SMTP RCPT
 + * command requires a forward relay path.  See RFC 821 for more details.
 + * In general, you will not have to deal with relay paths.
 + * <p>
 + * <p>
 + * @author Daniel F. Savarese
 + * @see SMTPClient
 + ***/
 +
 +public final class RelayPath
 +{
 +    Vector<String> _path;
 +    String _emailAddress;
 +
 +    /***
 +     * Create a relay path with the specified email address as the ultimate
 +     * destination.
 +     * <p>
 +     * @param emailAddress The destination email address.
 +     ***/
 +    public RelayPath(String emailAddress)
 +    {
 +        _path = new Vector<String>();
 +        _emailAddress = emailAddress;
 +    }
 +
 +    /***
 +     * Add a mail relay host to the relay path.  Hosts are added left to
 +     * right.  For example, the following will create the path
 +     * <code><b> < @bar.com,@foo.com:foobar@foo.com > </b></code>
 +     * <pre>
 +     * path = new RelayPath("foobar@foo.com");
 +     * path.addRelay("bar.com");
 +     * path.addRelay("foo.com");
 +     * </pre>
 +     * <p>
 +     * @param hostname The host to add to the relay path.
 +     ***/
 +    public void addRelay(String hostname)
 +    {
 +        _path.addElement(hostname);
 +    }
 +
 +    /***
 +     * Return the properly formatted string representation of the relay path.
 +     * <p>
 +     * @return The properly formatted string representation of the relay path.
 +     ***/
 +    @Override
 +    public String toString()
 +    {
 +        StringBuffer buffer = new StringBuffer();
 +        Enumeration<String> hosts;
 +
 +        buffer.append('<');
 +
 +        hosts = _path.elements();
 +
 +        if (hosts.hasMoreElements())
 +        {
 +            buffer.append('@');
 +            buffer.append(hosts.nextElement());
 +
 +            while (hosts.hasMoreElements())
 +            {
 +                buffer.append(",@");
 +                buffer.append(hosts.nextElement());
 +            }
 +            buffer.append(':');
 +        }
 +
 +        buffer.append(_emailAddress);
 +        buffer.append('>');
 +
 +        return buffer.toString();
 +    }
 +
 +}
 diff --git a/org/apache/commons/net/smtp/SMTP.java b/org/apache/commons/net/smtp/SMTP.java new file mode 100644 index 0000000..0a628b1 --- /dev/null +++ b/org/apache/commons/net/smtp/SMTP.java @@ -0,0 +1,777 @@ +/*
 + * Licensed to the Apache Software Foundation (ASF) under one or more
 + * contributor license agreements.  See the NOTICE file distributed with
 + * this work for additional information regarding copyright ownership.
 + * The ASF licenses this file to You under the Apache License, Version 2.0
 + * (the "License"); you may not use this file except in compliance with
 + * the License.  You may obtain a copy of the License at
 + *
 + *      http://www.apache.org/licenses/LICENSE-2.0
 + *
 + * Unless required by applicable law or agreed to in writing, software
 + * distributed under the License is distributed on an "AS IS" BASIS,
 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 + * See the License for the specific language governing permissions and
 + * limitations under the License.
 + */
 +
 +package org.apache.commons.net.smtp;
 +
 +import java.io.BufferedReader;
 +import java.io.BufferedWriter;
 +import java.io.IOException;
 +import java.io.InputStreamReader;
 +import java.io.OutputStreamWriter;
 +import java.util.ArrayList;
 +import java.util.Arrays;
 +
 +import org.apache.commons.net.MalformedServerReplyException;
 +import org.apache.commons.net.ProtocolCommandListener;
 +import org.apache.commons.net.ProtocolCommandSupport;
 +import org.apache.commons.net.SocketClient;
 +
 +/***
 + * SMTP provides the basic the functionality necessary to implement your
 + * own SMTP client.  To derive the full benefits of the SMTP class requires
 + * some knowledge of the FTP protocol defined in RFC 821.  However, there
 + * is no reason why you should have to use the SMTP class.  The
 + * {@link org.apache.commons.net.smtp.SMTPClient} class,
 + * derived from SMTP,
 + * implements all the functionality required of an SMTP client.  The
 + * SMTP class is made public to provide access to various SMTP constants
 + * and to make it easier for adventurous programmers (or those with
 + * special needs) to interact with the SMTP protocol and implement their
 + * own clients.  A set of methods with names corresponding to the SMTP
 + * command names are provided to facilitate this interaction.
 + * <p>
 + * You should keep in mind that the SMTP server may choose to prematurely
 + * close a connection for various reasons.  The SMTP class will detect a
 + * premature SMTP server connection closing when it receives a
 + * {@link org.apache.commons.net.smtp.SMTPReply#SERVICE_NOT_AVAILABLE SMTPReply.SERVICE_NOT_AVAILABLE }
 + *  response to a command.
 + * When that occurs, the SMTP class method encountering that reply will throw
 + * an {@link org.apache.commons.net.smtp.SMTPConnectionClosedException}
 + * .
 + * <code>SMTPConectionClosedException</code>
 + * is a subclass of <code> IOException </code> and therefore need not be
 + * caught separately, but if you are going to catch it separately, its
 + * catch block must appear before the more general <code> IOException </code>
 + * catch block.  When you encounter an
 + * {@link org.apache.commons.net.smtp.SMTPConnectionClosedException}
 + * , you must disconnect the connection with
 + * {@link org.apache.commons.net.SocketClient#disconnect  disconnect() }
 + * to properly clean up the system resources used by SMTP.  Before
 + * disconnecting, you may check the
 + * last reply code and text with
 + * {@link #getReplyCode  getReplyCode },
 + * {@link #getReplyString  getReplyString },
 + * and {@link #getReplyStrings  getReplyStrings}.
 + * <p>
 + * Rather than list it separately for each method, we mention here that
 + * every method communicating with the server and throwing an IOException
 + * can also throw a
 + * {@link org.apache.commons.net.MalformedServerReplyException}
 + * , which is a subclass
 + * of IOException.  A MalformedServerReplyException will be thrown when
 + * the reply received from the server deviates enough from the protocol
 + * specification that it cannot be interpreted in a useful manner despite
 + * attempts to be as lenient as possible.
 + * <p>
 + * <p>
 + * @author Daniel F. Savarese
 + * @see SMTPClient
 + * @see SMTPConnectionClosedException
 + * @see org.apache.commons.net.MalformedServerReplyException
 + ***/
 +
 +public class SMTP extends SocketClient
 +{
 +    /*** The default SMTP port (25). ***/
 +    public static final int DEFAULT_PORT = 25;
 +
 +    // We have to ensure that the protocol communication is in ASCII
 +    // but we use ISO-8859-1 just in case 8-bit characters cross
 +    // the wire.
 +    private static final String __DEFAULT_ENCODING = "ISO-8859-1";
 +    
 +    /** The encoding to use (user-settable) */
 +    private String encoding = __DEFAULT_ENCODING;
 +
 +    private StringBuffer __commandBuffer;
 +
 +    BufferedReader _reader;
 +    BufferedWriter _writer;
 +    int _replyCode;
 +    ArrayList<String> _replyLines;
 +    boolean _newReplyString;
 +    String _replyString;
 +
 +    /***
 +     * A ProtocolCommandSupport object used to manage the registering of
 +     * ProtocolCommandListeners and te firing of ProtocolCommandEvents.
 +     ***/
 +    protected ProtocolCommandSupport _commandSupport_;
 +
 +    /***
 +     * The default SMTP constructor.  Sets the default port to
 +     * <code>DEFAULT_PORT</code> and initializes internal data structures
 +     * for saving SMTP reply information.
 +     ***/
 +    public SMTP()
 +    {
 +        setDefaultPort(DEFAULT_PORT);
 +        __commandBuffer = new StringBuffer();
 +        _replyLines = new ArrayList<String>();
 +        _newReplyString = false;
 +        _replyString = null;
 +        _commandSupport_ = new ProtocolCommandSupport(this);
 +    }
 +    
 +    /**
 +     * Overloaded constructor where the user may specify a default encoding.
 +     * @param encoding
 +     * @since 2.0
 +     */
 +    public SMTP(String encoding) {
 +        this();
 +        this.encoding = encoding;
 +    }
 +
 +    private int __sendCommand(String command, String args, boolean includeSpace)
 +    throws IOException
 +    {
 +        String message;
 +
 +        __commandBuffer.setLength(0);
 +        __commandBuffer.append(command);
 +
 +        if (args != null)
 +        {
 +            if (includeSpace)
 +                __commandBuffer.append(' ');
 +            __commandBuffer.append(args);
 +        }
 +
 +        __commandBuffer.append(SocketClient.NETASCII_EOL);
 +
 +        _writer.write(message = __commandBuffer.toString());
 +        _writer.flush();
 +
 +        if (_commandSupport_.getListenerCount() > 0)
 +            _commandSupport_.fireCommandSent(command, message);
 +
 +        __getReply();
 +        return _replyCode;
 +    }
 +
 +    private int __sendCommand(int command, String args, boolean includeSpace)
 +    throws IOException
 +    {
 +        return __sendCommand(SMTPCommand._commands[command], args, includeSpace);
 +    }
 +
 +    private void __getReply() throws IOException
 +    {
 +        int length;
 +
 +        _newReplyString = true;
 +        _replyLines.clear();
 +
 +        String line = _reader.readLine();
 +
 +        if (line == null)
 +            throw new SMTPConnectionClosedException(
 +                "Connection closed without indication.");
 +
 +        // In case we run into an anomaly we don't want fatal index exceptions
 +        // to be thrown.
 +        length = line.length();
 +        if (length < 3)
 +            throw new MalformedServerReplyException(
 +                "Truncated server reply: " + line);
 +
 +        try
 +        {
 +            String code = line.substring(0, 3);
 +            _replyCode = Integer.parseInt(code);
 +        }
 +        catch (NumberFormatException e)
 +        {
 +            throw new MalformedServerReplyException(
 +                "Could not parse response code.\nServer Reply: " + line);
 +        }
 +
 +        _replyLines.add(line);
 +
 +        // Get extra lines if message continues.
 +        if (length > 3 && line.charAt(3) == '-')
 +        {
 +            do
 +            {
 +                line = _reader.readLine();
 +
 +                if (line == null)
 +                    throw new SMTPConnectionClosedException(
 +                        "Connection closed without indication.");
 +
 +                _replyLines.add(line);
 +
 +                // The length() check handles problems that could arise from readLine()
 +                // returning too soon after encountering a naked CR or some other
 +                // anomaly.
 +            }
 +            while (!(line.length() >= 4 && line.charAt(3) != '-' &&
 +                     Character.isDigit(line.charAt(0))));
 +            // This is too strong a condition because a non-conforming server
 +            // could screw things up like ftp.funet.fi does for FTP
 +            // line.startsWith(code)));
 +        }
 +
 +        if (_commandSupport_.getListenerCount() > 0)
 +            _commandSupport_.fireReplyReceived(_replyCode, getReplyString());
 +
 +        if (_replyCode == SMTPReply.SERVICE_NOT_AVAILABLE)
 +            throw new SMTPConnectionClosedException(
 +                "SMTP response 421 received.  Server closed connection.");
 +    }
 +
 +    /*** Initiates control connections and gets initial reply. ***/
 +    @Override
 +    protected void _connectAction_() throws IOException
 +    {
 +        super._connectAction_();
 +        _reader =
 +            new BufferedReader(new InputStreamReader(_input_,
 +                                                    encoding));
 +        _writer =
 +            new BufferedWriter(new OutputStreamWriter(_output_,
 +                                                      encoding));
 +        __getReply();
 +        
 +    }
 +
 +
 +    /***
 +     * Adds a ProtocolCommandListener.  Delegates this task to
 +     * {@link #_commandSupport_  _commandSupport_ }.
 +     * <p>
 +     * @param listener  The ProtocolCommandListener to add.
 +     ***/
 +    public void addProtocolCommandListener(ProtocolCommandListener listener)
 +    {
 +        _commandSupport_.addProtocolCommandListener(listener);
 +    }
 +
 +    /***
 +     * Removes a ProtocolCommandListener.  Delegates this task to
 +     * {@link #_commandSupport_  _commandSupport_ }.
 +     * <p>
 +     * @param listener  The ProtocolCommandListener to remove.
 +     ***/
 +    public void removeProtocolCommandistener(ProtocolCommandListener listener)
 +    {
 +        _commandSupport_.removeProtocolCommandListener(listener);
 +    }
 +
 +
 +    /***
 +     * Closes the connection to the SMTP server and sets to null
 +     * some internal data so that the memory may be reclaimed by the
 +     * garbage collector.  The reply text and code information from the
 +     * last command is voided so that the memory it used may be reclaimed.
 +     * <p>
 +     * @exception IOException If an error occurs while disconnecting.
 +     ***/
 +    @Override
 +    public void disconnect() throws IOException
 +    {
 +        super.disconnect();
 +        _reader = null;
 +        _writer = null;
 +        _replyString = null;
 +        _replyLines.clear();
 +        _newReplyString = false;
 +    }
 +
 +
 +    /***
 +     * Sends an SMTP command to the server, waits for a reply and returns the
 +     * numerical response code.  After invocation, for more detailed
 +     * information, the actual reply text can be accessed by calling
 +     * {@link #getReplyString  getReplyString } or
 +     * {@link #getReplyStrings  getReplyStrings }.
 +     * <p>
 +     * @param command  The text representation of the  SMTP command to send.
 +     * @param args The arguments to the SMTP command.  If this parameter is
 +     *             set to null, then the command is sent with no argument.
 +     * @return The integer value of the SMTP reply code returned by the server
 +     *         in response to the command.
 +     * @exception SMTPConnectionClosedException
 +     *      If the SMTP server prematurely closes the connection as a result
 +     *      of the client being idle or some other reason causing the server
 +     *      to send SMTP reply code 421.  This exception may be caught either
 +     *      as an IOException or independently as itself.
 +     * @exception IOException  If an I/O error occurs while either sending the
 +     *      command or receiving the server reply.
 +     ***/
 +    public int sendCommand(String command, String args) throws IOException
 +    {
 +        return __sendCommand(command, args, true);
 +    }
 +
 +
 +    /***
 +     * Sends an SMTP command to the server, waits for a reply and returns the
 +     * numerical response code.  After invocation, for more detailed
 +     * information, the actual reply text can be accessed by calling
 +     * {@link #getReplyString  getReplyString } or
 +     * {@link #getReplyStrings  getReplyStrings }.
 +     * <p>
 +     * @param command  The SMTPCommand constant corresponding to the SMTP command
 +     *                 to send.
 +     * @param args The arguments to the SMTP command.  If this parameter is
 +     *             set to null, then the command is sent with no argument.
 +     * @return The integer value of the SMTP reply code returned by the server
 +     *         in response to the command.
 +     * @exception SMTPConnectionClosedException
 +     *      If the SMTP server prematurely closes the connection as a result
 +     *      of the client being idle or some other reason causing the server
 +     *      to send SMTP reply code 421.  This exception may be caught either
 +     *      as an IOException or independently as itself.
 +     * @exception IOException  If an I/O error occurs while either sending the
 +     *      command or receiving the server reply.
 +     ***/
 +    public int sendCommand(int command, String args) throws IOException
 +    {
 +        return sendCommand(SMTPCommand._commands[command], args);
 +    }
 +
 +
 +    /***
 +     * Sends an SMTP command with no arguments to the server, waits for a
 +     * reply and returns the numerical response code.  After invocation, for
 +     * more detailed information, the actual reply text can be accessed by
 +     * calling {@link #getReplyString  getReplyString } or
 +     * {@link #getReplyStrings  getReplyStrings }.
 +     * <p>
 +     * @param command  The text representation of the  SMTP command to send.
 +     * @return The integer value of the SMTP reply code returned by the server
 +     *         in response to the command.
 +     * @exception SMTPConnectionClosedException
 +     *      If the SMTP server prematurely closes the connection as a result
 +     *      of the client being idle or some other reason causing the server
 +     *      to send SMTP reply code 421.  This exception may be caught either
 +     *      as an IOException or independently as itself.
 +     * @exception IOException  If an I/O error occurs while either sending the
 +     *      command or receiving the server reply.
 +     ***/
 +    public int sendCommand(String command) throws IOException
 +    {
 +        return sendCommand(command, null);
 +    }
 +
 +
 +    /***
 +     * Sends an SMTP command with no arguments to the server, waits for a
 +     * reply and returns the numerical response code.  After invocation, for
 +     * more detailed information, the actual reply text can be accessed by
 +     * calling {@link #getReplyString  getReplyString } or
 +     * {@link #getReplyStrings  getReplyStrings }.
 +     * <p>
 +     * @param command  The SMTPCommand constant corresponding to the SMTP command
 +     *                 to send.
 +     * @return The integer value of the SMTP reply code returned by the server
 +     *         in response to the command.
 +     * @exception SMTPConnectionClosedException
 +     *      If the SMTP server prematurely closes the connection as a result
 +     *      of the client being idle or some other reason causing the server
 +     *      to send SMTP reply code 421.  This exception may be caught either
 +     *      as an IOException or independently as itself.
 +     * @exception IOException  If an I/O error occurs while either sending the
 +     *      command or receiving the server reply.
 +     ***/
 +    public int sendCommand(int command) throws IOException
 +    {
 +        return sendCommand(command, null);
 +    }
 +
 +
 +    /***
 +     * Returns the integer value of the reply code of the last SMTP reply.
 +     * You will usually only use this method after you connect to the
 +     * SMTP server to check that the connection was successful since
 +     * <code> connect </code> is of type void.
 +     * <p>
 +     * @return The integer value of the reply code of the last SMTP reply.
 +     ***/
 +    public int getReplyCode()
 +    {
 +        return _replyCode;
 +    }
 +
 +    /***
 +     * Fetches a reply from the SMTP server and returns the integer reply
 +     * code.  After calling this method, the actual reply text can be accessed
 +     * from either  calling {@link #getReplyString  getReplyString } or
 +     * {@link #getReplyStrings  getReplyStrings }.  Only use this
 +     * method if you are implementing your own SMTP client or if you need to
 +     * fetch a secondary response from the SMTP server.
 +     * <p>
 +     * @return The integer value of the reply code of the fetched SMTP reply.
 +     * @exception SMTPConnectionClosedException
 +     *      If the SMTP server prematurely closes the connection as a result
 +     *      of the client being idle or some other reason causing the server
 +     *      to send SMTP reply code 421.  This exception may be caught either
 +     *      as an IOException or independently as itself.
 +     * @exception IOException  If an I/O error occurs while receiving the
 +     *                         server reply.
 +     ***/
 +    public int getReply() throws IOException
 +    {
 +        __getReply();
 +        return _replyCode;
 +    }
 +
 +
 +    /***
 +     * Returns the lines of text from the last SMTP server response as an array
 +     * of strings, one entry per line.  The end of line markers of each are
 +     * stripped from each line.
 +     * <p>
 +     * @return The lines of text from the last SMTP response as an array.
 +     ***/
 +    public String[] getReplyStrings()
 +    {
 +        String[] lines;
 +        lines = new String[_replyLines.size()];
 +        _replyLines.addAll(Arrays.asList(lines));
 +        return lines;
 +    }
 +
 +    /***
 +     * Returns the entire text of the last SMTP server response exactly
 +     * as it was received, including all end of line markers in NETASCII
 +     * format.
 +     * <p>
 +     * @return The entire text from the last SMTP response as a String.
 +     ***/
 +    public String getReplyString()
 +    {
 +        StringBuilder buffer;
 +
 +        if (!_newReplyString)
 +            return _replyString;
 +
 +        buffer = new StringBuilder();
 +        
 +        for (String line : _replyLines)
 +        {
 +            buffer.append(line);
 +            buffer.append(SocketClient.NETASCII_EOL);
 +        }
 +
 +        _newReplyString = false;
 +
 +        return (_replyString = buffer.toString());
 +    }
 +
 +
 +    /***
 +     * A convenience method to send the SMTP HELO command to the server,
 +     * receive the reply, and return the reply code.
 +     * <p>
 +     * @param hostname The hostname of the sender.
 +     * @return The reply code received from the server.
 +     * @exception SMTPConnectionClosedException
 +     *      If the SMTP server prematurely closes the connection as a result
 +     *      of the client being idle or some other reason causing the server
 +     *      to send SMTP reply code 421.  This exception may be caught either
 +     *      as an IOException or independently as itself.
 +     * @exception IOException  If an I/O error occurs while either sending the
 +     *      command or receiving the server reply.
 +     ***/
 +    public int helo(String hostname) throws IOException
 +    {
 +        return sendCommand(SMTPCommand.HELO, hostname);
 +    }
 +
 +
 +    /***
 +     * A convenience method to send the SMTP MAIL command to the server,
 +     * receive the reply, and return the reply code.
 +     * <p>
 +     * @param reversePath The reverese path.
 +     * @return The reply code received from the server.
 +     * @exception SMTPConnectionClosedException
 +     *      If the SMTP server prematurely closes the connection as a result
 +     *      of the client being idle or some other reason causing the server
 +     *      to send SMTP reply code 421.  This exception may be caught either
 +     *      as an IOException or independently as itself.
 +     * @exception IOException  If an I/O error occurs while either sending the
 +     *      command or receiving the server reply.
 +     ***/
 +    public int mail(String reversePath) throws IOException
 +    {
 +        return __sendCommand(SMTPCommand.MAIL, reversePath, false);
 +    }
 +
 +
 +    /***
 +     * A convenience method to send the SMTP RCPT command to the server,
 +     * receive the reply, and return the reply code.
 +     * <p>
 +     * @param forwardPath The forward path.
 +     * @return The reply code received from the server.
 +     * @exception SMTPConnectionClosedException
 +     *      If the SMTP server prematurely closes the connection as a result
 +     *      of the client being idle or some other reason causing the server
 +     *      to send SMTP reply code 421.  This exception may be caught either
 +     *      as an IOException or independently as itself.
 +     * @exception IOException  If an I/O error occurs while either sending the
 +     *      command or receiving the server reply.
 +     ***/
 +    public int rcpt(String forwardPath) throws IOException
 +    {
 +        return __sendCommand(SMTPCommand.RCPT, forwardPath, false);
 +    }
 +
 +
 +    /***
 +     * A convenience method to send the SMTP DATA command to the server,
 +     * receive the reply, and return the reply code.
 +     * <p>
 +     * @return The reply code received from the server.
 +     * @exception SMTPConnectionClosedException
 +     *      If the SMTP server prematurely closes the connection as a result
 +     *      of the client being idle or some other reason causing the server
 +     *      to send SMTP reply code 421.  This exception may be caught either
 +     *      as an IOException or independently as itself.
 +     * @exception IOException  If an I/O error occurs while either sending the
 +     *      command or receiving the server reply.
 +     ***/
 +    public int data() throws IOException
 +    {
 +        return sendCommand(SMTPCommand.DATA);
 +    }
 +
 +
 +    /***
 +     * A convenience method to send the SMTP SEND command to the server,
 +     * receive the reply, and return the reply code.
 +     * <p>
 +     * @param reversePath The reverese path.
 +     * @return The reply code received from the server.
 +     * @exception SMTPConnectionClosedException
 +     *      If the SMTP server prematurely closes the connection as a result
 +     *      of the client being idle or some other reason causing the server
 +     *      to send SMTP reply code 421.  This exception may be caught either
 +     *      as an IOException or independently as itself.
 +     * @exception IOException  If an I/O error occurs while either sending the
 +     *      command or receiving the server reply.
 +     ***/
 +    public int send(String reversePath) throws IOException
 +    {
 +        return sendCommand(SMTPCommand.SEND, reversePath);
 +    }
 +
 +
 +    /***
 +     * A convenience method to send the SMTP SOML command to the server,
 +     * receive the reply, and return the reply code.
 +     * <p>
 +     * @param reversePath The reverese path.
 +     * @return The reply code received from the server.
 +     * @exception SMTPConnectionClosedException
 +     *      If the SMTP server prematurely closes the connection as a result
 +     *      of the client being idle or some other reason causing the server
 +     *      to send SMTP reply code 421.  This exception may be caught either
 +     *      as an IOException or independently as itself.
 +     * @exception IOException  If an I/O error occurs while either sending the
 +     *      command or receiving the server reply.
 +     ***/
 +    public int soml(String reversePath) throws IOException
 +    {
 +        return sendCommand(SMTPCommand.SOML, reversePath);
 +    }
 +
 +
 +    /***
 +     * A convenience method to send the SMTP SAML command to the server,
 +     * receive the reply, and return the reply code.
 +     * <p>
 +     * @param reversePath The reverese path.
 +     * @return The reply code received from the server.
 +     * @exception SMTPConnectionClosedException
 +     *      If the SMTP server prematurely closes the connection as a result
 +     *      of the client being idle or some other reason causing the server
 +     *      to send SMTP reply code 421.  This exception may be caught either
 +     *      as an IOException or independently as itself.
 +     * @exception IOException  If an I/O error occurs while either sending the
 +     *      command or receiving the server reply.
 +     ***/
 +    public int saml(String reversePath) throws IOException
 +    {
 +        return sendCommand(SMTPCommand.SAML, reversePath);
 +    }
 +
 +
 +    /***
 +     * A convenience method to send the SMTP RSET command to the server,
 +     * receive the reply, and return the reply code.
 +     * <p>
 +     * @return The reply code received from the server.
 +     * @exception SMTPConnectionClosedException
 +     *      If the SMTP server prematurely closes the connection as a result
 +     *      of the client being idle or some other reason causing the server
 +     *      to send SMTP reply code 421.  This exception may be caught either
 +     *      as an IOException or independently as itself.
 +     * @exception IOException  If an I/O error occurs while either sending the
 +     *      command or receiving the server reply.
 +     ***/
 +    public int rset() throws IOException
 +    {
 +        return sendCommand(SMTPCommand.RSET);
 +    }
 +
 +
 +    /***
 +     * A convenience method to send the SMTP VRFY command to the server,
 +     * receive the reply, and return the reply code.
 +     * <p>
 +     * @param user The user address to verify.
 +     * @return The reply code received from the server.
 +     * @exception SMTPConnectionClosedException
 +     *      If the SMTP server prematurely closes the connection as a result
 +     *      of the client being idle or some other reason causing the server
 +     *      to send SMTP reply code 421.  This exception may be caught either
 +     *      as an IOException or independently as itself.
 +     * @exception IOException  If an I/O error occurs while either sending the
 +     *      command or receiving the server reply.
 +     ***/
 +    public int vrfy(String user) throws IOException
 +    {
 +        return sendCommand(SMTPCommand.VRFY, user);
 +    }
 +
 +
 +    /***
 +     * A convenience method to send the SMTP VRFY command to the server,
 +     * receive the reply, and return the reply code.
 +     * <p>
 +     * @param name The name to expand.
 +     * @return The reply code received from the server.
 +     * @exception SMTPConnectionClosedException
 +     *      If the SMTP server prematurely closes the connection as a result
 +     *      of the client being idle or some other reason causing the server
 +     *      to send SMTP reply code 421.  This exception may be caught either
 +     *      as an IOException or independently as itself.
 +     * @exception IOException  If an I/O error occurs while either sending the
 +     *      command or receiving the server reply.
 +     ***/
 +    public int expn(String name) throws IOException
 +    {
 +        return sendCommand(SMTPCommand.EXPN, name);
 +    }
 +
 +    /***
 +     * A convenience method to send the SMTP HELP command to the server,
 +     * receive the reply, and return the reply code.
 +     * <p>
 +     * @return The reply code received from the server.
 +     * @exception SMTPConnectionClosedException
 +     *      If the SMTP server prematurely closes the connection as a result
 +     *      of the client being idle or some other reason causing the server
 +     *      to send SMTP reply code 421.  This exception may be caught either
 +     *      as an IOException or independently as itself.
 +     * @exception IOException  If an I/O error occurs while either sending the
 +     *      command or receiving the server reply.
 +     ***/
 +    public int help() throws IOException
 +    {
 +        return sendCommand(SMTPCommand.HELP);
 +    }
 +
 +    /***
 +     * A convenience method to send the SMTP HELP command to the server,
 +     * receive the reply, and return the reply code.
 +     * <p>
 +     * @param command  The command name on which to request help.
 +     * @return The reply code received from the server.
 +     * @exception SMTPConnectionClosedException
 +     *      If the SMTP server prematurely closes the connection as a result
 +     *      of the client being idle or some other reason causing the server
 +     *      to send SMTP reply code 421.  This exception may be caught either
 +     *      as an IOException or independently as itself.
 +     * @exception IOException  If an I/O error occurs while either sending the
 +     *      command or receiving the server reply.
 +     ***/
 +    public int help(String command) throws IOException
 +    {
 +        return sendCommand(SMTPCommand.HELP, command);
 +    }
 +
 +    /***
 +     * A convenience method to send the SMTP NOOP command to the server,
 +     * receive the reply, and return the reply code.
 +     * <p>
 +     * @return The reply code received from the server.
 +     * @exception SMTPConnectionClosedException
 +     *      If the SMTP server prematurely closes the connection as a result
 +     *      of the client being idle or some other reason causing the server
 +     *      to send SMTP reply code 421.  This exception may be caught either
 +     *      as an IOException or independently as itself.
 +     * @exception IOException  If an I/O error occurs while either sending the
 +     *      command or receiving the server reply.
 +     ***/
 +    public int noop() throws IOException
 +    {
 +        return sendCommand(SMTPCommand.NOOP);
 +    }
 +
 +
 +    /***
 +     * A convenience method to send the SMTP TURN command to the server,
 +     * receive the reply, and return the reply code.
 +     * <p>
 +     * @return The reply code received from the server.
 +     * @exception SMTPConnectionClosedException
 +     *      If the SMTP server prematurely closes the connection as a result
 +     *      of the client being idle or some other reason causing the server
 +     *      to send SMTP reply code 421.  This exception may be caught either
 +     *      as an IOException or independently as itself.
 +     * @exception IOException  If an I/O error occurs while either sending the
 +     *      command or receiving the server reply.
 +     ***/
 +    public int turn() throws IOException
 +    {
 +        return sendCommand(SMTPCommand.TURN);
 +    }
 +
 +
 +    /***
 +     * A convenience method to send the SMTP QUIT command to the server,
 +     * receive the reply, and return the reply code.
 +     * <p>
 +     * @return The reply code received from the server.
 +     * @exception SMTPConnectionClosedException
 +     *      If the SMTP server prematurely closes the connection as a result
 +     *      of the client being idle or some other reason causing the server
 +     *      to send SMTP reply code 421.  This exception may be caught either
 +     *      as an IOException or independently as itself.
 +     * @exception IOException  If an I/O error occurs while either sending the
 +     *      command or receiving the server reply.
 +     ***/
 +    public int quit() throws IOException
 +    {
 +        return sendCommand(SMTPCommand.QUIT);
 +    }
 +
 +}
 +
 +/* Emacs configuration
 + * Local variables:        **
 + * mode:             java  **
 + * c-basic-offset:   4     **
 + * indent-tabs-mode: nil   **
 + * End:                    **
 + */
 diff --git a/org/apache/commons/net/smtp/SMTPClient.java b/org/apache/commons/net/smtp/SMTPClient.java new file mode 100644 index 0000000..8b9ed45 --- /dev/null +++ b/org/apache/commons/net/smtp/SMTPClient.java @@ -0,0 +1,607 @@ +/*
 + * Licensed to the Apache Software Foundation (ASF) under one or more
 + * contributor license agreements.  See the NOTICE file distributed with
 + * this work for additional information regarding copyright ownership.
 + * The ASF licenses this file to You under the Apache License, Version 2.0
 + * (the "License"); you may not use this file except in compliance with
 + * the License.  You may obtain a copy of the License at
 + *
 + *      http://www.apache.org/licenses/LICENSE-2.0
 + *
 + * Unless required by applicable law or agreed to in writing, software
 + * distributed under the License is distributed on an "AS IS" BASIS,
 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 + * See the License for the specific language governing permissions and
 + * limitations under the License.
 + */
 +
 +package org.apache.commons.net.smtp;
 +
 +import java.io.IOException;
 +import java.io.Writer;
 +import java.net.InetAddress;
 +
 +import org.apache.commons.net.io.DotTerminatedMessageWriter;
 +
 +/***
 + * SMTPClient encapsulates all the functionality necessary to send files
 + * through an SMTP server.  This class takes care of all
 + * low level details of interacting with an SMTP server and provides
 + * a convenient higher level interface.  As with all classes derived
 + * from {@link org.apache.commons.net.SocketClient},
 + * you must first connect to the server with
 + * {@link org.apache.commons.net.SocketClient#connect  connect }
 + * before doing anything, and finally
 + * {@link org.apache.commons.net.SocketClient#disconnect  disconnect }
 + * after you're completely finished interacting with the server.
 + * Then you need to check the SMTP reply code to see if the connection
 + * was successful.  For example:
 + * <pre>
 + *    try {
 + *      int reply;
 + *      client.connect("mail.foobar.com");
 + *      System.out.print(client.getReplyString());
 + *
 + *      // After connection attempt, you should check the reply code to verify
 + *      // success.
 + *      reply = client.getReplyCode();
 + *
 + *      if(!SMTPReply.isPositiveCompletion(reply)) {
 + *        client.disconnect();
 + *        System.err.println("SMTP server refused connection.");
 + *        System.exit(1);
 + *      }
 + *
 + *      // Do useful stuff here.
 + *      ...
 + *    } catch(IOException e) {
 + *      if(client.isConnected()) {
 + *        try {
 + *          client.disconnect();
 + *        } catch(IOException f) {
 + *          // do nothing
 + *        }
 + *      }
 + *      System.err.println("Could not connect to server.");
 + *      e.printStackTrace();
 + *      System.exit(1);
 + *    }
 + * </pre>
 + * <p>
 + * Immediately after connecting is the only real time you need to check the
 + * reply code (because connect is of type void).  The convention for all the
 + * SMTP command methods in SMTPClient is such that they either return a
 + * boolean value or some other value.
 + * The boolean methods return true on a successful completion reply from
 + * the SMTP server and false on a reply resulting in an error condition or
 + * failure.  The methods returning a value other than boolean return a value
 + * containing the higher level data produced by the SMTP command, or null if a
 + * reply resulted in an error condition or failure.  If you want to access
 + * the exact SMTP reply code causing a success or failure, you must call
 + * {@link org.apache.commons.net.smtp.SMTP#getReplyCode  getReplyCode } after
 + * a success or failure.
 + * <p>
 + * You should keep in mind that the SMTP server may choose to prematurely
 + * close a connection for various reasons.  The SMTPClient class will detect a
 + * premature SMTP server connection closing when it receives a
 + * {@link org.apache.commons.net.smtp.SMTPReply#SERVICE_NOT_AVAILABLE SMTPReply.SERVICE_NOT_AVAILABLE }
 + *  response to a command.
 + * When that occurs, the method encountering that reply will throw
 + * an {@link org.apache.commons.net.smtp.SMTPConnectionClosedException}
 + * .
 + * <code>SMTPConectionClosedException</code>
 + * is a subclass of <code> IOException </code> and therefore need not be
 + * caught separately, but if you are going to catch it separately, its
 + * catch block must appear before the more general <code> IOException </code>
 + * catch block.  When you encounter an
 + * {@link org.apache.commons.net.smtp.SMTPConnectionClosedException}
 + * , you must disconnect the connection with
 + * {@link #disconnect  disconnect() } to properly clean up the
 + * system resources used by SMTPClient.  Before disconnecting, you may check
 + * the last reply code and text with
 + * {@link org.apache.commons.net.smtp.SMTP#getReplyCode  getReplyCode },
 + * {@link org.apache.commons.net.smtp.SMTP#getReplyString  getReplyString },
 + * and
 + * {@link org.apache.commons.net.smtp.SMTP#getReplyStrings getReplyStrings}.
 + * <p>
 + * Rather than list it separately for each method, we mention here that
 + * every method communicating with the server and throwing an IOException
 + * can also throw a
 + * {@link org.apache.commons.net.MalformedServerReplyException}
 + * , which is a subclass
 + * of IOException.  A MalformedServerReplyException will be thrown when
 + * the reply received from the server deviates enough from the protocol
 + * specification that it cannot be interpreted in a useful manner despite
 + * attempts to be as lenient as possible.
 + * <p>
 + * <p>
 + * @author Daniel F. Savarese
 + * @see SMTP
 + * @see SimpleSMTPHeader
 + * @see RelayPath
 + * @see SMTPConnectionClosedException
 + * @see org.apache.commons.net.MalformedServerReplyException
 + ***/
 +
 +public class SMTPClient extends SMTP
 +{
 +
 +    /**
 +     * Default SMTPClient constructor.  Creates a new SMTPClient instance.
 +     */
 +    public SMTPClient() {  }
 +    
 +    /**
 +     * Overloaded constructor that takes an encoding specification
 +     * @param encoding The encoding to use
 +     * @since 2.0
 +     */
 +    public SMTPClient(String encoding) {
 +        super(encoding);
 +    }
 +
 +
 +    /***
 +     * At least one SMTPClient method ({@link #sendMessageData  sendMessageData })
 +     * does not complete the entire sequence of SMTP commands to complete a
 +     * transaction.  These types of commands require some action by the
 +     * programmer after the reception of a positive intermediate command.
 +     * After the programmer's code completes its actions, it must call this
 +     * method to receive the completion reply from the server and verify the
 +     * success of the entire transaction.
 +     * <p>
 +     * For example,
 +     * <pre>
 +     * writer = client.sendMessage();
 +     * if(writer == null) // failure
 +     *   return false;
 +     * header =
 +     *  new SimpleSMTPHeader("foobar@foo.com", "foo@foobar.com", "Re: Foo");
 +     * writer.write(header.toString());
 +     * writer.write("This is just a test");
 +     * writer.close();
 +     * if(!client.completePendingCommand()) // failure
 +     *   return false;
 +     * </pre>
 +     * <p>
 +     * @return True if successfully completed, false if not.
 +     * @exception SMTPConnectionClosedException
 +     *      If the SMTP server prematurely closes the connection as a result
 +     *      of the client being idle or some other reason causing the server
 +     *      to send SMTP reply code 421.  This exception may be caught either
 +     *      as an IOException or independently as itself.
 +     * @exception IOException  If an I/O error occurs while either sending a
 +     *      command to the server or receiving a reply from the server.
 +     ***/
 +    public boolean completePendingCommand() throws IOException
 +    {
 +        return SMTPReply.isPositiveCompletion(getReply());
 +    }
 +
 +
 +    /***
 +     * Login to the SMTP server by sending the HELO command with the
 +     * given hostname as an argument.  Before performing any mail commands,
 +     * you must first login.
 +     * <p>
 +     * @param hostname  The hostname with which to greet the SMTP server.
 +     * @return True if successfully completed, false if not.
 +     * @exception SMTPConnectionClosedException
 +     *      If the SMTP server prematurely closes the connection as a result
 +     *      of the client being idle or some other reason causing the server
 +     *      to send SMTP reply code 421.  This exception may be caught either
 +     *      as an IOException or independently as itself.
 +     * @exception IOException  If an I/O error occurs while either sending a
 +     *      command to the server or receiving a reply from the server.
 +     ***/
 +    public boolean login(String hostname) throws IOException
 +    {
 +        return SMTPReply.isPositiveCompletion(helo(hostname));
 +    }
 +
 +
 +    /***
 +     * Login to the SMTP server by sending the HELO command with the
 +     * client hostname as an argument.  Before performing any mail commands,
 +     * you must first login.
 +     * <p>
 +     * @return True if successfully completed, false if not.
 +     * @exception SMTPConnectionClosedException
 +     *      If the SMTP server prematurely closes the connection as a result
 +     *      of the client being idle or some other reason causing the server
 +     *      to send SMTP reply code 421.  This exception may be caught either
 +     *      as an IOException or independently as itself.
 +     * @exception IOException  If an I/O error occurs while either sending a
 +     *      command to the server or receiving a reply from the server.
 +     ***/
 +    public boolean login() throws IOException
 +    {
 +        String name;
 +        InetAddress host;
 +
 +        host = getLocalAddress();
 +        name = host.getHostName();
 +
 +        if (name == null)
 +            return false;
 +
 +        return SMTPReply.isPositiveCompletion(helo(name));
 +    }
 +
 +
 +    /***
 +     * Set the sender of a message using the SMTP MAIL command, specifying
 +     * a reverse relay path.  The sender must be set first before any
 +     * recipients may be specified, otherwise the mail server will reject
 +     * your commands.
 +     * <p>
 +     * @param path  The reverse relay path pointing back to the sender.
 +     * @return True if successfully completed, false if not.
 +     * @exception SMTPConnectionClosedException
 +     *      If the SMTP server prematurely closes the connection as a result
 +     *      of the client being idle or some other reason causing the server
 +     *      to send SMTP reply code 421.  This exception may be caught either
 +     *      as an IOException or independently as itself.
 +     * @exception IOException  If an I/O error occurs while either sending a
 +     *      command to the server or receiving a reply from the server.
 +     ***/
 +    public boolean setSender(RelayPath path) throws IOException
 +    {
 +        return SMTPReply.isPositiveCompletion(mail(path.toString()));
 +    }
 +
 +
 +    /***
 +     * Set the sender of a message using the SMTP MAIL command, specifying
 +     * the sender's email address. The sender must be set first before any
 +     * recipients may be specified, otherwise the mail server will reject
 +     * your commands.
 +     * <p>
 +     * @param address  The sender's email address.
 +     * @return True if successfully completed, false if not.
 +     * @exception SMTPConnectionClosedException
 +     *      If the SMTP server prematurely closes the connection as a result
 +     *      of the client being idle or some other reason causing the server
 +     *      to send SMTP reply code 421.  This exception may be caught either
 +     *      as an IOException or independently as itself.
 +     * @exception IOException  If an I/O error occurs while either sending a
 +     *      command to the server or receiving a reply from the server.
 +     ***/
 +    public boolean setSender(String address) throws IOException
 +    {
 +        return SMTPReply.isPositiveCompletion(mail("<" + address + ">"));
 +    }
 +
 +
 +    /***
 +     * Add a recipient for a message using the SMTP RCPT command, specifying
 +     * a forward relay path.  The sender must be set first before any
 +     * recipients may be specified, otherwise the mail server will reject
 +     * your commands.
 +     * <p>
 +     * @param path  The forward relay path pointing to the recipient.
 +     * @return True if successfully completed, false if not.
 +     * @exception SMTPConnectionClosedException
 +     *      If the SMTP server prematurely closes the connection as a result
 +     *      of the client being idle or some other reason causing the server
 +     *      to send SMTP reply code 421.  This exception may be caught either
 +     *      as an IOException or independently as itself.
 +     * @exception IOException  If an I/O error occurs while either sending a
 +     *      command to the server or receiving a reply from the server.
 +     ***/
 +    public boolean addRecipient(RelayPath path) throws IOException
 +    {
 +        return SMTPReply.isPositiveCompletion(rcpt(path.toString()));
 +    }
 +
 +
 +    /***
 +     * Add a recipient for a message using the SMTP RCPT command, the
 +     * recipient's email address.  The sender must be set first before any
 +     * recipients may be specified, otherwise the mail server will reject
 +     * your commands.
 +     * <p>
 +     * @param address  The recipient's email address.
 +     * @return True if successfully completed, false if not.
 +     * @exception SMTPConnectionClosedException
 +     *      If the SMTP server prematurely closes the connection as a result
 +     *      of the client being idle or some other reason causing the server
 +     *      to send SMTP reply code 421.  This exception may be caught either
 +     *      as an IOException or independently as itself.
 +     * @exception IOException  If an I/O error occurs while either sending a
 +     *      command to the server or receiving a reply from the server.
 +     ***/
 +    public boolean addRecipient(String address) throws IOException
 +    {
 +        return SMTPReply.isPositiveCompletion(rcpt("<" + address + ">"));
 +    }
 +
 +
 +
 +    /***
 +     * Send the SMTP DATA command in preparation to send an email message.
 +     * This method returns a DotTerminatedMessageWriter instance to which
 +     * the message can be written.  Null is returned if the DATA command
 +     * fails.
 +     * <p>
 +     * You must not issue any commands to the SMTP server (i.e., call any
 +     * (other methods) until you finish writing to the returned Writer
 +     * instance and close it.  The SMTP protocol uses the same stream for
 +     * issuing commands as it does for returning results.  Therefore the
 +     * returned Writer actually writes directly to the SMTP connection.
 +     * After you close the writer, you can execute new commands.  If you
 +     * do not follow these requirements your program will not work properly.
 +     * <p>
 +     * You can use the provided
 +     * {@link org.apache.commons.net.smtp.SimpleSMTPHeader}
 +     * class to construct a bare minimum header.
 +     * To construct more complicated headers you should
 +     * refer to RFC 822.  When the Java Mail API is finalized, you will be
 +     * able to use it to compose fully compliant Internet text messages.
 +     * The DotTerminatedMessageWriter takes care of doubling line-leading
 +     * dots and ending the message with a single dot upon closing, so all
 +     * you have to worry about is writing the header and the message.
 +     * <p>
 +     * Upon closing the returned Writer, you need to call
 +     * {@link #completePendingCommand  completePendingCommand() }
 +     * to finalize the transaction and verify its success or failure from
 +     * the server reply.
 +     * <p>
 +     * @return A DotTerminatedMessageWriter to which the message (including
 +     *      header) can be written.  Returns null if the command fails.
 +     * @exception SMTPConnectionClosedException
 +     *      If the SMTP server prematurely closes the connection as a result
 +     *      of the client being idle or some other reason causing the server
 +     *      to send SMTP reply code 421.  This exception may be caught either
 +     *      as an IOException or independently as itself.
 +     * @exception IOException  If an I/O error occurs while either sending a
 +     *      command to the server or receiving a reply from the server.
 +     ***/
 +    public Writer sendMessageData() throws IOException
 +    {
 +        if (!SMTPReply.isPositiveIntermediate(data()))
 +            return null;
 +
 +        return new DotTerminatedMessageWriter(_writer);
 +    }
 +
 +
 +    /***
 +     * A convenience method for sending short messages.  This method fetches
 +     * the Writer returned by {@link #sendMessageData  sendMessageData() }
 +     * and writes the specified String to it.  After writing the message,
 +     * this method calls {@link #completePendingCommand completePendingCommand() }
 +     *  to finalize the transaction and returns
 +     * its success or failure.
 +     * <p>
 +     * @param message  The short email message to send.
 +     * @return True if successfully completed, false if not.
 +     * @exception SMTPConnectionClosedException
 +     *      If the SMTP server prematurely closes the connection as a result
 +     *      of the client being idle or some other reason causing the server
 +     *      to send SMTP reply code 421.  This exception may be caught either
 +     *      as an IOException or independently as itself.
 +     * @exception IOException  If an I/O error occurs while either sending a
 +     *      command to the server or receiving a reply from the server.
 +     ***/
 +    public boolean sendShortMessageData(String message) throws IOException
 +    {
 +        Writer writer;
 +
 +        writer = sendMessageData();
 +
 +        if (writer == null)
 +            return false;
 +
 +        writer.write(message);
 +        writer.close();
 +
 +        return completePendingCommand();
 +    }
 +
 +
 +    /***
 +     * A convenience method for a sending short email without having to
 +     * explicitly set the sender and recipient(s).  This method
 +     * sets the sender and recipient using
 +     * {@link #setSender  setSender } and
 +     * {@link #addRecipient  addRecipient }, and then sends the
 +     * message using {@link #sendShortMessageData  sendShortMessageData }.
 +     * <p>
 +     * @param sender  The email address of the sender.
 +     * @param recipient  The email address of the recipient.
 +     * @param message  The short email message to send.
 +     * @return True if successfully completed, false if not.
 +     * @exception SMTPConnectionClosedException
 +     *      If the SMTP server prematurely closes the connection as a result
 +     *      of the client being idle or some other reason causing the server
 +     *      to send SMTP reply code 421.  This exception may be caught either
 +     *      as an IOException or independently as itself.
 +     * @exception IOException  If an I/O error occurs while either sending a
 +     *      command to the server or receiving a reply from the server.
 +     ***/
 +    public boolean sendSimpleMessage(String sender, String recipient,
 +                                     String message)
 +    throws IOException
 +    {
 +        if (!setSender(sender))
 +            return false;
 +
 +        if (!addRecipient(recipient))
 +            return false;
 +
 +        return sendShortMessageData(message);
 +    }
 +
 +
 +
 +    /***
 +     * A convenience method for a sending short email without having to
 +     * explicitly set the sender and recipient(s).  This method
 +     * sets the sender and recipients using
 +     * {@link #setSender  setSender } and
 +     * {@link #addRecipient  addRecipient }, and then sends the
 +     * message using {@link #sendShortMessageData  sendShortMessageData }.
 +     * <p>
 +     * @param sender  The email address of the sender.
 +     * @param recipients  An array of recipient email addresses.
 +     * @param message  The short email message to send.
 +     * @return True if successfully completed, false if not.
 +     * @exception SMTPConnectionClosedException
 +     *      If the SMTP server prematurely closes the connection as a result
 +     *      of the client being idle or some other reason causing the server
 +     *      to send SMTP reply code 421.  This exception may be caught either
 +     *      as an IOException or independently as itself.
 +     * @exception IOException  If an I/O error occurs while either sending a
 +     *      command to the server or receiving a reply from the server.
 +     ***/
 +    public boolean sendSimpleMessage(String sender, String[] recipients,
 +                                     String message)
 +    throws IOException
 +    {
 +        boolean oneSuccess = false;
 +        int count;
 +
 +        if (!setSender(sender))
 +            return false;
 +
 +        for (count = 0; count < recipients.length; count++)
 +        {
 +            if (addRecipient(recipients[count]))
 +                oneSuccess = true;
 +        }
 +
 +        if (!oneSuccess)
 +            return false;
 +
 +        return sendShortMessageData(message);
 +    }
 +
 +
 +    /***
 +     * Logout of the SMTP server by sending the QUIT command.
 +     * <p>
 +     * @return True if successfully completed, false if not.
 +     * @exception SMTPConnectionClosedException
 +     *      If the SMTP server prematurely closes the connection as a result
 +     *      of the client being idle or some other reason causing the server
 +     *      to send SMTP reply code 421.  This exception may be caught either
 +     *      as an IOException or independently as itself.
 +     * @exception IOException  If an I/O error occurs while either sending a
 +     *      command to the server or receiving a reply from the server.
 +     ***/
 +    public boolean logout() throws IOException
 +    {
 +        return SMTPReply.isPositiveCompletion(quit());
 +    }
 +
 +
 +
 +    /***
 +     * Aborts the current mail transaction, resetting all server stored
 +     * sender, recipient, and mail data, cleaing all buffers and tables.
 +     * <p>
 +     * @return True if successfully completed, false if not.
 +     * @exception SMTPConnectionClosedException
 +     *      If the SMTP server prematurely closes the connection as a result
 +     *      of the client being idle or some other reason causing the server
 +     *      to send SMTP reply code 421.  This exception may be caught either
 +     *      as an IOException or independently as itself.
 +     * @exception IOException  If an I/O error occurs while either sending a
 +     *      command to the server or receiving a reply from the server.
 +     ***/
 +    public boolean reset() throws IOException
 +    {
 +        return SMTPReply.isPositiveCompletion(rset());
 +    }
 +
 +
 +    /***
 +     * Verify that a username or email address is valid, i.e., that mail
 +     * can be delivered to that mailbox on the server.
 +     * <p>
 +     * @param username  The username or email address to validate.
 +     * @return True if the username is valid, false if not.
 +     * @exception SMTPConnectionClosedException
 +     *      If the SMTP server prematurely closes the connection as a result
 +     *      of the client being idle or some other reason causing the server
 +     *      to send SMTP reply code 421.  This exception may be caught either
 +     *      as an IOException or independently as itself.
 +     * @exception IOException  If an I/O error occurs while either sending a
 +     *      command to the server or receiving a reply from the server.
 +     ***/
 +    public boolean verify(String username) throws IOException
 +    {
 +        int result;
 +
 +        result = vrfy(username);
 +
 +        return (result == SMTPReply.ACTION_OK ||
 +                result == SMTPReply.USER_NOT_LOCAL_WILL_FORWARD);
 +    }
 +
 +
 +    /***
 +     * Fetches the system help information from the server and returns the
 +     * full string.
 +     * <p>
 +     * @return The system help string obtained from the server.  null if the
 +     *       information could not be obtained.
 +     * @exception SMTPConnectionClosedException
 +     *      If the SMTP server prematurely closes the connection as a result
 +     *      of the client being idle or some other reason causing the server
 +     *      to send SMTP reply code 421.  This exception may be caught either
 +     *      as an IOException or independently as itself.
 +     * @exception IOException  If an I/O error occurs while either sending a
 +     *  command to the server or receiving a reply from the server.
 +     ***/
 +    public String listHelp() throws IOException
 +    {
 +        if (SMTPReply.isPositiveCompletion(help()))
 +            return getReplyString();
 +        return null;
 +    }
 +
 +
 +    /***
 +     * Fetches the help information for a given command from the server and
 +     * returns the full string.
 +     * <p>
 +     * @param command The command on which to ask for help.
 +     * @return The command help string obtained from the server.  null if the
 +     *       information could not be obtained.
 +     * @exception SMTPConnectionClosedException
 +     *      If the SMTP server prematurely closes the connection as a result
 +     *      of the client being idle or some other reason causing the server
 +     *      to send SMTP reply code 421.  This exception may be caught either
 +     *      as an IOException or independently as itself.
 +     * @exception IOException  If an I/O error occurs while either sending a
 +     *  command to the server or receiving a reply from the server.
 +     ***/
 +    public String listHelp(String command) throws IOException
 +    {
 +        if (SMTPReply.isPositiveCompletion(help(command)))
 +            return getReplyString();
 +        return null;
 +    }
 +
 +
 +    /***
 +     * Sends a NOOP command to the SMTP server.  This is useful for preventing
 +     * server timeouts.
 +     * <p>
 +     * @return True if successfully completed, false if not.
 +     * @exception SMTPConnectionClosedException
 +     *      If the SMTP server prematurely closes the connection as a result
 +     *      of the client being idle or some other reason causing the server
 +     *      to send SMTP reply code 421.  This exception may be caught either
 +     *      as an IOException or independently as itself.
 +     * @exception IOException  If an I/O error occurs while either sending a
 +     *      command to the server or receiving a reply from the server.
 +     ***/
 +    public boolean sendNoOp() throws IOException
 +    {
 +        return SMTPReply.isPositiveCompletion(noop());
 +    }
 +
 +}
 diff --git a/org/apache/commons/net/smtp/SMTPCommand.java b/org/apache/commons/net/smtp/SMTPCommand.java new file mode 100644 index 0000000..04dbf99 --- /dev/null +++ b/org/apache/commons/net/smtp/SMTPCommand.java @@ -0,0 +1,91 @@ +/*
 + * Licensed to the Apache Software Foundation (ASF) under one or more
 + * contributor license agreements.  See the NOTICE file distributed with
 + * this work for additional information regarding copyright ownership.
 + * The ASF licenses this file to You under the Apache License, Version 2.0
 + * (the "License"); you may not use this file except in compliance with
 + * the License.  You may obtain a copy of the License at
 + *
 + *      http://www.apache.org/licenses/LICENSE-2.0
 + *
 + * Unless required by applicable law or agreed to in writing, software
 + * distributed under the License is distributed on an "AS IS" BASIS,
 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 + * See the License for the specific language governing permissions and
 + * limitations under the License.
 + */
 +
 +package org.apache.commons.net.smtp;
 +
 +/***
 + * SMTPCommand stores a set of constants for SMTP command codes.  To interpret
 + * the meaning of the codes, familiarity with RFC 821 is assumed.
 + * The mnemonic constant names are transcriptions from the code descriptions
 + * of RFC 821.  For those who think in terms of the actual SMTP commands,
 + * a set of constants such as {@link #HELO  HELO } are provided
 + * where the constant name is the same as the SMTP command.
 + * <p>
 + * <p>
 + * @author Daniel F. Savarese
 + ***/
 +
 +public final class SMTPCommand
 +{
 +
 +
 +    public static final int HELO = 0;
 +    public static final int MAIL = 1;
 +    public static final int RCPT = 2;
 +    public static final int DATA = 3;
 +    public static final int SEND = 4;
 +    public static final int SOML = 5;
 +    public static final int SAML = 6;
 +    public static final int RSET = 7;
 +    public static final int VRFY = 8;
 +    public static final int EXPN = 9;
 +    public static final int HELP = 10;
 +    public static final int NOOP = 11;
 +    public static final int TURN = 12;
 +    public static final int QUIT = 13;
 +
 +    public static final int HELLO = HELO;
 +    public static final int LOGIN = HELO;
 +    public static final int MAIL_FROM = MAIL;
 +    public static final int RECIPIENT = RCPT;
 +    public static final int SEND_MESSAGE_DATA = DATA;
 +    public static final int SEND_FROM = SEND;
 +    public static final int SEND_OR_MAIL_FROM = SOML;
 +    public static final int SEND_AND_MAIL_FROM = SAML;
 +    public static final int RESET = RSET;
 +    public static final int VERIFY = VRFY;
 +    public static final int EXPAND = EXPN;
 +    // public static final int HELP = HELP;
 +    // public static final int NOOP = NOOP;
 +    // public static final int TURN = TURN;
 +    // public static final int QUIT = QUIT;
 +    public static final int LOGOUT = QUIT;
 +
 +    // Cannot be instantiated
 +    private SMTPCommand()
 +    {}
 +
 +    static final String[] _commands = {
 +                                          "HELO", "MAIL FROM:", "RCPT TO:", "DATA", "SEND FROM:", "SOML FROM:",
 +                                          "SAML FROM:", "RSET", "VRFY", "EXPN", "HELP", "NOOP", "TURN", "QUIT"
 +                                      };
 +
 +
 +    /***
 +     * Retrieve the SMTP protocol command string corresponding to a specified
 +     * command code.
 +     * <p>
 +     * @param command The command code.
 +     * @return The SMTP protcol command string corresponding to a specified
 +     *         command code.
 +     ***/
 +    public static final String getCommand(int command)
 +    {
 +        return _commands[command];
 +    }
 +
 +}
 diff --git a/org/apache/commons/net/smtp/SMTPConnectionClosedException.java b/org/apache/commons/net/smtp/SMTPConnectionClosedException.java new file mode 100644 index 0000000..f9a5762 --- /dev/null +++ b/org/apache/commons/net/smtp/SMTPConnectionClosedException.java @@ -0,0 +1,56 @@ +/*
 + * Licensed to the Apache Software Foundation (ASF) under one or more
 + * contributor license agreements.  See the NOTICE file distributed with
 + * this work for additional information regarding copyright ownership.
 + * The ASF licenses this file to You under the Apache License, Version 2.0
 + * (the "License"); you may not use this file except in compliance with
 + * the License.  You may obtain a copy of the License at
 + *
 + *      http://www.apache.org/licenses/LICENSE-2.0
 + *
 + * Unless required by applicable law or agreed to in writing, software
 + * distributed under the License is distributed on an "AS IS" BASIS,
 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 + * See the License for the specific language governing permissions and
 + * limitations under the License.
 + */
 +
 +package org.apache.commons.net.smtp;
 +
 +import java.io.IOException;
 +
 +/***
 + * SMTPConnectionClosedException is used to indicate the premature or
 + * unexpected closing of an SMTP connection resulting from a
 + * {@link org.apache.commons.net.smtp.SMTPReply#SERVICE_NOT_AVAILABLE SMTPReply.SERVICE_NOT_AVAILABLE }
 + *  response (SMTP reply code 421) to a
 + * failed SMTP command.  This exception is derived from IOException and
 + * therefore may be caught either as an IOException or specifically as an
 + * SMTPConnectionClosedException.
 + * <p>
 + * <p>
 + * @author Daniel F. Savarese
 + * @see SMTP
 + * @see SMTPClient
 + ***/
 +
 +public final class SMTPConnectionClosedException extends IOException
 +{
 +
 +    /*** Constructs a SMTPConnectionClosedException with no message ***/
 +    public SMTPConnectionClosedException()
 +    {
 +        super();
 +    }
 +
 +    /***
 +     * Constructs a SMTPConnectionClosedException with a specified message.
 +     * <p>
 +     * @param message  The message explaining the reason for the exception.
 +     ***/
 +    public SMTPConnectionClosedException(String message)
 +    {
 +        super(message);
 +    }
 +
 +}
 diff --git a/org/apache/commons/net/smtp/SMTPReply.java b/org/apache/commons/net/smtp/SMTPReply.java new file mode 100644 index 0000000..45fd7c8 --- /dev/null +++ b/org/apache/commons/net/smtp/SMTPReply.java @@ -0,0 +1,167 @@ +/*
 + * Licensed to the Apache Software Foundation (ASF) under one or more
 + * contributor license agreements.  See the NOTICE file distributed with
 + * this work for additional information regarding copyright ownership.
 + * The ASF licenses this file to You under the Apache License, Version 2.0
 + * (the "License"); you may not use this file except in compliance with
 + * the License.  You may obtain a copy of the License at
 + *
 + *      http://www.apache.org/licenses/LICENSE-2.0
 + *
 + * Unless required by applicable law or agreed to in writing, software
 + * distributed under the License is distributed on an "AS IS" BASIS,
 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 + * See the License for the specific language governing permissions and
 + * limitations under the License.
 + */
 +
 +package org.apache.commons.net.smtp;
 +
 +/***
 + * SMTPReply stores a set of constants for SMTP reply codes.  To interpret
 + * the meaning of the codes, familiarity with RFC 821 is assumed.
 + * The mnemonic constant names are transcriptions from the code descriptions
 + * of RFC 821.  For those who think in terms of the actual reply code values,
 + * a set of CODE_NUM constants are provided where NUM is the numerical value
 + * of the code.
 + * <p>
 + * <p>
 + * @author Daniel F. Savarese
 + ***/
 +
 +public final class SMTPReply
 +{
 +
 +    public static final int CODE_211 = 211;
 +    public static final int CODE_214 = 214;
 +    public static final int CODE_215 = 215;
 +    public static final int CODE_220 = 220;
 +    public static final int CODE_221 = 221;
 +    public static final int CODE_250 = 250;
 +    public static final int CODE_251 = 251;
 +    public static final int CODE_354 = 354;
 +    public static final int CODE_421 = 421;
 +    public static final int CODE_450 = 450;
 +    public static final int CODE_451 = 451;
 +    public static final int CODE_452 = 452;
 +    public static final int CODE_500 = 500;
 +    public static final int CODE_501 = 501;
 +    public static final int CODE_502 = 502;
 +    public static final int CODE_503 = 503;
 +    public static final int CODE_504 = 504;
 +    public static final int CODE_550 = 550;
 +    public static final int CODE_551 = 551;
 +    public static final int CODE_552 = 552;
 +    public static final int CODE_553 = 553;
 +    public static final int CODE_554 = 554;
 +
 +    public static final int SYSTEM_STATUS = CODE_211;
 +    public static final int HELP_MESSAGE = CODE_214;
 +    public static final int SERVICE_READY = CODE_220;
 +    public static final int SERVICE_CLOSING_TRANSMISSION_CHANNEL = CODE_221;
 +    public static final int ACTION_OK = CODE_250;
 +    public static final int USER_NOT_LOCAL_WILL_FORWARD = CODE_251;
 +    public static final int START_MAIL_INPUT = CODE_354;
 +    public static final int SERVICE_NOT_AVAILABLE = CODE_421;
 +    public static final int ACTION_NOT_TAKEN = CODE_450;
 +    public static final int ACTION_ABORTED = CODE_451;
 +    public static final int INSUFFICIENT_STORAGE = CODE_452;
 +    public static final int UNRECOGNIZED_COMMAND = CODE_500;
 +    public static final int SYNTAX_ERROR_IN_ARGUMENTS = CODE_501;
 +    public static final int COMMAND_NOT_IMPLEMENTED = CODE_502;
 +    public static final int BAD_COMMAND_SEQUENCE = CODE_503;
 +    public static final int COMMAND_NOT_IMPLEMENTED_FOR_PARAMETER = CODE_504;
 +    public static final int MAILBOX_UNAVAILABLE = CODE_550;
 +    public static final int USER_NOT_LOCAL = CODE_551;
 +    public static final int STORAGE_ALLOCATION_EXCEEDED = CODE_552;
 +    public static final int MAILBOX_NAME_NOT_ALLOWED = CODE_553;
 +    public static final int TRANSACTION_FAILED = CODE_554;
 +
 +    // Cannot be instantiated
 +    private SMTPReply()
 +    {}
 +
 +    /***
 +     * Determine if a reply code is a positive preliminary response.  All
 +     * codes beginning with a 1 are positive preliminary responses.
 +     * Postitive preliminary responses are used to indicate tentative success.
 +     * No further commands can be issued to the SMTP server after a positive
 +     * preliminary response until a follow up response is received from the
 +     * server.
 +     * <p>
 +     * <b> Note: </b> <em> No SMTP commands defined in RFC 822 provide this
 +     * type of reply. </em>
 +     * <p>
 +     * @param reply  The reply code to test.
 +     * @return True if a reply code is a postive preliminary response, false
 +     *         if not.
 +     ***/
 +    public static boolean isPositivePreliminary(int reply)
 +    {
 +        return (reply >= 100 && reply < 200);
 +    }
 +
 +    /***
 +     * Determine if a reply code is a positive completion response.  All
 +     * codes beginning with a 2 are positive completion responses.
 +     * The SMTP server will send a positive completion response on the final
 +     * successful completion of a command.
 +     * <p>
 +     * @param reply  The reply code to test.
 +     * @return True if a reply code is a postive completion response, false
 +     *         if not.
 +     ***/
 +    public static boolean isPositiveCompletion(int reply)
 +    {
 +        return (reply >= 200 && reply < 300);
 +    }
 +
 +    /***
 +     * Determine if a reply code is a positive intermediate response.  All
 +     * codes beginning with a 3 are positive intermediate responses.
 +     * The SMTP server will send a positive intermediate response on the
 +     * successful completion of one part of a multi-part sequence of
 +     * commands.  For example, after a successful DATA command, a positive
 +     * intermediate response will be sent to indicate that the server is
 +     * ready to receive the message data.
 +     * <p>
 +     * @param reply  The reply code to test.
 +     * @return True if a reply code is a postive intermediate response, false
 +     *         if not.
 +     ***/
 +    public static boolean isPositiveIntermediate(int reply)
 +    {
 +        return (reply >= 300 && reply < 400);
 +    }
 +
 +    /***
 +     * Determine if a reply code is a negative transient response.  All
 +     * codes beginning with a 4 are negative transient responses.
 +     * The SMTP server will send a negative transient response on the
 +     * failure of a command that can be reattempted with success.
 +     * <p>
 +     * @param reply  The reply code to test.
 +     * @return True if a reply code is a negative transient response, false
 +     *         if not.
 +     ***/
 +    public static boolean isNegativeTransient(int reply)
 +    {
 +        return (reply >= 400 && reply < 500);
 +    }
 +
 +    /***
 +     * Determine if a reply code is a negative permanent response.  All
 +     * codes beginning with a 5 are negative permanent responses.
 +     * The SMTP server will send a negative permanent response on the
 +     * failure of a command that cannot be reattempted with success.
 +     * <p>
 +     * @param reply  The reply code to test.
 +     * @return True if a reply code is a negative permanent response, false
 +     *         if not.
 +     ***/
 +    public static boolean isNegativePermanent(int reply)
 +    {
 +        return (reply >= 500 && reply < 600);
 +    }
 +
 +}
 diff --git a/org/apache/commons/net/smtp/SimpleSMTPHeader.java b/org/apache/commons/net/smtp/SimpleSMTPHeader.java new file mode 100644 index 0000000..ed0ea4d --- /dev/null +++ b/org/apache/commons/net/smtp/SimpleSMTPHeader.java @@ -0,0 +1,153 @@ +/*
 + * Licensed to the Apache Software Foundation (ASF) under one or more
 + * contributor license agreements.  See the NOTICE file distributed with
 + * this work for additional information regarding copyright ownership.
 + * The ASF licenses this file to You under the Apache License, Version 2.0
 + * (the "License"); you may not use this file except in compliance with
 + * the License.  You may obtain a copy of the License at
 + *
 + *      http://www.apache.org/licenses/LICENSE-2.0
 + *
 + * Unless required by applicable law or agreed to in writing, software
 + * distributed under the License is distributed on an "AS IS" BASIS,
 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 + * See the License for the specific language governing permissions and
 + * limitations under the License.
 + */
 +
 +package org.apache.commons.net.smtp;
 +
 +/***
 + * This class is used to construct a bare minimum
 + * acceptable header for an email message.  To construct more
 + * complicated headers you should refer to RFC 822.  When the
 + * Java Mail API is finalized, you will be
 + * able to use it to compose fully compliant Internet text messages.
 + * <p>
 + * The main purpose of the class is to faciliatate the mail sending
 + * process, by relieving the programmer from having to explicitly format
 + * a simple message header.  For example:
 + * <pre>
 + * writer = client.sendMessageData();
 + * if(writer == null) // failure
 + *   return false;
 + * header =
 + *    new SimpleSMTPHeader("foobar@foo.com", "foo@bar.com" "Just testing");
 + * header.addCC("bar@foo.com");
 + * header.addHeaderField("Organization", "Foobar, Inc.");
 + * writer.write(header.toString());
 + * writer.write("This is just a test");
 + * writer.close();
 + * if(!client.completePendingCommand()) // failure
 + *   return false;
 + * </pre>
 + * <p>
 + * <p>
 + * @author Daniel F. Savarese
 + * @see SMTPClient
 + ***/
 +
 +public class SimpleSMTPHeader
 +{
 +    private String __subject, __from, __to;
 +    private StringBuffer __headerFields, __cc;
 +
 +    /***
 +     * Creates a new SimpleSMTPHeader instance initialized with the given
 +     * from, to, and subject header field values.
 +     * <p>
 +     * @param from  The value of the <code>From:</code> header field.  This
 +     *              should be the sender's email address.
 +     * @param to    The value of the <code>To:</code> header field.  This
 +     *              should be the recipient's email address.
 +     * @param subject  The value of the <code>Subject:</code> header field.
 +     *              This should be the subject of the message.
 +     ***/
 +    public SimpleSMTPHeader(String from, String to, String subject)
 +    {
 +        __to = to;
 +        __from = from;
 +        __subject = subject;
 +        __headerFields = new StringBuffer();
 +        __cc = null;
 +    }
 +
 +    /***
 +     * Adds an arbitrary header field with the given value to the article
 +     * header.  These headers will be written before the From, To, Subject, and
 +     * Cc fields when the SimpleSMTPHeader is convertered to a string.
 +     * An example use would be:
 +     * <pre>
 +     * header.addHeaderField("Organization", "Foobar, Inc.");
 +     * </pre>
 +     * <p>
 +     * @param headerField  The header field to add, not including the colon.
 +     * @param value  The value of the added header field.
 +     ***/
 +    public void addHeaderField(String headerField, String value)
 +    {
 +        __headerFields.append(headerField);
 +        __headerFields.append(": ");
 +        __headerFields.append(value);
 +        __headerFields.append('\n');
 +    }
 +
 +
 +    /***
 +     * Add an email address to the CC (carbon copy or courtesy copy) list.
 +     * <p>
 +     * @param address The email address to add to the CC list.
 +     ***/
 +    public void addCC(String address)
 +    {
 +        if (__cc == null)
 +            __cc = new StringBuffer();
 +        else
 +            __cc.append(", ");
 +
 +        __cc.append(address);
 +    }
 +
 +
 +    /***
 +     * Converts the SimpleSMTPHeader to a properly formatted header in
 +     * the form of a String, including the blank line used to separate
 +     * the header from the article body.  The header fields CC and Subject
 +     * are only included when they are non-null.
 +     * <p>
 +     * @return The message header in the form of a String.
 +     ***/
 +    @Override
 +    public String toString()
 +    {
 +        StringBuffer header = new StringBuffer();
 +
 +        if (__headerFields.length() > 0)
 +            header.append(__headerFields.toString());
 +
 +        header.append("From: ");
 +        header.append(__from);
 +        header.append("\nTo: ");
 +        header.append(__to);
 +
 +        if (__cc != null)
 +        {
 +            header.append("\nCc: ");
 +            header.append(__cc.toString());
 +        }
 +
 +        if (__subject != null)
 +        {
 +            header.append("\nSubject: ");
 +            header.append(__subject);
 +        }
 +
 +        header.append('\n');
 +        header.append('\n');
 +
 +        return header.toString();
 +    }
 +}
 +
 +
 +
 | 
