Original Post
Can someone help me out, and just take a quick look at the code below
before I copy and paste it in my compiler.
I plan to fully study the code, but I got it from a web-site, and
I am worried it might have some viral code.
It''s about C++ and SMTP. It''s contains header, and cpp file.
Thanks.
/* Here is the header file... */
/*\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
\ SendEmail.h, Declaration for SendEmail class and SendEmailSimple function
\
/ Version: 1.0, 2002-02-01: created
\
/ Author: David Maisonave (david@axter.com)
\ http://www.axter.com
/ Top ten expert at the Expert Exchange
\ http://www.experts-exchange.com/Programming/Programming_Languages/Cplusplus/
/
\
/ Please send comments and bugfixes to the above email address.
\
/ This code is provided AS IS, you use it at your own risk!
\ You may use it for whatever you want.
/
\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/
/*
For example usage of the SendEmail class, see the bottom of the SendEmail.cpp file
Example usuage for SendEmailSimple function:
int main(int , char*)
{
const char* Hostname = "axter_x.com";
const char* UserID = "axter_x";
const char* To = "maisonave@axter_x.com";
const char* Subject = "This is a test email";
const char* Body = "Test body";
const char* UserPassword = "abc123";
SendEmailSimple(Hostname, UserID, To, Subject, Body, UserPassword);
return 0;
}
*/
#ifndef SENDEMAIL_HEADER_GAURD
#define SENDEMAIL_HEADER_GAURD
#if defined(WIN32) || defined(__WIN32__)
//For VC++ ******************************
#ifdef _MSC_VER
#include <afxsock.h>
#pragma warning(disable:4786)
#endif //_MSC_VER
//For Borland C++ ******************************
#ifdef __BORLANDC__
#include <winsock2.h>
#pragma option -x
#endif //__BORLANDC__
//For GNU C++ ******************************
#ifdef __GNUC__
#include <winsock.h>
#endif //__GNUC__
//For Unix and Linux ******************************
#else //defined(WIN32) || defined(__WIN32__)
typedef unsigned int SOCKET;
#endif //defined(WIN32) || defined(__WIN32__)
#include <string>
#include <vector>
#include <fstream>
#include <list>
#include <time.h>
#include <ctype.h>
#if defined(__GNUC__) && __GNUC__ < 3 && __GNUC_MINOR__ < 96
#include <strstream>
class StrngStream
{
public:
StrngStream():m_stream(new std::ostrstream){}
~StrngStream(){delete m_stream;}
StrngStream& operator<<(const char* Src)
{
*m_stream << Src;
return *this;
}
StrngStream& operator<<(const std::string &Src)
{
*m_stream << Src.c_str();
return *this;
}
std::string str() const
{
return std::string(m_stream->str(), m_stream->str()+m_stream->pcount());
}
void str(const char *Src)
{
if (Src)
{
delete m_stream;
m_stream = new std::ostrstream;
}
}
private:
std::ostrstream *m_stream;
};
#else //defined(__GNUC__) && __GNUC__ < 3 && __GNUC_MINOR__ < 96
#include <sstream>
typedef std::ostringstream StrngStream;
#endif //defined(__GNUC__) && __GNUC__ < 3 && __GNUC_MINOR__ < 96
class SendEmail
{//SendEmail by David Maisonave (david@axter.com)
public:
enum {SMTP_OUTGOING_MAIL_PORT = 25, BASE64_MAXLINE = 76, MAX_LINE_SIZE = 4094, AUTHENTICATION_PORT = 113};
enum LoginMethod{LOGIN_AUTH_METHOD, LOGIN_PLAIN_METHOD/*, LOGIN_CRAM_MD5_METHOD*/};
SendEmail(
std::string EmailSenderHostName,
std::string Auth_UserID,
std::string Auth_Password = "",
std::string Sender = "",
std::string ReplyToAddr = "",
LoginMethod LoginMethod_ = LOGIN_AUTH_METHOD,
std::string X_Mailer = "X-Mailer: SendEmail By David Maisonave\r\n",
std::string X_Phone = "",
std::string EmailAddrSeperator = ", ");
~SendEmail();
std::string operator()(
const std::list &To,
const std::string &Subject,
const std::string &Body,
const std::list *CC_List = 0,
const std::list *BCC_List = 0,
const std::list *AttachmentPath_List = 0,
const std::string *MessageID = 0);
std::string operator()(
const std::string &To,
const std::string &Subject,
const std::string &Body,
const std::list *CC_List = 0,
const std::list *BCC_List = 0,
const std::list *AttachmentPath_List = 0,
const std::string *MessageID = 0);
std::string Mail(
const std::list &To,
const std::string &Subject,
const std::string &Body,
const std::list &CC_List ,
const std::list &BCC_List ,
const std::list *AttachmentPath_List /* = 0 */,
const std::string *MessageID = 0);
std::string Mail(
const std::list &To,
const std::string &Subject,
const std::string &Body,
const std::list *CC_List = 0,
const std::list *BCC_List = 0,
const std::list *AttachmentPath_List = 0,
const std::string *MessageID = 0);
std::string Mail(
const std::string &To,
const std::string &Subject,
const std::string &Body,
const std::list *CC_List = 0,
const std::list *BCC_List = 0,
const std::list *AttachmentPath_List = 0,
const std::string *MessageID = 0);
void DoLogin(void);
static const char* NO_ERRORS;
const std::vector &RecentErrorLog
private:
std::list* StrLstToELst(const std::list *Src, std::list &Dest);
enum{TO_BLOCK, CC_BLOCK, BCC_BLOCK};
std::string Mail(
const std::string &RCPT_To,
const std::list &To,
const std::string &Subject,
const std::string &Body,
const std::list &CC_List,
const std::list *AttachmentPath_List,
const std::string &MessageID);
std::vector m_RecentErrorLog;
LoginMethod m_LoginMethod;
std::string m_EmailSenderHostName;
std::string m_Sender;
std::string m_ReplyToAddr;
std::string m_Auth_UserID;
std::string m_Auth_Password;
std::string m_EmailAddrSeperator;
SOCKET m_socket;
bool m_InitiateGood;
char m_EmailBuffer[MAX_LINE_SIZE + 1];
const std::string m_X_Mailer;
const std::string m_X_Phone;
int m_UniqueContentID;
bool m_UseReplyToAddr_ForMailFrom;
std::string ReturnValueFromReceive;
static const char* m_base64Table;
static const char* CHK_220_REPLY;
static const char* CHK_221_REPLY;
static const char* CHK_235_REPLY;
static const char* CHK_250_REPLY;
static const char* CHK_334_REPLY;
static const char* CHK_354_REPLY;
static const char* EMAIL_ADDR_DIV_CHR;
static const std::string CRLF_SET;
bool SendStr(const StrngStream &Src);
bool SendStr(const char* Buffer);
bool VerifyReply(const char* szReplyString);
bool Receive(char* szBuffer, int nLenMax, int nFlags, const char* szReplyString);
bool Send(const char *szBuffer, size_t nLen);
bool Encode64File(const std::string &FileName);
std::string Encode64String(const std::string &Src);
char Encode64Byte(unsigned char uc);
static std::string EmailAddrFormat(const std::string &Src);
const char* Encode64(const std::vector & vBytes, std::string *Dest = NULL, bool EndWithCR = false);
};
bool SendEmailSimple(const char* HostName, const char* UserID, const char* To, const char* Subject, const char* Body, const char* UserPassword = NULL, const char* FileName_Attach = NULL);
#endif //!SENDEMAIL_HEADER_GAURD
/* Okay here is the cpp file */
/*\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
\ SendEmail.cpp, Declaration for SendEmail class and SendEmailSimple function
\
/ Version: 1.0, 2002-02-01: created
\
/ Author: David Maisonave (david@axter.com)
\ http://www.axter.com
/ Top ten expert at the Expert Exchange
\ http://www.experts-exchange.com/Programming/Programming_Languages/Cplusplus/
/
\
/ Please send comments and bugfixes to the above email address.
\
/ This code is provided AS IS, you use it at your own risk!
\ You may use it for whatever you want.
/ Specs for SMTP can be found via the following links:
\ http://www.ietf.org/rfc/rfc2821.txt
/ http://www.ietf.org/rfc/rfc2822.txt
\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/
#include "SendEmail.h"
const char* SendEmail::NO_ERRORS = "OK";
const char* SendEmail::CHK_220_REPLY = "220";
const char* SendEmail::CHK_221_REPLY = "221";
const char* SendEmail::CHK_235_REPLY = "235";
const char* SendEmail::CHK_250_REPLY = "250";
const char* SendEmail::CHK_334_REPLY = "334";
const char* SendEmail::CHK_354_REPLY = "354";
const char* SendEmail::EMAIL_ADDR_DIV_CHR = ",";
const std::string SendEmail::CRLF_SET = "\r\n";
const char* SendEmail::m_base64Table =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????";
SendEmail::SendEmail(
std::string EmailSenderHostName,
std::string Auth_UserID,
std::string Auth_Password /* = "" */,
std::string Sender /* = "" */,
std::string ReplyToAddr /* = "" */,
LoginMethod LoginMethod_ /* = LOGIN_AUTH_METHOD */,
std::string X_Mailer /* = "X-Mailer: SendEmail By David Maisonave\r\n" */,
std::string X_Phone /* = "" */,
std::string EmailAddrSeperator /* = ", " */
)
: m_EmailSenderHostName(EmailSenderHostName), m_Auth_UserID(Auth_UserID), m_Auth_Password(Auth_Password),
m_Sender(Sender), m_ReplyToAddr(ReplyToAddr),
m_LoginMethod(LoginMethod_),
m_X_Mailer(X_Mailer), m_X_Phone(X_Phone), m_EmailAddrSeperator(EmailAddrSeperator),
m_socket(0), m_InitiateGood(true),m_UniqueContentID(0), RecentErrorLog(m_RecentErrorLog)
{
#if defined(WIN32) || defined(__WIN32__)
WORD wVersion = MAKEWORD( 1, 1 );
WSADATA wsaData;
if (WSAStartup(wVersion, &wsaData)) m_InitiateGood=false;
else m_InitiateGood = true;
#endif //defined(WIN32) || defined(__WIN32__)
}
SendEmail::~SendEmail()
{
#if defined(WIN32) || defined(__WIN32__)
WSACleanup();
#endif //defined(WIN32) || defined(__WIN32__)
}
std::string SendEmail::EmailAddrFormat(const std::string &Src)
{
if (Src.find("<") == std::string::npos)
{
return std::string("<") + Src + std::string(">");
}
return Src;
}
void SendEmail::DoLogin(void)
{
StrngStream StrStm;
if (m_Auth_Password.size())
{
// send EHLO message
StrStm << "EHLO " << m_EmailSenderHostName << CRLF_SET << std::ends;
if (!SendStr(StrStm)) throw("Error: Failed to send EHLO");
if (!VerifyReply(CHK_250_REPLY )) throw("Error: Failed to Recv 250 after sending EHLO");
StrStm.str("");
// Send Auth Login
switch(m_LoginMethod)
{
case LOGIN_AUTH_METHOD:
StrStm << "AUTH LOGIN" << CRLF_SET;
break;
case LOGIN_PLAIN_METHOD:
StrStm << "AUTH LOGIN PLAIN" << CRLF_SET;
break;
// case LOGIN_CRAM_MD5_METHOD: //Missing implementation code for CRAM-MD5 Login
// StrStm << "AUTH CRAM-MD5" << CRLF_SET;
// break;
}
if (!SendStr(StrStm)) throw("Error: Failed to send AUTH LOGIN");
if (!VerifyReply(CHK_334_REPLY ))
{
throw("Error: Failed to Recv 334 after sending AUTH LOGIN");
}
StrStm.str("");
// Send AuthUserID
StrStm << ((m_LoginMethod == LOGIN_AUTH_METHOD)?Encode64String(m_Auth_UserID).c_str():m_Auth_UserID.c_str()) << CRLF_SET;
if (!SendStr(StrStm)) throw("Error: Failed to send m_Auth_UserID");
if (!VerifyReply(CHK_334_REPLY )) throw("Error: Failed to Recv 334 after sending m_Auth_UserID");
StrStm.str("");
// Send AuthPassword
StrStm << ((m_LoginMethod == LOGIN_AUTH_METHOD)?Encode64String(m_Auth_Password).c_str():m_Auth_Password.c_str()) << CRLF_SET;
if (!SendStr(StrStm)) throw("Error: Failed to send m_Auth_Password");
if (!VerifyReply(CHK_235_REPLY ))
{
throw("Error: Failed to Recv 235 after sending m_Auth_Password");
}
}
else
{
// send HELO message
StrStm << "HELO " << m_EmailSenderHostName << CRLF_SET;
if (!SendStr(StrStm)) throw("Error: Failed to send Hello");
if (!VerifyReply(CHK_250_REPLY )) throw("Error: Failed to Recv 250 after sending hello");
}
}
std::list* SendEmail::StrLstToELst(const std::list *Src, std::list &Dest)
{
if (!Src) return NULL;
for (std::list::const_iterator i = Src->begin();i!=Src->end();i++)
{
Dest.push_back(i->c_str());
}
return &Dest
}
std::string SendEmail::operator ()(
const std::list &To,
const std::string &Subject,
const std::string &Body,
const std::list *CC_List /* = 0 */,
const std::list *BCC_List /* = 0 */,
const std::list *AttachmentPath_List /* = 0 */,
const std::string *MessageID /* = 0 */)
{
std::list ToLst;
std::list CCLst;
std::list BCCLst;
return Mail(
*StrLstToELst(&To, ToLst),
Subject,
Body,
StrLstToELst(CC_List, CCLst),
StrLstToELst(BCC_List, BCCLst),
AttachmentPath_List,
MessageID);
}
std::string SendEmail::operator ()(
const std::string &To,
const std::string &Subject,
const std::string &Body,
const std::list *CC_List /* = 0 */,
const std::list *BCC_List /* = 0 */,
const std::list *AttachmentPath_List /* = 0 */,
const std::string *MessageID /* = 0 */)
{
std::list CCLst;
std::list BCCLst;
return Mail(
To,
Subject,
Body,
StrLstToELst(CC_List, CCLst),
StrLstToELst(BCC_List, BCCLst),
AttachmentPath_List,
MessageID);
}
std::string SendEmail::Mail(
const std::string &To,
const std::string &Subject,
const std::string &Body,
const std::list *CC_List /* = 0 */,
const std::list *BCC_List /* = 0 */,
const std::list *AttachmentPath_List /* = 0 */,
const std::string *MessageID /* = 0 */)
{
std::list ToList;
ToList.push_back(To);
return Mail(ToList, Subject, Body, CC_List,BCC_List, AttachmentPath_List, MessageID);
}
std::string SendEmail::Mail(
const std::list &To,
const std::string &Subject,
const std::string &Body,
const std::list &CC_List ,
const std::list &BCC_List ,
const std::list *AttachmentPath_List /* = 0 */,
const std::string *MessageID /* = 0 */)
{
return operator()(To, Subject, Body, &CC_List, &BCC_List, AttachmentPath_List, MessageID);
}
std::string SendEmail::Mail(
const std::list &To,
const std::string &Subject,
const std::string &Body,
const std::list *CC_List /* = 0 */,
const std::list *BCC_List /* = 0 */,
const std::list *AttachmentPath_List /* = 0 */,
const std::string *MessageID /* = 0 */)
{
std::list dummy;
m_RecentErrorLog.clear();
// CC:
for(int EList = 0;EList < 3;EList++)
{
const std::list *Cur_List = NULL;
switch(EList)
{
case TO_BLOCK:
Cur_List = &To
break;
case CC_BLOCK:
if (!CC_List) continue;
Cur_List = CC_List;
break;
case BCC_BLOCK:
if (!BCC_List) continue;
Cur_List = BCC_List;
break;
}
for (std::list::const_iterator email_addr_item = Cur_List->begin();
email_addr_item != Cur_List->end();email_addr_item++)
{
std::string StatStr = Mail( *email_addr_item,
To,
Subject,
Body,
((CC_List)?*CC_List:dummy),
AttachmentPath_List,
((MessageID)?*MessageID:""));
if (StatStr != NO_ERRORS)
{
StrngStream StrStm;
StrStm << ((EList)?"BCC (":"CC (") << email_addr_item->c_str() << ") Error(" << StatStr << ")";
m_RecentErrorLog.push_back(StrStm.str());
}
}
}
if (m_RecentErrorLog.size()) return *m_RecentErrorLog.begin();
return NO_ERRORS;
}
std::string SendEmail::Mail(
const std::string &RCPT_To,
const std::list &To,
const std::string &Subject,
const std::string &Body,
const std::list &CC_List,
const std::list *AttachmentPath_List,
const std::string &MessageID)
{
if (!m_InitiateGood) return "Error: SendEmail failed to initiate properly";
if( (m_socket = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET )
return "Error: socket function return INVALID_SOCKET";
std::string ReturnValue = NO_ERRORS;
bool SendResetIf_Throw = false;
ReturnValueFromReceive="";
try
{
hostent *mailhost = 0;
if( isdigit(*m_EmailSenderHostName.c_str()) && strchr(m_EmailSenderHostName.c_str(), ''.'') )
{
unsigned long tmp_iaddr = inet_addr(m_EmailSenderHostName.c_str());
mailhost = gethostbyaddr( (const char *)&tmp_iaddr, 4, PF_INET );
}
else mailhost = gethostbyname(m_EmailSenderHostName.c_str());
if(mailhost == 0) throw("Error: hostent *mailhost = 0");
struct sockaddr_in my_addr;
my_addr.sin_family = AF_INET;
my_addr.sin_port = htons(SMTP_OUTGOING_MAIL_PORT);
memcpy( &my_addr.sin_addr, mailhost->h_addr_list[0], sizeof(struct in_addr) );
if (connect(m_socket, (struct sockaddr *)&my_addr, sizeof(struct sockaddr))) throw("Error: connect failed");
if (!VerifyReply(CHK_220_REPLY)) throw("Error: Did not Recv 220 before hello");
DoLogin();
SendResetIf_Throw = true;
// send MAIL message
//Figure out m_Sender''s EmailAddress
std::string SendersEmailAddr = m_Sender.c_str();
if(SendersEmailAddr.size())
{//Need to add code for m_Sender.m_UserName
if (SendersEmailAddr.find(''@'') == std::string::npos)
SendersEmailAddr += "@" + m_EmailSenderHostName;
}
else
{
if (m_Auth_UserID.find(''@'') == std::string::npos)
SendersEmailAddr = m_Auth_UserID + "@" + m_EmailSenderHostName;
else SendersEmailAddr = m_Auth_UserID;
}
StrngStream StrStm;
// send MAIL FROM message
StrStm << "MAIL FROM: 1" << EmailAddrFormat(SendersEmailAddr) << m_Sender << CRLF_SET;
if (!SendStr(StrStm)) throw("Error: Failed to send From");
if (!VerifyReply(CHK_250_REPLY )) throw("Error: Failed to Recv 250 after sending From");
// send RCPT message
StrStm.str("");//Clear stream buffer
StrStm << "RCPT TO: " << EmailAddrFormat(RCPT_To) << CRLF_SET;
if (!SendStr(StrStm)) throw("Error: Failed to send TO");
if (!VerifyReply(CHK_250_REPLY )) throw("Error: Failed to Recv 250 after sending RCPT TO");
// send DATA message
StrStm.str("");
StrStm << "DATA" << CRLF_SET;
if (!SendStr(StrStm)) throw("Error: Failed to send DATA line");
if (!VerifyReply(CHK_354_REPLY )) throw("Error: Failed to Recv 354 after sending DATA line");
// construct date string
time_t tTime = time( 0 );
strftime(m_EmailBuffer, MAX_LINE_SIZE, "Date: %a, %d %b %Y %H:%M:%S %Z", gmtime(&tTime));
strcat(m_EmailBuffer, CRLF_SET.c_str());
// send mail headers
// Date:
if(!SendStr(m_EmailBuffer)) throw("Error: Failed to send DATE");
// X-Mailer:
if (m_X_Mailer.size())
{
if(!Send(m_X_Mailer.c_str(), m_X_Mailer.size())) throw("Error: Failed to send X-Mailer");
}
// X-Phone:
if (m_X_Phone.size())
{
if(!Send(m_X_Phone.c_str(), m_X_Phone.size())) throw("Error: Failed to send X-Phone");
}
// Message-ID:
if(MessageID.size())
{
StrStm.str("");
StrStm << "Message-ID: " << MessageID << CRLF_SET;
if(!SendStr(StrStm)) throw("Error: Failed to send Message-ID");
}
// To:
StrStm.str("");
StrStm << "To: ";
for (std::list::const_iterator email_addr_item = To.begin();
email_addr_item != To.end();email_addr_item++)
{
StrStm << email_addr_item->c_str() << m_EmailAddrSeperator;
}
StrStm << CRLF_SET;
if(!SendStr(StrStm)) throw("Error: Failed to send TO_List");
// From:
StrStm.str("");
StrStm << "From: " << EmailAddrFormat(SendersEmailAddr) << m_Sender << CRLF_SET;
if(!SendStr(StrStm)) throw("Error: Failed to send From");
// Reply-To:
if(m_ReplyToAddr.size())
{
StrStm.str("");
StrStm << "Reply-To: " << m_ReplyToAddr.c_str() << CRLF_SET;
if(!SendStr(StrStm)) throw("Error: Failed to send Reply-To");
}
// CC:
if(CC_List.size())
{
strcpy(m_EmailBuffer,"CC: ");
for (std::list::const_iterator email_addr_item = CC_List.begin();
email_addr_item != CC_List.end();email_addr_item++)
{
strcat(m_EmailBuffer, email_addr_item->c_str());
strcat(m_EmailBuffer,m_EmailAddrSeperator.c_str());
}
strcat(m_EmailBuffer, CRLF_SET.c_str());
if(!SendStr(m_EmailBuffer)) throw("Error: Failed to send CC_List");
}
// Subject:
StrStm.str("");
StrStm << "Subject: " << Subject << CRLF_SET;
if(!SendStr(StrStm)) throw("Error: Failed to send Subject");
if(AttachmentPath_List)
{
StrStm.str("");
StrStm << "MIME-Version: 1.0" << CRLF_SET;
StrStm << "Content-type: multipart/mixed; boundary=\"#BOUNDARY#\"" << CRLF_SET;
SendStr(StrStm);
}
/////////////////////////////////////////////////////////
// 08/13/98 rlb
// empty line needed after headers, RFC822
strcpy(m_EmailBuffer, CRLF_SET.c_str());
if(!SendStr(m_EmailBuffer)) throw("Error: Failed to send empty line needed after headers(1)");
strcpy(m_EmailBuffer, CRLF_SET.c_str());
if(!SendStr(m_EmailBuffer)) throw("Error: Failed to send empty line needed after headers(2)");
if(AttachmentPath_List)
{
StrStm.str("");
StrStm << CRLF_SET;
StrStm << "--#BOUNDARY#" << CRLF_SET;
StrStm << "Content-Type: text/plain; charset=ISO-8859-1" << CRLF_SET;
StrStm << "Content-Transfer-Encoding: quoted-printable" << CRLF_SET;
StrStm << CRLF_SET;
SendStr(StrStm);
}
/////////////////////////////////////////////////////////
// send message text
if(!Send(Body.c_str(), Body.size())) throw("Error: Failed to send send message text");
// AttachmentPath_List:
if(AttachmentPath_List)
{
for (std::list::const_iterator attachment_file_item = AttachmentPath_List->begin();
attachment_file_item != AttachmentPath_List->end();
attachment_file_item++)
{
if (!Encode64File(*attachment_file_item))
{
throw("Error: Failed to attachment_file_item");
}
}
strcpy(m_EmailBuffer, CRLF_SET.c_str());
strcat(m_EmailBuffer, "--#BOUNDARY#--");
SendStr(m_EmailBuffer);
}
// send message terminator and receive reply
if(!Send("\r\n.\r\n", 5)) throw("Error: Failed to send message terminator");
if(!VerifyReply(CHK_250_REPLY )) throw("Error: Failed to Recv 250 reply after sending message terminator");
SendResetIf_Throw=false; //No use sending reset if fail at this point
// send QUIT message
strcpy(m_EmailBuffer, "QUIT" );
strcat(m_EmailBuffer, CRLF_SET.c_str());
if(!SendStr(m_EmailBuffer)) throw("Error: Failed to send QUIT message");
if(!VerifyReply(CHK_221_REPLY )) throw("Error: Failed to Recv 221 reply after sending QUIT message");
}
catch(const char* ErrMsg)
{
ReturnValue = ErrMsg;
if (ReturnValueFromReceive.size())
{
ReturnValue += " Last Rcvd = " + ReturnValueFromReceive;
}
if (SendResetIf_Throw)
{
strcpy(m_EmailBuffer, "RESET");
strcat(m_EmailBuffer, CRLF_SET.c_str());
SendStr(m_EmailBuffer);
strcpy(m_EmailBuffer, "QUIT");
strcat(m_EmailBuffer, CRLF_SET.c_str());
SendStr(m_EmailBuffer);
}
}
shutdown (m_socket, 2);
#if defined(WIN32) || defined(__WIN32__)
closesocket(m_socket);
#endif //defined(WIN32) || defined(__WIN32__)
m_socket = 0;
return ReturnValue;
}
bool SendEmail::SendStr(const StrngStream &Src)
{
return SendStr(Src.str().c_str());
}
bool SendEmail::SendStr(const char* Buffer)
{
return Send(Buffer, strlen(Buffer));
}
bool SendEmail::VerifyReply(const char* szReplyString)
{
return Receive(m_EmailBuffer, MAX_LINE_SIZE, 0, szReplyString);
}
bool SendEmail::Receive(char* szBuffer, int nLenMax, int nFlags, const char* szReplyString)
{
int nRes = recv(m_socket, szBuffer, nLenMax, nFlags);
ReturnValueFromReceive = szBuffer;
if (nRes == SOCKET_ERROR ) return false;
#if defined(_DEBUG) || defined(DEBUG)
static bool FirstPass = true;
std::ofstream file("log_recv.txt",std::ios::out|((FirstPass)?0:std::ios::app));
FirstPass=false;
if (!file.fail())
{
file.seekp(0, std::ios::end);
file.write(szBuffer,nRes);
file.close();
}
#endif //defined(_DEBUG) || defined(DEBUG)
*(szBuffer + nRes ) = ''\0'';
char* szPtr = strtok( szBuffer, "\n" );
while(szPtr)
{
if(*(szPtr + 3) == '' '')
{
if(!strncmp(szPtr, szReplyString, strlen(szReplyString))) return true;
else return false;
}
else szPtr = strtok( 0, "\n" );
}
return false;
}
bool SendEmail::Send(const char *szBuffer, size_t nLen)
{
size_t nCnt = 0;
while( nCnt < nLen )
{
int nRes = send( m_socket, szBuffer + nCnt, nLen - nCnt, 0);
if( nRes == SOCKET_ERROR) return false;
else nCnt += nRes;
}
return true;
}
bool SendEmail::Encode64File(const std::string &FileName)
{
std::ifstream file(FileName.c_str(), std::ios::in|std::ios::binary);
if (file.fail())
{
return false;
}
file.unsetf(std::ios::skipws);
std::vector vBytes;
for(unsigned char uc = 0;
{
file >> uc;
if (file.eof()) break;
vBytes.push_back(uc);
}
std::string FileNameWithOutPath = (FileName.find_last_of(''/'')==std::string::npos)?FileName:FileName.begin()+FileName.find_last_of(''/'')+1;
FileNameWithOutPath = (FileNameWithOutPath.find_last_of(''\\'')==std::string::npos)?FileNameWithOutPath:FileNameWithOutPath.begin()+FileNameWithOutPath.find_last_of(''\\'')+1;
std::string encodedBuffer = CRLF_SET + CRLF_SET + "--#BOUNDARY#";
encodedBuffer += CRLF_SET + "Content-Type: text/plain; charset=ISO-8859-1; name=" + FileNameWithOutPath;
encodedBuffer += CRLF_SET + "Content-Transfer-Encoding: base64";
encodedBuffer += CRLF_SET + "Content-Disposition: attachment; filename=" + FileNameWithOutPath;
encodedBuffer += CRLF_SET + CRLF_SET;
Send(encodedBuffer.c_str(), encodedBuffer.size());
Encode64(vBytes, &encodedBuffer, true);
Send(encodedBuffer.c_str(), encodedBuffer.size());
return true;
}
std::string SendEmail::Encode64String(const std::string &Src)
{
return Encode64(std::vector((const unsigned char*)Src.begin(), (const unsigned char*)Src.end()));
}
inline char SendEmail::Encode64Byte(unsigned char uc)
{
if (uc < 26) return ''A''+uc;
if (uc < 52) return ''a''+(uc-26);
if (uc < 62) return ''0''+(uc-52);
if (uc == 62) return ''+'';
return ''/'';
}
inline const char* SendEmail::Encode64(const std::vector & vBytes, std::string *Dest, bool EndWithCR)
{
static std::string DefaultStr;
std::string &retval = (Dest)?(*Dest):DefaultStr;
retval = "";
if (vBytes.size() == 0) return retval.c_str();
for (int i=0;i;
if (i+1>2;
by5 = ((by1&0x3)<<4)|(by2>>4);
by6 = ((by2&0xf)<<2)|(by3>>6);
by7 = by3&0x3f;
retval += Encode64Byte(by4);
retval += Encode64Byte(by5);
if (i+1 Attachments;
if (FileName_Attach) Attachments.push_back(FileName_Attach);
std::string Results = SendEmail(HostName, UserID, (UserPassword)?UserPassword:"")(To, Subject, Body, NULL, NULL, (FileName_Attach)?&Attachments:NULL);
if (Results != SendEmail::NO_ERRORS)
return false;
return true;
}
/*
*******************The following is example usuage for the SendEmail class*******************************
const char ToListTest[][64] = {"\"David\"","\"Bill Gate\"","sendemailtestx2@altavista.com","sendemailtestx3@altavista.com "};
const char CCListTest[][64] = {"sendemailtestx4@altavista.com","\"John Doe\"","sendemailtestx6@altavista.com"};
const char BCCListTest[][64] = {"sendemailtestx7@altavista.com","sendemailtestx8@altavista.com","sendemailtestx9@altavista.com"};
void ExampleFunctionToSendMailToMultipleTo(const std::string &Hostname, const std::string &UserID, const std::string &UserPassword)
{//Example for Multiple TO fields
std::list ToList;
ToList.push_back(ToListTest[0]);
ToList.push_back(ToListTest[1]);
ToList.push_back(ToListTest[2]);
std::string Results = SendEmail(Hostname, UserID, UserPassword)(
ToList,
"*File Test x15: Please ignore this email.",
"Test from SendEmail. Please ignore this email.");
if (Results != SendEmail::NO_ERRORS)
{
printf("Error:\r\n");
printf(Results.c_str());
printf("\r\n\r\nPress ENTER to quit\r\n");
getchar();
}
}
void ExampleFunctionToSendMailToMultipleToCC_AndBCC(const std::string &Hostname, const std::string &UserID, const std::string &UserPassword)
{//Example for Multiple TO fields CC and BCC field
std::list ToList;
ToList.push_back(ToListTest[0]);
ToList.push_back(ToListTest[1]);
ToList.push_back(ToListTest[2]);
std::list CCList;
CCList.push_back(CCListTest[0]);
CCList.push_back(CCListTest[1]);
CCList.push_back(CCListTest[2]);
std::list BCCList;
BCCList.push_back(BCCListTest[0]);
BCCList.push_back(BCCListTest[1]);
BCCList.push_back(BCCListTest[2]);
std::string Results = SendEmail(Hostname, UserID, UserPassword)(
ToList,
"*File Test x15x: Please ignore this email.",
"Test from SendEmail. Please ignore this email.",
&CCList,
&BCCList);
if (Results != SendEmail::NO_ERRORS)
{
printf("Error:\r\n");
printf(Results.c_str());
printf("\r\n\r\nPress ENTER to quit\r\n");
getchar();
}
}
void Example3FunctionUsingSendEmail(const std::string &Hostname, const std::string &UserID, const std::string &UserPassword)
{//Example for CC and BCC field
std::list CCList;
CCList.push_back(CCListTest[0]);
CCList.push_back(CCListTest[1]);
CCList.push_back(CCListTest[2]);
std::list BCCList;
BCCList.push_back(BCCListTest[0]);
BCCList.push_back(BCCListTest[1]);
BCCList.push_back(BCCListTest[2]);
std::string Results = SendEmail(Hostname, UserID, UserPassword)(
ToListTest[0],
"*File Test x15: Please ignore this email.",
"Test from SendEmail. Please ignore this email.",
&CCList,
&BCCList);
if (Results != SendEmail::NO_ERRORS)
{
printf("Error:\r\n");
printf(Results.c_str());
printf("\r\n\r\nPress ENTER to quit\r\n");
getchar();
}
}
void Example2FunctionUsingSendEmail(const std::string &Hostname, const std::string &UserID, const std::string &UserPassword)
{//Example for CC
std::list CCList;
CCList.push_back(CCListTest[0]);
CCList.push_back(CCListTest[1]);
CCList.push_back(CCListTest[2]);
std::string Sender = ToListTest[1];
std::string ReplyTo = ToListTest[2];
std::string Results = SendEmail(Hostname, UserID, UserPassword, Sender, ReplyTo)(
ToListTest[0],
"*File Test x15: Please ignore this email.",
"Test from SendEmail. Please ignore this email.",
&CCList);
if (Results != SendEmail::NO_ERRORS)
{
printf("Error:\r\n");
printf(Results.c_str());
printf("\r\n\r\nPress ENTER to quit\r\n");
getchar();
}
}
void Example1FunctionUsingSendEmail(const std::string &Hostname, const std::string &UserID, const std::string &UserPassword)
{//Example sending attachments
SendEmail MySendEmail(Hostname, UserID, UserPassword);
std::list ListOfAttachments; //optional list of attachments
ListOfAttachments.push_back("D:\\documents\\text.txt");
ListOfAttachments.push_back("D:\\documents\\bitmap.bmp");
ListOfAttachments.push_back("D:\\documents\\text2.txt");
ListOfAttachments.push_back("D:\\documents\\text3.txt");
ListOfAttachments.push_back("D:\\documents\\text4.txt");
ListOfAttachments.push_back("D:\\documents\\text5.txt");
std::string Results = MySendEmail.Mail(
ToListTest[0], // Recipient Email address
"Example sending attachments",//Subject
"This is a test email.",//Email Body
0, //CC list
0, //BCC list
&ListOfAttachments);
if (Results != SendEmail::NO_ERRORS)
{
printf("Error:\r\n");
printf(Results.c_str());
printf("\r\n\r\nPress ENTER to quit\r\n");
getchar();
}
}
void VerySimpleExampleFunctionUsingSendEmail(const std::string &Hostname, const std::string &UserID, const std::string &UserPassword)
{
SendEmail MySendEmail(Hostname, UserID, UserPassword);
//SendEmail MySendEmail("mail.foofoo.com", "MyUserID");
MySendEmail.Mail(
ToListTest[0], // Recipient Email address
"*File Test x99: Please ignore this email.", //Subject
"Test from SendEmail. Please ignore this email." //Email Body
);
}
void VerySimpleExampleFunctionUsingSendEmail_ViaOperator(const std::string &Hostname, const std::string &UserID, const std::string &UserPassword)
{
std::string Results = SendEmail(Hostname, UserID, UserPassword)(ToListTest[0], "Hello Subject2", "This is the body");
if (Results != SendEmail::NO_ERRORS)
{
printf("Error:\r\n");
printf(Results.c_str());
printf("\r\n\r\nPress ENTER to quit\r\n");
getchar();
}
}
void SimpleExampleFunctionUsingSendEmail(const std::string &Hostname, const std::string &UserID, const std::string &UserPassword)
{
SendEmail MySendEmail(Hostname, UserID, UserPassword);
//SendEmail MySendEmail("mail.foofoo.com", UserID);
MySendEmail.Mail(
ToListTest[0], // Recipient Email address
"*File Test x99: Please ignore this email.", //Subject
"Test from SendEmail. Please ignore this email." //Email Body
);
}
*/
