/***************************************************************************
                              emailthread.cpp
                              ----------------
    begin                : Jul 7 2004
    copyright            : (C) 2004 The University of british Columbia
    email                :
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 ***************************************************************************/

#include <ctype.h>
#include <netdb.h>
#include <sys/socket.h>
 
#include <kdebug.h>

#include "emailthread.h"

EMailThread::EMailThread( const QString& strTo,
                          const QString& strFrom,
                          const QString& strSubject,
                          const QString& strBody,
                          const QString& strSMTPServer )
: QThread() {
  _strTo          = strTo;
  _strFrom        = strFrom;
  _strSubject     = strSubject;
  _strBody        = strBody;
  _strSMTPServer  = strSMTPServer;
}


EMailThread::~EMailThread() {
}


void EMailThread::run() {
  QHostAddress    hostAddress;
  QSocketDevice   socketDevice;
  bool            bOK = false;
  int             iLength;
  int             i;
  struct hostent* pHostAddress;

  if( _strSMTPServer.length() > 0 ) {
    if( isalpha( (_strSMTPServer.ascii())[0] ) ) {
      //
      // the host address is a name...
      //
      pHostAddress = gethostbyname( _strSMTPServer.ascii() );
      if( pHostAddress ) {
        for( i=0; i<4; i++ ) {
          if( i == 0 ) {
            _strSMTPServer = "";
          } else {
            _strSMTPServer += ".";
          }
          _strSMTPServer += QString("%1").arg((uint)(uchar)pHostAddress->h_addr[i]);
        }
        if( hostAddress.setAddress( _strSMTPServer ) ) {
          bOK = true;
        }
      }
    } else {
      if( hostAddress.setAddress( _strSMTPServer ) ) {
        bOK = true;
      }
    }

    if( bOK ) {
      if( socketDevice.connect( hostAddress, 25 ) ) {
        _strMessage = QString::fromLatin1( "From: " ) + _strFrom +
                  QString::fromLatin1( "\nTo: " ) + _strTo +
                  QString::fromLatin1( "\nSubject: " ) + _strSubject +
                  QString::fromLatin1( "\n\n" ) + _strBody + "\n";
        _strMessage.replace( QString::fromLatin1( "\n" ),
                  QString::fromLatin1( "\r\n" ) );
        _strMessage.replace( QString::fromLatin1( "\r\n.\r\n" ),
                  QString::fromLatin1( "\r\n..\r\n" ) );

        _state = Init;

        while( _state != Close ) {
          iLength = socketDevice.waitForMore( 0, NULL );
          if( iLength > 0 ) {
            read( socketDevice );
          } else if( iLength == -1 ) {
            _state = Close;
          }
        }
      }
    }
  }

  delete this;
}


bool EMailThread::write( QSocketDevice& socketDevice, const QString& strWrite )
{
  bool  bRetVal = false;
  int   iLength;
  int   iLengthRead;
  
  iLength = strWrite.length();
  iLengthRead = socketDevice.writeBlock( strWrite.ascii(), iLength );

  if( iLengthRead == iLength ) {
    bRetVal = true;
  } else {
    _state = Close;
  }

  return bRetVal;
}


void EMailThread::read( QSocketDevice& socketDevice )
{
  QString responseLine;
  QString strWrite;
  char*   pRead = NULL;
  int     iLength;
  int     iLengthRead;
  
  iLength = socketDevice.waitForMore(0, NULL);
  if( iLength != -1 ) {
    pRead = new char[iLength];
    iLengthRead = socketDevice.readBlock(pRead, iLength);
    if( iLengthRead != -1 ) {
      responseLine = pRead;
      responseLine.truncate( 3 );
      
      if( _state == Init && responseLine[0] == '2' ) {
        strWrite = "HELO there\r\n";
        if( write( socketDevice, strWrite ) ) {
          _state = Mail;
        }
      } else if( _state == Mail && responseLine[0] == '2' ) {
        strWrite = QString("MAIL FROM: <%1>\r\n").arg( _strFrom );
        if( write( socketDevice, strWrite ) ) {
          _state = Rcpt;
        }
      } else if( _state == Rcpt && responseLine[0] == '2' ) {
        strWrite = QString("RCPT TO: <%1>\r\n").arg( _strTo );
        if( write( socketDevice, strWrite ) ) {
          _state = Data;
        }
      } else if( _state == Data && responseLine[0] == '2' ) {
        strWrite = "DATA\r\n";
        if( write( socketDevice, strWrite ) ) {
          _state = Body;
        }
      } else if( _state == Body && responseLine[0] == '3' ) {
        strWrite = QString("%1.\r\n").arg( _strMessage );
        if( write( socketDevice, strWrite ) ) {
          _state = Quit;
        }
      } else if( _state == Quit && responseLine[0] == '2' ) {
        strWrite = "QUIT\r\n";
        if( write( socketDevice, strWrite ) ) {
          _state = Close;
        }
      } else {
        _state = Close;
      }
    } else {
      _state = Close;
    }
  } else {
    _state = Close;
  }

  delete[] pRead;
}

// vim: ts=2 sw=2 et
