/*
 */
import java.net.*;
import java.io.*;


public class SmtpFake {
	static final int proxyport = 8025;
	static final String remoteHost = "lemi";
	
	static Object po;

	public static void notify1()
	{
		synchronized(po){
			po.notify();
		}
		
	}

    public static void main(String[] args) {
        ServerSocket serverSocket = null;
        Socket clientSocket = null;

		Socket backSocket = null;

        try {
            serverSocket = new ServerSocket( proxyport );
        } catch (IOException e) {
            System.out.println("Could not listen on port: " + proxyport + ", " + e);
            System.exit(1);
        }
		try {
			while( true ){
				try {
					clientSocket = serverSocket.accept();
				} catch (IOException e) {
					System.out.println("Accept failed: " + proxyport + ", " + e);
					System.exit(1);
				}

				try {
					backSocket = new Socket( remoteHost, 25);
				} catch (UnknownHostException e) {
					System.err.println("Don't know about host: " + remoteHost);
				} catch (IOException e) {
					System.err.println("Couldn't get I/O for the connection to: lemi");
				}

				po = new Object();

				try {
		
					DoRelayClient relay1 = new DoRelayClient();
					relay1.fromTo( clientSocket, backSocket );

					DoRelayServer relay2 = new DoRelayServer();
					relay2.fromTo( backSocket, clientSocket );
			
					Thread t1 = new Thread( relay1 );
					Thread t2 = new Thread( relay2 );
			
					t1.start();
					t2.start();
			
					try {
						synchronized(po){
							po.wait();
						}
				
					}
					catch( InterruptedException ign) {
					}
			
					t1.stop();
					t2.stop();

					clientSocket.close();
					backSocket.close();
			

				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		catch( IOException e ){
			try { serverSocket.close(); }
			catch( IOException ee ) {
			}
			
		}
    }
}

class DoRelayServer implements Runnable {
	DataInputStream is;
	PrintStream os;

	public void run() {
		String input;

		try {
			while( (input = is.readLine() )!=null){
				os.println( input );
			}
		}
		catch( IOException e ){
			System.err.println( "Socket Error" );
		}
		SmtpFake.notify1();
	}
	
	public void fromTo( Socket src, Socket dst)
		throws IOException{
		is = new DataInputStream( src.getInputStream());
		os = new PrintStream( dst.getOutputStream ());
	}
}

class DoRelayClient implements Runnable {
	DataInputStream is;
	PrintStream os;

    final int commandMode = 1;
	final int dataMode1 = 2;
	final int dataMode2 = 3;

	int mode = commandMode;

	public void run() {
		String input;

		try {
			while( (input = is.readLine() )!=null){
				if( mode == commandMode ){
					os.println( input );
					if( input.equalsIgnoreCase( "data" ))
						mode = dataMode1;
				}
				else if( mode == dataMode1) {
					if( input.equals( "" )){
						mode = dataMode2;
					}
					else{
						os.println( input );
					}
				}
				else if( mode == dataMode2 ){
					os.println( input );
					if( input.equals(".")){
						mode = commandMode;
					}
				}
				else{
					throw new InternalError();
				}
			}
		}
		catch( IOException e ){
			System.err.println( "Socket Error" );
		}
		catch( InternalError e){
			System.err.println( "Internal Error" );
		}
		
		SmtpFake.notify1();
	}
	
	public void fromTo( Socket src, Socket dst)
		throws IOException{
		is = new DataInputStream( src.getInputStream());
		os = new PrintStream( dst.getOutputStream ());
	}
}

