import java.awt.*;
import java.net.*;
import java.util.*;
import java.io.*;
/**
* SMTP Class. You can use this class to
* send e-mail via a SMTP server.
* You can find more info about E-mail and SMTP via the RFC's particularly
* <A HREF=http://www.faqs.org/rfcs/rfc821.html>RFC821</A> and
* <A HREF=http://www.faqs.org/rfcs/rfc822.html>RFC822</A>
* @author Al Williams
* @version 1.0
*/
public class SMTP
{
// things you might want to change
// 30 seconds timeout
final static boolean debug = true;
final static int WAIT_TIMEOUT = ( 30 * 1000 );
final static int smtpPort = 25;
final static String addressSep = ";"; // separates e-mail addresses
// SMTP server for testing
final static String testServer = "mail.direcpc.com";
String smtpServer;
// could hardcode this
MailMessage message;
String hostname;
BufferedReader input;
OutputStream output;
String errorText; // copy of last response -- in case of error
Socket sock;
final String crlf = "\r\n";
/**
* Get the last response message. Useful for displaying error from SMTP server.
* @returns String containing last response from server.
*/
public String getLastResponse()
{
if (errorText==null) return "Unable to connect or unknown error";
return errorText;
}
/**
* Constructor. Requires SMTP server name.
* @param host An SMTP server. Remember, the server must be accessible from this code.
* In particular, applets can usually only connect back to the same host
* they originated from.
*/
public SMTP( String host )
{
smtpServer = host;
}
//read data from input stream to buffer String
private int getResponse( int expect1 ) throws IOException
{
return getResponse( expect1, -1 );
}
synchronized private int getResponse( int expect1, int expect2 ) throws IOException
{
boolean defStatus;
long startTime;
int replyCode;
TimeoutRead thread = new TimeoutRead( input );
thread.setBuffer("");
thread.start();
try
{
thread.join( WAIT_TIMEOUT );
}
catch( InterruptedException e )
{
}
if( thread.isComplete() && thread.getBuffer().length() > 0 )
{
try
{
errorText = thread.getBuffer(); // if there is an error, this is it.
replyCode = Integer.valueOf( errorText.substring( 0, 3 ) ).intValue();
if( replyCode == 0 ) return -1;
if( replyCode == expect1 || replyCode == expect2 ) return 0;
return replyCode;
}
catch( NumberFormatException e )
{
error(e);
return -1;
}
}
return -1;
// nothing in buffer
}
private void writeString( String s ) throws IOException
{
output.write( s.getBytes() );
}
private int sendAddresses(String pfx, String addr) throws IOException
{
int n0=0;
int n;
int rv=0;
while (rv==0 && (n=addr.indexOf(addressSep,n0))!=-1)
{
writeString(pfx+addr.substring(n0,n)+crlf);
n0=n+1;
rv=getResponse( SMTPResults.SMTP_RESULT_COMPLETED, SMTPResults.SMTP_RESULT_FORWARD );
}
if (rv==0)
{
writeString(pfx+addr.substring(n0)+crlf);
rv=getResponse( SMTPResults.SMTP_RESULT_COMPLETED, SMTPResults.SMTP_RESULT_FORWARD );
}
return rv;
}
/**
* Use sendMail to actually send an e-mail message.
* @param MailMessage This is a filled-in MailMessage object that specifies the text, subject, and recipients.
* @return Zero if successful. Otherwise, it returns the SMTP return code.
* @see SMTPResults
*/
public int sendMail( MailMessage msg)
{
String inBuffer;
String outBuffer;
int rv;
message = msg;
if( msg.to == null || msg.to.length() == 0 )
{
error("Must supply To field");
return -1;
}
// Create connection
try
{
sock = new Socket( smtpServer, smtpPort );
hostname = "[" + sock.getLocalAddress().getHostAddress() + "]";
}
catch( IOException e )
{
error(e);
return -1;
}
//Create I/O streams
try
{
input = new BufferedReader( new InputStreamReader( sock.getInputStream() ) );
}
catch( IOException e )
{
error(e);
return -1;
}
try
{
output = sock.getOutputStream();
}
catch( IOException e )
{
error(e);
return -1;
}
rv=sendMailEngine();
// end connection
try
{
sock.close();
sock=null;
}
catch( IOException e )
{
error(e);
return -1;
}
return rv;
}
// this is a separate routine so the main sendMail can always close the socket
private int sendMailEngine()
{
try
{
int replyCode;
int n;
Date today = new Date();
replyCode = getResponse( SMTPResults.SMTP_RESULT_READY );
if( replyCode != 0 ) return replyCode;
//Send HELO
writeString( "HELO " + hostname + crlf );
replyCode = getResponse( SMTPResults.SMTP_RESULT_COMPLETED );
if( replyCode != 0 ) return replyCode;
// Identify sender
writeString( "MAIL FROM: " + message.sender + crlf );
replyCode = getResponse( SMTPResults.SMTP_RESULT_COMPLETED );
if( replyCode != 0 ) return replyCode;
// Send to all recipients
replyCode = sendAddresses("RCPT TO: ",message.to);
if( replyCode != 0 ) return replyCode;
// Send to all CC's (if any)
if( message.cc != null && message.cc.length() != 0 )
{
replyCode = sendAddresses("RCPT TO: ",message.cc);
if( replyCode != 0 ) return replyCode;
}
// Send to all BCC's (if any)
if( message.bcc != null && message.bcc.length() != 0 )
{
replyCode = sendAddresses("RCPT TO: ",message.bcc);
if( replyCode != 0 ) return replyCode;
}
// Send mesage
writeString( "DATA" + crlf );
replyCode = getResponse( SMTPResults.SMTP_RESULT_MAIL_START );
if( replyCode != 0 ) return replyCode;
//Send mail content CRLF.CRLF
// Start with headers
writeString( "Subject: " + message.subject + crlf);
writeString( "From: " + message.sender + crlf);
writeString( "To: " + message.to + crlf);
if( message.cc != null && message.cc.length() != 0 )
writeString( "Cc: " + message.cc + crlf);
writeString( "X-Mailer: SMTP Java Class by Al Williams" + crlf );
writeString( "Comment: Unauthenticated sender" + crlf );
if (message.headers!=null) {
Enumeration key=message.headers.keys();
while (key.hasMoreElements()) {
String keystring=(String)key.nextElement();
writeString(keystring+":"+(String)message.headers.get(keystring)+crlf);
}
}
writeString( "Date: " + today.toString() +crlf + crlf );
String bodybuf=message.body;
评论0