www.pudn.com > ZJMailer > ZJMailAgent.cpp


// ZJMailAgent.cpp: implementation of the CZJMailAgent class. 
// 
////////////////////////////////////////////////////////////////////// 
// CZJMailAgent class Implementation files 
// 
// Author: ÕÅ ½Ü (codez) 
// 
// Finished At Oct 2nd, 2002. 
// 
//============================================================== 
// note: 
//   The CZJMailAgent class is made by codez, 
// you can modify and/or distribute this file,  
// but do not remove this header please. 
// 
// This file is provided "as is" with no expressed or implied 
// warranty. 
//============================================================== 
//  
// If there is any bugs, please let me know. 
// Thanks! 
// 
// 
// Contact me: 
// 
// Email: jay_zephyr2002@yahoo.com.cn 
// Home Page: http://www.xlrj.com/codez 
//============================================================== 
 
#include "stdafx.h" 
#include "ZJMailAgent.h" 
#include "TextBuffer.h" 
 
#ifdef _DEBUG 
#undef THIS_FILE 
static char THIS_FILE[]=__FILE__; 
#define new DEBUG_NEW 
#endif 
 
#define	MAX_LINE_COUNT	76 
 
////////////////////////////////////////////////////////////////////// 
// Construction/Destruction 
////////////////////////////////////////////////////////////////////// 
 
CZJMailAgent::CZJMailAgent() 
{ 
	m_authLogin = false; 
} 
 
CZJMailAgent::~CZJMailAgent() 
{ 
 
} 
 
bool CZJMailAgent::Connect(LPCTSTR szHost, int nPort) 
{ 
	TCHAR szBuffer[BUFFER_SIZE]; 
 
	if (m_mail.IsConnected()) 
		m_mail.Close(); 
 
	if (m_mail.Create()==false) 
	{ 
		TRACE0("CZJSocket create error!\n"); 
		return false; 
	} 
 
	if (m_mail.Connect((LPTSTR)szHost, nPort)==false) 
	{ 
		TRACE("CZJSocket connect error!\n"); 
		return false; 
	} 
 
	if (m_mail.Receive(szBuffer, BUFFER_SIZE)==false) 
	{ 
		TRACE0("Received error!\n"); 
		return false; 
	} 
 
	if (m_mail.GetRetCode(szBuffer)!=220) 
	{ 
		TRACE0("Invalidate Smtp server!\n"); 
		return false; 
	} 
 
	return true; 
} 
 
bool CZJMailAgent::GetAuthLogin() const 
{ 
	return m_authLogin; 
} 
 
void CZJMailAgent::SetAuthLoginParam(CString &name, CString &pass) 
{ 
	if (name.IsEmpty() || pass.IsEmpty()) 
	{ 
		return; 
	} 
 
	m_loginName = name; 
	m_loginPass = pass; 
} 
 
void CZJMailAgent::SetAuthLogin(bool login) 
{ 
	m_authLogin = login; 
} 
 
bool CZJMailAgent::Hello(CString & who) 
{ 
	CString tmp; 
//	char szBuffer[BUFFER_SIZE]; 
 
	if (m_authLogin) 
	{ 
		tmp = _T("EHLO "); 
	} 
	else 
	{ 
		tmp = _T("HELO "); 
	} 
 
	tmp = tmp+who+_T("\r\n"); 
/* 
	if (m_mail.Send(LPCTSTR(tmp), tmp.GetLength())==false) 
	{ 
		TRACE0("send hello error!\n"); 
		return false; 
	} 
 
	if (m_mail.Receive(szBuffer, BUFFER_SIZE)==false) 
	{ 
		TRACE0("recv hello error!\n"); 
		return false; 
	} 
 
	if (m_mail.GetRetCode(szBuffer)!=250) 
	{ 
		TRACE0("Hello Error!\n"); 
		return false; 
	} 
*/ 
	if (m_mail.SendRecv((LPTSTR)(LPCTSTR(tmp)), tmp.GetLength())!=250) 
		return false; 
 
	// begin to auth login 
	if (m_authLogin) 
	{ 
		tmp = _T("AUTH LOGIN\r\n"); 
 
		if (m_mail.SendRecv((LPTSTR)(LPCTSTR(tmp)), tmp.GetLength())!=334) 
			return false; 
 
		if (SendBase64Msg(m_loginName)!=334) 
			return false; 
 
		if (SendBase64Msg(m_loginPass)!=235) 
			return false; 
	} 
 
	return true; 
} 
 
void CZJMailAgent::DisConnect() 
{ 
	m_mail.Close(); 
} 
 
