Click here to Skip to main content
Click here to Skip to main content
Add your own
alternative version
Go to top

SMTP Client

, 16 Jul 2010
The CSmtp class allows to send emails with attachments. It only provides the AUTH LOGIN authentication.
CSmtp.zip
CSmtp
CSmtp.dsp
CSmtp.dsw
CSmtp_v1_1.zip
CSmtp.dsp
CSmtp.dsw
CSmtp_v1_2.zip
CSmtp.dsp
CSmtp.dsw
CSmtp_v1_3.zip
CSmtp_v1_3
CSmtp.dsp
CSmtp.dsw
CSmtp_v1_4.zip
CSmtp_v1_4
CSmtp.dsp
CSmtp.dsw
CSmtp.ncb
CSmtp.opt
CSmtp.plg
CSmtp_v1_5.zip
CSmtp_v1_5
CSmtp.dsp
CSmtp.dsw
CSmtp.ncb
CSmtp.opt
CSmtp.plg
CSmtp_v1_6.zip
CSmtp_v1_6
CSmtp.dsp
CSmtp.dsw
CSmtp.opt
CSmtp.plg
CSmtp_v1_7.zip
CSmtp_v1_7
CSmtp.dsp
CSmtp.dsw
CSmtp.ncb
CSmtp.opt
CSmtp_v1_8a.zip
CSmtp_v1_8a
CSmtp.dsp
CSmtp.dsw
CSmtp_v1_8b.zip
CSmtp_v1_8b
makefile
//////////////////////////////////////////////////////////////////////
// Original class CFastSmtp written by 
// christopher w. backen <immortal@cox.net>
// More details at: http://www.codeproject.com/KB/IP/zsmtp.aspx
// 
// Modifications:
// 1. name of the class and some functions
// 2. new functions added: SendData,ReceiveData and more
// 3. authentication added
// 4. attachments added
// introduced by Jakub Piwowarczyk <podsaski@gmail.com> 
// More details at: http://www.codeproject.com/KB/mcpp/CSmtp.aspx
//////////////////////////////////////////////////////////////////////

#include "CSmtp.h"

#pragma warning(push)
#pragma warning(disable:4786)

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CSmtp::CSmtp()
{
	// Initialize variables
  m_bCon = false;

	m_oError = CSMTP_NO_ERROR;
	
	m_iXPriority = XPRIORITY_NORMAL;

	m_pcLocalHostName = NULL;
	m_pcRemoteHostName = NULL;
	m_pcMailFrom = NULL;
	m_pcNameFrom = NULL;
	m_pcSubject = NULL;
	m_pcMsgBody = NULL;
	m_pcXMailer = NULL;
	m_pcReplyTo = NULL;
	m_pcLogin = NULL;
	m_pcPassword = NULL;
	RecvBuf = new char[BUFFER_SIZE];
	SendBuf = new char[BUFFER_SIZE];
	
	// 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;
	}    
}

CSmtp::~CSmtp()
{
	// Clear vectors
	Recipients.clear();
	CCRecipients.clear();
	BCCRecipients.clear();
	Attachments.clear();

	// Free memory
	if (m_pcLocalHostName)
		delete[] m_pcLocalHostName;
	if (m_pcRemoteHostName)
		delete[] m_pcRemoteHostName;
	if (m_pcMailFrom)
		delete[] m_pcMailFrom;
	if (m_pcNameFrom)
		delete[] m_pcNameFrom;
	if (m_pcSubject)
		delete[] m_pcSubject;
	if (m_pcMsgBody)
		delete[] m_pcMsgBody;
	if (m_pcXMailer)
		delete[] m_pcXMailer;
	if (m_pcReplyTo)
		delete[] m_pcReplyTo;
	if (m_pcLogin)
		delete[] m_pcLogin;
	if (m_pcPassword)
		delete[] m_pcPassword;

	delete[] SendBuf;
	delete[] RecvBuf;
	
	// Close connection
	if (m_bCon)
		Disconnect();
	
	// Cleanup
	WSACleanup();
}

//////////////////////////////////////////////////////////////////////
// Methods
//////////////////////////////////////////////////////////////////////

