Overview
CSmtpProxyMT
is a C++ class that provides developers with a simple way to
implement a multi-threaded SMTP proxy server in their applications. You can use
it in MFC projects as well as in non-MFC C++ projects. I'd like to thank my good
friend Colin Davies for his idea of inserting signatures into mails at
the SMTP level instead of at the mail client level.
Features
- Simple C++ interface
- The code does not use the MFC Socket classes. Thus it avoids several
pitfalls associated with the MFC Socket classes
- You can use it in MFC/non-MFC applications as well as in console
applications
- Multithreaded [uses the CRT function
_beginthreadex
instead of the API
functions]
- Ability to insert a signature to all outgoing mails [html mails, text
mails, mails with attachments]
- You can create
CSmtpProxyMT
object only on the heap. If you attempt to
create the CSmtpProxyMT
object on the stack, you'll get unpredictable results.
Usage
- Add SmtpProxyMT.cpp and SmtpProxyMT.h to your project
- Put
#include "SmtpProxyMT.h"
on top of your source file, from
where you wish to instantiate the class
- Add WS2_32.lib to the list of Library/object modules
- Add a member variable to your class or if you are not using a class,
simply declare a member variable as follows :-
CSmtpProxyMT *m_smtpproxy;
- Now create the object either in your constructor or somewhere similarly
suitable :-
m_smtpproxy = new CSmtpProxyMT;
- You can also set the signature to be attached to all outgoing mails
m_smtpproxy->SetSignature("Hello World from Nish");
- Starting the proxy is easy :-
m_smtpproxy->StartProxy("192.168.1.44",25,125);
- You can stop the proxy just as easily :-
m_smtpproxy->StopProxy();
Function Reference
I'll list below the public member functions that you can use
CSmtpProxyMT::CSmtpProxyMT
CSmtpProxyMT();
Remarks :- Constructs a CSmtpProxyMT
object. Please remember that you
should only create the CSmtpProxyMT
object on the heap.
CSmtpProxyMT::StartProxy
int StartProxy(char *server, int port, int localport);
Return Value :- This will return ERR_RUNNING
if the proxy is already
started. Else it will return OK_SUCCESS
Parameters :-
server
- You specify the SMTP server here. You can use a domain
name such as smtp.nish.com or you can use an IP address such as 202.54.6.60
port
- This is where you specify the SMTP port, usually 25
localport
- This is the SMTP proxy port. You can specify 25
here too, unless you are running the proxy on the same IP as the SMTP server. In
that case use something else.
Remarks :- This will start the SMTP proxy service. Currently if there
is a host resolve problem you will not get notified. This is a TODO for me.
CSmtpProxyMT::StopProxy
int StopProxy();
Return Value :- This returns ERR_STOPPED
if the proxy is not running.
Otherwise it returns OK_SUCCESS
Remarks :- This stops the SMTP proxy service.
CSmtpProxyMT::SetSignature
BOOL SetSignature(char *sig);
Return Value :- This will return true
if the signature was
successfully set. It will return false
if the signature is too large.
Parameters :-
sig
- This is used to specify the signature. It should be a
null-terminated string.
Remarks :- Currently there is a 2 KB limit which can be easily
modified by editing the source. This version supports only text signatures. It's
a TODO for me to add HTML signature options in the next version
Acknowledgements
- Colin Davies - For the signature idea
Some remarks
I am sure purist C++ programmers will frown on seeing my source code. I have
not followed strictly proper coding standards nor have I tried to stick to perfect
OOP concepts. There might be people who say, that this is not the way to write
code. Well, that's the way I write code. Perhaps I need to change, but it's not
going to be easy
I have tested the class using Outlook Express 6.0. I have tested it with
several combinations such as text only mails, html mails, mails with
single/multiple attachments. So far I haven't had any problems. But I presume
that there might be problems with some mail clients that use their own methods
in sending mails.
You'll also notice that I haven't commented the code much. But the code is
self-explanatory. I don't usually comment my code and even when I do, the
comments I put are obscure and often serve only to confuse my colleagues.
Therefore I try to avoid comments. But there are comments where required. And if
anyone requires any clarification, I'll be glad to oblige him or her.
Thanks