CSMTPConnection
v2.15
Welcome to CSMTPConnection, a freeware MFC class to
support the SMTP protocol. SMTP for those not familiar with all the internet protocols is
the protocol used to send internet email.
For detailed information about the Simple Mail
Transfer Protocol you should read RFC 821,
Other documents that these classes refer to are RFC 2045 (which
defines how MIME attachments are to be handled in a standard SMTP message) and
RFC 822 (which defines the way standard headers which SMTP uses). You might also
want to check out RFC 2110 which covers MHTML (aka HTML Email).
You can find numerous Web Servers which carry these documents by
going to www.yahoo.com and look for RFC and 821,
822, 1321, 2045, 2104 and 2195.
Please note that portions of the code is provided by RSA
security. Please see md5.cpp for more details on this.
Features
- Simple and clean C++ interface.
- The interface provided is synchronous which
provides an easier programming model than using asynchronous sockets.
- The code does not rely on the MFC socket
classes. These classes have a number of shortcomings, one of which causes problems when
they are used in NT services.
- The code can be used in a console
application without any problems (Again this is not the case for the MFC socket classes).
- A configurable timeout for the connection
can be set through the class API.
- The classes are fully Unicode compliant and
include Unicode built options in the workspace file.
- As of v1.1, the classes now fully supports
sending file attachments.
- Multi CC, BCC & Reply To support is
included.
- Support for regular email address formats
and multiple email address parsing.
- Full support for MIME and
MHTML (aka HTML Email).
- Full support for MIME
Charsets.
- Comprehensive sample program
included which exercises most of the classes functionality.
Copyright
You are allowed to include the source code in any product
(commercial, shareware, freeware or otherwise) when your product is released in
binary form. You are allowed to modify the source code in any way you want
except you cannot modify the copyright details at the top of each module. If you
want to distribute source code with your application, then you are only allowed
to distribute versions released by the author. This is to maintain a single
distribution point for the source code.
Usage
- To use the class in your code simply include
smtp.cpp base64code.cpp and md5.cpp in your project and #include smtp.h in which ever of your modules needs to make
calls to the classes.
- Your code will need to include MFC either statically or dynamically.
- You will need to have a functioning winsock stack installed and
correctly initialised prior to calling any functions in CSMTPConnection. Depending on your
application, this will involve calling either WSAStartup or AfxSocketInit at startup of
your application.
- You will also need to have afxtempl.h ,winsock.h or afxsock.h and
afxpriv.h in your precompiled header. The code will work just as well in a GUI or console
app. The code should also work in a multithreaded application, although it has not be
explicitly tested in this scenario.
- To see the class in action, have a look at the code in InitInstance
in the module "main.cpp". For example to send a message to the author
about this class, the code would look something like this (ignoring error handling):
CSMTPConnection
smtp;
smtp.Connect("mail.someisp.com");
CSMTPMessage m;
m.AddRecipient(CSMTPAddress("pjna@naughter.com"));
m.m_From =
CSMTPAddress("adeveloper@someisp.com");
m.m_sSubject = "A Fellow developer!";
m.AddTextBody("if you can read this then the
CSMTPConnection code is working");
smtp.SendMessage(m);
To send your autoexec.bat
as a file attachment to me you would use the following code:
CSMTPConnection
smtp;
smtp.Connect("mail.yourisp.com");
CSMTPMessage m;
m.AddRecipient(CSMTPAddress("pjna@naughter.com"));
m.m_From =
CSMTPAddress("you@someisp.com");
m.m_sSubject = "Here's my autoexec.bat
file!";
CSMTPBodyPart a;
a.SetFilename("c:\\autoexec.bat");
m.AddBodyPart(a);
smtp.SendMessage(m);
- For further details on usage of the classes please
consult the sample application which comes with the code, specifically check
out CMailDlg::OnSend in maildlg.cpp.
History
V1.0 (26th May 1998)
V1.1 (17th June 1998)
- Fixed the case where a single dot occurs on its own in the body of a
message
- Classes now supports an optional "Reply-To" Header Field
- Classes now fully supports file attachments
- Some rework on the contents of the help file
V1.11 (18th June 1998)
- Fixed a memory overwrite problem which was occurring with the buffer
used for encoding base64 attachments.
V1.12 (27th June 1998)
- The case where a line begins with a "." but contains other
text is now also catered for. See RFC821, Section 4.5.2 for further details.
- m_sBody in CSMTPMessage has now been made protected. Client
applications now should call AddBody instead. This ensures that FixSingleDot is only
called once even if the same message is sent a number of times.
- Fixed a number of problems with how the MIME boundaries were defined
and sent.
- Got rid of an unreferenced formal parameter compiler warning when
doing a release build.
V1.2 (11 August 1998)
- VC 5 project file is now provided instead of VC 4.x
- Attachment array which the message class contains now uses references
instead of pointers.
- Now uses Sleep(0) to yield our time slice instead of Sleep(100), this
is the preferred way of writting polling style code in Win32 without serverly impacting
performance.
- All trace statements now display the value as returned from
GetLastError
- A number of extra asserts have been added
- AddMultipleRecipients has been added which supports added a number of
recipients at one time from a single string
- Extra trace statements have been added to help in debugging
- A number of updates to the documentation.
V1.21 (12 September 1998)
- Removed a couple of unreferenced variable compiler warnings
discovered when the class was compiled on Visual C++ 6.0.
- Fixed a major bug which was causing an ASSERT when the
CSMTPAttachment destructor was being called in the InitInstance of the sample app. This
was inadvertingly introduced for the 1.2 release. The fix is to revert fix 2) as done for
v1.2. This new fix will also help to reduce the number of attachment images kept in memory
at one time.
- Fixed a few errors in this help file.
V1.3 (18 January 1999)
- Full support has now been added for CC (Carbon Copy) & BCC (Blind
Carbon Copy).
V1.31 (22 February 1999)
- Added a Get and SetTitle method which allows a files attachment title
to be different that the original filename.
- Updated sample app to include a more descriptive subject line.
- Default timeout for the code when a debug build is built has now been
set to 60 seconds.
- Improved the reading of responses back from the server by
implementing a growable receive buffer.
- Updated instructions on how the relavent RFC documents can be
retrieved.
V1.32 (25 March 1999)
- Now sleeps for 250 ms instead of yielding the time slice. This helps
reduce CPU usage when waiting for data to arrive in the socket.
V1.33 (14 May 1999)
- Updated documentation to refer to RFC 822.
- Fixed a bug with the way the code generates time zone
fields in the Date headers. Thanks to Randy
A. Scott for reporting this bug.
V1.34 (10 September 1999)
- Improved CSMTPMessage::GetHeader to include mime field
even when no attachments are included.
V1.35 (5 October 1999)
- Fixed 2 level 4 warnings when compiled using VC 6.
V1.36 (16 February 2000)
- Fixed another compiler problem when compiled with VC 6.
V1.37 (19 March 2000)
- Fixed a problem in GetHeader on Non-English Windows machines
- Now ships with a VC 5 workspace. I accidentally shipped a VC 6 version in one of the previous versions of the code.
- Fixed a number of UNICODE problems
- Updated the sample app to deliberately assert before connecting to the author's SMTP server.
V1.38 (26 March 2000)
- Updated the sample app provided with the code to be a
mini mail client. This should now also give a better idea of what the code
can be used for.
V1.39 (28 March 2000)
- Set the release mode timeout to be 10 seconds. 2 seconds was causing problems for slow dial up networking connections.
V1.40 (7 May 2000)
- Addition of some ASSERT's in CSMTPSocket::Connect.
V1.41 (20 June 2000)
- Removed the base64 encoder from this file
- Added the base64 encoder/decoder implementation in a separate file. This was done because base64 decoding was not part of the previous implementation
- Added support for ESMTP connection. The class now attempts to authenticate the user on the ESMTP server using the username and
passwords supplied. For this connect now takes the username and passwords as parameters. These can be null in which case ESMTP authentication is not attempted
- This class can now handle AUTH LOGIN and AUTH LOGIN PLAIN authentication
schemes
- Added the files md5.* containing the MD5 digest generation code
after modifications so that it compiles with VC++ 6
- Added the CRAM-MD5 login procedure.
- Please note that all the support for SMTP
authentication was added by Puneet Pawaia to which I am gratefully
appreciated for all the hard work put in.
V2.0 (21 June 2000)
- Now includes a number of files missing from the zip
file.
- Updated the version number to v2 to reflect the major
changes which occurred in v1.41
V2.01 (10 July 2000)
- Fixed a problem with sending attachments > 1K in size.
- Changed the parameters to CSMTPConnection::Connect
V2.02 (30 July 2000)
- Fixed a bug in AuthLogin which was transmitting the username and password
with an extra "=" which was causing the login to failure. Thanks to Victor Vogelpoel for
finding this.
V2.03 (5 September 2000)
- Added a CSMTP_NORSA preprocessor macro to allow the
CSMTPConnection code to be compiled
without the dependence on the RSA code.
V2.04 (28 December 2000)
- Removed an unused variable from ConnectESMTP.
- Allowed the hostname as sent in the HELO command to be specified at run time
in addition to using the hostname of the client machine
- Fixed a problem where high ascii characters were not being properly encoded in
the quoted-printable version of the body sent.
- Added support for user definable charset's for the message body.
- Mime boundaries are now always sent irrespective of whether attachments are included or
not. This is required as the body is using quoted-printable.
- Fixed a bug in sendLines which was causing small message bodies to be sent incorrectly
- Now fully supports custom headers in the SMTP message
- Fixed a copy and paste bug where the default port for the SMTP socket class was 110.
- You can now specify the address on which the socket is bound. This enables the programmer
to decide on which NIC data should be sent from. This is especially useful on a machine
with multiple IP addresses.
- Addition of functions in the SMTP connection class to auto dial and auto disconnect to the Internet if you so desire.
- Sample app has been improved to allow Auto Dial and
binding to IP addresses to be configured.
- Thanks go to Yaroslav Liapkov, Josef Hampl, Duncan Strand,
Fritz Roland "Nick" Bjorklund, Lev Elbert and Perry Rapp for
finding these problems and/or suggesting the improvements.
V2.1 (14 May 2001)
- Charset now defaults to ISO 8859-1 instead of us-ascii
- Removed a number of unreferrenced variables from the sample app.
- Headers are now encoded if they contain non ascii characters.
- Fixed a bug in getLine, Thanks to Lev Evert for spotting this one.
- Made the charset value a member of the message class instead of the connection class
- Sample app now fully supports specifying the charset of the message
- Added a AddMultipleAttachments method to CSMTPMessage
- Attachments can now be copied to each other via new methods in CSMTPAttachment
- Message class now contains copies of the attachments instead of pointers to them
- Sample app now allows multiple attachments to be added
- Removed an unnecessary assert in QuotedPrintableEncode
- Added a Mime flag to the CSMTPMessage class which allows you to decide whether or not a message
should be sent as MIME. Note that if you have attachments, then mime is assumed.
- CSMTPAttachment class has now become CSMTPBodyPart in anticipation of full support for MIME and MHTML email support
- Updated copright message in source code and documentation
- Fixed a bug in GetHeader related to _tsetlocale usage. Thanks to Sean McKinnon for spotting this
problem.
- Fixed a bug in SendLines when sending small attachments. Thanks to Deng Tao for spotting this
problem.
- Removed the need for SendLines function entirely.
- Now fully supports HTML email (aka MHTML)
V2.11 (17 June 2001)
- Fixed a bug in CSMTPMessage::HeaderEncode where spaces were not being interpreted correctly. Thanks
to Jim Alberico for spotting this.
- Fixed 2 issues with ReadResponse both having to do with multi-line responses. Thanks to Chris Hanson for this update.
V2.12 (25 June 2001)
- Code now links in Winsock and RPCRT40 automatically.
This avoids client code having to specify it in their linker settings.
Thanks to Malte and Phillip for spotting this issue.
- Updated sample code in documentation. Thanks to Phillip
for spotting this.
- Improved the code in CSMTPBodyPart::SetText to ensure
lines are correctly wrapped. Thanks to Thomas Moser for this fix.
V2.13 (1 July 2001)
- Modified QuotedPrintableEncode to prevent the code to enter in an infinite loop due to a long word i.e. bigger than SMTP_MAXLINE, in this case, the word is breaked. Thanks to Manuel Gustavo Saraiva for this fix.
- Provided a new protected variable in CSMTPBodyPart called m_bQuotedPrintable to bypass the QuotedPrintableEncode function in cases that we don't want that kind of correction. Again thanks to Manuel Gustavo Saraiva for this fix.
V2.14 (15 July 2001)
- Improved the error handling in the function CSMTPMessage::AddMultipleAttachments. In addition the return value has been changed from BOOL to int.
V2.15 (13 August 2001)
- Fixed a bug in QuotedPrintableEncode which was wrapping encoding characters across multiple lines. Thanks to Roy He for spotting this.
- Provided a "SendMessage" method which sends a email directly from disk. This allows you to construct your own emails and the use the class just to do the sending. This function also has the advantage that it efficiently uses memory and reports progress.
- Provided support for progress notification and cancelling via the "OnSendProgress" virtual method.
PLANNED
ENHANCEMENTS
- Optimize usage of T2A macros.
- Provide User exits.
- If you have any other suggested
improvements, please let me know so that I can incorporate them into the next release.
CONTACTING
THE AUTHOR
PJ Naughter
Email: pjna@naughter.com
Web: http://www.naughter.com
13 August 2001