////////////////////////////////////////////////////////////////////////////////
// Original class CFastSmtp written by
// christopher w. backen <immortal@cox.net>
// More details at: http://www.codeproject.com/KB/IP/zsmtp.aspx
//
// Modifications introduced by Jakub Piwowarczyk:
// 1. name of the class and functions
// 2. new functions added: SendData,ReceiveData and more
// 3. authentication added
// 4. attachments added
// 5 .comments added
// 6. DELAY_IN_MS removed (no delay during sending the message)
// More details at: http://www.codeproject.com/KB/mcpp/CSmtp.aspx
////////////////////////////////////////////////////////////////////////////////
#include "CSmtp.h"
#pragma warning(push)
#pragma warning(disable:4786)
////////////////////////////////////////////////////////////////////////////////
// NAME: CSmtp
// DESCRIPTION: Constructor of CSmtp class.
// ARGUMENTS: none
// USES GLOBAL: none
// MODIFIES GL: m_oError, m_iXPriority, m_iSMTPSrvPort, m_pcLocalHostName
// m_pcMailFrom, m_pcNameFrom, m_pcSubject, m_pcMsgBody, m_pcXMailer
// m_pcReplyTo, m_pcIPAddr, m_pcLogin, m_pcPassword, m_pcSMTPSrvName,
// RecvBuf, SendBuf
// RETURNS: none
// AUTHOR: Jakub Piwowarczyk
// AUTHOR/DATE: JP 2010-01-28
////////////////////////////////////////////////////////////////////////////////
CSmtp::CSmtp()
{
// Initialize variables
m_oError = CSMTP_NO_ERROR;
m_iXPriority = XPRIORITY_NORMAL;
m_iSMTPSrvPort = 0;
m_pcLocalHostName = NULL;
m_pcMailFrom = NULL;
m_pcNameFrom = NULL;
m_pcSubject = NULL;
m_pcMsgBody = NULL;
m_pcXMailer = NULL;
m_pcReplyTo = NULL;
m_pcIPAddr = NULL;
m_pcLogin = NULL;
m_pcPassword = NULL;
m_pcSMTPSrvName = NULL;
if((RecvBuf = new char[BUFFER_SIZE]) == NULL)
{
m_oError = CSMTP_LACK_OF_MEMORY;
return;
}
if((SendBuf = new char[BUFFER_SIZE]) == NULL)
{
m_oError = CSMTP_LACK_OF_MEMORY;
return;
}
// Initialize WinSock
WORD wVer = MAKEWORD(2,2);
if (WSAStartup(wVer,&wsaData) != NO_ERROR)
{
m_oError = CSMTP_WSA_STARTUP;
return;
}
if (LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 2 )
{
m_oError = CSMTP_WSA_VER;
WSACleanup();
return;
}
}
////////////////////////////////////////////////////////////////////////////////
// NAME: CSmtp
// DESCRIPTION: Destructor of CSmtp class.
// ARGUMENTS: none
// USES GLOBAL: m_pcLocalHostName, m_pcMailFrom, m_pcNameFrom, m_pcSubject,
// m_pcMsgBody, m_pcXMailer, m_pcReplyTo, m_pcIPAddr, m_pcLogin,
// m_pcPassword, m_pcSMTPSrvName, RecvBuf, SendBuf
// MODIFIES GL: m_pcLocalHostName, m_pcMailFrom, m_pcNameFrom, m_pcSubject,
// m_pcMsgBody, m_pcXMailer, m_pcReplyTo, m_pcIPAddr, m_pcLogin,
// m_pcPassword, m_pcSMTPSrvName, RecvBuf, SendBuf, Recipients,
// CCRecipients, BCCRecipients, Attachments
// RETURNS: none
// AUTHOR: Jakub Piwowarczyk
// AUTHOR/DATE: JP 2010-01-28
////////////////////////////////////////////////////////////////////////////////
CSmtp::~CSmtp()
{
// Clear vectors
Recipients.clear();
CCRecipients.clear();
BCCRecipients.clear();
Attachments.clear();
// Free memory
if (m_pcLocalHostName)
{
delete[] m_pcLocalHostName;
m_pcLocalHostName = NULL;
}
if (m_pcMailFrom)
{
delete[] m_pcMailFrom;
m_pcMailFrom = NULL;
}
if (m_pcNameFrom)
{
delete[] m_pcNameFrom;
m_pcNameFrom = NULL;
}
if (m_pcSubject)
{
delete[] m_pcSubject;
m_pcSubject = NULL;
}
if (m_pcMsgBody)
{
delete[] m_pcMsgBody;
m_pcMsgBody = NULL;
}
if (m_pcXMailer)
{
delete[] m_pcXMailer;
m_pcXMailer = NULL;
}
if (m_pcReplyTo)
{
delete[] m_pcReplyTo;
m_pcReplyTo = NULL;
}
if (m_pcIPAddr)
{
delete[] m_pcIPAddr;
m_pcIPAddr = NULL;
}
if (m_pcLogin)
{
delete[] m_pcLogin;
m_pcLogin = NULL;
}
if (m_pcPassword)
{
delete[] m_pcPassword;
m_pcPassword = NULL;
}
if (m_pcSMTPSrvName)
{
delete[] m_pcSMTPSrvName;
m_pcSMTPSrvName = NULL;
}
if(SendBuf)
{
delete[] SendBuf;
SendBuf = NULL;
}
if(RecvBuf)
{
delete[] RecvBuf;
RecvBuf = NULL;
}
// Cleanup
WSACleanup();
}
////////////////////////////////////////////////////////////////////////////////
// NAME: AddAttachment
// DESCRIPTION: New attachment is added. .
// ARGUMENTS: const char *path - name of attachment added
// USES GLOBAL: Attachments
// MODIFIES GL: Attachments
// RETURNS: returns always true (in this wersion)
// AUTHOR: Jakub Piwowarczyk
// AUTHOR/DATE: JP 2010-01-28
////////////////////////////////////////////////////////////////////////////////
bool CSmtp::AddAttachment(const char *path)
{
std::string str(path);
Attachments.insert(Attachments.end(),str);
return true;
}
////////////////////////////////////////////////////////////////////////////////
// NAME: AddRecipient
// DESCRIPTION: New recipient data is added i.e.: email and name. .
// ARGUMENTS: const char *email - mail of the recipient
// const char *name - name of the recipient
// USES GLOBAL: Recipients
// MODIFIES GL: Recipients, m_oError
// RETURNS: true if operation was successful
// false if oprtation failed
// AUTHOR: Jakub Piwowarczyk
// AUTHOR/DATE: JP 2010-01-28
////////////////////////////////////////////////////////////////////////////////
bool CSmtp::AddRecipient(const char *email, const char *name)
{
assert(email);
if(!email)
{
m_oError = CSMTP_UNDEF_RECIPENT_MAIL;
return false;
}
Recipent recipent;
recipent.Mail.insert(0,email);
name!=NULL ? recipent.Name.insert(0,name) : recipent.Name.insert(0,"");
Recipients.insert(Recipients.end(), recipent);
return true;
}
////////////////////////////////////////////////////////////////////////////////
// NAME: AddCCRecipient
// DESCRIPTION: New cc-recipient data is added i.e.: email and name. .
// ARGUMENTS: const char *email - mail of the cc-recipient
// const char *name - name of the ccc-recipient
// USES GLOBAL: CCRecipients
// MODIFIES GL: CCRecipients, m_oError
// RETURNS: true if operation was successful
// false if oprtation failed
// AUTHOR: Jakub Piwowarczyk
// AUTHOR/DATE: JP 2010-01-28
////////////////////////////////////////////////////////////////////////////////
bool CSmtp::AddCCRecipient(const char *email, const char *name)
{
assert(email);
if(!email)
{
m_oError = CSMTP_UNDEF_RECIPENT_MAIL;
return false;
}
Recipent recipent;
recipent.Mail.insert(0,email);
name!=NULL ? recipent.Name.insert(0,name) : recipent.Name.insert(0,"");
CCRecipients.insert(CCRecipients.end(), recipent);
return true;
}
////////////////////////////////////////////////////////////////////////////////
// NAME: AddBCCRecipient
// DESCRIPTION: New bcc-recipient data is added i.e.: email and name. .
// ARGUMENTS: const char *email - mail of the bcc-recipient
// const char *name - name of the bccc-recipient
// USES GLOBAL: BCCRecipients
// MODIFIES GL: BCCRecipients, m_oError
// RETURNS: true if operation was successful
// false if oprtation failed
// AUTHOR: Jakub Piwowarczyk
// AUTHOR/DATE: JP 2010-01-28
////////////////////////////////////////////////////////////////////////////////
bool CSmtp::AddBCCRecipient(const char *email, const char *name)
{
assert(email);
if(!email)
{
m_oError = CSMTP_UNDEF_RECIPENT_MAIL;
return false;
}
Recipent recipent;
recipent.Mail.insert(0,email);
name!=NULL ? recipent.Name.insert(0,name) : recipent.Name.insert(0,"");
BCCRecipients.insert(BCCRecipients.end(), recipent);
return true;
}
////////////////////////////////////////////////////////////////////////////////
// NAME: Send
// DESCRIPTION: Sending the mail. .
// ARGUMENTS: none
// USES GLOBAL: m_pcSMTPSrvName, m_iSMTPSrvPort, SendBuf, RecvBuf, m_pcLogin,
// m_pcPassword, m_pcMailFrom, Recipients, CCRecipients,
// BCCRecipients, m_pcMsgBody, Attachments,
// MODIFIES GL: m_oError, SendBuf
// RETURNS: true if operation was successful
// false if oprtation failed
// AUTHOR: Jakub Piwowarczyk
// AUTHOR/DATE: JP 2010-01-28
////////////////////////////////////////////////////////////////////////////////
bool CSmtp::Send()
{
unsigned int i,rcpt_count,res,FileId,counter;
char *FileBuf = NULL, *FileName = NULL;
FILE* hFile = NULL;
unsigned long int FileSize,TotalSize,MsgPart;
// ***** CONNECTING TO SMTP SERVER *****
assert(m_pcSMTPSrvName);
// connecting to remote host:
if( (hSocket = ConnectRemoteServer(m_pcSMTPSrvName, m_iSMTPSrvPort)) == INVALID_SOCKET )
{
m_oError = CSMTP_WSA_INVALID_SOCKET;
return false;
}
counter = 0;
do
{
counter++;
if(counter >= COUNTER_VALUE)
{
m_oError = CSMTP_SERVER_NOT_RESPONDING;
return false;
}
if(!ReceiveData())
return false;
switch(SmtpXYZdigits())
{
case 220:
counter = 0;
break;
default:
m_oError = CSMTP_SERVER_NOT_READY;
return false;
}
}while(counter > 0);
// EHLO <SP> <domain> <CRLF>
sprintf(SendBuf,"EHLO %s\r\n",GetLocalHostName()!=NULL ? m_pcLocalHostName : "domain");
if(!SendData())
return false;
counter = 0;
do
{
counter++;
if(counter >= COUNTER_VALUE)
{
m_oError = CSMTP_SERVER_NOT_RESPONDING;
return false;
}
if(!ReceiveData())
return false;
switch(SmtpXYZdigits())
{
case 250:
counter = 0;
break;
default:
m_oError = CSMTP_COMMAND_EHLO;
return false;
}
}while(counter > 0);
// AUTH <SP> LOGIN <CRLF>
strcpy(SendBuf,"AUTH LOGIN\r\n");
if(!SendData())
return false;
counter = 0;
do
{
counter++;
if(counter >= COUNTER_VALUE)
{
m_oError = CSMTP_SERVER_NOT_RESPONDING;
return false;
}
if(!ReceiveData())
return false;
switch(SmtpXYZdigits())
{
case 250:
break;
case 334:
counter = 0;
break;
default:
m_oError = CSMTP_COMMAND_AUTH_LOGIN;
return false;
}
}while(counter > 0);
// send login:
if(!m_pcLogin)
{
m_oError = CSMTP_UNDEF_LOGIN;
return false;
}
std::string encoded_login = base64_encode(reinterpret_cast<const unsigned char*>(m_pcLogin),strlen(m_pcLogin));
sprintf(SendBuf,"%s\r\n",encoded_login.c_str());
if(!SendData())
return false;
counter = 0;
do
{
counter++;
if(counter >= COUNTER_VALUE)
{
m_oError = CSMTP_SERVER_NOT_RESPONDING;
return false;
}
if(!ReceiveData())
return false;
switch(SmtpXYZdigits())
{
case 334:
counter = 0;
break;
default:
m_oError = CSMTP_UNDEF_XYZ_RESPOMSE;
return false;
}
}while(counter > 0);
// send password:
if(!m_pcPassword)
{
m_oError = CSMTP_UNDEF_PASSWORD;
return false;
}
std::string encoded_password = base64_encode(reinterpret_cast<const unsigned char*>(m_pcPassword),strlen(m_pcPassword));
sprintf(SendBuf,"%s\r\n",encoded_password.c_str());
if(!SendData())
return false;
counter = 0;
do
{
counter++;
if(counter >= COUNTER_VALUE)
{
m_oError = CSMTP_SERVER_NOT_RESPONDING;
return false;
}
if(!ReceiveData())
return false;
switch(SmtpXYZdigits())
{
case 235:
counter = 0;
break;
case 334:
break;
case 535:
m_oError = CSMTP_BAD_LOGIN_PASS;
return false;
default:
m_oError = CSMTP_UNDEF_XYZ_RESPOMSE;
return false;
}
}while(counter > 0);
// ***** SENDING E-MAIL *****
// MAIL <SP> FROM:<reverse-path> <CRLF>
if(m_pcMailFrom == NULL)
{
m_oError = CSMTP_UNDEF_MAILFROM;
return false;
}
sprintf(SendBuf,"MAIL FROM:<%s>\r\n",m_pcMailFrom);
if(!SendData())
return false;
counter = 0;
do
{
counter++;
if(counter >= COUNTER_VALUE)
{
m_oError = CSMTP_SERVER_NOT_RESPONDING;
return false;
}
if(!ReceiveData())
return false;
switch(SmtpXYZdigits())
{
case 250:
counter = 0;
break;
default:
m_oError = CSMTP_COMMAND_MAIL_FROM;
return false;
}
}while(counter > 0);
// RCPT <SP> TO:<forward-path> <CRLF>
rcpt_count = Recipients.size();
for(i=0;i<Recipients.size();i++)
{
sprintf(SendBuf,"RCPT TO:<%s>\r\n",(Recipients.at(i).Mail).c_str());
if(!SendData())
return false;
counter = 0;
do
{
counter++;
if(counter >= COUNTER_VALUE)
{
m_oError = CSMTP_SERVER_NOT_RESPONDING;
return false;
}
if(!ReceiveData())
return false;
switch(SmtpXYZdigits())
{
case 250:
counter = 0;
break;
default:
m_oError = CSMTP_COMMAND_RCPT_TO;
rcpt_count--;
}
}while(counter > 0);
}
if(!rcpt_count)
return false;
for(i=0;i<CCRecipients.size();i++)
{
sprintf(SendBuf,"RCPT TO:<%s>\r\n",(CCRecipients.at(i).Mail).c_str());
if(!SendData())
return false;
counter = 0;
do
{
counter++;
if(counter >= COUNTER_VALUE)
{
m_oError = CSMTP_SERVER_NOT_RESPONDING;
return false;
}
if(!ReceiveData())
return false;
switch(SmtpXYZdigits())
{
case 250:
counter = 0;
break;
default:
m_oError = CSMTP_COMMAND_RCPT_TO;
rcpt_count--;
}
}while(counter > 0);
}
for(i=0;i<BCCRecipients.size();i++)
{
sprintf(SendBuf,"RCPT TO:<%s>\r\n",(BCCRecipients.at(i).Mail).c_str());
if(!SendData())
return false;
counter = 0;
do
{
counter++;
if(counter >= COUNTER_VALUE)
{
m_oError = CSMTP_SERVER_NOT_RESPONDING;
return false;
}
if(!ReceiveData())
return false;
switch(SmtpXYZdigits())
{
case 250:
counter = 0;
break;
default:
m_oError = CSMTP_COMMAND_RCPT_TO;
rcpt_count--;
}
}while(counter > 0);
}
// DATA <CRLF>
strcpy(SendBuf,"DATA\r\n");
if(!SendData())
return false;
counter = 0;
do
{
counter++;
if(counter >= COUNTER_VALUE)
{
m_oError = CSMTP_SERVER_NOT_RESPONDING;
return false;
}
if(!ReceiveData())
return false;
switch(SmtpXYZdigits())
{
case 354:
counter = 0;
break;
case 250:
break;
default:
m_oError = CSMTP_COMMAND_DATA;
return false;
}
}while(counter > 0);
// send header(s)
if(!FormatHeader(SendBuf))
{
m_oError = CSMTP_UNDEF_MSG_HEADER;
return false;
}
if(!SendData())
return false;
// send text message
sprintf(SendBuf,"%s\r\n",m_pcMsgBody); // NOTICE: each line ends with <CRLF>
if(!SendData())
return false;
// next goes attachments (if they are)
if((FileBuf = new char[55]) == NULL)
{
m_oError = CSMTP_LACK_OF_MEMORY;
return false;
}
if((FileName = new char[255]) == NULL)
{
m_oError = CSMTP_LACK_OF_MEMORY;
return false;
}
TotalSize = 0;
for(FileId=0;FileId<Attachments.size();FileId++)
{
strcpy(FileName,Attachments[FileId].c_str());
sprintf(SendBuf,"--%s\r\n",BOUNDARY_TEXT);
strcat(SendBuf,"Content-Type: application/x-msdownload; name=\"");
strcat(SendBuf,&FileName[Attachments[FileId].find_last_of("\\") + 1]);
strcat(SendBuf,"\"\r\n");
strcat(SendBuf,"Content-Transfer-Encoding: base64\r\n");
strcat(SendBuf,"Content-Disposition: attachment; filename=\"");
strcat(SendBuf,&FileName[Attachments[FileId].find_last_of("\\") + 1]);
strcat(SendBuf,"\"\r\n");
strcat(SendBuf,"\r\n");
if(!SendData())
return false;
// opening the file:
hFile = fopen(FileName,"rb");
if(hFile == NULL)
{
m_oError = CSMTP_FILE_NOT_EXIST;
break;
}
// checking file size:
FileSize = 0;
while(!feof(hFile))
FileSize += fread(FileBuf,sizeof(char),54,hFile);
TotalSize += FileSize;
// sending the file:
if(TotalSize/1024 > MSG_SIZE_IN_MB*1024)
m_oError = CSMTP_MSG_TOO_BIG;
else
{
fseek (hFile,0,SEEK_SET);
MsgPart = 0;
for(i=0;i<FileSize/54+1;i++)
{
res = fread(FileBuf,sizeof(char),54,hFile);
MsgPart ? strcat(SendBuf,base64_encode(reinterpret_cast<const unsigned char*>(FileBuf),res).c_str())
: strcpy(SendBuf,base64_encode(reinterpret_cast<const unsigned char*>(FileBuf),res).c_str());
strcat(SendBuf,"\r\n");
MsgPart += res + 2;
if(MsgPart >= BUFFER_SIZE/2)
{ // sending part of the message
MsgPart = 0;
if(!SendData())
{
delete[] FileBuf;
delete[] FileName;
fclose(hFile);
return false;
}
}
}
if(MsgPart)
{
if(!SendData())
{
delete[] FileBuf;
delete[] FileName;
fclose(hFile);
return false;
}
}
}
fclose(hFile);
}
delete[] FileBuf;
delete[] FileName;
// sending last message block (if there is one or more attachments)
if(Attachments.size())
{
sprintf(SendBuf,"\r\n--%s--\r\n",BOUNDARY_TEXT);
if(!SendData())
return false;
}
// <CRLF> . <CRLF>
strcpy(SendBuf,"\r\n.\r\n");
if(!SendData())
return false;
counter = 0;
do
{
counter++;
if(counter >= COUNTER_VALUE)
{
m_oError = CSMTP_SERVER_NOT_RESPONDING;
return false;
}
if(!ReceiveData())
return false;
switch(SmtpXYZdigits())
{
case 250:
counter = 0;
break;
default:
m_oError = CSMTP_MSG_BODY_ERROR;
return false;
}
}while(counter > 0);
// ***** CLOSING CONNECTION *****
// QUIT <CRLF>
strcpy(SendBuf,"QUIT\r\n");
if(!SendData())
return false;
counter = 0;
do
{
counter = 0;
if(counter >= COUNTER_VALUE)
{
m_oError = CSMTP_SERVER_NOT_RESPONDING;
return false;
}
if(!ReceiveData())
return false;
switch(SmtpXYZdigits())
{
case 221:
break;
default:
m_oError = CSMTP_COMMAND_QUIT;
hSocket = NULL;
return false;
}
}while(counter > 0);
closesocket(hSocket);
hSocket = NULL;
return true;
}
////////////////////////////////////////////////////////////////////////////////
// NAME: ConnectRemoteServer
// DESCRIPTION: Connecting to the service running on the remote server.
// ARGUMENTS: const char *server - service name
// const unsigned short port - service port
// USES GLOBAL: m_pcSMTPSrvName, m_iSMTPSrvPort, SendBuf, RecvBuf, m_pcLogin,
// m_pcPassword, m_pcMailFrom, Recipients, CCRecipients,
// BCCRecipients, m_pcMsgBody, Attachments,
// MODIFIES GL: m_oError
// RETURNS: socket of the remote service
// AUTHOR: Jakub Piwowarczyk
// AUTHOR/DATE: JP 2010-01-28
////////////////////////////////////////////////////////////////////////////////
SOCKET CSmtp::ConnectRemoteServer(const char *server,const unsigned short port)
{
short nProtocolPort;
LPHOSTENT lpHostEnt;
LPSERVENT lpServEnt;
SOCKADDR_IN sockAddr;
SOCKET hServerSocket = INVALID_SOCKET;
struct in_addr addr;
// If the user input is an alpha name for the host, use gethostbyname()
// If not, get host by addr (assume IPv4)
if(isalpha(server[0]))
lpHostEnt = gethostbyname(server);
else
{
addr.s_addr = inet_addr(server);
if(addr.s_addr == INADDR_NONE)
{
m_oError = CSMTP_BAD_IPV4_ADDR;
return INVALID_SOCKET;
}
else
lpHostEnt = gethostbyaddr((char *) &addr, 4, AF_INET);
}
if(lpHostEnt != NULL)
{
if((hServerSocket = socket(PF_INET, SOCK_STREAM,0)) != INVALID_SOCKET)
{
if(port != NULL)
nProtocolPort = htons(port);
else
{
lpServEnt = getservbyname("mail", 0);
if (lpServEnt == NULL)
nProtocolPort = htons(25);
else
nProtocolPort = lpServEnt->s_port;
}
sockAddr.sin_family = AF_INET;
sockAddr.sin_port = nProtocolPort;
sockAddr.sin_addr = *((LPIN_ADDR)*lpHostEnt->h_addr_list);
if(connect(hServerSocket,(PSOCKADDR)&sockAddr,sizeof(sockAddr)) == SOCKET_ERROR)
{
m_oError = CSMTP_WSA_CONNECT;
hServerSocket = INVALID_SOCKET;
}
}
else
{
m_oError = CSMTP_WSA_INVALID_SOCKET;
return INVALID_SOCKET;
}
}
else
{
m_oError = CSMTP_WSA_GETHOSTBY_NAME_ADDR;
return INVALID_SOCKET;
}
return hServerSocket;
}
////////////////////////////////////////////////////////////////////////////////
// NAME: SmtpXYZdigits
// DESCRIPTION: Converts three letters from RecvBuf to the number.
// ARGUMENTS: none
// USES GLOBAL: RecvBuf
// MODIFIES GL: none
// RETURNS: integer number
// AUTHOR: Jakub Piwowarczyk
// AUTHOR/DATE: JP 2010-01-28
////////////////////////////////////////////////////////////////////////////////
int CSmtp::SmtpXYZdigits()
{
assert(RecvBuf);
if(RecvBuf == NULL)
return 0;
return (RecvBuf[0]-'0')*100 + (RecvBuf[1]-'0')*10 + RecvBuf[2]-'0';
}
////////////////////////////////////////////////////////////////////////////////
// NAME: FormatHeader
// DESCRIPTION: Prepares a header of the message.
// ARGUMENTS: char* header - formated header string
// USES GLOBAL: Recipients, CCRecipients, BCCRecipients
// MODIFIES GL: none
// RETURNS: integer number
// AUTHOR: Jakub Piwowarczyk
// AUTHOR/DATE: JP 2010-01-28
////////////////////////////////////////////////////////////////////////////////
bool CSmtp::FormatHeader(char* header)
{
int i,s = 0;
TCHAR szDate[500];
TCHAR sztTime[500];
char *to = NULL;
char *cc = NULL;
char *bcc = NULL;
// check for at least one recipient
if(Recipients.size())
{
for (unsigned int i=s=0;i<Recipients.size();i++)
s += Recipients[i].Mail.size() + Recipients[i].Name.size() + 3;
if (s == 0)
s = 1;
if((to = new char[s]) == NULL)
{
m_oError = CSMTP_LACK_OF_MEMORY;
return false;
}
to[0] = '\0';
for (i=0;i<Recipients.size();i++)
{
i > 0 ? strcat(to,","):strcpy(to,"");
strcat(to,Recipients[i].Name.c_str());
strcat(to,"<");
strcat(to,Recipients[i].Mail.c_str());
strcat(to,">");
}
}
else
{
m_oError = CSMTP_UNDEF_RECIPENTS;
return false;
}
if(CCRecipients.size())
{
for (i=s=0;i<CCRecipients.size();i++)
s += CCRecipients[i].Mail.size() + CCRecipients[i].Name.size() + 3;
if (s == 0)
s = 1;
if((cc = new char[s]) == NULL)
{
m_oError = CSMTP_LACK_OF_MEMORY;
delete[] to;
return false;
}
cc[0] = '\0';
for (i=0;i<CCRecipients.size();i++)
{
i > 0 ? strcat(cc,","):strcpy(cc,"");
strcat(cc,CCRecipients[i].Name.c_str());
strcat(cc,"<");
strcat(cc,CCRecipients[i].Mail.c_str());
strcat(cc,">");
}
}
if(BCCRecipients.size())
{
for (i=s=0;i<BCCRecipients.size();i++)
s += BCCRecipients[i].Mail.size() + BCCRecipients[i].Name.size() + 3;
if(s == 0)
s=1;
if((bcc = new char[s]) == NULL)
{
m_oError = CSMTP_LACK_OF_MEMORY;
delete[] to;
delete[] cc;
return false;
}
bcc[0] = '\0';
for (i=0;i<BCCRecipients.size();i++)
{
i > 0 ? strcat(bcc,","):strcpy(bcc,"");
strcat(bcc,BCCRecipients[i].Name.c_str());
strcat(bcc,"<");
strcat(bcc,BCCRecipients[i].Mail.c_str());
strcat(bcc,">");
}
}
// Date: <SP> <dd> <SP> <mon> <SP> <yy> <SP> <hh> ":" <mm> ":" <ss> <SP> <zone> <CRLF>
SYSTEMTIME st={0};
::GetSystemTime(&st);
::GetDateFormat(MAKELCID(0x0409,SORT_DEFAULT),0,&st,"ddd\',\' dd MMM yyyy",szDate,sizeof(szDate));
::GetTimeFormat(MAKELCID(0x0409,SORT_DEFAULT),TIME_FORCE24HOURFORMAT,&st,"HH\':\'mm\':\'ss",sztTime,sizeof(sztTime));
sprintf(header,"Date: %s %s\r\n", szDate, sztTime);
// From: <SP> <sender> <SP> "<" <sender-email> ">" <CRLF>
if(m_pcMailFrom == NULL)
{
m_oError = CSMTP_UNDEF_MAILFROM;
delete[] to;
delete[] cc;
delete[] bcc;
return false;
}
strcat(header,"From: ");
if(m_pcNameFrom)
strcat(header, m_pcNameFrom);
strcat(header," <");
if(m_pcNameFrom)
strcat(header,m_pcMailFrom);
else
strcat(header,"mail@domain.com");
strcat(header, ">\r\n");
// X-Mailer: <SP> <xmailer-app> <CRLF>
if (m_pcXMailer != NULL)
{
strcat(header,"X-Mailer: ");
strcat(header, m_pcXMailer);
strcat(header, "\r\n");
}
// Reply-To: <SP> <reverse-path> <CRLF>
if(m_pcReplyTo != NULL)
{
strcat(header, "Reply-To: ");
strcat(header, m_pcReplyTo);
strcat(header, "\r\n");
}
// X-Priority: <SP> <number> <CRLF>
switch(m_iXPriority)
{
case XPRIORITY_HIGH:
strcat(header,"X-Priority: 2 (High)\r\n");
break;
case XPRIORITY_NORMAL:
strcat(header,"X-Priority: 3 (Normal)\r\n");
break;
case XPRIORITY_LOW:
strcat(header,"X-Priority: 4 (Low)\r\n");
break;
default:
strcat(header,"X-Priority: 3 (Normal)\r\n");
}
// To: <SP> <remote-user-mail> <CRLF>
strcat(header,"To: ");
strcat(header, to);
strcat(header, "\r\n");
// Cc: <SP> <remote-user-mail> <CRLF>
if(CCRecipients.size())
{
strcat(header,"Cc: ");
strcat(header, cc);
strcat(header, "\r\n");
}
if(BCCRecipients.size())
{
strcat(header,"Bcc: ");
strcat(header, bcc);
strcat(header, "\r\n");
}
// Subject: <SP> <subject-text> <CRLF>
if(m_pcSubject == NULL)
{
m_oError = CSMTP_UNDEF_SUBJECT;
strcat(header, "Subject: ");
}
else
{
strcat(header, "Subject: ");
strcat(header, m_pcSubject);
}
strcat(header, "\r\n");
// MIME-Version: <SP> 1.0 <CRLF>
strcat(header,"MIME-Version: 1.0\r\n");
if(!Attachments.size())
{ // no attachments
strcat(header,"Content-type: text/plain; charset=US-ASCII\r\n");
strcat(header,"Content-Transfer-Encoding: 7bit\r\n");
strcat(SendBuf,"\r\n");
}
else
{ // there is one or more attachments
strcat(header,"Content-Type: multipart/mixed; boundary=\"");
strcat(header,BOUNDARY_TEXT);
strcat(header,"\"\r\n");
strcat(header,"\r\n");
// first goes text message
strcat(SendBuf,"--");
strcat(SendBuf,BOUNDARY_TEXT);
strcat(SendBuf,"\r\n");
strcat(SendBuf,"Content-type: text/plain; charset=US-ASCII\r\n");
strcat(SendBuf,"Content-Transfer-Encoding: 7bit\r\n");
strcat(SendBuf,"\r\n");
}
// clean up
delete[] to;
delete[] cc;
delete[] bcc;
// done
return true;
}
////////////////////////////////////////////////////////////////////////////////
// NAME: ReceiveData
// DESCRIPTION: Receives a row terminated '\n'.
// ARGUMENTS: none
// USES GLOBAL: RecvBuf
// MODIFIES GL: RecvBuf
// RETURNS: false - operation failed
// true - operation is successful
// AUTHOR: Jakub Piwowarczyk
// AUTHOR/DATE: JP 2010-01-28
////////////////////////////////////////////////////////////////////////////////
bool CSmtp::ReceiveData()
{
int res,i = 0;
assert(RecvBuf);
if(RecvBuf == NULL)
return false;
do
{
if(i >= BUFFER_SIZE)
{
m_oError = CSMTP_LACK_OF_MEMORY;
return false;
}
if( (res = recv(hSocket,&RecvBuf[i],1,0)) == SOCKET_ERROR )
{
m_oError = CSMTP_WSA_RECV;
return false;
}
if(res)
i++;
}while(RecvBuf[i-1]!='\n');
if(!res && !i)
{
m_oError = CSMTP_CONNECTION_CLOSED;
return false;
}
RecvBuf[i] = '\0';
return true;
}
////////////////////////////////////////////////////////////////////////////////
// NAME: SendData
// DESCRIPTION: Sends data from SendBuf buffer.
// ARGUMENTS: none
// USES GLOBAL: SendBuf
// MODIFIES GL: none
// RETURNS: false - operation failed
// true - operation is successful
// AUTHOR: Jakub Piwowarczyk
// AUTHOR/DATE: JP 2010-01-28
////////////////////////////////////////////////////////////////////////////////
bool CSmtp::SendData()
{
int idx = 0,res,nLeft = strlen(SendBuf);
assert(SendBuf);
if(RecvBuf == NULL)
return false;
while(nLeft > 0)
{
if( res = send(hSocket,&SendBuf[idx],nLeft,0) == SOCKET_ERROR)
{
m_oError = CSMTP_WSA_SEND;
return false;
}
if(!res)
break;
nLeft -= res;
idx += res;
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
// NAME: GetLastError
// DESCRIPTION: Return the code of current error.
// ARGUMENTS: none
// USES GLOBAL: m_oError
// MODIFIES GL: none
// RETURNS: enum CSmtpError - error code
// AUTHOR: Jakub Piwowarczyk
// AUTHOR/DATE: JP 2010-01-28
////////////////////////////////////////////////////////////////////////////////
CSmtpError CSmtp::GetLastError()
{
return m_oError;
}
////////////////////////////////////////////////////////////////////////////////
// NAME: GetLocalHostName
// DESCRIPTION: Returns local host name.
// ARGUMENTS: none
// USES GLOBAL: m_pcLocalHostName
// MODIFIES GL: m_oError, m_pcLocalHostName
// RETURNS: socket of the remote service
// AUTHOR: Jakub Piwowarczyk
// AUTHOR/DATE: JP 2010-01-28
////////////////////////////////////////////////////////////////////////////////
const char* const CSmtp::GetLocalHostName()
{
if(m_pcLocalHostName)
delete[] m_pcLocalHostName;
if((m_pcLocalHostName = new char[255]) == NULL)
{
m_oError = CSMTP_LACK_OF_MEMORY;
return NULL;
}
if(gethostname((char FAR*)m_pcLocalHostName,255) == SOCKET_ERROR)
m_oError = CSMTP_WSA_HOSTNAME;
return m_pcLocalHostName;
}
////////////////////////////////////////////////////////////////////////////////
// NAME: GetRecipientCount
// DESCRIPTION: Returns the number of recipents.
// ARGUMENTS: none
// USES GLOBAL: Recipients
// MODIFIES GL: none
// RETURNS: number of recipents
// AUTHOR: Jakub Piwowarczyk
// AUTHOR/DATE: JP 2010-01-28
////////////////////////////////////////////////////////////////////////////////
unsigned const int CSmtp::GetRecipientCount()
{
return Recipients.size();
}
////////////////////////////////////////////////////////////////////////////////
// NAME: GetBCCRecipientCount
// DESCRIPTION: Returns the number of bcc-recipents.
// ARGUMENTS: none
// USES GLOBAL: BCCRecipients
// MODIFIES GL: none
// RETURNS: number of bcc-recipents
// AUTHOR: Jakub Piwowarczyk
// AUTHOR/DATE: JP 2010-01-28
////////////////////////////////////////////////////////////////////////////////
unsigned const int CSmtp::GetBCCRecipientCount()
{
return BCCRecipients.size();
}
////////////////////////////////////////////////////////////////////////////////
// NAME: GetCCRecipientCount
// DESCRIPTION: Returns the number of cc-recipents.
// ARGUMENTS: none
// USES GLOBAL: CCRecipients
// MODIFIES GL: none
// RETURNS: number of cc-recipents
// AUTHOR: Jakub Piwowarczyk
// AUTHOR/DATE: JP 2010-01-28
////////////////////////////////////////////////////////////////////////////////
unsigned const int CSmtp::GetCCRecipientCount()
{
return CCRecipients.size();
}
////////////////////////////////////////////////////////////////////////////////
// NAME: GetMessageBody
// DESCRIPTION: Returns the number of cc-recipents.
// ARGUMENTS: none
// USES GLOBAL: CCRecipients
// MODIFIES GL: none
// RETURNS: number of cc-recipents
// AUTHOR: Jakub Piwowarczyk
// AUTHOR/DATE: JP 2010-01-28
////////////////////////////////////////////////////////////////////////////////
const char* const CSmtp::GetMessageBody()
{
return m_pcMsgBody;
}
////////////////////////////////////////////////////////////////////////////////
// NAME: GetReplyTo
// DESCRIPTION: Returns m_pcReplyTo string.
// ARGUMENTS: none
// USES GLOBAL: m_pcReplyTo
// MODIFIES GL: none
// RETURNS: m_pcReplyTo string
// AUTHOR: Jakub Piwowarczyk
// AUTHOR/DATE: JP 2010-01-28
////////////////////////////////////////////////////////////////////////////////
const char* const CSmtp::GetReplyTo()
{
return m_pcReplyTo;
}
////////////////////////////////////////////////////////////////////////////////
// NAME: GetMailFrom
// DESCRIPTION: Returns m_pcMailFrom string.
// ARGUMENTS: none
// USES GLOBAL: m_pcMailFrom
// MODIFIES GL: none
// RETURNS: m_pcMailFrom string
// AUTHOR: Jakub Piwowarczyk
// AUTHOR/DATE: JP 2010-01-28
////////////////////////////////////////////////////////////////////////////////
const char* const CSmtp::GetMailFrom()
{
return m_pcMailFrom;
}
////////////////////////////////////////////////////////////////////////////////
// NAME: GetSenderName
// DESCRIPTION: Returns m_pcNameFrom string.
// ARGUMENTS: none
// USES GLOBAL: m_pcNameFrom
// MODIFIES GL: none
// RETURNS: m_pcNameFrom string
// AUTHOR: Jakub Piwowarczyk
// AUTHOR/DATE: JP 2010-01-28
////////////////////////////////////////////////////////////////////////////////
const char* const CSmtp::GetSenderName()
{
return m_pcNameFrom;
}
////////////////////////////////////////////////////////////////////////////////
// NAME: GetSubject
// DESCRIPTION: Returns m_pcSubject string.
// ARGUMENTS: none
// USES GLOBAL: m_pcSubject
// MODIFIES GL: none
// RETURNS: m_pcSubject string
// AUTHOR: Jakub Piwowarczyk
// AUTHOR/DATE: JP 2010-01-28
////////////////////////////////////////////////////////////////////////////////
const char* const CSmtp::GetSubject()
{
return m_pcSubject;
}
////////////////////////////////////////////////////////////////////////////////
// NAME: GetXMailer
// DESCRIPTION: Returns m_pcXMailer string.
// ARGUMENTS: none
// USES GLOBAL: m_pcXMailer
// MODIFIES GL: none
// RETURNS: m_pcXMailer string
// AUTHOR: Jakub Piwowarczyk
// AUTHOR/DATE: JP 2010-01-28
////////////////////////////////////////////////////////////////////////////////
const char* const CSmtp::GetXMailer()
{
return m_pcXMailer;
}
////////////////////////////////////////////////////////////////////////////////
// NAME: GetXPriority
// DESCRIPTION: Returns m_iXPriority string.
// ARGUMENTS: none
// USES GLOBAL: m_iXPriority
// MODIFIES GL: none
// RETURNS: CSmptXPriority m_pcXMailer
// AUTHOR: Jakub Piwowarczyk
// AUTHOR/DATE: JP 2010-01-28
////////////////////////////////////////////////////////////////////////////////
CSmptXPriority CSmtp::GetXPriority()
{
return m_iXPriority;
}
////////////////////////////////////////////////////////////////////////////////
// NAME: SetXPriority
// DESCRIPTION: Setting priority of the message.
// ARGUMENTS: CSmptXPriority priority - priority of the message ( XPRIORITY_HIGH,
// XPRIORITY_NORMAL, XPRIORITY_LOW)
// USES GLOBAL: none
// MODIFIES GL: m_iXPriority
// RETURNS: none
// AUTHOR: Jakub Piwowarczyk
// AUTHOR/DATE: JP 2010-01-28
////////////////////////////////////////////////////////////////////////////////
void CSmtp::SetXPriority(CSmptXPriority priority)
{
m_iXPriority = priority;
}
////////////////////////////////////////////////////////////////////////////////
// NAME: SetMessageBody
// DESCRIPTION: Setting the text of the message.
// ARGUMENTS: const char *body - text of the message
// USES GLOBAL: m_pcMsgBody
// MODIFIES GL: m_pcMsgBody, m_oError
// RETURNS: none
// AUTHOR: Jakub Piwowarczyk
// AUTHOR/DATE: JP 2010-01-28
////////////////////////////////////////////////////////////////////////////////
void CSmtp::SetMessageBody(const char *body)
{
assert(body);
int s = strlen(body);
if (m_pcMsgBody)
{
delete[] m_pcMsgBody;
m_pcMsgBody = NULL;
}
if((m_pcMsgBody = new char[s+1]) == NULL)
{
m_oError = CSMTP_LACK_OF_MEMORY;
return;
}
strcpy(m_pcMsgBody, body);
}
////////////////////////////////////////////////////////////////////////////////
// NAME: SetReplyTo
// DESCRIPTION: Setting the return address.
// ARGUMENTS: const char *replyto - return address
// USES GLOBAL: m_pcReplyTo
// MODIFIES GL: m_pcReplyTo, m_oError
// RETURNS: none
// AUTHOR: Jakub Piwowarczyk
// AUTHOR/DATE: JP 2010-01-28
////////////////////////////////////////////////////////////////////////////////
void CSmtp::SetReplyTo(const char *replyto)
{
assert(replyto);
int s = strlen(replyto);
if (m_pcReplyTo)
{
delete[] m_pcReplyTo;
m_pcReplyTo = NULL;
}
if((m_pcReplyTo = new char[s+1]) == NULL)
{
m_oError = CSMTP_LACK_OF_MEMORY;
return;
}
strcpy(m_pcReplyTo, replyto);
}
////////////////////////////////////////////////////////////////////////////////
// NAME: SetSenderMail
// DESCRIPTION: Setting sender's mail.
// ARGUMENTS: const char *email - sender's e-mail
// USES GLOBAL: m_pcMailFrom
// MODIFIES GL: m_pcMailFrom, m_oError
// RETURNS: none
// AUTHOR: Jakub Piwowarczyk
// AUTHOR/DATE: JP 2010-01-28
////////////////////////////////////////////////////////////////////////////////
void CSmtp::SetSenderMail(const char *email)
{
assert(email);
int s = strlen(email);
if (m_pcMailFrom)
{
delete[] m_pcMailFrom;
m_pcMailFrom = NULL;
}
if((m_pcMailFrom = new char[s+1]) == NULL)
{
m_oError = CSMTP_LACK_OF_MEMORY;
return;
}
strcpy(m_pcMailFrom, email);
}
////////////////////////////////////////////////////////////////////////////////
// NAME: SetSenderName
// DESCRIPTION: Setting sender's name.
// ARGUMENTS: const char *name - sender's name
// USES GLOBAL: m_pcNameFrom
// MODIFIES GL: m_pcNameFrom, m_oError
// RETURNS: none
// AUTHOR: Jakub Piwowarczyk
// AUTHOR/DATE: JP 2010-01-28
////////////////////////////////////////////////////////////////////////////////
void CSmtp::SetSenderName(const char *name)
{
assert(name);
int s = strlen(name);
if (m_pcNameFrom)
{
delete[] m_pcNameFrom;
m_pcNameFrom = NULL;
}
if((m_pcNameFrom = new char[s+1]) == NULL)
{
m_oError = CSMTP_LACK_OF_MEMORY;
return;
}
strcpy(m_pcNameFrom, name);
}
////////////////////////////////////////////////////////////////////////////////
// NAME: SetSubject
// DESCRIPTION: Setting subject of the message.
// ARGUMENTS: const char *subject - subject of the message
// USES GLOBAL: m_pcSubject
// MODIFIES GL: m_pcSubject, m_oError
// RETURNS: none
// AUTHOR: Jakub Piwowarczyk
// AUTHOR/DATE: JP 2010-01-28
////////////////////////////////////////////////////////////////////////////////
void CSmtp::SetSubject(const char *subject)
{
assert(subject);
int s = strlen(subject);
if (m_pcSubject)
{
delete[] m_pcSubject;
m_pcSubject = NULL;
}
if((m_pcSubject = new char[s+1]) == NULL)
{
m_oError = CSMTP_LACK_OF_MEMORY;
return;
}
strcpy(m_pcSubject, subject);
}
////////////////////////////////////////////////////////////////////////////////
// NAME: SetSubject
// DESCRIPTION: Setting the name of program which is sending the mail.
// ARGUMENTS: const char *xmailer - programe name
// USES GLOBAL: m_pcXMailer
// MODIFIES GL: m_pcXMailer, m_oError
// RETURNS: none
// AUTHOR: Jakub Piwowarczyk
// AUTHOR/DATE: JP 2010-01-28
////////////////////////////////////////////////////////////////////////////////
void CSmtp::SetXMailer(const char *xmailer)
{
assert(xmailer);
int s = strlen(xmailer);
if (m_pcXMailer)
{
delete[] m_pcXMailer;
m_pcXMailer = NULL;
}
if((m_pcXMailer = new char[s+1]) == NULL)
{
m_oError = CSMTP_LACK_OF_MEMORY;
return;
}
strcpy(m_pcXMailer, xmailer);
}
////////////////////////////////////////////////////////////////////////////////
// NAME: SetLogin
// DESCRIPTION: Setting the login of SMTP account's owner.
// ARGUMENTS: const char *login - login of SMTP account's owner
// USES GLOBAL: m_pcLogin
// MODIFIES GL: m_pcLogin, m_oError
// RETURNS: none
// AUTHOR: Jakub Piwowarczyk
// AUTHOR/DATE: JP 2010-01-28
////////////////////////////////////////////////////////////////////////////////
void CSmtp::SetLogin(const char *login)
{
assert(login);
int s = strlen(login);
if (m_pcLogin)
{
delete[] m_pcLogin;
m_pcLogin = NULL;
}
if((m_pcLogin = new char[s+1]) == NULL)
{
m_oError = CSMTP_LACK_OF_MEMORY;
return;
}
strcpy(m_pcLogin, login);
}
////////////////////////////////////////////////////////////////////////////////
// NAME: SetPassword
// DESCRIPTION: Setting the password of SMTP account's owner.
// ARGUMENTS: const char *password - password of SMTP account's owner
// USES GLOBAL: m_pcPassword
// MODIFIES GL: m_pcPassword, m_oError
// RETURNS: none
// AUTHOR: Jakub Piwowarczyk
// AUTHOR/DATE: JP 2010-01-28
////////////////////////////////////////////////////////////////////////////////
void CSmtp::SetPassword(const char *password)
{
assert(password);
int s = strlen(password);
if (m_pcPassword)
{
delete[] m_pcPassword;
m_pcPassword = NULL;
}
if((m_pcPassword = new char[s+1]) == NULL)
{
m_oError = CSMTP_LACK_OF_MEMORY;
return;
}
strcpy(m_pcPassword, password);
}
////////////////////////////////////////////////////////////////////////////////
// NAME: SetSMTPServer
// DESCRIPTION: Setting the SMTP service name and port.
// ARGUMENTS: const char* SrvName - SMTP service name
// const unsigned short SrvPort - SMTO service port
// USES GLOBAL: m_pcSMTPSrvName
// MODIFIES GL: m_pcSMTPSrvName, m_oError
// RETURNS: none
// AUTHOR: Jakub Piwowarczyk
// AUTHOR/DATE: JP 2010-01-28
////////////////////////////////////////////////////////////////////////////////
void CSmtp::SetSMTPServer(const char* SrvName,const unsigned short SrvPort)
{
assert(SrvName);
m_iSMTPSrvPort = SrvPort;
int s = strlen(SrvName);
if(m_pcSMTPSrvName)
{
delete[] m_pcSMTPSrvName;
m_pcSMTPSrvName = NULL;
}
if((m_pcSMTPSrvName = new char[s+1]) == NULL)
{
m_oError = CSMTP_LACK_OF_MEMORY;
return;
}
strcpy(m_pcSMTPSrvName, SrvName);
}
////////////////////////////////////////////////////////////////////////////////
// NAME: GetErrorText (friend function)
// DESCRIPTION: Returns the string for specified error code.
// ARGUMENTS: CSmtpError ErrorId - error code
// USES GLOBAL: none
// MODIFIES GL: none
// RETURNS: error string
// AUTHOR: Jakub Piwowarczyk
// AUTHOR/DATE: JP 2010-01-28
////////////////////////////////////////////////////////////////////////////////
char* GetErrorText(CSmtpError ErrorId)
{
switch(ErrorId)
{
case CSMTP_NO_ERROR:
return "";
case CSMTP_WSA_STARTUP:
return "Unable to initialise winsock2.";
case CSMTP_WSA_VER:
return "Wrong version of the winsock2.";
case CSMTP_WSA_SEND:
return "Function send() failed.";
case CSMTP_WSA_RECV:
return "Function recv() failed.";
case CSMTP_WSA_CONNECT:
return "Function connect failed.";
case CSMTP_WSA_GETHOSTBY_NAME_ADDR:
return "Functions gethostbyname() or gethostbyaddr() failed.";
case CSMTP_WSA_INVALID_SOCKET:
return "Invalid winsock2 socket.";
case CSMTP_WSA_HOSTNAME:
return "Function hostname() failed.";
case CSMTP_BAD_IPV4_ADDR:
return "Improper IPv4 address.";
case CSMTP_UNDEF_MSG_HEADER:
return "Undefined message header.";
case CSMTP_UNDEF_MAILFROM:
return "Undefined from is the mail.";
case CSMTP_UNDEF_SUBJECT:
return "Undefined message subject.";
case CSMTP_UNDEF_RECIPENTS:
return "Undefined at least one reciepent.";
case CSMTP_UNDEF_RECIPENT_MAIL:
return "Undefined recipent mail.";
case CSMTP_UNDEF_LOGIN:
return "Undefined user login.";
case CSMTP_UNDEF_PASSWORD:
return "Undefined user password.";
case CSMTP_COMMAND_MAIL_FROM:
return "Server returned error after sending MAIL FROM.";
case CSMTP_COMMAND_EHLO:
return "Server returned error after sending EHLO.";
case CSMTP_COMMAND_AUTH_LOGIN:
return "Server returned error after sending AUTH LOGIN.";
case CSMTP_COMMAND_DATA:
return "Server returned error after sending DATA.";
case CSMTP_COMMAND_QUIT:
return "Server returned error after sending QUIT.";
case CSMTP_COMMAND_RCPT_TO:
return "Server returned error after sending RCPT TO.";
case CSMTP_MSG_BODY_ERROR:
return "Error in message body";
case CSMTP_CONNECTION_CLOSED:
return "Server has closed the connection.";
case CSMTP_SERVER_NOT_READY:
return "Server is not ready.";
case CSMTP_SERVER_NOT_RESPONDING:
return "Server not responding";
case CSMTP_FILE_NOT_EXIST:
return "File not exist.";
case CSMTP_MSG_TOO_BIG:
return "Message is too big.";
case CSMTP_BAD_LOGIN_PASS:
return "Bad login or password.";
case CSMTP_UNDEF_XYZ_RESPOMSE:
return "Undefined xyz SMTP response.";
case CSMTP_LACK_OF_MEMORY:
return "Lack of memory.";
default:
return "Undefined error id.";
}
}
#pragma warning(pop)