www.pudn.com > NETINFO.rar > pop3.cpp
#include "pop3.h"
void OnPop3MessageHeader(void *pUserData, const char* from,
const char* to, const char* subject);
void OnPop3MessageEntityHeader(void *pUserData,
const char* mimeMainType, const char* mimeSubType,
const char* filename);
void OnPop3MessageEntityBody(void *pUserData, const BYTE* pData, DWORD length);
void OnPop3MessageEntityBodyEnd(void *pUserData);
const MESSAGE_DECODE_CALLBACKS g_fnPop3Funcs =
{OnPop3MessageHeader, OnPop3MessageEntityHeader, OnPop3MessageEntityBody, OnPop3MessageEntityBodyEnd};
CPop3Connection::CPop3Connection(const ETHERNET *ether, const IP*ip, NetInfo* pNi, const NETINFO_CALLBACKS *pFuncs, DWORD dwAttachData)
:CLineConnection(ether, ip, pNi, pFuncs, dwAttachData)
{
m_status = POP3_NORMAL;
m_pDecoder = NULL;
}
void CPop3Connection::ClearContext()
{
if( m_pDecoder )
{
delete m_pDecoder;
m_pDecoder = NULL;
}
m_status = POP3_NORMAL;
}
CPop3Connection::~CPop3Connection()
{
ClearContext();
}
void CPop3Connection::OnLine(int sender, int receiver, const char* line, int lineLen)
{
if( sender == m_connecter ) //client send command
{
char szCommand[MAX_EMAIL_LINE];
memcpy(szCommand, line, lineLen-2);
szCommand[lineLen-2] = 0;
m_cmdQueue.AddTail(szCommand);
if( m_pFuncs && m_pFuncs->OnPop3Command )
m_pFuncs->OnPop3Command(m_pNi, this, szCommand);
}
else //server sending reply or data
{
if( m_status == POP3_NORMAL )
{
//it's a real reply and command queue is not empty
if( ( memicmp(line, "+OK", 3) == 0 || memicmp(line, "+ERR", 4) == 0 )
&& !m_cmdQueue.IsEmpty() )
{
char szReply[MAX_EMAIL_LINE];
memcpy(szReply, line, lineLen-2);
szReply[lineLen-2] = 0;
CString cmd = m_cmdQueue.RemoveHead();
if( m_pFuncs && m_pFuncs->OnPop3Reply )
m_pFuncs->OnPop3Reply(m_pNi, this, cmd, szReply);
if( memicmp((const char*)cmd, "RETR", 4)==0
&& memicmp(line, "+OK", 3) == 0 )
{
m_status = POP3_RETR_DATA;
if( m_pDecoder ) delete m_pDecoder;
if( m_pFuncs && m_pFuncs->OnPop3MessageTransferBegin )
m_pFuncs->OnPop3MessageTransferBegin(m_pNi, this);
m_pDecoder = new CMessageDecoder(this, &g_fnPop3Funcs);
}
}
}
else if( m_status == POP3_RETR_DATA )//retrieve data
{
if( strcmp(line, ".\r\n") == 0 ) //end of message
{
ClearContext();
}
else //data
{
const char *begin = ( line[0] == '.' ? line + 1 : line );
int realLen = ( line[0] == '.' ? lineLen - 1 : lineLen );
if( m_pDecoder )
m_pDecoder->GetLine(begin, realLen);
}
}
}
}
void OnPop3MessageHeader(void *pUserData, const char* from,
const char* to, const char* subject)
{
CPop3Connection *pPop3 = (CPop3Connection*)pUserData;
if( pPop3 && pPop3->m_pFuncs && pPop3->m_pFuncs->OnPop3MessageHeader )
pPop3->m_pFuncs->OnPop3MessageHeader(pPop3->m_pNi, pPop3, from, to, subject);
}
void OnPop3MessageEntityHeader(void *pUserData,
const char* mimeMainType, const char* mimeSubType,
const char* filename)
{
CPop3Connection *pPop3 = (CPop3Connection*)pUserData;
if( pPop3 && pPop3->m_pFuncs && pPop3->m_pFuncs->OnPop3MessageEntityHeader )
pPop3->m_pFuncs->OnPop3MessageEntityHeader(pPop3->m_pNi, pPop3, mimeMainType, mimeSubType, filename);
}
void OnPop3MessageEntityBody(void *pUserData, const BYTE* pData, DWORD length)
{
CPop3Connection *pPop3 = (CPop3Connection*)pUserData;
if( pPop3 && pPop3->m_pFuncs && pPop3->m_pFuncs->OnPop3MessageEntityBody )
pPop3->m_pFuncs->OnPop3MessageEntityBody(pPop3->m_pNi, pPop3, pData, length);
}
void OnPop3MessageEntityBodyEnd(void *pUserData)
{
CPop3Connection *pPop3 = (CPop3Connection*)pUserData;
if( pPop3 && pPop3->m_pFuncs && pPop3->m_pFuncs->OnPop3MessageEntityBodyEnd )
pPop3->m_pFuncs->OnPop3MessageEntityBodyEnd(pPop3->m_pNi, pPop3);
}