PopReceiveManager.cpp
上传用户:weimei12
上传日期:2022-08-11
资源大小:185k
文件大小:12k
源码类别:
Email客户端
开发平台:
Visual C++
- #include "StdAfx.h"
- #include "SimpleMail.h"
- #include "Pop3Message.h"
- #include "MailSaveMngr.h"
- #include "RecvProgressDlg.h"
- #include "PopReceiveManager.h"
- CPopReceiveManager::CPopReceiveManager(void)
- {
- m_nNumMail = 0;
- m_nTotalSize = 0;
- m_nRecvTimeout = 500;
- m_nSendTimeout = 500;
- AfxSocketInit();
- }
- CPopReceiveManager::~CPopReceiveManager(void)
- {
- m_PopServer.Close();
- }
- ///<summary>
- /// receive the mails
- ///</summary>
- HRESULT CPopReceiveManager::RecMail(IN CMailSaveMngr* pSaveMngr, IN CRecvProgressDlg* pProgressDlg, CArray<MAILPOS>& arrPos, CArray<UINT>& arrSize)
- {
- if (!Connect())
- {
- return HRESULT_FAIL;
- }
- pProgressDlg->UpdateProgress(CONNECT_SERVER_SUCCESS);
- if (!CmdStat())
- {
- return HRESULT_FAIL;
- }
- if (!CmdList())
- {
- return HRESULT_FAIL;
- }
- pProgressDlg->UpdateProgress(RECEIVING_MAILS);
- int i = 0;
- for (; i < m_nNumMail; i++)
- {
- if (m_SizeOfMsg[i] > MAX_MAIL_SIZE_LIMIT)
- {//unavailable to process the big size mail
- TRACE("A mail size exceeds the limit size.");
- continue;
- }
- if (CmdRetr(i + 1))
- {
- MAILPOS tmpPos;
- pSaveMngr->SaveMail(m_strMsgContents, m_SizeOfMsg[i], tmpPos);
- arrPos.Add(tmpPos);
- arrSize.Add(m_SizeOfMsg[i]);
- }
- }
- if (!Disconnect())
- {
- return HRESULT_FAIL;
- }
- pProgressDlg->UpdateProgress(UPDATING_MAILS);
- return HRESULT_SUCCESS;
- }
- ///<summary>
- /// delete the specified mail
- ///</summary>
- HRESULT CPopReceiveManager::DelMail(const CArray<UINT>& arrIndex)
- {
- if (!Connect())
- {
- return HRESULT_FAIL;
- }
- if (!CmdStat())
- {
- return HRESULT_FAIL;
- }
- BOOL bSuc = TRUE;
- int i = 0;
- for (; i < arrIndex.GetSize(); i++)
- {
- if (!CmdDele(arrIndex[i]))
- {
- bSuc = FALSE;
- }
- }
- if (!Disconnect())
- {
- return HRESULT_FAIL;
- }
- if (!bSuc)
- {
- return HRESULT_FAIL;
- }
- return HRESULT_SUCCESS;
- }
- ///<summary>
- /// set the user name
- ///</summary>
- void CPopReceiveManager::SetUserName(const CString& strUserName)
- {
- m_strUserName = strUserName;
- }
- ///<summary>
- /// set the password
- ///</summary>
- void CPopReceiveManager::SetPassword(const CString& strPassword)
- {
- m_strPassword = strPassword;
- }
- ///<summary>
- /// set the pop3 server address
- ///</summary>
- void CPopReceiveManager::SetPopServer(const CString& strPopServer)
- {
- m_strPopServer = strPopServer;
- }
- ///<summary>
- /// get the last error description
- ///</summary>
- CString CPopReceiveManager::GetLastErrorMsg()
- {
- return m_strError;
- }
- ///<summary>
- /// basic network functions
- ///</summary>
- BOOL CPopReceiveManager::Connect()
- {
- if (!m_PopServer.Create())
- {
- m_strError = _T("Failed to create the socket used for pop3!");
- return FALSE;
- }
- if (!SetNetParams())
- {
- return FALSE;
- }
- if (!m_PopServer.Connect(m_strPopServer,POP3_PORT)) // 110 Pop3 Port
- {
- m_strError = _T("Server can't be connected.");
- m_PopServer.Close();
- return FALSE;
- }
- if(CheckResponse(CONNECTION_CHECK) == FALSE)
- {
- m_strError = _T("Server didn't respond.");
- return FALSE;
- }
- if (!AuthorizationState())
- {
- m_strError = _T("Failed to identify the client to the POP3 server. ");
- return FALSE;
- }
- return TRUE;
- }
- BOOL CPopReceiveManager::Disconnect()
- {
- CmdQuit();
- m_PopServer.Close();
- return TRUE;
- }
- ///<summary>
- /// commands in the AUTHORIZATION state, identify the client to the POP3 server
- ///</summary>
- BOOL CPopReceiveManager::AuthorizationState()
- {
- char szBuf[SEND_CMD_SIZE] = {0};
- sprintf_s(szBuf, SEND_CMD_SIZE, "USER %srn", m_strUserName);
- m_PopServer.Send(szBuf, (int)strlen(szBuf));
- if(CheckResponse(USER_CHECK) == FALSE)
- {
- m_strError = _T("Bad User Name.");
- return FALSE;
- }
- memset(szBuf, 0, sizeof(szBuf));
- sprintf_s(szBuf, SEND_CMD_SIZE, "PASS %srn", m_strPassword);
- m_PopServer.Send(szBuf, (int)strlen(szBuf));
- if (CheckResponse(PASSWORD_CHECK) == FALSE)
- {
- m_strError = _T("Bad Password.");
- return FALSE;
- }
- return TRUE;
- }
- ///<summary>
- /// query the number of messages and the size of the maildrop
- ///</summary>
- BOOL CPopReceiveManager::CmdStat()
- {
- char szBuf[SEND_CMD_SIZE] = {0};
- sprintf_s(szBuf, SEND_CMD_SIZE, "STAT rn");
- m_PopServer.Send(szBuf, (int)strlen(szBuf));
- if (CheckResponse(STAT_CHECK) == FALSE)
- {
- m_strError = _T("Error occured during STAT");
- return FALSE;
- }
- return TRUE;
- }
- ///<summary>
- /// query the message-number of the mail and the exact size of the mail
- ///</summary>
- BOOL CPopReceiveManager::CmdList(int nMsgNumber)
- {
- char szBuf[SEND_CMD_SIZE] = {0};
- if (0 == nMsgNumber)
- {
- sprintf_s(szBuf, SEND_CMD_SIZE, "LIST rn");
- }
- else
- {
- sprintf_s(szBuf, SEND_CMD_SIZE, "LIST %drn", nMsgNumber);
- }
- m_PopServer.Send(szBuf, (int)strlen(szBuf));
- if (CheckResponse(LIST_CHECK) == FALSE)
- {
- m_strError = _T("Error occured during LIST.");
- return FALSE;
- }
- return TRUE;
- }
- ///<summary>
- /// Receive any specified mail
- ///</summary>
- BOOL CPopReceiveManager::CmdRetr(int nMsgNumber)
- {
- char szBuf[SEND_CMD_SIZE] = {0};
- sprintf_s(szBuf, SEND_CMD_SIZE, "RETR %drn", nMsgNumber);
- m_PopServer.Send(szBuf, (int)strlen(szBuf));
- if (CheckResponse(RETR_CHECK) == FALSE)
- {
- m_strError = _T("Error occured during RETR.");
- return FALSE;
- }
- return TRUE;
- }
- ///<summary>
- /// Delete a specified mail from the server
- ///</summary>
- BOOL CPopReceiveManager::CmdDele(int nMsgNumber)
- {
- char szBuf[SEND_CMD_SIZE] = {0};
- sprintf_s(szBuf, SEND_CMD_SIZE, "DELE %drn",nMsgNumber);
- m_PopServer.Send(szBuf, (int)strlen(szBuf));
- if (CheckResponse(DELETE_CHECK) == FALSE)
- {
- m_strError = _T("Error occured during DELE.");
- return FALSE;
- }
- return TRUE;
- }
- ///<summary>
- /// no action other than that the receiver send an OK reply
- ///</summary>
- BOOL CPopReceiveManager::CmdNoop()
- {
- char szBuf[SEND_CMD_SIZE] = {0};
- sprintf_s(szBuf, SEND_CMD_SIZE, "NOOP rn");
- m_PopServer.Send(szBuf, (int)strlen(szBuf));
- if (CheckResponse(NOOP_CHECK) == FALSE)
- {
- m_strError = _T("Error occured during NOOP.");
- return FALSE;
- }
- return TRUE;
- }
- ///<summary>
- /// change the mails marked as deleted to be unmarked
- ///</summary>
- BOOL CPopReceiveManager::CmdRset()
- {
- char szBuf[SEND_CMD_SIZE] = {0};
- sprintf_s(szBuf, SEND_CMD_SIZE, "RSET rn");
- m_PopServer.Send(szBuf, (int)strlen(szBuf));
- if (CheckResponse(RSET_CHECK) == FALSE)
- {
- m_strError = _T("Error occured during RSET.");
- return FALSE;
- }
- return TRUE;
- }
- ///<summary>
- /// to enter the UPDATE state
- ///</summary>
- BOOL CPopReceiveManager::CmdQuit()
- {
- char szBuf[SEND_CMD_SIZE] = {0};
- sprintf_s(szBuf, SEND_CMD_SIZE, "QUIT rn");
- m_PopServer.Send(szBuf, (int)strlen(szBuf));
- if (CheckResponse(QUIT_CHECK) == FALSE)
- {
- m_strError = _T("Error occured during QUIT.");
- return FALSE;
- }
- return TRUE;
- }
- ///<summary>
- /// get certain number of lines of the specified message's body
- ///</summary>
- BOOL CPopReceiveManager::CmdTop(int nMsgNumber, int nLength)
- {
- char szBuf[SEND_CMD_SIZE] = {0};
- sprintf_s(szBuf, SEND_CMD_SIZE, "TOP %d %drn", nMsgNumber, nLength);
- m_PopServer.Send(szBuf, (int)strlen(szBuf));
- if (CheckResponse(TOP_CHECK) == FALSE)
- {
- m_strError = _T("Error occured during TOP.");
- return FALSE;
- }
- return TRUE;
- }
- ///<summary>
- /// read the response from the network
- ///</summary>
- BOOL CPopReceiveManager::ReadResponse(LPSTR pszBuf, int nBufSize)
- {
- int nRecNum = 0;
- Sleep(SLEEP_INTERVAL);
- nRecNum = m_PopServer.Receive(pszBuf, nBufSize);
- if (SOCKET_ERROR == nRecNum)
- {
- m_strError = _T("Error reading from socket!");
- return FALSE;
- }
- return TRUE;
- }
- ///<summary>
- /// get the response and parse
- ///</summary>
- BOOL CPopReceiveManager::CheckResponse(int nResponseType)
- {
- char szBuf[RECV_BUFFER_SIZE] = {0};
- if (!ReadResponse(szBuf, RECV_BUFFER_SIZE))
- {
- return FALSE;
- }
- //check whether there is any error
- if (_strnicmp(szBuf, "-ERR", 4) == 0)
- {
- return FALSE;
- }
- //handle the responde of the command STAT
- if (STAT_CHECK == nResponseType)
- {
- if (ParseStatResponse(szBuf))
- {
- return TRUE;
- }
- else
- {
- return FALSE;
- }
- }
- //handle the responde of the command LIST
- if (LIST_CHECK == nResponseType)
- {
- if (ParseListResponse(szBuf))
- {
- return TRUE;
- }
- else
- {
- return FALSE;
- }
- }
- //handle the responde of the command RETR
- if (RETR_CHECK == nResponseType)
- {
- if (ParseRetrResponse(szBuf))
- {
- return TRUE;
- }
- else
- {
- return FALSE;
- }
- }
- //handle the responde of the command TOP
- if (TOP_CHECK == nResponseType)
- {
- if (ParseTopResponse(szBuf))
- {
- return TRUE;
- }
- else
- {
- return FALSE;
- }
- }
- return TRUE;
- }
- ///<summary>
- /// get the first char meaningful in the response
- ///</summary>
- LPCSTR CPopReceiveManager::GetFirstMeaningChar(LPCSTR pszData) const
- {
- while ((*pszData != 'n') && *pszData)
- {
- ++pszData;
- }
- //skip over the "n" onto the next line
- if (*pszData)
- {
- ++pszData;
- }
- return pszData;
- }
- ///<summary>
- /// check the response of STAT
- ///</summary>
- BOOL CPopReceiveManager::ParseStatResponse(LPCSTR szBuf)
- {
- BOOL bEmailNumber = TRUE;
- for (const char *p = szBuf; *p != ' '; p++)
- {//the possible response: +OK nn mm
- if (*p == 't' || *p == ' ')
- {
- if(bEmailNumber == TRUE)
- {
- m_nNumMail = atoi(p);
- bEmailNumber = FALSE;
- }
- else
- {
- m_nTotalSize = atoi(p);
- return TRUE;
- }
- }
- }
- return FALSE;
- }
- ///<summary>
- /// check the response of LIST
- ///</summary>
- BOOL CPopReceiveManager::ParseListResponse(LPCSTR szBuf)
- {
- const char* pszRes = GetFirstMeaningChar(szBuf);
- VERIFY(pszRes);
- m_SizeOfMsg.RemoveAll();
- for (; *pszRes != '.'; pszRes++)
- {
- if (*pszRes == 't' || *pszRes == ' ')
- {
- m_SizeOfMsg.Add(atoi(pszRes));
- }
- }
- return TRUE;
- }
- ///<summary>
- /// parse the response of RETR
- ///</summary>
- BOOL CPopReceiveManager::ParseRetrResponse(LPCSTR szBuf)
- {
- VERIFY(szBuf);
- m_strMsgContents = szBuf;
- //There is some information that the mail server may add, such as the return path if any error occurs
- int nPos = -1;
- nPos = m_strMsgContents.Find("rnDate:");
- if (nPos >= 0)
- {
- m_strMsgContents = m_strMsgContents.Right(m_strMsgContents.GetLength() - nPos);
- }
- return TRUE;
- }
- ///<summary>
- /// parse the response of TOP
- ///</summary>
- BOOL CPopReceiveManager::ParseTopResponse(LPCSTR szBuf)
- {
- const char* pszRes = GetFirstMeaningChar(szBuf);
- VERIFY(pszRes);
- //do sth to extract the useful information
- //.......
- return FALSE;
- }
- ///<summary>
- /// return the size of overall mails
- ///</summary>
- int CPopReceiveManager::GetTotalMailSize()
- {
- return m_nTotalSize;
- }
- ///<summary>
- /// set socket parameters
- ///</summary>
- BOOL CPopReceiveManager::SetNetParams()
- {
- //off TIME_WAIT
- struct linger zeroLinger;
- zeroLinger.l_onoff = 1;
- zeroLinger.l_linger = 0;
- if(!m_PopServer.SetSockOpt(SO_LINGER, (const char *)&zeroLinger
- ,sizeof(zeroLinger)))
- {
- m_strError = _T("Unable to off time_wait.");
- return FALSE;
- }
- //set receive timeout
- if(!m_PopServer.SetSockOpt(SO_RCVTIMEO, (const char *)&m_nRecvTimeout
- ,sizeof(m_nRecvTimeout)))
- {
- m_strError = _T("Unable to set receive timeout.");
- return FALSE;
- }
- //set send timeout
- if(!m_PopServer.SetSockOpt(SO_SNDTIMEO, (const char *)&m_nSendTimeout
- ,sizeof(m_nSendTimeout)))
- {
- m_strError = _T("Unable to set send timeout.");
- return FALSE;
- }
- return TRUE;
- }