/*
* The contents of this file are subject to the Netscape Public License
* Version 1.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.mozilla.org/NPL/.
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the License.
*
* The Original Code is the Netscape Messaging Access SDK Version 3.5 code,
* released on or about June 15, 1998.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are Copyright (C) 1998 Netscape
* Communications Corporation. All Rights Reserved.
*
* Contributor(s): ______________________________________.
*/
/*
* Copyright (c) 1997 and 1998 Netscape Communications Corporation
* (http://home.netscape.com/misc/trademarks.html)
*/
package netscape.messaging.smtp;
import java.io.IOException;
import java.io.InputStream;
import java.util.Vector;
import netscape.messaging.*;
/**
*The SMTPClient class represents the SMTP client.
*The client uses this class for communicating with a
*server using the SMTP protocol.
*The SMTP client conforms to the specifications of the client
*described in RFC 821.
*<p>For a list of the SMTP RFCs referenced in the
*Messaging Access SDK and their URLs,
*see "Where to Find More Information" in "About This Book."
*@author [email protected]
*@version 1.0
*/
public class SMTPClient
{
///////////////////////////////////////////////////////////////////////////
// Internal class used for socket I/O.
///////////////////////////////////////////////////////////////////////////
private IO m_io;
///////////////////////////////////////////////////////////////////////////
// Data member used for C-runtime equivalent routines.
///////////////////////////////////////////////////////////////////////////
private Common m_common;
///////////////////////////////////////////////////////////////////////////
// Data member used to store the timeout value.
///////////////////////////////////////////////////////////////////////////
private int m_timeout;
///////////////////////////////////////////////////////////////////////////
// Last character sent to the server used for byte stuffing messages.
///////////////////////////////////////////////////////////////////////////
private byte m_lastSentChar;
///////////////////////////////////////////////////////////////////////////
// State variable indicating if the DATA command was last executed.
///////////////////////////////////////////////////////////////////////////
private boolean m_fSendingData;
///////////////////////////////////////////////////////////////////////////
// Boolean variable to determine if we can send another command.
///////////////////////////////////////////////////////////////////////////
private boolean m_mustProcess;
///////////////////////////////////////////////////////////////////////////
// Callback data members.
///////////////////////////////////////////////////////////////////////////
private Vector m_pendingList;
private ISMTPSink m_notifySink;
///////////////////////////////////////////////////////////////////////////
// Data members specific for PIPELINING mode.
///////////////////////////////////////////////////////////////////////////
private Vector m_pipelinedCommandList;
private boolean m_fPipeliningSupported;
private boolean m_fPipeliningEnabled;
///////////////////////////////////////////////////////////////////////////
// Reused response objects.
///////////////////////////////////////////////////////////////////////////
private StringBuffer m_responseMessage;
///////////////////////////////////////////////////////////////////////////
// Byte arrays that are reused for commands and responses.
///////////////////////////////////////////////////////////////////////////
private byte[] m_response;
private byte[] m_messageData;
private byte[] m_itoaBuffer;
///////////////////////////////////////////////////////////////////////////
// Constants.
///////////////////////////////////////////////////////////////////////////
private final static int m_defaultPort = 25;
private final static int m_minChunkSize = 1024;
private final static int m_maxReplyLine = 512;
private final static byte[] m_bdat = { 'B', 'D', 'A', 'T', ' ' };
private final static byte[] m_data = { 'D', 'A', 'T', 'A' };
private final static byte[] m_ehlo = { 'E', 'H', 'L', 'O', ' ' };
private final static byte[] m_expn = { 'E', 'X', 'P', 'N', ' ' };
private final static byte[] m_help = { 'H', 'E', 'L', 'P', ' ' };
private final static byte[] m_mail = { 'M', 'A', 'I', 'L', ' ', 'F', 'R', 'O', 'M', ':', '<' };
private final static byte[] m_noop = { 'N', 'O', 'O', 'P' };
private final static byte[] m_quit = { 'Q', 'U', 'I', 'T' };
private final static byte[] m_rcpt = { 'R', 'C', 'P', 'T', ' ', 'T', 'O', ':', '<' };
private final static byte[] m_rset = { 'R', 'S', 'E', 'T' };
private final static byte[] m_vrfy = { 'V', 'R', 'F', 'Y', ' ' };
//private final static byte[] m_rBracket = { '>', ' ' };
private final static byte[] m_rBracket = { '>' };
private final static byte[] m_newline = { '\r', '\n' };
private final static byte[] m_eomessage = { '\r', '\n', '.' };
private final static byte[] m_bdatLast = { ' ', 'L', 'A', 'S', 'T' };
private final static byte[] m_empty = {};
///////////////////////////////////////////////////////////////////////////
// Command types for SMTP.
///////////////////////////////////////////////////////////////////////////
private final static int BDAT = 0;
private final static int CONN = 1;
private final static int DATA = 2;
private final static int EHLO = 3;
private final static int EXPN = 4;
private final static int HELP = 5;
private final static int MAIL = 6;
private final static int NOOP = 7;
private final static int QUIT = 8;
private final static int RCPT = 9;
private final static int RSET = 10;
private final static int SEND = 11;
private final static int SENDCOMMAND = 12;
private final static int VRFY = 13;
private final static Integer BDAT_OBJ = new Integer(BDAT);
private final static Integer CONN_OBJ = new Integer(CONN);
private final static Integer DATA_OBJ = new Integer(DATA);
private final static Integer EHLO_OBJ = new Integer(EHLO);
private final static Integer EXPN_OBJ = new Integer(EXPN);
private final static Integer HELP_OBJ = new Integer(HELP);
private final static Integer MAIL_OBJ = new Integer(MAIL);
private final static Integer NOOP_OBJ = new Integer(NOOP);
private final static Integer QUIT_OBJ = new Integer(QUIT);
private final static Integer RCPT_OBJ = new Integer(RCPT);
private final static Integer RSET_OBJ = new Integer(RSET);
private final static Integer SEND_OBJ = new Integer(SEND);
private final static Integer SENDCOMMAND_OBJ = new Integer(SENDCOMMAND);
private final static Integer VRFY_OBJ = new Integer(VRFY);
///////////////////////////////////////////////////////////////////////////
// Error messages for SMTP.
///////////////////////////////////////////////////////////////////////////
private final static String errProcessResponses = new String("Must call processResponses()");
private final static String errSendingData = new String("Must send data immediately after the Data() command");
private final static String errNoPipelining = new String("Pipelining is not supported");
private final static String errParse = new String("Error while pa