bool CSmtp::AddAttachment(const char *path)
{
	std::string str(path);
	Attachments.insert(Attachments.end(),str);
	return true;
}

bool CSmtp::AddRecipient(const char *email, const char *name)
{
	assert(email);
	
	if(!email)
		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;    
}

bool CSmtp::AddCCRecipient(const char *email, const char *name)
{
	assert(email);
	
	if(!email)
		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;
}

bool CSmtp::AddBCCRecipient(const char *email, const char *name)
{
	assert(email);
	
	if(!email)
		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;
}

bool CSmtp::Disconnect()
{
	if (!m_bCon)
    return false;
	
	// QUIT <CRLF>
	strcpy(SendBuf,"QUIT\r\n");
	if(!SendData())
		return false;
	Sleep(DELAY_IN_MS);
	if(!ReceiveData())
		return false;

	switch(SmtpXYZdigits())
	{
		case 221:
			break;
		default:
			m_oError = CSMTP_COMMAND_QUIT;
			m_bCon = false;
			hSocket = NULL;
			return false;
	}

	m_bCon = false;
	hSocket = NULL;
	return true;
}

bool CSmtp::Send()
{
	unsigned int i,rcpt_count,res,FileId;
	char *FileBuf = NULL, *FileName = NULL;
	FILE* hFile = NULL;
	unsigned long int FileSize,TotalSize,MsgPart;
	
	// 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;
	Sleep(DELAY_IN_MS);
	if(!ReceiveData())
		return false;

	switch(SmtpXYZdigits())
	{
		case 250:
			break;
		default:
			m_oError = CSMTP_COMMAND_MAIL_FROM;
			return false;
	}

	// 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;
		Sleep(DELAY_IN_MS);
		if(!ReceiveData())
			return false;

		switch(SmtpXYZdigits())
		{
			case 250:
				break;
			default:
				m_oError = CSMTP_COMMAND_RCPT_TO;
				rcpt_count--;
		}
	}
	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;
		Sleep(DELAY_IN_MS);
		if(!ReceiveData())
			return false;
	}
	for(i=0;i<BCCRecipients.size();i++)
	{
		sprintf(SendBuf,"RCPT TO:<%s>\r\n",(BCCRecipients.at(i).Mail).c_str());
		if(!SendData())
			return false;
		Sleep(DELAY_IN_MS);
		if(!ReceiveData())
			return false;
	}
	
	// DATA <CRLF>
	strcpy(SendBuf,"DATA\r\n");
	if(!SendData())
		return false;
	Sleep(DELAY_IN_MS);
	if(!ReceiveData())
		return false;
	
	switch(SmtpXYZdigits())
	{
		case 354:
			break;
		default:
			m_oError = CSMTP_COMMAND_DATA;
			return false;
	}
	
	// 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)
	FileBuf = new char[55];
	FileName = new char[255];
	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
	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;
	Sleep(DELAY_IN_MS);
	if(!ReceiveData())
		return false;

	switch(SmtpXYZdigits())
	{
		case 250:
			break;
		default:
			m_oError = CSMTP_MSG_BODY_ERROR;
			return false;
	}

	return true;
}

