www.pudn.com > MUMail.rar > SmtpClient.java


/*
 * Copyright (C) 1998-2001 Mark Tuempfel and Uli Luckas
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is" distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 *
 * To reach the Authors you can send E-Mail to:
 *	Mark Tuempfel 
 *      Uli Luckas    
 *
 */

// HELO hostname
// MAIL FROM:
// RCPT TO:
// DATA
// .

package mumail.net;

import java.io.*;
import java.net.*;
import java.util.*;
import java.text.*;

public class SmtpClient {


  private String Host = "localhost";
  private int Port = 25;
  private Socket PopSocket;
  private DataOutputStream os;
  private DataInputStream is;
  private BufferedReader ir;
  private String ServerID = "";
  private boolean Connected = false;

  public SmtpClient() throws IOException {
    Connect();
  }


  public SmtpClient(String Host) throws IOException {
    this.Host = new String(Host);
    Connect();
  }


  public SmtpClient(String Host, int Port) throws IOException {
    this.Host = new String(Host);
    this.Port = Port;
    Connect();
  }


  private void Connect() throws IOException {
    String Servername;

    PopSocket = new Socket(Host, Port);
    os = new DataOutputStream(PopSocket.getOutputStream());
    is = new DataInputStream(PopSocket.getInputStream());
    ir = new BufferedReader(new InputStreamReader(is, "8859_1"));
    Connected = true;
    try {
      Servername = InetAddress.getLocalHost().getHostName();
    } catch (Exception e) {
      Servername = "dont.know.my.name";
    }
    sendCommandS("HELO", Servername, "250");
   }


  public String sendMail(String Mail, String Encoding, String ExpectedResult) throws IOException {
    String ResultString = "555 Not Connected";
    byte[] lineBytes;

    if (Connected) {
      BufferedReader mr = new BufferedReader(new StringReader(Mail));
      String mailLine;
      int i;

      // Write the header lines
      while ((mailLine = mr.readLine()).length() > 0) {
          lineBytes = mailLine.getBytes("ASCII");
          for (i = 0; i < lineBytes.length; i++) {
              os.writeByte(lineBytes[i] );
          }
          os.writeBytes("\r\n");
      }
      while ((mailLine = mr.readLine()) != null) {
          if (mailLine.length() > 0 && mailLine.charAt(0) == '.') {
	    mailLine = '.' + mailLine;
          }
          lineBytes = mailLine.getBytes(mumail.mime.CharacterEncoding.aliasName(Encoding));
          for (i = 0; i < lineBytes.length; i++) {
            if ( i % 72 == 71 ) {    // Soft Line Break at Pos 70
              os.writeBytes("=\r\n");
            }
            if ((lineBytes[i] >= 32) && (lineBytes[i] < 128) && (lineBytes[i] != '=')) {
              os.writeByte(lineBytes[i] );
            } else {
              String hexString = "00" + java.lang.Integer.toHexString(new Byte(lineBytes[i]).intValue());
              hexString = hexString.substring(hexString.length() - 2);
              os.writeByte('=');
              os.writeBytes(hexString);
            }
          }
          os.writeBytes("\r\n");
        }
        os.writeBytes(".");
        os.writeBytes("\r\n");
        ResultString = ir.readLine();
      }
      if (!ResultString.startsWith(ExpectedResult))
        throw new SmtpException(ResultString.substring(4));
      return(ResultString);
  }


  public String sendCommand(String Command, String ExpectedResult) throws IOException {
    String ResultString;
    if (Connected) {
      os.writeBytes(Command);
      os.writeBytes("\r\n");
      ResultString = ir.readLine();
      while (ResultString.startsWith("220")) {
        System.out.println(ResultString);
        ResultString = ir.readLine();
      }
      if (!ResultString.startsWith(ExpectedResult)) {
        throw new SmtpException(ResultString.substring(4));
      }
    } else {
      throw new SmtpException("Not Connected");
    }

    return(ResultString);
  }


  public String sendCommandS(String Command, String Parameter1, String ExpectedResult) throws IOException {
    return sendCommand(Command + " " + Parameter1, ExpectedResult);
  }


  public void Disconnect() throws IOException {
    if (Connected) {
      try {
      	sendCommand("QUIT", "250");
        os.close();
        ir.close();
        PopSocket.close();
      } catch (IOException exep) {
	;
      }
    }
  }


  public String GetServerID() {
    return(new String(ServerID));
  }


  public void submitMail(String From, String To, String Subject, String Body, String Encoding) throws IOException {

    GregorianCalendar currentCalendar = new GregorianCalendar(Locale.US);

    SimpleDateFormat rfc822DateFormat = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss", Locale.US);
    rfc822DateFormat.setCalendar(currentCalendar);

    int milliSecsOffset = currentCalendar.get(GregorianCalendar.ZONE_OFFSET)+currentCalendar.get(GregorianCalendar.DST_OFFSET);
    Date offset = new Date(java.lang.Math.abs(milliSecsOffset));

    SimpleDateFormat offsetFormat;
    if (milliSecsOffset>=0) {
	offsetFormat = new SimpleDateFormat("'+'HHmm", Locale.US);
    } else {
	offsetFormat = new SimpleDateFormat("'-'HHmm", Locale.US);
    }
    offsetFormat.setTimeZone(new SimpleTimeZone(0, "GMT"));

    String dstString;
    if (currentCalendar.getTimeZone().inDaylightTime(currentCalendar.getTime())) {
	dstString = " DST";
    } else {
	dstString = "";
    }



    String Mail = "Date: " + rfc822DateFormat.format(currentCalendar.getTime()) + " " + offsetFormat.format(offset) + " (" + currentCalendar.getTimeZone().getID() + dstString + ")\r\n"
                + "To: " + To + "\r\n"
                + "From: " + From + "\r\n"
                + "Subject: " + Subject + "\r\n"
                + "MIME-Version: 1.0\r\n"
                + "Content-Type: text/plain; charset=" + Encoding + "\r\n"
                + "Content-Transfer-Encoding: quoted-printable\r\n"
                + "X-Mailer: " + mumail.MUMail.ID + "\r\n"
                + "\r\n"
                + Body;

    String Sender = Canonicalize(From);
    String Reciepient = Canonicalize(To);

    sendCommand("MAIL FROM:" + Sender, "250");
    sendCommand("RCPT TO:" + Reciepient, "250");
//    sendCommand("MAIL FROM:" + From, "250");
//    sendCommand("RCPT TO:" + To, "250");
    sendCommand("DATA", "354");
    sendMail(Mail, Encoding, "250");
    sendCommand("RSET", "250");
  }


  protected String Canonicalize(String SmtpAddr) {
    int start;
    int stop;

    start = SmtpAddr.indexOf('<');
    if (start == -1) {
      return "<" + SmtpAddr.trim() + ">";
    } else {
      stop = SmtpAddr.indexOf('>') + 1;
      return SmtpAddr.substring(start, stop);
    }
  }


  protected void finalize () throws Throwable {
    Disconnect();
    super.finalize();
  }

}