int CZJMailAgent::SendBase64Msg(CString &msg) 
{ 
	TCHAR szBuffer[BUFFER_SIZE]; 
	CBase64Buffer buf; 
 
	buf.SetBuffer(LPTSTR(LPCTSTR(msg))); 
	buf.Encode(); 
 
	if (m_mail.Send(buf.GetBuffer(), buf.GetBufferLength())==false) 
		return -1; 
 
	m_mail.SendCRLF(); 
 
	if (m_mail.Receive(szBuffer, BUFFER_SIZE)==false) 
		return -1; 
 
	return m_mail.GetRetCode(szBuffer); 
} 
 
bool CZJMailAgent::SendMail(CZJMessage &msg) 
{ 
	// check connection 
	if (m_mail.IsConnected()==false) 
		return false;	// invalid connection 
 
	if (msg.GetTo().IsEmpty()) 
		return false;	// no send destination 
 
	// begin to send data! 
	CString tmp, tmp1; 
 
	// MAIL FROM: 
	if (msg.GetFromEmail().IsEmpty()) 
		tmp = _T("MAIL FROM:<>\r\n"); 
	else 
		tmp.Format(_T("MAIL FROM:<%s>\r\n"), 
			LPCTSTR(msg.GetFromEmail())); 
 
	if (m_mail.SendRecv( (LPTSTR)(LPCTSTR(tmp)), tmp.GetLength())!=250) 
		return false; 
 
	// RCPT TO: 
	// Begin loop to [RCPT TO] command 
	tmp.Format(_T("RCPT TO:<%s>\r\n"), 
		LPCTSTR(msg.GetTo())); 
 
	if (m_mail.SendRecv( (LPTSTR)(LPCTSTR(tmp)), tmp.GetLength())!=250) 
		return false; 
 
	// End loop to [RCPT TO] command 
 
	// DATA start 
	tmp.Format(_T("DATA\r\n")); 
 
	if (m_mail.SendRecv( (LPTSTR)(LPCTSTR(tmp)), tmp.GetLength())!=354) 
		return false; 
 
	// header 
	tmp = msg.GetMailHeader(); 
	if (m_mail.Send( (LPTSTR)(LPCTSTR(tmp)), tmp.GetLength())==false) 
		return false; 
 
	// Subject 
	tmp = _T("Subject: "); 
	 
	if (m_mail.Send( (LPTSTR)(LPCTSTR(tmp)), tmp.GetLength())==false) 
		return false; 
 
	tmp = msg.GetSubject(); 
 
	if (msg.NeedEncode(tmp)) 
	{ 
		// Encode 
		CBase64Buffer buf; 
 
		if (buf.SetBuffer((LPTSTR)(LPCTSTR(tmp)))==false) 
			return false; 
 
		if (buf.Encode()==false) 
			return false; 
 
		int len = buf.GetBufferLength(); 
		LPSTR p = buf.GetBuffer(); 
 
		CString sHead, sTail = _T("?=");; 
				 
		sHead.Format(_T("=?%s?B?"), LPCTSTR(msg.GetCharSet())); 
/* 
		int SUBJECT_LINE_COUNT; 
		SUBJECT_LINE_COUNT = MAX_LINE_COUNT - sTail.GetLength() 
			- sHead.GetLength(); 
 
		while(len>0) 
		{ 
			if (m_mail.Send((LPTSTR)(LPCTSTR(sHead)), sHead.GetLength())==false) 
				return false; 
 
			if (len>SUBJECT_LINE_COUNT) 
			{ 
				if (m_mail.Send(p, SUBJECT_LINE_COUNT)==false) 
					return false; 
 
				p += SUBJECT_LINE_COUNT; 
			} 
			else 
			{ 
				if (m_mail.Send(p, len)==false) 
					return false; 
			} 
 
			if (m_mail.Send((LPTSTR)(LPCTSTR(sTail)), sTail.GetLength())==false) 
				return false; 
 
			if (m_mail.SendCRLF()==false) 
				return false; 
 
			len -= SUBJECT_LINE_COUNT; 
 
		} 
*/ 
 
		if (m_mail.Send((LPTSTR)(LPCTSTR(sHead)), sHead.GetLength())==false) 
			return false; 
 
		if (m_mail.Send(buf.GetBuffer(), buf.GetBufferLength())==false) 
			return false; 
 
		if (m_mail.Send((LPTSTR)(LPCTSTR(sTail)), sTail.GetLength())==false) 
			return false;		 
 
		if (m_mail.SendCRLF()==false) 
			return false; 
	} 
	else 
	{ 
		if (m_mail.Send((LPTSTR)(LPCTSTR(tmp)), tmp.GetLength())==false) 
			return false; 
 
		if (m_mail.SendCRLF()==false) 
			return false; 
	} 
 
	// X-mailer & Mime-Version 
	tmp.Format(_T("X-mailer: %s\r\nMime-Version: 1.0\r\n"), 
		LPCTSTR(msg.GetXMailer())); 
 
	if (m_mail.Send( (LPTSTR)(LPCTSTR(tmp)), tmp.GetLength())==false) 
		return false; 
 
	// write others content 
	if (SendMailContent(msg)==false) 
		return false; 
 
	// End Msg 
	tmp = _T("\r\n.\r\n"); 
 
	if (m_mail.SendRecv((LPTSTR)(LPCTSTR(tmp)), tmp.GetLength())!=250) 
		return false; 
 
	tmp = _T("QUIT\r\n"); 
	if (m_mail.SendRecv((LPTSTR)(LPCTSTR(tmp)), tmp.GetLength())!=221) 
		return false; 
 
	m_mail.Close(); 
		 
	return true; 
} 
 
