www.pudn.com > MUMail.rar > Pop3Client.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    
 *
 */

package mumail.net;

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

public class Pop3Client extends AbstractMailClient{


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

  private synchronized String sendCommand(String Command) throws IOException {
    String ResultString = "Not Connected";
    try {
      os.writeBytes(Command);
      //System.err.println(Command);
      os.writeByte(10);
      ResultString = ir.readLine();
      //System.err.println(ResultString);
      if (!ResultString.startsWith("+OK"))
	throw new PopException(ResultString.length() >= 4 ? ResultString.substring(4) : ResultString);
    } catch (IOException e) {
      Disconnect();
      throw e;
    }
    return(ResultString);
  }


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


  private  String sendCommandSS(String Command, String Parameter1, String Parameter2) throws IOException {
    return(sendCommand(Command + " " + Parameter1 + " " + Parameter2));
  }


  public void Connect(String host, int port, String userName, String passwd) throws IOException{
    this.Host = new String(host);
    this.Port = port;    
    this.Connect(userName, passwd);
  }

  public void Connect(String userName, String passwd) throws IOException {
    if (!Connected) {
      PopSocket = new Socket(Host, Port);
      os = new DataOutputStream(PopSocket.getOutputStream());
      is = new DataInputStream(PopSocket.getInputStream());
      ir = new BufferedReader(new InputStreamReader(is, "8859_1"));
      try {
        ServerID = ir.readLine();
        System.err.println(ServerID);
        sendUsername(userName);
        sendPassword(passwd);
        setConnected(true);
      } catch (IOException e) {
        Disconnect();
        throw e;
      }
    }
  }


  public void Disconnect() {
    if (Connected) {
      try {
        if (!disconnecting) {
          disconnecting = true;
       	  try {
            sendCommand("QUIT");
          } catch (IOException e1) {
            // We might have read a result from another asynchronous communication
            // This is OK
          }
//          os.close();
//          ir.close();
          PopSocket.close();
        }
      } catch (IOException e2) {
        ;
//	e.printStackTrace();
      } finally {
        setConnected(false);
        disconnecting = false;
      }
    }
  }


  public Pop3Client() {
  }


  public Pop3Client(String Host) {
    this.Host = new String(Host);
  }


  public Pop3Client(String Host, int Port) {
    this.Host = new String(Host);
    this.Port = Port;
  }


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


  private void sendUsername(String Username) throws IOException {
    sendCommandS("USER", Username);
  }


  private void sendPassword(String Password) throws IOException {
    sendCommandS("PASS", Password);
  }


  public int getSize(int index) throws IOException {
    StringTokenizer statusLine;
    String statusString;
    int Size = 0;

    statusString = sendCommandS("LIST", Integer.toString(index));
    statusLine = new StringTokenizer(statusString);

    if (statusLine.hasMoreTokens() && (statusLine.nextToken().equals("+OK"))) {
      if (statusLine.hasMoreTokens() && (statusLine.nextToken().equals(Integer.toString(index)))) {
				Size = Integer.parseInt(statusLine.nextToken());
      } else {
				; // Throw popException (Wrong Index)
      }
    } else {
			; // Throw popException
    }
    return Size;
  }

  public int getCount() throws IOException {
    int Count = 0;
    String statusString;
    StringTokenizer statusLine;

    statusString = sendCommand("STAT");
    statusLine = new StringTokenizer(statusString);
    statusLine.nextToken(); //Drop +OK
    if (!statusLine.hasMoreTokens()) {
      throw new PopException("Protocol Error in STAT Response. No message count found.");
    }

    Count = Integer.parseInt(statusLine.nextToken());

    return Count;
  }


  public String getUID(int index) throws IOException {
    String UID;
    String messageNumber = Integer.toString(index);
    String statusString;
    StringTokenizer statusLine;

    statusString = sendCommandS("UIDL", messageNumber);
    statusLine = new StringTokenizer(statusString);
    statusLine.nextToken(); //Drop +OK
    if (!(statusLine.hasMoreTokens() && statusLine.nextToken().equals(messageNumber))) { //Drop message number
      throw new PopException("Protocol Error in UIDL Response. Message number expected as second word!");
    }
    if (statusLine.hasMoreTokens()) {
      UID = statusLine.nextToken();
    } else {
      throw new PopException("Protocol Error in UIDL Response. No UID found.");
    }

    return UID;
  }


  public String[] getHeader(int index) throws IOException {

    String newLine;
    Vector headerLines = new Vector();
    String headerLinesA[];

    //    CommandString = "TOP " + Integer.toString(index) + " 0";
    //    os.writeBytes(CommandString);
    //    os.writeByte(10);
    newLine = sendCommandSS("TOP", Integer.toString(index), "0");
    while ( !(newLine = ir.readLine()).equals(".") ) {
      headerLines.addElement(newLine);
    }
    headerLinesA = new String[headerLines.size()];
    headerLines.copyInto(headerLinesA);

    return headerLinesA;
  }


  public String[] getMail(int index, MailListener mailListener) throws IOException, InterruptedException {

    int i;
    int size;
    int oldPercentDone = 0;
    int percentDone = 0;
    int absoluteDone = 0;
    String newLine;
    Vector mailLines = new Vector();
    String mailLinesA[];

    //    CommandString = "RETR " + Integer.toString(index);
    //    os.writeBytes(CommandString);
    //    os.writeByte(10);
    size = getSize(index);
    newLine = sendCommandS("RETR", Integer.toString(index));
    try {
      while ( !(newLine = ir.readLine()).equals(".") ) {
        if (Thread.currentThread().interrupted()) {
          throw new InterruptedException();
        }
        absoluteDone += newLine.length() + 2; // count lineLength + CR + LF
        percentDone = absoluteDone / (size / 100);
        if (percentDone > oldPercentDone) {
          oldPercentDone = percentDone;
          mailListener.downloadStatusUpdated(percentDone);
//          Thread.currentThread().yield();
	  synchronized (this) {
	      wait(1);
	  }
        }
        if (newLine.length() > 0 && newLine.charAt(0) == '.') {
       	  if (newLine.length() > 1 && newLine.charAt(1) == '.') {
    	    newLine = newLine.substring(1);
          } else {
            System.err.println("Single dot found at beginning of this mail line:");
            System.err.println(newLine);
            System.err.println();
          }
        }
        mailLines.addElement(newLine);
      }
    } catch (IOException e) {
      Disconnect();
      throw e;
    }
    mailLinesA = new String[mailLines.size()];
    mailLines.copyInto(mailLinesA);

    return mailLinesA;
  }


  public void deleteMail(int index) throws IOException {
    sendCommandS("DELE", Integer.toString(index));
  }

  /**
   *
   **/
  public String getProtocolName(){
    return "POP3";
  }

  /**
   *
   **/
  public String getDefaultPort(){
    return "110";
  }

}