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); 
}