/*
Module : SMTP.CPP
Purpose: Implementation for a MFC class encapsulation of the SMTP protocol
Created: PJN / 22-05-1998
History: PJN / 15-06-1998 1) Fixed the case where a single dot occurs on its own
in the body of a message
2) Class now supports Reply-To Header Field
3) Class now supports file attachments
PJN / 18-06-1998 1) Fixed a memory overwrite problem which was occurring
with the buffer used for encoding base64 attachments
PJN / 27-06-1998 1) The case where a line begins with a "." but contains
other text is now also catered for. See RFC821, Section 4.5.2
for further details.
2) m_sBody in CSMTPMessage has now been made protected.
Client applications now should call AddBody instead. This
ensures that FixSingleDot is only called once even if the
same message is sent a number of times.
3) Fixed a number of problems with how the MIME boundaries
were defined and sent.
4) Got rid of an unreferenced formal parameter
compiler warning when doing a release build
PJN / 11-09-1998 1) VC 5 project file is now provided
2) Attachment array which the message class contains now uses
references instead of pointers.
3) Now uses Sleep(0) to yield our time slice instead of Sleep(100),
this is the preferred way of writting polling style code in Win32
without serverly impacting performance.
4) All Trace statements now display the value as returned from
GetLastError
5) A number of extra asserts have been added
6) A AddMultipleRecipients function has been added which supports added a
number of recipients at one time from a single string
7) Extra trace statements have been added to help in debugging
PJN / 12-09-98 1) Removed a couple of unreferenced variable compiler warnings when code
was compiled with Visual C++ 6.0
2) Fixed a major bug which was causing an ASSERT when the CSMTPAttachment
destructor was being called in the InitInstance of the sample app.
This was inadvertingly introduced for the 1.2 release. The fix is to revert
fix 2) as done on 11-09-1998. This will also help to reduce the number of
attachment images kept in memory at one time.
Copyright (c) 1998 by PJ Naughter.
All rights reserved.
*/
//////////////// Includes ////////////////////////////////////////////
#include "stdafx.h"
#include "smtp.h"
//////////////// Macros / Locals /////////////////////////////////////
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
char CSMTPAttachment::m_base64tab[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz0123456789+/";
#define BASE64_MAXLINE 76
#define EOL "\r\n"
//////////////// Implementation //////////////////////////////////////
CSMTPSocket::CSMTPSocket()
{
m_hSocket = INVALID_SOCKET; //default to an invalid scoket descriptor
}
CSMTPSocket::~CSMTPSocket()
{
Close();
}
BOOL CSMTPSocket::Create()
{
m_hSocket = socket(AF_INET, SOCK_STREAM, 0);
return (m_hSocket != INVALID_SOCKET);
}
BOOL CSMTPSocket::Connect(LPCTSTR pszHostAddress, int nPort)
{
//For correct operation of the T2A macro, see MFC Tech Note 59
USES_CONVERSION;
//must have been created first
ASSERT(m_hSocket != INVALID_SOCKET);
LPSTR lpszAscii = T2A((LPTSTR)pszHostAddress);
//Determine if the address is in dotted notation
SOCKADDR_IN sockAddr;
ZeroMemory(&sockAddr, sizeof(sockAddr));
sockAddr.sin_family = AF_INET;
sockAddr.sin_port = htons((u_short)nPort);
sockAddr.sin_addr.s_addr = inet_addr(lpszAscii);
//If the address is not dotted notation, then do a DNS
//lookup of it.
if (sockAddr.sin_addr.s_addr == INADDR_NONE)
{
LPHOSTENT lphost;
lphost = gethostbyname(lpszAscii);
if (lphost != NULL)
sockAddr.sin_addr.s_addr = ((LPIN_ADDR)lphost->h_addr)->s_addr;
else
{
WSASetLastError(WSAEINVAL);
return FALSE;
}
}
//Call the protected version which takes an address
//in the form of a standard C style struct.
return Connect((SOCKADDR*)&sockAddr, sizeof(sockAddr));
}
BOOL CSMTPSocket::Connect(const SOCKADDR* lpSockAddr, int nSockAddrLen)
{
return (connect(m_hSocket, lpSockAddr, nSockAddrLen) != SOCKET_ERROR);
}
BOOL CSMTPSocket::Send(LPCSTR pszBuf, int nBuf)
{
//must have been created first
ASSERT(m_hSocket != INVALID_SOCKET);
return (send(m_hSocket, pszBuf, nBuf, 0) != SOCKET_ERROR);
}
int CSMTPSocket::Receive(LPSTR pszBuf, int nBuf)
{
//must have been created first
ASSERT(m_hSocket != INVALID_SOCKET);
return recv(m_hSocket, pszBuf, nBuf, 0);
}
void CSMTPSocket::Close()
{
if (m_hSocket != INVALID_SOCKET)
{
VERIFY(SOCKET_ERROR != closesocket(m_hSocket));
m_hSocket = INVALID_SOCKET;
}
}
BOOL CSMTPSocket::IsReadible(BOOL& bReadible)
{
timeval timeout = {0, 0};
fd_set fds;
FD_ZERO(&fds);
FD_SET(m_hSocket, &fds);
int nStatus = select(0, &fds, NULL, NULL, &timeout);
if (nStatus == SOCKET_ERROR)
{
return FALSE;
}
else
{
bReadible = !(nStatus == 0);
return TRUE;
}
}
CSMTPAddress::CSMTPAddress(const CString& sAddress) : m_sEmailAddress(sAddress)
{
ASSERT(m_sEmailAddress.GetLength()); //An empty address is not allowed
}
CSMTPAddress::CSMTPAddress(const CString& sFriendly, const CString& sAddress) :
m_sFriendlyName(sFriendly), m_sEmailAddress(sAddress)
{
ASSERT(m_sEmailAddress.GetLength()); //An empty address is not allowed
}
CSMTPAddress& CSMTPAddress::operator=(const CSMTPAddress& r)
{
m_sFriendlyName = r.m_sFriendlyName;
m_sEmailAddress = r.m_sEmailAddress;
return *this;
}
CString CSMTPAddress::GetRegularFormat() const
{
ASSERT(m_sEmailAddress.GetLength()); //Email Address must be valid
CString sAddress;
if (m_sFriendlyName.IsEmpty())
sAddress = m_sEmailAddress; //Just transfer the address across directly
else
sAddress.Format(_T("%s <%s>"), m_sFriendlyName, m_sEmailAddress);
return sAddress;
}
CSMTPAttachment::CSMTPAttachment()
{
m_pszEncoded = NULL;
m_nEncodedSize = 0;
}
CSMTPAttachment::~CSMTPAttachment()
{
//free up any memory we allocated
if (m_pszEncoded)
{
delete [] m_pszEncoded;
m_pszEncoded = NULL;
}
}
BOOL CSMTPAttachment::Attach(const CString& sFilename)
{
ASSERT(sFilename.GetLength()); //Empty Filename !
//free up any memory we previously allocated
if (m_pszEncoded)
{
delete [] m_pszEncoded;
m_pszEncoded = NULL;
}
//determine the file size
CFileStatus fs;
if (!CFile::GetStatus(sFilename, fs))
{
TRACE(_T("Failed to get the status for file %s, probably does not exist\n"), sFilename);
return FALSE;
}
//open up the file for reading in
CFile infile;
if (!infile.Open(sFilename, CFile::modeRead | CFile::shareDenyWrite))
{
TRACE(_T("Failed to open file to be attached\n"));
return FALSE;
}
//read in the contents of the input file
char* pszIn = new char[fs.m_size];
infile.Read(pszIn, fs.m_size);
//allocate the encoded buffer
int
支持SMTP的MFC类CSMTPConnection
5星 · 超过95%的资源 需积分: 50 174 浏览量
2002-08-14
00:00:00
上传
评论 5
收藏 20KB ZIP 举报
普通网友
- 粉丝: 882
- 资源: 2万+
最新资源
- 1_提高高温超导体的临界温度的方法_pdf_1629817512307_9.jpg
- 用户故事示例导入模板(官网示例)
- 1_提高高温超导体的临界温度的方法_pdf_1629817510190_0.jpg
- Java实现计数排序算法(源代码)
- 这个 ide98 是适合老式机器上用到的一个补充文件,文件的过程代表过程的文件这个 ide98 是适合老式机器上用到的一个补充文
- 866164937784007CarLife3.0车机修改版支持无线和方控.apk
- 天津理工大学-操作系统实验3:磁盘调度算法的实现.doc
- 天津理工大学数据库期末复习试题一.doc
- 花农科技的驱动整合,ide98,这个工具可以用来修改计算机,修改后的计算机会更好用的,多合一,很好用,很实用
- 天猫电子商务案例分析-PPT.ppt
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
- 1
- 2
前往页