bool CZJMailAgent::SendMailContent(CZJMessage &msg) 
{ 
	bool bAttachment = msg.m_attach.GetCount() ? true:false; 
 
//	USES_CONVERSION;	 
	CString tmp, tmp1; 
 
	if (bAttachment) 
	{ 
		// Contain the Attachment 
		// no implemetation 
		CString sLogoText(_T("\r\nA multi-part message in MIME format, made by codez!\r\n")); 
		CString sCRLF(_T("\r\n")); 
		CString sPreHeader(_T("--")); 
 
		if (msg.GetBoundary().GetLength()==0) 
			return false; 
 
		tmp.Format(_T("Content-Type: multipart/mixed; boundary=\"%s\"\r\n"), 
			LPCTSTR(msg.GetBoundary())); 
 
		tmp += sLogoText; 
 
		// Insert a boundary 
		tmp += sCRLF; 
		tmp += sPreHeader; 
		tmp += msg.GetBoundary(); 
		tmp += sCRLF; 
		 
		if (m_mail.Send((LPTSTR)(LPCTSTR(tmp)), tmp.GetLength())==false) 
			return false; 
 
		// body content and text 
		if (SendMailText(msg)==false) 
			return false; 
 
		for (int i=0;i0) 
		{ 
			if (len>MAX_LINE_COUNT) 
			{ 
				if (m_mail.Send(p, MAX_LINE_COUNT)==false) 
					return false; 
 
				p += MAX_LINE_COUNT; 
			} 
			else 
			{ 
				if (m_mail.Send(p, len)==false) 
					return false; 
			} 
			 
			if (m_mail.SendCRLF()==false) 
				return false; 
 
			len -= MAX_LINE_COUNT; 
		} 
	} 
	else 
	{ 
		if (m_mail.Send(buf.GetBuffer(), buf.GetBufferLength())==false) 
			return false; 
	} 
 
	return true; 
} 
 
bool CZJMailAgent::SendAttachment(CString & path,  
								   CString & name,  
								   CString & boundary) 
{ 
	CString sCRLF(_T("\r\n")); 
	CString sPreHeader(_T("--")); 
 
	CString tmp, tmp1; 
 
	tmp = sCRLF; 
	tmp += sPreHeader; 
	tmp += boundary; 
	tmp += sCRLF; 
 
	tmp1.Format(_T("Content-Type: application/octet-stream; name=\"%s\"\r\nContent-Transfer-Encoding: base64\r\nContent-Disposition: attachment; filename=\"%s\"\r\n"), 
		LPCTSTR(name), LPCTSTR(name)); 
 
	tmp += tmp1; 
 
	if (m_mail.Send((LPTSTR)(LPCTSTR(tmp)), tmp.GetLength())==false) 
		return false; 
 
	if (m_mail.SendCRLF()==false) 
		return false; 
 
	CBase64Buffer buf; 
 
	CFile inFile; 
	CFileException ex; 
 
	if (inFile.Open(LPCTSTR(path), CFile::modeRead | CFile::shareDenyWrite, &ex)==FALSE) 
	{ 
		return false; 
	} 
 
	int size = inFile.GetLength(); 
	if (buf.AllocBuffer(size)==false) 
		return false;	// not enough buffer 
 
	if (inFile.ReadHuge(buf.GetBuffer(), size)==0) 
		return false;	// no read 
 
	inFile.Close(); 
 
	if (buf.Encode()==false) 
		return false; 
 
	size = buf.GetBufferLength(); 
	LPSTR p = buf.GetBuffer(); 
 
	while(size>0) 
	{ 
		if (size>MAX_LINE_COUNT) 
		{ 
			if (m_mail.Send(p, MAX_LINE_COUNT)==false) 
				return false; 
 
			p += MAX_LINE_COUNT; 
		} 
		else 
		{ 
			if (m_mail.Send(p, size)==false) 
				return false; 
		} 
			 
		if (m_mail.SendCRLF()==false) 
			return false; 
 
		size -= MAX_LINE_COUNT; 
	} 
 
	return true; 
}