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