bool CSmtp::ConnectServer(const char *server,const unsigned short port)
{
	int s;

	assert(server);
	
	if (m_bCon)
		Disconnect();
	m_bCon = false;

	// connecting to remote host:
	if( (hSocket = ConnectRemoteServer(server, port)) == INVALID_SOCKET ) 
	{
		m_oError = CSMTP_WSA_INVALID_SOCKET;
		return false;
	}
	Sleep(DELAY_IN_MS);
	if(!ReceiveData())
		return false;

	switch(SmtpXYZdigits())
	{
		case 220:
			break;
		default:
			m_oError = CSMTP_SERVER_NOT_READY;
			return false;
	}

	s = strlen(server);
	if (m_pcRemoteHostName)
		delete[] m_pcRemoteHostName;
	m_pcRemoteHostName = new char[s+1];
	strcpy(m_pcRemoteHostName, server);

	// EHLO <SP> <domain> <CRLF>
	sprintf(SendBuf,"EHLO %s\r\n",GetLocalHostName()!=NULL ? m_pcLocalHostName : "domain");
	if(!SendData())
		return false;
	Sleep(DELAY_IN_MS);
	if(!ReceiveData())
		return false;

	switch(SmtpXYZdigits())
	{
		case 250:
			break;
		default:
			m_oError = CSMTP_COMMAND_EHLO;
			return false;
	}

	// AUTH <SP> LOGIN <CRLF>
	strcpy(SendBuf,"AUTH LOGIN\r\n");
	if(!SendData())
		return false;
	Sleep(DELAY_IN_MS);
	if(!ReceiveData())
		return false;

	switch(SmtpXYZdigits())
	{
		case 334:
			break;
		default:
			m_oError = CSMTP_COMMAND_AUTH_LOGIN;
			return false;
	}

	// 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;
	Sleep(DELAY_IN_MS);
	if(!ReceiveData())
		return false;

	switch(SmtpXYZdigits())
	{
		case 334:
			break;
		default:
			m_oError = CSMTP_UNDEF_XYZ_RESPOMSE;
			return false;
	}
	
	// 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;
	Sleep(DELAY_IN_MS);
	if(!ReceiveData())
		return false;

	switch(SmtpXYZdigits())
	{
		case 235:
			break;
		case 535:
			m_oError = CSMTP_BAD_LOGIN_PASS;
			return false;
		default:
			m_oError = CSMTP_UNDEF_XYZ_RESPOMSE;
			return false;
	}
	
	m_bCon = true;
	return true;
}

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

int CSmtp::SmtpXYZdigits()
{
	assert(RecvBuf);
	if(RecvBuf == NULL)
		return 0;
	return (RecvBuf[0]-'0')*100 + (RecvBuf[1]-'0')*10 + RecvBuf[2]-'0';
}

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;
		to = new char[s];

		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;
		cc = new char[s];

		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;
		bcc = new char[s];

		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_pcNameFrom == NULL)
		strcpy(m_pcNameFrom,"");
	if(m_pcMailFrom == NULL)
	{
		m_oError = CSMTP_UNDEF_MAILFROM;
    delete[] to;
    delete[] cc;
    delete[] bcc;
		return false;
	}
	strcat(header,"From: ");	
	strcat(header, m_pcNameFrom);
	strcat(header," <");
	strcat(header,m_pcMailFrom);
	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:  ");
	}
	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;    
}

bool CSmtp::ReceiveData()
{
	assert(RecvBuf);

	int res;

	if(RecvBuf == NULL)
		return false;
	
	if( (res = recv(hSocket,RecvBuf,BUFFER_SIZE,0)) == SOCKET_ERROR )
	{
		m_oError = CSMTP_WSA_RECV;
		return false;
	}
	if(res == 0)
	{
		m_oError = CSMTP_CONNECTION_CLOSED;
		return false;
	}
	RecvBuf[res] = '\0';

	return true;
}

bool CSmtp::SendData()
{
	assert(SendBuf);

	int idx = 0,res,nLeft = strlen(SendBuf);
	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;
}

CSmtpError CSmtp::GetLastError()
{
	return m_oError;
}

/*
const char* const CSmtp::GetLocalHostIP()
{
	in_addr *iaHost = NULL;
	HOSTENT *pHe = NULL;
	
	if (m_pcIPAddr)
		delete[] m_pcIPAddr;
	
	if(gethostname(m_pcHostName,255) != SOCKET_ERROR)
	{
		pHe = gethostbyname(m_pcHostName);
		if (pHe != NULL) 
		{
			for (int i=0;pHe->h_addr_list[i] != 0;i++)
			{
				iaHost = (LPIN_ADDR)pHe->h_addr_list[i];
				m_pcIPAddr = inet_ntoa(*iaHost);
			}
		}            
	} 
	else 
	{
		m_oError = CSMTP_WSA_GETHOSTBY_NAME_ADDR;
		m_pcIPAddr = NULL;
	}
	
	return m_pcIPAddr;
}
*/

