/*
 * Main.java
 *
 * Created on 5 de enero de 2005, 11:14
 *
 * This code demonstrates how to send mail (text or html one)
 * without the java mail api: connecting directly w. the smtp
 * of the destination e-mail address :)
 *
 * The soft resolves the mail server of the <to> field using
 * JNDI
 *
 */

package mailthedj;

import java.util.*;
import javax.naming.InitialContext.*;
import javax.naming.directory.*;
import javax.naming.*;

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

/**
 *
 * @author  rafael.carballo
 */
    public class smtp_mailer  implements Runnable {

    private static final String DNS_SERVER="192.168.0.212"; //for resolving MX's domain
    private static final int SMTP_PORT=25;
    private static final String FROM="rcc@la-ira.com";
    private static final String TO="rcc@la-ira.com";

    private Vector mx_dns,patron;
    private Socket sk;
    private String mheader;
    private String from,to,subject,message,lastLog;
    private boolean status;

    public smtp_mailer(){
        new smtp_mailer(FROM,TO,"empty subject","empty body");
    }

    public void start(){
        run();
    }
    public void run(){
        try{

         //Gets Domain name from e-mail TO field
         String dominio=getDomainFromEmail(to);
         mx_dns=getMXRegistry(dominio);

         if(mx_dns.size()>0){
             //would b great to set a loop to guarantee a real connection for one of the
             //real mail server for the <to> domain.
               int actual=0;
               sk=null;
               while(sk==null){
                System.out.println("TRYING WITH----->"+mx_dns.elementAt(actual)+"<-");
                try {
                sk=new Socket((String)mx_dns.elementAt(actual),SMTP_PORT);
                } catch(Exception eu90){
                    actual++;
                    if(actual>mx_dns.size()){
                        actual=0;
                    }

                }
               }

            if(sk.isConnected()){
                if(sendMessage()){
                    status=true;
                    lastLog="ok";
                } else{
                    status=false;
                    //The error message is set at sendMessage()
                }
            } else{
                 status=false;
                 lastLog="Fallo en la conexión con el servidor SMTP";
            }
            sk.close();

         } else {
             //Can't get the MX registry for the domain
             lastLog="No se pudo obtener el registro MX para el dominio ["+dominio+"]";
             status=false;
         }


        } catch (Exception e){
            status=false;
            // Unknown error
            lastLog="Fallo de origen no controlado";
            //e.printStackTrace();
        }
    }

    public smtp_mailer(String from,String to, String subject, String message) {
        this.lastLog="";
        this.status=true;
        this.from=from;
        this.to=to;
        this.subject=subject;
        this.message=message;
    }

    public boolean getStatus(){
        return this.status;
    }
    public String getLastLog(){
        return this.lastLog;
    }

    private boolean sendMessage(){
        boolean stat=true;
        try {
             BufferedReader in=new BufferedReader(new InputStreamReader(sk.getInputStream()));
             PrintWriter out=new PrintWriter(sk.getOutputStream());

             load_patron();
             in.readLine();
             String estado=new String("");
             for(int i=0;i<patron.size()-1;i++){

               out.println((String)patron.elementAt(i));
               out.flush();

               System.out.println("Sending:"+patron.elementAt(i));

               estado=in.readLine();

               System.out.println("Receiving:"+estado);

               String[] code=estado.split(" ");

               if(!code[0].equals("250") && !code[0].equals("354")){
                   stat=false;
                   lastLog=estado;          //set the error message
                   out.println("quit");
                   out.flush();
                   System.out.println("Sending:"+patron.elementAt(i));
                   String jarl=in.readLine();
                   System.out.println("Receiving:"+jarl);
                   break;
               }
             }

             if(stat){
                 //Compose Message Header
                 load_header();
                 //Send Message Header
                 out.println(mheader);
                 out.flush();

                 System.out.println("Sending:"+mheader);

                 //Sends the body of the message
                 out.println(message+" \r\n.");
                 out.flush();
                 //Reads the response
                 in.readLine();

                 //Exit the remote SMTP System.
                 out.println("quit");
                 out.flush();
                 in.readLine();
             }

             in.close();
             out.close();

        } catch (Exception sme){
            stat=false;
        }
        return stat;
    }

    private Vector getMXRegistry(String dominio) {

         Vector r=new Vector();

         try {
             //Get MX registry for a Domain using JNDI
             DirContext ictx = new InitialDirContext();
             String valores=(ictx.getAttributes("dns://"+DNS_SERVER+"/"+dominio,new String[] {"MX"})).toString();

             //get the useful info
             valores=valores.substring(7,valores.length()-1);
             String[] dns=valores.split(",");

             for(int i=0;i<dns.length;i++){
                 r.addElement(dns[i].substring(3,(dns[i].length())-1));
             }

             //remove blanks from the server address
             for(int j=0;j<r.size();j++){
                 r.setElementAt(((String)r.elementAt(j)).replace(" ",""),j);
             }

         } catch (Exception mxe){
             //mxe.printStackTrace();
             //System.out.println("No se pudo obtener el Registro MX");
         }
         return r;
    }

    private String getDomainFromEmail(String address){
        String resultado="";
        String[] slots=address.split("@");
        if(slots.length>0)
            resultado=slots[1];

        return resultado;
    }

    private void load_patron(){
        patron=null;
        patron=new Vector();
        patron.addElement("helo RcCMailer");
        patron.addElement("rset");
        patron.addElement("mail from: "+from);
        patron.addElement("rcpt to: "+to);
        patron.addElement("data");
        patron.addElement("quit");
    }

    private void load_header(){
        mheader=new String("");
        mheader+="From: "+from+"\n";
        mheader+="To: "+to+"\n";
        mheader+="Content-type: text/html; charset=ISO-8859-1; format=flowed\n";
        mheader+="MIME-Version: 1.0 \n";
        mheader+="Content-Transfer-Encoding: 7bit\n";
        mheader+="X-Mailer: Mozilla Thunderbird 0.8 (Windows/20040913)\n";
        mheader+="X-Priority: Normal\n";
        mheader+="Return-Path: "+from+"\n";
        mheader+="X-Accept-Language: en-us, en\n";
        mheader+="Subject: "+subject+"\n";
        mheader+="\r\n";
    }










//main.method.

    public static void main(String[] args) {


		/*For testing, uncomment the lines below*/

        /*smtp_mailer a=new smtp_mailer("from@yourserver.com","to@yourserver.com","subject","body");
        a.start();
        System.out.println("Estado de la operacion:"+a.getStatus());
        System.out.println("Estado de la operacion:"+a.getLastLog());*/
    }

}
