|
Although it's better to use:
strcat(msgHeader, "MIME-Version: 1.0\r\nContent-type: multipart/alternative;\r\n\tboundary=\"----=_NEXTPART_000\"\r\n");
and then format your message as below:
This is a multi-part message in MIME format.
------=_NEXTPART_000
Content-Type: text/plain;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
Hi there,
This is the alternative (plaintext) version of this email.
Regards,
John A. Doe
------=_NEXTPART_000
Content-Type: text/html;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
<HTML>
<BODY>
<p>Hi there,
<p>This is the primary (HTML) version of this email.
<p>Regards,
<p>John A. Doe
</BODY></HTML>
------=_NEXTPART_000--
This is the preferred method, since in the event a user receives your email on a client that doesn't accept HTML, they will have a plaintext alternative to read, otherwise they either receive a blank screen or they see the actual HTML code (depending on the client).
Just a couple things to note: 1) use a boundary identifier that is unique enough it won't chance being duplicated in any email text, and 2) note that each boundary line in the body is prefaced by two additional dashes '--' and the closing boundary is ended with two dashes.
In business, if two people always agree, one of them is unnecessary.
|
|
|
|
|
I try to use this clas and when build the project the liker shows following:
FastSmtp.obj : error LNK2001: unresolved external symbol __imp__WSACleanup@0
FastSmtp.obj : error LNK2001: unresolved external symbol __imp__recv@16
FastSmtp.obj : error LNK2001: unresolved external symbol __imp__WSAGetLastError@0
FastSmtp.obj : error LNK2001: unresolved external symbol __imp__send@16
FastSmtp.obj : error LNK2001: unresolved external symbol __imp__connect@12
FastSmtp.obj : error LNK2001: unresolved external symbol __imp__htons@4
FastSmtp.obj : error LNK2001: unresolved external symbol __imp__getservbyname@8
FastSmtp.obj : error LNK2001: unresolved external symbol __imp__socket@12
FastSmtp.obj : error LNK2001: unresolved external symbol __imp__gethostbyname@4
FastSmtp.obj : error LNK2001: unresolved external symbol __imp__inet_ntoa@4
FastSmtp.obj : error LNK2001: unresolved external symbol __imp__gethostname@8
D
Anybody can help me?
Thacks in advance
|
|
|
|
|
Me too, but I don't know what to do too 
|
|
|
|
|
Use Ws2_32.lib can solve this problem
|
|
|
|
|
Add "ws2_32.lib" to the linker arguments!
|
|
|
|
|
It seems, there are great SOCKET handles leaks in this class. I recommend to add a call to closesocket(hSocket) to the Disconnect() function and in the _connectServerSocket() function. _connectServerSocket() contains a call to the connect() function. If connect failed, call to the closesocket(hSocket) must be performed.
|
|
|
|
|
i modified to support username and password. enjoy!
CFastSmtp.h
CFastSmtp.cpp
base64.h
base64.cpp
usage
// CFastSmtp.h: interface for the Smtp class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_SMTP_H__C66CDD0A_4F6F_4465_BAD6_8FA531785B5D__INCLUDED_)
#define AFX_SMTP_H__C66CDD0A_4F6F_4465_BAD6_8FA531785B5D__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include <winsock2.h>
#include <assert.h>
#include <vector>
#include <string>
const int DEFAULT_PROTOCOL = 0;
const int NO_FLAGS = 0;
class CFastSmtp
{
public:
CFastSmtp();
virtual ~CFastSmtp();
bool AddRecipient(const char email[], const char name[]="");
bool AddBCCRecipient(const char email[], const char name[]="");
bool AddCCRecipient(const char email[], const char name[]="");
bool ConnectServer(const char server[], const unsigned short port=NULL);
bool Disconnect();
bool GetConnectStatus();
const unsigned int GetBCCRecipientCount();
const unsigned int GetCCRecipientCount();
const unsigned int GetRecipientCount();
const unsigned int GetSocket();
const char* const GetLocalHostIp();
const char* const GetLocalHostname();
const char* const GetMessageBody();
const char* const GetReplyTo();
const char* const GetSenderEmail();
const char* const GetSenderName();
const char* const GetSubject();
const char* const GetXMailer();
bool Send();
void SetMessageBody(const char body[]);
void SetSubject(const char subject[]);
void SetSenderName(const char name[]);
void SetSenderEmail(const char email[]);
void SetReplyTo(const char replyto[]);
void SetXMailer(const char xmailer[]);
void SetUserName( std::string un ){ username = un; };
std::string GetUserName() { return username; };
void SetPassward( std::string psw ) { password = psw; };
std::string GetPassward() { return password; };
private:
class CRecipient
{
public:
CRecipient()
{
m_pcEmail = NULL;
};
CRecipient& operator=(const CRecipient& src)
{
if (&src != this)
{
if (m_pcEmail)
delete [] m_pcEmail;
int s = strlen(src.m_pcEmail);
m_pcEmail = new char[s+1];
strcpy(m_pcEmail, src.m_pcEmail);
}
return (*this);
};
virtual ~CRecipient()
{
if (m_pcEmail)
delete [] m_pcEmail;
};
char* GetEmail()
{
return m_pcEmail;
};
void SetEmail(const char email[])
{
assert(email);
int s=strlen(email);
if (s > 0)
{
m_pcEmail = new char[s+1];
strcpy(m_pcEmail, email);
}
};
private:
char *m_pcEmail;
};
bool bCon;
char m_cHostName[MAX_PATH];
char* m_pcFromEmail;
char* m_pcFromName;
char* m_pcSubject;
char* m_pcMsgBody;
char* m_pcXMailer;
char* m_pcReplyTo;
char* m_pcIPAddr;
std::string username;
std::string password;
WSADATA wsaData;
SOCKET hSocket;
std::vector<crecipient*> Recipients;
std::vector<crecipient*> CCRecipients;
std::vector<crecipient*> BCCRecipients;
char* _formatHeader();
bool _formatMessage();
SOCKET _connectServerSocket(const char* server, const unsigned short port=NULL);
};
#endif // !defined(AFX_SMTP_H__C66CDD0A_4F6F_4465_BAD6_8FA531785B5D__INCLUDED_)
//********************************************************************
/*
Fast & Simple SMTP Class
Author:
christopher w. backen <immortal@cox.net>
Purpose:
Simple smtp class with handy local ip and hostname functions
ToDo:
Attachments & UUEncode/Decode
*/
//********************************************************************
//*** Change History
//*** DEVELOPER DATE MODIFICATION
//***
//*** christopher w. backen 09.05.2002 Misc. updates and corrections
//*** christopher w. backen 08.28.2001 Bug fixes & code changes
//*** christopher w. backen 04.12.2001 Release
//***
//********************************************************************
//#include "stdafx.h"
#include "FastSmtp.h"
#include "base64.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CFastSmtp::CFastSmtp()
{
// Initialize variables
bCon = false;
m_pcFromEmail = NULL;
m_pcFromName = NULL;
m_pcSubject = NULL;
m_pcMsgBody = NULL;
m_pcXMailer = NULL;
m_pcReplyTo = NULL;
m_pcIPAddr = NULL;
// Initialize WinSock
WORD wVer = MAKEWORD(2,2);
if (WSAStartup(wVer,&wsaData) != NO_ERROR) {
printf("WSAStartup %d\r\n", WSAGetLastError());
throw;
}
if (LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 2 ) {
printf("Can't find a useable WinSock DLL\r\n");
WSACleanup();
throw;
}
}
CFastSmtp::~CFastSmtp()
{
// Free recipient lists
for (unsigned int n = 0; n < Recipients.size(); n++)
delete Recipients[n];
for ( n = 0; n < CCRecipients.size(); n++)
delete CCRecipients[n];
for ( n = 0; n < BCCRecipients.size(); n++)
delete BCCRecipients[n];
// Free variables
if (m_pcFromEmail)
delete m_pcFromEmail;
if (m_pcFromName)
delete m_pcFromName;
if (m_pcSubject)
delete m_pcSubject;
if (m_pcMsgBody)
delete m_pcMsgBody;
if (m_pcXMailer)
delete m_pcXMailer;
if (m_pcReplyTo)
delete m_pcReplyTo;
// Close connection
if (bCon)
Disconnect();
// Cleanup
WSACleanup();
}
bool CFastSmtp::AddRecipient(const char email[], const char name[])
{
assert(email);
int s=strlen(email);
if (s==0)
return false;
CRecipient *pRec = new CRecipient();
char *pcBuf = new char[s+strlen(name)+4];
sprintf(pcBuf,"%s<%s>",name,email);
pRec->SetEmail(pcBuf);
Recipients.insert(Recipients.end(), pRec);
delete pcBuf;
return (true);
}
bool CFastSmtp::AddCCRecipient(const char email[], const char name[])
{
assert(email);
int s=strlen(email);
if (s==0)
return false;
CRecipient *pRec = new CRecipient();
char *pcBuf = new char[s+strlen(name)+4];
sprintf(pcBuf,"%s<%s>",name,email);
pRec->SetEmail(pcBuf);
CCRecipients.insert(CCRecipients.end(), pRec);
delete pcBuf;
return (true);
}
bool CFastSmtp::AddBCCRecipient(const char email[], const char name[])
{
assert(email);
int s=strlen(email);
if (s==0)
return false;
CRecipient *pRec = new CRecipient();
char *pcBuf = new char[s+strlen(name)+4];
sprintf(pcBuf,"%s<%s>",name,email);
pRec->SetEmail(pcBuf);
BCCRecipients.insert(BCCRecipients.end(), pRec);
delete pcBuf;
return (true);
}
bool CFastSmtp::Disconnect()
{
if (!bCon) {
printf("Not connected to server!\r\n");
return (false);
}
BYTE sReceiveBuffer[4096];
int iLength = 0;
int iEnd = 0;
if (send(hSocket, (LPSTR)"QUIT\r\n", strlen("QUIT\r\n"),
NO_FLAGS) == SOCKET_ERROR) {
printf("Socket send error: %d\r\n", WSAGetLastError());
return (false);
}
iLength = recv(hSocket, (LPSTR)sReceiveBuffer+iEnd,sizeof(sReceiveBuffer)-iEnd,
NO_FLAGS);
iEnd += iLength;
sReceiveBuffer[iEnd] = '\0';
bCon=false;
hSocket=NULL;
return (true);
}
bool CFastSmtp::Send()
{
// verify sender email
if (m_pcFromEmail == NULL) {
printf("Please specifiy a sender email address\r\n");
return (false);
}
char base64buf[1024];
BYTE sReceiveBuffer[4096];
int iLength = 0;
int iEnd = 0;
char buf[4096];
// get proper header
char* msgHeader = _formatHeader();
if (msgHeader == NULL) {
delete [] msgHeader;
printf("Failed to format message header\r\n");
return (false);
}
// start - user
strcpy(buf, "AUTH LOGIN");
strcat(buf, "\r\n");
if (send(hSocket, (LPSTR)buf, strlen(buf), NO_FLAGS) == SOCKET_ERROR) {
printf("Socket send error: %d\r\n", WSAGetLastError());
return (false);
}
iLength = recv(hSocket, (LPSTR)sReceiveBuffer+iEnd,sizeof(sReceiveBuffer)-iEnd,
NO_FLAGS);
iEnd += iLength;
sReceiveBuffer[iEnd] = '\0';
memset( base64buf, 0, sizeof(base64buf) );
b64encode( GetUserName().begin(), base64buf, GetUserName().size(), 4 );
strcpy(buf, base64buf);
strcat(buf, "\r\n");
if (send(hSocket, (LPSTR)buf, strlen(buf), NO_FLAGS) == SOCKET_ERROR) {
printf("Socket send error: %d\r\n", WSAGetLastError());
return (false);
}
iLength = recv(hSocket, (LPSTR)sReceiveBuffer+iEnd,sizeof(sReceiveBuffer)-iEnd,
NO_FLAGS);
iEnd += iLength;
sReceiveBuffer[iEnd] = '\0';
// password
memset( base64buf, 0, sizeof(base64buf) );
b64encode( GetPassward().begin(), base64buf, GetPassward().size(), 4 );
strcpy(buf, base64buf);
strcat(buf, "\r\n");
if (send(hSocket, (LPSTR)buf, strlen(buf), NO_FLAGS) == SOCKET_ERROR) {
printf("Socket send error: %d\r\n", WSAGetLastError());
return (false);
}
iLength = recv(hSocket, (LPSTR)sReceiveBuffer+iEnd,sizeof(sReceiveBuffer)-iEnd,
NO_FLAGS);
iEnd += iLength;
sReceiveBuffer[iEnd] = '\0';
// mail from
strcpy(buf, "MAIL FROM: <");
strcat(buf, m_pcFromEmail);
strcat(buf, ">\r\n");
if (send(hSocket, (LPSTR)buf, strlen(buf), NO_FLAGS) == SOCKET_ERROR) {
printf("Socket send error: %d\r\n", WSAGetLastError());
return (false);
}
iLength = recv(hSocket, (LPSTR)sReceiveBuffer+iEnd,sizeof(sReceiveBuffer)-iEnd,
NO_FLAGS);
iEnd += iLength;
sReceiveBuffer[iEnd] = '\0';
// create message receipts
char *token;
for(unsigned int i=0;i<recipients.size();i++) {
="" token="strtok(Recipients.at(i)-">GetEmail(),"<");
token = strtok(NULL,"<");
if (token == NULL)
token = strtok(Recipients.at(i)->GetEmail(),"<");
strcpy(buf, "RCPT TO: <");
strcat(buf, token);
strcat(buf, "\r\n");
if (send(hSocket, (LPSTR)buf, strlen(buf), NO_FLAGS) == SOCKET_ERROR) {
printf("Socket send error: %d\r\n", WSAGetLastError());
return (false);
}
iLength = recv(hSocket,
(LPSTR)sReceiveBuffer+iEnd,sizeof(sReceiveBuffer)-iEnd,
NO_FLAGS);
iEnd += iLength;
sReceiveBuffer[iEnd] = '\0';
}
for( i=0;i<ccrecipients.size();i++) {
="" token="strtok(CCRecipients.at(i)-">GetEmail(),"<");
token = strtok(NULL,"<");
if (token == NULL)
token = strtok(Recipients.at(i)->GetEmail(),"<");
strcpy(buf, "RCPT TO: <");
strcat(buf, token);
strcat(buf, "\r\n");
if (send(hSocket, (LPSTR)buf, strlen(buf), NO_FLAGS) == SOCKET_ERROR) {
printf("Socket send error: %d\r\n", WSAGetLastError());
return (false);
}
iLength = recv(hSocket,
(LPSTR)sReceiveBuffer+iEnd,sizeof(sReceiveBuffer)-iEnd,
NO_FLAGS);
iEnd += iLength;
sReceiveBuffer[iEnd] = '\0';
}
for( i=0;i<bccrecipients.size();i++) {
="" token="strtok(BCCRecipients.at(i)-">GetEmail(),"<");
token = strtok(NULL,"<");
if (token == NULL)
token = strtok(Recipients.at(i)->GetEmail(),"<");
strcpy(buf, "RCPT TO: <");
strcat(buf, token);
strcat(buf, "\r\n");
if (send(hSocket, (LPSTR)buf, strlen(buf), NO_FLAGS) == SOCKET_ERROR) {
printf("Socket send error: %d\r\n", WSAGetLastError());
return (false);
}
iLength = recv(hSocket, (LPSTR)sReceiveBuffer+iEnd,
sizeof(sReceiveBuffer)-iEnd,
NO_FLAGS);
iEnd += iLength;
sReceiveBuffer[iEnd] = '\0';
}
// init data
if (send(hSocket, (LPSTR)"DATA\r\n", strlen("DATA\r\n"), NO_FLAGS) == SOCKET_ERROR) {
printf("Socket send error: %d\r\n", WSAGetLastError());
return (false);
}
iLength = recv(hSocket, (LPSTR)sReceiveBuffer+iEnd,sizeof(sReceiveBuffer)-iEnd,
NO_FLAGS);
iEnd += iLength;
sReceiveBuffer[iEnd] = '\0';
// send header
if (send(hSocket,
(LPSTR)msgHeader, strlen(msgHeader), NO_FLAGS) == SOCKET_ERROR) {
printf("Socket send error: %d\r\n", WSAGetLastError());
delete [] msgHeader;
return (false);
}
// send body
if (send(hSocket,
(LPSTR)m_pcMsgBody, strlen(m_pcMsgBody), NO_FLAGS) == SOCKET_ERROR) {
printf("Socket send error: %d\r\n", WSAGetLastError());
return (false);
}
// signal end
if (send(hSocket,
(LPSTR)"\r\n.\r\n", strlen("\r\n.\r\n"), NO_FLAGS) == SOCKET_ERROR) {
printf("Socket send error: %d\r\n", WSAGetLastError());
return (false);
}
iLength = recv(hSocket, (LPSTR)sReceiveBuffer+iEnd,sizeof(sReceiveBuffer)-iEnd,
NO_FLAGS);
iEnd += iLength;
sReceiveBuffer[iEnd] = '\0';
delete [] msgHeader;
return (true);
}
bool CFastSmtp::ConnectServer(const char server[], const unsigned short port)
{
assert(server);
if (bCon)
Disconnect();
bCon=false;
hSocket = INVALID_SOCKET;
hSocket = _connectServerSocket(server, port);
if (hSocket != INVALID_SOCKET) {
BYTE sReceiveBuffer[4096];
int iLength = 0;
int iEnd = 0;
char buf[4096];
strcpy(buf, "HELO ");
strcat(buf, server);
strcat(buf, "\r\n");
if (send(hSocket, (LPSTR)buf, strlen(buf), NO_FLAGS) == SOCKET_ERROR) {
printf("Socket send error: %d\r\n", WSAGetLastError());
return (false);
}
iLength = recv(hSocket,
(LPSTR)sReceiveBuffer+iEnd,sizeof(sReceiveBuffer)-iEnd,
NO_FLAGS);
iEnd += iLength;
sReceiveBuffer[iEnd] = '\0';
} else {
printf("Invalid socket\r\n");
return (false);
}
bCon=true;
return (true);
}
SOCKET CFastSmtp::_connectServerSocket(const char server[],
const unsigned short port)
{
int nConnect;
short nProtocolPort;
LPHOSTENT lpHostEnt;
LPSERVENT lpServEnt;
SOCKADDR_IN sockAddr;
SOCKET hServerSocket = INVALID_SOCKET;
lpHostEnt = gethostbyname(server);
if (lpHostEnt) {
hServerSocket = socket(PF_INET, SOCK_STREAM,DEFAULT_PROTOCOL);
if (hServerSocket != INVALID_SOCKET) {
if (port != NULL) {
nProtocolPort = port;
}else{
lpServEnt = getservbyname("mail", DEFAULT_PROTOCOL);
if (lpServEnt == NULL)
nProtocolPort = htons(IPPORT_SMTP);
else
nProtocolPort = lpServEnt->s_port;
}
sockAddr.sin_family = AF_INET;
sockAddr.sin_port = nProtocolPort;
sockAddr.sin_addr = *((LPIN_ADDR)*lpHostEnt->h_addr_list);
nConnect = connect(hServerSocket, (PSOCKADDR)&sockAddr,
sizeof(sockAddr));
if(nConnect)
hServerSocket = INVALID_SOCKET;
} else {
printf("Invalid socket\r\n");
throw;
}
}
return(hServerSocket);
}
char* CFastSmtp::_formatHeader()
{
// check for at least one recipient
if(Recipients.size() <= 0 ) {
printf("Please add a message recipient!\r\n");
return NULL;
}
int s=0;
char *msgHeader = new char[16385];
//char to[1024];
for (unsigned int i=s=0;i<recipients.size();i++) {=""
="" s+="strlen(Recipients.at(i)-">GetEmail())+1;
} if (s==0) s=1; char *to = new char[s];
//char cc[1024];
for (i=s=0;i<ccrecipients.size();i++) {=""
="" s+="strlen(CCRecipients.at(i)-">GetEmail())+1;
} if (s==0) s=1; char *cc = new char[s];
//char bcc[1024];
for (i=s=0;i<bccrecipients.size();i++) {=""
="" s+="strlen(BCCRecipients.at(i)-">GetEmail())+1;
} if (s==0) s=1; char *bcc = new char[s];
TCHAR szDate[500];
TCHAR sztTime[500];
// create the recipient string, cc string, and bcc string
to[0] = '\0';
for (i=0;i<recipients.size();i++) {=""
="" i=""> 0 ? strcat(to,","):strcat(to,"");
strcat(to,Recipients.at(i)->GetEmail());
}
cc[0] = '\0';
for (i=0;i<ccrecipients.size();i++) {
="" i=""> 0 ? strcat(cc,","):strcat(cc,"");
strcat(cc,CCRecipients.at(i)->GetEmail());
}
bcc[0] = '\0';
for (i=0;i<bccrecipients.size();i++) {
="" i=""> 0 ? strcat(bcc,","):strcat(bcc,"");
strcat(bcc,BCCRecipients.at(i)->GetEmail());
}
// get the current date and time
SYSTEMTIME st={0};
::GetSystemTime(&st);
::GetDateFormat(LOCALE_SYSTEM_DEFAULT,0,&st,"ddd',\
' dd MMM yyyy",szDate,sizeof(szDate));
::GetTimeFormat(LOCALE_SYSTEM_DEFAULT,TIME_FORCE24HOURFORMAT,&st,
"HH':'mm':'ss tt",sztTime,sizeof(sztTime));
// here it is...the main data of the message
wsprintf(msgHeader,"DATE: %s %s\r\n", szDate, sztTime);
if (m_pcFromName != NULL) {
strcat(msgHeader,"FROM: ");
strcat(msgHeader, m_pcFromName);
strcat(msgHeader, "\r\n");
}
strcat(msgHeader,"To: ");
strcat(msgHeader, to);
strcat(msgHeader, "\r\n");
strcat(msgHeader,"Cc: ");
strcat(msgHeader, cc);
strcat(msgHeader, "\r\n");
if (m_pcSubject != NULL) {
strcat(msgHeader, "Subject: ");
strcat(msgHeader, m_pcSubject);
strcat(msgHeader, "\r\n");
}
if (m_pcXMailer != NULL) {
strcat(msgHeader,"X-Mailer: ");
strcat(msgHeader, m_pcXMailer);
strcat(msgHeader, "\r\n");
}
// start optional fields
if (m_pcReplyTo != NULL) {
strcat(msgHeader, "Reply-To: ");
strcat(msgHeader, m_pcReplyTo);
strcat(msgHeader, "\r\n");
}
// start MIME versions
strcat(msgHeader,
"MIME-Version: 1.0\r\nContent-type: text/plain; charset=US-ASCII\r\n");
// send header finish command
strcat(msgHeader, "\r\n");
// clean up
delete to;
delete cc;
delete bcc;
// done
return msgHeader;
}
const char* const CFastSmtp::GetLocalHostIp()
{
in_addr *iaHost;
if (gethostname(m_cHostName,255) != SOCKET_ERROR) {
HOSTENT *pHe = NULL;
pHe = gethostbyname(m_cHostName);
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 {
DWORD dErr = WSAGetLastError();
printf("Failed to get the local ip address\r\n");
}
return m_pcIPAddr;
}
const char* const CFastSmtp::GetLocalHostname()
{
if (gethostname((char FAR*)m_cHostName,255) == SOCKET_ERROR)
printf("Failed to get the local hostname\r\n");
return m_cHostName;
}
//**********************************************************************************
//*** Properties
//**********************************************************************************
bool CFastSmtp::GetConnectStatus()
{
return (bCon);
}
unsigned const int CFastSmtp::GetBCCRecipientCount()
{
return (BCCRecipients.size());
}
unsigned const int CFastSmtp::GetCCRecipientCount()
{
return (CCRecipients.size());
}
unsigned const int CFastSmtp::GetSocket()
{
return (hSocket);
}
const char* const CFastSmtp::GetMessageBody()
{
return (m_pcMsgBody);
}
unsigned const int CFastSmtp::GetRecipientCount()
{
return (Recipients.size());
}
const char* const CFastSmtp::GetReplyTo()
{
return (m_pcReplyTo);
}
const char* const CFastSmtp::GetSenderEmail()
{
return (m_pcFromEmail);
}
const char* const CFastSmtp::GetSenderName()
{
return (m_pcFromName);
}
const char* const CFastSmtp::GetSubject()
{
return (m_pcSubject);
}
const char* const CFastSmtp::GetXMailer()
{
return (m_pcXMailer);
}
void CFastSmtp::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 CFastSmtp::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 CFastSmtp::SetSenderEmail(const char email[])
{
assert(email);
int s=strlen(email);
if (m_pcFromEmail)
delete [] m_pcFromEmail;
m_pcFromEmail = new char[s+1];
strcpy(m_pcFromEmail, email);
}
void CFastSmtp::SetSenderName(const char name[])
{
assert(name);
int s=strlen(name);
if (m_pcFromName)
delete [] m_pcFromName;
m_pcFromName = new char[s+1];
strcpy(m_pcFromName, name);
}
void CFastSmtp::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 CFastSmtp::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);
}
#ifndef _BASE64_H_
#define _BASE64_H_
/*
base64 is an encoding system where groups of three bytes are replaced by
four characters. The character alphabet is picket to be compatible on ALL
platforms. This is unlike the alphabet used by uuencode. See RFC1521
The base64 API has four functions. The main functions are one for encoding,
and one for decoding.
The third one is for for calculating the exact needed buffer size
when encoding.
The exact buffer size needed for decoding is impossible to
predict without decoding. But it will NEVER be more than 3/4 of the
size of the encoded data. The last function will however go through
a set of data, stripping away anything not in the alphabet.
NOTE: It is very important that the size of the tobuffers are large enough.
The functions will not make sure the buffer van be used, it will blindly try
to use it.
The functions are
b64encode() encodes binary data to the b64encode system. it has the option
to format the output by adding newline characters at regular intervals
given in number of four characters. A final newline will not be added
after the last line, unless it naturally ends in a newline. That is
when the exact number of characters written is the same as prescribed per
line by the argument.
b64decode() decodes base64 encoded data. It does not check for any
heading identifying data, but assumes the buffer contains the data.
It will stop before when the '=' end character is encountered, even if
not the whole buffer is decoded. Will return -1 on error.
Both b64encode() and b64decode() returns the actual number of bytes
written to the buffer.
int b64strip_encoded_buffer() will walk through an encoded buffer
and strip away all characters not in the alphabet. It will return
the length of the now clean buffer.
b64get_encode_buffer_size() calcuates and returns
the buffer size needed for encoding the given buffer.
The size must be at least four characters for every three in the
from buffer, and always an even number of four. For example one to three
characters need four charcaters in the output buffer. Four to six
characters need eight characters in the outputbuffer. And so forth.
If output_quads_per_line is not zero, a newline character is added
after every output_quads_per_line*4 characters. A final newline will
not be written unless the line happens to be exact
output_quads_per_line*4 characters long.
TODO: make sure decode handles all strange stuff
*/
int b64encode(char *from,char *to,int from_length, int output_quads_per_line);
int b64decode(char *from,char *to,int from_length);
int b64get_encode_buffer_size(int from_length,int output_quads_per_line);
int b64strip_encoded_buffer(char *buf,int length);
#endif
#include <stdio.h>
#include <string.h>
#include "base64.h"
char ntc(unsigned char n){
if (n<26) return 'A'+n;
if (n<52) return 'a'-26+n;
if (n<62) return '0'-52+n;
if (n==62) return '+';
return '/';
}
unsigned char ctn(char c){
if (c=='/') return 63;
if (c=='+') return 62;
if ((c>='A')&&(c<='Z')) return c-'A';
if ((c>='a')&&(c<='z')) return c-'a'+26;
if ((c>='0')&&(c<='9')) return c-'0'+52;
if (c=='=') return 80;
return 100;
}
int b64encode(char *from,char *to,int length,int quads){
// 3 8bit numbers become four characters
int i =0;
char *tot=to;
int qc=0; // Quadcount
unsigned char c;
unsigned char d;
while(i<length){
c="from[i];
" *to++="ntc(c/4);
"
="" i++;
="" if="" (i="">=length) {
*to++=ntc(c/4);
*to++='=';
*to++='=';
break;
}
d=from[i];
*to++=ntc(c/4+d/16);
d=d*16;
i++;
if (i>=length) {
*to++=ntc(d/4);
*to++='=';
break;
}
c=from[i];
*to++=ntc(d/4+c/64);
c=c*4;
i++;
*to++=ntc(c/4);
qc++; /* qz will never be zero, quads = 0 means no linebreaks */
if (qc==quads){
*to++='\n';
qc=0;
}
}
/* if ((quads!=0)&&(qc!=0)) *to++='\n'; */ /* Insert last linebreak */
return to-tot;
}
int b64decode(char *from,char *to,int length){
unsigned char c,d,e,f;
char A,B,C;
int i;
int add;
char *tot=to;
for (i=0;i+3
|
|
|
|
|
hi, i tried your method for providing the username and password to the server and it works but not as i expected.
i thought that if i logged on to my own server that i could send emails to addresses using other servers, without specifying their particular server. could you please explain what the purpose of logging in is?
thanks,
joanne
|
|
|
|
|
what you mean " i logged on to my own server ", with IE or other mail tools ?
the program used class CFastSmtp MUST log on to the smtp server itself even though other tools had already logged on. they are not one.
you must log in, if not, the smtp server would not send email for you , it's a authentication.
below is usage:
// connecting...
if (mail.ConnectServer("smtp.163.com"))
{
// connectted
// now send username and password to smtp.163.com
// to authenticate
mail.SetSenderEmail("kkk@163.com");
mail.SetUserName( "kkk" );
mail.SetPassward( "kkk's password" );
// add several addresses using other servers
mail.AddRecipient("jjj@hotmail.com");
mail.AddRecipient("ppp@21cn.com");
}
|
|
|
|
|
Thanks for your response.
When I said I logged on to my own server I meant that I used your modified CFastSmtp class and provided my user name and password, exactly as you showed in you example.
Even without your additions to CFastSmtp to supply the user name and password, I was able to connect to my server and send emails. But I could only send emails to addresses on that server.
For example, if I use "mail.Connect("smtp.163.com")" then I could send mail to "xyz@163.com" but not to "xyz@hotmail.com".
My question was, is the purpose of providing the user name and password (and thus allowing the server to do the authenification) to allow you to send emails to addresses on other servers?
|
|
|
|
|
no.
at my smtp server i will not send email if i did not log on with correct username and password.
quote your example, if you use IE to log on to mail.163.com, can you send one email to xyz@hotmail.com?
some smtp server prohibit user send emails to some other server for some reasons.
i am not sure and i will do some tests tonight. and then reply you. 
|
|
|
|
|
i think its a problem with my server details (smpt.ozhosting.com) when i configure my smtp server in outlook i get the same error, 550 The Server is not configured to relay the email to ...hotmail.com.
at least i know if outlook has the same problem my code must be ok;P
thanks for your help,
joanne![Rose | [Rose]](https://codeproject.freetls.fastly.net/script/Forums/Images/rose.gif)
|
|
|
|
|
it's the reason, i think
you can try other smtp server, good luck!
|
|
|
|
|
Note than when using the authentication option, the session must be started with the keyword "EHLO" instead of "HELO". Take a look at ftp://ftp.isi.edu/in-notes/rfc2554.txt for more details.
Great class indeed!
|
|
|
|
|
There seems to be a code chopped off the ends of some of the for and while loops in the base64.cpp area leaving guessing as to what it should by. Can you repost this code?
Thank you.
Walter Boncal
|
|
|
|
|
Here you have the full base64.cpp file:
#include <stdio.h>
#include <string.h>
#include "stdafx.h"
char ntc(unsigned char n)
{
if (n<26) return 'A'+n;
if (n<52) return 'a'-26+n;
if (n<62) return '0'-52+n;
if (n==62) return '+';
return '/';
}
unsigned char ctn(char c)
{
if (c=='/') return 63;
if (c=='+') return 62;
if ((c>='A')&&(c<='Z')) return c-'A';
if ((c>='a')&&(c<='z')) return c-'a'+26;
if ((c>='0')&&(c<='9')) return c-'0'+52;
if (c=='=') return 80;
return 100;
}
int b64encode(const char *from,char *to,int length,int quads)
{
// 3 8bit numbers become four characters
int i =0;
char *tot=to;
int qc=0; // Quadcount
unsigned char c;
unsigned char d;
while(i<length)
{
c=from[i];
*to++=ntc(c/4);
c=c*64;
i++;
if (i>=length)
{
*to++=ntc(c/4);
*to++='=';
*to++='=';
break;
}
d=from[i];
*to++=ntc(c/4+d/16);
d=d*16;
i++;
if (i>=length)
{
*to++=ntc(d/4);
*to++='=';
break;
}
c=from[i];
*to++=ntc(d/4+c/64);
c=c*4;
i++;
*to++=ntc(c/4);
qc++; // qz will never be zero, quads = 0 means no linebreaks
if (qc==quads)
{
*to++='\n';
qc=0;
}
}
// if ((quads!=0)&&(qc!=0)) *to++='\n'; // Insert last linebreak
return to-tot;
}
int b64decode(char *from,char *to,int length)
{
unsigned char c,d,e,f;
char A,B,C;
int i;
int add;
char *tot=to;
for (i=0;i+3<length;)
{
add=0;
A=B=C=0;
c=d=e=f=100;
while ((c==100)&&(i<length)) c=ctn(from[i++]);
while ((d==100)&&(i<length)) d=ctn(from[i++]);
while ((e==100)&&(i<length)) e=ctn(from[i++]);
while ((f==100)&&(i<length)) f=ctn(from[i++]);
if (f==100) return -1; // Not valid end
if (c<64)
{
A+=c*4;
if (d<64)
{
A+=d/16;
B+=d*16;
if (e<64)
{
B+=e/4;
C+=e*64;
if (f<64)
{
C+=f;
to[2]=C;
add+=1;
}
to[1]=B;
add+=1;
}
to[0]=A;
add+=1;
}
}
to+=add;
if (f==80) return to-tot; // end because '=' encountered
}
return to-tot;
}
int b64get_encode_buffer_size(int l,int q)
{
int ret;
ret = (l/3)*4;
if (l%3!=0) ret +=4;
if (q!=0)
{
ret += (ret/(q*4));
// if (ret%(q/4)!=0) ret ++; // Add space for trailing \n
}
return ret;
}
int b64strip_encoded_buffer(char *buf,int length)
{
int i;
int ret=0;
for (i=0;i<length;i++) if (ctn(buf[i])!=100) buf[ret++] = buf [i];
return ret;
}
|
|
|
|
|
Thank you for the update.
Walter J. Boncal PE
|
|
|
|
|
Hi Joanne or others:
I have the same problem. I could not send emails to the addresses not inside my mail server.
If my mail server is mail.mycompany.com, I can send email to xyz@mycompany.com. But my email to xyz@hotmail.com is blocked. What should I do? Also how to send the attachment?
Thanks in advance.
Ke
|
|
|
|
|
Dear all !
I need to built and application to send email in Visual C++.
I use CFastSMTP class but it don't support username and password. I can't send email to other domain.
you can help me to do it.
Thanks!
Best Regrads,
NghiaDuong
nghiaduong
|
|
|
|
|
Hi man.. Great class .. i tried the first one example, and now i'm trying to test this new release.. but.. i have a problem with a UNRESOLVED EXTERNAL SYMBOL..
in the compilation
Linking...
FastSmtp.obj : error LNK2001: unresolved external symbol "int __cdecl b64encode(char *,char *,int,int)" (?b64encode@@YAHPAD0HH@Z)
Debug/ZincMail.exe : fatal error LNK1120: 1 unresolved externals
Error executing link.exe.
i think.. the b64encode function is correctly declared.. but the compiler can't find it...
Please, tellme what's worng
Thanks in advance
|
|
|
|
|
Hi...
i'm having the same error...
any sugestion?
Thanks.
|
|
|
|
|
it means the linker can't find the implementation of function b64encode.
the source i posted already include the implementation of function b64encode, just split them yourself.
|
|
|
|
|
Hello Everybody,
I just can't copy this code... When I paste into my project there's a lot of mistakes like this:
#include
#include
#include
#include
I tried all...
Please, can anybody send me these files??
my email:
salvaterra@gmail.com
Thank you very much
|
|
|
|
|
Rubbish!
There are so many code errors even a lot of grammar errors in your sample code!
How can u put this code to web?
rfrvd
|
|
|
|
|
I'm trying to use this class to send email through an exchange server, but i'm having problems...
When it sends the login username it waits forever for the server reply...
Can anyone help me?
RSG
|
|
|
|
|