You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by br...@apache.org on 2002/04/03 06:40:25 UTC

cvs commit: jakarta-commons-sandbox/net/src/java/org/apache/commons/net/smtp RelayPath.java SMTP.java SMTPClient.java SMTPCommand.java SMTPConnectionClosedException.java SMTPReply.java SimpleSMTPHeader.java

brekke      02/04/02 20:40:25

  Added:       net/src/java/org/apache/commons/net/smtp RelayPath.java
                        SMTP.java SMTPClient.java SMTPCommand.java
                        SMTPConnectionClosedException.java SMTPReply.java
                        SimpleSMTPHeader.java
  Log:
  Moving com.oroinc.net.smtp to org.apache.commons.net.smtp
  
  Revision  Changes    Path
  1.1                  jakarta-commons-sandbox/net/src/java/org/apache/commons/net/smtp/RelayPath.java
  
  Index: RelayPath.java
  ===================================================================
  package org.apache.commons.net.smtp;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * 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.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *    "Apache Commons" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    "Apache Turbine", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 APACHE SOFTWARE FOUNDATION OR
   * ITS 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.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  import java.util.*;
  
  /***
   * 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 _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();
      _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> &lt @bar.com,@foo.com:foobar@foo.com &gt </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.
     ***/
    public String toString() {
      StringBuffer buffer = new StringBuffer();
      Enumeration hosts;
  
      buffer.append('<');
  
      hosts = _path.elements();
  
      if(hosts.hasMoreElements()) {
        buffer.append('@');
        buffer.append((String)hosts.nextElement());
  
        while(hosts.hasMoreElements()) {
  	buffer.append(",@");
  	buffer.append((String)hosts.nextElement());
        }
        buffer.append(':');
      }
  
      buffer.append(_emailAddress);
      buffer.append('>');
  
      return buffer.toString();
    }
  
  }
  
  
  
  1.1                  jakarta-commons-sandbox/net/src/java/org/apache/commons/net/smtp/SMTP.java
  
  Index: SMTP.java
  ===================================================================
  package org.apache.commons.net.smtp;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * 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.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *    "Apache Commons" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    "Apache Turbine", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 APACHE SOFTWARE FOUNDATION OR
   * ITS 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.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  import java.net.*;
  import java.io.*;
  import java.util.*;
  
  import org.apache.commons.net.*;
  
  /***
   * 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
   * <a href="org.apache.commons.net.smtp.SMTPClient.html"> SMTPClient </a> 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
   * <a href="org.apache.commons.net.smtp.SMTPReply.html#SERVICE_NOT_AVAILABLE">
   * SMTPReply.SERVICE_NOT_AVAILABLE </a> response to a command.
   * When that occurs, the SMTP class method encountering that reply will throw
   * an <a href="org.apache.commons.net.smtp.SMTPConnectionClosedException.html">
   * SMTPConnectionClosedException </a>.
   * <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
   * <a href="org.apache.commons.net.smtp.SMTPConnectionClosedException.html">
   * SMTPConnectionClosedException </a>, you must disconnect the connection with
   * <a href="org.apache.commons.net.SocketClient.html#disconnect"> disconnect() </a>
   * to properly clean up the system resources used by SMTP.  Before
   * disconnecting, you may check the
   * last reply code and text with
   * <a href="#getReplyCode"> getReplyCode </a>,
   * <a href="#getReplyString"> getReplyString </a>,
   * and <a href="#getReplyStrings"> getReplyStrings</a>.
   * <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 
   * <a href="org.apache.commons.net.MalformedServerReplyException.html">
   * MalformedServerReplyException </a>, 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;
  
    private StringBuffer __commandBuffer;
  
    BufferedReader _reader;
    BufferedWriter _writer;
    int _replyCode;
    Vector  _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 Vector();
      _newReplyString = false;
      _replyString    = null;
      _commandSupport_ = new ProtocolCommandSupport(this);
    }
  
    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;
      String line, code;
  
      _newReplyString = true;
      _replyLines.setSize(0);
  
      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 {
        _replyCode = Integer.parseInt(code = line.substring(0, 3));
      } catch(NumberFormatException e) {
        throw new MalformedServerReplyException(
        "Could not parse response code.\nServer Reply: " + line);
      }
  
      _replyLines.addElement(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.addElement(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. ***/
    protected void _connectAction_() throws IOException {
      super._connectAction_();
      _reader = 
        new BufferedReader(new InputStreamReader(_input_));
      _writer =
        new BufferedWriter(new OutputStreamWriter(_output_));
      __getReply();
    }
  
  
    /***
     * Adds a ProtocolCommandListener.  Delegates this task to
     * <a href="#_commandSupport_"> _commandSupport_ </a>.
     * <p>
     * @param listener  The ProtocolCommandListener to add.
     ***/
    public void addProtocolCommandListener(ProtocolCommandListener listener){
      _commandSupport_.addProtocolCommandListener(listener);
    }
  
    /***
     * Removes a ProtocolCommandListener.  Delegates this task to
     * <a href="#_commandSupport_"> _commandSupport_ </a>.
     * <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.
     ***/
    public void disconnect() throws IOException {
      super.disconnect();
      _reader          = null;
      _writer          = null;
      _replyString     = null;
      _replyLines.setSize(0);
      _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
     * <a href="#getReplyString"> getReplyString </a> or 
     * <a href="#getReplyStrings"> getReplyStrings </a>.
     * <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
     * <a href="#getReplyString"> getReplyString </a> or 
     * <a href="#getReplyStrings"> getReplyStrings </a>.
     * <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 <a href="#getReplyString"> getReplyString </a> or 
     * <a href="#getReplyStrings"> getReplyStrings </a>.
     * <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 <a href="#getReplyString"> getReplyString </a> or 
     * <a href="#getReplyStrings"> getReplyStrings </a>.
     * <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 <a href="#getReplyString"> getReplyString </a> or 
     * <a href="#getReplyStrings"> getReplyStrings </a>.  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.copyInto(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() {
      Enumeration enum;
      StringBuffer buffer;
  
      if(!_newReplyString)
        return _replyString;
  
      buffer = new StringBuffer(256);
      enum = _replyLines.elements();
      while(enum.hasMoreElements()) {
        buffer.append((String)enum.nextElement());
        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);
    }
  
  }
  
  
  
  1.1                  jakarta-commons-sandbox/net/src/java/org/apache/commons/net/smtp/SMTPClient.java
  
  Index: SMTPClient.java
  ===================================================================
  package org.apache.commons.net.smtp;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * 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.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *    "Apache Commons" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    "Apache Turbine", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 APACHE SOFTWARE FOUNDATION OR
   * ITS 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.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  import java.net.*;
  import java.io.*;
  import java.util.*;
  
  import org.apache.commons.io.*;
  import org.apache.commons.net.MalformedServerReplyException;
  
  /***
   * 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 <a href="org.apache.commons.net.SocketClient.html"> SocketClient </a>,
   * you must first connect to the server with 
   * <a href="org.apache.commons.net.SocketClient.html#connect"> connect </a>
   * before doing anything, and finally
   * <a href="org.apache.commons.net.SocketClient.html#disconnect"> disconnect </a>
   * 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
   * <a href="org.apache.commons.net.smtp.SMTP.html#getReplyCode"> getReplyCode </a> 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
   * <a href="org.apache.commons.net.smtp.SMTPReply.html#SERVICE_NOT_AVAILABLE">
   * SMTPReply.SERVICE_NOT_AVAILABLE </a> response to a command.
   * When that occurs, the method encountering that reply will throw
   * an <a href="org.apache.commons.net.smtp.SMTPConnectionClosedException.html">
   * SMTPConnectionClosedException </a>. 
   * <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
   * <a href="org.apache.commons.net.smtp.SMTPConnectionClosedException.html">
   * SMTPConnectionClosedException </a>, you must disconnect the connection with
   * <a href="#disconnect"> disconnect() </a> to properly clean up the
   * system resources used by SMTPClient.  Before disconnecting, you may check
   * the last reply code and text with
   * <a href="org.apache.commons.net.smtp.SMTP.html#getReplyCode"> getReplyCode </a>,
   * <a href="org.apache.commons.net.smtp.SMTP.html#getReplyString"> getReplyString </a>,
   * and
   * <a href="org.apache.commons.net.smtp.SMTP.html#getReplyStrings">getReplyStrings</a>.
   * <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 
   * <a href="org.apache.commons.net.MalformedServerReplyException.html">
   * MalformedServerReplyException </a>, 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() {  }
  
  
    /***
     * At least one SMTPClient method (<a href="#sendMessage"> sendMessage </a>)
     * 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
     * <a href="org.apache.commons.net.smtp.SimpleSMTPHeader.html"> SimpleSMTPHeader </a>
     * 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
     * <a href="#completePendingCommand"> completePendingCommand() </a>
     * 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 <a href="#sendMessageData"> sendMessageData() </a>
     * and writes the specified String to it.  After writing the message,
     * this method calls <a href="#completePendingCommand">
     * completePendingCommand() </a> 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
     * <a href="#setSender"> setSender </a> and
     * <a href="#addRecipient"> addRecipient </a>, and then sends the
     * message using <a href="#sendShortMessageData"> sendShortMessageData </a>.
     * <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
     * <a href="#setSender"> setSender </a> and
     * <a href="#addRecipient"> addRecipient </a>, and then sends the
     * message using <a href="#sendShortMessageData"> sendShortMessageData </a>.
     * <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  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());
    }
  
  }
  
  
  
  1.1                  jakarta-commons-sandbox/net/src/java/org/apache/commons/net/smtp/SMTPCommand.java
  
  Index: SMTPCommand.java
  ===================================================================
  package org.apache.commons.net.smtp;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * 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.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *    "Apache Commons" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    "Apache Turbine", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 APACHE SOFTWARE FOUNDATION OR
   * ITS 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.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  import java.net.*;
  import java.io.*;
  
  /***
   * 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 <a href="#HELO"> HELO </a> 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 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];
    }
  
  }
  
  
  
  1.1                  jakarta-commons-sandbox/net/src/java/org/apache/commons/net/smtp/SMTPConnectionClosedException.java
  
  Index: SMTPConnectionClosedException.java
  ===================================================================
  package org.apache.commons.net.smtp;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * 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.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *    "Apache Commons" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    "Apache Turbine", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 APACHE SOFTWARE FOUNDATION OR
   * ITS 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.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  import java.io.*;
  
  /***
   * SMTPConnectionClosedException is used to indicate the premature or
   * unexpected closing of an SMTP connection resulting from a 
   * <a href="org.apache.commons.net.smtp.SMTPReply.html#SERVICE_NOT_AVAILABLE">
   * SMTPReply.SERVICE_NOT_AVAILABLE </a> 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);
    }
  
  }
  
  
  
  1.1                  jakarta-commons-sandbox/net/src/java/org/apache/commons/net/smtp/SMTPReply.java
  
  Index: SMTPReply.java
  ===================================================================
  package org.apache.commons.net.smtp;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * 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.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *    "Apache Commons" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    "Apache Turbine", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 APACHE SOFTWARE FOUNDATION OR
   * ITS 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.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  import java.net.*;
  import java.io.*;
  
  /***
   * 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);
    }
  
  }
  
  
  
  1.1                  jakarta-commons-sandbox/net/src/java/org/apache/commons/net/smtp/SimpleSMTPHeader.java
  
  Index: SimpleSMTPHeader.java
  ===================================================================
  package org.apache.commons.net.smtp;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * 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.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *    "Apache Commons" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    "Apache Turbine", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 APACHE SOFTWARE FOUNDATION OR
   * ITS 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.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  /***
   * 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 from  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.
     * <p>
     * @return The message header in the form of a String.
     ***/
    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);
      }
  
      header.append("\nSubject: ");
      header.append(__subject);
      header.append('\n');
  
      header.append('\n');
  
      return header.toString();
    }
  }
  
  
  
  
  
  

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>