SmtpClient provides a member function Connect() for opening a connection to an SMTP server, a member function Disconnect() for closing the connection, and member functions for each of the SMTP commands. Each of these member functions, except Disconnect(), returns 0 if communication with the server succeeded, and -1 if communication with the server failed. It is important to remember that these member functions return 0, indicating success, even in the case that the response from the server was negative (that is, a 4xx or 5xx response). The function's return value indicates only if communication between the client and the server succeeded -- in particular, no network errors occurred. A success return value does not imply that the server successfully executed the SMTP command. You use the member function ReplyCode() to get the server's reply code, which indicates if the server successfully executed the SMTP command.
To use SmtpClient, you first call the Connect() member function to open a connection to the SMTP server. Once you have opened the connection, you send SMTP commands to the server using various member functions. In the typical case, you start with the EHLO command, then complete one or more mail transactions via the MAIL, RCPT, and DATA commands, and finally finish with the QUIT command. You send these commands using the Ehlo(), MailFrom(), RcptTo(), Data(), and Quit() member functions. When you have finished sending commands, you call the Disconnect() member function to close the connection to the server.
You detect network-layer errors by examining the return value of most member functions. If a member function indicates that an error has occurred, you get the details of the error by calling additional member functions. Call ErrorCode() to get a platform independent error code. Call OsErrorCode() to get the error code that was reported by the operating system. Call ErrorMessage() to get a text error message that can be written to a log file.
One advanced feature of SmtpClient is the ability to cancel a network operation. For example, if you are developing an interactive application with a user interface, you can allow the user to cancel a network operation that has stalled. To provide this ability, SmtpClient provides a Cancel() member function that you can call from your user interface thread, which is a different thread from the thread that is managing the SMTP connection.
It is possible customize SmtpClient -- for example, to use non-standard commmands -- using the member functions SendCommand() and ReceiveResponse(). The library itself uses these member functions to implement most SMTP commands. The following code sample shows how an XFOO command could be implemented:
int Xfoo()
{
int retVal = -1;
retVal = SendCommand("XFOO\r\\n");
if (retVal == 0) {
retVal = ReceiveResponse();
}
return retVal;
}
The SendCommand() and ReceiveResponse() member functions are considered advanced functions, which are not required for most applications, but which may be useful in extending the library.
Public Member Functions | |
| SmtpClient () | |
| Default constructor. | |
| virtual | ~SmtpClient () |
| Destructor. | |
| void | SetTraceOutput (TraceOutput *out, bool takeOwnership) |
| Sets a Trace Output instance. | |
| void | SetTimeout (int secs) |
| Sets the timeout value for network send and receive operations. | |
| void | SetReceiveTimeout (int secs) |
| Sets the timeout value for network receive operations. | |
| void | SetSendTimeout (int secs) |
| Sets the timeout value for network send operations. | |
| void | Cancel () |
| Cancels a currently executing command. | |
| int | Connect (const char *address, int port=25, bool wait=true) |
| Opens a connection to an SMTP server. | |
| int | ConnectTls (const char *serverHostName, bool wait=false) |
| Establishes a TLS connection over an existing TCP connection. | |
| int | ConnectTlsOpenSSL (const char *serverHostName, void *ssl, bool wait=false) |
| Establishes a TLS connection over an existing TCP connection. | |
| void | Disconnect () |
| Closes the connection to the SMTP server. | |
| int | Helo (const char *hostname) |
| Sends the HELO command. | |
| int | Ehlo (const char *hostname) |
| Sends the EHLO command. | |
| int | Auth (const char *mechanism, const char *params=0) |
| Sends the AUTH command. | |
| int | AuthLogin (const char *name, const char *password) |
| Sends the AUTH LOGIN command. | |
| int | AuthPlain (const char *name, const char *password) |
| Sends the AUTH PLAIN command. | |
| int | AuthCramMd5 (const char *name, const char *password) |
| Sends the AUTH CRAM-MD5 command. | |
| int | AuthNtlm (const char *name, const char *password) |
| Sends the AUTH NTLM command. | |
| int | Starttls () |
| Sends the STARTTLS command. | |
| int | Rset () |
| Sends the RSET command. | |
| int | Noop () |
| Sends the NOOP command. | |
| int | Quit () |
| Sends the QUIT command. | |
| int | Vrfy (const char *recipient) |
| Sends the VRFY command. | |
| int | MailFrom (const char *sender, const char *params=0) |
| Sends the MAIL command. | |
| int | RcptTo (const char *recipient, const char *params=0) |
| Sends the RCPT command. | |
| int | Data () |
| Sends the DATA command. | |
| int | SendBytes (const char *bytes, int length, int options) |
| Sends mail content as uninterpreted bytes. | |
| int | SendLines (const char *bytes, int length, int options) |
| Sends mail content as text lines. | |
| int | NumCapabilities () const |
| Gets the number of server capability items. | |
| const char * | CapabilityAt (int index) const |
| Gets the server capability item at specified index. | |
| bool | HasCapability (const char *name) const |
| Gets true value if server has specified capability. | |
| int | ReplyCode () const |
| Gets the server's reply code. | |
| const char * | ReplyText () const |
| Gets the text of the server's reply. | |
| const char * | EnhancedStatusCode () const |
| Gets the server's enhanced status code. | |
| Error | ErrorCode () const |
| Gets the platform-independent error code of last error. | |
| int | OsErrorCode () const |
| Gets the platform-specific error code of last error. | |
| const char * | ErrorMessage () const |
| Gets the error message associated with last error. | |
| int | SendCommand (const char *commandStr) |
| Sends a command to the server. | |
| int | ReceiveResponse () |
| Receives a response from the server. | |
|
|
Default constructor. |
|
|
Destructor. The destructor performs all necessary clean-up, including closing the connection to the server if it is not already closed. |
|
||||||||||||
|
Sends the AUTH command. This is an advanced function that should not be used. Use the AuthPlain() or AuthCramMd5() for supported authentication mechanisms.
|
|
||||||||||||
|
Sends the AUTH CRAM-MD5 command. AUTH is actually the name of the SMTP command; CRAM-MD5 is the name of a registered SASL authentication mechanism, which is supplied as a parameter to the AUTH command. (SASL, described in RFC 2222, means "Simple Authentication and Security Layer".) The CRAM-MD5 authentication mechanism is described in RFC 2195. CRAM-MD5 is more secure than the PLAIN authentication mechanism. If the server does not support CRAM-MD5, but does support PLAIN, you can use the AuthPlain() member function to send the AUTH PLAIN command. The AuthCramMd5() member function takes a user name and password as parameters. If the return value indicates success, you should check the server's reply code, by calling the ReplyCode() member function. A 2xx reply code indicates success.
|
|
||||||||||||
|
Sends the AUTH LOGIN command. AUTH is actually the name of the SMTP command; LOGIN is the name of a registered SASL authentication mechanism, which is supplied as a parameter to the AUTH command. (SASL, described in RFC 2222, means "Simple Authentication and Security Layer".) There is no RFC for the LOGIN SASL mechanism. The mechanism is specified by an Internet draft by Murchison. (To get it, use your favorite web search engine to find the latest version of "draft-murchison-sasl-login".) The AuthLogin() member function takes a user name and password as parameters. If the return value indicates success, you should check the server's reply code, by calling the ReplyCode() member function. A 2xx reply code indicates success.
|
|
||||||||||||
|
Sends the AUTH NTLM command. AUTH is actually the name of the SMTP command; NTLM is the name of a registered SASL authentication mechanism, which is supplied as a parameter to the AUTH command. (SASL, described in RFC 2222, means "Simple Authentication and Security Layer".) The NTLM is the native authentication protocol of Windows NT, which is supported by Microsoft Exchange Server. The AuthNtlm() member function takes a user name and password as parameters. If the return value indicates success, you should check the server's reply code, by calling the ReplyCode() member function. A 2xx reply code indicates success.
|
|
||||||||||||
|
Sends the AUTH PLAIN command. AUTH is actually the name of the SMTP command; PLAIN is the name of a registered SASL authentication mechanism, which is supplied as a parameter to the AUTH command. (SASL, described in RFC 2222, means "Simple Authentication and Security Layer".) The PLAIN authentication mechanism is described in RFC 2595. PLAIN is the least secure of all the SASL authentication mechanisms, since the password is essentially sent unencrypted across the network. The CRAM-MD5 authentication mechanism is much more secure. You can use the AuthCramMd5() member function to send the AUTH CRAM-MD5 command. The AuthPlain() member function takes a user name and password as parameters. If the return value indicates success, you should check the server's reply code, by calling the ReplyCode() member function. A 2xx reply code indicates success.
|
|
|
Cancels the currently executing command. Since it is possible for a network connection to stop responding, an interactive application must be able to cancel a command that is waiting on a network operation (connect, send, or receive). For this reason, the SmtpClient class provides a Cancel() member function, which promptly terminates any currently executing client command. Cancel() is the only member function that is safe to call from another thread. In a typical situation, you have one thread that executes SMTP commands, and another thread that serves the user interface. A user action to cancel is serviced by the user interface thread, which calls Cancel() on the SmtpClient object to cancel a command. The command function that the SMTP client thread was executing at the time may return an error. (It will return an error if the cancel operation occurred before the command was completed.) Because it is difficult to recover the client/server state after a cancel operation, the library closes the connection whenever you call the Cancel() member function. You must call Connect() again to reconnect to the SMTP server. Note: You should not call the Connect() function from the same thread thread that called Cancel().
|
|
|
Gets the cabability at the specified index. If the EHLO command is successful, the SMTP server returns a list of optional capabilities that it supports. The SmtpClient class saves this list of capabilities and provides member functions that allow you to examine it. The CapabilityAt() function returns the item in the list at the specified position. Using this member function together with the NumCapabilities() member function you can iterate over the entries in the list.
|
|
||||||||||||||||
|
Opens a connection to an SMTP server. This member function opens a connection to the host at network address address and TCP port port. The address parameter may be either a hostname, such as "smtp.example.com", or an IP address in dotted decimal form, such as "192.168.2.25". The default value for port is 25, the well-known TCP port number for SMTP. If the client connects to the server successfully, then Connect() returns 0. If the client fails to connect to the server -- for example, if the host is not found or some other network error occurs -- then Connect() returns -1. If Connect() returns 0, then you should also check the server's reply code. The server sends a 2xx reply code (specifically, a 220 reply code) if it is ready to process commands. You may check the reply code by calling the ReplyCode() member function. You may call the Cancel() member function from another thread to cancel this operation. If the optional parameter wait is true, it causes the client to wait for the server's greeting. In the SMTP protocol, the server always begins the dialog with its initial greeting. However, if you need to establish a TLS connection to the server, you may set wait to false. Then, the function returns immediately after the TCP connection is established without waiting for the server's initial greeting.
|
|
||||||||||||
|
Opens a TLS connection over an existing TCP connection. Transport Layer Security (TLS) provides server authentication and private communication over a TCP connection. TLS is the successor to Secure Sockets Layer (SSL), and individuals often use the term SSL even if the actual protocol is TLS. TLS is a standards track protocol developed by the IETF and described in RFC 2246. Before you call ConnectTls(), you must have established a TCP connection to the server. You must also have configured the TlsConfig object. Normally, you configure the TlsConfig object when you initialize your application. ConnectTls() starts a dialog between client and server, called a TLS handshake, to negotiate security parameters for the secure connection and to authenticate the server. If the handshake succeeds, a secure TLS connection is established between client and server. During the TLS handshake, the server sends a certificate to the client, and the client examines the certificate to verify the identity of the server. The certificate must be valid, and it must contain the host name of the server. When you call ConnectTls(), you provide the server's host name in the serverHostName parameter. The library tries to match serverHostName with the host name in the certificate. If the match fails, but the handshake otherwise succeeds, then the function returns -1, and the error code is BAD_CERTIFICATE_NAME_ERROR. In many applications, a BAD_CERTIFICATE_NAME_ERROR is not automatically treated as a fatal error; rather, the application presents an alert to the user and allows the user the choice to abort the connection or to continue and ignore the failure. Therefore, BAD_CERTIFICATE_NAME_ERROR should be treated as a severe warning: the server authentication failed but the secure connection succeeded. You should treat any other error that occurs during the handshake as a fatal error and close the TCP connection. If the optional parameter wait is true, it causes the client to wait for the server's greeting. It is important to set the correct value for this parameter. There are two cases: In the first case, you call Connect() to connect to a special secure SMTP port (for example, TCP port 465) and then immediately call ConnectTls() to create a TLS connection. In this case, you call Connect() with wait false and you call ConnectTls() with wait true. In the second case, you call Connect() to connect to the standard SMTP port (TCP port 25 or 587). Then you call Starttls() to indicate to the server that you want to begin a TLS handshake. Then you call ConnectTls() create a TLS connection. In this case, you call Connect() with wait true (the default), and you call ConnectTls() with wait false (also the default). The function returns 0 on success and -1 on failure. To check the error code after a failure, call ErrorCode().
|
|
||||||||||||||||
|
Opens a TLS connection over an existing TCP connection, using a specified SSL struct. For simple use of TLS, you may use the ConnectTls() member function. For advanced use, you may use this member function, which allows you to create an SSL struct and pass it to the library to use. Examples of situations where you may choose to use the ConnectTlsOpenSSL() function include:
To use ConnectTlsOpenSSL(), you must call the OpenSSL function SSL_new(SSL_CTX*) to create an SSL struct. After you configure the SSL struct, you pass it as the ssl parameter to ConnectTlsOpenSSL(). The SmtpClient destructor calls SSL_free(SSL*) to free the SSL struct. However, OpenSSL uses a reference counting mechanism, and you may use that mechanism to prevent the SmtpClient destructor from freeing the SSL struct. To prevent the SmtpClient's destructor from freeing the SSL struct, increment the reference count before you pass the struct to the SmtpClient, like so:
CRYPTO_add(&ssl->references, 1, CRYPTO_LOCK_SSL);
|
|
|
Sends the DATA command. The DATA command follows the RCPT command and tells the SMTP server to prepare to receive the current message. The message content of the current message follows the DATA command. If the return value indicates success, you should check the server's reply code, by calling the ReplyCode() member function. A 3xx reply code indicates that the server is ready to receive the message content.
|
|
|
Closes the connection to the SMTP server. The correct way to end an SMTP session is to send a QUIT command, which causes the server perform any necessary closing operations and close the connection. Therefore you should almost always call Quit() immediately before you call Disconnect().
|
|
|
Sends the EHLO command. An SMTP client sends an EHLO command to identify itself to an SMTP server. RFC 2822 requires that the hostname argument in the EHLO command be a fully qualified domain name or an IP address literal. (In practice, many SMTP server's ignore the hostname argument, regarding it as untrustworthy.) If the return value indicates success, you should check the server's reply code, by calling the ReplyCode() member function. A 2xx reply code indicates success.
|
|
|
Gets the server's enhanced status code. Enhanced status codes are an optional feature that is not supported by all SMTP servers. |
|
|
Gets the platform-independent error code for the last error. The error codes are enumerated in the file mailpp/Error.h. Note that they are defined in the mailpp namespace. The ErrorMessage() member function returns a textual description of the platform-independent error. If the error code is SYSTEM_ERROR, you may call OsErrorCode() to get more detailed information about the error.
|
|
|
Gets the error message for the last error. This function returns a textual description of the platform-independent error code.
|
|
|
Returns true if the named capability is in the server's capabilities list. If the EHLO command is successful, the SMTP server returns a list of optional capabilities that it supports. The SmtpClient class saves this list of capabilities and provides member functions that allow you to examine it. The HasCapability() member function provides a simple way for you to check if the server supports a particular capability. Internally, the HasCapability() member function iterates over the list of capabilities attempting to match the desired capability name. The function returns a true value if a match is found.
|
|
|
Sends the HELO command. An SMTP client sends a HELO command to identify itself to an SMTP server. The HELO command is deprecated in current usage; it is replaced by the EHLO command. However, the HELO command is sometimes needed as a fallback in situations where an old SMTP server implementation does not recognize the EHLO command. RFC 2822 requires that the hostname argument in the HELO command be a fully qualified domain name or an IP address literal. (In practice, many SMTP server's ignore the hostname argument, regarding it as untrustworthy.) If the return value indicates success, you should check the server's reply code, by calling the ReplyCode() member function. A 2xx reply code indicates success.
|
|
||||||||||||
|
Sends the MAIL command. The MAIL command begins a mail transaction, and tells the SMTP server the sender of the current message. Various SMTP extensions permit optional parameters to the MAIL command. One of the most useful extensions is the SIZE extension defined in RFC 1870. The SIZE extension allows the size of a message to be reported to the server before the message is sent. The server can then reject a message that is too large. (The alternative is for the message to be rejected by the server after the message is sent!) The MailFrom() member function takes the sender email address as a required parameter, and a list of MAIL command parameters as an optional parameter. The sender string should be a simple email address in the form "jdoe\@example.org". The params string should contain the MAIL command parameters as they would be sent in the MAIL command line.
|
|
|
Sends the NOOP command. The server takes no action in response to a NOOP command except to send a positive response. (NOOP means "no operation".) An SMTP client may send the NOOP command to reset a connection timeout timer at the server. The return value indicates if the communication between client and server was successful. The server always responds with a 250 reply to the NOOP command.
|
|
|
Gets the number of capabilities in the server's capabilities list. If the EHLO command is successful, the SMTP server returns a list of optional capabilities that it supports. The SmtpClient class saves this list of capabilities and provides member functions that allow you to examine it. The NumCapabilities() function returns the number of capabilities in the list. Using this member function together with the CapabilityAt() member function you can iterate over the entries in the list.
|
|
|
Returns the operating system's error code that resulted from the most recent command execution. The operating system's error code is necessarily platform-specific. This error code is probably not as useful as the platform-independent error code, but could provide information helpful for debugging. The operating system's error code provides more specific information when the platform-independent error code is SYSTEM_ERROR. Not all errors have an operating system error code. Some errors, such as library usage errors, are detected in the Hunny Mail++ library itself.
|
|
|
Sends the QUIT command. The QUIT command causes the server to perform any closing operations and to close the connection. The return value indicates if the communication between client and server was successful. The server always responds with a 221 reply to the QUIT command.
|
|
||||||||||||
|
Sends the RCPT command. The RCPT command follows the MAIL command, and tells the SMTP server one of the recipients of the current message. The RCPT command can be repeated multiple times to tell the SMTP server of multiple recipients. The RcptTo() member function takes the recipient email address as a required parameter, and a list of RCPT command parameters as an optional parameter. The recipient string should be a simple email address in the form "jdoe\@example.org". The params string should contain the RCPT command parameters as they would be sent in the RCPT command line.
|
|
|
Receives a response from the SMTP server. This is an advanced function that allows the library to be extended. |
|
|
Gets the reply code of the server's response to the most recent command. Reply codes in SMTP are three-digit numbers. The first digit (the most significant digit) indicates success or failure; the second and third digits provide more detailed information about the error. Error codes are listed in RFC 2822.
|
|
|
Gets the reply text of the server's response to the most recent command. The ReplyText() member function removes the initial reply code and the final CR LF from the server's response. For example, if the server's response is "550 No such user here\r\\n", the reply text is "No such user here". If the server sends a multiple line reply, this member function returns only the text of the first line.
|
|
|
Sends the RSET command. The RSET command aborts a mail transaction. (In database terminology, this is a "rollback".) The return value indicates if the communication between client and server was successful. The server always responds with a 250 reply to the RSET command.
|
|
||||||||||||||||
|
Sends bytes to the server. This member function is an advanced function that can be used to extend the library. The bytes parameter is a pointer to a buffer containing the bytes to send. The length parameter specifies how many bytes to send. The options parameter can be 0, to indicate that the libary code should not try receive a response after sending the bytes; or SmtpClient::LAST, to indicate that the library code should try to receive a response after sending the bytes.
|
|
|
Sends the argument as an SMTP command. This is an advanced function that allows the library to be extended. |
|
||||||||||||||||
|
Sends the message as text lines. The message follows the DATA command, if the DATA command succeeds. In SMTP, the message is sent as a series of lines, where each line ends with the CR LF characters. The bytes provided as an argument to the SendLines() member function should be in the required format -- that is, the buffers should contain lines of text. (Remember that non-text data is converted to text by base64 encoding as required by the MIME specification.) To send the message, call the SendLines() member function as many times as you need to send all the bytes of the message. When you call SendLines() to send the first buffer, you must set the SmtpClient::FIRST bit in the options argument. When you send the last buffer, you must set the SmtpClient::LAST bit in the options argument. SendLines() performs the conversion to CR LF end-of-line characters if you specify SmtpClient::CONVERT_EOL as one of the options. With the SmtpClient::CONVERT_EOL option set, conversions are performed as follows: LF --> CR LF, and CR LF --> CR LF. Therefore, with the SmtpClient::CONVERT_EOL option, you can safely submit text with LF end-of-line characters or with CR LF end-of-line characters. The SmtpClient::LAST option is an indication to the library code to receive a response from the server. You should then check the reply code of the server's response, which you may get by calling the ReplyCode() member function. A 250 reply code indicates success.
|
|
|
Sets the timeout for network read operations. The timeout applies to these network operations: receive. If a network operation times out, the member function that was executing returns -1, and ErrorCode() returns TIMED_OUT_ERROR.
|
|
|
Sets the timeout for network write operations. The timeout applies to these network operations: connect, write. If a network operation times out, the member function that was executing returns -1, and ErrorCode() returns TIMED_OUT_ERROR.
|
|
|
Sets the timeout for network operations. The timeout applies to these network operations: connect, receive, and send. If a network operation times out, the member function that was executing returns -1, and ErrorCode() returns TIMED_OUT_ERROR. This member function is deprecated. Use SetRecieveTimeout() and SetSendTimeout() to set network timeouts.
|
|
||||||||||||
|
Sets a TraceOutput instance. When you set a TraceOutput instance, you enable trace output, which may be helpful for debugging. You may set a null value to disable trace output. The Hunny Mail++ library provides a StdTraceOutput class that prints all output to standard output. If you pass a true value for the takeOwnership parameter, then the SmtpClient object has the responsibility to delete the trace output object. On the other hand, if you pass false, then your code must delete the trace output object when it is no longer needed.
|
|
|
Sends the STARTTLS command. The STARTTLS command asks the server to begin a TLS handshake. If the STARTTLS command succeeds, as indicated by a 2xx reply code from the server, then you should immediately call ConnectTls() to start the TLS handshake and to establish the secure connection. The STARTTLS SMTP command is documented in RFC 2487. Note: You must have Secure Mail++ to use this member function. In (non-Secure) Mail++, the function returns -1.
|
|
|
Sends the VRFY command. The VRFY command requests the server to "verify" a recipient address. The VRFY command is used primarily to "debug" addresses. A mail administrator can telnet to the SMTP port, type the VRFY command, and view the server's responses. The VRFY command is not used to send mail. Consequently, the VRFY command is an optional command in SMTP, and may not be implemented in all servers. In addition, a mail administrator may disable the VRFY command to unknown clients in order to protect the privacy of its users. The return value indicates if the communication between client and server was successful. If the server finds the recipient address to be valid, it returns a 250 reply code. If the server finds the address to be invalid, it returns a 55x reply code. If the server refuses to execute the VRFY command for policy reasons, it returns a 252 reply code.
|
Copyright © 2001-2005 Hunny Software, Inc. All rights reserved.