www.pudn.com > MUMail.rar > Imap4Client.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 final class Imap4Client extends AbstractMailClient{


  /**
   *
   **/
  private String imapHost;


  /**
   *
   **/
  private int imapPort = 143;


  /**
   *
   **/
  private Socket imapSocket;


  /**
   *
   **/
  private DataOutputStream os;


  /**
   *
   **/
  private DataInputStream is;


  /**
   *
   **/
  private BufferedReader ir;


  /**
   *
   **/
  private String serverID = "";


  /**
   *
   **/
  private boolean disconnecting = false;


  /**
   *
   **/
  private int identifier = 0;


  /**
   *
   **/
  private String completionResult;


  /**
   *
   **/
  private int count = -1;


  /**
   *
   **/
  public Imap4Client(){
    imapHost = "localhost";
  }


  /**
   *
   **/
  public Imap4Client(String host){

    imapHost = new String(host);

  }


  /**
   *
   **/
  public Imap4Client(String host, int port){

    imapHost = new String(host);
    imapPort = port;

  }


  /**
   *
   **/
  public void Connect(String host, int port,
		      String userName, String passwd) throws IOException{

    imapHost = new String(host);
    imapPort = port;

    if (!Connected) {
      imapSocket = new Socket(imapHost, imapPort);
      os = new DataOutputStream(imapSocket.getOutputStream());
      is = new DataInputStream(imapSocket.getInputStream());
      ir = new BufferedReader(new InputStreamReader(is, "8859_1"));

      try {
        serverID = ir.readLine();
        System.err.println(serverID);
	authenticate(userName, passwd);
	count = selectInbox();
        setConnected(true);
      } catch (IOException e) {
        Disconnect();
        throw e;
      }

    }

  }


  /**
   *
   **/
  public void Disconnect(){

    if (Connected) {

      try {

        if (!disconnecting) {
          disconnecting = true;

       	  try {
            sendCommandS("LOGOUT", "");
          } catch (IOException e1) {
            // We might have read a result from another
	    // asynchronous communication
            // This is OK
          }
	  // os.close();
	  // ir.close();
          imapSocket.close();
        }
      } catch (IOException e2) {
	// e.printStackTrace();
      } finally {
        setConnected(false);
        disconnecting = false;
      }

    }

  }


  /**
   *
   **/
  private String[] sendCommandS(String command,
				String parameter) throws IOException{

    String[] result;
    String id = Integer.toString(++identifier);
    try {
      String c = id + " " + command + " " + parameter;
      os.writeBytes(c);
      //System.err.println(c);
      os.writeByte(10);
      result = readResponse();
      //System.out.println(completionResult);
      //for(int u=0;u=0){
	StringTokenizer tok = new StringTokenizer(result[i]);
	if (tok.hasMoreTokens() && (tok.nextToken().equals("*"))) {
	  if (tok.hasMoreTokens()){
	    return Integer.parseInt(tok.nextToken());
	  }
	}
	break;
      }
    }
    throw new ImapException("IMAPv1 Protocol Error in SELECT Response." +
			    "REQUIRED untagged response EXISTS missed!");
  }


  /**
   *
   **/
  public int getSize(int index) throws IOException{

    //System.err.println("getSize("+index+")");

    String[] result = sendCommandSS("FETCH",
				    Integer.toString(index), "RFC822.SIZE");

    if(completionResult.startsWith("OK")){

      for(int i=0;i=0){	  

	  StringTokenizer tok = new StringTokenizer(result[i].substring(result[i].indexOf("UID ")+4), " ()");

	  if (tok.hasMoreTokens()){
	    return Integer.toString(Integer.parseInt(tok.nextToken()));
	  }

	  break;

	}

      }

    }

    throw new ImapException("IMAPv1 Protocol Error in UID Response.");
    
  }


  /**
   *
   **/
  public String[] getHeader(int index) throws IOException{
    //System.err.println("getHeader("+index+")");
    
    String[] header;

    String[] result = sendCommandSS("FETCH", Integer.toString(index), "RFC822.HEADER");

    if(completionResult.startsWith("OK")){

      for(int i=0;i=0){

	  for(int j=i+1;j=0){
	  StringTokenizer tok = new StringTokenizer(s.substring(s.indexOf("RFC822 ")+7), " {}");
	  if (tok.hasMoreTokens()){
	    int size = Integer.parseInt(tok.nextToken());
	    int current = 0;
	    //System.out.println(size);

	    while((s=ir.readLine())!=null && (current< size)){

	      if (Thread.currentThread().interrupted()) {
		throw new InterruptedException();
	      }
	      absoluteDone = current;
	      percentDone = absoluteDone / (size / 100);
	      if (percentDone > oldPercentDone) {
		oldPercentDone = percentDone;
		mailListener.downloadStatusUpdated(percentDone);
		// Thread.currentThread().yield();
		synchronized (this) {
		  wait(1);
		}
	      }

	      //System.out.println(s);
	      current = current + s.length() + 2;
	      //System.out.println(current);
	      v.addElement(s);
	    }		

	    //
	    s=ir.readLine();
	    //System.err.println(s);

	    String[] result = new String[v.size()];
	    v.copyInto(result);
	    
	    return result;
	    
	  }
	  else{
	    //problem
	  }
	}
	else{
	  //problem
	}
      }
      else{
	// problem
      }	       

      return null;

    } catch (IOException e) {
      System.err.println(e);
      Disconnect();
      throw e;
    }

  }

  /**
   *
   **/
  public void deleteMail(int index) throws IOException {

    //System.err.println("deleteMail("+index+")");

  }

  /**
   *
   **/
  private String[] readResponse(){

    String s;
    Vector v = new Vector();

    try{

      while((s=ir.readLine())!=null){
	//System.out.println(s);
	if(s.startsWith("* ")){
	  v.addElement(s);
	  if(s.indexOf("RFC822.HEADER")>=0){
	    StringTokenizer tok = new StringTokenizer(s.substring(s.indexOf("RFC822.HEADER ")+14), " {}");
	    if (tok.hasMoreTokens()){
	      int size = Integer.parseInt(tok.nextToken());
	      int current = 0;
	      //System.out.println(size);

	      while((s=ir.readLine())!=null){
		//System.out.println(s);
		current = current + s.length() + 2;
		//System.out.println(current);
		v.addElement(s);
		if(current>=size){
		  v.addElement(ir.readLine());
		  break;
		}
	      }		
	    }
	  }
	}
	else{
	  String[] result = new String[v.size()];
	  v.copyInto(result);
	  completionResult = s.substring(s.indexOf(' ')+1);
	  //System.out.println(v);
	  return result;
	}	       
      }
    } catch (IOException e){
    }

    return null;

  }


  /**
   *
   **/
  private IdleReader idleReader;


  /**
   *
   **/
  private void startIdleReading(){

    idleReader = new IdleReader(ir);
    idleReader.start();

  }


  /**
   *
   **/
  private void stopIdleReading(){

    idleReader.stopReading();

  }


  /**
   *
   **/
  private static class IdleReader extends Thread{

    /**
     *
     **/
    private BufferedReader reader;

    /**
     *
     **/
    boolean doReading = false;
    
    /**
     *
     **/
    boolean readingStopped = false;

    /**
     *
     **/
    IdleReader(BufferedReader reader){

      this.reader = reader;

    }

    /**
     *
     **/
    public void run(){

      doReading = true;
      readingStopped = false;

      try{
	while(doReading){
	  if(reader.ready()){
	    System.err.println(reader.readLine());
	  }
	  else{
	    Thread.currentThread().sleep(500);
	  }
	}
      } catch (IOException e){
      } catch (InterruptedException e2){
      }
    }

    /**
     *
     **/
    void stopReading(){

      doReading = false;
      while(!readingStopped){
      }

    }

  }


}