www.pudn.com > NETINFO.rar > smtp.cpp
#include "smtp.h"
void OnSmtpMessageHeader(void *pUserData, const char* from,
const char* to, const char* subject);
void OnSmtpMessageEntityHeader(void *pUserData,
const char* mimeMainType, const char* mimeSubType,
const char* filename);
void OnSmtpMessageEntityBody(void *pUserData, const BYTE* pData, DWORD length);
void OnSmtpMessageEntityBodyEnd(void *pUserData);
const MESSAGE_DECODE_CALLBACKS g_fnSmtpFuncs =
{OnSmtpMessageHeader, OnSmtpMessageEntityHeader, OnSmtpMessageEntityBody, OnSmtpMessageEntityBodyEnd};
CSmtpConnection::CSmtpConnection(const ETHERNET *ether, const IP*ip, NetInfo* pNi, const NETINFO_CALLBACKS *pFuncs, DWORD dwAttachData)
:CLineConnection(ether, ip, pNi, pFuncs, dwAttachData)
{
m_status = SMTP_NORMAL;
m_pDecoder = NULL;
}
void CSmtpConnection::ClearContext()
{
if( m_pDecoder )
{
delete m_pDecoder;
m_pDecoder = NULL;
}
m_status = SMTP_NORMAL;
}
CSmtpConnection::~CSmtpConnection()
{
ClearContext();
}
void CSmtpConnection::OnLine(int sender, int receiver, const char* line, int lineLen)
{
if( sender == m_connecter ) //this is client sending command or data
{
if( m_status == SMTP_NORMAL ) //command
{
char szCommand[MAX_EMAIL_LINE];
memcpy(szCommand, line, lineLen-2);
szCommand[lineLen-2] = 0;
m_cmdQueue.AddTail(szCommand);
if( m_pFuncs && m_pFuncs->OnSmtpCommand )
m_pFuncs->OnSmtpCommand(m_pNi, this, szCommand);
}
else if( m_status == SMTP_DATA_OK )
{
if( strcmp(line, ".\r\n") == 0 ) //end of data
{
m_cmdQueue.AddTail("RLDT");
ClearContext();
if( m_pFuncs && m_pFuncs->OnSmtpMessageTransferEnd )
m_pFuncs->OnSmtpMessageTransferEnd(m_pNi, this);
}
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);
}
}
}
else //server send reply
{
//a real reply
if( isdigit(line[0]) && isdigit(line[1]) && isdigit(line[2]) && line[3] == ' ' )
{
if( !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->OnSmtpReply )
m_pFuncs->OnSmtpReply(m_pNi, this, cmd, szReply);
if( memicmp((const char*)cmd, "DATA", 4) ==0
&& line[0] == '3' )
{
m_status = SMTP_DATA_OK;
if( m_pDecoder ) delete m_pDecoder;
if( m_pFuncs && m_pFuncs->OnSmtpMessageTransferBegin )
m_pFuncs->OnSmtpMessageTransferBegin(m_pNi, this);
m_pDecoder = new CMessageDecoder(this, &g_fnSmtpFuncs);
}
else
m_status = SMTP_NORMAL;
}
}
}
}
void OnSmtpMessageHeader(void *pUserData, const char* from,
const char* to, const char* subject)
{
CSmtpConnection *pSmtp = (CSmtpConnection*)pUserData;
if( pSmtp && pSmtp->m_pFuncs && pSmtp->m_pFuncs->OnSmtpMessageHeader )
pSmtp->m_pFuncs->OnSmtpMessageHeader(pSmtp->m_pNi, pSmtp, from, to, subject);
}
void OnSmtpMessageEntityHeader(void *pUserData,
const char* mimeMainType, const char* mimeSubType,
const char* filename)
{
CSmtpConnection *pSmtp = (CSmtpConnection*)pUserData;
if( pSmtp && pSmtp->m_pFuncs && pSmtp->m_pFuncs->OnSmtpMessageEntityHeader )
pSmtp->m_pFuncs->OnSmtpMessageEntityHeader(pSmtp->m_pNi, pSmtp, mimeMainType, mimeSubType, filename);
}
void OnSmtpMessageEntityBody(void *pUserData, const BYTE* pData, DWORD length)
{
CSmtpConnection *pSmtp = (CSmtpConnection*)pUserData;
if( pSmtp && pSmtp->m_pFuncs && pSmtp->m_pFuncs->OnSmtpMessageEntityBody )
pSmtp->m_pFuncs->OnSmtpMessageEntityBody(pSmtp->m_pNi, pSmtp, pData, length);
}
void OnSmtpMessageEntityBodyEnd(void *pUserData)
{
CSmtpConnection *pSmtp = (CSmtpConnection*)pUserData;
if( pSmtp && pSmtp->m_pFuncs && pSmtp->m_pFuncs->OnSmtpMessageEntityBodyEnd )
pSmtp->m_pFuncs->OnSmtpMessageEntityBodyEnd(pSmtp->m_pNi, pSmtp);
}