Click here to Skip to main content
15,886,919 members
Articles / Desktop Programming / MFC
Article

CFastSmtp - Fast and easy SMTP class...

Rate me:
Please Sign up or sign in to vote.
4.38/5 (37 votes)
4 Sep 2002 421.7K   16   107   135
Fast and simple win32 SMTP class with handy local ip/name funtions

Introduction

zSmtp v1.1

Win32 SMTP Wrapper with handy local ip and hostname functions.

Notes

A real basic SMTP wrapper. I tried to find one, but I couldn't - so here is another one. It is fast and straight forward - just instantiate the class with a SMTP server and then set the sender email property and message body. The rest of the settings are pretty much optional. There are also a couple of nice utility functions for getting your local hostname and local ip address.

We hope this code helps you out!

To Do

  • UUEncode/Decode
  • Attachments

Usage

CFastSmtp mail;

if (mail.ConnectServer("SERVER")) {
    mail.SetSenderName("Sender's Name");
    mail.SetSenderEmail("senders@address.com");
    mail.SetSubject("CFastSmtp v1.1 Release");

    mail.AddRecipient("test@test.com");
    mail.AddCCRecipient("test@test.com");
    mail.AddBCCRecipient("test@test.com");

    mail.SetMessageBody("Here is another test of CFastSmtp SMTP class!");
    
    if (mail.GetConnectStatus()) {        
        printf(mail.Send() ? "Send was a success!" : "Send failed!");
        mail.Disconnect();                    
    }
}   

Source Code

Here is the source (FastSmtp.cpp):

//********************************************************************
/*
  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"

//////////////////////////////////////////////////////////////////////
// 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 (unsigned int n = 0; n < CCRecipients.size(); n++)
        delete CCRecipients[n];
    for (unsigned int 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);
    }

    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
    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(unsigned int 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(unsigned int 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);
}
Here is the header (FastSmtp.h):
// 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>

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[]);

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;    

    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_)

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralRe: Sending HTML mails Pin
HughJampton17-Nov-04 6:12
HughJampton17-Nov-04 6:12 
GeneralRe: Sending HTML mails Pin
Douglas R. Keesler9-Jul-05 18:44
Douglas R. Keesler9-Jul-05 18:44 
GeneralUnresolved Externals Pin
ivax14-Apr-04 5:34
ivax14-Apr-04 5:34 
GeneralRe: Unresolved Externals Pin
Lorenz Blum18-Apr-04 4:07
sussLorenz Blum18-Apr-04 4:07 
GeneralRe: Unresolved Externals Pin
flypoint24-Aug-05 17:10
sussflypoint24-Aug-05 17:10 
GeneralRe: Unresolved Externals - I GOT IT Pin
Lorenz Blum19-Apr-04 6:08
sussLorenz Blum19-Apr-04 6:08 
GeneralSocket handles leaks detected!! Pin
Igor V. Polyakoff15-Dec-03 7:37
Igor V. Polyakoff15-Dec-03 7:37 
Generalsupport username&password Pin
bowdom4-Nov-03 0:57
bowdom4-Nov-03 0:57 
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
GeneralRe: support username&amp;password Pin
Jo Fredrickson25-Nov-03 22:26
Jo Fredrickson25-Nov-03 22:26 
GeneralRe: support username&amp;password Pin
bowdom26-Nov-03 4:35
bowdom26-Nov-03 4:35 
GeneralRe: support username&amp;password Pin
Jo Fredrickson26-Nov-03 13:04
Jo Fredrickson26-Nov-03 13:04 
GeneralRe: support username&amp;password Pin
bowdom26-Nov-03 22:24
bowdom26-Nov-03 22:24 
GeneralRe: support username&amp;password Pin
Jo Fredrickson27-Nov-03 3:05
Jo Fredrickson27-Nov-03 3:05 
GeneralRe: support username&amp;password Pin
bowdom27-Nov-03 19:56
bowdom27-Nov-03 19:56 
GeneralRe: support username&amp;password Pin
pprados16-Dec-03 7:36
pprados16-Dec-03 7:36 
GeneralRe: support username&amp;password Pin
wboncal16-Dec-03 9:39
wboncal16-Dec-03 9:39 
GeneralRe: support username&amp;password Pin
pprados17-Dec-03 9:41
pprados17-Dec-03 9:41 
GeneralRe: support username&amp;password Pin
wboncal17-Dec-03 9:52
wboncal17-Dec-03 9:52 
GeneralRe: support username&amp;amp;password Pin
kezhu9-Dec-05 10:53
kezhu9-Dec-05 10:53 
GeneralRe: support username&amp;amp;password Pin
nghiaduong14-Dec-05 16:31
nghiaduong14-Dec-05 16:31 
GeneralRe: support username&amp;password Pin
porlachucha15-Mar-04 5:23
porlachucha15-Mar-04 5:23 
GeneralRe: support username&amp;password Pin
silencew25-Mar-04 12:37
silencew25-Mar-04 12:37 
GeneralRe: support username&amp;password Pin
Anonymous28-Mar-04 22:28
Anonymous28-Mar-04 22:28 
GeneralWrong copy Pin
salvaterra73-Aug-05 9:18
salvaterra73-Aug-05 9:18 
GeneralRe: support username&amp;password Pin
cynew6-Nov-05 21:15
cynew6-Nov-05 21:15 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.