Example #1
0
   IMAPSort::SortField 
   IMAPSort::GetSortField_(AnsiString sHeaderField)
   {
      SortField sortField;

      sHeaderField.MakeUpper();

      if (sHeaderField == "SUBJECT")
         sortField = Subject;
      else if (sHeaderField == "CC")
         sortField = CC;
      else if (sHeaderField == "DATE")
         sortField = Date;
      else if (sHeaderField == "FROM")
         sortField = From;
      else if (sHeaderField == "TO")
         sortField = To;
      else if (sHeaderField == "ARRIVAL")
         sortField = Arrival;
      else if (sHeaderField == "SIZE")
         sortField = Size;
      else
         sortField = Unknown;

      return sortField;
   }
   MessageMetaData::MetaDataField 
   MessageMetaData::GetMetaDataField(const String &fieldName)
   {
      AnsiString sHeaderField = fieldName;
      sHeaderField.MakeUpper();

      MetaDataField metaDataField;

      if (sHeaderField == "SUBJECT")
         metaDataField = Subject;
      else if (sHeaderField == "CC")
         metaDataField = CC;
      else if (sHeaderField == "DATE")
         metaDataField = Date;
      else if (sHeaderField == "FROM")
         metaDataField = From;
      else if (sHeaderField == "TO")
         metaDataField = To;
      else
         metaDataField = Unknown;

      return metaDataField;
   }
   void
   SMTPClientConnection::InternalParseData(const AnsiString  &Request)
   {
      LOG_DEBUG("SMTPClientConnection::_ParseASCII()");

      String sData = "RECEIVED: " + Request;
      LOG_SMTP_CLIENT(GetSessionID(), GetIPAddress().ToString(), sData);

      // Below 3 lines is fix of the problem that occurs when the remote server answers
      // with 2 line in his welcome message.
      String sMinus = "-";
      if ((Request.GetLength() > 3) && (Request.GetAt(3) == sMinus.GetAt(0)))
      {
         LOG_DEBUG("SMTPClientConnection::~_ParseASCII() - 1");
         return;
      }

      int lFirstSpace = Request.Find(" ");
   
      AnsiString sFirstWordTemp;
      if (lFirstSpace < 0)
         sFirstWordTemp = Request;
      else
         sFirstWordTemp = Request.Mid(0, lFirstSpace);
      sFirstWordTemp.MakeUpper();
      int iCode = atoi(sFirstWordTemp);

      // We should not update all recipient's if we've just sent a
      // RCPT TO. We should only update the specific one we've just
      // sent to.
      // 
      // Also, we should not update state if we've just sent QUIT to
      // the server. At the time we send QUIT, the message has already
      // been either accepted for delivery and rejected. Any error after
      // this isn't relvat.
      if (m_CurrentState != RCPTTOSENT && m_CurrentState != QUITSENT)
      {
         if (IsPermanentNegative(iCode))
         {
            _UpdateAllRecipientsWithError(iCode, Request, false);
            _SendQUIT();
            return;
         }
         else if (IsTransientNegative(iCode))
         {
            _UpdateAllRecipientsWithError(iCode, Request, false);
            _SendQUIT();
            return;
         }
      }
   
      switch (m_CurrentState)
      {
      case SENDUSERNAME:
         _ProtocolSendUsername();
         break;
      case SENDPASSWORD:
         _ProtocolSendPassword();
         break;
      case PASSWORDCHECK:
         if (!_ProtocolPassswordCheck(iCode, Request))
         {
            // Authentication failed. We have just sent
            // a quit command.
            return;
         }

         break;
      }
      
      if (m_CurrentState == HELO)
      {
         if (iCode == 220)
         {
			   String sComputerName = Utilities::ComputerName(); 
      
            if (m_bUseSMTPAuth)
            {
               _SendData("EHLO " + sComputerName);
               _SetState(EHLOSENT);
            }
            else
            {
               _SendData("HELO " + sComputerName);
               _SetState(HELOSENT);
            }
        
            LOG_DEBUG("SMTPClientConnection::~_ParseASCII() - 2");

            return ;
         }
         else
         {
            LOG_DEBUG("SMTPClientConnection::~_ParseASCII() - 3");
            _UpdateAllRecipientsWithError(iCode, Request, false);
            _SendQUIT();
            return;
         }
      }

      if (m_CurrentState == EHLOSENT)
      {
         // Ask the server to initiate login process.
         _SendData("AUTH LOGIN");
         _SetState(SENDUSERNAME);
         return ;
      }

      if (m_CurrentState == HELOSENT)
      {
         if (IsPositiveCompletion(iCode))
         {
            // --- Server accepted HELO. Go to HEADER/MAILFROM state.
            _SetState(MAILFROM);
         }
	      else
         {
            _UpdateAllRecipientsWithError(iCode, Request, false);
         }
      }
   

      if (m_CurrentState == MAILFROM)
      {
         String sFrom = m_pDeliveryMessage->GetFromAddress();
         String sData = "MAIL FROM:<" + sFrom + ">";
         _SendData(sData);
         m_CurrentState = MAILFROMSENT;
         LOG_DEBUG("SMTPClientConnection::~_ParseASCII() - 4");
         return;
      }

      if (m_CurrentState == MAILFROMSENT)
      {
         if (IsPositiveCompletion(iCode))
         {
            // --- Server accepted mail from. Go to header/rcpt to state.
            m_CurrentState = RCPTTO;
         }
         else
         {
            LOG_DEBUG("SMTPClientConnection::~_ParseASCII() - 5");
            _UpdateAllRecipientsWithError(iCode, Request, false);
         }

      }

      if (m_CurrentState == RCPTTO)
      {
         LOG_DEBUG("SMTPClientConnection::~_ParseASCII() - 6");

         shared_ptr<MessageRecipient> pRecipient = _GetNextRecipient();
         if (!pRecipient) 
         {
            _SendQUIT();
            return;
         }
         
         String sRecipient = pRecipient->GetAddress();
         String sData = "RCPT TO:<" + sRecipient + ">";
         _SendData(sData);
         m_CurrentState = RCPTTOSENT;

         return;

      }

      if (m_CurrentState == RCPTTOSENT)
      {
         if (m_iCurRecipient < m_vecRecipients.size())
         {
            if (IsPositiveCompletion(iCode))
            {
               _actualRecipients.insert(m_vecRecipients[m_iCurRecipient]);
            }
            else
            {
               _UpdateRecipientWithError(iCode, Request, m_vecRecipients[m_iCurRecipient], false);
            }
         }

         shared_ptr<MessageRecipient> pRecipient = _GetNextRecipient();
         if (pRecipient)
         {
            // Send next recipient.
            _SendData("RCPT TO:<" + pRecipient->GetAddress() + ">");
            m_CurrentState = RCPTTOSENT;
         }
         else
         {
            if (_actualRecipients.size() == 0)
            {
               _SendQUIT();
               return;
            }
            
            m_CurrentState = DATAQUESTION;
         }
      }

      if (m_CurrentState == DATAQUESTION)
      {
         _SendData("DATA");
         m_CurrentState = DATA;
         LOG_DEBUG("SMTPClientConnection::~_ParseASCII() - 7");
         return;
      }

      if (m_CurrentState == DATA)
      {
         if (IsPositiveIntermediate(iCode))
         {
            // Send the data!
            const String fileName = PersistentMessage::GetFileName(m_pDeliveryMessage);
            LOG_DEBUG("SMTPClientConnection::~_BEFORE SendFile");
            _StartSendFile(fileName);
            LOG_DEBUG("SMTPClientConnection::~_AFTER SendFile");
            return;
         }
      }

      if (m_CurrentState == DATASENT)
      {
            LOG_DEBUG("SMTPClientConnection::~_BEFORE SendQUIT");
         _SendQUIT();
            LOG_DEBUG("SMTPClientConnection::~_AFTER SendQUIT");

         if (IsPositiveCompletion(iCode))
         {
            _UpdateSuccessfulRecipients();
            LOG_DEBUG("SMTPClientConnection::~_ParseASCII() - 9");
            return;
         }
         else
         {
            _UpdateAllRecipientsWithError(iCode, Request, false);
            LOG_DEBUG("SMTPClientConnection::~_ParseASCII() - 10");
         }

         return;
      }

      if (m_CurrentState == QUITSENT)
      {     
         // We just received a reply on our QUIT. Time to disconnect.
         m_bPendingDisconnect = true;
         PostDisconnect();
      }
   }
   bool
   SMTPClientConnection::InternalParseData(const AnsiString &Request)
   {
      LogReceivedResponse_(Request);

      int lFirstSpace = Request.Find(" ");
   
      AnsiString sFirstWordTemp;
      if (lFirstSpace < 0)
         sFirstWordTemp = Request;
      else
         sFirstWordTemp = Request.Mid(0, lFirstSpace);

      sFirstWordTemp.MakeUpper();
      int iCode = atoi(sFirstWordTemp);
   
      bool ifFailureFailAllRecipientsAndQuit = 
         current_state_ == HELO ||
         current_state_ == HELOSENT ||
         current_state_ == AUTHLOGINSENT ||
         current_state_ == USERNAMESENT || 
         current_state_ == PASSWORDSENT ||
         current_state_ == MAILFROMSENT ||
         current_state_ == DATACOMMANDSENT ||
         current_state_ == DATASENT ||
         current_state_ == PASSWORDSENT;

      if (ifFailureFailAllRecipientsAndQuit)
      {
         if (!IsPositiveCompletion(iCode))
         {
            UpdateAllRecipientsWithError_(iCode, Request, false);
            SendQUIT_();
            return true;
         }
      }

      switch (current_state_)
      {
      case HELO:
         ProtocolStateHELOEHLO_(Request);  
         return true;
      case HELOSENT:
         ProtocolHELOSent_(Request);
         return true;
      case EHLOSENT:
         ProtocolEHLOSent_(iCode, Request);
         return true;
      case STARTTLSSENT:
         ProtocolSTARTTLSSent_(iCode);
         return false;
      case AUTHLOGINSENT:
         ProtocolSendUsername_();
         return true;
      case USERNAMESENT:
         ProtocolSendPassword_();
         return true;
      case PASSWORDSENT:
         ProtocolSendMailFrom_();
         return true;
      case MAILFROMSENT:
         ProtocolMailFromSent_();
         return true;
      case DATACOMMANDSENT:
         ProtocolData_();
         return false;
      case DATASENT:
         SendQUIT_();
         UpdateSuccessfulRecipients_();
         return true;
      case RCPTTOSENT:
         ProtocolRcptToSent_(iCode, Request);
         return true;
      case QUITSENT:
         // We just received a reply on our QUIT. Time to disconnect.
         EnqueueDisconnect();
         return false;
      }

      return true;
   }