const char* const CSmtp::GetLocalHostName() 
{
	if(m_pcLocalHostName)
		delete[] m_pcLocalHostName;
	m_pcLocalHostName = new char[255];
	if(gethostname((char FAR*)m_pcLocalHostName,255) == SOCKET_ERROR)
		m_oError = CSMTP_WSA_HOSTNAME;
	return m_pcLocalHostName;
}

bool CSmtp::GetConnectStatus()
{
	return m_bCon;
}

unsigned const int CSmtp::GetBCCRecipientCount()
{
	return BCCRecipients.size();
}

unsigned const int CSmtp::GetCCRecipientCount() 
{
	return CCRecipients.size();
}

const char* const CSmtp::GetMessageBody() 
{
	return m_pcMsgBody;
}

unsigned const int CSmtp::GetRecipientCount()
{
	return Recipients.size();
}

const char* const CSmtp::GetReplyTo()  
{
	return m_pcReplyTo;
}

const char* const CSmtp::GetMailFrom() 
{
	return m_pcMailFrom;
}

const char* const CSmtp::GetSenderName() 
{
	return m_pcNameFrom;
}

const char* const CSmtp::GetSubject() 
{
	return m_pcSubject;
}

const char* const CSmtp::GetXMailer() 
{
	return m_pcXMailer;
}

CSmptXPriority CSmtp::GetXPriority()
{
	return m_iXPriority;
}

void CSmtp::SetXPriority(CSmptXPriority priority)
{
	m_iXPriority = priority;
}

void CSmtp::SetMessageBody(const char *body)
{
	assert(body);
	int s = strlen(body);
	if (m_pcMsgBody)
		delete[] m_pcMsgBody;
	m_pcMsgBody = new char[s+1];
	strcpy(m_pcMsgBody, body);    
}

void CSmtp::SetReplyTo(const char *replyto)
{
	assert(replyto);
	int s = strlen(replyto);
	if (m_pcReplyTo)
		delete[] m_pcReplyTo;
	m_pcReplyTo = new char[s+1];
	strcpy(m_pcReplyTo, replyto);
}

void CSmtp::SetSenderMail(const char *email)
{
	assert(email);
	int s = strlen(email);
	if (m_pcMailFrom)
		delete[] m_pcMailFrom;
	m_pcMailFrom = new char[s+1];
	strcpy(m_pcMailFrom, email);        
}

void CSmtp::SetSenderName(const char *name)
{
	assert(name);
	int s = strlen(name);
	if (m_pcNameFrom)
		delete[] m_pcNameFrom;
	m_pcNameFrom = new char[s+1];
	strcpy(m_pcNameFrom, name);
}

void CSmtp::SetSubject(const char *subject)
{
	assert(subject);
	int s = strlen(subject);
	if (m_pcSubject)
		delete[] m_pcSubject;
	m_pcSubject = new char[s+1];
	strcpy(m_pcSubject, subject);
}

void CSmtp::SetXMailer(const char *xmailer)
{
	assert(xmailer);
	int s = strlen(xmailer);
	if (m_pcXMailer)
		delete[] m_pcXMailer;
	m_pcXMailer = new char[s+1];
	strcpy(m_pcXMailer, xmailer);
}

void CSmtp::SetLogin(const char *login)
{
	assert(login);
	int s = strlen(login);
	if (m_pcLogin)
		delete[] m_pcLogin;
	m_pcLogin = new char[s+1];
	strcpy(m_pcLogin, login);
}

void CSmtp::SetPassword(const char *password)
{
	assert(password);
	int s = strlen(password);
	if (m_pcPassword)
		delete[] m_pcPassword;
	m_pcPassword = new char[s+1];
	strcpy(m_pcPassword, password);
}

//////////////////////////////////////////////////////////////////////
// Friends
//////////////////////////////////////////////////////////////////////

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_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_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.";
		default:
			return "Undefined error id.";
	}
}

#pragma warning(pop)

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Jakub Piwowarczyk
Engineer Technical University of Lodz
Poland Poland
No Biography provided

| Advertise | Privacy | Mobile
Web04 | 2.8.140916.1 | Last Updated 16 Jul 2010
Article Copyright 2008 by Jakub Piwowarczyk
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid